From mboxrd@z Thu Jan 1 00:00:00 1970 From: mick@ics.forth.gr (Nick Kossifidis) Date: Sat, 03 Nov 2018 01:45:06 +0200 Subject: SBI extension proposal In-Reply-To: <5725574a-60c3-26f4-565b-4498c757a8f8@wdc.com> References: <7f2a546a-6ebb-43c6-83a0-5e712ec2e2c7@wdc.com> <3245c74a8dc9f651cb07e382585fa311@mailhost.ics.forth.gr> <5725574a-60c3-26f4-565b-4498c757a8f8@wdc.com> Message-ID: To: linux-riscv@lists.infradead.org List-Id: linux-riscv.lists.infradead.org ???? 2018-11-03 01:12, Atish Patra ??????: > On 11/2/18 8:25 AM, Nick Kossifidis wrote: >> Hello Atish and thanks for bringing this up, >> >> ???? 2018-10-31 20:23, Atish Patra ??????: >>> Here is a proposal to make SBI a flexible and extensible interface. >>> It is based on the foundation policy of RISC-V i.e. modularity and >>> openness. It is designed in such a way that it introduces very few >>> new >>> mandatory SBI APIs that are absolutely required to maintain backward >>> compatibility. Everything else is optional so that it remains an open >>> standard yet robust. >>> >>> 1. Introduction: >>> ---------------- >>> The current RISC-V SBI only defines a few mandatory functions such as >>> inter-processor interrupts (IPI) interface, reprogramming timer, >>> serial >>> console and memory barrier instructions. The existing SBI >>> documentation >>> can be found here [1]. Many important functionalities such as power >>> management/cpu-hotplug are not yet defined due to difficulties in >>> accommodating modifications without breaking the backward >>> compatibility >>> with the current interface. >>> >>> Its design is inspired by Power State Coordination Interface (PSCI) >>> from >>> ARM world. However, it adds only two new mandatory SBI calls >>> providing >>> version information and supported APIs, unlike PSCI where a >>> significant >>> number of functions are mandatory. The version of the existing SBI >>> will >>> be defined as a minimum version(0.1) which will always be backward >>> compatible. Similarly, any Linux kernel with newer feature will fall >>> back if an older version of SBI does not support the updated >>> capabilities. Both the operating system and SEE can be implemented to >>> be two way backward compatible. >>> >>> 2. New functions: >>> ----------------- >>> >>> -- u32 sbi_get_version(void): >>> >>> Returns the current SBI version implemented by the firmware. >>> version: uint32: Bits[31:16] Major Version >>> Bits[15:0] Minor Version >>> >>> The existing SBI version can be 0.1. The proposed version will be at >>> 0.2 >>> A different major version may indicate possible incompatible >>> functions. >>> A different minor version must be compatible with each other even if >>> they have a higher number of features. >>> >>> -- u32 sbi_check_api(unsigned long start_api_id, unsigned long >>> count): >>> >>> Accepts a start_api_id as an argument and returns if start_api_id to >>> (start_api_id + count - 1) are supported or not. >>> The API numbering scheme is described in section 3. >>> >>> A count is introduced so that a range of APIs can be checked at one >>> SBI >>> call to minimize the M-mode traps. >>> >> >> Is this really needed ? We can determine the SBI version from >> sbi_get_version, why >> include an SBI call to perform a check that can easily be performed by >> the caller >> instead ? >> > > This API is still in discussion. Probably, an API returning bitmask of > all the features make more sense ? > > However, I feel a separate API is required from sbi_get_version as > there vendors can choose not to implement some of the features that is > specified by a version as most of the API set are optional. > We can always rely on the SBI_NOT_SUPPORTED error code you've already included ;-) If we use a bitmask for capabilities we'll be limited by the encoding. >>> -- int sbi_hart_up(unsigned long hartid, unsigned long start, >>> unsigned >>> long priv) >>> >>> Brings up "hartid" either during initial boot or after a >>> sbi_hart_down >>> SBI call. >>> >>> "start" points to a runtime-specified address where a hart can enter >>> into supervisor mode. This must be a physical address. >>> >>> "priv" is a private data that caller can use to pass information >>> about >>> execution context. >>> >>> Return the appropriate SBI error code. >>> >>> -- int sbi_hart_suspend(u32 state, unsigned long resume_entry, >>> unsigned >>> long priv) >>> >>> Suspends the calling hart to a particular power state. Suspended hart >>> will automatically wake-up based on some wakeup events at >>> resume_entry >>> physical address. >>> >>> "priv" is a private data that caller can use to pass information >>> about >>> execution context. The SBI implementation must save a copy so that >>> caller can reuse while restoring hart from suspend. >>> >>> Return the appropriate SBI error code. >>> >>> -- int sbi_hart_down() >>> >>> It powers off the hart and will be used in cpu-hotplug. >>> Only individual hart can remove itself from supervisor mode. It can >>> be >>> moved to normal state only by sbi_hart_up function. >>> >>> Return the appropriate SBI error code. >>> >>> -- u32 sbi_hart_state(unsigned long hartid) >>> >>> Returns the RISCV_POWER_STATE for a specific hartid. This will help >>> make >>> kexec like functionality more robust. >>> >> >> Instead of the above I believe it would be cleaner and simpler to have >> an sbi_get_hart_state and an sbi_set_hart_state call. This way we can >> better handle state transitions and, handle ON/OFF/STANDBY/RETENTION >> and any other state we come up with, without adding extra sbi calls. >> > > When do you want to use sbi_set_hart_state ? > The power states will be modified as a part of sbi_hart_down or > sbi_shutdown/suspend calls anyways. > The idea is to have sbi_set_hart_state instead of sbi_hart_down/shutdown/suspend/etc. Instead of having different calls for different states we just have two calls, one to get the state and one to set it. This way we have fewer calls and if we add a new state we can add it without having to add a new call. >>> -- void sbi_system_shutdown() >>> >>> Powers off the entire system. >>> >> >> Don't we already have that ? What's the difference between >> sbi_system_shutdown >> and sbi_shutdown ? Does it make sense to use sbi_shutdown and leave >> the >> system >> on with all the harts down ? Maybe we can just say that sbi_shutdown >> also >> powers down the system and rename it to sbi_system_shutdown with the >> same >> function ID. >> > > Yeah. That's a better. > > >>> 3. SBI API ID numbering scheme: >>> ------------------------------ >>> An API Set is a set of SBI APIs which collectively implement some >>> kind of feature/functionality. >>> >>> Let's say SBI API ID is u32 then >>> Bit[31:24] = API Set Number >>> Bit[23:0] = API Number within API Set >>> >>> Here are few API Sets for SBI v0.2: >>> 1. Base APIs >>> API Set Number: 0x0 >>> Description: Base APIs mandatory for any SBI version >>> >>> 2. HART PM APIs >>> API Set Number: 0x1 >>> Description: Hart UP/Down/Suspend APIs for per-Hart >>> power management >>> >>> 3. System PM APIs >>> API Set Number; 0x2 >>> Description: System Shutdown/Reboot/Suspend for system-level >>> power management >>> >>> 4. Vendor APIs >>> API Set Number: 0xff >>> Description: Vendor specific APIs. >>> There is a possibility that different vendors can choose to assign >>> same API numbers for different functionality. In that case, vendor >>> specific strings in Device Tree can be used to verify if a specific >>> API belongs to the intended vendor or not. >>> >> >> I understand the rationale behind this but I believe it's better to >> call them services or functions instead of APIs, they are not sets >> of APIs the way I see it. Also since we are moving that path why call >> it SBI and restrict it only to be used by the supervisor ? I'd love to >> have another category for the secure monitor calls for example, >> but on the software architecture that we are discussing on the TEE >> group, such calls can also originate from U mode or HS/HU modes. >> The same goes for vendor specific calls, there are lots of use case >> scenarios where vendors would like to be able to call their stuff >> from U mode for example (e.g. a user space library talking to a >> smart card directly). >> >> I suggest we rename it from SBI to something more generic that is not >> defined by who is calling it but by what we are calling, which in this >> case is the firmware (FBI?). > > possible conflict with a very famous law enforcement agency :) :). > > Jokes aside, renaming to something more generic is a good idea. But it > will probably break a ton of documentation/spec in RISC-V which I > don't want to deal with right now. May be in future versions ? > I get that updating the documentation can be a pain, I can help with that if you want (and I promise I'll stay away from law enforcement agencies !). I suggest we do the renaming as early as possible because we are going to carry it for a long time instead and it'll only get harder to change later on. >> Since you mentioned ARM, in their case >> the ABI used for PSCI is the Secure Monitor Call (which is the >> alternative >> to what is defined on the first paragraph of the SBI document), but it >> has the same limitation. According to the documentation if an SMC >> comes >> from a user application, we get an undefined exception. We can do >> better >> ! >> > > > >> >>> 4. Return error code Table: >>> --------------------------- >>> >>> Here are the SBI return error codes defined. >>> >>> SBI_SUCCESS 0 >>> SBI_NOT_SUPPORTED -1 >>> SBI_INVALID_PARAM -2 >>> SBI_DENIED -3 >>> SBI_INVALID_ADDRESS -4 >>> >>> A mapping function between SBI error code & Linux error code should >>> be >>> provided. >>> >> >> I believe it should be up to the OS to translate the SBI error codes >> to >> its >> native ones. >> > > Correct. Olof also pointed this out. I will remove it in next version. > >>> 5. Power State >>> -------------- >>> >>> A RISC-V core can exist in any of the following power states. >>> >>> enum RISCV_POWER_STATE { >>> //Powered up & operational. >>> RISCV_HART_ON = 0, >>> //Powered up but at reduced energy consumption. WFI >>> instruction >>> can be used to achieve this state. >>> RISCV_HART_STANDBY = 1, >>> //Deeper low power state. No reset required but higher wakeup >>> latency. >>> RISCV_HART_RETENTION = 2, >>> //Powered off. Reset of the core required after power >>> restore. >>> RISCV_HART_OFF = 3 >>> } >>> >>> TODO: >>> Any other power management related features or state? >>> >> >> How about LOCKSTEP ? We could have a way of declaring a hart as a >> "mirror" of another >> hart (https://en.wikipedia.org/wiki/Lockstep_(computing)). We can have >> an extra argument >> on sbi_get/set_state when the LOCKSTEP state is used, that will >> get/set >> the hart that >> this hart is mirroring. >> > > Not sure if we need it right now. I want to keep it simple and focus > on the bare minimum ones. We can always add exotic ones once we have > feature/versioning in place. > I agree, I mentioned LOCKSTEP because it'll need an extra argument when setting the state. Btw I know lockstep sounds exotic at this point but it's needed by many industries that deal with safety (automotive stuff, medical devices etc). However it needs more thinking. >>> 6. Implementation >>> ------------------- >>> Currently, SBI is implemented as a part of BBL. There is a different >>> SBI implementation available in coreboot as well. >>> >>> Alternatively, a separate open BSD/MIT licensed SBI project can be >>> created which can be used by anybody to avoid these kind of SBI >>> fragmentation in future. This project can generate both a firmware >>> binary (to executed directly in M mode) or a static library that can >>> be used by different boot loaders. It will also help individual boot >>> loaders to either work from M or S mode without a separate SBI >>> implementation. >>> >> >> Why implement this at the boot loader level ? This is more like a >> firmware interface >> than something that belongs to the bootloader. The bootloader should >> use >> this interface >> not provide it. > It depends on the bootloader. For example, there are patches in > coreboot that implements SBI. The idea with OpenSBI implementation is > to avoid such fragmentation. > >> Also this is something that belongs to the M mode, a >> bootloader >> should belong to the S mode, running the bootloader in M mode is not >> right from >> a security point of view. We can provide something like "RISC-V >> Firmware >> Services" >> that's code running on M mode after the first stage boot >> loader/BootROM >> and let >> bootloaders use it without having to implement it. > > That's the idea for S mode bootloaders. However, there are folks who > are interested in M mode ones and I understand their usecase. Thus, > idea is to implement OpenSBI in such a way that, everybody can make > use of it. > I guess then we can provide it as a library and also provide a reference implementation around it. However I still believe that something like "RISC-V Firmware Services" is more appropriate, we can structure this in a client/server way and let bootloaders use the server part and OS drivers/modules use the client part. This way we can also avoid fragmentation across OSes. Regards, Nick 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=-2.5 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_PASS, URIBL_BLOCKED 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 0FE00C32789 for ; Fri, 2 Nov 2018 23:46:01 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (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 B925720831 for ; Fri, 2 Nov 2018 23:46:00 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="pNGE4Ktx" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B925720831 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=ics.forth.gr Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-riscv-bounces+infradead-linux-riscv=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender:Content-Type: Content-Transfer-Encoding:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:Message-ID:References:In-Reply-To:Subject:To:From: Date:MIME-Version:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=QkKSSP/Mtn7jDtG1WVzYKH8d6YqF1u4NHUFyQy/8sxM=; b=pNGE4KtxY5E0HU13t2e6ctFt1 I65RMoDkKIvDKABDgTf5ImJ06VNXgapTf+NlqHS8GQFH7SvfwfswVtwVK2JFpguCMsfpq9PSJoH0Z PmRE7mloPXgPCfLlz8bQGGyUf4okZJ6/ERwCH6BLrucZFKafbHmWs7sSp9/ueSCuW3bK8hrQmPsp4 g0gfrbJk/oZwla7Lu8V+CzpPpfrXWj//Mfn+EXVBdR++9JsvNeJIV7MtugV7pNgmJ5RfP4cUGEztE qopV8EbCC3tONI8yWfn+3By8jxrr34Uo/NRGzBNWd2rr4eoUTyExIPXADVGbRSATe2Hp/eMPvn9Sq gZl+Bh6kA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gIj8Z-0001px-Kw; Fri, 02 Nov 2018 23:45:59 +0000 Received: from mailgate-4.ics.forth.gr ([139.91.1.7]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gIj8U-0001oN-WA for linux-riscv@lists.infradead.org; Fri, 02 Nov 2018 23:45:57 +0000 Received: from av1.ics.forth.gr (av3in.ics.forth.gr. [139.91.1.77]) by mailgate-4.ics.forth.gr (8.14.5/ICS-FORTH/V10-1.9-GATE-OUT) with ESMTP id wA2Nj96Y073745; Sat, 3 Nov 2018 01:45:11 +0200 (EET) X-AuditID: 8b5b9d4d-903ff70000000e62-11-5bdce184a9d7 Received: from enigma.ics.forth.gr (webmail.ics.forth.gr [139.91.1.35]) by av1.ics.forth.gr (SMTP Outbound / FORTH / ICS) with SMTP id 99.46.03682.481ECDB5; Sat, 3 Nov 2018 01:45:08 +0200 (EET) Received: from webmail.ics.forth.gr (localhost [127.0.0.1]) by enigma.ics.forth.gr (8.15.1//ICS-FORTH/V10.5.0C-EXTNULL-SSL-SASL) with ESMTP id wA2Nj6fk026874; Sat, 3 Nov 2018 01:45:07 +0200 X-ICS-AUTH-INFO: Authenticated user: at ics.forth.gr MIME-Version: 1.0 Date: Sat, 03 Nov 2018 01:45:06 +0200 From: Nick Kossifidis To: Atish Patra Subject: Re: SBI extension proposal Organization: FORTH In-Reply-To: <5725574a-60c3-26f4-565b-4498c757a8f8@wdc.com> References: <7f2a546a-6ebb-43c6-83a0-5e712ec2e2c7@wdc.com> <3245c74a8dc9f651cb07e382585fa311@mailhost.ics.forth.gr> <5725574a-60c3-26f4-565b-4498c757a8f8@wdc.com> Message-ID: X-Sender: mick@mailhost.ics.forth.gr User-Agent: Roundcube Webmail/1.1.2 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrLIsWRmVeSWpSXmKPExsXSHc2orNv68E60wbfpzBYPe+4wWWxbsprV YsvtGIuWD+9YLf5OOsZusWjFdxaL1vZvTBbTF/5msjg9YRFQ2ecWNoul1y8yWTS/O8dusezD XkaLnV13WC02T1jAatE2i99i/vInLBa7du9is3i+spfNQdhjz+lZzB5r5q1h9Pj9axKjx9Tf Z1g8Hp2byuixc9Zddo9duxrZPR5uusTksXmFlsfmJfUe7/ddZfO41Hyd3aP9QDdTAG8Ul01K ak5mWWqRvl0CV8b8rc1sBe8zK37Pm83cwPg0qIuRg0NCwESi41NaFyMXh5DAEUaJP9cuM0M4 BxklNn3ewdrFyAlUZCoxe28nI4jNKyAocXLmExYQm1nAQmLqlf2MELa8RPPW2cwgNouAqsTC riNgcTYBTYn5lw6ygCwTAYrPWsQPMp9ZoJFN4uGkZ4wgcWEBZYmbd3RByvkFhCU+3b3IChLm FLCWeLaNF+KcZYwSHzreMYPEeQVcJP7fKoW4TEXiw+8H7CC2KNCUFyems05gFJqF5NBZSA6d heTQBYzMqxgFEsuM9TKTi/XS8otKMvTSizYxgiN5ru8OxnML7A8xCnAwKvHwGlTeiRZiTSwr rsw9xCjBwawkwvulFSjEm5JYWZValB9fVJqTWnyIUZqDRUmc9/CL8CAhgfTEktTs1NSC1CKY LBMHp1QDI79uddGVuReOsnS4+1lM272zz6PbsGvxuYiDHTaL5ezai5ct+XtMkHdr/I/J+4SX fpBcPDkh8Soj743n2sfer/ON+tXXcp1ztZDIrV7Fiu8BRd0+aRpGk7W37eALvzXT+aS3Vnbv RPe3nzxfcuv677ugLXxdfe3rXo2bC3kfh25O+XGVReWsmhJLcUaioRZzUXEiAF4KMszgAgAA X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181102_164555_773982_4D513A50 X-CRM114-Status: GOOD ( 32.52 ) X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, Zong Li , Damien Le Moal , Olof Johansson , Andrew Waterman , Alan Kao , Anup Patel , Palmer Dabbelt , "Rwmjones.fedora" , Christoph Hellwig , vincentc@andestech.com, Michael Clark , Arnd Bergmann , Paul Walmsley , Nick Kossifidis , linux-riscv@lists.infradead.org, "Chang, Abner \(HPS SW/FW Technologist\)" , David.Abdurachmanov@cern.ch Content-Transfer-Encoding: base64 Content-Type: text/plain; charset="utf-8"; Format="flowed" Sender: "linux-riscv" Errors-To: linux-riscv-bounces+infradead-linux-riscv=archiver.kernel.org@lists.infradead.org Message-ID: <20181102234506.QND9yYEoa7R2lbiOBcrPqXSgtitZ4Zo6Fl6DFBP6a34@z> zqPPhM65z4IgMjAxOC0xMS0wMyAwMToxMiwgQXRpc2ggUGF0cmEgzq3Os8+BzrHPiM61Ogo+IE9u IDExLzIvMTggODoyNSBBTSwgTmljayBLb3NzaWZpZGlzIHdyb3RlOgo+PiBIZWxsbyBBdGlzaCBh bmQgdGhhbmtzIGZvciBicmluZ2luZyB0aGlzIHVwLAo+PiAKPj4gzqPPhM65z4IgMjAxOC0xMC0z MSAyMDoyMywgQXRpc2ggUGF0cmEgzq3Os8+BzrHPiM61Ogo+Pj4gSGVyZSBpcyBhIHByb3Bvc2Fs IHRvIG1ha2UgU0JJIGEgZmxleGlibGUgYW5kIGV4dGVuc2libGUgaW50ZXJmYWNlLgo+Pj4gSXQg aXMgYmFzZWQgb24gdGhlIGZvdW5kYXRpb24gcG9saWN5IG9mIFJJU0MtViBpLmUuIG1vZHVsYXJp dHkgYW5kCj4+PiBvcGVubmVzcy4gSXQgaXMgZGVzaWduZWQgaW4gc3VjaCBhIHdheSB0aGF0IGl0 IGludHJvZHVjZXMgdmVyeSBmZXcgCj4+PiBuZXcKPj4+IG1hbmRhdG9yeSBTQkkgQVBJcyB0aGF0 IGFyZSBhYnNvbHV0ZWx5IHJlcXVpcmVkIHRvIG1haW50YWluIGJhY2t3YXJkCj4+PiBjb21wYXRp YmlsaXR5LiBFdmVyeXRoaW5nIGVsc2UgaXMgb3B0aW9uYWwgc28gdGhhdCBpdCByZW1haW5zIGFu IG9wZW4KPj4+IHN0YW5kYXJkIHlldCByb2J1c3QuCj4+PiAKPj4+IDEuIEludHJvZHVjdGlvbjoK Pj4+IC0tLS0tLS0tLS0tLS0tLS0KPj4+IFRoZSBjdXJyZW50IFJJU0MtViBTQkkgb25seSBkZWZp bmVzIGEgZmV3IG1hbmRhdG9yeSBmdW5jdGlvbnMgc3VjaCBhcwo+Pj4gaW50ZXItcHJvY2Vzc29y IGludGVycnVwdHMgKElQSSkgaW50ZXJmYWNlLCByZXByb2dyYW1taW5nIHRpbWVyLCAKPj4+IHNl cmlhbAo+Pj4gY29uc29sZSBhbmQgbWVtb3J5IGJhcnJpZXIgaW5zdHJ1Y3Rpb25zLiBUaGUgZXhp c3RpbmcgU0JJIAo+Pj4gZG9jdW1lbnRhdGlvbgo+Pj4gY2FuIGJlIGZvdW5kIGhlcmUgWzFdLiBN YW55IGltcG9ydGFudCBmdW5jdGlvbmFsaXRpZXMgc3VjaCBhcyBwb3dlcgo+Pj4gbWFuYWdlbWVu dC9jcHUtaG90cGx1ZyBhcmUgbm90IHlldCBkZWZpbmVkIGR1ZSB0byBkaWZmaWN1bHRpZXMgaW4K Pj4+IGFjY29tbW9kYXRpbmcgbW9kaWZpY2F0aW9ucyB3aXRob3V0IGJyZWFraW5nIHRoZSBiYWNr d2FyZCAKPj4+IGNvbXBhdGliaWxpdHkKPj4+IHdpdGggdGhlIGN1cnJlbnQgaW50ZXJmYWNlLgo+ Pj4gCj4+PiBJdHMgZGVzaWduIGlzIGluc3BpcmVkIGJ5IFBvd2VyIFN0YXRlIENvb3JkaW5hdGlv biBJbnRlcmZhY2UgKFBTQ0kpCj4+PiBmcm9tCj4+PiBBUk0gd29ybGQuIEhvd2V2ZXIsIGl0IGFk ZHMgb25seSB0d28gbmV3IG1hbmRhdG9yeSBTQkkgY2FsbHMgCj4+PiBwcm92aWRpbmcKPj4+IHZl cnNpb24gaW5mb3JtYXRpb24gYW5kIHN1cHBvcnRlZCBBUElzLCB1bmxpa2UgUFNDSSB3aGVyZSBh IAo+Pj4gc2lnbmlmaWNhbnQKPj4+IG51bWJlciBvZiBmdW5jdGlvbnMgYXJlIG1hbmRhdG9yeS4g VGhlIHZlcnNpb24gb2YgdGhlIGV4aXN0aW5nIFNCSSAKPj4+IHdpbGwKPj4+IGJlIGRlZmluZWQg YXMgYSBtaW5pbXVtIHZlcnNpb24oMC4xKSB3aGljaCB3aWxsIGFsd2F5cyBiZSBiYWNrd2FyZAo+ Pj4gY29tcGF0aWJsZS4gU2ltaWxhcmx5LCBhbnkgTGludXgga2VybmVsIHdpdGggbmV3ZXIgZmVh dHVyZSB3aWxsIGZhbGwKPj4+IGJhY2sgaWYgYW4gb2xkZXIgdmVyc2lvbiBvZiBTQkkgZG9lcyBu b3Qgc3VwcG9ydCB0aGUgdXBkYXRlZAo+Pj4gY2FwYWJpbGl0aWVzLiBCb3RoIHRoZSBvcGVyYXRp bmcgc3lzdGVtIGFuZCBTRUUgY2FuIGJlIGltcGxlbWVudGVkIHRvCj4+PiBiZSB0d28gd2F5IGJh Y2t3YXJkIGNvbXBhdGlibGUuCj4+PiAKPj4+IDIuIE5ldyBmdW5jdGlvbnM6Cj4+PiAtLS0tLS0t LS0tLS0tLS0tLQo+Pj4gCj4+PiAtLSB1MzIgc2JpX2dldF92ZXJzaW9uKHZvaWQpOgo+Pj4gCj4+ PiBSZXR1cm5zIHRoZSBjdXJyZW50IFNCSSB2ZXJzaW9uIGltcGxlbWVudGVkIGJ5IHRoZSBmaXJt d2FyZS4KPj4+IHZlcnNpb246IHVpbnQzMjogQml0c1szMToxNl0gTWFqb3IgVmVyc2lvbgo+Pj4g ICAgICAgICAgICAgICBCaXRzWzE1OjBdIE1pbm9yIFZlcnNpb24KPj4+IAo+Pj4gVGhlIGV4aXN0 aW5nIFNCSSB2ZXJzaW9uIGNhbiBiZSAwLjEuIFRoZSBwcm9wb3NlZCB2ZXJzaW9uIHdpbGwgYmUg YXQKPj4+IDAuMgo+Pj4gQSBkaWZmZXJlbnQgbWFqb3IgdmVyc2lvbiBtYXkgaW5kaWNhdGUgcG9z c2libGUgaW5jb21wYXRpYmxlIAo+Pj4gZnVuY3Rpb25zLgo+Pj4gQSBkaWZmZXJlbnQgbWlub3Ig dmVyc2lvbiBtdXN0IGJlIGNvbXBhdGlibGUgd2l0aCBlYWNoIG90aGVyIGV2ZW4gaWYKPj4+IHRo ZXkgaGF2ZSBhIGhpZ2hlciBudW1iZXIgb2YgZmVhdHVyZXMuCj4+PiAKPj4+IC0tIHUzMiBzYmlf Y2hlY2tfYXBpKHVuc2lnbmVkIGxvbmcgc3RhcnRfYXBpX2lkLCB1bnNpZ25lZCBsb25nIAo+Pj4g Y291bnQpOgo+Pj4gCj4+PiBBY2NlcHRzIGEgc3RhcnRfYXBpX2lkIGFzIGFuIGFyZ3VtZW50IGFu ZCByZXR1cm5zIGlmIHN0YXJ0X2FwaV9pZCB0bwo+Pj4gKHN0YXJ0X2FwaV9pZCArIGNvdW50IC0g MSkgYXJlIHN1cHBvcnRlZCBvciBub3QuCj4+PiBUaGUgQVBJIG51bWJlcmluZyBzY2hlbWUgaXMg ZGVzY3JpYmVkIGluIHNlY3Rpb24gMy4KPj4+IAo+Pj4gQSBjb3VudCBpcyBpbnRyb2R1Y2VkIHNv IHRoYXQgYSByYW5nZSBvZiBBUElzIGNhbiBiZSBjaGVja2VkIGF0IG9uZSAKPj4+IFNCSQo+Pj4g Y2FsbCB0byBtaW5pbWl6ZSB0aGUgTS1tb2RlIHRyYXBzLgo+Pj4gCj4+IAo+PiBJcyB0aGlzIHJl YWxseSBuZWVkZWQgPyBXZSBjYW4gZGV0ZXJtaW5lIHRoZSBTQkkgdmVyc2lvbiBmcm9tCj4+IHNi aV9nZXRfdmVyc2lvbiwgd2h5Cj4+IGluY2x1ZGUgYW4gU0JJIGNhbGwgdG8gcGVyZm9ybSBhIGNo ZWNrIHRoYXQgY2FuIGVhc2lseSBiZSBwZXJmb3JtZWQgYnkKPj4gdGhlIGNhbGxlcgo+PiBpbnN0 ZWFkID8KPj4gCj4gCj4gVGhpcyBBUEkgaXMgc3RpbGwgaW4gZGlzY3Vzc2lvbi4gUHJvYmFibHks IGFuIEFQSSByZXR1cm5pbmcgYml0bWFzayBvZgo+IGFsbCB0aGUgZmVhdHVyZXMgbWFrZSBtb3Jl IHNlbnNlID8KPiAKPiBIb3dldmVyLCBJIGZlZWwgYSBzZXBhcmF0ZSBBUEkgaXMgcmVxdWlyZWQg ZnJvbSBzYmlfZ2V0X3ZlcnNpb24gYXMKPiB0aGVyZSB2ZW5kb3JzIGNhbiBjaG9vc2Ugbm90IHRv IGltcGxlbWVudCBzb21lIG9mIHRoZSBmZWF0dXJlcyB0aGF0IGlzCj4gc3BlY2lmaWVkIGJ5IGEg dmVyc2lvbiBhcyBtb3N0IG9mIHRoZSBBUEkgc2V0IGFyZSBvcHRpb25hbC4KPiAKCldlIGNhbiBh bHdheXMgcmVseSBvbiB0aGUgU0JJX05PVF9TVVBQT1JURUQgZXJyb3IgY29kZSB5b3UndmUgYWxy ZWFkeQppbmNsdWRlZCA7LSkgSWYgd2UgdXNlIGEgYml0bWFzayBmb3IgY2FwYWJpbGl0aWVzIHdl J2xsIGJlIGxpbWl0ZWQgYnkKdGhlIGVuY29kaW5nLgoKPj4+IC0tIGludCBzYmlfaGFydF91cCh1 bnNpZ25lZCBsb25nIGhhcnRpZCwgdW5zaWduZWQgbG9uZyBzdGFydCwgCj4+PiB1bnNpZ25lZAo+ Pj4gbG9uZyBwcml2KQo+Pj4gCj4+PiBCcmluZ3MgdXAgImhhcnRpZCIgZWl0aGVyIGR1cmluZyBp bml0aWFsIGJvb3Qgb3IgYWZ0ZXIgYSAKPj4+IHNiaV9oYXJ0X2Rvd24KPj4+IFNCSSBjYWxsLgo+ Pj4gCj4+PiAic3RhcnQiIHBvaW50cyB0byBhIHJ1bnRpbWUtc3BlY2lmaWVkIGFkZHJlc3Mgd2hl cmUgYSBoYXJ0IGNhbiBlbnRlcgo+Pj4gaW50byBzdXBlcnZpc29yIG1vZGUuIFRoaXMgbXVzdCBi ZSBhIHBoeXNpY2FsIGFkZHJlc3MuCj4+PiAKPj4+ICJwcml2IiBpcyBhIHByaXZhdGUgZGF0YSB0 aGF0IGNhbGxlciBjYW4gdXNlIHRvIHBhc3MgaW5mb3JtYXRpb24gCj4+PiBhYm91dAo+Pj4gZXhl Y3V0aW9uIGNvbnRleHQuCj4+PiAKPj4+IFJldHVybiB0aGUgYXBwcm9wcmlhdGUgU0JJIGVycm9y IGNvZGUuCj4+PiAKPj4+IC0tIGludCBzYmlfaGFydF9zdXNwZW5kKHUzMiBzdGF0ZSwgdW5zaWdu ZWQgbG9uZyByZXN1bWVfZW50cnksIAo+Pj4gdW5zaWduZWQKPj4+IGxvbmcgcHJpdikKPj4+IAo+ Pj4gU3VzcGVuZHMgdGhlIGNhbGxpbmcgaGFydCB0byBhIHBhcnRpY3VsYXIgcG93ZXIgc3RhdGUu IFN1c3BlbmRlZCBoYXJ0Cj4+PiB3aWxsIGF1dG9tYXRpY2FsbHkgd2FrZS11cCBiYXNlZCBvbiBz b21lIHdha2V1cCBldmVudHMgYXQgCj4+PiByZXN1bWVfZW50cnkKPj4+IHBoeXNpY2FsIGFkZHJl c3MuCj4+PiAKPj4+ICJwcml2IiBpcyBhIHByaXZhdGUgZGF0YSB0aGF0IGNhbGxlciBjYW4gdXNl IHRvIHBhc3MgaW5mb3JtYXRpb24gCj4+PiBhYm91dAo+Pj4gZXhlY3V0aW9uIGNvbnRleHQuIFRo ZSBTQkkgaW1wbGVtZW50YXRpb24gbXVzdCBzYXZlIGEgY29weSBzbyB0aGF0Cj4+PiBjYWxsZXIg Y2FuIHJldXNlIHdoaWxlIHJlc3RvcmluZyBoYXJ0IGZyb20gc3VzcGVuZC4KPj4+IAo+Pj4gUmV0 dXJuIHRoZSBhcHByb3ByaWF0ZSBTQkkgZXJyb3IgY29kZS4KPj4+IAo+Pj4gLS0gaW50IHNiaV9o YXJ0X2Rvd24oKQo+Pj4gCj4+PiBJdCBwb3dlcnMgb2ZmIHRoZSBoYXJ0IGFuZCB3aWxsIGJlIHVz ZWQgaW4gY3B1LWhvdHBsdWcuCj4+PiBPbmx5IGluZGl2aWR1YWwgaGFydCBjYW4gcmVtb3ZlIGl0 c2VsZiBmcm9tIHN1cGVydmlzb3IgbW9kZS4gSXQgY2FuIAo+Pj4gYmUKPj4+IG1vdmVkIHRvIG5v cm1hbCBzdGF0ZSBvbmx5IGJ5IHNiaV9oYXJ0X3VwIGZ1bmN0aW9uLgo+Pj4gCj4+PiBSZXR1cm4g dGhlIGFwcHJvcHJpYXRlIFNCSSBlcnJvciBjb2RlLgo+Pj4gCj4+PiAtLSB1MzIgc2JpX2hhcnRf c3RhdGUodW5zaWduZWQgbG9uZyBoYXJ0aWQpCj4+PiAKPj4+IFJldHVybnMgdGhlIFJJU0NWX1BP V0VSX1NUQVRFIGZvciBhIHNwZWNpZmljIGhhcnRpZC4gVGhpcyB3aWxsIGhlbHAKPj4+IG1ha2UK Pj4+IGtleGVjIGxpa2UgZnVuY3Rpb25hbGl0eSBtb3JlIHJvYnVzdC4KPj4+IAo+PiAKPj4gSW5z dGVhZCBvZiB0aGUgYWJvdmUgSSBiZWxpZXZlIGl0IHdvdWxkIGJlIGNsZWFuZXIgYW5kIHNpbXBs ZXIgdG8gaGF2ZQo+PiBhbiBzYmlfZ2V0X2hhcnRfc3RhdGUgYW5kIGFuIHNiaV9zZXRfaGFydF9z dGF0ZSBjYWxsLiBUaGlzIHdheSB3ZSBjYW4KPj4gYmV0dGVyIGhhbmRsZSBzdGF0ZSB0cmFuc2l0 aW9ucyBhbmQsIGhhbmRsZSBPTi9PRkYvU1RBTkRCWS9SRVRFTlRJT04KPj4gYW5kIGFueSBvdGhl ciBzdGF0ZSB3ZSBjb21lIHVwIHdpdGgsIHdpdGhvdXQgYWRkaW5nIGV4dHJhIHNiaSBjYWxscy4K Pj4gCj4gCj4gV2hlbiBkbyB5b3Ugd2FudCB0byB1c2Ugc2JpX3NldF9oYXJ0X3N0YXRlID8KPiBU aGUgcG93ZXIgc3RhdGVzIHdpbGwgYmUgbW9kaWZpZWQgYXMgYSBwYXJ0IG9mIHNiaV9oYXJ0X2Rv d24gb3IKPiBzYmlfc2h1dGRvd24vc3VzcGVuZCBjYWxscyBhbnl3YXlzLgo+IAoKVGhlIGlkZWEg aXMgdG8gaGF2ZSBzYmlfc2V0X2hhcnRfc3RhdGUgaW5zdGVhZCBvZiAKc2JpX2hhcnRfZG93bi9z aHV0ZG93bi9zdXNwZW5kL2V0Yy4KSW5zdGVhZCBvZiBoYXZpbmcgZGlmZmVyZW50IGNhbGxzIGZv ciBkaWZmZXJlbnQgc3RhdGVzIHdlIGp1c3QgaGF2ZSB0d28gCmNhbGxzLCBvbmUKdG8gZ2V0IHRo ZSBzdGF0ZSBhbmQgb25lIHRvIHNldCBpdC4gVGhpcyB3YXkgd2UgaGF2ZSBmZXdlciBjYWxscyBh bmQgaWYgCndlIGFkZCBhCm5ldyBzdGF0ZSB3ZSBjYW4gYWRkIGl0IHdpdGhvdXQgaGF2aW5nIHRv IGFkZCBhIG5ldyBjYWxsLgoKPj4+IC0tIHZvaWQgc2JpX3N5c3RlbV9zaHV0ZG93bigpCj4+PiAK Pj4+IFBvd2VycyBvZmYgdGhlIGVudGlyZSBzeXN0ZW0uCj4+PiAKPj4gCj4+IERvbid0IHdlIGFs cmVhZHkgaGF2ZSB0aGF0ID8gV2hhdCdzIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4KPj4gc2JpX3N5 c3RlbV9zaHV0ZG93bgo+PiBhbmQgc2JpX3NodXRkb3duID8gRG9lcyBpdCBtYWtlIHNlbnNlIHRv IHVzZSBzYmlfc2h1dGRvd24gYW5kIGxlYXZlIAo+PiB0aGUKPj4gc3lzdGVtCj4+IG9uIHdpdGgg YWxsIHRoZSBoYXJ0cyBkb3duID8gTWF5YmUgd2UgY2FuIGp1c3Qgc2F5IHRoYXQgc2JpX3NodXRk b3duCj4+IGFsc28KPj4gcG93ZXJzIGRvd24gdGhlIHN5c3RlbSBhbmQgcmVuYW1lIGl0IHRvIHNi aV9zeXN0ZW1fc2h1dGRvd24gd2l0aCB0aGUKPj4gc2FtZQo+PiBmdW5jdGlvbiBJRC4KPj4gCj4g Cj4gWWVhaC4gVGhhdCdzIGEgYmV0dGVyLgo+IAo+IAo+Pj4gMy4gU0JJIEFQSSBJRCBudW1iZXJp bmcgc2NoZW1lOgo+Pj4gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCj4+PiBBbiBBUEkg U2V0IGlzIGEgc2V0IG9mIFNCSSBBUElzIHdoaWNoIGNvbGxlY3RpdmVseSBpbXBsZW1lbnQgc29t ZQo+Pj4ga2luZCBvZiBmZWF0dXJlL2Z1bmN0aW9uYWxpdHkuCj4+PiAKPj4+IExldCdzIHNheSBT QkkgQVBJIElEIGlzIHUzMiAgdGhlbgo+Pj4gQml0WzMxOjI0XSA9ICBBUEkgU2V0IE51bWJlcgo+ Pj4gQml0WzIzOjBdID0gQVBJIE51bWJlciB3aXRoaW4gQVBJIFNldAo+Pj4gCj4+PiBIZXJlIGFy ZSBmZXcgQVBJIFNldHMgZm9yIFNCSSB2MC4yOgo+Pj4gMS4gQmFzZSBBUElzCj4+PiBBUEkgU2V0 IE51bWJlcjogMHgwCj4+PiBEZXNjcmlwdGlvbjogQmFzZSBBUElzIG1hbmRhdG9yeSBmb3IgYW55 IFNCSSB2ZXJzaW9uCj4+PiAKPj4+IDIuIEhBUlQgUE0gQVBJcwo+Pj4gQVBJIFNldCBOdW1iZXI6 IDB4MQo+Pj4gRGVzY3JpcHRpb246IEhhcnQgVVAvRG93bi9TdXNwZW5kIEFQSXMgZm9yIHBlci1I YXJ0Cj4+PiBwb3dlciBtYW5hZ2VtZW50Cj4+PiAKPj4+IDMuIFN5c3RlbSBQTSBBUElzCj4+PiBB UEkgU2V0IE51bWJlcjsgMHgyCj4+PiBEZXNjcmlwdGlvbjogU3lzdGVtIFNodXRkb3duL1JlYm9v dC9TdXNwZW5kIGZvciBzeXN0ZW0tbGV2ZWwKPj4+IHBvd2VyIG1hbmFnZW1lbnQKPj4+IAo+Pj4g NC4gVmVuZG9yIEFQSXMKPj4+IEFQSSBTZXQgTnVtYmVyOiAweGZmCj4+PiBEZXNjcmlwdGlvbjog VmVuZG9yIHNwZWNpZmljIEFQSXMuCj4+PiBUaGVyZSBpcyBhIHBvc3NpYmlsaXR5IHRoYXQgZGlm ZmVyZW50IHZlbmRvcnMgY2FuIGNob29zZSB0byBhc3NpZ24KPj4+IHNhbWUgQVBJIG51bWJlcnMg Zm9yIGRpZmZlcmVudCBmdW5jdGlvbmFsaXR5LiBJbiB0aGF0IGNhc2UsIHZlbmRvcgo+Pj4gc3Bl Y2lmaWMgc3RyaW5ncyBpbiBEZXZpY2UgVHJlZSBjYW4gYmUgdXNlZCB0byB2ZXJpZnkgaWYgYSBz cGVjaWZpYwo+Pj4gQVBJIGJlbG9uZ3MgdG8gdGhlIGludGVuZGVkIHZlbmRvciBvciBub3QuCj4+ PiAKPj4gCj4+IEkgdW5kZXJzdGFuZCB0aGUgcmF0aW9uYWxlIGJlaGluZCB0aGlzIGJ1dCBJIGJl bGlldmUgaXQncyBiZXR0ZXIgdG8KPj4gY2FsbCB0aGVtIHNlcnZpY2VzIG9yIGZ1bmN0aW9ucyBp bnN0ZWFkIG9mIEFQSXMsIHRoZXkgYXJlIG5vdCBzZXRzCj4+IG9mIEFQSXMgdGhlIHdheSBJIHNl ZSBpdC4gQWxzbyBzaW5jZSB3ZSBhcmUgbW92aW5nIHRoYXQgcGF0aCB3aHkgY2FsbAo+PiBpdCBT QkkgYW5kIHJlc3RyaWN0IGl0IG9ubHkgdG8gYmUgdXNlZCBieSB0aGUgc3VwZXJ2aXNvciA/IEkn ZCBsb3ZlIHRvCj4+IGhhdmUgYW5vdGhlciBjYXRlZ29yeSBmb3IgdGhlIHNlY3VyZSBtb25pdG9y IGNhbGxzIGZvciBleGFtcGxlLAo+PiBidXQgb24gdGhlIHNvZnR3YXJlIGFyY2hpdGVjdHVyZSB0 aGF0IHdlIGFyZSBkaXNjdXNzaW5nIG9uIHRoZSBURUUKPj4gZ3JvdXAsIHN1Y2ggY2FsbHMgY2Fu IGFsc28gb3JpZ2luYXRlIGZyb20gVSBtb2RlIG9yIEhTL0hVIG1vZGVzLgo+PiBUaGUgc2FtZSBn b2VzIGZvciB2ZW5kb3Igc3BlY2lmaWMgY2FsbHMsIHRoZXJlIGFyZSBsb3RzIG9mIHVzZSBjYXNl Cj4+IHNjZW5hcmlvcyB3aGVyZSB2ZW5kb3JzIHdvdWxkIGxpa2UgdG8gYmUgYWJsZSB0byBjYWxs IHRoZWlyIHN0dWZmCj4+IGZyb20gVSBtb2RlIGZvciBleGFtcGxlIChlLmcuIGEgdXNlciBzcGFj ZSBsaWJyYXJ5IHRhbGtpbmcgdG8gYQo+PiBzbWFydCBjYXJkIGRpcmVjdGx5KS4KPj4gCj4+IEkg c3VnZ2VzdCB3ZSByZW5hbWUgaXQgZnJvbSBTQkkgdG8gc29tZXRoaW5nIG1vcmUgZ2VuZXJpYyB0 aGF0IGlzIG5vdAo+PiBkZWZpbmVkIGJ5IHdobyBpcyBjYWxsaW5nIGl0IGJ1dCBieSB3aGF0IHdl IGFyZSBjYWxsaW5nLCB3aGljaCBpbiB0aGlzCj4+IGNhc2UgaXMgdGhlIGZpcm13YXJlIChGQkk/ KS4KPiAKPiBwb3NzaWJsZSBjb25mbGljdCB3aXRoIGEgdmVyeSBmYW1vdXMgbGF3IGVuZm9yY2Vt ZW50IGFnZW5jeSA6KSA6KS4KPiAKPiBKb2tlcyBhc2lkZSwgcmVuYW1pbmcgdG8gc29tZXRoaW5n IG1vcmUgZ2VuZXJpYyBpcyBhIGdvb2QgaWRlYS4gQnV0IGl0Cj4gd2lsbCBwcm9iYWJseSBicmVh ayBhIHRvbiBvZiBkb2N1bWVudGF0aW9uL3NwZWMgaW4gUklTQy1WIHdoaWNoIEkKPiBkb24ndCB3 YW50IHRvIGRlYWwgd2l0aCByaWdodCBub3cuIE1heSBiZSBpbiBmdXR1cmUgdmVyc2lvbnMgPwo+ IAoKSSBnZXQgdGhhdCB1cGRhdGluZyB0aGUgZG9jdW1lbnRhdGlvbiBjYW4gYmUgYSBwYWluLCBJ IGNhbiBoZWxwIHdpdGgKdGhhdCBpZiB5b3Ugd2FudCAoYW5kIEkgcHJvbWlzZSBJJ2xsIHN0YXkg YXdheSBmcm9tIGxhdyBlbmZvcmNlbWVudAphZ2VuY2llcyAhKS4gSSBzdWdnZXN0IHdlIGRvIHRo ZSByZW5hbWluZyBhcyBlYXJseSBhcyBwb3NzaWJsZQpiZWNhdXNlIHdlIGFyZSBnb2luZyB0byBj YXJyeSBpdCBmb3IgYSBsb25nIHRpbWUgaW5zdGVhZCBhbmQgaXQnbGwKb25seSBnZXQgaGFyZGVy IHRvIGNoYW5nZSBsYXRlciBvbi4KCj4+IFNpbmNlIHlvdSBtZW50aW9uZWQgQVJNLCBpbiB0aGVp ciBjYXNlCj4+IHRoZSBBQkkgdXNlZCBmb3IgUFNDSSBpcyB0aGUgU2VjdXJlIE1vbml0b3IgQ2Fs bCAod2hpY2ggaXMgdGhlCj4+IGFsdGVybmF0aXZlCj4+IHRvIHdoYXQgaXMgZGVmaW5lZCBvbiB0 aGUgZmlyc3QgcGFyYWdyYXBoIG9mIHRoZSBTQkkgZG9jdW1lbnQpLCBidXQgaXQKPj4gaGFzIHRo ZSBzYW1lIGxpbWl0YXRpb24uIEFjY29yZGluZyB0byB0aGUgZG9jdW1lbnRhdGlvbiBpZiBhbiBT TUMgCj4+IGNvbWVzCj4+IGZyb20gYSB1c2VyIGFwcGxpY2F0aW9uLCB3ZSBnZXQgYW4gdW5kZWZp bmVkIGV4Y2VwdGlvbi4gV2UgY2FuIGRvIAo+PiBiZXR0ZXIKPj4gIQo+PiAKPiAKPiAKPiAKPj4g Cj4+PiA0LiBSZXR1cm4gZXJyb3IgY29kZSBUYWJsZToKPj4+IC0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLQo+Pj4gCj4+PiBIZXJlIGFyZSB0aGUgU0JJIHJldHVybiBlcnJvciBjb2RlcyBkZWZp bmVkLgo+Pj4gCj4+PiAgICAgICAgU0JJX1NVQ0NFU1MgICAgICAgICAgIDAKPj4+ICAgICAgICBT QklfTk9UX1NVUFBPUlRFRCAgICAtMQo+Pj4gICAgICAgIFNCSV9JTlZBTElEX1BBUkFNICAgIC0y Cj4+PiAgICAgICAgU0JJX0RFTklFRCAgICAgICAgICAgLTMKPj4+ICAgICAgICBTQklfSU5WQUxJ RF9BRERSRVNTICAtNAo+Pj4gCj4+PiBBIG1hcHBpbmcgZnVuY3Rpb24gYmV0d2VlbiBTQkkgZXJy b3IgY29kZSAmIExpbnV4IGVycm9yIGNvZGUgc2hvdWxkIAo+Pj4gYmUKPj4+IHByb3ZpZGVkLgo+ Pj4gCj4+IAo+PiBJIGJlbGlldmUgaXQgc2hvdWxkIGJlIHVwIHRvIHRoZSBPUyB0byB0cmFuc2xh dGUgdGhlIFNCSSBlcnJvciBjb2RlcyAKPj4gdG8KPj4gaXRzCj4+IG5hdGl2ZSBvbmVzLgo+PiAK PiAKPiBDb3JyZWN0LiBPbG9mIGFsc28gcG9pbnRlZCB0aGlzIG91dC4gSSB3aWxsIHJlbW92ZSBp dCBpbiBuZXh0IHZlcnNpb24uCj4gCj4+PiA1LiBQb3dlciBTdGF0ZQo+Pj4gLS0tLS0tLS0tLS0t LS0KPj4+IAo+Pj4gQSBSSVNDLVYgY29yZSBjYW4gZXhpc3QgaW4gYW55IG9mIHRoZSBmb2xsb3dp bmcgcG93ZXIgc3RhdGVzLgo+Pj4gCj4+PiBlbnVtIFJJU0NWX1BPV0VSX1NUQVRFIHsKPj4+ICAg ICAgICAgLy9Qb3dlcmVkIHVwICYgb3BlcmF0aW9uYWwuCj4+PiAgICAgICAgIFJJU0NWX0hBUlRf T04gICAgICAgICAgICAgID0gIDAsCj4+PiAgICAgICAgIC8vUG93ZXJlZCB1cCBidXQgYXQgcmVk dWNlZCBlbmVyZ3kgY29uc3VtcHRpb24uIFdGSSAKPj4+IGluc3RydWN0aW9uCj4+PiBjYW4gYmUg dXNlZCB0byBhY2hpZXZlIHRoaXMgc3RhdGUuCj4+PiAgICAgICAgIFJJU0NWX0hBUlRfU1RBTkRC WSAgICAgICAgPSAgIDEsCj4+PiAgICAgICAgIC8vRGVlcGVyIGxvdyBwb3dlciBzdGF0ZS4gTm8g cmVzZXQgcmVxdWlyZWQgYnV0IGhpZ2hlciB3YWtldXAKPj4+IGxhdGVuY3kuCj4+PiAgICAgICAg IFJJU0NWX0hBUlRfUkVURU5USU9OICAgICAgID0gIDIsCj4+PiAgICAgICAgIC8vUG93ZXJlZCBv ZmYuIFJlc2V0IG9mIHRoZSBjb3JlIHJlcXVpcmVkIGFmdGVyIHBvd2VyIAo+Pj4gcmVzdG9yZS4K Pj4+ICAgICAgICAgUklTQ1ZfSEFSVF9PRkYgICAgICAgICAgICAgPSAgMwo+Pj4gfQo+Pj4gCj4+ PiBUT0RPOgo+Pj4gQW55IG90aGVyIHBvd2VyIG1hbmFnZW1lbnQgcmVsYXRlZCBmZWF0dXJlcyBv ciBzdGF0ZT8KPj4+IAo+PiAKPj4gSG93IGFib3V0IExPQ0tTVEVQID8gV2UgY291bGQgaGF2ZSBh IHdheSBvZiBkZWNsYXJpbmcgYSBoYXJ0IGFzIGEKPj4gIm1pcnJvciIgb2YgYW5vdGhlcgo+PiBo YXJ0IChodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Mb2Nrc3RlcF8oY29tcHV0aW5nKSku IFdlIGNhbiBoYXZlCj4+IGFuIGV4dHJhIGFyZ3VtZW50Cj4+IG9uIHNiaV9nZXQvc2V0X3N0YXRl IHdoZW4gdGhlIExPQ0tTVEVQIHN0YXRlIGlzIHVzZWQsIHRoYXQgd2lsbCAKPj4gZ2V0L3NldAo+ PiB0aGUgaGFydCB0aGF0Cj4+IHRoaXMgaGFydCBpcyBtaXJyb3JpbmcuCj4+IAo+IAo+IE5vdCBz dXJlIGlmIHdlIG5lZWQgaXQgcmlnaHQgbm93LiBJIHdhbnQgdG8ga2VlcCBpdCBzaW1wbGUgYW5k IGZvY3VzCj4gb24gdGhlIGJhcmUgbWluaW11bSBvbmVzLiBXZSBjYW4gYWx3YXlzIGFkZCBleG90 aWMgb25lcyBvbmNlIHdlIGhhdmUKPiBmZWF0dXJlL3ZlcnNpb25pbmcgaW4gcGxhY2UuCj4gCgpJ IGFncmVlLCBJIG1lbnRpb25lZCBMT0NLU1RFUCBiZWNhdXNlIGl0J2xsIG5lZWQgYW4gZXh0cmEg YXJndW1lbnQKd2hlbiBzZXR0aW5nIHRoZSBzdGF0ZS4gQnR3IEkga25vdyBsb2Nrc3RlcCBzb3Vu ZHMgZXhvdGljIGF0IHRoaXMgcG9pbnQKYnV0IGl0J3MgbmVlZGVkIGJ5IG1hbnkgaW5kdXN0cmll cyB0aGF0IGRlYWwgd2l0aCBzYWZldHkgKGF1dG9tb3RpdmUgCnN0dWZmLAptZWRpY2FsIGRldmlj ZXMgZXRjKS4gSG93ZXZlciBpdCBuZWVkcyBtb3JlIHRoaW5raW5nLgoKPj4+IDYuIEltcGxlbWVu dGF0aW9uCj4+PiAtLS0tLS0tLS0tLS0tLS0tLS0tCj4+PiBDdXJyZW50bHksIFNCSSBpcyBpbXBs ZW1lbnRlZCBhcyBhIHBhcnQgb2YgQkJMLiBUaGVyZSBpcyBhIGRpZmZlcmVudAo+Pj4gU0JJIGlt cGxlbWVudGF0aW9uIGF2YWlsYWJsZSBpbiBjb3JlYm9vdCBhcyB3ZWxsLgo+Pj4gCj4+PiBBbHRl cm5hdGl2ZWx5LCBhIHNlcGFyYXRlIG9wZW4gQlNEL01JVCBsaWNlbnNlZCBTQkkgcHJvamVjdCBj YW4gYmUKPj4+IGNyZWF0ZWQgd2hpY2ggY2FuIGJlIHVzZWQgYnkgYW55Ym9keSB0byBhdm9pZCB0 aGVzZSBraW5kIG9mIFNCSQo+Pj4gZnJhZ21lbnRhdGlvbiBpbiBmdXR1cmUuIFRoaXMgcHJvamVj dCBjYW4gZ2VuZXJhdGUgYm90aCBhIGZpcm13YXJlCj4+PiBiaW5hcnkgKHRvIGV4ZWN1dGVkIGRp cmVjdGx5IGluIE0gbW9kZSkgb3IgYSBzdGF0aWMgbGlicmFyeSB0aGF0IGNhbgo+Pj4gYmUgdXNl ZCBieSBkaWZmZXJlbnQgYm9vdCBsb2FkZXJzLiBJdCB3aWxsIGFsc28gaGVscCBpbmRpdmlkdWFs IGJvb3QKPj4+IGxvYWRlcnMgdG8gZWl0aGVyIHdvcmsgZnJvbSBNIG9yIFMgbW9kZSB3aXRob3V0 IGEgc2VwYXJhdGUgU0JJCj4+PiBpbXBsZW1lbnRhdGlvbi4KPj4+IAo+PiAKPj4gV2h5IGltcGxl bWVudCB0aGlzIGF0IHRoZSBib290IGxvYWRlciBsZXZlbCA/IFRoaXMgaXMgbW9yZSBsaWtlIGEK Pj4gZmlybXdhcmUgaW50ZXJmYWNlCj4+IHRoYW4gc29tZXRoaW5nIHRoYXQgYmVsb25ncyB0byB0 aGUgYm9vdGxvYWRlci4gVGhlIGJvb3Rsb2FkZXIgc2hvdWxkIAo+PiB1c2UKPj4gdGhpcyBpbnRl cmZhY2UKPj4gbm90IHByb3ZpZGUgaXQuCj4gSXQgZGVwZW5kcyBvbiB0aGUgYm9vdGxvYWRlci4g Rm9yIGV4YW1wbGUsIHRoZXJlIGFyZSBwYXRjaGVzIGluCj4gY29yZWJvb3QgdGhhdCBpbXBsZW1l bnRzIFNCSS4gVGhlIGlkZWEgd2l0aCBPcGVuU0JJIGltcGxlbWVudGF0aW9uIGlzCj4gdG8gYXZv aWQgc3VjaCBmcmFnbWVudGF0aW9uLgo+IAo+PiBBbHNvIHRoaXMgaXMgc29tZXRoaW5nIHRoYXQg YmVsb25ncyB0byB0aGUgTSBtb2RlLCBhCj4+IGJvb3Rsb2FkZXIKPj4gc2hvdWxkIGJlbG9uZyB0 byB0aGUgUyBtb2RlLCBydW5uaW5nIHRoZSBib290bG9hZGVyIGluIE0gbW9kZSBpcyBub3QKPj4g cmlnaHQgZnJvbQo+PiBhIHNlY3VyaXR5IHBvaW50IG9mIHZpZXcuIFdlIGNhbiBwcm92aWRlIHNv bWV0aGluZyBsaWtlICJSSVNDLVYgCj4+IEZpcm13YXJlCj4+IFNlcnZpY2VzIgo+PiB0aGF0J3Mg Y29kZSBydW5uaW5nIG9uIE0gbW9kZSBhZnRlciB0aGUgZmlyc3Qgc3RhZ2UgYm9vdCAKPj4gbG9h ZGVyL0Jvb3RST00KPj4gYW5kIGxldAo+PiBib290bG9hZGVycyB1c2UgaXQgd2l0aG91dCBoYXZp bmcgdG8gaW1wbGVtZW50IGl0Lgo+IAo+IFRoYXQncyB0aGUgaWRlYSBmb3IgUyBtb2RlIGJvb3Rs b2FkZXJzLiBIb3dldmVyLCB0aGVyZSBhcmUgZm9sa3Mgd2hvCj4gYXJlIGludGVyZXN0ZWQgaW4g TSBtb2RlIG9uZXMgYW5kIEkgdW5kZXJzdGFuZCB0aGVpciB1c2VjYXNlLiBUaHVzLAo+IGlkZWEg aXMgdG8gaW1wbGVtZW50IE9wZW5TQkkgaW4gc3VjaCBhIHdheSB0aGF0LCBldmVyeWJvZHkgY2Fu IG1ha2UKPiB1c2Ugb2YgaXQuCj4gCgpJIGd1ZXNzIHRoZW4gd2UgY2FuIHByb3ZpZGUgaXQgYXMg YSBsaWJyYXJ5IGFuZCBhbHNvIHByb3ZpZGUgYSByZWZlcmVuY2UKaW1wbGVtZW50YXRpb24gYXJv dW5kIGl0LiBIb3dldmVyIEkgc3RpbGwgYmVsaWV2ZSB0aGF0IHNvbWV0aGluZyBsaWtlCiJSSVND LVYgRmlybXdhcmUgU2VydmljZXMiIGlzIG1vcmUgYXBwcm9wcmlhdGUsIHdlIGNhbiBzdHJ1Y3R1 cmUgdGhpcwppbiBhIGNsaWVudC9zZXJ2ZXIgd2F5IGFuZCBsZXQgYm9vdGxvYWRlcnMgdXNlIHRo ZSBzZXJ2ZXIgcGFydCBhbmQKT1MgZHJpdmVycy9tb2R1bGVzIHVzZSB0aGUgY2xpZW50IHBhcnQu IFRoaXMgd2F5IHdlIGNhbiBhbHNvIGF2b2lkCmZyYWdtZW50YXRpb24gYWNyb3NzIE9TZXMuCgpS ZWdhcmRzLApOaWNrCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fXwpsaW51eC1yaXNjdiBtYWlsaW5nIGxpc3QKbGludXgtcmlzY3ZAbGlzdHMuaW5mcmFkZWFk Lm9yZwpodHRwOi8vbGlzdHMuaW5mcmFkZWFkLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xpbnV4LXJp c2N2Cg==