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=-4.0 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SIGNED_OFF_BY,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 7CE27C43381 for ; Fri, 29 Mar 2019 07:02:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2C1B82173C for ; Fri, 29 Mar 2019 07:02:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=nifty.com header.i=@nifty.com header.b="eWWDI9tS" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728825AbfC2HCx (ORCPT ); Fri, 29 Mar 2019 03:02:53 -0400 Received: from conssluserg-03.nifty.com ([210.131.2.82]:28218 "EHLO conssluserg-03.nifty.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728719AbfC2HCx (ORCPT ); Fri, 29 Mar 2019 03:02:53 -0400 Received: from mail-vs1-f51.google.com (mail-vs1-f51.google.com [209.85.217.51]) (authenticated) by conssluserg-03.nifty.com with ESMTP id x2T72aB3010461 for ; Fri, 29 Mar 2019 16:02:37 +0900 DKIM-Filter: OpenDKIM Filter v2.10.3 conssluserg-03.nifty.com x2T72aB3010461 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nifty.com; s=dec2015msa; t=1553842957; bh=Ruq2JIDk5dGxA9NJovtSIj+mgyV4C+T1XepbEFuu4z4=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=eWWDI9tSVm7NLtfnt4SxEesW8mBp28eGszdf5sFwa0baskaynZgl5gUZwV0Xbmu6P XC7tTK8FnE9K3LK87sQ73a9zEA8EaVy5He9s0X5hh2uG+yGSAU8XwClwHtSFEyN5Gt 08opxjas5gdYnYPgeTdQlOabxWWowUMZufKKO539Tz86x815ChbMIvVynuvuvFxVxa VgsBz+N+4bamwlPmNeCr7Rl/VYrT2XkU4RMnirelX5qcQfhu9zDnozOWCLaiPjpkRv eImqcaLuZgKiFXZK5J6otkZFz9Wy+yP+CwW9ocDm12kzpJKZT8CCqq8l0PJ3ndRbzq 5ZYZ1z9jTc9HQ== X-Nifty-SrcIP: [209.85.217.51] Received: by mail-vs1-f51.google.com with SMTP id s2so707998vsi.5 for ; Fri, 29 Mar 2019 00:02:37 -0700 (PDT) X-Gm-Message-State: APjAAAVlMRIgFANTIcNS7ncSmvkWIp1U26cKBNLNALWutoeQnv4ZQcXu u/pKnkreztZ80kVwPqe4ejqYWIAJOz0z6aYDPAc= X-Google-Smtp-Source: APXvYqzfUKI/WMYrkEEPnhaevPwvGhKTSTCm/EJIWVjLC6VaiP/KYjZ+Kydg/okhrnLn6fe/+8eFD4mE2YqOfYQB4wA= X-Received: by 2002:a67:7a43:: with SMTP id v64mr28921483vsc.54.1553842956015; Fri, 29 Mar 2019 00:02:36 -0700 (PDT) MIME-Version: 1.0 References: <1552380290-19951-1-git-send-email-yamada.masahiro@socionext.com> <1552380290-19951-3-git-send-email-yamada.masahiro@socionext.com> <20190312112811.1af0bb00@xps13> <20190312115425.612bcdf2@xps13> <20190312141327.31c6af3f@xps13> <20190315093429.35137adb@xps13> In-Reply-To: <20190315093429.35137adb@xps13> From: Masahiro Yamada Date: Fri, 29 Mar 2019 16:02:00 +0900 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: [PATCH v3 2/9] mtd: rawnand: denali: refactor syndrome layout handling for raw access To: Miquel Raynal Cc: Boris Brezillon , Richard Weinberger , Linux Kernel Mailing List , Marek Vasut , linux-mtd , Brian Norris , David Woodhouse Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Miquel, On Fri, Mar 15, 2019 at 5:34 PM Miquel Raynal w= rote: > > Hi Masahiro, > > Masahiro Yamada wrote on Thu, 14 Mar > 2019 17:24:41 +0900: > > > Hi Miquel, > > > > On Tue, Mar 12, 2019 at 10:13 PM Miquel Raynal > > wrote: > > > > > > Hi Masahiro, > > > > > > Masahiro Yamada wrote on Tue, 12 Mar > > > 2019 20:07:27 +0900: > > > > > > > Hi Miquel, > > > > > > > > > > > > On Tue, Mar 12, 2019 at 7:54 PM Miquel Raynal wrote: > > > > > > > > > > Hi Masahiro, > > > > > > > > > > Masahiro Yamada wrote on Tue, 12 = Mar > > > > > 2019 19:51:21 +0900: > > > > > > > > > > > On Tue, Mar 12, 2019 at 7:28 PM Miquel Raynal wrote: > > > > > > > > > > > > > > Hi Masahiro, > > > > > > > > > > > > > > Masahiro Yamada wrote on Tue,= 12 Mar > > > > > > > 2019 17:44:43 +0900: > > > > > > > > > > > > > > > The Denali IP adopts the syndrome page layout (payload and = ECC are > > > > > > > > interleaved). The *_page_raw() and *_oob() callbacks are co= mplicated > > > > > > > > because they must hide the underlying layout used by the ha= rdware, > > > > > > > > and always return contiguous in-band and out-of-band data. > > > > > > > > > > > > > > > > Currently, similar code is duplicated to reorganize the dat= a layout. > > > > > > > > For example, denali_read_page_raw() and denali_write_page_r= aw() look > > > > > > > > almost the same. > > > > > > > > > > > > > > > > The idea for refactoring is to split the code into two part= s: > > > > > > > > [1] conversion of page layout > > > > > > > > [2] what to do at every ECC chunk boundary > > > > > > > > > > > > > > > > For [1], I wrote denali_raw_payload_op() and denali_raw_oob= _op(). > > > > > > > > They manipulate data for the Denali controller's specific p= age layout > > > > > > > > of in-band, out-of-band, respectively. > > > > > > > > > > > > > > > > The difference between write and read is just the operation= at > > > > > > > > ECC chunk boundaries. For example, denali_read_oob() calls > > > > > > > > nand_change_read_column_op(), whereas denali_write_oob() ca= lls > > > > > > > > nand_change_write_column_op(). So, I implemented [2] as a c= allback > > > > > > > > passed into [1]. > > > > > > > > > > > > > > > > Signed-off-by: Masahiro Yamada > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > [...] > > > > > > > > > > > > > > > static int denali_read_page_raw(struct nand_chip *chip, ui= nt8_t *buf, > > > > > > > > int oob_required, int page) > > > > > > > > { > > > > > > > > + struct denali_nand_info *denali =3D to_denali(chip); > > > > > > > > struct mtd_info *mtd =3D nand_to_mtd(chip); > > > > > > > > - struct denali_nand_info *denali =3D mtd_to_denali(mtd= ); > > > > > > > > - int writesize =3D mtd->writesize; > > > > > > > > - int oobsize =3D mtd->oobsize; > > > > > > > > - int ecc_steps =3D chip->ecc.steps; > > > > > > > > - int ecc_size =3D chip->ecc.size; > > > > > > > > - int ecc_bytes =3D chip->ecc.bytes; > > > > > > > > void *tmp_buf =3D denali->buf; > > > > > > > > - int oob_skip =3D denali->oob_skip_bytes; > > > > > > > > - size_t size =3D writesize + oobsize; > > > > > > > > - int ret, i, pos, len; > > > > > > > > + size_t size =3D mtd->writesize + mtd->oobsize; > > > > > > > > + int ret; > > > > > > > > + > > > > > > > > + if (!buf) > > > > > > > > + return -EINVAL; > > > > > > > > > > > > > > > > ret =3D denali_data_xfer(chip, tmp_buf, size, page, 1= , 0); > > > > > > > > if (ret) > > > > > > > > return ret; > > > > > > > > > > > > > > > > - /* Arrange the buffer for syndrome payload/ecc layout= */ > > > > > > > > - if (buf) { > > > > > > > > - for (i =3D 0; i < ecc_steps; i++) { > > > > > > > > - pos =3D i * (ecc_size + ecc_bytes); > > > > > > > > - len =3D ecc_size; > > > > > > > > - > > > > > > > > - if (pos >=3D writesize) > > > > > > > > - pos +=3D oob_skip; > > > > > > > > - else if (pos + len > writesize) > > > > > > > > - len =3D writesize - pos; > > > > > > > > - > > > > > > > > - memcpy(buf, tmp_buf + pos, len); > > > > > > > > - buf +=3D len; > > > > > > > > - if (len < ecc_size) { > > > > > > > > - len =3D ecc_size - len; > > > > > > > > - memcpy(buf, tmp_buf + writesi= ze + oob_skip, > > > > > > > > - len); > > > > > > > > - buf +=3D len; > > > > > > > > - } > > > > > > > > - } > > > > > > > > - } > > > > > > > > + ret =3D denali_raw_payload_op(chip, buf, denali_memcp= y_in, tmp_buf); > > > > > > > > > > > > > > Honestly, I still don't like passing denali_memcpy_in/out as = parameter. > > > > > > > > > > > > > > Besides that, once you'll have added helpers to avoid abusing= the > > > > > > > ternary operator in 4/9, the rest looks fine by me. > > > > > > > > > > > > > > > > > > > > > > > > > Do you have any suggestion? > > > > > > > > > > Maybe register these two helpers at probe as controller specific = hooks, > > > > > then just pass an in/out boolean to the function? > > > > > > > > > > > > > Sorry, I do not understand. > > > > > > > > Are you suggesting to do like follows in probe ? > > > > > > > > denali->change_column_read_raw =3D denali_memcpy_in; > > > > denali->change_column_write_raw =3D denali_memcpy_out; > > > > denali->change_column_read_oob =3D denali_change_read_column_op; > > > > denali->change_column_write_oob =3D denali_change_write_column_op; > > > > > > > > > > > > All the 4 hooks are always needed > > > > regardless of any probed features. > > > > > > > > > > > > The result is just textual replacement > > > > denali_* with denali->*. > > > > > > > > What's the point of copying fixed function addresses > > > > to denali structure? > > > > > > > > > > > > > > What I don't like is the function pointer as a function parameter. > > > > This is a usual way to handle callback. > > > > > You > > > can use the functions defined statically if you prefer as long as the > > > parameter is just a boolean for instance? > > > > > > > > I still do not understand your concern, > > but if you ban the use of function pointer, > > the following is the best I can do > > since there are 4 hooks depending on the > > combination of oob/raw, write/read. > > > > > > > > if (oob) { > > if (write) > > return nand_change_write_column_op(chip, offset, buf, > > len, false); > > else > > return nand_change_read_column_op(chip, offset, buf, > > len, false); > > } > > > > if (write) > > memcpy(denali->buf + offset, buf, len); > > else > > memcpy(buf, denali->buf + offset, len); > > > > return 0; > > No, I meant passing a boolean to denali_raw_payload_op() instead of a > function pointer. Then from denali_raw_payload_op(), intead of doing > > ret =3D cb(); > if (ret) > ... > > doing: > > if (read) > ret =3D denali_memcpy_in() > else > ret =3D denali_memcpy_out() > > if (ret) > ... If you look at my code closely, you will notice 4 callbacks passed in denali_raw_payload_op(). So, if-conditional would end up like follows: if (oob) { if (write) ret =3D nand_change_write_column_op(chip, offset, buf, len, false); else ret =3D nand_change_read_column_op(chip, offset, buf, len, false); if (ret) return ret; } else { if (write) memcpy(denali->buf + offset, buf, len); else memcpy(buf, denali->buf + offset, len); } This is extremely ugly. That's why I passed a function pointer instead of two boolean parameters 'oob', 'write'. > But nevermind, if this is bothering you too much let's keep the current > form, it's fine. > > > > > > > BTW, when are .read_page_raw / .write_page_raw used? > > I'm not sure what is the question here but these hooks are important > and allow to test the driver. nandbiterrs use them (although we do > not care about the performance in these hooks). Currently, I use DMA transfer + memcpy() in order to get better performance for .read_page_raw() and .write_page_raw() nand_change_write_column_op() and nand_change_read_column_op() are slow since they are low-level hardware accesses. If we do not have to care about the performance, I will only use nand_change_{write,read}_column_op(). > > > > Currently, I use "whole page access && memcpy" for better performance. > > > > If those hooks are rarely used, I use > > nand_change_write_column_op / nand_change_read_column_op, > > which will reduce the if-conditional. > > Yes you can. We do not care about performance in raw accessors. OK, I will do this in v4. > Thanks, > Miqu=C3=A8l > > ______________________________________________________ > Linux MTD discussion mailing list > http://lists.infradead.org/mailman/listinfo/linux-mtd/ --=20 Best Regards Masahiro Yamada 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=-4.0 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SIGNED_OFF_BY, 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 92CF3C43381 for ; Fri, 29 Mar 2019 07:03:13 +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 5F7002173C for ; Fri, 29 Mar 2019 07:03:13 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="tytu+Php"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=nifty.com header.i=@nifty.com header.b="eWWDI9tS" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5F7002173C Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=socionext.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-mtd-bounces+linux-mtd=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-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:To:Subject:Message-ID:Date:From: In-Reply-To:References:MIME-Version:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=drSCzxgNmQzU6g4YZEBOqcRuYzT4+bDAHAq982ChPMk=; b=tytu+PhpjhWoWo cVng7cNrP7X7flpEz/cHWxXPU48mA1h51n5l/fYoWb3EGe7Z1zN5dGINmKTKTduHPNRhRwg7HdcUD pgCYebeEqhR4RoDWR3vHOlZ612VD894VfmeD4hk6cgzt+D794R9vsHblBsqpc0zXD3Q2lCWVVjnIy I3MEvSX+42uNONT9LrzGqLuTRJUxtKpF8mdSVilQE2M9TwBcgrwh7CTnlGRDxrEUMZjztMDwHk5fw kOBPv9PtK9kji+OONOLETxHK7YUo+F7SMscnJDuiY61QecWjKe92dVUk/KqkkPiZufkc8NOfyRfol XmJCWuD6PaljVHcmhoMw==; 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 1h9lXi-0003wM-Ay; Fri, 29 Mar 2019 07:03:10 +0000 Received: from conssluserg-04.nifty.com ([210.131.2.83]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1h9lXd-0003vm-Nq for linux-mtd@lists.infradead.org; Fri, 29 Mar 2019 07:03:08 +0000 Received: from mail-vs1-f43.google.com (mail-vs1-f43.google.com [209.85.217.43]) (authenticated) by conssluserg-04.nifty.com with ESMTP id x2T72ai7028017 for ; Fri, 29 Mar 2019 16:02:37 +0900 DKIM-Filter: OpenDKIM Filter v2.10.3 conssluserg-04.nifty.com x2T72ai7028017 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nifty.com; s=dec2015msa; t=1553842957; bh=Ruq2JIDk5dGxA9NJovtSIj+mgyV4C+T1XepbEFuu4z4=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=eWWDI9tSVm7NLtfnt4SxEesW8mBp28eGszdf5sFwa0baskaynZgl5gUZwV0Xbmu6P XC7tTK8FnE9K3LK87sQ73a9zEA8EaVy5He9s0X5hh2uG+yGSAU8XwClwHtSFEyN5Gt 08opxjas5gdYnYPgeTdQlOabxWWowUMZufKKO539Tz86x815ChbMIvVynuvuvFxVxa VgsBz+N+4bamwlPmNeCr7Rl/VYrT2XkU4RMnirelX5qcQfhu9zDnozOWCLaiPjpkRv eImqcaLuZgKiFXZK5J6otkZFz9Wy+yP+CwW9ocDm12kzpJKZT8CCqq8l0PJ3ndRbzq 5ZYZ1z9jTc9HQ== X-Nifty-SrcIP: [209.85.217.43] Received: by mail-vs1-f43.google.com with SMTP id d8so228230vsp.2 for ; Fri, 29 Mar 2019 00:02:37 -0700 (PDT) X-Gm-Message-State: APjAAAWJ2sVqzcC7Yy0N3WwDBO1fY2XYZJtgFjRgL1awuCSUVb2n7RPV cikqgkTHPv+0RzYGdrdkgPzADi/XhzSd2bTUx2A= X-Google-Smtp-Source: APXvYqzfUKI/WMYrkEEPnhaevPwvGhKTSTCm/EJIWVjLC6VaiP/KYjZ+Kydg/okhrnLn6fe/+8eFD4mE2YqOfYQB4wA= X-Received: by 2002:a67:7a43:: with SMTP id v64mr28921483vsc.54.1553842956015; Fri, 29 Mar 2019 00:02:36 -0700 (PDT) MIME-Version: 1.0 References: <1552380290-19951-1-git-send-email-yamada.masahiro@socionext.com> <1552380290-19951-3-git-send-email-yamada.masahiro@socionext.com> <20190312112811.1af0bb00@xps13> <20190312115425.612bcdf2@xps13> <20190312141327.31c6af3f@xps13> <20190315093429.35137adb@xps13> In-Reply-To: <20190315093429.35137adb@xps13> From: Masahiro Yamada Date: Fri, 29 Mar 2019 16:02:00 +0900 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: [PATCH v3 2/9] mtd: rawnand: denali: refactor syndrome layout handling for raw access To: Miquel Raynal X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190329_000306_132686_2532D73D X-CRM114-Status: GOOD ( 37.95 ) X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Boris Brezillon , Richard Weinberger , Linux Kernel Mailing List , Marek Vasut , linux-mtd , Brian Norris , David Woodhouse Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+linux-mtd=archiver.kernel.org@lists.infradead.org SGkgTWlxdWVsLAoKCk9uIEZyaSwgTWFyIDE1LCAyMDE5IGF0IDU6MzQgUE0gTWlxdWVsIFJheW5h bCA8bWlxdWVsLnJheW5hbEBib290bGluLmNvbT4gd3JvdGU6Cj4KPiBIaSBNYXNhaGlybywKPgo+ IE1hc2FoaXJvIFlhbWFkYSA8eWFtYWRhLm1hc2FoaXJvQHNvY2lvbmV4dC5jb20+IHdyb3RlIG9u IFRodSwgMTQgTWFyCj4gMjAxOSAxNzoyNDo0MSArMDkwMDoKPgo+ID4gSGkgTWlxdWVsLAo+ID4K PiA+IE9uIFR1ZSwgTWFyIDEyLCAyMDE5IGF0IDEwOjEzIFBNIE1pcXVlbCBSYXluYWwKPiA+IDxt aXF1ZWwucmF5bmFsQGJvb3RsaW4uY29tPiB3cm90ZToKPiA+ID4KPiA+ID4gSGkgTWFzYWhpcm8s Cj4gPiA+Cj4gPiA+IE1hc2FoaXJvIFlhbWFkYSA8eWFtYWRhLm1hc2FoaXJvQHNvY2lvbmV4dC5j b20+IHdyb3RlIG9uIFR1ZSwgMTIgTWFyCj4gPiA+IDIwMTkgMjA6MDc6MjcgKzA5MDA6Cj4gPiA+ Cj4gPiA+ID4gSGkgTWlxdWVsLAo+ID4gPiA+Cj4gPiA+ID4KPiA+ID4gPiBPbiBUdWUsIE1hciAx MiwgMjAxOSBhdCA3OjU0IFBNIE1pcXVlbCBSYXluYWwgPG1pcXVlbC5yYXluYWxAYm9vdGxpbi5j b20+IHdyb3RlOgo+ID4gPiA+ID4KPiA+ID4gPiA+IEhpIE1hc2FoaXJvLAo+ID4gPiA+ID4KPiA+ ID4gPiA+IE1hc2FoaXJvIFlhbWFkYSA8eWFtYWRhLm1hc2FoaXJvQHNvY2lvbmV4dC5jb20+IHdy b3RlIG9uIFR1ZSwgMTIgTWFyCj4gPiA+ID4gPiAyMDE5IDE5OjUxOjIxICswOTAwOgo+ID4gPiA+ ID4KPiA+ID4gPiA+ID4gT24gVHVlLCBNYXIgMTIsIDIwMTkgYXQgNzoyOCBQTSBNaXF1ZWwgUmF5 bmFsIDxtaXF1ZWwucmF5bmFsQGJvb3RsaW4uY29tPiB3cm90ZToKPiA+ID4gPiA+ID4gPgo+ID4g PiA+ID4gPiA+IEhpIE1hc2FoaXJvLAo+ID4gPiA+ID4gPiA+Cj4gPiA+ID4gPiA+ID4gTWFzYWhp cm8gWWFtYWRhIDx5YW1hZGEubWFzYWhpcm9Ac29jaW9uZXh0LmNvbT4gd3JvdGUgb24gVHVlLCAx MiBNYXIKPiA+ID4gPiA+ID4gPiAyMDE5IDE3OjQ0OjQzICswOTAwOgo+ID4gPiA+ID4gPiA+Cj4g PiA+ID4gPiA+ID4gPiBUaGUgRGVuYWxpIElQIGFkb3B0cyB0aGUgc3luZHJvbWUgcGFnZSBsYXlv dXQgKHBheWxvYWQgYW5kIEVDQyBhcmUKPiA+ID4gPiA+ID4gPiA+IGludGVybGVhdmVkKS4gVGhl ICpfcGFnZV9yYXcoKSBhbmQgKl9vb2IoKSBjYWxsYmFja3MgYXJlIGNvbXBsaWNhdGVkCj4gPiA+ ID4gPiA+ID4gPiBiZWNhdXNlIHRoZXkgbXVzdCBoaWRlIHRoZSB1bmRlcmx5aW5nIGxheW91dCB1 c2VkIGJ5IHRoZSBoYXJkd2FyZSwKPiA+ID4gPiA+ID4gPiA+IGFuZCBhbHdheXMgcmV0dXJuIGNv bnRpZ3VvdXMgaW4tYmFuZCBhbmQgb3V0LW9mLWJhbmQgZGF0YS4KPiA+ID4gPiA+ID4gPiA+Cj4g PiA+ID4gPiA+ID4gPiBDdXJyZW50bHksIHNpbWlsYXIgY29kZSBpcyBkdXBsaWNhdGVkIHRvIHJl b3JnYW5pemUgdGhlIGRhdGEgbGF5b3V0Lgo+ID4gPiA+ID4gPiA+ID4gRm9yIGV4YW1wbGUsIGRl bmFsaV9yZWFkX3BhZ2VfcmF3KCkgYW5kIGRlbmFsaV93cml0ZV9wYWdlX3JhdygpIGxvb2sKPiA+ ID4gPiA+ID4gPiA+IGFsbW9zdCB0aGUgc2FtZS4KPiA+ID4gPiA+ID4gPiA+Cj4gPiA+ID4gPiA+ ID4gPiBUaGUgaWRlYSBmb3IgcmVmYWN0b3JpbmcgaXMgdG8gc3BsaXQgdGhlIGNvZGUgaW50byB0 d28gcGFydHM6Cj4gPiA+ID4gPiA+ID4gPiAgIFsxXSBjb252ZXJzaW9uIG9mIHBhZ2UgbGF5b3V0 Cj4gPiA+ID4gPiA+ID4gPiAgIFsyXSB3aGF0IHRvIGRvIGF0IGV2ZXJ5IEVDQyBjaHVuayBib3Vu ZGFyeQo+ID4gPiA+ID4gPiA+ID4KPiA+ID4gPiA+ID4gPiA+IEZvciBbMV0sIEkgd3JvdGUgZGVu YWxpX3Jhd19wYXlsb2FkX29wKCkgYW5kIGRlbmFsaV9yYXdfb29iX29wKCkuCj4gPiA+ID4gPiA+ ID4gPiBUaGV5IG1hbmlwdWxhdGUgZGF0YSBmb3IgdGhlIERlbmFsaSBjb250cm9sbGVyJ3Mgc3Bl Y2lmaWMgcGFnZSBsYXlvdXQKPiA+ID4gPiA+ID4gPiA+IG9mIGluLWJhbmQsIG91dC1vZi1iYW5k LCByZXNwZWN0aXZlbHkuCj4gPiA+ID4gPiA+ID4gPgo+ID4gPiA+ID4gPiA+ID4gVGhlIGRpZmZl cmVuY2UgYmV0d2VlbiB3cml0ZSBhbmQgcmVhZCBpcyBqdXN0IHRoZSBvcGVyYXRpb24gYXQKPiA+ ID4gPiA+ID4gPiA+IEVDQyBjaHVuayBib3VuZGFyaWVzLiBGb3IgZXhhbXBsZSwgZGVuYWxpX3Jl YWRfb29iKCkgY2FsbHMKPiA+ID4gPiA+ID4gPiA+IG5hbmRfY2hhbmdlX3JlYWRfY29sdW1uX29w KCksIHdoZXJlYXMgZGVuYWxpX3dyaXRlX29vYigpIGNhbGxzCj4gPiA+ID4gPiA+ID4gPiBuYW5k X2NoYW5nZV93cml0ZV9jb2x1bW5fb3AoKS4gU28sIEkgaW1wbGVtZW50ZWQgWzJdIGFzIGEgY2Fs bGJhY2sKPiA+ID4gPiA+ID4gPiA+IHBhc3NlZCBpbnRvIFsxXS4KPiA+ID4gPiA+ID4gPiA+Cj4g PiA+ID4gPiA+ID4gPiBTaWduZWQtb2ZmLWJ5OiBNYXNhaGlybyBZYW1hZGEgPHlhbWFkYS5tYXNh aGlyb0Bzb2Npb25leHQuY29tPgo+ID4gPiA+ID4gPiA+ID4gLS0tCj4gPiA+ID4gPiA+ID4gPgo+ ID4gPiA+ID4gPiA+Cj4gPiA+ID4gPiA+ID4gWy4uLl0KPiA+ID4gPiA+ID4gPgo+ID4gPiA+ID4g PiA+ID4gIHN0YXRpYyBpbnQgZGVuYWxpX3JlYWRfcGFnZV9yYXcoc3RydWN0IG5hbmRfY2hpcCAq Y2hpcCwgdWludDhfdCAqYnVmLAo+ID4gPiA+ID4gPiA+ID4gICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgaW50IG9vYl9yZXF1aXJlZCwgaW50IHBhZ2UpCj4gPiA+ID4gPiA+ID4gPiAgewo+ ID4gPiA+ID4gPiA+ID4gKyAgICAgc3RydWN0IGRlbmFsaV9uYW5kX2luZm8gKmRlbmFsaSA9IHRv X2RlbmFsaShjaGlwKTsKPiA+ID4gPiA+ID4gPiA+ICAgICAgIHN0cnVjdCBtdGRfaW5mbyAqbXRk ID0gbmFuZF90b19tdGQoY2hpcCk7Cj4gPiA+ID4gPiA+ID4gPiAtICAgICBzdHJ1Y3QgZGVuYWxp X25hbmRfaW5mbyAqZGVuYWxpID0gbXRkX3RvX2RlbmFsaShtdGQpOwo+ID4gPiA+ID4gPiA+ID4g LSAgICAgaW50IHdyaXRlc2l6ZSA9IG10ZC0+d3JpdGVzaXplOwo+ID4gPiA+ID4gPiA+ID4gLSAg ICAgaW50IG9vYnNpemUgPSBtdGQtPm9vYnNpemU7Cj4gPiA+ID4gPiA+ID4gPiAtICAgICBpbnQg ZWNjX3N0ZXBzID0gY2hpcC0+ZWNjLnN0ZXBzOwo+ID4gPiA+ID4gPiA+ID4gLSAgICAgaW50IGVj Y19zaXplID0gY2hpcC0+ZWNjLnNpemU7Cj4gPiA+ID4gPiA+ID4gPiAtICAgICBpbnQgZWNjX2J5 dGVzID0gY2hpcC0+ZWNjLmJ5dGVzOwo+ID4gPiA+ID4gPiA+ID4gICAgICAgdm9pZCAqdG1wX2J1 ZiA9IGRlbmFsaS0+YnVmOwo+ID4gPiA+ID4gPiA+ID4gLSAgICAgaW50IG9vYl9za2lwID0gZGVu YWxpLT5vb2Jfc2tpcF9ieXRlczsKPiA+ID4gPiA+ID4gPiA+IC0gICAgIHNpemVfdCBzaXplID0g d3JpdGVzaXplICsgb29ic2l6ZTsKPiA+ID4gPiA+ID4gPiA+IC0gICAgIGludCByZXQsIGksIHBv cywgbGVuOwo+ID4gPiA+ID4gPiA+ID4gKyAgICAgc2l6ZV90IHNpemUgPSBtdGQtPndyaXRlc2l6 ZSArIG10ZC0+b29ic2l6ZTsKPiA+ID4gPiA+ID4gPiA+ICsgICAgIGludCByZXQ7Cj4gPiA+ID4g PiA+ID4gPiArCj4gPiA+ID4gPiA+ID4gPiArICAgICBpZiAoIWJ1ZikKPiA+ID4gPiA+ID4gPiA+ ICsgICAgICAgICAgICAgcmV0dXJuIC1FSU5WQUw7Cj4gPiA+ID4gPiA+ID4gPgo+ID4gPiA+ID4g PiA+ID4gICAgICAgcmV0ID0gZGVuYWxpX2RhdGFfeGZlcihjaGlwLCB0bXBfYnVmLCBzaXplLCBw YWdlLCAxLCAwKTsKPiA+ID4gPiA+ID4gPiA+ICAgICAgIGlmIChyZXQpCj4gPiA+ID4gPiA+ID4g PiAgICAgICAgICAgICAgIHJldHVybiByZXQ7Cj4gPiA+ID4gPiA+ID4gPgo+ID4gPiA+ID4gPiA+ ID4gLSAgICAgLyogQXJyYW5nZSB0aGUgYnVmZmVyIGZvciBzeW5kcm9tZSBwYXlsb2FkL2VjYyBs YXlvdXQgKi8KPiA+ID4gPiA+ID4gPiA+IC0gICAgIGlmIChidWYpIHsKPiA+ID4gPiA+ID4gPiA+ IC0gICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGVjY19zdGVwczsgaSsrKSB7Cj4gPiA+ID4g PiA+ID4gPiAtICAgICAgICAgICAgICAgICAgICAgcG9zID0gaSAqIChlY2Nfc2l6ZSArIGVjY19i eXRlcyk7Cj4gPiA+ID4gPiA+ID4gPiAtICAgICAgICAgICAgICAgICAgICAgbGVuID0gZWNjX3Np emU7Cj4gPiA+ID4gPiA+ID4gPiAtCj4gPiA+ID4gPiA+ID4gPiAtICAgICAgICAgICAgICAgICAg ICAgaWYgKHBvcyA+PSB3cml0ZXNpemUpCj4gPiA+ID4gPiA+ID4gPiAtICAgICAgICAgICAgICAg ICAgICAgICAgICAgICBwb3MgKz0gb29iX3NraXA7Cj4gPiA+ID4gPiA+ID4gPiAtICAgICAgICAg ICAgICAgICAgICAgZWxzZSBpZiAocG9zICsgbGVuID4gd3JpdGVzaXplKQo+ID4gPiA+ID4gPiA+ ID4gLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVuID0gd3JpdGVzaXplIC0gcG9zOwo+ ID4gPiA+ID4gPiA+ID4gLQo+ID4gPiA+ID4gPiA+ID4gLSAgICAgICAgICAgICAgICAgICAgIG1l bWNweShidWYsIHRtcF9idWYgKyBwb3MsIGxlbik7Cj4gPiA+ID4gPiA+ID4gPiAtICAgICAgICAg ICAgICAgICAgICAgYnVmICs9IGxlbjsKPiA+ID4gPiA+ID4gPiA+IC0gICAgICAgICAgICAgICAg ICAgICBpZiAobGVuIDwgZWNjX3NpemUpIHsKPiA+ID4gPiA+ID4gPiA+IC0gICAgICAgICAgICAg ICAgICAgICAgICAgICAgIGxlbiA9IGVjY19zaXplIC0gbGVuOwo+ID4gPiA+ID4gPiA+ID4gLSAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVtY3B5KGJ1ZiwgdG1wX2J1ZiArIHdyaXRlc2l6 ZSArIG9vYl9za2lwLAo+ID4gPiA+ID4gPiA+ID4gLSAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgIGxlbik7Cj4gPiA+ID4gPiA+ID4gPiAtICAgICAgICAgICAgICAgICAgICAgICAg ICAgICBidWYgKz0gbGVuOwo+ID4gPiA+ID4gPiA+ID4gLSAgICAgICAgICAgICAgICAgICAgIH0K PiA+ID4gPiA+ID4gPiA+IC0gICAgICAgICAgICAgfQo+ID4gPiA+ID4gPiA+ID4gLSAgICAgfQo+ ID4gPiA+ID4gPiA+ID4gKyAgICAgcmV0ID0gZGVuYWxpX3Jhd19wYXlsb2FkX29wKGNoaXAsIGJ1 ZiwgZGVuYWxpX21lbWNweV9pbiwgdG1wX2J1Zik7Cj4gPiA+ID4gPiA+ID4KPiA+ID4gPiA+ID4g PiBIb25lc3RseSwgSSBzdGlsbCBkb24ndCBsaWtlIHBhc3NpbmcgZGVuYWxpX21lbWNweV9pbi9v dXQgYXMgcGFyYW1ldGVyLgo+ID4gPiA+ID4gPiA+Cj4gPiA+ID4gPiA+ID4gQmVzaWRlcyB0aGF0 LCBvbmNlIHlvdSdsbCBoYXZlIGFkZGVkIGhlbHBlcnMgdG8gYXZvaWQgYWJ1c2luZyB0aGUKPiA+ ID4gPiA+ID4gPiB0ZXJuYXJ5IG9wZXJhdG9yIGluIDQvOSwgdGhlIHJlc3QgbG9va3MgZmluZSBi eSBtZS4KPiA+ID4gPiA+ID4gPgo+ID4gPiA+ID4gPgo+ID4gPiA+ID4gPgo+ID4gPiA+ID4gPiBE byB5b3UgaGF2ZSBhbnkgc3VnZ2VzdGlvbj8KPiA+ID4gPiA+Cj4gPiA+ID4gPiBNYXliZSByZWdp c3RlciB0aGVzZSB0d28gaGVscGVycyBhdCBwcm9iZSBhcyBjb250cm9sbGVyIHNwZWNpZmljIGhv b2tzLAo+ID4gPiA+ID4gdGhlbiBqdXN0IHBhc3MgYW4gaW4vb3V0IGJvb2xlYW4gdG8gdGhlIGZ1 bmN0aW9uPwo+ID4gPiA+ID4KPiA+ID4gPgo+ID4gPiA+IFNvcnJ5LCBJIGRvIG5vdCB1bmRlcnN0 YW5kLgo+ID4gPiA+Cj4gPiA+ID4gQXJlIHlvdSBzdWdnZXN0aW5nIHRvIGRvIGxpa2UgZm9sbG93 cyBpbiBwcm9iZSA/Cj4gPiA+ID4KPiA+ID4gPiBkZW5hbGktPmNoYW5nZV9jb2x1bW5fcmVhZF9y YXcgPSBkZW5hbGlfbWVtY3B5X2luOwo+ID4gPiA+IGRlbmFsaS0+Y2hhbmdlX2NvbHVtbl93cml0 ZV9yYXcgPSBkZW5hbGlfbWVtY3B5X291dDsKPiA+ID4gPiBkZW5hbGktPmNoYW5nZV9jb2x1bW5f cmVhZF9vb2IgPSBkZW5hbGlfY2hhbmdlX3JlYWRfY29sdW1uX29wOwo+ID4gPiA+IGRlbmFsaS0+ Y2hhbmdlX2NvbHVtbl93cml0ZV9vb2IgPSBkZW5hbGlfY2hhbmdlX3dyaXRlX2NvbHVtbl9vcDsK PiA+ID4gPgo+ID4gPiA+Cj4gPiA+ID4gQWxsIHRoZSA0IGhvb2tzIGFyZSBhbHdheXMgbmVlZGVk Cj4gPiA+ID4gcmVnYXJkbGVzcyBvZiBhbnkgcHJvYmVkIGZlYXR1cmVzLgo+ID4gPiA+Cj4gPiA+ ID4KPiA+ID4gPiBUaGUgcmVzdWx0IGlzIGp1c3QgdGV4dHVhbCByZXBsYWNlbWVudAo+ID4gPiA+ IGRlbmFsaV8qIHdpdGggZGVuYWxpLT4qLgo+ID4gPiA+Cj4gPiA+ID4gV2hhdCdzIHRoZSBwb2lu dCBvZiBjb3B5aW5nIGZpeGVkIGZ1bmN0aW9uIGFkZHJlc3Nlcwo+ID4gPiA+IHRvIGRlbmFsaSBz dHJ1Y3R1cmU/Cj4gPiA+ID4KPiA+ID4gPgo+ID4gPgo+ID4gPiBXaGF0IEkgZG9uJ3QgbGlrZSBp cyB0aGUgZnVuY3Rpb24gcG9pbnRlciBhcyBhIGZ1bmN0aW9uIHBhcmFtZXRlci4KPiA+Cj4gPiBU aGlzIGlzIGEgdXN1YWwgd2F5IHRvIGhhbmRsZSBjYWxsYmFjay4KPiA+Cj4gPiA+IFlvdQo+ID4g PiBjYW4gdXNlIHRoZSBmdW5jdGlvbnMgZGVmaW5lZCBzdGF0aWNhbGx5IGlmIHlvdSBwcmVmZXIg YXMgbG9uZyBhcyB0aGUKPiA+ID4gcGFyYW1ldGVyIGlzIGp1c3QgYSBib29sZWFuIGZvciBpbnN0 YW5jZT8KPiA+Cj4gPgo+ID4KPiA+IEkgc3RpbGwgZG8gbm90IHVuZGVyc3RhbmQgeW91ciBjb25j ZXJuLAo+ID4gYnV0IGlmIHlvdSBiYW4gdGhlIHVzZSBvZiBmdW5jdGlvbiBwb2ludGVyLAo+ID4g dGhlIGZvbGxvd2luZyBpcyB0aGUgYmVzdCBJIGNhbiBkbwo+ID4gc2luY2UgdGhlcmUgYXJlIDQg aG9va3MgZGVwZW5kaW5nIG9uIHRoZQo+ID4gY29tYmluYXRpb24gb2Ygb29iL3Jhdywgd3JpdGUv cmVhZC4KPiA+Cj4gPgo+ID4KPiA+IGlmIChvb2IpIHsKPiA+ICAgICAgICAgaWYgKHdyaXRlKQo+ ID4gICAgICAgICAgICAgICAgIHJldHVybiBuYW5kX2NoYW5nZV93cml0ZV9jb2x1bW5fb3AoY2hp cCwgb2Zmc2V0LCBidWYsCj4gPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICBsZW4sIGZhbHNlKTsKPiA+ICAgICAgICAgZWxzZQo+ID4gICAgICAgICAg ICAgICAgIHJldHVybiBuYW5kX2NoYW5nZV9yZWFkX2NvbHVtbl9vcChjaGlwLCBvZmZzZXQsIGJ1 ZiwKPiA+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg bGVuLCBmYWxzZSk7Cj4gPiB9Cj4gPgo+ID4gaWYgKHdyaXRlKQo+ID4gICAgICAgICBtZW1jcHko ZGVuYWxpLT5idWYgKyBvZmZzZXQsIGJ1ZiwgbGVuKTsKPiA+IGVsc2UKPiA+ICAgICAgICAgbWVt Y3B5KGJ1ZiwgZGVuYWxpLT5idWYgKyBvZmZzZXQsIGxlbik7Cj4gPgo+ID4gcmV0dXJuIDA7Cj4K PiBObywgSSBtZWFudCBwYXNzaW5nIGEgYm9vbGVhbiB0byBkZW5hbGlfcmF3X3BheWxvYWRfb3Ao KSBpbnN0ZWFkIG9mIGEKPiBmdW5jdGlvbiBwb2ludGVyLiBUaGVuIGZyb20gZGVuYWxpX3Jhd19w YXlsb2FkX29wKCksIGludGVhZCBvZiBkb2luZwo+Cj4gcmV0ID0gY2IoKTsKPiBpZiAocmV0KQo+ ICAgICAgICAgLi4uCj4KPiBkb2luZzoKPgo+IGlmIChyZWFkKQo+ICAgICAgICAgcmV0ID0gZGVu YWxpX21lbWNweV9pbigpCj4gZWxzZQo+ICAgICAgICAgcmV0ID0gZGVuYWxpX21lbWNweV9vdXQo KQo+Cj4gaWYgKHJldCkKPiAgICAgICAgIC4uLgoKCklmIHlvdSBsb29rIGF0IG15IGNvZGUgY2xv c2VseSwKeW91IHdpbGwgbm90aWNlIDQgY2FsbGJhY2tzIHBhc3NlZCBpbgpkZW5hbGlfcmF3X3Bh eWxvYWRfb3AoKS4KClNvLCBpZi1jb25kaXRpb25hbCB3b3VsZCBlbmQgdXAgbGlrZSBmb2xsb3dz OgoKCiAgICBpZiAob29iKSB7CiAgICAgICAgICAgIGlmICh3cml0ZSkKICAgICAgICAgICAgICAg ICAgICByZXQgPSBuYW5kX2NoYW5nZV93cml0ZV9jb2x1bW5fb3AoY2hpcCwgb2Zmc2V0LCBidWYs CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbiwg ZmFsc2UpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgcmV0ID0gbmFuZF9j aGFuZ2VfcmVhZF9jb2x1bW5fb3AoY2hpcCwgb2Zmc2V0LCBidWYsCiAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVuLCBmYWxzZSk7CiAgICAgICAgICAg IGlmIChyZXQpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgICB9IGVsc2Ugewog ICAgICAgICAgICBpZiAod3JpdGUpCiAgICAgICAgICAgICAgICAgIG1lbWNweShkZW5hbGktPmJ1 ZiArIG9mZnNldCwgYnVmLCBsZW4pOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAg IG1lbWNweShidWYsIGRlbmFsaS0+YnVmICsgb2Zmc2V0LCBsZW4pOwogICAgIH0KCgpUaGlzIGlz IGV4dHJlbWVseSB1Z2x5LgpUaGF0J3Mgd2h5IEkgcGFzc2VkIGEgZnVuY3Rpb24gcG9pbnRlcgpp bnN0ZWFkIG9mIHR3byBib29sZWFuIHBhcmFtZXRlcnMgJ29vYicsICd3cml0ZScuCgoKCgo+IEJ1 dCBuZXZlcm1pbmQsIGlmIHRoaXMgaXMgYm90aGVyaW5nIHlvdSB0b28gbXVjaCBsZXQncyBrZWVw IHRoZSBjdXJyZW50Cj4gZm9ybSwgaXQncyBmaW5lLgo+Cj4gPgo+ID4KPiA+IEJUVywgd2hlbiBh cmUgLnJlYWRfcGFnZV9yYXcgLyAud3JpdGVfcGFnZV9yYXcgdXNlZD8KPgo+IEknbSBub3Qgc3Vy ZSB3aGF0IGlzIHRoZSBxdWVzdGlvbiBoZXJlIGJ1dCB0aGVzZSBob29rcyBhcmUgaW1wb3J0YW50 Cj4gYW5kIGFsbG93IHRvIHRlc3QgdGhlIGRyaXZlci4gbmFuZGJpdGVycnMgdXNlIHRoZW0gKGFs dGhvdWdoIHdlIGRvCj4gbm90IGNhcmUgYWJvdXQgdGhlIHBlcmZvcm1hbmNlIGluIHRoZXNlIGhv b2tzKS4KCgpDdXJyZW50bHksIEkgdXNlIERNQSB0cmFuc2ZlciArIG1lbWNweSgpCmluIG9yZGVy IHRvIGdldCBiZXR0ZXIgcGVyZm9ybWFuY2UgZm9yCi5yZWFkX3BhZ2VfcmF3KCkgYW5kIC53cml0 ZV9wYWdlX3JhdygpCgoKbmFuZF9jaGFuZ2Vfd3JpdGVfY29sdW1uX29wKCkgYW5kCm5hbmRfY2hh bmdlX3JlYWRfY29sdW1uX29wKCkgYXJlIHNsb3cKc2luY2UgdGhleSBhcmUgbG93LWxldmVsIGhh cmR3YXJlIGFjY2Vzc2VzLgoKCklmIHdlIGRvIG5vdCBoYXZlIHRvIGNhcmUgYWJvdXQgdGhlIHBl cmZvcm1hbmNlLApJIHdpbGwgb25seSB1c2UgbmFuZF9jaGFuZ2Vfe3dyaXRlLHJlYWR9X2NvbHVt bl9vcCgpLgoKCgoKPiA+Cj4gPiBDdXJyZW50bHksIEkgdXNlICJ3aG9sZSBwYWdlIGFjY2VzcyAm JiBtZW1jcHkiIGZvciBiZXR0ZXIgcGVyZm9ybWFuY2UuCj4gPgo+ID4gSWYgdGhvc2UgaG9va3Mg YXJlIHJhcmVseSB1c2VkLCBJIHVzZQo+ID4gbmFuZF9jaGFuZ2Vfd3JpdGVfY29sdW1uX29wIC8g bmFuZF9jaGFuZ2VfcmVhZF9jb2x1bW5fb3AsCj4gPiB3aGljaCB3aWxsIHJlZHVjZSB0aGUgaWYt Y29uZGl0aW9uYWwuCj4KPiBZZXMgeW91IGNhbi4gV2UgZG8gbm90IGNhcmUgYWJvdXQgcGVyZm9y bWFuY2UgaW4gcmF3IGFjY2Vzc29ycy4KCk9LLCBJIHdpbGwgZG8gdGhpcyBpbiB2NC4KCgoKCj4g VGhhbmtzLAo+IE1pcXXDqGwKPgo+IF9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fXwo+IExpbnV4IE1URCBkaXNjdXNzaW9uIG1haWxpbmcgbGlzdAo+ IGh0dHA6Ly9saXN0cy5pbmZyYWRlYWQub3JnL21haWxtYW4vbGlzdGluZm8vbGludXgtbXRkLwoK CgotLSAKQmVzdCBSZWdhcmRzCk1hc2FoaXJvIFlhbWFkYQoKX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCkxpbnV4IE1URCBkaXNjdXNzaW9uIG1h aWxpbmcgbGlzdApodHRwOi8vbGlzdHMuaW5mcmFkZWFkLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xp bnV4LW10ZC8K