GNU bug report logs - #46456
[core-updates] d3.v5.js source checksum changed

Please note: This is a static page, with minimal formatting, updated once a day.
Click here to see this page with the latest information and nicer formatting.

Package: guix; Reported by: Danny Milosavljevic <dannym@HIDDEN>; dated Fri, 12 Feb 2021 03:54:01 UTC; Maintainer for guix is bug-guix@HIDDEN.

Message received at 46456 <at> debbugs.gnu.org:


Received: (at 46456) by debbugs.gnu.org; 12 Feb 2021 20:24:48 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Fri Feb 12 15:24:48 2021
Received: from localhost ([127.0.0.1]:33071 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1lAezf-0002PJ-Tg
	for submit <at> debbugs.gnu.org; Fri, 12 Feb 2021 15:24:48 -0500
Received: from sender4-of-o51.zoho.com ([136.143.188.51]:21116)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <rekado@HIDDEN>) id 1lAezc-0002Ow-Jj
 for 46456 <at> debbugs.gnu.org; Fri, 12 Feb 2021 15:24:44 -0500
ARC-Seal: i=1; a=rsa-sha256; t=1613161477; cv=none; 
 d=zohomail.com; s=zohoarc; 
 b=NMTnLZdb+yJg/nrO3BbsKmQD0plafWgYQ5Zgd0FAR6rs1UuRzs5L8dFZaFWhSZ/H2bb96Alzk8rLHqTP8QWwtwNpcyJOKR4CJAbetbiOxKqAdwfC+KXAFre2qcesK4YYQgRupGkbeAEjv+9IBwqZ8BYabl20csFmfkuBVjWEesU=
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com;
 s=zohoarc; t=1613161477;
 h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:To;
 bh=FW9S8YXNgbhjqdg/UC+HTtVVdSNrqJN6Nys+3sd7svc=; 
 b=Y+0UdSegzI9ayVp998RFyr64z/CMTbdtlOrvHMl1j5d3u/LFdy/e4JeYQqP56W0EdTzzpaEUGHoYUrEVRYwDMUfJ7bEK7+5C4ClR5/6ty4/FMpgwr60TDjQDmWOqgK3hOOvTzQazsCFnYtEBk+cC9zwddR2TJbbODgILYqrWcBU=
ARC-Authentication-Results: i=1; mx.zohomail.com;
 dkim=pass  header.i=elephly.net;
 spf=pass  smtp.mailfrom=rekado@HIDDEN;
 dmarc=pass header.from=<rekado@HIDDEN> header.from=<rekado@HIDDEN>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1613161477; 
 s=zoho; d=elephly.net; i=rekado@HIDDEN;
 h=References:From:To:Cc:Subject:In-reply-to:Date:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding;
 bh=FW9S8YXNgbhjqdg/UC+HTtVVdSNrqJN6Nys+3sd7svc=;
 b=MUbUal5gLqQ3gkmpQWPGaezkcDmF87/If36K+5PIMHzpS4DTLKrIg/kqJwtQhK03
 Mc+k1m2zqgKdqiGO36UihNnnPGCICMNJeN5ZLUHneQiXQEKFQdcbAwvqwNRHazri8tn
 q/H49RHglV6aK4JCOff7xV6ZjlBEp5DObAV2ZtZw=
Received: from localhost (p54ad4ba3.dip0.t-ipconnect.de [84.173.75.163]) by
 mx.zohomail.com with SMTPS id 1613161474329566.5760788480368;
 Fri, 12 Feb 2021 12:24:34 -0800 (PST)
References: <20210212045315.3f4e0a82@HIDDEN>
 <YCbFnrqhGN69A73L@HIDDEN>
User-agent: mu4e 1.4.14; emacs 27.1
From: Ricardo Wurmus <rekado@HIDDEN>
To: Leo Famulari <leo@HIDDEN>
Subject: Re: bug#46456: [core-updates] d3.v5.js source checksum changed
In-reply-to: <YCbFnrqhGN69A73L@HIDDEN>
X-URL: https://elephly.net
X-PGP-Key: https://elephly.net/rekado.pubkey
X-PGP-Fingerprint: BCA6 89B6 3655 3801 C3C6  2150 197A 5888 235F ACAC
Date: Fri, 12 Feb 2021 21:24:30 +0100
Message-ID: <87pn15owzl.fsf@HIDDEN>
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-ZohoMailClient: External
X-Spam-Score: 0.0 (/)
X-Debbugs-Envelope-To: 46456
Cc: 46456 <at> debbugs.gnu.org, Danny Milosavljevic <dannym@HIDDEN>,
 bug-guix@HIDDEN
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)


Leo Famulari <leo@HIDDEN> writes:

> On Fri, Feb 12, 2021 at 04:53:15AM +0100, Danny Milosavljevic wrote:
>> Starting download of /gnu/store/bf496ni94ik19gdxkgp0vddkfxbid2vf-d3.v5.js
>> From https://d3js.org/d3.v5.js...
>> downloading from https://d3js.org/d3.v5.js ...
>>  d3.v5.js                                                               =
                                                   2.22GiB/s 00:00 | 504KiB=
 transferred
>> sha256 hash mismatch for /gnu/store/bf496ni94ik19gdxkgp0vddkfxbid2vf-d3.=
v5.js:
>>   expected hash: 0kxvx5pfagxn6nhavdwsdnzyd26g0z5dsfi1pi5dvcmb0c8ipcdn
>
> Attached.

I guess we can=E2=80=99t use this URL then.  This is just for the latest mi=
nor
version for major version 5.  We use similar d3 URLs for the other major
versions.

--=20
Ricardo




Information forwarded to bug-guix@HIDDEN:
bug#46456; Package guix. Full text available.

Message received at submit <at> debbugs.gnu.org:


Received: (at submit) by debbugs.gnu.org; 12 Feb 2021 20:24:47 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Fri Feb 12 15:24:46 2021
Received: from localhost ([127.0.0.1]:33069 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1lAeze-0002PA-Jq
	for submit <at> debbugs.gnu.org; Fri, 12 Feb 2021 15:24:46 -0500
Received: from lists.gnu.org ([209.51.188.17]:38528)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <rekado@HIDDEN>) id 1lAezb-0002Ox-R2
 for submit <at> debbugs.gnu.org; Fri, 12 Feb 2021 15:24:44 -0500
Received: from eggs.gnu.org ([2001:470:142:3::10]:60056)
 by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.90_1) (envelope-from <rekado@HIDDEN>)
 id 1lAezb-00064U-FS
 for bug-guix@HIDDEN; Fri, 12 Feb 2021 15:24:43 -0500
Received: from sender4-of-o51.zoho.com ([136.143.188.51]:21114)
 by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.90_1) (envelope-from <rekado@HIDDEN>)
 id 1lAezZ-0007I7-GE
 for bug-guix@HIDDEN; Fri, 12 Feb 2021 15:24:43 -0500
ARC-Seal: i=1; a=rsa-sha256; t=1613161477; cv=none; 
 d=zohomail.com; s=zohoarc; 
 b=NMTnLZdb+yJg/nrO3BbsKmQD0plafWgYQ5Zgd0FAR6rs1UuRzs5L8dFZaFWhSZ/H2bb96Alzk8rLHqTP8QWwtwNpcyJOKR4CJAbetbiOxKqAdwfC+KXAFre2qcesK4YYQgRupGkbeAEjv+9IBwqZ8BYabl20csFmfkuBVjWEesU=
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com;
 s=zohoarc; t=1613161477;
 h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:To;
 bh=FW9S8YXNgbhjqdg/UC+HTtVVdSNrqJN6Nys+3sd7svc=; 
 b=Y+0UdSegzI9ayVp998RFyr64z/CMTbdtlOrvHMl1j5d3u/LFdy/e4JeYQqP56W0EdTzzpaEUGHoYUrEVRYwDMUfJ7bEK7+5C4ClR5/6ty4/FMpgwr60TDjQDmWOqgK3hOOvTzQazsCFnYtEBk+cC9zwddR2TJbbODgILYqrWcBU=
ARC-Authentication-Results: i=1; mx.zohomail.com;
 dkim=pass  header.i=elephly.net;
 spf=pass  smtp.mailfrom=rekado@HIDDEN;
 dmarc=pass header.from=<rekado@HIDDEN> header.from=<rekado@HIDDEN>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1613161477; 
 s=zoho; d=elephly.net; i=rekado@HIDDEN;
 h=References:From:To:Cc:Subject:In-reply-to:Date:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding;
 bh=FW9S8YXNgbhjqdg/UC+HTtVVdSNrqJN6Nys+3sd7svc=;
 b=MUbUal5gLqQ3gkmpQWPGaezkcDmF87/If36K+5PIMHzpS4DTLKrIg/kqJwtQhK03
 Mc+k1m2zqgKdqiGO36UihNnnPGCICMNJeN5ZLUHneQiXQEKFQdcbAwvqwNRHazri8tn
 q/H49RHglV6aK4JCOff7xV6ZjlBEp5DObAV2ZtZw=
Received: from localhost (p54ad4ba3.dip0.t-ipconnect.de [84.173.75.163]) by
 mx.zohomail.com with SMTPS id 1613161474329566.5760788480368;
 Fri, 12 Feb 2021 12:24:34 -0800 (PST)
References: <20210212045315.3f4e0a82@HIDDEN>
 <YCbFnrqhGN69A73L@HIDDEN>
User-agent: mu4e 1.4.14; emacs 27.1
From: Ricardo Wurmus <rekado@HIDDEN>
To: Leo Famulari <leo@HIDDEN>
Subject: Re: bug#46456: [core-updates] d3.v5.js source checksum changed
In-reply-to: <YCbFnrqhGN69A73L@HIDDEN>
X-URL: https://elephly.net
X-PGP-Key: https://elephly.net/rekado.pubkey
X-PGP-Fingerprint: BCA6 89B6 3655 3801 C3C6  2150 197A 5888 235F ACAC
Date: Fri, 12 Feb 2021 21:24:30 +0100
Message-ID: <87pn15owzl.fsf@HIDDEN>
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-ZohoMailClient: External
Received-SPF: pass client-ip=136.143.188.51; envelope-from=rekado@HIDDEN;
 helo=sender4-of-o51.zoho.com
X-Spam_score_int: -20
X-Spam_score: -2.1
X-Spam_bar: --
X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1,
 DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,
 RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001,
 SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no
X-Spam_action: no action
X-Spam-Score: -1.3 (-)
X-Debbugs-Envelope-To: submit
Cc: 46456 <at> debbugs.gnu.org, Danny Milosavljevic <dannym@HIDDEN>,
 bug-guix@HIDDEN
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -2.3 (--)


Leo Famulari <leo@HIDDEN> writes:

> On Fri, Feb 12, 2021 at 04:53:15AM +0100, Danny Milosavljevic wrote:
>> Starting download of /gnu/store/bf496ni94ik19gdxkgp0vddkfxbid2vf-d3.v5.js
>> From https://d3js.org/d3.v5.js...
>> downloading from https://d3js.org/d3.v5.js ...
>>  d3.v5.js                                                               =
                                                   2.22GiB/s 00:00 | 504KiB=
 transferred
>> sha256 hash mismatch for /gnu/store/bf496ni94ik19gdxkgp0vddkfxbid2vf-d3.=
v5.js:
>>   expected hash: 0kxvx5pfagxn6nhavdwsdnzyd26g0z5dsfi1pi5dvcmb0c8ipcdn
>
> Attached.

I guess we can=E2=80=99t use this URL then.  This is just for the latest mi=
nor
version for major version 5.  We use similar d3 URLs for the other major
versions.

--=20
Ricardo




Information forwarded to bug-guix@HIDDEN:
bug#46456; Package guix. Full text available.

Message received at 46456 <at> debbugs.gnu.org:


Received: (at 46456) by debbugs.gnu.org; 12 Feb 2021 18:15:03 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Fri Feb 12 13:15:03 2021
Received: from localhost ([127.0.0.1]:32935 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1lAcy7-0007le-MR
	for submit <at> debbugs.gnu.org; Fri, 12 Feb 2021 13:15:03 -0500
Received: from out2-smtp.messagingengine.com ([66.111.4.26]:60545)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <leo@HIDDEN>) id 1lAcy6-0007kn-C3
 for 46456 <at> debbugs.gnu.org; Fri, 12 Feb 2021 13:15:02 -0500
Received: from compute3.internal (compute3.nyi.internal [10.202.2.43])
 by mailout.nyi.internal (Postfix) with ESMTP id 52EB95C019B;
 Fri, 12 Feb 2021 13:14:57 -0500 (EST)
Received: from mailfrontend1 ([10.202.2.162])
 by compute3.internal (MEProxy); Fri, 12 Feb 2021 13:14:57 -0500
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=famulari.name;
 h=date:from:to:cc:subject:message-id:references:mime-version
 :content-type:in-reply-to; s=mesmtp; bh=/wPYSHu+JUj1o5MiaXbRO00C
 7DY+vJkSA8w2+42RRYk=; b=mcH7TFDb5SswUQE/ciQdVPra9lBlhRuAMNSUqRxX
 b+ic9KRn23b/Ng67oAfkhsRMs789vEc/NquW1IoDjIzS7KmH7KSy4xbjj54VpINz
 0wkDkzB1hL/JX5ddVCSxtuZ3KoZmC4SyB+k5VPEXnkYiPC1PG/4ZNJD+cXIdlX3q
 BzA=
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=
 messagingengine.com; h=cc:content-type:date:from:in-reply-to
 :message-id:mime-version:references:subject:to:x-me-proxy
 :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm2; bh=/wPYSH
 u+JUj1o5MiaXbRO00C7DY+vJkSA8w2+42RRYk=; b=LK0vaZEvW7BQIcRfRZCEpM
 lbp+VlAJm0PgtpSgwi0qllzlG5+OiKCVUgsMGWZabN02Xz1ROzFuViSSX2Zd6xbc
 wjgFpeLJTp3CdL4oR9G9VIQ0EOHBOCIj88Cqu4IR1+g5PnGPIlDgCcrcWNbxWJ5m
 SAnGHCauwGyyPn0vC5NlsOqU6gnPCv/dF8djKiTNTzhtmy425YHd9wbPp4/w5ZT2
 wTv/kcVyqGWitYiAoq0dNdS1wYCiR0gbXclPkf/VDsOU7PzLvSWcqQO7Kp9/Wbh2
 wBmyE8t/STj+Dlre8F+YBT59OU2y891kcB6zTh8uozgN0BwFIHeknlxyfstihpGA
 ==
X-ME-Sender: <xms:oMUmYDTEVjbzy4zApGvsotcmpB2wmx8EfLu8ojQwCDrwwRbRnIRZUw>
 <xme:oMUmYExeHldqaOWET_L-dsqmo29pIU1VNtA9JezsC-cKfCQEtD2KxWuMf9g0JqdDi
 4HdIDmHGjpeUWUHCQ>
X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduledriedugdduudegucetufdoteggodetrfdotf
 fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen
 uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne
 cujfgurhepfffhvffukfhfgggtuggjsehgtderredttddvnecuhfhrohhmpefnvghoucfh
 rghmuhhlrghrihcuoehlvghosehfrghmuhhlrghrihdrnhgrmhgvqeenucggtffrrghtth
 gvrhhnpeetvedtffdtgfeuieelhefguefgleefjeevgfeivdefheelleffhfeftdeggfel
 teenucffohhmrghinhepugefjhhsrdhorhhgnecukfhppedutddtrdduuddrudeiledrud
 dukeenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehl
 vghosehfrghmuhhlrghrihdrnhgrmhgv
X-ME-Proxy: <xmx:oMUmYI3GFi7FmTJmdAVNgeRJYaMLr4-is6bZ10a8y-KefVqu-o6uHQ>
 <xmx:oMUmYDCk9Kowk5bu5ytL3qJ9AhRdlpyQXqr35o_ccy_9m4F5Ms0w0Q>
 <xmx:oMUmYMjMMM6OmCK8DI6vutfHFjO5VaGPLqwJeaoVxYvkmXm2Srdj9w>
 <xmx:ocUmYKeOO1xSNm5LedNtq2g7A7y1sc-0i_S8tcHPwCB7HRhQmb55bw>
Received: from localhost (pool-100-11-169-118.phlapa.fios.verizon.net
 [100.11.169.118])
 by mail.messagingengine.com (Postfix) with ESMTPA id EF86424005A;
 Fri, 12 Feb 2021 13:14:55 -0500 (EST)
Date: Fri, 12 Feb 2021 13:14:54 -0500
From: Leo Famulari <leo@HIDDEN>
To: Danny Milosavljevic <dannym@HIDDEN>
Subject: Re: bug#46456: [core-updates] d3.v5.js source checksum changed
Message-ID: <YCbFnrqhGN69A73L@HIDDEN>
References: <20210212045315.3f4e0a82@HIDDEN>
MIME-Version: 1.0
Content-Type: multipart/signed; micalg=pgp-sha256;
 protocol="application/pgp-signature"; boundary="Ax9lNzlugw8JBjpt"
Content-Disposition: inline
In-Reply-To: <20210212045315.3f4e0a82@HIDDEN>
X-Debbugs-Envelope-To: 46456
Cc: 46456 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>


--Ax9lNzlugw8JBjpt
Content-Type: multipart/mixed; boundary="kLqR5wKUBEbm+NQl"
Content-Disposition: inline


--kLqR5wKUBEbm+NQl
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Fri, Feb 12, 2021 at 04:53:15AM +0100, Danny Milosavljevic wrote:
> Starting download of /gnu/store/bf496ni94ik19gdxkgp0vddkfxbid2vf-d3.v5.js
> From https://d3js.org/d3.v5.js...
> downloading from https://d3js.org/d3.v5.js ...
>  d3.v5.js                                                                                                                  2.22GiB/s 00:00 | 504KiB transferred
> sha256 hash mismatch for /gnu/store/bf496ni94ik19gdxkgp0vddkfxbid2vf-d3.v5.js:
>   expected hash: 0kxvx5pfagxn6nhavdwsdnzyd26g0z5dsfi1pi5dvcmb0c8ipcdn

Attached.

--kLqR5wKUBEbm+NQl
Content-Type: text/plain; charset=utf-8
Content-Disposition: attachment;
	filename="bf496ni94ik19gdxkgp0vddkfxbid2vf-d3.v5.js"
Content-Transfer-Encoding: quoted-printable

// https://d3js.org v5.9.7 Copyright 2019 Mike Bostock
(function (global, factory) {
typeof exports =3D=3D=3D 'object' && typeof module !=3D=3D 'undefined' ? fa=
ctory(exports) :
typeof define =3D=3D=3D 'function' && define.amd ? define(['exports'], fact=
ory) :
(factory((global.d3 =3D global.d3 || {})));
}(this, (function (exports) { 'use strict';

var version =3D "5.9.7";

function ascending(a, b) {
  return a < b ? -1 : a > b ? 1 : a >=3D b ? 0 : NaN;
}

function bisector(compare) {
  if (compare.length =3D=3D=3D 1) compare =3D ascendingComparator(compare);
  return {
    left: function(a, x, lo, hi) {
      if (lo =3D=3D null) lo =3D 0;
      if (hi =3D=3D null) hi =3D a.length;
      while (lo < hi) {
        var mid =3D lo + hi >>> 1;
        if (compare(a[mid], x) < 0) lo =3D mid + 1;
        else hi =3D mid;
      }
      return lo;
    },
    right: function(a, x, lo, hi) {
      if (lo =3D=3D null) lo =3D 0;
      if (hi =3D=3D null) hi =3D a.length;
      while (lo < hi) {
        var mid =3D lo + hi >>> 1;
        if (compare(a[mid], x) > 0) hi =3D mid;
        else lo =3D mid + 1;
      }
      return lo;
    }
  };
}

function ascendingComparator(f) {
  return function(d, x) {
    return ascending(f(d), x);
  };
}

var ascendingBisect =3D bisector(ascending);
var bisectRight =3D ascendingBisect.right;
var bisectLeft =3D ascendingBisect.left;

function pairs(array, f) {
  if (f =3D=3D null) f =3D pair;
  var i =3D 0, n =3D array.length - 1, p =3D array[0], pairs =3D new Array(=
n < 0 ? 0 : n);
  while (i < n) pairs[i] =3D f(p, p =3D array[++i]);
  return pairs;
}

function pair(a, b) {
  return [a, b];
}

function cross(values0, values1, reduce) {
  var n0 =3D values0.length,
      n1 =3D values1.length,
      values =3D new Array(n0 * n1),
      i0,
      i1,
      i,
      value0;

  if (reduce =3D=3D null) reduce =3D pair;

  for (i0 =3D i =3D 0; i0 < n0; ++i0) {
    for (value0 =3D values0[i0], i1 =3D 0; i1 < n1; ++i1, ++i) {
      values[i] =3D reduce(value0, values1[i1]);
    }
  }

  return values;
}

function descending(a, b) {
  return b < a ? -1 : b > a ? 1 : b >=3D a ? 0 : NaN;
}

function number(x) {
  return x =3D=3D=3D null ? NaN : +x;
}

function variance(values, valueof) {
  var n =3D values.length,
      m =3D 0,
      i =3D -1,
      mean =3D 0,
      value,
      delta,
      sum =3D 0;

  if (valueof =3D=3D null) {
    while (++i < n) {
      if (!isNaN(value =3D number(values[i]))) {
        delta =3D value - mean;
        mean +=3D delta / ++m;
        sum +=3D delta * (value - mean);
      }
    }
  }

  else {
    while (++i < n) {
      if (!isNaN(value =3D number(valueof(values[i], i, values)))) {
        delta =3D value - mean;
        mean +=3D delta / ++m;
        sum +=3D delta * (value - mean);
      }
    }
  }

  if (m > 1) return sum / (m - 1);
}

function deviation(array, f) {
  var v =3D variance(array, f);
  return v ? Math.sqrt(v) : v;
}

function extent(values, valueof) {
  var n =3D values.length,
      i =3D -1,
      value,
      min,
      max;

  if (valueof =3D=3D null) {
    while (++i < n) { // Find the first comparable value.
      if ((value =3D values[i]) !=3D null && value >=3D value) {
        min =3D max =3D value;
        while (++i < n) { // Compare the remaining values.
          if ((value =3D values[i]) !=3D null) {
            if (min > value) min =3D value;
            if (max < value) max =3D value;
          }
        }
      }
    }
  }

  else {
    while (++i < n) { // Find the first comparable value.
      if ((value =3D valueof(values[i], i, values)) !=3D null && value >=3D=
 value) {
        min =3D max =3D value;
        while (++i < n) { // Compare the remaining values.
          if ((value =3D valueof(values[i], i, values)) !=3D null) {
            if (min > value) min =3D value;
            if (max < value) max =3D value;
          }
        }
      }
    }
  }

  return [min, max];
}

var array =3D Array.prototype;

var slice =3D array.slice;
var map =3D array.map;

function constant(x) {
  return function() {
    return x;
  };
}

function identity(x) {
  return x;
}

function sequence(start, stop, step) {
  start =3D +start, stop =3D +stop, step =3D (n =3D arguments.length) < 2 ?=
 (stop =3D start, start =3D 0, 1) : n < 3 ? 1 : +step;

  var i =3D -1,
      n =3D Math.max(0, Math.ceil((stop - start) / step)) | 0,
      range =3D new Array(n);

  while (++i < n) {
    range[i] =3D start + i * step;
  }

  return range;
}

var e10 =3D Math.sqrt(50),
    e5 =3D Math.sqrt(10),
    e2 =3D Math.sqrt(2);

function ticks(start, stop, count) {
  var reverse,
      i =3D -1,
      n,
      ticks,
      step;

  stop =3D +stop, start =3D +start, count =3D +count;
  if (start =3D=3D=3D stop && count > 0) return [start];
  if (reverse =3D stop < start) n =3D start, start =3D stop, stop =3D n;
  if ((step =3D tickIncrement(start, stop, count)) =3D=3D=3D 0 || !isFinite=
(step)) return [];

  if (step > 0) {
    start =3D Math.ceil(start / step);
    stop =3D Math.floor(stop / step);
    ticks =3D new Array(n =3D Math.ceil(stop - start + 1));
    while (++i < n) ticks[i] =3D (start + i) * step;
  } else {
    start =3D Math.floor(start * step);
    stop =3D Math.ceil(stop * step);
    ticks =3D new Array(n =3D Math.ceil(start - stop + 1));
    while (++i < n) ticks[i] =3D (start - i) / step;
  }

  if (reverse) ticks.reverse();

  return ticks;
}

function tickIncrement(start, stop, count) {
  var step =3D (stop - start) / Math.max(0, count),
      power =3D Math.floor(Math.log(step) / Math.LN10),
      error =3D step / Math.pow(10, power);
  return power >=3D 0
      ? (error >=3D e10 ? 10 : error >=3D e5 ? 5 : error >=3D e2 ? 2 : 1) *=
 Math.pow(10, power)
      : -Math.pow(10, -power) / (error >=3D e10 ? 10 : error >=3D e5 ? 5 : =
error >=3D e2 ? 2 : 1);
}

function tickStep(start, stop, count) {
  var step0 =3D Math.abs(stop - start) / Math.max(0, count),
      step1 =3D Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)),
      error =3D step0 / step1;
  if (error >=3D e10) step1 *=3D 10;
  else if (error >=3D e5) step1 *=3D 5;
  else if (error >=3D e2) step1 *=3D 2;
  return stop < start ? -step1 : step1;
}

function thresholdSturges(values) {
  return Math.ceil(Math.log(values.length) / Math.LN2) + 1;
}

function histogram() {
  var value =3D identity,
      domain =3D extent,
      threshold =3D thresholdSturges;

  function histogram(data) {
    var i,
        n =3D data.length,
        x,
        values =3D new Array(n);

    for (i =3D 0; i < n; ++i) {
      values[i] =3D value(data[i], i, data);
    }

    var xz =3D domain(values),
        x0 =3D xz[0],
        x1 =3D xz[1],
        tz =3D threshold(values, x0, x1);

    // Convert number of thresholds into uniform thresholds.
    if (!Array.isArray(tz)) {
      tz =3D tickStep(x0, x1, tz);
      tz =3D sequence(Math.ceil(x0 / tz) * tz, x1, tz); // exclusive
    }

    // Remove any thresholds outside the domain.
    var m =3D tz.length;
    while (tz[0] <=3D x0) tz.shift(), --m;
    while (tz[m - 1] > x1) tz.pop(), --m;

    var bins =3D new Array(m + 1),
        bin;

    // Initialize bins.
    for (i =3D 0; i <=3D m; ++i) {
      bin =3D bins[i] =3D [];
      bin.x0 =3D i > 0 ? tz[i - 1] : x0;
      bin.x1 =3D i < m ? tz[i] : x1;
    }

    // Assign data to bins by value, ignoring any outside the domain.
    for (i =3D 0; i < n; ++i) {
      x =3D values[i];
      if (x0 <=3D x && x <=3D x1) {
        bins[bisectRight(tz, x, 0, m)].push(data[i]);
      }
    }

    return bins;
  }

  histogram.value =3D function(_) {
    return arguments.length ? (value =3D typeof _ =3D=3D=3D "function" ? _ =
: constant(_), histogram) : value;
  };

  histogram.domain =3D function(_) {
    return arguments.length ? (domain =3D typeof _ =3D=3D=3D "function" ? _=
 : constant([_[0], _[1]]), histogram) : domain;
  };

  histogram.thresholds =3D function(_) {
    return arguments.length ? (threshold =3D typeof _ =3D=3D=3D "function" =
? _ : Array.isArray(_) ? constant(slice.call(_)) : constant(_), histogram) =
: threshold;
  };

  return histogram;
}

function threshold(values, p, valueof) {
  if (valueof =3D=3D null) valueof =3D number;
  if (!(n =3D values.length)) return;
  if ((p =3D +p) <=3D 0 || n < 2) return +valueof(values[0], 0, values);
  if (p >=3D 1) return +valueof(values[n - 1], n - 1, values);
  var n,
      i =3D (n - 1) * p,
      i0 =3D Math.floor(i),
      value0 =3D +valueof(values[i0], i0, values),
      value1 =3D +valueof(values[i0 + 1], i0 + 1, values);
  return value0 + (value1 - value0) * (i - i0);
}

function freedmanDiaconis(values, min, max) {
  values =3D map.call(values, number).sort(ascending);
  return Math.ceil((max - min) / (2 * (threshold(values, 0.75) - threshold(=
values, 0.25)) * Math.pow(values.length, -1 / 3)));
}

function scott(values, min, max) {
  return Math.ceil((max - min) / (3.5 * deviation(values) * Math.pow(values=
=2Elength, -1 / 3)));
}

function max(values, valueof) {
  var n =3D values.length,
      i =3D -1,
      value,
      max;

  if (valueof =3D=3D null) {
    while (++i < n) { // Find the first comparable value.
      if ((value =3D values[i]) !=3D null && value >=3D value) {
        max =3D value;
        while (++i < n) { // Compare the remaining values.
          if ((value =3D values[i]) !=3D null && value > max) {
            max =3D value;
          }
        }
      }
    }
  }

  else {
    while (++i < n) { // Find the first comparable value.
      if ((value =3D valueof(values[i], i, values)) !=3D null && value >=3D=
 value) {
        max =3D value;
        while (++i < n) { // Compare the remaining values.
          if ((value =3D valueof(values[i], i, values)) !=3D null && value =
> max) {
            max =3D value;
          }
        }
      }
    }
  }

  return max;
}

function mean(values, valueof) {
  var n =3D values.length,
      m =3D n,
      i =3D -1,
      value,
      sum =3D 0;

  if (valueof =3D=3D null) {
    while (++i < n) {
      if (!isNaN(value =3D number(values[i]))) sum +=3D value;
      else --m;
    }
  }

  else {
    while (++i < n) {
      if (!isNaN(value =3D number(valueof(values[i], i, values)))) sum +=3D=
 value;
      else --m;
    }
  }

  if (m) return sum / m;
}

function median(values, valueof) {
  var n =3D values.length,
      i =3D -1,
      value,
      numbers =3D [];

  if (valueof =3D=3D null) {
    while (++i < n) {
      if (!isNaN(value =3D number(values[i]))) {
        numbers.push(value);
      }
    }
  }

  else {
    while (++i < n) {
      if (!isNaN(value =3D number(valueof(values[i], i, values)))) {
        numbers.push(value);
      }
    }
  }

  return threshold(numbers.sort(ascending), 0.5);
}

function merge(arrays) {
  var n =3D arrays.length,
      m,
      i =3D -1,
      j =3D 0,
      merged,
      array;

  while (++i < n) j +=3D arrays[i].length;
  merged =3D new Array(j);

  while (--n >=3D 0) {
    array =3D arrays[n];
    m =3D array.length;
    while (--m >=3D 0) {
      merged[--j] =3D array[m];
    }
  }

  return merged;
}

function min(values, valueof) {
  var n =3D values.length,
      i =3D -1,
      value,
      min;

  if (valueof =3D=3D null) {
    while (++i < n) { // Find the first comparable value.
      if ((value =3D values[i]) !=3D null && value >=3D value) {
        min =3D value;
        while (++i < n) { // Compare the remaining values.
          if ((value =3D values[i]) !=3D null && min > value) {
            min =3D value;
          }
        }
      }
    }
  }

  else {
    while (++i < n) { // Find the first comparable value.
      if ((value =3D valueof(values[i], i, values)) !=3D null && value >=3D=
 value) {
        min =3D value;
        while (++i < n) { // Compare the remaining values.
          if ((value =3D valueof(values[i], i, values)) !=3D null && min > =
value) {
            min =3D value;
          }
        }
      }
    }
  }

  return min;
}

function permute(array, indexes) {
  var i =3D indexes.length, permutes =3D new Array(i);
  while (i--) permutes[i] =3D array[indexes[i]];
  return permutes;
}

function scan(values, compare) {
  if (!(n =3D values.length)) return;
  var n,
      i =3D 0,
      j =3D 0,
      xi,
      xj =3D values[j];

  if (compare =3D=3D null) compare =3D ascending;

  while (++i < n) {
    if (compare(xi =3D values[i], xj) < 0 || compare(xj, xj) !=3D=3D 0) {
      xj =3D xi, j =3D i;
    }
  }

  if (compare(xj, xj) =3D=3D=3D 0) return j;
}

function shuffle(array, i0, i1) {
  var m =3D (i1 =3D=3D null ? array.length : i1) - (i0 =3D i0 =3D=3D null ?=
 0 : +i0),
      t,
      i;

  while (m) {
    i =3D Math.random() * m-- | 0;
    t =3D array[m + i0];
    array[m + i0] =3D array[i + i0];
    array[i + i0] =3D t;
  }

  return array;
}

function sum(values, valueof) {
  var n =3D values.length,
      i =3D -1,
      value,
      sum =3D 0;

  if (valueof =3D=3D null) {
    while (++i < n) {
      if (value =3D +values[i]) sum +=3D value; // Note: zero and null are =
equivalent.
    }
  }

  else {
    while (++i < n) {
      if (value =3D +valueof(values[i], i, values)) sum +=3D value;
    }
  }

  return sum;
}

function transpose(matrix) {
  if (!(n =3D matrix.length)) return [];
  for (var i =3D -1, m =3D min(matrix, length), transpose =3D new Array(m);=
 ++i < m;) {
    for (var j =3D -1, n, row =3D transpose[i] =3D new Array(n); ++j < n;) {
      row[j] =3D matrix[j][i];
    }
  }
  return transpose;
}

function length(d) {
  return d.length;
}

function zip() {
  return transpose(arguments);
}

var slice$1 =3D Array.prototype.slice;

function identity$1(x) {
  return x;
}

var top =3D 1,
    right =3D 2,
    bottom =3D 3,
    left =3D 4,
    epsilon =3D 1e-6;

function translateX(x) {
  return "translate(" + (x + 0.5) + ",0)";
}

function translateY(y) {
  return "translate(0," + (y + 0.5) + ")";
}

function number$1(scale) {
  return function(d) {
    return +scale(d);
  };
}

function center(scale) {
  var offset =3D Math.max(0, scale.bandwidth() - 1) / 2; // Adjust for 0.5p=
x offset.
  if (scale.round()) offset =3D Math.round(offset);
  return function(d) {
    return +scale(d) + offset;
  };
}

function entering() {
  return !this.__axis;
}

function axis(orient, scale) {
  var tickArguments =3D [],
      tickValues =3D null,
      tickFormat =3D null,
      tickSizeInner =3D 6,
      tickSizeOuter =3D 6,
      tickPadding =3D 3,
      k =3D orient =3D=3D=3D top || orient =3D=3D=3D left ? -1 : 1,
      x =3D orient =3D=3D=3D left || orient =3D=3D=3D right ? "x" : "y",
      transform =3D orient =3D=3D=3D top || orient =3D=3D=3D bottom ? trans=
lateX : translateY;

  function axis(context) {
    var values =3D tickValues =3D=3D null ? (scale.ticks ? scale.ticks.appl=
y(scale, tickArguments) : scale.domain()) : tickValues,
        format =3D tickFormat =3D=3D null ? (scale.tickFormat ? scale.tickF=
ormat.apply(scale, tickArguments) : identity$1) : tickFormat,
        spacing =3D Math.max(tickSizeInner, 0) + tickPadding,
        range =3D scale.range(),
        range0 =3D +range[0] + 0.5,
        range1 =3D +range[range.length - 1] + 0.5,
        position =3D (scale.bandwidth ? center : number$1)(scale.copy()),
        selection =3D context.selection ? context.selection() : context,
        path =3D selection.selectAll(".domain").data([null]),
        tick =3D selection.selectAll(".tick").data(values, scale).order(),
        tickExit =3D tick.exit(),
        tickEnter =3D tick.enter().append("g").attr("class", "tick"),
        line =3D tick.select("line"),
        text =3D tick.select("text");

    path =3D path.merge(path.enter().insert("path", ".tick")
        .attr("class", "domain")
        .attr("stroke", "currentColor"));

    tick =3D tick.merge(tickEnter);

    line =3D line.merge(tickEnter.append("line")
        .attr("stroke", "currentColor")
        .attr(x + "2", k * tickSizeInner));

    text =3D text.merge(tickEnter.append("text")
        .attr("fill", "currentColor")
        .attr(x, k * spacing)
        .attr("dy", orient =3D=3D=3D top ? "0em" : orient =3D=3D=3D bottom =
? "0.71em" : "0.32em"));

    if (context !=3D=3D selection) {
      path =3D path.transition(context);
      tick =3D tick.transition(context);
      line =3D line.transition(context);
      text =3D text.transition(context);

      tickExit =3D tickExit.transition(context)
          .attr("opacity", epsilon)
          .attr("transform", function(d) { return isFinite(d =3D position(d=
)) ? transform(d) : this.getAttribute("transform"); });

      tickEnter
          .attr("opacity", epsilon)
          .attr("transform", function(d) { var p =3D this.parentNode.__axis=
; return transform(p && isFinite(p =3D p(d)) ? p : position(d)); });
    }

    tickExit.remove();

    path
        .attr("d", orient =3D=3D=3D left || orient =3D=3D right
            ? (tickSizeOuter ? "M" + k * tickSizeOuter + "," + range0 + "H0=
=2E5V" + range1 + "H" + k * tickSizeOuter : "M0.5," + range0 + "V" + range1)
            : (tickSizeOuter ? "M" + range0 + "," + k * tickSizeOuter + "V0=
=2E5H" + range1 + "V" + k * tickSizeOuter : "M" + range0 + ",0.5H" + range1=
));

    tick
        .attr("opacity", 1)
        .attr("transform", function(d) { return transform(position(d)); });

    line
        .attr(x + "2", k * tickSizeInner);

    text
        .attr(x, k * spacing)
        .text(format);

    selection.filter(entering)
        .attr("fill", "none")
        .attr("font-size", 10)
        .attr("font-family", "sans-serif")
        .attr("text-anchor", orient =3D=3D=3D right ? "start" : orient =3D=
=3D=3D left ? "end" : "middle");

    selection
        .each(function() { this.__axis =3D position; });
  }

  axis.scale =3D function(_) {
    return arguments.length ? (scale =3D _, axis) : scale;
  };

  axis.ticks =3D function() {
    return tickArguments =3D slice$1.call(arguments), axis;
  };

  axis.tickArguments =3D function(_) {
    return arguments.length ? (tickArguments =3D _ =3D=3D null ? [] : slice=
$1.call(_), axis) : tickArguments.slice();
  };

  axis.tickValues =3D function(_) {
    return arguments.length ? (tickValues =3D _ =3D=3D null ? null : slice$=
1.call(_), axis) : tickValues && tickValues.slice();
  };

  axis.tickFormat =3D function(_) {
    return arguments.length ? (tickFormat =3D _, axis) : tickFormat;
  };

  axis.tickSize =3D function(_) {
    return arguments.length ? (tickSizeInner =3D tickSizeOuter =3D +_, axis=
) : tickSizeInner;
  };

  axis.tickSizeInner =3D function(_) {
    return arguments.length ? (tickSizeInner =3D +_, axis) : tickSizeInner;
  };

  axis.tickSizeOuter =3D function(_) {
    return arguments.length ? (tickSizeOuter =3D +_, axis) : tickSizeOuter;
  };

  axis.tickPadding =3D function(_) {
    return arguments.length ? (tickPadding =3D +_, axis) : tickPadding;
  };

  return axis;
}

function axisTop(scale) {
  return axis(top, scale);
}

function axisRight(scale) {
  return axis(right, scale);
}

function axisBottom(scale) {
  return axis(bottom, scale);
}

function axisLeft(scale) {
  return axis(left, scale);
}

var noop =3D {value: function() {}};

function dispatch() {
  for (var i =3D 0, n =3D arguments.length, _ =3D {}, t; i < n; ++i) {
    if (!(t =3D arguments[i] + "") || (t in _)) throw new Error("illegal ty=
pe: " + t);
    _[t] =3D [];
  }
  return new Dispatch(_);
}

function Dispatch(_) {
  this._ =3D _;
}

function parseTypenames(typenames, types) {
  return typenames.trim().split(/^|\s+/).map(function(t) {
    var name =3D "", i =3D t.indexOf(".");
    if (i >=3D 0) name =3D t.slice(i + 1), t =3D t.slice(0, i);
    if (t && !types.hasOwnProperty(t)) throw new Error("unknown type: " + t=
);
    return {type: t, name: name};
  });
}

Dispatch.prototype =3D dispatch.prototype =3D {
  constructor: Dispatch,
  on: function(typename, callback) {
    var _ =3D this._,
        T =3D parseTypenames(typename + "", _),
        t,
        i =3D -1,
        n =3D T.length;

    // If no callback was specified, return the callback of the given type =
and name.
    if (arguments.length < 2) {
      while (++i < n) if ((t =3D (typename =3D T[i]).type) && (t =3D get(_[=
t], typename.name))) return t;
      return;
    }

    // If a type was specified, set the callback for the given type and nam=
e.
    // Otherwise, if a null callback was specified, remove callbacks of the=
 given name.
    if (callback !=3D null && typeof callback !=3D=3D "function") throw new=
 Error("invalid callback: " + callback);
    while (++i < n) {
      if (t =3D (typename =3D T[i]).type) _[t] =3D set(_[t], typename.name,=
 callback);
      else if (callback =3D=3D null) for (t in _) _[t] =3D set(_[t], typena=
me.name, null);
    }

    return this;
  },
  copy: function() {
    var copy =3D {}, _ =3D this._;
    for (var t in _) copy[t] =3D _[t].slice();
    return new Dispatch(copy);
  },
  call: function(type, that) {
    if ((n =3D arguments.length - 2) > 0) for (var args =3D new Array(n), i=
 =3D 0, n, t; i < n; ++i) args[i] =3D arguments[i + 2];
    if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + ty=
pe);
    for (t =3D this._[type], i =3D 0, n =3D t.length; i < n; ++i) t[i].valu=
e.apply(that, args);
  },
  apply: function(type, that, args) {
    if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + ty=
pe);
    for (var t =3D this._[type], i =3D 0, n =3D t.length; i < n; ++i) t[i].=
value.apply(that, args);
  }
};

function get(type, name) {
  for (var i =3D 0, n =3D type.length, c; i < n; ++i) {
    if ((c =3D type[i]).name =3D=3D=3D name) {
      return c.value;
    }
  }
}

function set(type, name, callback) {
  for (var i =3D 0, n =3D type.length; i < n; ++i) {
    if (type[i].name =3D=3D=3D name) {
      type[i] =3D noop, type =3D type.slice(0, i).concat(type.slice(i + 1));
      break;
    }
  }
  if (callback !=3D null) type.push({name: name, value: callback});
  return type;
}

var xhtml =3D "http://www.w3.org/1999/xhtml";

var namespaces =3D {
  svg: "http://www.w3.org/2000/svg",
  xhtml: xhtml,
  xlink: "http://www.w3.org/1999/xlink",
  xml: "http://www.w3.org/XML/1998/namespace",
  xmlns: "http://www.w3.org/2000/xmlns/"
};

function namespace(name) {
  var prefix =3D name +=3D "", i =3D prefix.indexOf(":");
  if (i >=3D 0 && (prefix =3D name.slice(0, i)) !=3D=3D "xmlns") name =3D n=
ame.slice(i + 1);
  return namespaces.hasOwnProperty(prefix) ? {space: namespaces[prefix], lo=
cal: name} : name;
}

function creatorInherit(name) {
  return function() {
    var document =3D this.ownerDocument,
        uri =3D this.namespaceURI;
    return uri =3D=3D=3D xhtml && document.documentElement.namespaceURI =3D=
=3D=3D xhtml
        ? document.createElement(name)
        : document.createElementNS(uri, name);
  };
}

function creatorFixed(fullname) {
  return function() {
    return this.ownerDocument.createElementNS(fullname.space, fullname.loca=
l);
  };
}

function creator(name) {
  var fullname =3D namespace(name);
  return (fullname.local
      ? creatorFixed
      : creatorInherit)(fullname);
}

function none() {}

function selector(selector) {
  return selector =3D=3D null ? none : function() {
    return this.querySelector(selector);
  };
}

function selection_select(select) {
  if (typeof select !=3D=3D "function") select =3D selector(select);

  for (var groups =3D this._groups, m =3D groups.length, subgroups =3D new =
Array(m), j =3D 0; j < m; ++j) {
    for (var group =3D groups[j], n =3D group.length, subgroup =3D subgroup=
s[j] =3D new Array(n), node, subnode, i =3D 0; i < n; ++i) {
      if ((node =3D group[i]) && (subnode =3D select.call(node, node.__data=
__, i, group))) {
        if ("__data__" in node) subnode.__data__ =3D node.__data__;
        subgroup[i] =3D subnode;
      }
    }
  }

  return new Selection(subgroups, this._parents);
}

function empty() {
  return [];
}

function selectorAll(selector) {
  return selector =3D=3D null ? empty : function() {
    return this.querySelectorAll(selector);
  };
}

function selection_selectAll(select) {
  if (typeof select !=3D=3D "function") select =3D selectorAll(select);

  for (var groups =3D this._groups, m =3D groups.length, subgroups =3D [], =
parents =3D [], j =3D 0; j < m; ++j) {
    for (var group =3D groups[j], n =3D group.length, node, i =3D 0; i < n;=
 ++i) {
      if (node =3D group[i]) {
        subgroups.push(select.call(node, node.__data__, i, group));
        parents.push(node);
      }
    }
  }

  return new Selection(subgroups, parents);
}

function matcher(selector) {
  return function() {
    return this.matches(selector);
  };
}

function selection_filter(match) {
  if (typeof match !=3D=3D "function") match =3D matcher(match);

  for (var groups =3D this._groups, m =3D groups.length, subgroups =3D new =
Array(m), j =3D 0; j < m; ++j) {
    for (var group =3D groups[j], n =3D group.length, subgroup =3D subgroup=
s[j] =3D [], node, i =3D 0; i < n; ++i) {
      if ((node =3D group[i]) && match.call(node, node.__data__, i, group))=
 {
        subgroup.push(node);
      }
    }
  }

  return new Selection(subgroups, this._parents);
}

function sparse(update) {
  return new Array(update.length);
}

function selection_enter() {
  return new Selection(this._enter || this._groups.map(sparse), this._paren=
ts);
}

function EnterNode(parent, datum) {
  this.ownerDocument =3D parent.ownerDocument;
  this.namespaceURI =3D parent.namespaceURI;
  this._next =3D null;
  this._parent =3D parent;
  this.__data__ =3D datum;
}

EnterNode.prototype =3D {
  constructor: EnterNode,
  appendChild: function(child) { return this._parent.insertBefore(child, th=
is._next); },
  insertBefore: function(child, next) { return this._parent.insertBefore(ch=
ild, next); },
  querySelector: function(selector) { return this._parent.querySelector(sel=
ector); },
  querySelectorAll: function(selector) { return this._parent.querySelectorA=
ll(selector); }
};

function constant$1(x) {
  return function() {
    return x;
  };
}

var keyPrefix =3D "$"; // Protect against keys like =E2=80=9C__proto__=E2=
=80=9D.

function bindIndex(parent, group, enter, update, exit, data) {
  var i =3D 0,
      node,
      groupLength =3D group.length,
      dataLength =3D data.length;

  // Put any non-null nodes that fit into update.
  // Put any null nodes into enter.
  // Put any remaining data into enter.
  for (; i < dataLength; ++i) {
    if (node =3D group[i]) {
      node.__data__ =3D data[i];
      update[i] =3D node;
    } else {
      enter[i] =3D new EnterNode(parent, data[i]);
    }
  }

  // Put any non-null nodes that don=E2=80=99t fit into exit.
  for (; i < groupLength; ++i) {
    if (node =3D group[i]) {
      exit[i] =3D node;
    }
  }
}

function bindKey(parent, group, enter, update, exit, data, key) {
  var i,
      node,
      nodeByKeyValue =3D {},
      groupLength =3D group.length,
      dataLength =3D data.length,
      keyValues =3D new Array(groupLength),
      keyValue;

  // Compute the key for each node.
  // If multiple nodes have the same key, the duplicates are added to exit.
  for (i =3D 0; i < groupLength; ++i) {
    if (node =3D group[i]) {
      keyValues[i] =3D keyValue =3D keyPrefix + key.call(node, node.__data_=
_, i, group);
      if (keyValue in nodeByKeyValue) {
        exit[i] =3D node;
      } else {
        nodeByKeyValue[keyValue] =3D node;
      }
    }
  }

  // Compute the key for each datum.
  // If there a node associated with this key, join and add it to update.
  // If there is not (or the key is a duplicate), add it to enter.
  for (i =3D 0; i < dataLength; ++i) {
    keyValue =3D keyPrefix + key.call(parent, data[i], i, data);
    if (node =3D nodeByKeyValue[keyValue]) {
      update[i] =3D node;
      node.__data__ =3D data[i];
      nodeByKeyValue[keyValue] =3D null;
    } else {
      enter[i] =3D new EnterNode(parent, data[i]);
    }
  }

  // Add any remaining nodes that were not bound to data to exit.
  for (i =3D 0; i < groupLength; ++i) {
    if ((node =3D group[i]) && (nodeByKeyValue[keyValues[i]] =3D=3D=3D node=
)) {
      exit[i] =3D node;
    }
  }
}

function selection_data(value, key) {
  if (!value) {
    data =3D new Array(this.size()), j =3D -1;
    this.each(function(d) { data[++j] =3D d; });
    return data;
  }

  var bind =3D key ? bindKey : bindIndex,
      parents =3D this._parents,
      groups =3D this._groups;

  if (typeof value !=3D=3D "function") value =3D constant$1(value);

  for (var m =3D groups.length, update =3D new Array(m), enter =3D new Arra=
y(m), exit =3D new Array(m), j =3D 0; j < m; ++j) {
    var parent =3D parents[j],
        group =3D groups[j],
        groupLength =3D group.length,
        data =3D value.call(parent, parent && parent.__data__, j, parents),
        dataLength =3D data.length,
        enterGroup =3D enter[j] =3D new Array(dataLength),
        updateGroup =3D update[j] =3D new Array(dataLength),
        exitGroup =3D exit[j] =3D new Array(groupLength);

    bind(parent, group, enterGroup, updateGroup, exitGroup, data, key);

    // Now connect the enter nodes to their following update node, such that
    // appendChild can insert the materialized enter node before this node,
    // rather than at the end of the parent node.
    for (var i0 =3D 0, i1 =3D 0, previous, next; i0 < dataLength; ++i0) {
      if (previous =3D enterGroup[i0]) {
        if (i0 >=3D i1) i1 =3D i0 + 1;
        while (!(next =3D updateGroup[i1]) && ++i1 < dataLength);
        previous._next =3D next || null;
      }
    }
  }

  update =3D new Selection(update, parents);
  update._enter =3D enter;
  update._exit =3D exit;
  return update;
}

function selection_exit() {
  return new Selection(this._exit || this._groups.map(sparse), this._parent=
s);
}

function selection_join(onenter, onupdate, onexit) {
  var enter =3D this.enter(), update =3D this, exit =3D this.exit();
  enter =3D typeof onenter =3D=3D=3D "function" ? onenter(enter) : enter.ap=
pend(onenter + "");
  if (onupdate !=3D null) update =3D onupdate(update);
  if (onexit =3D=3D null) exit.remove(); else onexit(exit);
  return enter && update ? enter.merge(update).order() : update;
}

function selection_merge(selection$$1) {

  for (var groups0 =3D this._groups, groups1 =3D selection$$1._groups, m0 =
=3D groups0.length, m1 =3D groups1.length, m =3D Math.min(m0, m1), merges =
=3D new Array(m0), j =3D 0; j < m; ++j) {
    for (var group0 =3D groups0[j], group1 =3D groups1[j], n =3D group0.len=
gth, merge =3D merges[j] =3D new Array(n), node, i =3D 0; i < n; ++i) {
      if (node =3D group0[i] || group1[i]) {
        merge[i] =3D node;
      }
    }
  }

  for (; j < m0; ++j) {
    merges[j] =3D groups0[j];
  }

  return new Selection(merges, this._parents);
}

function selection_order() {

  for (var groups =3D this._groups, j =3D -1, m =3D groups.length; ++j < m;=
) {
    for (var group =3D groups[j], i =3D group.length - 1, next =3D group[i]=
, node; --i >=3D 0;) {
      if (node =3D group[i]) {
        if (next && node.compareDocumentPosition(next) ^ 4) next.parentNode=
=2EinsertBefore(node, next);
        next =3D node;
      }
    }
  }

  return this;
}

function selection_sort(compare) {
  if (!compare) compare =3D ascending$1;

  function compareNode(a, b) {
    return a && b ? compare(a.__data__, b.__data__) : !a - !b;
  }

  for (var groups =3D this._groups, m =3D groups.length, sortgroups =3D new=
 Array(m), j =3D 0; j < m; ++j) {
    for (var group =3D groups[j], n =3D group.length, sortgroup =3D sortgro=
ups[j] =3D new Array(n), node, i =3D 0; i < n; ++i) {
      if (node =3D group[i]) {
        sortgroup[i] =3D node;
      }
    }
    sortgroup.sort(compareNode);
  }

  return new Selection(sortgroups, this._parents).order();
}

function ascending$1(a, b) {
  return a < b ? -1 : a > b ? 1 : a >=3D b ? 0 : NaN;
}

function selection_call() {
  var callback =3D arguments[0];
  arguments[0] =3D this;
  callback.apply(null, arguments);
  return this;
}

function selection_nodes() {
  var nodes =3D new Array(this.size()), i =3D -1;
  this.each(function() { nodes[++i] =3D this; });
  return nodes;
}

function selection_node() {

  for (var groups =3D this._groups, j =3D 0, m =3D groups.length; j < m; ++=
j) {
    for (var group =3D groups[j], i =3D 0, n =3D group.length; i < n; ++i) {
      var node =3D group[i];
      if (node) return node;
    }
  }

  return null;
}

function selection_size() {
  var size =3D 0;
  this.each(function() { ++size; });
  return size;
}

function selection_empty() {
  return !this.node();
}

function selection_each(callback) {

  for (var groups =3D this._groups, j =3D 0, m =3D groups.length; j < m; ++=
j) {
    for (var group =3D groups[j], i =3D 0, n =3D group.length, node; i < n;=
 ++i) {
      if (node =3D group[i]) callback.call(node, node.__data__, i, group);
    }
  }

  return this;
}

function attrRemove(name) {
  return function() {
    this.removeAttribute(name);
  };
}

function attrRemoveNS(fullname) {
  return function() {
    this.removeAttributeNS(fullname.space, fullname.local);
  };
}

function attrConstant(name, value) {
  return function() {
    this.setAttribute(name, value);
  };
}

function attrConstantNS(fullname, value) {
  return function() {
    this.setAttributeNS(fullname.space, fullname.local, value);
  };
}

function attrFunction(name, value) {
  return function() {
    var v =3D value.apply(this, arguments);
    if (v =3D=3D null) this.removeAttribute(name);
    else this.setAttribute(name, v);
  };
}

function attrFunctionNS(fullname, value) {
  return function() {
    var v =3D value.apply(this, arguments);
    if (v =3D=3D null) this.removeAttributeNS(fullname.space, fullname.loca=
l);
    else this.setAttributeNS(fullname.space, fullname.local, v);
  };
}

function selection_attr(name, value) {
  var fullname =3D namespace(name);

  if (arguments.length < 2) {
    var node =3D this.node();
    return fullname.local
        ? node.getAttributeNS(fullname.space, fullname.local)
        : node.getAttribute(fullname);
  }

  return this.each((value =3D=3D null
      ? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value =3D=3D=
=3D "function"
      ? (fullname.local ? attrFunctionNS : attrFunction)
      : (fullname.local ? attrConstantNS : attrConstant)))(fullname, value)=
);
}

function defaultView(node) {
  return (node.ownerDocument && node.ownerDocument.defaultView) // node is =
a Node
      || (node.document && node) // node is a Window
      || node.defaultView; // node is a Document
}

function styleRemove(name) {
  return function() {
    this.style.removeProperty(name);
  };
}

function styleConstant(name, value, priority) {
  return function() {
    this.style.setProperty(name, value, priority);
  };
}

function styleFunction(name, value, priority) {
  return function() {
    var v =3D value.apply(this, arguments);
    if (v =3D=3D null) this.style.removeProperty(name);
    else this.style.setProperty(name, v, priority);
  };
}

function selection_style(name, value, priority) {
  return arguments.length > 1
      ? this.each((value =3D=3D null
            ? styleRemove : typeof value =3D=3D=3D "function"
            ? styleFunction
            : styleConstant)(name, value, priority =3D=3D null ? "" : prior=
ity))
      : styleValue(this.node(), name);
}

function styleValue(node, name) {
  return node.style.getPropertyValue(name)
      || defaultView(node).getComputedStyle(node, null).getPropertyValue(na=
me);
}

function propertyRemove(name) {
  return function() {
    delete this[name];
  };
}

function propertyConstant(name, value) {
  return function() {
    this[name] =3D value;
  };
}

function propertyFunction(name, value) {
  return function() {
    var v =3D value.apply(this, arguments);
    if (v =3D=3D null) delete this[name];
    else this[name] =3D v;
  };
}

function selection_property(name, value) {
  return arguments.length > 1
      ? this.each((value =3D=3D null
          ? propertyRemove : typeof value =3D=3D=3D "function"
          ? propertyFunction
          : propertyConstant)(name, value))
      : this.node()[name];
}

function classArray(string) {
  return string.trim().split(/^|\s+/);
}

function classList(node) {
  return node.classList || new ClassList(node);
}

function ClassList(node) {
  this._node =3D node;
  this._names =3D classArray(node.getAttribute("class") || "");
}

ClassList.prototype =3D {
  add: function(name) {
    var i =3D this._names.indexOf(name);
    if (i < 0) {
      this._names.push(name);
      this._node.setAttribute("class", this._names.join(" "));
    }
  },
  remove: function(name) {
    var i =3D this._names.indexOf(name);
    if (i >=3D 0) {
      this._names.splice(i, 1);
      this._node.setAttribute("class", this._names.join(" "));
    }
  },
  contains: function(name) {
    return this._names.indexOf(name) >=3D 0;
  }
};

function classedAdd(node, names) {
  var list =3D classList(node), i =3D -1, n =3D names.length;
  while (++i < n) list.add(names[i]);
}

function classedRemove(node, names) {
  var list =3D classList(node), i =3D -1, n =3D names.length;
  while (++i < n) list.remove(names[i]);
}

function classedTrue(names) {
  return function() {
    classedAdd(this, names);
  };
}

function classedFalse(names) {
  return function() {
    classedRemove(this, names);
  };
}

function classedFunction(names, value) {
  return function() {
    (value.apply(this, arguments) ? classedAdd : classedRemove)(this, names=
);
  };
}

function selection_classed(name, value) {
  var names =3D classArray(name + "");

  if (arguments.length < 2) {
    var list =3D classList(this.node()), i =3D -1, n =3D names.length;
    while (++i < n) if (!list.contains(names[i])) return false;
    return true;
  }

  return this.each((typeof value =3D=3D=3D "function"
      ? classedFunction : value
      ? classedTrue
      : classedFalse)(names, value));
}

function textRemove() {
  this.textContent =3D "";
}

function textConstant(value) {
  return function() {
    this.textContent =3D value;
  };
}

function textFunction(value) {
  return function() {
    var v =3D value.apply(this, arguments);
    this.textContent =3D v =3D=3D null ? "" : v;
  };
}

function selection_text(value) {
  return arguments.length
      ? this.each(value =3D=3D null
          ? textRemove : (typeof value =3D=3D=3D "function"
          ? textFunction
          : textConstant)(value))
      : this.node().textContent;
}

function htmlRemove() {
  this.innerHTML =3D "";
}

function htmlConstant(value) {
  return function() {
    this.innerHTML =3D value;
  };
}

function htmlFunction(value) {
  return function() {
    var v =3D value.apply(this, arguments);
    this.innerHTML =3D v =3D=3D null ? "" : v;
  };
}

function selection_html(value) {
  return arguments.length
      ? this.each(value =3D=3D null
          ? htmlRemove : (typeof value =3D=3D=3D "function"
          ? htmlFunction
          : htmlConstant)(value))
      : this.node().innerHTML;
}

function raise() {
  if (this.nextSibling) this.parentNode.appendChild(this);
}

function selection_raise() {
  return this.each(raise);
}

function lower() {
  if (this.previousSibling) this.parentNode.insertBefore(this, this.parentN=
ode.firstChild);
}

function selection_lower() {
  return this.each(lower);
}

function selection_append(name) {
  var create =3D typeof name =3D=3D=3D "function" ? name : creator(name);
  return this.select(function() {
    return this.appendChild(create.apply(this, arguments));
  });
}

function constantNull() {
  return null;
}

function selection_insert(name, before) {
  var create =3D typeof name =3D=3D=3D "function" ? name : creator(name),
      select =3D before =3D=3D null ? constantNull : typeof before =3D=3D=
=3D "function" ? before : selector(before);
  return this.select(function() {
    return this.insertBefore(create.apply(this, arguments), select.apply(th=
is, arguments) || null);
  });
}

function remove() {
  var parent =3D this.parentNode;
  if (parent) parent.removeChild(this);
}

function selection_remove() {
  return this.each(remove);
}

function selection_cloneShallow() {
  return this.parentNode.insertBefore(this.cloneNode(false), this.nextSibli=
ng);
}

function selection_cloneDeep() {
  return this.parentNode.insertBefore(this.cloneNode(true), this.nextSiblin=
g);
}

function selection_clone(deep) {
  return this.select(deep ? selection_cloneDeep : selection_cloneShallow);
}

function selection_datum(value) {
  return arguments.length
      ? this.property("__data__", value)
      : this.node().__data__;
}

var filterEvents =3D {};

exports.event =3D null;

if (typeof document !=3D=3D "undefined") {
  var element =3D document.documentElement;
  if (!("onmouseenter" in element)) {
    filterEvents =3D {mouseenter: "mouseover", mouseleave: "mouseout"};
  }
}

function filterContextListener(listener, index, group) {
  listener =3D contextListener(listener, index, group);
  return function(event) {
    var related =3D event.relatedTarget;
    if (!related || (related !=3D=3D this && !(related.compareDocumentPosit=
ion(this) & 8))) {
      listener.call(this, event);
    }
  };
}

function contextListener(listener, index, group) {
  return function(event1) {
    var event0 =3D exports.event; // Events can be reentrant (e.g., focus).
    exports.event =3D event1;
    try {
      listener.call(this, this.__data__, index, group);
    } finally {
      exports.event =3D event0;
    }
  };
}

function parseTypenames$1(typenames) {
  return typenames.trim().split(/^|\s+/).map(function(t) {
    var name =3D "", i =3D t.indexOf(".");
    if (i >=3D 0) name =3D t.slice(i + 1), t =3D t.slice(0, i);
    return {type: t, name: name};
  });
}

function onRemove(typename) {
  return function() {
    var on =3D this.__on;
    if (!on) return;
    for (var j =3D 0, i =3D -1, m =3D on.length, o; j < m; ++j) {
      if (o =3D on[j], (!typename.type || o.type =3D=3D=3D typename.type) &=
& o.name =3D=3D=3D typename.name) {
        this.removeEventListener(o.type, o.listener, o.capture);
      } else {
        on[++i] =3D o;
      }
    }
    if (++i) on.length =3D i;
    else delete this.__on;
  };
}

function onAdd(typename, value, capture) {
  var wrap =3D filterEvents.hasOwnProperty(typename.type) ? filterContextLi=
stener : contextListener;
  return function(d, i, group) {
    var on =3D this.__on, o, listener =3D wrap(value, i, group);
    if (on) for (var j =3D 0, m =3D on.length; j < m; ++j) {
      if ((o =3D on[j]).type =3D=3D=3D typename.type && o.name =3D=3D=3D ty=
pename.name) {
        this.removeEventListener(o.type, o.listener, o.capture);
        this.addEventListener(o.type, o.listener =3D listener, o.capture =
=3D capture);
        o.value =3D value;
        return;
      }
    }
    this.addEventListener(typename.type, listener, capture);
    o =3D {type: typename.type, name: typename.name, value: value, listener=
: listener, capture: capture};
    if (!on) this.__on =3D [o];
    else on.push(o);
  };
}

function selection_on(typename, value, capture) {
  var typenames =3D parseTypenames$1(typename + ""), i, n =3D typenames.len=
gth, t;

  if (arguments.length < 2) {
    var on =3D this.node().__on;
    if (on) for (var j =3D 0, m =3D on.length, o; j < m; ++j) {
      for (i =3D 0, o =3D on[j]; i < n; ++i) {
        if ((t =3D typenames[i]).type =3D=3D=3D o.type && t.name =3D=3D=3D =
o.name) {
          return o.value;
        }
      }
    }
    return;
  }

  on =3D value ? onAdd : onRemove;
  if (capture =3D=3D null) capture =3D false;
  for (i =3D 0; i < n; ++i) this.each(on(typenames[i], value, capture));
  return this;
}

function customEvent(event1, listener, that, args) {
  var event0 =3D exports.event;
  event1.sourceEvent =3D exports.event;
  exports.event =3D event1;
  try {
    return listener.apply(that, args);
  } finally {
    exports.event =3D event0;
  }
}

function dispatchEvent(node, type, params) {
  var window =3D defaultView(node),
      event =3D window.CustomEvent;

  if (typeof event =3D=3D=3D "function") {
    event =3D new event(type, params);
  } else {
    event =3D window.document.createEvent("Event");
    if (params) event.initEvent(type, params.bubbles, params.cancelable), e=
vent.detail =3D params.detail;
    else event.initEvent(type, false, false);
  }

  node.dispatchEvent(event);
}

function dispatchConstant(type, params) {
  return function() {
    return dispatchEvent(this, type, params);
  };
}

function dispatchFunction(type, params) {
  return function() {
    return dispatchEvent(this, type, params.apply(this, arguments));
  };
}

function selection_dispatch(type, params) {
  return this.each((typeof params =3D=3D=3D "function"
      ? dispatchFunction
      : dispatchConstant)(type, params));
}

var root =3D [null];

function Selection(groups, parents) {
  this._groups =3D groups;
  this._parents =3D parents;
}

function selection() {
  return new Selection([[document.documentElement]], root);
}

Selection.prototype =3D selection.prototype =3D {
  constructor: Selection,
  select: selection_select,
  selectAll: selection_selectAll,
  filter: selection_filter,
  data: selection_data,
  enter: selection_enter,
  exit: selection_exit,
  join: selection_join,
  merge: selection_merge,
  order: selection_order,
  sort: selection_sort,
  call: selection_call,
  nodes: selection_nodes,
  node: selection_node,
  size: selection_size,
  empty: selection_empty,
  each: selection_each,
  attr: selection_attr,
  style: selection_style,
  property: selection_property,
  classed: selection_classed,
  text: selection_text,
  html: selection_html,
  raise: selection_raise,
  lower: selection_lower,
  append: selection_append,
  insert: selection_insert,
  remove: selection_remove,
  clone: selection_clone,
  datum: selection_datum,
  on: selection_on,
  dispatch: selection_dispatch
};

function select(selector) {
  return typeof selector =3D=3D=3D "string"
      ? new Selection([[document.querySelector(selector)]], [document.docum=
entElement])
      : new Selection([[selector]], root);
}

function create(name) {
  return select(creator(name).call(document.documentElement));
}

var nextId =3D 0;

function local() {
  return new Local;
}

function Local() {
  this._ =3D "@" + (++nextId).toString(36);
}

Local.prototype =3D local.prototype =3D {
  constructor: Local,
  get: function(node) {
    var id =3D this._;
    while (!(id in node)) if (!(node =3D node.parentNode)) return;
    return node[id];
  },
  set: function(node, value) {
    return node[this._] =3D value;
  },
  remove: function(node) {
    return this._ in node && delete node[this._];
  },
  toString: function() {
    return this._;
  }
};

function sourceEvent() {
  var current =3D exports.event, source;
  while (source =3D current.sourceEvent) current =3D source;
  return current;
}

function point(node, event) {
  var svg =3D node.ownerSVGElement || node;

  if (svg.createSVGPoint) {
    var point =3D svg.createSVGPoint();
    point.x =3D event.clientX, point.y =3D event.clientY;
    point =3D point.matrixTransform(node.getScreenCTM().inverse());
    return [point.x, point.y];
  }

  var rect =3D node.getBoundingClientRect();
  return [event.clientX - rect.left - node.clientLeft, event.clientY - rect=
=2Etop - node.clientTop];
}

function mouse(node) {
  var event =3D sourceEvent();
  if (event.changedTouches) event =3D event.changedTouches[0];
  return point(node, event);
}

function selectAll(selector) {
  return typeof selector =3D=3D=3D "string"
      ? new Selection([document.querySelectorAll(selector)], [document.docu=
mentElement])
      : new Selection([selector =3D=3D null ? [] : selector], root);
}

function touch(node, touches, identifier) {
  if (arguments.length < 3) identifier =3D touches, touches =3D sourceEvent=
().changedTouches;

  for (var i =3D 0, n =3D touches ? touches.length : 0, touch; i < n; ++i) {
    if ((touch =3D touches[i]).identifier =3D=3D=3D identifier) {
      return point(node, touch);
    }
  }

  return null;
}

function touches(node, touches) {
  if (touches =3D=3D null) touches =3D sourceEvent().touches;

  for (var i =3D 0, n =3D touches ? touches.length : 0, points =3D new Arra=
y(n); i < n; ++i) {
    points[i] =3D point(node, touches[i]);
  }

  return points;
}

function nopropagation() {
  exports.event.stopImmediatePropagation();
}

function noevent() {
  exports.event.preventDefault();
  exports.event.stopImmediatePropagation();
}

function dragDisable(view) {
  var root =3D view.document.documentElement,
      selection$$1 =3D select(view).on("dragstart.drag", noevent, true);
  if ("onselectstart" in root) {
    selection$$1.on("selectstart.drag", noevent, true);
  } else {
    root.__noselect =3D root.style.MozUserSelect;
    root.style.MozUserSelect =3D "none";
  }
}

function yesdrag(view, noclick) {
  var root =3D view.document.documentElement,
      selection$$1 =3D select(view).on("dragstart.drag", null);
  if (noclick) {
    selection$$1.on("click.drag", noevent, true);
    setTimeout(function() { selection$$1.on("click.drag", null); }, 0);
  }
  if ("onselectstart" in root) {
    selection$$1.on("selectstart.drag", null);
  } else {
    root.style.MozUserSelect =3D root.__noselect;
    delete root.__noselect;
  }
}

function constant$2(x) {
  return function() {
    return x;
  };
}

function DragEvent(target, type, subject, id, active, x, y, dx, dy, dispatc=
h) {
  this.target =3D target;
  this.type =3D type;
  this.subject =3D subject;
  this.identifier =3D id;
  this.active =3D active;
  this.x =3D x;
  this.y =3D y;
  this.dx =3D dx;
  this.dy =3D dy;
  this._ =3D dispatch;
}

DragEvent.prototype.on =3D function() {
  var value =3D this._.on.apply(this._, arguments);
  return value =3D=3D=3D this._ ? this : value;
};

// Ignore right-click, since that should open the context menu.
function defaultFilter() {
  return !exports.event.button;
}

function defaultContainer() {
  return this.parentNode;
}

function defaultSubject(d) {
  return d =3D=3D null ? {x: exports.event.x, y: exports.event.y} : d;
}

function defaultTouchable() {
  return "ontouchstart" in this;
}

function drag() {
  var filter =3D defaultFilter,
      container =3D defaultContainer,
      subject =3D defaultSubject,
      touchable =3D defaultTouchable,
      gestures =3D {},
      listeners =3D dispatch("start", "drag", "end"),
      active =3D 0,
      mousedownx,
      mousedowny,
      mousemoving,
      touchending,
      clickDistance2 =3D 0;

  function drag(selection$$1) {
    selection$$1
        .on("mousedown.drag", mousedowned)
      .filter(touchable)
        .on("touchstart.drag", touchstarted)
        .on("touchmove.drag", touchmoved)
        .on("touchend.drag touchcancel.drag", touchended)
        .style("touch-action", "none")
        .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)");
  }

  function mousedowned() {
    if (touchending || !filter.apply(this, arguments)) return;
    var gesture =3D beforestart("mouse", container.apply(this, arguments), =
mouse, this, arguments);
    if (!gesture) return;
    select(exports.event.view).on("mousemove.drag", mousemoved, true).on("m=
ouseup.drag", mouseupped, true);
    dragDisable(exports.event.view);
    nopropagation();
    mousemoving =3D false;
    mousedownx =3D exports.event.clientX;
    mousedowny =3D exports.event.clientY;
    gesture("start");
  }

  function mousemoved() {
    noevent();
    if (!mousemoving) {
      var dx =3D exports.event.clientX - mousedownx, dy =3D exports.event.c=
lientY - mousedowny;
      mousemoving =3D dx * dx + dy * dy > clickDistance2;
    }
    gestures.mouse("drag");
  }

  function mouseupped() {
    select(exports.event.view).on("mousemove.drag mouseup.drag", null);
    yesdrag(exports.event.view, mousemoving);
    noevent();
    gestures.mouse("end");
  }

  function touchstarted() {
    if (!filter.apply(this, arguments)) return;
    var touches$$1 =3D exports.event.changedTouches,
        c =3D container.apply(this, arguments),
        n =3D touches$$1.length, i, gesture;

    for (i =3D 0; i < n; ++i) {
      if (gesture =3D beforestart(touches$$1[i].identifier, c, touch, this,=
 arguments)) {
        nopropagation();
        gesture("start");
      }
    }
  }

  function touchmoved() {
    var touches$$1 =3D exports.event.changedTouches,
        n =3D touches$$1.length, i, gesture;

    for (i =3D 0; i < n; ++i) {
      if (gesture =3D gestures[touches$$1[i].identifier]) {
        noevent();
        gesture("drag");
      }
    }
  }

  function touchended() {
    var touches$$1 =3D exports.event.changedTouches,
        n =3D touches$$1.length, i, gesture;

    if (touchending) clearTimeout(touchending);
    touchending =3D setTimeout(function() { touchending =3D null; }, 500); =
// Ghost clicks are delayed!
    for (i =3D 0; i < n; ++i) {
      if (gesture =3D gestures[touches$$1[i].identifier]) {
        nopropagation();
        gesture("end");
      }
    }
  }

  function beforestart(id, container, point$$1, that, args) {
    var p =3D point$$1(container, id), s, dx, dy,
        sublisteners =3D listeners.copy();

    if (!customEvent(new DragEvent(drag, "beforestart", s, id, active, p[0]=
, p[1], 0, 0, sublisteners), function() {
      if ((exports.event.subject =3D s =3D subject.apply(that, args)) =3D=
=3D null) return false;
      dx =3D s.x - p[0] || 0;
      dy =3D s.y - p[1] || 0;
      return true;
    })) return;

    return function gesture(type) {
      var p0 =3D p, n;
      switch (type) {
        case "start": gestures[id] =3D gesture, n =3D active++; break;
        case "end": delete gestures[id], --active; // nobreak
        case "drag": p =3D point$$1(container, id), n =3D active; break;
      }
      customEvent(new DragEvent(drag, type, s, id, n, p[0] + dx, p[1] + dy,=
 p[0] - p0[0], p[1] - p0[1], sublisteners), sublisteners.apply, sublistener=
s, [type, that, args]);
    };
  }

  drag.filter =3D function(_) {
    return arguments.length ? (filter =3D typeof _ =3D=3D=3D "function" ? _=
 : constant$2(!!_), drag) : filter;
  };

  drag.container =3D function(_) {
    return arguments.length ? (container =3D typeof _ =3D=3D=3D "function" =
? _ : constant$2(_), drag) : container;
  };

  drag.subject =3D function(_) {
    return arguments.length ? (subject =3D typeof _ =3D=3D=3D "function" ? =
_ : constant$2(_), drag) : subject;
  };

  drag.touchable =3D function(_) {
    return arguments.length ? (touchable =3D typeof _ =3D=3D=3D "function" =
? _ : constant$2(!!_), drag) : touchable;
  };

  drag.on =3D function() {
    var value =3D listeners.on.apply(listeners, arguments);
    return value =3D=3D=3D listeners ? drag : value;
  };

  drag.clickDistance =3D function(_) {
    return arguments.length ? (clickDistance2 =3D (_ =3D +_) * _, drag) : M=
ath.sqrt(clickDistance2);
  };

  return drag;
}

function define(constructor, factory, prototype) {
  constructor.prototype =3D factory.prototype =3D prototype;
  prototype.constructor =3D constructor;
}

function extend(parent, definition) {
  var prototype =3D Object.create(parent.prototype);
  for (var key in definition) prototype[key] =3D definition[key];
  return prototype;
}

function Color() {}

var darker =3D 0.7;
var brighter =3D 1 / darker;

var reI =3D "\\s*([+-]?\\d+)\\s*",
    reN =3D "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*",
    reP =3D "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*",
    reHex3 =3D /^#([0-9a-f]{3})$/,
    reHex6 =3D /^#([0-9a-f]{6})$/,
    reRgbInteger =3D new RegExp("^rgb\\(" + [reI, reI, reI] + "\\)$"),
    reRgbPercent =3D new RegExp("^rgb\\(" + [reP, reP, reP] + "\\)$"),
    reRgbaInteger =3D new RegExp("^rgba\\(" + [reI, reI, reI, reN] + "\\)$"=
),
    reRgbaPercent =3D new RegExp("^rgba\\(" + [reP, reP, reP, reN] + "\\)$"=
),
    reHslPercent =3D new RegExp("^hsl\\(" + [reN, reP, reP] + "\\)$"),
    reHslaPercent =3D new RegExp("^hsla\\(" + [reN, reP, reP, reN] + "\\)$"=
);

var named =3D {
  aliceblue: 0xf0f8ff,
  antiquewhite: 0xfaebd7,
  aqua: 0x00ffff,
  aquamarine: 0x7fffd4,
  azure: 0xf0ffff,
  beige: 0xf5f5dc,
  bisque: 0xffe4c4,
  black: 0x000000,
  blanchedalmond: 0xffebcd,
  blue: 0x0000ff,
  blueviolet: 0x8a2be2,
  brown: 0xa52a2a,
  burlywood: 0xdeb887,
  cadetblue: 0x5f9ea0,
  chartreuse: 0x7fff00,
  chocolate: 0xd2691e,
  coral: 0xff7f50,
  cornflowerblue: 0x6495ed,
  cornsilk: 0xfff8dc,
  crimson: 0xdc143c,
  cyan: 0x00ffff,
  darkblue: 0x00008b,
  darkcyan: 0x008b8b,
  darkgoldenrod: 0xb8860b,
  darkgray: 0xa9a9a9,
  darkgreen: 0x006400,
  darkgrey: 0xa9a9a9,
  darkkhaki: 0xbdb76b,
  darkmagenta: 0x8b008b,
  darkolivegreen: 0x556b2f,
  darkorange: 0xff8c00,
  darkorchid: 0x9932cc,
  darkred: 0x8b0000,
  darksalmon: 0xe9967a,
  darkseagreen: 0x8fbc8f,
  darkslateblue: 0x483d8b,
  darkslategray: 0x2f4f4f,
  darkslategrey: 0x2f4f4f,
  darkturquoise: 0x00ced1,
  darkviolet: 0x9400d3,
  deeppink: 0xff1493,
  deepskyblue: 0x00bfff,
  dimgray: 0x696969,
  dimgrey: 0x696969,
  dodgerblue: 0x1e90ff,
  firebrick: 0xb22222,
  floralwhite: 0xfffaf0,
  forestgreen: 0x228b22,
  fuchsia: 0xff00ff,
  gainsboro: 0xdcdcdc,
  ghostwhite: 0xf8f8ff,
  gold: 0xffd700,
  goldenrod: 0xdaa520,
  gray: 0x808080,
  green: 0x008000,
  greenyellow: 0xadff2f,
  grey: 0x808080,
  honeydew: 0xf0fff0,
  hotpink: 0xff69b4,
  indianred: 0xcd5c5c,
  indigo: 0x4b0082,
  ivory: 0xfffff0,
  khaki: 0xf0e68c,
  lavender: 0xe6e6fa,
  lavenderblush: 0xfff0f5,
  lawngreen: 0x7cfc00,
  lemonchiffon: 0xfffacd,
  lightblue: 0xadd8e6,
  lightcoral: 0xf08080,
  lightcyan: 0xe0ffff,
  lightgoldenrodyellow: 0xfafad2,
  lightgray: 0xd3d3d3,
  lightgreen: 0x90ee90,
  lightgrey: 0xd3d3d3,
  lightpink: 0xffb6c1,
  lightsalmon: 0xffa07a,
  lightseagreen: 0x20b2aa,
  lightskyblue: 0x87cefa,
  lightslategray: 0x778899,
  lightslategrey: 0x778899,
  lightsteelblue: 0xb0c4de,
  lightyellow: 0xffffe0,
  lime: 0x00ff00,
  limegreen: 0x32cd32,
  linen: 0xfaf0e6,
  magenta: 0xff00ff,
  maroon: 0x800000,
  mediumaquamarine: 0x66cdaa,
  mediumblue: 0x0000cd,
  mediumorchid: 0xba55d3,
  mediumpurple: 0x9370db,
  mediumseagreen: 0x3cb371,
  mediumslateblue: 0x7b68ee,
  mediumspringgreen: 0x00fa9a,
  mediumturquoise: 0x48d1cc,
  mediumvioletred: 0xc71585,
  midnightblue: 0x191970,
  mintcream: 0xf5fffa,
  mistyrose: 0xffe4e1,
  moccasin: 0xffe4b5,
  navajowhite: 0xffdead,
  navy: 0x000080,
  oldlace: 0xfdf5e6,
  olive: 0x808000,
  olivedrab: 0x6b8e23,
  orange: 0xffa500,
  orangered: 0xff4500,
  orchid: 0xda70d6,
  palegoldenrod: 0xeee8aa,
  palegreen: 0x98fb98,
  paleturquoise: 0xafeeee,
  palevioletred: 0xdb7093,
  papayawhip: 0xffefd5,
  peachpuff: 0xffdab9,
  peru: 0xcd853f,
  pink: 0xffc0cb,
  plum: 0xdda0dd,
  powderblue: 0xb0e0e6,
  purple: 0x800080,
  rebeccapurple: 0x663399,
  red: 0xff0000,
  rosybrown: 0xbc8f8f,
  royalblue: 0x4169e1,
  saddlebrown: 0x8b4513,
  salmon: 0xfa8072,
  sandybrown: 0xf4a460,
  seagreen: 0x2e8b57,
  seashell: 0xfff5ee,
  sienna: 0xa0522d,
  silver: 0xc0c0c0,
  skyblue: 0x87ceeb,
  slateblue: 0x6a5acd,
  slategray: 0x708090,
  slategrey: 0x708090,
  snow: 0xfffafa,
  springgreen: 0x00ff7f,
  steelblue: 0x4682b4,
  tan: 0xd2b48c,
  teal: 0x008080,
  thistle: 0xd8bfd8,
  tomato: 0xff6347,
  turquoise: 0x40e0d0,
  violet: 0xee82ee,
  wheat: 0xf5deb3,
  white: 0xffffff,
  whitesmoke: 0xf5f5f5,
  yellow: 0xffff00,
  yellowgreen: 0x9acd32
};

define(Color, color, {
  displayable: function() {
    return this.rgb().displayable();
  },
  hex: function() {
    return this.rgb().hex();
  },
  toString: function() {
    return this.rgb() + "";
  }
});

function color(format) {
  var m;
  format =3D (format + "").trim().toLowerCase();
  return (m =3D reHex3.exec(format)) ? (m =3D parseInt(m[1], 16), new Rgb((=
m >> 8 & 0xf) | (m >> 4 & 0x0f0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) <=
< 4) | (m & 0xf), 1)) // #f00
      : (m =3D reHex6.exec(format)) ? rgbn(parseInt(m[1], 16)) // #ff0000
      : (m =3D reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) //=
 rgb(255, 0, 0)
      : (m =3D reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] =
* 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%)
      : (m =3D reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) /=
/ rgba(255, 0, 0, 1)
      : (m =3D reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * =
255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1)
      : (m =3D reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 1=
00, 1) // hsl(120, 50%, 50%)
      : (m =3D reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / =
100, m[4]) // hsla(120, 50%, 50%, 1)
      : named.hasOwnProperty(format) ? rgbn(named[format])
      : format =3D=3D=3D "transparent" ? new Rgb(NaN, NaN, NaN, 0)
      : null;
}

function rgbn(n) {
  return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1);
}

function rgba(r, g, b, a) {
  if (a <=3D 0) r =3D g =3D b =3D NaN;
  return new Rgb(r, g, b, a);
}

function rgbConvert(o) {
  if (!(o instanceof Color)) o =3D color(o);
  if (!o) return new Rgb;
  o =3D o.rgb();
  return new Rgb(o.r, o.g, o.b, o.opacity);
}

function rgb(r, g, b, opacity) {
  return arguments.length =3D=3D=3D 1 ? rgbConvert(r) : new Rgb(r, g, b, op=
acity =3D=3D null ? 1 : opacity);
}

function Rgb(r, g, b, opacity) {
  this.r =3D +r;
  this.g =3D +g;
  this.b =3D +b;
  this.opacity =3D +opacity;
}

define(Rgb, rgb, extend(Color, {
  brighter: function(k) {
    k =3D k =3D=3D null ? brighter : Math.pow(brighter, k);
    return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
  },
  darker: function(k) {
    k =3D k =3D=3D null ? darker : Math.pow(darker, k);
    return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
  },
  rgb: function() {
    return this;
  },
  displayable: function() {
    return (-0.5 <=3D this.r && this.r < 255.5)
        && (-0.5 <=3D this.g && this.g < 255.5)
        && (-0.5 <=3D this.b && this.b < 255.5)
        && (0 <=3D this.opacity && this.opacity <=3D 1);
  },
  hex: function() {
    return "#" + hex(this.r) + hex(this.g) + hex(this.b);
  },
  toString: function() {
    var a =3D this.opacity; a =3D isNaN(a) ? 1 : Math.max(0, Math.min(1, a)=
);
    return (a =3D=3D=3D 1 ? "rgb(" : "rgba(")
        + Math.max(0, Math.min(255, Math.round(this.r) || 0)) + ", "
        + Math.max(0, Math.min(255, Math.round(this.g) || 0)) + ", "
        + Math.max(0, Math.min(255, Math.round(this.b) || 0))
        + (a =3D=3D=3D 1 ? ")" : ", " + a + ")");
  }
}));

function hex(value) {
  value =3D Math.max(0, Math.min(255, Math.round(value) || 0));
  return (value < 16 ? "0" : "") + value.toString(16);
}

function hsla(h, s, l, a) {
  if (a <=3D 0) h =3D s =3D l =3D NaN;
  else if (l <=3D 0 || l >=3D 1) h =3D s =3D NaN;
  else if (s <=3D 0) h =3D NaN;
  return new Hsl(h, s, l, a);
}

function hslConvert(o) {
  if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity);
  if (!(o instanceof Color)) o =3D color(o);
  if (!o) return new Hsl;
  if (o instanceof Hsl) return o;
  o =3D o.rgb();
  var r =3D o.r / 255,
      g =3D o.g / 255,
      b =3D o.b / 255,
      min =3D Math.min(r, g, b),
      max =3D Math.max(r, g, b),
      h =3D NaN,
      s =3D max - min,
      l =3D (max + min) / 2;
  if (s) {
    if (r =3D=3D=3D max) h =3D (g - b) / s + (g < b) * 6;
    else if (g =3D=3D=3D max) h =3D (b - r) / s + 2;
    else h =3D (r - g) / s + 4;
    s /=3D l < 0.5 ? max + min : 2 - max - min;
    h *=3D 60;
  } else {
    s =3D l > 0 && l < 1 ? 0 : h;
  }
  return new Hsl(h, s, l, o.opacity);
}

function hsl(h, s, l, opacity) {
  return arguments.length =3D=3D=3D 1 ? hslConvert(h) : new Hsl(h, s, l, op=
acity =3D=3D null ? 1 : opacity);
}

function Hsl(h, s, l, opacity) {
  this.h =3D +h;
  this.s =3D +s;
  this.l =3D +l;
  this.opacity =3D +opacity;
}

define(Hsl, hsl, extend(Color, {
  brighter: function(k) {
    k =3D k =3D=3D null ? brighter : Math.pow(brighter, k);
    return new Hsl(this.h, this.s, this.l * k, this.opacity);
  },
  darker: function(k) {
    k =3D k =3D=3D null ? darker : Math.pow(darker, k);
    return new Hsl(this.h, this.s, this.l * k, this.opacity);
  },
  rgb: function() {
    var h =3D this.h % 360 + (this.h < 0) * 360,
        s =3D isNaN(h) || isNaN(this.s) ? 0 : this.s,
        l =3D this.l,
        m2 =3D l + (l < 0.5 ? l : 1 - l) * s,
        m1 =3D 2 * l - m2;
    return new Rgb(
      hsl2rgb(h >=3D 240 ? h - 240 : h + 120, m1, m2),
      hsl2rgb(h, m1, m2),
      hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2),
      this.opacity
    );
  },
  displayable: function() {
    return (0 <=3D this.s && this.s <=3D 1 || isNaN(this.s))
        && (0 <=3D this.l && this.l <=3D 1)
        && (0 <=3D this.opacity && this.opacity <=3D 1);
  }
}));

/* From FvD 13.37, CSS Color Module Level 3 */
function hsl2rgb(h, m1, m2) {
  return (h < 60 ? m1 + (m2 - m1) * h / 60
      : h < 180 ? m2
      : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60
      : m1) * 255;
}

var deg2rad =3D Math.PI / 180;
var rad2deg =3D 180 / Math.PI;

// https://observablehq.com/@mbostock/lab-and-rgb
var K =3D 18,
    Xn =3D 0.96422,
    Yn =3D 1,
    Zn =3D 0.82521,
    t0 =3D 4 / 29,
    t1 =3D 6 / 29,
    t2 =3D 3 * t1 * t1,
    t3 =3D t1 * t1 * t1;

function labConvert(o) {
  if (o instanceof Lab) return new Lab(o.l, o.a, o.b, o.opacity);
  if (o instanceof Hcl) return hcl2lab(o);
  if (!(o instanceof Rgb)) o =3D rgbConvert(o);
  var r =3D rgb2lrgb(o.r),
      g =3D rgb2lrgb(o.g),
      b =3D rgb2lrgb(o.b),
      y =3D xyz2lab((0.2225045 * r + 0.7168786 * g + 0.0606169 * b) / Yn), =
x, z;
  if (r =3D=3D=3D g && g =3D=3D=3D b) x =3D z =3D y; else {
    x =3D xyz2lab((0.4360747 * r + 0.3850649 * g + 0.1430804 * b) / Xn);
    z =3D xyz2lab((0.0139322 * r + 0.0971045 * g + 0.7141733 * b) / Zn);
  }
  return new Lab(116 * y - 16, 500 * (x - y), 200 * (y - z), o.opacity);
}

function gray(l, opacity) {
  return new Lab(l, 0, 0, opacity =3D=3D null ? 1 : opacity);
}

function lab(l, a, b, opacity) {
  return arguments.length =3D=3D=3D 1 ? labConvert(l) : new Lab(l, a, b, op=
acity =3D=3D null ? 1 : opacity);
}

function Lab(l, a, b, opacity) {
  this.l =3D +l;
  this.a =3D +a;
  this.b =3D +b;
  this.opacity =3D +opacity;
}

define(Lab, lab, extend(Color, {
  brighter: function(k) {
    return new Lab(this.l + K * (k =3D=3D null ? 1 : k), this.a, this.b, th=
is.opacity);
  },
  darker: function(k) {
    return new Lab(this.l - K * (k =3D=3D null ? 1 : k), this.a, this.b, th=
is.opacity);
  },
  rgb: function() {
    var y =3D (this.l + 16) / 116,
        x =3D isNaN(this.a) ? y : y + this.a / 500,
        z =3D isNaN(this.b) ? y : y - this.b / 200;
    x =3D Xn * lab2xyz(x);
    y =3D Yn * lab2xyz(y);
    z =3D Zn * lab2xyz(z);
    return new Rgb(
      lrgb2rgb( 3.1338561 * x - 1.6168667 * y - 0.4906146 * z),
      lrgb2rgb(-0.9787684 * x + 1.9161415 * y + 0.0334540 * z),
      lrgb2rgb( 0.0719453 * x - 0.2289914 * y + 1.4052427 * z),
      this.opacity
    );
  }
}));

function xyz2lab(t) {
  return t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0;
}

function lab2xyz(t) {
  return t > t1 ? t * t * t : t2 * (t - t0);
}

function lrgb2rgb(x) {
  return 255 * (x <=3D 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4)=
 - 0.055);
}

function rgb2lrgb(x) {
  return (x /=3D 255) <=3D 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.0=
55, 2.4);
}

function hclConvert(o) {
  if (o instanceof Hcl) return new Hcl(o.h, o.c, o.l, o.opacity);
  if (!(o instanceof Lab)) o =3D labConvert(o);
  if (o.a =3D=3D=3D 0 && o.b =3D=3D=3D 0) return new Hcl(NaN, 0 < o.l && o.=
l < 100 ? 0 : NaN, o.l, o.opacity);
  var h =3D Math.atan2(o.b, o.a) * rad2deg;
  return new Hcl(h < 0 ? h + 360 : h, Math.sqrt(o.a * o.a + o.b * o.b), o.l=
, o.opacity);
}

function lch(l, c, h, opacity) {
  return arguments.length =3D=3D=3D 1 ? hclConvert(l) : new Hcl(h, c, l, op=
acity =3D=3D null ? 1 : opacity);
}

function hcl(h, c, l, opacity) {
  return arguments.length =3D=3D=3D 1 ? hclConvert(h) : new Hcl(h, c, l, op=
acity =3D=3D null ? 1 : opacity);
}

function Hcl(h, c, l, opacity) {
  this.h =3D +h;
  this.c =3D +c;
  this.l =3D +l;
  this.opacity =3D +opacity;
}

function hcl2lab(o) {
  if (isNaN(o.h)) return new Lab(o.l, 0, 0, o.opacity);
  var h =3D o.h * deg2rad;
  return new Lab(o.l, Math.cos(h) * o.c, Math.sin(h) * o.c, o.opacity);
}

define(Hcl, hcl, extend(Color, {
  brighter: function(k) {
    return new Hcl(this.h, this.c, this.l + K * (k =3D=3D null ? 1 : k), th=
is.opacity);
  },
  darker: function(k) {
    return new Hcl(this.h, this.c, this.l - K * (k =3D=3D null ? 1 : k), th=
is.opacity);
  },
  rgb: function() {
    return hcl2lab(this).rgb();
  }
}));

var A =3D -0.14861,
    B =3D +1.78277,
    C =3D -0.29227,
    D =3D -0.90649,
    E =3D +1.97294,
    ED =3D E * D,
    EB =3D E * B,
    BC_DA =3D B * C - D * A;

function cubehelixConvert(o) {
  if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity=
);
  if (!(o instanceof Rgb)) o =3D rgbConvert(o);
  var r =3D o.r / 255,
      g =3D o.g / 255,
      b =3D o.b / 255,
      l =3D (BC_DA * b + ED * r - EB * g) / (BC_DA + ED - EB),
      bl =3D b - l,
      k =3D (E * (g - l) - C * bl) / D,
      s =3D Math.sqrt(k * k + bl * bl) / (E * l * (1 - l)), // NaN if l=3D0=
 or l=3D1
      h =3D s ? Math.atan2(k, bl) * rad2deg - 120 : NaN;
  return new Cubehelix(h < 0 ? h + 360 : h, s, l, o.opacity);
}

function cubehelix(h, s, l, opacity) {
  return arguments.length =3D=3D=3D 1 ? cubehelixConvert(h) : new Cubehelix=
(h, s, l, opacity =3D=3D null ? 1 : opacity);
}

function Cubehelix(h, s, l, opacity) {
  this.h =3D +h;
  this.s =3D +s;
  this.l =3D +l;
  this.opacity =3D +opacity;
}

define(Cubehelix, cubehelix, extend(Color, {
  brighter: function(k) {
    k =3D k =3D=3D null ? brighter : Math.pow(brighter, k);
    return new Cubehelix(this.h, this.s, this.l * k, this.opacity);
  },
  darker: function(k) {
    k =3D k =3D=3D null ? darker : Math.pow(darker, k);
    return new Cubehelix(this.h, this.s, this.l * k, this.opacity);
  },
  rgb: function() {
    var h =3D isNaN(this.h) ? 0 : (this.h + 120) * deg2rad,
        l =3D +this.l,
        a =3D isNaN(this.s) ? 0 : this.s * l * (1 - l),
        cosh =3D Math.cos(h),
        sinh =3D Math.sin(h);
    return new Rgb(
      255 * (l + a * (A * cosh + B * sinh)),
      255 * (l + a * (C * cosh + D * sinh)),
      255 * (l + a * (E * cosh)),
      this.opacity
    );
  }
}));

function basis(t1, v0, v1, v2, v3) {
  var t2 =3D t1 * t1, t3 =3D t2 * t1;
  return ((1 - 3 * t1 + 3 * t2 - t3) * v0
      + (4 - 6 * t2 + 3 * t3) * v1
      + (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2
      + t3 * v3) / 6;
}

function basis$1(values) {
  var n =3D values.length - 1;
  return function(t) {
    var i =3D t <=3D 0 ? (t =3D 0) : t >=3D 1 ? (t =3D 1, n - 1) : Math.flo=
or(t * n),
        v1 =3D values[i],
        v2 =3D values[i + 1],
        v0 =3D i > 0 ? values[i - 1] : 2 * v1 - v2,
        v3 =3D i < n - 1 ? values[i + 2] : 2 * v2 - v1;
    return basis((t - i / n) * n, v0, v1, v2, v3);
  };
}

function basisClosed(values) {
  var n =3D values.length;
  return function(t) {
    var i =3D Math.floor(((t %=3D 1) < 0 ? ++t : t) * n),
        v0 =3D values[(i + n - 1) % n],
        v1 =3D values[i % n],
        v2 =3D values[(i + 1) % n],
        v3 =3D values[(i + 2) % n];
    return basis((t - i / n) * n, v0, v1, v2, v3);
  };
}

function constant$3(x) {
  return function() {
    return x;
  };
}

function linear(a, d) {
  return function(t) {
    return a + t * d;
  };
}

function exponential(a, b, y) {
  return a =3D Math.pow(a, y), b =3D Math.pow(b, y) - a, y =3D 1 / y, funct=
ion(t) {
    return Math.pow(a + t * b, y);
  };
}

function hue(a, b) {
  var d =3D b - a;
  return d ? linear(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) =
: d) : constant$3(isNaN(a) ? b : a);
}

function gamma(y) {
  return (y =3D +y) =3D=3D=3D 1 ? nogamma : function(a, b) {
    return b - a ? exponential(a, b, y) : constant$3(isNaN(a) ? b : a);
  };
}

function nogamma(a, b) {
  var d =3D b - a;
  return d ? linear(a, d) : constant$3(isNaN(a) ? b : a);
}

var interpolateRgb =3D (function rgbGamma(y) {
  var color$$1 =3D gamma(y);

  function rgb$$1(start, end) {
    var r =3D color$$1((start =3D rgb(start)).r, (end =3D rgb(end)).r),
        g =3D color$$1(start.g, end.g),
        b =3D color$$1(start.b, end.b),
        opacity =3D nogamma(start.opacity, end.opacity);
    return function(t) {
      start.r =3D r(t);
      start.g =3D g(t);
      start.b =3D b(t);
      start.opacity =3D opacity(t);
      return start + "";
    };
  }

  rgb$$1.gamma =3D rgbGamma;

  return rgb$$1;
})(1);

function rgbSpline(spline) {
  return function(colors) {
    var n =3D colors.length,
        r =3D new Array(n),
        g =3D new Array(n),
        b =3D new Array(n),
        i, color$$1;
    for (i =3D 0; i < n; ++i) {
      color$$1 =3D rgb(colors[i]);
      r[i] =3D color$$1.r || 0;
      g[i] =3D color$$1.g || 0;
      b[i] =3D color$$1.b || 0;
    }
    r =3D spline(r);
    g =3D spline(g);
    b =3D spline(b);
    color$$1.opacity =3D 1;
    return function(t) {
      color$$1.r =3D r(t);
      color$$1.g =3D g(t);
      color$$1.b =3D b(t);
      return color$$1 + "";
    };
  };
}

var rgbBasis =3D rgbSpline(basis$1);
var rgbBasisClosed =3D rgbSpline(basisClosed);

function array$1(a, b) {
  var nb =3D b ? b.length : 0,
      na =3D a ? Math.min(nb, a.length) : 0,
      x =3D new Array(na),
      c =3D new Array(nb),
      i;

  for (i =3D 0; i < na; ++i) x[i] =3D interpolateValue(a[i], b[i]);
  for (; i < nb; ++i) c[i] =3D b[i];

  return function(t) {
    for (i =3D 0; i < na; ++i) c[i] =3D x[i](t);
    return c;
  };
}

function date(a, b) {
  var d =3D new Date;
  return a =3D +a, b -=3D a, function(t) {
    return d.setTime(a + b * t), d;
  };
}

function interpolateNumber(a, b) {
  return a =3D +a, b -=3D a, function(t) {
    return a + b * t;
  };
}

function object(a, b) {
  var i =3D {},
      c =3D {},
      k;

  if (a =3D=3D=3D null || typeof a !=3D=3D "object") a =3D {};
  if (b =3D=3D=3D null || typeof b !=3D=3D "object") b =3D {};

  for (k in b) {
    if (k in a) {
      i[k] =3D interpolateValue(a[k], b[k]);
    } else {
      c[k] =3D b[k];
    }
  }

  return function(t) {
    for (k in i) c[k] =3D i[k](t);
    return c;
  };
}

var reA =3D /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,
    reB =3D new RegExp(reA.source, "g");

function zero(b) {
  return function() {
    return b;
  };
}

function one(b) {
  return function(t) {
    return b(t) + "";
  };
}

function interpolateString(a, b) {
  var bi =3D reA.lastIndex =3D reB.lastIndex =3D 0, // scan index for next =
number in b
      am, // current match in a
      bm, // current match in b
      bs, // string preceding current number in b, if any
      i =3D -1, // index in s
      s =3D [], // string constants and placeholders
      q =3D []; // number interpolators

  // Coerce inputs to strings.
  a =3D a + "", b =3D b + "";

  // Interpolate pairs of numbers in a & b.
  while ((am =3D reA.exec(a))
      && (bm =3D reB.exec(b))) {
    if ((bs =3D bm.index) > bi) { // a string precedes the next number in b
      bs =3D b.slice(bi, bs);
      if (s[i]) s[i] +=3D bs; // coalesce with previous string
      else s[++i] =3D bs;
    }
    if ((am =3D am[0]) =3D=3D=3D (bm =3D bm[0])) { // numbers in a & b match
      if (s[i]) s[i] +=3D bm; // coalesce with previous string
      else s[++i] =3D bm;
    } else { // interpolate non-matching numbers
      s[++i] =3D null;
      q.push({i: i, x: interpolateNumber(am, bm)});
    }
    bi =3D reB.lastIndex;
  }

  // Add remains of b.
  if (bi < b.length) {
    bs =3D b.slice(bi);
    if (s[i]) s[i] +=3D bs; // coalesce with previous string
    else s[++i] =3D bs;
  }

  // Special optimization for only a single match.
  // Otherwise, interpolate each of the numbers and rejoin the string.
  return s.length < 2 ? (q[0]
      ? one(q[0].x)
      : zero(b))
      : (b =3D q.length, function(t) {
          for (var i =3D 0, o; i < b; ++i) s[(o =3D q[i]).i] =3D o.x(t);
          return s.join("");
        });
}

function interpolateValue(a, b) {
  var t =3D typeof b, c;
  return b =3D=3D null || t =3D=3D=3D "boolean" ? constant$3(b)
      : (t =3D=3D=3D "number" ? interpolateNumber
      : t =3D=3D=3D "string" ? ((c =3D color(b)) ? (b =3D c, interpolateRgb=
) : interpolateString)
      : b instanceof color ? interpolateRgb
      : b instanceof Date ? date
      : Array.isArray(b) ? array$1
      : typeof b.valueOf !=3D=3D "function" && typeof b.toString !=3D=3D "f=
unction" || isNaN(b) ? object
      : interpolateNumber)(a, b);
}

function discrete(range) {
  var n =3D range.length;
  return function(t) {
    return range[Math.max(0, Math.min(n - 1, Math.floor(t * n)))];
  };
}

function hue$1(a, b) {
  var i =3D hue(+a, +b);
  return function(t) {
    var x =3D i(t);
    return x - 360 * Math.floor(x / 360);
  };
}

function interpolateRound(a, b) {
  return a =3D +a, b -=3D a, function(t) {
    return Math.round(a + b * t);
  };
}

var degrees =3D 180 / Math.PI;

var identity$2 =3D {
  translateX: 0,
  translateY: 0,
  rotate: 0,
  skewX: 0,
  scaleX: 1,
  scaleY: 1
};

function decompose(a, b, c, d, e, f) {
  var scaleX, scaleY, skewX;
  if (scaleX =3D Math.sqrt(a * a + b * b)) a /=3D scaleX, b /=3D scaleX;
  if (skewX =3D a * c + b * d) c -=3D a * skewX, d -=3D b * skewX;
  if (scaleY =3D Math.sqrt(c * c + d * d)) c /=3D scaleY, d /=3D scaleY, sk=
ewX /=3D scaleY;
  if (a * d < b * c) a =3D -a, b =3D -b, skewX =3D -skewX, scaleX =3D -scal=
eX;
  return {
    translateX: e,
    translateY: f,
    rotate: Math.atan2(b, a) * degrees,
    skewX: Math.atan(skewX) * degrees,
    scaleX: scaleX,
    scaleY: scaleY
  };
}

var cssNode,
    cssRoot,
    cssView,
    svgNode;

function parseCss(value) {
  if (value =3D=3D=3D "none") return identity$2;
  if (!cssNode) cssNode =3D document.createElement("DIV"), cssRoot =3D docu=
ment.documentElement, cssView =3D document.defaultView;
  cssNode.style.transform =3D value;
  value =3D cssView.getComputedStyle(cssRoot.appendChild(cssNode), null).ge=
tPropertyValue("transform");
  cssRoot.removeChild(cssNode);
  value =3D value.slice(7, -1).split(",");
  return decompose(+value[0], +value[1], +value[2], +value[3], +value[4], +=
value[5]);
}

function parseSvg(value) {
  if (value =3D=3D null) return identity$2;
  if (!svgNode) svgNode =3D document.createElementNS("http://www.w3.org/200=
0/svg", "g");
  svgNode.setAttribute("transform", value);
  if (!(value =3D svgNode.transform.baseVal.consolidate())) return identity=
$2;
  value =3D value.matrix;
  return decompose(value.a, value.b, value.c, value.d, value.e, value.f);
}

function interpolateTransform(parse, pxComma, pxParen, degParen) {

  function pop(s) {
    return s.length ? s.pop() + " " : "";
  }

  function translate(xa, ya, xb, yb, s, q) {
    if (xa !=3D=3D xb || ya !=3D=3D yb) {
      var i =3D s.push("translate(", null, pxComma, null, pxParen);
      q.push({i: i - 4, x: interpolateNumber(xa, xb)}, {i: i - 2, x: interp=
olateNumber(ya, yb)});
    } else if (xb || yb) {
      s.push("translate(" + xb + pxComma + yb + pxParen);
    }
  }

  function rotate(a, b, s, q) {
    if (a !=3D=3D b) {
      if (a - b > 180) b +=3D 360; else if (b - a > 180) a +=3D 360; // sho=
rtest path
      q.push({i: s.push(pop(s) + "rotate(", null, degParen) - 2, x: interpo=
lateNumber(a, b)});
    } else if (b) {
      s.push(pop(s) + "rotate(" + b + degParen);
    }
  }

  function skewX(a, b, s, q) {
    if (a !=3D=3D b) {
      q.push({i: s.push(pop(s) + "skewX(", null, degParen) - 2, x: interpol=
ateNumber(a, b)});
    } else if (b) {
      s.push(pop(s) + "skewX(" + b + degParen);
    }
  }

  function scale(xa, ya, xb, yb, s, q) {
    if (xa !=3D=3D xb || ya !=3D=3D yb) {
      var i =3D s.push(pop(s) + "scale(", null, ",", null, ")");
      q.push({i: i - 4, x: interpolateNumber(xa, xb)}, {i: i - 2, x: interp=
olateNumber(ya, yb)});
    } else if (xb !=3D=3D 1 || yb !=3D=3D 1) {
      s.push(pop(s) + "scale(" + xb + "," + yb + ")");
    }
  }

  return function(a, b) {
    var s =3D [], // string constants and placeholders
        q =3D []; // number interpolators
    a =3D parse(a), b =3D parse(b);
    translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q);
    rotate(a.rotate, b.rotate, s, q);
    skewX(a.skewX, b.skewX, s, q);
    scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q);
    a =3D b =3D null; // gc
    return function(t) {
      var i =3D -1, n =3D q.length, o;
      while (++i < n) s[(o =3D q[i]).i] =3D o.x(t);
      return s.join("");
    };
  };
}

var interpolateTransformCss =3D interpolateTransform(parseCss, "px, ", "px)=
", "deg)");
var interpolateTransformSvg =3D interpolateTransform(parseSvg, ", ", ")", "=
)");

var rho =3D Math.SQRT2,
    rho2 =3D 2,
    rho4 =3D 4,
    epsilon2 =3D 1e-12;

function cosh(x) {
  return ((x =3D Math.exp(x)) + 1 / x) / 2;
}

function sinh(x) {
  return ((x =3D Math.exp(x)) - 1 / x) / 2;
}

function tanh(x) {
  return ((x =3D Math.exp(2 * x)) - 1) / (x + 1);
}

// p0 =3D [ux0, uy0, w0]
// p1 =3D [ux1, uy1, w1]
function interpolateZoom(p0, p1) {
  var ux0 =3D p0[0], uy0 =3D p0[1], w0 =3D p0[2],
      ux1 =3D p1[0], uy1 =3D p1[1], w1 =3D p1[2],
      dx =3D ux1 - ux0,
      dy =3D uy1 - uy0,
      d2 =3D dx * dx + dy * dy,
      i,
      S;

  // Special case for u0 =E2=89=85 u1.
  if (d2 < epsilon2) {
    S =3D Math.log(w1 / w0) / rho;
    i =3D function(t) {
      return [
        ux0 + t * dx,
        uy0 + t * dy,
        w0 * Math.exp(rho * t * S)
      ];
    };
  }

  // General case.
  else {
    var d1 =3D Math.sqrt(d2),
        b0 =3D (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1),
        b1 =3D (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1),
        r0 =3D Math.log(Math.sqrt(b0 * b0 + 1) - b0),
        r1 =3D Math.log(Math.sqrt(b1 * b1 + 1) - b1);
    S =3D (r1 - r0) / rho;
    i =3D function(t) {
      var s =3D t * S,
          coshr0 =3D cosh(r0),
          u =3D w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0));
      return [
        ux0 + u * dx,
        uy0 + u * dy,
        w0 * coshr0 / cosh(rho * s + r0)
      ];
    };
  }

  i.duration =3D S * 1000;

  return i;
}

function hsl$1(hue$$1) {
  return function(start, end) {
    var h =3D hue$$1((start =3D hsl(start)).h, (end =3D hsl(end)).h),
        s =3D nogamma(start.s, end.s),
        l =3D nogamma(start.l, end.l),
        opacity =3D nogamma(start.opacity, end.opacity);
    return function(t) {
      start.h =3D h(t);
      start.s =3D s(t);
      start.l =3D l(t);
      start.opacity =3D opacity(t);
      return start + "";
    };
  }
}

var hsl$2 =3D hsl$1(hue);
var hslLong =3D hsl$1(nogamma);

function lab$1(start, end) {
  var l =3D nogamma((start =3D lab(start)).l, (end =3D lab(end)).l),
      a =3D nogamma(start.a, end.a),
      b =3D nogamma(start.b, end.b),
      opacity =3D nogamma(start.opacity, end.opacity);
  return function(t) {
    start.l =3D l(t);
    start.a =3D a(t);
    start.b =3D b(t);
    start.opacity =3D opacity(t);
    return start + "";
  };
}

function hcl$1(hue$$1) {
  return function(start, end) {
    var h =3D hue$$1((start =3D hcl(start)).h, (end =3D hcl(end)).h),
        c =3D nogamma(start.c, end.c),
        l =3D nogamma(start.l, end.l),
        opacity =3D nogamma(start.opacity, end.opacity);
    return function(t) {
      start.h =3D h(t);
      start.c =3D c(t);
      start.l =3D l(t);
      start.opacity =3D opacity(t);
      return start + "";
    };
  }
}

var hcl$2 =3D hcl$1(hue);
var hclLong =3D hcl$1(nogamma);

function cubehelix$1(hue$$1) {
  return (function cubehelixGamma(y) {
    y =3D +y;

    function cubehelix$$1(start, end) {
      var h =3D hue$$1((start =3D cubehelix(start)).h, (end =3D cubehelix(e=
nd)).h),
          s =3D nogamma(start.s, end.s),
          l =3D nogamma(start.l, end.l),
          opacity =3D nogamma(start.opacity, end.opacity);
      return function(t) {
        start.h =3D h(t);
        start.s =3D s(t);
        start.l =3D l(Math.pow(t, y));
        start.opacity =3D opacity(t);
        return start + "";
      };
    }

    cubehelix$$1.gamma =3D cubehelixGamma;

    return cubehelix$$1;
  })(1);
}

var cubehelix$2 =3D cubehelix$1(hue);
var cubehelixLong =3D cubehelix$1(nogamma);

function piecewise(interpolate, values) {
  var i =3D 0, n =3D values.length - 1, v =3D values[0], I =3D new Array(n =
< 0 ? 0 : n);
  while (i < n) I[i] =3D interpolate(v, v =3D values[++i]);
  return function(t) {
    var i =3D Math.max(0, Math.min(n - 1, Math.floor(t *=3D n)));
    return I[i](t - i);
  };
}

function quantize(interpolator, n) {
  var samples =3D new Array(n);
  for (var i =3D 0; i < n; ++i) samples[i] =3D interpolator(i / (n - 1));
  return samples;
}

var frame =3D 0, // is an animation frame pending?
    timeout =3D 0, // is a timeout pending?
    interval =3D 0, // are any timers active?
    pokeDelay =3D 1000, // how frequently we check for clock skew
    taskHead,
    taskTail,
    clockLast =3D 0,
    clockNow =3D 0,
    clockSkew =3D 0,
    clock =3D typeof performance =3D=3D=3D "object" && performance.now ? pe=
rformance : Date,
    setFrame =3D typeof window =3D=3D=3D "object" && window.requestAnimatio=
nFrame ? window.requestAnimationFrame.bind(window) : function(f) { setTimeo=
ut(f, 17); };

function now() {
  return clockNow || (setFrame(clearNow), clockNow =3D clock.now() + clockS=
kew);
}

function clearNow() {
  clockNow =3D 0;
}

function Timer() {
  this._call =3D
  this._time =3D
  this._next =3D null;
}

Timer.prototype =3D timer.prototype =3D {
  constructor: Timer,
  restart: function(callback, delay, time) {
    if (typeof callback !=3D=3D "function") throw new TypeError("callback i=
s not a function");
    time =3D (time =3D=3D null ? now() : +time) + (delay =3D=3D null ? 0 : =
+delay);
    if (!this._next && taskTail !=3D=3D this) {
      if (taskTail) taskTail._next =3D this;
      else taskHead =3D this;
      taskTail =3D this;
    }
    this._call =3D callback;
    this._time =3D time;
    sleep();
  },
  stop: function() {
    if (this._call) {
      this._call =3D null;
      this._time =3D Infinity;
      sleep();
    }
  }
};

function timer(callback, delay, time) {
  var t =3D new Timer;
  t.restart(callback, delay, time);
  return t;
}

function timerFlush() {
  now(); // Get the current time, if not already set.
  ++frame; // Pretend we=E2=80=99ve set an alarm, if we haven=E2=80=99t alr=
eady.
  var t =3D taskHead, e;
  while (t) {
    if ((e =3D clockNow - t._time) >=3D 0) t._call.call(null, e);
    t =3D t._next;
  }
  --frame;
}

function wake() {
  clockNow =3D (clockLast =3D clock.now()) + clockSkew;
  frame =3D timeout =3D 0;
  try {
    timerFlush();
  } finally {
    frame =3D 0;
    nap();
    clockNow =3D 0;
  }
}

function poke() {
  var now =3D clock.now(), delay =3D now - clockLast;
  if (delay > pokeDelay) clockSkew -=3D delay, clockLast =3D now;
}

function nap() {
  var t0, t1 =3D taskHead, t2, time =3D Infinity;
  while (t1) {
    if (t1._call) {
      if (time > t1._time) time =3D t1._time;
      t0 =3D t1, t1 =3D t1._next;
    } else {
      t2 =3D t1._next, t1._next =3D null;
      t1 =3D t0 ? t0._next =3D t2 : taskHead =3D t2;
    }
  }
  taskTail =3D t0;
  sleep(time);
}

function sleep(time) {
  if (frame) return; // Soonest alarm already set, or will be.
  if (timeout) timeout =3D clearTimeout(timeout);
  var delay =3D time - clockNow; // Strictly less than if we recomputed clo=
ckNow.
  if (delay > 24) {
    if (time < Infinity) timeout =3D setTimeout(wake, time - clock.now() - =
clockSkew);
    if (interval) interval =3D clearInterval(interval);
  } else {
    if (!interval) clockLast =3D clock.now(), interval =3D setInterval(poke=
, pokeDelay);
    frame =3D 1, setFrame(wake);
  }
}

function timeout$1(callback, delay, time) {
  var t =3D new Timer;
  delay =3D delay =3D=3D null ? 0 : +delay;
  t.restart(function(elapsed) {
    t.stop();
    callback(elapsed + delay);
  }, delay, time);
  return t;
}

function interval$1(callback, delay, time) {
  var t =3D new Timer, total =3D delay;
  if (delay =3D=3D null) return t.restart(callback, delay, time), t;
  delay =3D +delay, time =3D time =3D=3D null ? now() : +time;
  t.restart(function tick(elapsed) {
    elapsed +=3D total;
    t.restart(tick, total +=3D delay, time);
    callback(elapsed);
  }, delay, time);
  return t;
}

var emptyOn =3D dispatch("start", "end", "cancel", "interrupt");
var emptyTween =3D [];

var CREATED =3D 0;
var SCHEDULED =3D 1;
var STARTING =3D 2;
var STARTED =3D 3;
var RUNNING =3D 4;
var ENDING =3D 5;
var ENDED =3D 6;

function schedule(node, name, id, index, group, timing) {
  var schedules =3D node.__transition;
  if (!schedules) node.__transition =3D {};
  else if (id in schedules) return;
  create$1(node, id, {
    name: name,
    index: index, // For context during callback.
    group: group, // For context during callback.
    on: emptyOn,
    tween: emptyTween,
    time: timing.time,
    delay: timing.delay,
    duration: timing.duration,
    ease: timing.ease,
    timer: null,
    state: CREATED
  });
}

function init(node, id) {
  var schedule =3D get$1(node, id);
  if (schedule.state > CREATED) throw new Error("too late; already schedule=
d");
  return schedule;
}

function set$1(node, id) {
  var schedule =3D get$1(node, id);
  if (schedule.state > STARTED) throw new Error("too late; already running"=
);
  return schedule;
}

function get$1(node, id) {
  var schedule =3D node.__transition;
  if (!schedule || !(schedule =3D schedule[id])) throw new Error("transitio=
n not found");
  return schedule;
}

function create$1(node, id, self) {
  var schedules =3D node.__transition,
      tween;

  // Initialize the self timer when the transition is created.
  // Note the actual delay is not known until the first callback!
  schedules[id] =3D self;
  self.timer =3D timer(schedule, 0, self.time);

  function schedule(elapsed) {
    self.state =3D SCHEDULED;
    self.timer.restart(start, self.delay, self.time);

    // If the elapsed delay is less than our first sleep, start immediately.
    if (self.delay <=3D elapsed) start(elapsed - self.delay);
  }

  function start(elapsed) {
    var i, j, n, o;

    // If the state is not SCHEDULED, then we previously errored on start.
    if (self.state !=3D=3D SCHEDULED) return stop();

    for (i in schedules) {
      o =3D schedules[i];
      if (o.name !=3D=3D self.name) continue;

      // While this element already has a starting transition during this f=
rame,
      // defer starting an interrupting transition until that transition ha=
s a
      // chance to tick (and possibly end); see d3/d3-transition#54!
      if (o.state =3D=3D=3D STARTED) return timeout$1(start);

      // Interrupt the active transition, if any.
      if (o.state =3D=3D=3D RUNNING) {
        o.state =3D ENDED;
        o.timer.stop();
        o.on.call("interrupt", node, node.__data__, o.index, o.group);
        delete schedules[i];
      }

      // Cancel any pre-empted transitions.
      else if (+i < id) {
        o.state =3D ENDED;
        o.timer.stop();
        o.on.call("cancel", node, node.__data__, o.index, o.group);
        delete schedules[i];
      }
    }

    // Defer the first tick to end of the current frame; see d3/d3#1576.
    // Note the transition may be canceled after start and before the first=
 tick!
    // Note this must be scheduled before the start event; see d3/d3-transi=
tion#16!
    // Assuming this is successful, subsequent callbacks go straight to tic=
k.
    timeout$1(function() {
      if (self.state =3D=3D=3D STARTED) {
        self.state =3D RUNNING;
        self.timer.restart(tick, self.delay, self.time);
        tick(elapsed);
      }
    });

    // Dispatch the start event.
    // Note this must be done before the tween are initialized.
    self.state =3D STARTING;
    self.on.call("start", node, node.__data__, self.index, self.group);
    if (self.state !=3D=3D STARTING) return; // interrupted
    self.state =3D STARTED;

    // Initialize the tween, deleting null tween.
    tween =3D new Array(n =3D self.tween.length);
    for (i =3D 0, j =3D -1; i < n; ++i) {
      if (o =3D self.tween[i].value.call(node, node.__data__, self.index, s=
elf.group)) {
        tween[++j] =3D o;
      }
    }
    tween.length =3D j + 1;
  }

  function tick(elapsed) {
    var t =3D elapsed < self.duration ? self.ease.call(null, elapsed / self=
=2Eduration) : (self.timer.restart(stop), self.state =3D ENDING, 1),
        i =3D -1,
        n =3D tween.length;

    while (++i < n) {
      tween[i].call(node, t);
    }

    // Dispatch the end event.
    if (self.state =3D=3D=3D ENDING) {
      self.on.call("end", node, node.__data__, self.index, self.group);
      stop();
    }
  }

  function stop() {
    self.state =3D ENDED;
    self.timer.stop();
    delete schedules[id];
    for (var i in schedules) return; // eslint-disable-line no-unused-vars
    delete node.__transition;
  }
}

function interrupt(node, name) {
  var schedules =3D node.__transition,
      schedule$$1,
      active,
      empty =3D true,
      i;

  if (!schedules) return;

  name =3D name =3D=3D null ? null : name + "";

  for (i in schedules) {
    if ((schedule$$1 =3D schedules[i]).name !=3D=3D name) { empty =3D false=
; continue; }
    active =3D schedule$$1.state > STARTING && schedule$$1.state < ENDING;
    schedule$$1.state =3D ENDED;
    schedule$$1.timer.stop();
    schedule$$1.on.call(active ? "interrupt" : "cancel", node, node.__data_=
_, schedule$$1.index, schedule$$1.group);
    delete schedules[i];
  }

  if (empty) delete node.__transition;
}

function selection_interrupt(name) {
  return this.each(function() {
    interrupt(this, name);
  });
}

function tweenRemove(id, name) {
  var tween0, tween1;
  return function() {
    var schedule$$1 =3D set$1(this, id),
        tween =3D schedule$$1.tween;

    // If this node shared tween with the previous node,
    // just assign the updated shared tween and we=E2=80=99re done!
    // Otherwise, copy-on-write.
    if (tween !=3D=3D tween0) {
      tween1 =3D tween0 =3D tween;
      for (var i =3D 0, n =3D tween1.length; i < n; ++i) {
        if (tween1[i].name =3D=3D=3D name) {
          tween1 =3D tween1.slice();
          tween1.splice(i, 1);
          break;
        }
      }
    }

    schedule$$1.tween =3D tween1;
  };
}

function tweenFunction(id, name, value) {
  var tween0, tween1;
  if (typeof value !=3D=3D "function") throw new Error;
  return function() {
    var schedule$$1 =3D set$1(this, id),
        tween =3D schedule$$1.tween;

    // If this node shared tween with the previous node,
    // just assign the updated shared tween and we=E2=80=99re done!
    // Otherwise, copy-on-write.
    if (tween !=3D=3D tween0) {
      tween1 =3D (tween0 =3D tween).slice();
      for (var t =3D {name: name, value: value}, i =3D 0, n =3D tween1.leng=
th; i < n; ++i) {
        if (tween1[i].name =3D=3D=3D name) {
          tween1[i] =3D t;
          break;
        }
      }
      if (i =3D=3D=3D n) tween1.push(t);
    }

    schedule$$1.tween =3D tween1;
  };
}

function transition_tween(name, value) {
  var id =3D this._id;

  name +=3D "";

  if (arguments.length < 2) {
    var tween =3D get$1(this.node(), id).tween;
    for (var i =3D 0, n =3D tween.length, t; i < n; ++i) {
      if ((t =3D tween[i]).name =3D=3D=3D name) {
        return t.value;
      }
    }
    return null;
  }

  return this.each((value =3D=3D null ? tweenRemove : tweenFunction)(id, na=
me, value));
}

function tweenValue(transition, name, value) {
  var id =3D transition._id;

  transition.each(function() {
    var schedule$$1 =3D set$1(this, id);
    (schedule$$1.value || (schedule$$1.value =3D {}))[name] =3D value.apply=
(this, arguments);
  });

  return function(node) {
    return get$1(node, id).value[name];
  };
}

function interpolate(a, b) {
  var c;
  return (typeof b =3D=3D=3D "number" ? interpolateNumber
      : b instanceof color ? interpolateRgb
      : (c =3D color(b)) ? (b =3D c, interpolateRgb)
      : interpolateString)(a, b);
}

function attrRemove$1(name) {
  return function() {
    this.removeAttribute(name);
  };
}

function attrRemoveNS$1(fullname) {
  return function() {
    this.removeAttributeNS(fullname.space, fullname.local);
  };
}

function attrConstant$1(name, interpolate$$1, value1) {
  var string00,
      string1 =3D value1 + "",
      interpolate0;
  return function() {
    var string0 =3D this.getAttribute(name);
    return string0 =3D=3D=3D string1 ? null
        : string0 =3D=3D=3D string00 ? interpolate0
        : interpolate0 =3D interpolate$$1(string00 =3D string0, value1);
  };
}

function attrConstantNS$1(fullname, interpolate$$1, value1) {
  var string00,
      string1 =3D value1 + "",
      interpolate0;
  return function() {
    var string0 =3D this.getAttributeNS(fullname.space, fullname.local);
    return string0 =3D=3D=3D string1 ? null
        : string0 =3D=3D=3D string00 ? interpolate0
        : interpolate0 =3D interpolate$$1(string00 =3D string0, value1);
  };
}

function attrFunction$1(name, interpolate$$1, value) {
  var string00,
      string10,
      interpolate0;
  return function() {
    var string0, value1 =3D value(this), string1;
    if (value1 =3D=3D null) return void this.removeAttribute(name);
    string0 =3D this.getAttribute(name);
    string1 =3D value1 + "";
    return string0 =3D=3D=3D string1 ? null
        : string0 =3D=3D=3D string00 && string1 =3D=3D=3D string10 ? interp=
olate0
        : (string10 =3D string1, interpolate0 =3D interpolate$$1(string00 =
=3D string0, value1));
  };
}

function attrFunctionNS$1(fullname, interpolate$$1, value) {
  var string00,
      string10,
      interpolate0;
  return function() {
    var string0, value1 =3D value(this), string1;
    if (value1 =3D=3D null) return void this.removeAttributeNS(fullname.spa=
ce, fullname.local);
    string0 =3D this.getAttributeNS(fullname.space, fullname.local);
    string1 =3D value1 + "";
    return string0 =3D=3D=3D string1 ? null
        : string0 =3D=3D=3D string00 && string1 =3D=3D=3D string10 ? interp=
olate0
        : (string10 =3D string1, interpolate0 =3D interpolate$$1(string00 =
=3D string0, value1));
  };
}

function transition_attr(name, value) {
  var fullname =3D namespace(name), i =3D fullname =3D=3D=3D "transform" ? =
interpolateTransformSvg : interpolate;
  return this.attrTween(name, typeof value =3D=3D=3D "function"
      ? (fullname.local ? attrFunctionNS$1 : attrFunction$1)(fullname, i, t=
weenValue(this, "attr." + name, value))
      : value =3D=3D null ? (fullname.local ? attrRemoveNS$1 : attrRemove$1=
)(fullname)
      : (fullname.local ? attrConstantNS$1 : attrConstant$1)(fullname, i, v=
alue));
}

function attrInterpolate(name, i) {
  return function(t) {
    this.setAttribute(name, i(t));
  };
}

function attrInterpolateNS(fullname, i) {
  return function(t) {
    this.setAttributeNS(fullname.space, fullname.local, i(t));
  };
}

function attrTweenNS(fullname, value) {
  var t0, i0;
  function tween() {
    var i =3D value.apply(this, arguments);
    if (i !=3D=3D i0) t0 =3D (i0 =3D i) && attrInterpolateNS(fullname, i);
    return t0;
  }
  tween._value =3D value;
  return tween;
}

function attrTween(name, value) {
  var t0, i0;
  function tween() {
    var i =3D value.apply(this, arguments);
    if (i !=3D=3D i0) t0 =3D (i0 =3D i) && attrInterpolate(name, i);
    return t0;
  }
  tween._value =3D value;
  return tween;
}

function transition_attrTween(name, value) {
  var key =3D "attr." + name;
  if (arguments.length < 2) return (key =3D this.tween(key)) && key._value;
  if (value =3D=3D null) return this.tween(key, null);
  if (typeof value !=3D=3D "function") throw new Error;
  var fullname =3D namespace(name);
  return this.tween(key, (fullname.local ? attrTweenNS : attrTween)(fullnam=
e, value));
}

function delayFunction(id, value) {
  return function() {
    init(this, id).delay =3D +value.apply(this, arguments);
  };
}

function delayConstant(id, value) {
  return value =3D +value, function() {
    init(this, id).delay =3D value;
  };
}

function transition_delay(value) {
  var id =3D this._id;

  return arguments.length
      ? this.each((typeof value =3D=3D=3D "function"
          ? delayFunction
          : delayConstant)(id, value))
      : get$1(this.node(), id).delay;
}

function durationFunction(id, value) {
  return function() {
    set$1(this, id).duration =3D +value.apply(this, arguments);
  };
}

function durationConstant(id, value) {
  return value =3D +value, function() {
    set$1(this, id).duration =3D value;
  };
}

function transition_duration(value) {
  var id =3D this._id;

  return arguments.length
      ? this.each((typeof value =3D=3D=3D "function"
          ? durationFunction
          : durationConstant)(id, value))
      : get$1(this.node(), id).duration;
}

function easeConstant(id, value) {
  if (typeof value !=3D=3D "function") throw new Error;
  return function() {
    set$1(this, id).ease =3D value;
  };
}

function transition_ease(value) {
  var id =3D this._id;

  return arguments.length
      ? this.each(easeConstant(id, value))
      : get$1(this.node(), id).ease;
}

function transition_filter(match) {
  if (typeof match !=3D=3D "function") match =3D matcher(match);

  for (var groups =3D this._groups, m =3D groups.length, subgroups =3D new =
Array(m), j =3D 0; j < m; ++j) {
    for (var group =3D groups[j], n =3D group.length, subgroup =3D subgroup=
s[j] =3D [], node, i =3D 0; i < n; ++i) {
      if ((node =3D group[i]) && match.call(node, node.__data__, i, group))=
 {
        subgroup.push(node);
      }
    }
  }

  return new Transition(subgroups, this._parents, this._name, this._id);
}

function transition_merge(transition$$1) {
  if (transition$$1._id !=3D=3D this._id) throw new Error;

  for (var groups0 =3D this._groups, groups1 =3D transition$$1._groups, m0 =
=3D groups0.length, m1 =3D groups1.length, m =3D Math.min(m0, m1), merges =
=3D new Array(m0), j =3D 0; j < m; ++j) {
    for (var group0 =3D groups0[j], group1 =3D groups1[j], n =3D group0.len=
gth, merge =3D merges[j] =3D new Array(n), node, i =3D 0; i < n; ++i) {
      if (node =3D group0[i] || group1[i]) {
        merge[i] =3D node;
      }
    }
  }

  for (; j < m0; ++j) {
    merges[j] =3D groups0[j];
  }

  return new Transition(merges, this._parents, this._name, this._id);
}

function start(name) {
  return (name + "").trim().split(/^|\s+/).every(function(t) {
    var i =3D t.indexOf(".");
    if (i >=3D 0) t =3D t.slice(0, i);
    return !t || t =3D=3D=3D "start";
  });
}

function onFunction(id, name, listener) {
  var on0, on1, sit =3D start(name) ? init : set$1;
  return function() {
    var schedule$$1 =3D sit(this, id),
        on =3D schedule$$1.on;

    // If this node shared a dispatch with the previous node,
    // just assign the updated shared dispatch and we=E2=80=99re done!
    // Otherwise, copy-on-write.
    if (on !=3D=3D on0) (on1 =3D (on0 =3D on).copy()).on(name, listener);

    schedule$$1.on =3D on1;
  };
}

function transition_on(name, listener) {
  var id =3D this._id;

  return arguments.length < 2
      ? get$1(this.node(), id).on.on(name)
      : this.each(onFunction(id, name, listener));
}

function removeFunction(id) {
  return function() {
    var parent =3D this.parentNode;
    for (var i in this.__transition) if (+i !=3D=3D id) return;
    if (parent) parent.removeChild(this);
  };
}

function transition_remove() {
  return this.on("end.remove", removeFunction(this._id));
}

function transition_select(select$$1) {
  var name =3D this._name,
      id =3D this._id;

  if (typeof select$$1 !=3D=3D "function") select$$1 =3D selector(select$$1=
);

  for (var groups =3D this._groups, m =3D groups.length, subgroups =3D new =
Array(m), j =3D 0; j < m; ++j) {
    for (var group =3D groups[j], n =3D group.length, subgroup =3D subgroup=
s[j] =3D new Array(n), node, subnode, i =3D 0; i < n; ++i) {
      if ((node =3D group[i]) && (subnode =3D select$$1.call(node, node.__d=
ata__, i, group))) {
        if ("__data__" in node) subnode.__data__ =3D node.__data__;
        subgroup[i] =3D subnode;
        schedule(subgroup[i], name, id, i, subgroup, get$1(node, id));
      }
    }
  }

  return new Transition(subgroups, this._parents, name, id);
}

function transition_selectAll(select$$1) {
  var name =3D this._name,
      id =3D this._id;

  if (typeof select$$1 !=3D=3D "function") select$$1 =3D selectorAll(select=
$$1);

  for (var groups =3D this._groups, m =3D groups.length, subgroups =3D [], =
parents =3D [], j =3D 0; j < m; ++j) {
    for (var group =3D groups[j], n =3D group.length, node, i =3D 0; i < n;=
 ++i) {
      if (node =3D group[i]) {
        for (var children =3D select$$1.call(node, node.__data__, i, group)=
, child, inherit =3D get$1(node, id), k =3D 0, l =3D children.length; k < l=
; ++k) {
          if (child =3D children[k]) {
            schedule(child, name, id, k, children, inherit);
          }
        }
        subgroups.push(children);
        parents.push(node);
      }
    }
  }

  return new Transition(subgroups, parents, name, id);
}

var Selection$1 =3D selection.prototype.constructor;

function transition_selection() {
  return new Selection$1(this._groups, this._parents);
}

function styleNull(name, interpolate$$1) {
  var string00,
      string10,
      interpolate0;
  return function() {
    var string0 =3D styleValue(this, name),
        string1 =3D (this.style.removeProperty(name), styleValue(this, name=
));
    return string0 =3D=3D=3D string1 ? null
        : string0 =3D=3D=3D string00 && string1 =3D=3D=3D string10 ? interp=
olate0
        : interpolate0 =3D interpolate$$1(string00 =3D string0, string10 =
=3D string1);
  };
}

function styleRemove$1(name) {
  return function() {
    this.style.removeProperty(name);
  };
}

function styleConstant$1(name, interpolate$$1, value1) {
  var string00,
      string1 =3D value1 + "",
      interpolate0;
  return function() {
    var string0 =3D styleValue(this, name);
    return string0 =3D=3D=3D string1 ? null
        : string0 =3D=3D=3D string00 ? interpolate0
        : interpolate0 =3D interpolate$$1(string00 =3D string0, value1);
  };
}

function styleFunction$1(name, interpolate$$1, value) {
  var string00,
      string10,
      interpolate0;
  return function() {
    var string0 =3D styleValue(this, name),
        value1 =3D value(this),
        string1 =3D value1 + "";
    if (value1 =3D=3D null) string1 =3D value1 =3D (this.style.removeProper=
ty(name), styleValue(this, name));
    return string0 =3D=3D=3D string1 ? null
        : string0 =3D=3D=3D string00 && string1 =3D=3D=3D string10 ? interp=
olate0
        : (string10 =3D string1, interpolate0 =3D interpolate$$1(string00 =
=3D string0, value1));
  };
}

function styleMaybeRemove(id, name) {
  var on0, on1, listener0, key =3D "style." + name, event =3D "end." + key,=
 remove;
  return function() {
    var schedule$$1 =3D set$1(this, id),
        on =3D schedule$$1.on,
        listener =3D schedule$$1.value[key] =3D=3D null ? remove || (remove=
 =3D styleRemove$1(name)) : undefined;

    // If this node shared a dispatch with the previous node,
    // just assign the updated shared dispatch and we=E2=80=99re done!
    // Otherwise, copy-on-write.
    if (on !=3D=3D on0 || listener0 !=3D=3D listener) (on1 =3D (on0 =3D on)=
=2Ecopy()).on(event, listener0 =3D listener);

    schedule$$1.on =3D on1;
  };
}

function transition_style(name, value, priority) {
  var i =3D (name +=3D "") =3D=3D=3D "transform" ? interpolateTransformCss =
: interpolate;
  return value =3D=3D null ? this
      .styleTween(name, styleNull(name, i))
      .on("end.style." + name, styleRemove$1(name))
    : typeof value =3D=3D=3D "function" ? this
      .styleTween(name, styleFunction$1(name, i, tweenValue(this, "style." =
+ name, value)))
      .each(styleMaybeRemove(this._id, name))
    : this
      .styleTween(name, styleConstant$1(name, i, value), priority)
      .on("end.style." + name, null);
}

function styleInterpolate(name, i, priority) {
  return function(t) {
    this.style.setProperty(name, i(t), priority);
  };
}

function styleTween(name, value, priority) {
  var t, i0;
  function tween() {
    var i =3D value.apply(this, arguments);
    if (i !=3D=3D i0) t =3D (i0 =3D i) && styleInterpolate(name, i, priorit=
y);
    return t;
  }
  tween._value =3D value;
  return tween;
}

function transition_styleTween(name, value, priority) {
  var key =3D "style." + (name +=3D "");
  if (arguments.length < 2) return (key =3D this.tween(key)) && key._value;
  if (value =3D=3D null) return this.tween(key, null);
  if (typeof value !=3D=3D "function") throw new Error;
  return this.tween(key, styleTween(name, value, priority =3D=3D null ? "" =
: priority));
}

function textConstant$1(value) {
  return function() {
    this.textContent =3D value;
  };
}

function textFunction$1(value) {
  return function() {
    var value1 =3D value(this);
    this.textContent =3D value1 =3D=3D null ? "" : value1;
  };
}

function transition_text(value) {
  return this.tween("text", typeof value =3D=3D=3D "function"
      ? textFunction$1(tweenValue(this, "text", value))
      : textConstant$1(value =3D=3D null ? "" : value + ""));
}

function transition_transition() {
  var name =3D this._name,
      id0 =3D this._id,
      id1 =3D newId();

  for (var groups =3D this._groups, m =3D groups.length, j =3D 0; j < m; ++=
j) {
    for (var group =3D groups[j], n =3D group.length, node, i =3D 0; i < n;=
 ++i) {
      if (node =3D group[i]) {
        var inherit =3D get$1(node, id0);
        schedule(node, name, id1, i, group, {
          time: inherit.time + inherit.delay + inherit.duration,
          delay: 0,
          duration: inherit.duration,
          ease: inherit.ease
        });
      }
    }
  }

  return new Transition(groups, this._parents, name, id1);
}

function transition_end() {
  var on0, on1, that =3D this, id =3D that._id, size =3D that.size();
  return new Promise(function(resolve, reject) {
    var cancel =3D {value: reject},
        end =3D {value: function() { if (--size =3D=3D=3D 0) resolve(); }};

    that.each(function() {
      var schedule$$1 =3D set$1(this, id),
          on =3D schedule$$1.on;

      // If this node shared a dispatch with the previous node,
      // just assign the updated shared dispatch and we=E2=80=99re done!
      // Otherwise, copy-on-write.
      if (on !=3D=3D on0) {
        on1 =3D (on0 =3D on).copy();
        on1._.cancel.push(cancel);
        on1._.interrupt.push(cancel);
        on1._.end.push(end);
      }

      schedule$$1.on =3D on1;
    });
  });
}

var id =3D 0;

function Transition(groups, parents, name, id) {
  this._groups =3D groups;
  this._parents =3D parents;
  this._name =3D name;
  this._id =3D id;
}

function transition(name) {
  return selection().transition(name);
}

function newId() {
  return ++id;
}

var selection_prototype =3D selection.prototype;

Transition.prototype =3D transition.prototype =3D {
  constructor: Transition,
  select: transition_select,
  selectAll: transition_selectAll,
  filter: transition_filter,
  merge: transition_merge,
  selection: transition_selection,
  transition: transition_transition,
  call: selection_prototype.call,
  nodes: selection_prototype.nodes,
  node: selection_prototype.node,
  size: selection_prototype.size,
  empty: selection_prototype.empty,
  each: selection_prototype.each,
  on: transition_on,
  attr: transition_attr,
  attrTween: transition_attrTween,
  style: transition_style,
  styleTween: transition_styleTween,
  text: transition_text,
  remove: transition_remove,
  tween: transition_tween,
  delay: transition_delay,
  duration: transition_duration,
  ease: transition_ease,
  end: transition_end
};

function linear$1(t) {
  return +t;
}

function quadIn(t) {
  return t * t;
}

function quadOut(t) {
  return t * (2 - t);
}

function quadInOut(t) {
  return ((t *=3D 2) <=3D 1 ? t * t : --t * (2 - t) + 1) / 2;
}

function cubicIn(t) {
  return t * t * t;
}

function cubicOut(t) {
  return --t * t * t + 1;
}

function cubicInOut(t) {
  return ((t *=3D 2) <=3D 1 ? t * t * t : (t -=3D 2) * t * t + 2) / 2;
}

var exponent =3D 3;

var polyIn =3D (function custom(e) {
  e =3D +e;

  function polyIn(t) {
    return Math.pow(t, e);
  }

  polyIn.exponent =3D custom;

  return polyIn;
})(exponent);

var polyOut =3D (function custom(e) {
  e =3D +e;

  function polyOut(t) {
    return 1 - Math.pow(1 - t, e);
  }

  polyOut.exponent =3D custom;

  return polyOut;
})(exponent);

var polyInOut =3D (function custom(e) {
  e =3D +e;

  function polyInOut(t) {
    return ((t *=3D 2) <=3D 1 ? Math.pow(t, e) : 2 - Math.pow(2 - t, e)) / =
2;
  }

  polyInOut.exponent =3D custom;

  return polyInOut;
})(exponent);

var pi =3D Math.PI,
    halfPi =3D pi / 2;

function sinIn(t) {
  return 1 - Math.cos(t * halfPi);
}

function sinOut(t) {
  return Math.sin(t * halfPi);
}

function sinInOut(t) {
  return (1 - Math.cos(pi * t)) / 2;
}

function expIn(t) {
  return Math.pow(2, 10 * t - 10);
}

function expOut(t) {
  return 1 - Math.pow(2, -10 * t);
}

function expInOut(t) {
  return ((t *=3D 2) <=3D 1 ? Math.pow(2, 10 * t - 10) : 2 - Math.pow(2, 10=
 - 10 * t)) / 2;
}

function circleIn(t) {
  return 1 - Math.sqrt(1 - t * t);
}

function circleOut(t) {
  return Math.sqrt(1 - --t * t);
}

function circleInOut(t) {
  return ((t *=3D 2) <=3D 1 ? 1 - Math.sqrt(1 - t * t) : Math.sqrt(1 - (t -=
=3D 2) * t) + 1) / 2;
}

var b1 =3D 4 / 11,
    b2 =3D 6 / 11,
    b3 =3D 8 / 11,
    b4 =3D 3 / 4,
    b5 =3D 9 / 11,
    b6 =3D 10 / 11,
    b7 =3D 15 / 16,
    b8 =3D 21 / 22,
    b9 =3D 63 / 64,
    b0 =3D 1 / b1 / b1;

function bounceIn(t) {
  return 1 - bounceOut(1 - t);
}

function bounceOut(t) {
  return (t =3D +t) < b1 ? b0 * t * t : t < b3 ? b0 * (t -=3D b2) * t + b4 =
: t < b6 ? b0 * (t -=3D b5) * t + b7 : b0 * (t -=3D b8) * t + b9;
}

function bounceInOut(t) {
  return ((t *=3D 2) <=3D 1 ? 1 - bounceOut(1 - t) : bounceOut(t - 1) + 1) =
/ 2;
}

var overshoot =3D 1.70158;

var backIn =3D (function custom(s) {
  s =3D +s;

  function backIn(t) {
    return t * t * ((s + 1) * t - s);
  }

  backIn.overshoot =3D custom;

  return backIn;
})(overshoot);

var backOut =3D (function custom(s) {
  s =3D +s;

  function backOut(t) {
    return --t * t * ((s + 1) * t + s) + 1;
  }

  backOut.overshoot =3D custom;

  return backOut;
})(overshoot);

var backInOut =3D (function custom(s) {
  s =3D +s;

  function backInOut(t) {
    return ((t *=3D 2) < 1 ? t * t * ((s + 1) * t - s) : (t -=3D 2) * t * (=
(s + 1) * t + s) + 2) / 2;
  }

  backInOut.overshoot =3D custom;

  return backInOut;
})(overshoot);

var tau =3D 2 * Math.PI,
    amplitude =3D 1,
    period =3D 0.3;

var elasticIn =3D (function custom(a, p) {
  var s =3D Math.asin(1 / (a =3D Math.max(1, a))) * (p /=3D tau);

  function elasticIn(t) {
    return a * Math.pow(2, 10 * --t) * Math.sin((s - t) / p);
  }

  elasticIn.amplitude =3D function(a) { return custom(a, p * tau); };
  elasticIn.period =3D function(p) { return custom(a, p); };

  return elasticIn;
})(amplitude, period);

var elasticOut =3D (function custom(a, p) {
  var s =3D Math.asin(1 / (a =3D Math.max(1, a))) * (p /=3D tau);

  function elasticOut(t) {
    return 1 - a * Math.pow(2, -10 * (t =3D +t)) * Math.sin((t + s) / p);
  }

  elasticOut.amplitude =3D function(a) { return custom(a, p * tau); };
  elasticOut.period =3D function(p) { return custom(a, p); };

  return elasticOut;
})(amplitude, period);

var elasticInOut =3D (function custom(a, p) {
  var s =3D Math.asin(1 / (a =3D Math.max(1, a))) * (p /=3D tau);

  function elasticInOut(t) {
    return ((t =3D t * 2 - 1) < 0
        ? a * Math.pow(2, 10 * t) * Math.sin((s - t) / p)
        : 2 - a * Math.pow(2, -10 * t) * Math.sin((s + t) / p)) / 2;
  }

  elasticInOut.amplitude =3D function(a) { return custom(a, p * tau); };
  elasticInOut.period =3D function(p) { return custom(a, p); };

  return elasticInOut;
})(amplitude, period);

var defaultTiming =3D {
  time: null, // Set on use.
  delay: 0,
  duration: 250,
  ease: cubicInOut
};

function inherit(node, id) {
  var timing;
  while (!(timing =3D node.__transition) || !(timing =3D timing[id])) {
    if (!(node =3D node.parentNode)) {
      return defaultTiming.time =3D now(), defaultTiming;
    }
  }
  return timing;
}

function selection_transition(name) {
  var id,
      timing;

  if (name instanceof Transition) {
    id =3D name._id, name =3D name._name;
  } else {
    id =3D newId(), (timing =3D defaultTiming).time =3D now(), name =3D nam=
e =3D=3D null ? null : name + "";
  }

  for (var groups =3D this._groups, m =3D groups.length, j =3D 0; j < m; ++=
j) {
    for (var group =3D groups[j], n =3D group.length, node, i =3D 0; i < n;=
 ++i) {
      if (node =3D group[i]) {
        schedule(node, name, id, i, group, timing || inherit(node, id));
      }
    }
  }

  return new Transition(groups, this._parents, name, id);
}

selection.prototype.interrupt =3D selection_interrupt;
selection.prototype.transition =3D selection_transition;

var root$1 =3D [null];

function active(node, name) {
  var schedules =3D node.__transition,
      schedule$$1,
      i;

  if (schedules) {
    name =3D name =3D=3D null ? null : name + "";
    for (i in schedules) {
      if ((schedule$$1 =3D schedules[i]).state > SCHEDULED && schedule$$1.n=
ame =3D=3D=3D name) {
        return new Transition([[node]], root$1, name, +i);
      }
    }
  }

  return null;
}

function constant$4(x) {
  return function() {
    return x;
  };
}

function BrushEvent(target, type, selection) {
  this.target =3D target;
  this.type =3D type;
  this.selection =3D selection;
}

function nopropagation$1() {
  exports.event.stopImmediatePropagation();
}

function noevent$1() {
  exports.event.preventDefault();
  exports.event.stopImmediatePropagation();
}

var MODE_DRAG =3D {name: "drag"},
    MODE_SPACE =3D {name: "space"},
    MODE_HANDLE =3D {name: "handle"},
    MODE_CENTER =3D {name: "center"};

var X =3D {
  name: "x",
  handles: ["e", "w"].map(type),
  input: function(x, e) { return x && [[x[0], e[0][1]], [x[1], e[1][1]]]; },
  output: function(xy) { return xy && [xy[0][0], xy[1][0]]; }
};

var Y =3D {
  name: "y",
  handles: ["n", "s"].map(type),
  input: function(y, e) { return y && [[e[0][0], y[0]], [e[1][0], y[1]]]; },
  output: function(xy) { return xy && [xy[0][1], xy[1][1]]; }
};

var XY =3D {
  name: "xy",
  handles: ["n", "e", "s", "w", "nw", "ne", "se", "sw"].map(type),
  input: function(xy) { return xy; },
  output: function(xy) { return xy; }
};

var cursors =3D {
  overlay: "crosshair",
  selection: "move",
  n: "ns-resize",
  e: "ew-resize",
  s: "ns-resize",
  w: "ew-resize",
  nw: "nwse-resize",
  ne: "nesw-resize",
  se: "nwse-resize",
  sw: "nesw-resize"
};

var flipX =3D {
  e: "w",
  w: "e",
  nw: "ne",
  ne: "nw",
  se: "sw",
  sw: "se"
};

var flipY =3D {
  n: "s",
  s: "n",
  nw: "sw",
  ne: "se",
  se: "ne",
  sw: "nw"
};

var signsX =3D {
  overlay: +1,
  selection: +1,
  n: null,
  e: +1,
  s: null,
  w: -1,
  nw: -1,
  ne: +1,
  se: +1,
  sw: -1
};

var signsY =3D {
  overlay: +1,
  selection: +1,
  n: -1,
  e: null,
  s: +1,
  w: null,
  nw: -1,
  ne: -1,
  se: +1,
  sw: +1
};

function type(t) {
  return {type: t};
}

// Ignore right-click, since that should open the context menu.
function defaultFilter$1() {
  return !exports.event.button;
}

function defaultExtent() {
  var svg =3D this.ownerSVGElement || this;
  return [[0, 0], [svg.width.baseVal.value, svg.height.baseVal.value]];
}

// Like d3.local, but with the name =E2=80=9C__brush=E2=80=9D rather than a=
uto-generated.
function local$1(node) {
  while (!node.__brush) if (!(node =3D node.parentNode)) return;
  return node.__brush;
}

function empty$1(extent) {
  return extent[0][0] =3D=3D=3D extent[1][0]
      || extent[0][1] =3D=3D=3D extent[1][1];
}

function brushSelection(node) {
  var state =3D node.__brush;
  return state ? state.dim.output(state.selection) : null;
}

function brushX() {
  return brush$1(X);
}

function brushY() {
  return brush$1(Y);
}

function brush() {
  return brush$1(XY);
}

function brush$1(dim) {
  var extent =3D defaultExtent,
      filter =3D defaultFilter$1,
      listeners =3D dispatch(brush, "start", "brush", "end"),
      handleSize =3D 6,
      touchending;

  function brush(group) {
    var overlay =3D group
        .property("__brush", initialize)
      .selectAll(".overlay")
      .data([type("overlay")]);

    overlay.enter().append("rect")
        .attr("class", "overlay")
        .attr("pointer-events", "all")
        .attr("cursor", cursors.overlay)
      .merge(overlay)
        .each(function() {
          var extent =3D local$1(this).extent;
          select(this)
              .attr("x", extent[0][0])
              .attr("y", extent[0][1])
              .attr("width", extent[1][0] - extent[0][0])
              .attr("height", extent[1][1] - extent[0][1]);
        });

    group.selectAll(".selection")
      .data([type("selection")])
      .enter().append("rect")
        .attr("class", "selection")
        .attr("cursor", cursors.selection)
        .attr("fill", "#777")
        .attr("fill-opacity", 0.3)
        .attr("stroke", "#fff")
        .attr("shape-rendering", "crispEdges");

    var handle =3D group.selectAll(".handle")
      .data(dim.handles, function(d) { return d.type; });

    handle.exit().remove();

    handle.enter().append("rect")
        .attr("class", function(d) { return "handle handle--" + d.type; })
        .attr("cursor", function(d) { return cursors[d.type]; });

    group
        .each(redraw)
        .attr("fill", "none")
        .attr("pointer-events", "all")
        .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)")
        .on("mousedown.brush touchstart.brush", started);
  }

  brush.move =3D function(group, selection$$1) {
    if (group.selection) {
      group
          .on("start.brush", function() { emitter(this, arguments).beforest=
art().start(); })
          .on("interrupt.brush end.brush", function() { emitter(this, argum=
ents).end(); })
          .tween("brush", function() {
            var that =3D this,
                state =3D that.__brush,
                emit =3D emitter(that, arguments),
                selection0 =3D state.selection,
                selection1 =3D dim.input(typeof selection$$1 =3D=3D=3D "fun=
ction" ? selection$$1.apply(this, arguments) : selection$$1, state.extent),
                i =3D interpolateValue(selection0, selection1);

            function tween(t) {
              state.selection =3D t =3D=3D=3D 1 && empty$1(selection1) ? nu=
ll : i(t);
              redraw.call(that);
              emit.brush();
            }

            return selection0 && selection1 ? tween : tween(1);
          });
    } else {
      group
          .each(function() {
            var that =3D this,
                args =3D arguments,
                state =3D that.__brush,
                selection1 =3D dim.input(typeof selection$$1 =3D=3D=3D "fun=
ction" ? selection$$1.apply(that, args) : selection$$1, state.extent),
                emit =3D emitter(that, args).beforestart();

            interrupt(that);
            state.selection =3D selection1 =3D=3D null || empty$1(selection=
1) ? null : selection1;
            redraw.call(that);
            emit.start().brush().end();
          });
    }
  };

  function redraw() {
    var group =3D select(this),
        selection$$1 =3D local$1(this).selection;

    if (selection$$1) {
      group.selectAll(".selection")
          .style("display", null)
          .attr("x", selection$$1[0][0])
          .attr("y", selection$$1[0][1])
          .attr("width", selection$$1[1][0] - selection$$1[0][0])
          .attr("height", selection$$1[1][1] - selection$$1[0][1]);

      group.selectAll(".handle")
          .style("display", null)
          .attr("x", function(d) { return d.type[d.type.length - 1] =3D=3D=
=3D "e" ? selection$$1[1][0] - handleSize / 2 : selection$$1[0][0] - handle=
Size / 2; })
          .attr("y", function(d) { return d.type[0] =3D=3D=3D "s" ? selecti=
on$$1[1][1] - handleSize / 2 : selection$$1[0][1] - handleSize / 2; })
          .attr("width", function(d) { return d.type =3D=3D=3D "n" || d.typ=
e =3D=3D=3D "s" ? selection$$1[1][0] - selection$$1[0][0] + handleSize : ha=
ndleSize; })
          .attr("height", function(d) { return d.type =3D=3D=3D "e" || d.ty=
pe =3D=3D=3D "w" ? selection$$1[1][1] - selection$$1[0][1] + handleSize : h=
andleSize; });
    }

    else {
      group.selectAll(".selection,.handle")
          .style("display", "none")
          .attr("x", null)
          .attr("y", null)
          .attr("width", null)
          .attr("height", null);
    }
  }

  function emitter(that, args) {
    return that.__brush.emitter || new Emitter(that, args);
  }

  function Emitter(that, args) {
    this.that =3D that;
    this.args =3D args;
    this.state =3D that.__brush;
    this.active =3D 0;
  }

  Emitter.prototype =3D {
    beforestart: function() {
      if (++this.active =3D=3D=3D 1) this.state.emitter =3D this, this.star=
ting =3D true;
      return this;
    },
    start: function() {
      if (this.starting) this.starting =3D false, this.emit("start");
      return this;
    },
    brush: function() {
      this.emit("brush");
      return this;
    },
    end: function() {
      if (--this.active =3D=3D=3D 0) delete this.state.emitter, this.emit("=
end");
      return this;
    },
    emit: function(type) {
      customEvent(new BrushEvent(brush, type, dim.output(this.state.selecti=
on)), listeners.apply, listeners, [type, this.that, this.args]);
    }
  };

  function started() {
    if (exports.event.touches) { if (exports.event.changedTouches.length < =
exports.event.touches.length) return noevent$1(); }
    else if (touchending) return;
    if (!filter.apply(this, arguments)) return;

    var that =3D this,
        type =3D exports.event.target.__data__.type,
        mode =3D (exports.event.metaKey ? type =3D "overlay" : type) =3D=3D=
=3D "selection" ? MODE_DRAG : (exports.event.altKey ? MODE_CENTER : MODE_HA=
NDLE),
        signX =3D dim =3D=3D=3D Y ? null : signsX[type],
        signY =3D dim =3D=3D=3D X ? null : signsY[type],
        state =3D local$1(that),
        extent =3D state.extent,
        selection$$1 =3D state.selection,
        W =3D extent[0][0], w0, w1,
        N =3D extent[0][1], n0, n1,
        E =3D extent[1][0], e0, e1,
        S =3D extent[1][1], s0, s1,
        dx,
        dy,
        moving,
        shifting =3D signX && signY && exports.event.shiftKey,
        lockX,
        lockY,
        point0 =3D mouse(that),
        point$$1 =3D point0,
        emit =3D emitter(that, arguments).beforestart();

    if (type =3D=3D=3D "overlay") {
      state.selection =3D selection$$1 =3D [
        [w0 =3D dim =3D=3D=3D Y ? W : point0[0], n0 =3D dim =3D=3D=3D X ? N=
 : point0[1]],
        [e0 =3D dim =3D=3D=3D Y ? E : w0, s0 =3D dim =3D=3D=3D X ? S : n0]
      ];
    } else {
      w0 =3D selection$$1[0][0];
      n0 =3D selection$$1[0][1];
      e0 =3D selection$$1[1][0];
      s0 =3D selection$$1[1][1];
    }

    w1 =3D w0;
    n1 =3D n0;
    e1 =3D e0;
    s1 =3D s0;

    var group =3D select(that)
        .attr("pointer-events", "none");

    var overlay =3D group.selectAll(".overlay")
        .attr("cursor", cursors[type]);

    if (exports.event.touches) {
      group
          .on("touchmove.brush", moved, true)
          .on("touchend.brush touchcancel.brush", ended, true);
    } else {
      var view =3D select(exports.event.view)
          .on("keydown.brush", keydowned, true)
          .on("keyup.brush", keyupped, true)
          .on("mousemove.brush", moved, true)
          .on("mouseup.brush", ended, true);

      dragDisable(exports.event.view);
    }

    nopropagation$1();
    interrupt(that);
    redraw.call(that);
    emit.start();

    function moved() {
      var point1 =3D mouse(that);
      if (shifting && !lockX && !lockY) {
        if (Math.abs(point1[0] - point$$1[0]) > Math.abs(point1[1] - point$=
$1[1])) lockY =3D true;
        else lockX =3D true;
      }
      point$$1 =3D point1;
      moving =3D true;
      noevent$1();
      move();
    }

    function move() {
      var t;

      dx =3D point$$1[0] - point0[0];
      dy =3D point$$1[1] - point0[1];

      switch (mode) {
        case MODE_SPACE:
        case MODE_DRAG: {
          if (signX) dx =3D Math.max(W - w0, Math.min(E - e0, dx)), w1 =3D =
w0 + dx, e1 =3D e0 + dx;
          if (signY) dy =3D Math.max(N - n0, Math.min(S - s0, dy)), n1 =3D =
n0 + dy, s1 =3D s0 + dy;
          break;
        }
        case MODE_HANDLE: {
          if (signX < 0) dx =3D Math.max(W - w0, Math.min(E - w0, dx)), w1 =
=3D w0 + dx, e1 =3D e0;
          else if (signX > 0) dx =3D Math.max(W - e0, Math.min(E - e0, dx))=
, w1 =3D w0, e1 =3D e0 + dx;
          if (signY < 0) dy =3D Math.max(N - n0, Math.min(S - n0, dy)), n1 =
=3D n0 + dy, s1 =3D s0;
          else if (signY > 0) dy =3D Math.max(N - s0, Math.min(S - s0, dy))=
, n1 =3D n0, s1 =3D s0 + dy;
          break;
        }
        case MODE_CENTER: {
          if (signX) w1 =3D Math.max(W, Math.min(E, w0 - dx * signX)), e1 =
=3D Math.max(W, Math.min(E, e0 + dx * signX));
          if (signY) n1 =3D Math.max(N, Math.min(S, n0 - dy * signY)), s1 =
=3D Math.max(N, Math.min(S, s0 + dy * signY));
          break;
        }
      }

      if (e1 < w1) {
        signX *=3D -1;
        t =3D w0, w0 =3D e0, e0 =3D t;
        t =3D w1, w1 =3D e1, e1 =3D t;
        if (type in flipX) overlay.attr("cursor", cursors[type =3D flipX[ty=
pe]]);
      }

      if (s1 < n1) {
        signY *=3D -1;
        t =3D n0, n0 =3D s0, s0 =3D t;
        t =3D n1, n1 =3D s1, s1 =3D t;
        if (type in flipY) overlay.attr("cursor", cursors[type =3D flipY[ty=
pe]]);
      }

      if (state.selection) selection$$1 =3D state.selection; // May be set =
by brush.move!
      if (lockX) w1 =3D selection$$1[0][0], e1 =3D selection$$1[1][0];
      if (lockY) n1 =3D selection$$1[0][1], s1 =3D selection$$1[1][1];

      if (selection$$1[0][0] !=3D=3D w1
          || selection$$1[0][1] !=3D=3D n1
          || selection$$1[1][0] !=3D=3D e1
          || selection$$1[1][1] !=3D=3D s1) {
        state.selection =3D [[w1, n1], [e1, s1]];
        redraw.call(that);
        emit.brush();
      }
    }

    function ended() {
      nopropagation$1();
      if (exports.event.touches) {
        if (exports.event.touches.length) return;
        if (touchending) clearTimeout(touchending);
        touchending =3D setTimeout(function() { touchending =3D null; }, 50=
0); // Ghost clicks are delayed!
        group.on("touchmove.brush touchend.brush touchcancel.brush", null);
      } else {
        yesdrag(exports.event.view, moving);
        view.on("keydown.brush keyup.brush mousemove.brush mouseup.brush", =
null);
      }
      group.attr("pointer-events", "all");
      overlay.attr("cursor", cursors.overlay);
      if (state.selection) selection$$1 =3D state.selection; // May be set =
by brush.move (on start)!
      if (empty$1(selection$$1)) state.selection =3D null, redraw.call(that=
);
      emit.end();
    }

    function keydowned() {
      switch (exports.event.keyCode) {
        case 16: { // SHIFT
          shifting =3D signX && signY;
          break;
        }
        case 18: { // ALT
          if (mode =3D=3D=3D MODE_HANDLE) {
            if (signX) e0 =3D e1 - dx * signX, w0 =3D w1 + dx * signX;
            if (signY) s0 =3D s1 - dy * signY, n0 =3D n1 + dy * signY;
            mode =3D MODE_CENTER;
            move();
          }
          break;
        }
        case 32: { // SPACE; takes priority over ALT
          if (mode =3D=3D=3D MODE_HANDLE || mode =3D=3D=3D MODE_CENTER) {
            if (signX < 0) e0 =3D e1 - dx; else if (signX > 0) w0 =3D w1 - =
dx;
            if (signY < 0) s0 =3D s1 - dy; else if (signY > 0) n0 =3D n1 - =
dy;
            mode =3D MODE_SPACE;
            overlay.attr("cursor", cursors.selection);
            move();
          }
          break;
        }
        default: return;
      }
      noevent$1();
    }

    function keyupped() {
      switch (exports.event.keyCode) {
        case 16: { // SHIFT
          if (shifting) {
            lockX =3D lockY =3D shifting =3D false;
            move();
          }
          break;
        }
        case 18: { // ALT
          if (mode =3D=3D=3D MODE_CENTER) {
            if (signX < 0) e0 =3D e1; else if (signX > 0) w0 =3D w1;
            if (signY < 0) s0 =3D s1; else if (signY > 0) n0 =3D n1;
            mode =3D MODE_HANDLE;
            move();
          }
          break;
        }
        case 32: { // SPACE
          if (mode =3D=3D=3D MODE_SPACE) {
            if (exports.event.altKey) {
              if (signX) e0 =3D e1 - dx * signX, w0 =3D w1 + dx * signX;
              if (signY) s0 =3D s1 - dy * signY, n0 =3D n1 + dy * signY;
              mode =3D MODE_CENTER;
            } else {
              if (signX < 0) e0 =3D e1; else if (signX > 0) w0 =3D w1;
              if (signY < 0) s0 =3D s1; else if (signY > 0) n0 =3D n1;
              mode =3D MODE_HANDLE;
            }
            overlay.attr("cursor", cursors[type]);
            move();
          }
          break;
        }
        default: return;
      }
      noevent$1();
    }
  }

  function initialize() {
    var state =3D this.__brush || {selection: null};
    state.extent =3D extent.apply(this, arguments);
    state.dim =3D dim;
    return state;
  }

  brush.extent =3D function(_) {
    return arguments.length ? (extent =3D typeof _ =3D=3D=3D "function" ? _=
 : constant$4([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), brush) : exten=
t;
  };

  brush.filter =3D function(_) {
    return arguments.length ? (filter =3D typeof _ =3D=3D=3D "function" ? _=
 : constant$4(!!_), brush) : filter;
  };

  brush.handleSize =3D function(_) {
    return arguments.length ? (handleSize =3D +_, brush) : handleSize;
  };

  brush.on =3D function() {
    var value =3D listeners.on.apply(listeners, arguments);
    return value =3D=3D=3D listeners ? brush : value;
  };

  return brush;
}

var cos =3D Math.cos;
var sin =3D Math.sin;
var pi$1 =3D Math.PI;
var halfPi$1 =3D pi$1 / 2;
var tau$1 =3D pi$1 * 2;
var max$1 =3D Math.max;

function compareValue(compare) {
  return function(a, b) {
    return compare(
      a.source.value + a.target.value,
      b.source.value + b.target.value
    );
  };
}

function chord() {
  var padAngle =3D 0,
      sortGroups =3D null,
      sortSubgroups =3D null,
      sortChords =3D null;

  function chord(matrix) {
    var n =3D matrix.length,
        groupSums =3D [],
        groupIndex =3D sequence(n),
        subgroupIndex =3D [],
        chords =3D [],
        groups =3D chords.groups =3D new Array(n),
        subgroups =3D new Array(n * n),
        k,
        x,
        x0,
        dx,
        i,
        j;

    // Compute the sum.
    k =3D 0, i =3D -1; while (++i < n) {
      x =3D 0, j =3D -1; while (++j < n) {
        x +=3D matrix[i][j];
      }
      groupSums.push(x);
      subgroupIndex.push(sequence(n));
      k +=3D x;
    }

    // Sort groups=E2=80=A6
    if (sortGroups) groupIndex.sort(function(a, b) {
      return sortGroups(groupSums[a], groupSums[b]);
    });

    // Sort subgroups=E2=80=A6
    if (sortSubgroups) subgroupIndex.forEach(function(d, i) {
      d.sort(function(a, b) {
        return sortSubgroups(matrix[i][a], matrix[i][b]);
      });
    });

    // Convert the sum to scaling factor for [0, 2pi].
    // TODO Allow start and end angle to be specified?
    // TODO Allow padding to be specified as percentage?
    k =3D max$1(0, tau$1 - padAngle * n) / k;
    dx =3D k ? padAngle : tau$1 / n;

    // Compute the start and end angle for each group and subgroup.
    // Note: Opera has a bug reordering object literal properties!
    x =3D 0, i =3D -1; while (++i < n) {
      x0 =3D x, j =3D -1; while (++j < n) {
        var di =3D groupIndex[i],
            dj =3D subgroupIndex[di][j],
            v =3D matrix[di][dj],
            a0 =3D x,
            a1 =3D x +=3D v * k;
        subgroups[dj * n + di] =3D {
          index: di,
          subindex: dj,
          startAngle: a0,
          endAngle: a1,
          value: v
        };
      }
      groups[di] =3D {
        index: di,
        startAngle: x0,
        endAngle: x,
        value: groupSums[di]
      };
      x +=3D dx;
    }

    // Generate chords for each (non-empty) subgroup-subgroup link.
    i =3D -1; while (++i < n) {
      j =3D i - 1; while (++j < n) {
        var source =3D subgroups[j * n + i],
            target =3D subgroups[i * n + j];
        if (source.value || target.value) {
          chords.push(source.value < target.value
              ? {source: target, target: source}
              : {source: source, target: target});
        }
      }
    }

    return sortChords ? chords.sort(sortChords) : chords;
  }

  chord.padAngle =3D function(_) {
    return arguments.length ? (padAngle =3D max$1(0, _), chord) : padAngle;
  };

  chord.sortGroups =3D function(_) {
    return arguments.length ? (sortGroups =3D _, chord) : sortGroups;
  };

  chord.sortSubgroups =3D function(_) {
    return arguments.length ? (sortSubgroups =3D _, chord) : sortSubgroups;
  };

  chord.sortChords =3D function(_) {
    return arguments.length ? (_ =3D=3D null ? sortChords =3D null : (sortC=
hords =3D compareValue(_))._ =3D _, chord) : sortChords && sortChords._;
  };

  return chord;
}

var slice$2 =3D Array.prototype.slice;

function constant$5(x) {
  return function() {
    return x;
  };
}

var pi$2 =3D Math.PI,
    tau$2 =3D 2 * pi$2,
    epsilon$1 =3D 1e-6,
    tauEpsilon =3D tau$2 - epsilon$1;

function Path() {
  this._x0 =3D this._y0 =3D // start of current subpath
  this._x1 =3D this._y1 =3D null; // end of current subpath
  this._ =3D "";
}

function path() {
  return new Path;
}

Path.prototype =3D path.prototype =3D {
  constructor: Path,
  moveTo: function(x, y) {
    this._ +=3D "M" + (this._x0 =3D this._x1 =3D +x) + "," + (this._y0 =3D =
this._y1 =3D +y);
  },
  closePath: function() {
    if (this._x1 !=3D=3D null) {
      this._x1 =3D this._x0, this._y1 =3D this._y0;
      this._ +=3D "Z";
    }
  },
  lineTo: function(x, y) {
    this._ +=3D "L" + (this._x1 =3D +x) + "," + (this._y1 =3D +y);
  },
  quadraticCurveTo: function(x1, y1, x, y) {
    this._ +=3D "Q" + (+x1) + "," + (+y1) + "," + (this._x1 =3D +x) + "," +=
 (this._y1 =3D +y);
  },
  bezierCurveTo: function(x1, y1, x2, y2, x, y) {
    this._ +=3D "C" + (+x1) + "," + (+y1) + "," + (+x2) + "," + (+y2) + ","=
 + (this._x1 =3D +x) + "," + (this._y1 =3D +y);
  },
  arcTo: function(x1, y1, x2, y2, r) {
    x1 =3D +x1, y1 =3D +y1, x2 =3D +x2, y2 =3D +y2, r =3D +r;
    var x0 =3D this._x1,
        y0 =3D this._y1,
        x21 =3D x2 - x1,
        y21 =3D y2 - y1,
        x01 =3D x0 - x1,
        y01 =3D y0 - y1,
        l01_2 =3D x01 * x01 + y01 * y01;

    // Is the radius negative? Error.
    if (r < 0) throw new Error("negative radius: " + r);

    // Is this path empty? Move to (x1,y1).
    if (this._x1 =3D=3D=3D null) {
      this._ +=3D "M" + (this._x1 =3D x1) + "," + (this._y1 =3D y1);
    }

    // Or, is (x1,y1) coincident with (x0,y0)? Do nothing.
    else if (!(l01_2 > epsilon$1));

    // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?
    // Equivalently, is (x1,y1) coincident with (x2,y2)?
    // Or, is the radius zero? Line to (x1,y1).
    else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon$1) || !r) {
      this._ +=3D "L" + (this._x1 =3D x1) + "," + (this._y1 =3D y1);
    }

    // Otherwise, draw an arc!
    else {
      var x20 =3D x2 - x0,
          y20 =3D y2 - y0,
          l21_2 =3D x21 * x21 + y21 * y21,
          l20_2 =3D x20 * x20 + y20 * y20,
          l21 =3D Math.sqrt(l21_2),
          l01 =3D Math.sqrt(l01_2),
          l =3D r * Math.tan((pi$2 - Math.acos((l21_2 + l01_2 - l20_2) / (2=
 * l21 * l01))) / 2),
          t01 =3D l / l01,
          t21 =3D l / l21;

      // If the start tangent is not coincident with (x0,y0), line to.
      if (Math.abs(t01 - 1) > epsilon$1) {
        this._ +=3D "L" + (x1 + t01 * x01) + "," + (y1 + t01 * y01);
      }

      this._ +=3D "A" + r + "," + r + ",0,0," + (+(y01 * x20 > x01 * y20)) =
+ "," + (this._x1 =3D x1 + t21 * x21) + "," + (this._y1 =3D y1 + t21 * y21);
    }
  },
  arc: function(x, y, r, a0, a1, ccw) {
    x =3D +x, y =3D +y, r =3D +r;
    var dx =3D r * Math.cos(a0),
        dy =3D r * Math.sin(a0),
        x0 =3D x + dx,
        y0 =3D y + dy,
        cw =3D 1 ^ ccw,
        da =3D ccw ? a0 - a1 : a1 - a0;

    // Is the radius negative? Error.
    if (r < 0) throw new Error("negative radius: " + r);

    // Is this path empty? Move to (x0,y0).
    if (this._x1 =3D=3D=3D null) {
      this._ +=3D "M" + x0 + "," + y0;
    }

    // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y=
0).
    else if (Math.abs(this._x1 - x0) > epsilon$1 || Math.abs(this._y1 - y0)=
 > epsilon$1) {
      this._ +=3D "L" + x0 + "," + y0;
    }

    // Is this arc empty? We=E2=80=99re done.
    if (!r) return;

    // Does the angle go the wrong way? Flip the direction.
    if (da < 0) da =3D da % tau$2 + tau$2;

    // Is this a complete circle? Draw two arcs to complete the circle.
    if (da > tauEpsilon) {
      this._ +=3D "A" + r + "," + r + ",0,1," + cw + "," + (x - dx) + "," +=
 (y - dy) + "A" + r + "," + r + ",0,1," + cw + "," + (this._x1 =3D x0) + ",=
" + (this._y1 =3D y0);
    }

    // Is this arc non-empty? Draw an arc!
    else if (da > epsilon$1) {
      this._ +=3D "A" + r + "," + r + ",0," + (+(da >=3D pi$2)) + "," + cw =
+ "," + (this._x1 =3D x + r * Math.cos(a1)) + "," + (this._y1 =3D y + r * M=
ath.sin(a1));
    }
  },
  rect: function(x, y, w, h) {
    this._ +=3D "M" + (this._x0 =3D this._x1 =3D +x) + "," + (this._y0 =3D =
this._y1 =3D +y) + "h" + (+w) + "v" + (+h) + "h" + (-w) + "Z";
  },
  toString: function() {
    return this._;
  }
};

function defaultSource(d) {
  return d.source;
}

function defaultTarget(d) {
  return d.target;
}

function defaultRadius(d) {
  return d.radius;
}

function defaultStartAngle(d) {
  return d.startAngle;
}

function defaultEndAngle(d) {
  return d.endAngle;
}

function ribbon() {
  var source =3D defaultSource,
      target =3D defaultTarget,
      radius =3D defaultRadius,
      startAngle =3D defaultStartAngle,
      endAngle =3D defaultEndAngle,
      context =3D null;

  function ribbon() {
    var buffer,
        argv =3D slice$2.call(arguments),
        s =3D source.apply(this, argv),
        t =3D target.apply(this, argv),
        sr =3D +radius.apply(this, (argv[0] =3D s, argv)),
        sa0 =3D startAngle.apply(this, argv) - halfPi$1,
        sa1 =3D endAngle.apply(this, argv) - halfPi$1,
        sx0 =3D sr * cos(sa0),
        sy0 =3D sr * sin(sa0),
        tr =3D +radius.apply(this, (argv[0] =3D t, argv)),
        ta0 =3D startAngle.apply(this, argv) - halfPi$1,
        ta1 =3D endAngle.apply(this, argv) - halfPi$1;

    if (!context) context =3D buffer =3D path();

    context.moveTo(sx0, sy0);
    context.arc(0, 0, sr, sa0, sa1);
    if (sa0 !=3D=3D ta0 || sa1 !=3D=3D ta1) { // TODO sr !=3D=3D tr?
      context.quadraticCurveTo(0, 0, tr * cos(ta0), tr * sin(ta0));
      context.arc(0, 0, tr, ta0, ta1);
    }
    context.quadraticCurveTo(0, 0, sx0, sy0);
    context.closePath();

    if (buffer) return context =3D null, buffer + "" || null;
  }

  ribbon.radius =3D function(_) {
    return arguments.length ? (radius =3D typeof _ =3D=3D=3D "function" ? _=
 : constant$5(+_), ribbon) : radius;
  };

  ribbon.startAngle =3D function(_) {
    return arguments.length ? (startAngle =3D typeof _ =3D=3D=3D "function"=
 ? _ : constant$5(+_), ribbon) : startAngle;
  };

  ribbon.endAngle =3D function(_) {
    return arguments.length ? (endAngle =3D typeof _ =3D=3D=3D "function" ?=
 _ : constant$5(+_), ribbon) : endAngle;
  };

  ribbon.source =3D function(_) {
    return arguments.length ? (source =3D _, ribbon) : source;
  };

  ribbon.target =3D function(_) {
    return arguments.length ? (target =3D _, ribbon) : target;
  };

  ribbon.context =3D function(_) {
    return arguments.length ? ((context =3D _ =3D=3D null ? null : _), ribb=
on) : context;
  };

  return ribbon;
}

var prefix =3D "$";

function Map() {}

Map.prototype =3D map$1.prototype =3D {
  constructor: Map,
  has: function(key) {
    return (prefix + key) in this;
  },
  get: function(key) {
    return this[prefix + key];
  },
  set: function(key, value) {
    this[prefix + key] =3D value;
    return this;
  },
  remove: function(key) {
    var property =3D prefix + key;
    return property in this && delete this[property];
  },
  clear: function() {
    for (var property in this) if (property[0] =3D=3D=3D prefix) delete thi=
s[property];
  },
  keys: function() {
    var keys =3D [];
    for (var property in this) if (property[0] =3D=3D=3D prefix) keys.push(=
property.slice(1));
    return keys;
  },
  values: function() {
    var values =3D [];
    for (var property in this) if (property[0] =3D=3D=3D prefix) values.pus=
h(this[property]);
    return values;
  },
  entries: function() {
    var entries =3D [];
    for (var property in this) if (property[0] =3D=3D=3D prefix) entries.pu=
sh({key: property.slice(1), value: this[property]});
    return entries;
  },
  size: function() {
    var size =3D 0;
    for (var property in this) if (property[0] =3D=3D=3D prefix) ++size;
    return size;
  },
  empty: function() {
    for (var property in this) if (property[0] =3D=3D=3D prefix) return fal=
se;
    return true;
  },
  each: function(f) {
    for (var property in this) if (property[0] =3D=3D=3D prefix) f(this[pro=
perty], property.slice(1), this);
  }
};

function map$1(object, f) {
  var map =3D new Map;

  // Copy constructor.
  if (object instanceof Map) object.each(function(value, key) { map.set(key=
, value); });

  // Index array by numeric index or specified key function.
  else if (Array.isArray(object)) {
    var i =3D -1,
        n =3D object.length,
        o;

    if (f =3D=3D null) while (++i < n) map.set(i, object[i]);
    else while (++i < n) map.set(f(o =3D object[i], i, object), o);
  }

  // Convert object to map.
  else if (object) for (var key in object) map.set(key, object[key]);

  return map;
}

function nest() {
  var keys =3D [],
      sortKeys =3D [],
      sortValues,
      rollup,
      nest;

  function apply(array, depth, createResult, setResult) {
    if (depth >=3D keys.length) {
      if (sortValues !=3D null) array.sort(sortValues);
      return rollup !=3D null ? rollup(array) : array;
    }

    var i =3D -1,
        n =3D array.length,
        key =3D keys[depth++],
        keyValue,
        value,
        valuesByKey =3D map$1(),
        values,
        result =3D createResult();

    while (++i < n) {
      if (values =3D valuesByKey.get(keyValue =3D key(value =3D array[i]) +=
 "")) {
        values.push(value);
      } else {
        valuesByKey.set(keyValue, [value]);
      }
    }

    valuesByKey.each(function(values, key) {
      setResult(result, key, apply(values, depth, createResult, setResult));
    });

    return result;
  }

  function entries(map, depth) {
    if (++depth > keys.length) return map;
    var array, sortKey =3D sortKeys[depth - 1];
    if (rollup !=3D null && depth >=3D keys.length) array =3D map.entries();
    else array =3D [], map.each(function(v, k) { array.push({key: k, values=
: entries(v, depth)}); });
    return sortKey !=3D null ? array.sort(function(a, b) { return sortKey(a=
=2Ekey, b.key); }) : array;
  }

  return nest =3D {
    object: function(array) { return apply(array, 0, createObject, setObjec=
t); },
    map: function(array) { return apply(array, 0, createMap, setMap); },
    entries: function(array) { return entries(apply(array, 0, createMap, se=
tMap), 0); },
    key: function(d) { keys.push(d); return nest; },
    sortKeys: function(order) { sortKeys[keys.length - 1] =3D order; return=
 nest; },
    sortValues: function(order) { sortValues =3D order; return nest; },
    rollup: function(f) { rollup =3D f; return nest; }
  };
}

function createObject() {
  return {};
}

function setObject(object, key, value) {
  object[key] =3D value;
}

function createMap() {
  return map$1();
}

function setMap(map, key, value) {
  map.set(key, value);
}

function Set() {}

var proto =3D map$1.prototype;

Set.prototype =3D set$2.prototype =3D {
  constructor: Set,
  has: proto.has,
  add: function(value) {
    value +=3D "";
    this[prefix + value] =3D value;
    return this;
  },
  remove: proto.remove,
  clear: proto.clear,
  values: proto.keys,
  size: proto.size,
  empty: proto.empty,
  each: proto.each
};

function set$2(object, f) {
  var set =3D new Set;

  // Copy constructor.
  if (object instanceof Set) object.each(function(value) { set.add(value); =
});

  // Otherwise, assume it=E2=80=99s an array.
  else if (object) {
    var i =3D -1, n =3D object.length;
    if (f =3D=3D null) while (++i < n) set.add(object[i]);
    else while (++i < n) set.add(f(object[i], i, object));
  }

  return set;
}

function keys(map) {
  var keys =3D [];
  for (var key in map) keys.push(key);
  return keys;
}

function values(map) {
  var values =3D [];
  for (var key in map) values.push(map[key]);
  return values;
}

function entries(map) {
  var entries =3D [];
  for (var key in map) entries.push({key: key, value: map[key]});
  return entries;
}

var array$2 =3D Array.prototype;

var slice$3 =3D array$2.slice;

function ascending$2(a, b) {
  return a - b;
}

function area(ring) {
  var i =3D 0, n =3D ring.length, area =3D ring[n - 1][1] * ring[0][0] - ri=
ng[n - 1][0] * ring[0][1];
  while (++i < n) area +=3D ring[i - 1][1] * ring[i][0] - ring[i - 1][0] * =
ring[i][1];
  return area;
}

function constant$6(x) {
  return function() {
    return x;
  };
}

function contains(ring, hole) {
  var i =3D -1, n =3D hole.length, c;
  while (++i < n) if (c =3D ringContains(ring, hole[i])) return c;
  return 0;
}

function ringContains(ring, point) {
  var x =3D point[0], y =3D point[1], contains =3D -1;
  for (var i =3D 0, n =3D ring.length, j =3D n - 1; i < n; j =3D i++) {
    var pi =3D ring[i], xi =3D pi[0], yi =3D pi[1], pj =3D ring[j], xj =3D =
pj[0], yj =3D pj[1];
    if (segmentContains(pi, pj, point)) return 0;
    if (((yi > y) !=3D=3D (yj > y)) && ((x < (xj - xi) * (y - yi) / (yj - y=
i) + xi))) contains =3D -contains;
  }
  return contains;
}

function segmentContains(a, b, c) {
  var i; return collinear(a, b, c) && within(a[i =3D +(a[0] =3D=3D=3D b[0])=
], c[i], b[i]);
}

function collinear(a, b, c) {
  return (b[0] - a[0]) * (c[1] - a[1]) =3D=3D=3D (c[0] - a[0]) * (b[1] - a[=
1]);
}

function within(p, q, r) {
  return p <=3D q && q <=3D r || r <=3D q && q <=3D p;
}

function noop$1() {}

var cases =3D [
  [],
  [[[1.0, 1.5], [0.5, 1.0]]],
  [[[1.5, 1.0], [1.0, 1.5]]],
  [[[1.5, 1.0], [0.5, 1.0]]],
  [[[1.0, 0.5], [1.5, 1.0]]],
  [[[1.0, 1.5], [0.5, 1.0]], [[1.0, 0.5], [1.5, 1.0]]],
  [[[1.0, 0.5], [1.0, 1.5]]],
  [[[1.0, 0.5], [0.5, 1.0]]],
  [[[0.5, 1.0], [1.0, 0.5]]],
  [[[1.0, 1.5], [1.0, 0.5]]],
  [[[0.5, 1.0], [1.0, 0.5]], [[1.5, 1.0], [1.0, 1.5]]],
  [[[1.5, 1.0], [1.0, 0.5]]],
  [[[0.5, 1.0], [1.5, 1.0]]],
  [[[1.0, 1.5], [1.5, 1.0]]],
  [[[0.5, 1.0], [1.0, 1.5]]],
  []
];

function contours() {
  var dx =3D 1,
      dy =3D 1,
      threshold$$1 =3D thresholdSturges,
      smooth =3D smoothLinear;

  function contours(values) {
    var tz =3D threshold$$1(values);

    // Convert number of thresholds into uniform thresholds.
    if (!Array.isArray(tz)) {
      var domain =3D extent(values), start =3D domain[0], stop =3D domain[1=
];
      tz =3D tickStep(start, stop, tz);
      tz =3D sequence(Math.floor(start / tz) * tz, Math.floor(stop / tz) * =
tz, tz);
    } else {
      tz =3D tz.slice().sort(ascending$2);
    }

    return tz.map(function(value) {
      return contour(values, value);
    });
  }

  // Accumulate, smooth contour rings, assign holes to exterior rings.
  // Based on https://github.com/mbostock/shapefile/blob/v0.6.2/shp/polygon=
=2Ejs
  function contour(values, value) {
    var polygons =3D [],
        holes =3D [];

    isorings(values, value, function(ring) {
      smooth(ring, values, value);
      if (area(ring) > 0) polygons.push([ring]);
      else holes.push(ring);
    });

    holes.forEach(function(hole) {
      for (var i =3D 0, n =3D polygons.length, polygon; i < n; ++i) {
        if (contains((polygon =3D polygons[i])[0], hole) !=3D=3D -1) {
          polygon.push(hole);
          return;
        }
      }
    });

    return {
      type: "MultiPolygon",
      value: value,
      coordinates: polygons
    };
  }

  // Marching squares with isolines stitched into rings.
  // Based on https://github.com/topojson/topojson-client/blob/v3.0.0/src/s=
titch.js
  function isorings(values, value, callback) {
    var fragmentByStart =3D new Array,
        fragmentByEnd =3D new Array,
        x, y, t0, t1, t2, t3;

    // Special case for the first row (y =3D -1, t2 =3D t3 =3D 0).
    x =3D y =3D -1;
    t1 =3D values[0] >=3D value;
    cases[t1 << 1].forEach(stitch);
    while (++x < dx - 1) {
      t0 =3D t1, t1 =3D values[x + 1] >=3D value;
      cases[t0 | t1 << 1].forEach(stitch);
    }
    cases[t1 << 0].forEach(stitch);

    // General case for the intermediate rows.
    while (++y < dy - 1) {
      x =3D -1;
      t1 =3D values[y * dx + dx] >=3D value;
      t2 =3D values[y * dx] >=3D value;
      cases[t1 << 1 | t2 << 2].forEach(stitch);
      while (++x < dx - 1) {
        t0 =3D t1, t1 =3D values[y * dx + dx + x + 1] >=3D value;
        t3 =3D t2, t2 =3D values[y * dx + x + 1] >=3D value;
        cases[t0 | t1 << 1 | t2 << 2 | t3 << 3].forEach(stitch);
      }
      cases[t1 | t2 << 3].forEach(stitch);
    }

    // Special case for the last row (y =3D dy - 1, t0 =3D t1 =3D 0).
    x =3D -1;
    t2 =3D values[y * dx] >=3D value;
    cases[t2 << 2].forEach(stitch);
    while (++x < dx - 1) {
      t3 =3D t2, t2 =3D values[y * dx + x + 1] >=3D value;
      cases[t2 << 2 | t3 << 3].forEach(stitch);
    }
    cases[t2 << 3].forEach(stitch);

    function stitch(line) {
      var start =3D [line[0][0] + x, line[0][1] + y],
          end =3D [line[1][0] + x, line[1][1] + y],
          startIndex =3D index(start),
          endIndex =3D index(end),
          f, g;
      if (f =3D fragmentByEnd[startIndex]) {
        if (g =3D fragmentByStart[endIndex]) {
          delete fragmentByEnd[f.end];
          delete fragmentByStart[g.start];
          if (f =3D=3D=3D g) {
            f.ring.push(end);
            callback(f.ring);
          } else {
            fragmentByStart[f.start] =3D fragmentByEnd[g.end] =3D {start: f=
=2Estart, end: g.end, ring: f.ring.concat(g.ring)};
          }
        } else {
          delete fragmentByEnd[f.end];
          f.ring.push(end);
          fragmentByEnd[f.end =3D endIndex] =3D f;
        }
      } else if (f =3D fragmentByStart[endIndex]) {
        if (g =3D fragmentByEnd[startIndex]) {
          delete fragmentByStart[f.start];
          delete fragmentByEnd[g.end];
          if (f =3D=3D=3D g) {
            f.ring.push(end);
            callback(f.ring);
          } else {
            fragmentByStart[g.start] =3D fragmentByEnd[f.end] =3D {start: g=
=2Estart, end: f.end, ring: g.ring.concat(f.ring)};
          }
        } else {
          delete fragmentByStart[f.start];
          f.ring.unshift(start);
          fragmentByStart[f.start =3D startIndex] =3D f;
        }
      } else {
        fragmentByStart[startIndex] =3D fragmentByEnd[endIndex] =3D {start:=
 startIndex, end: endIndex, ring: [start, end]};
      }
    }
  }

  function index(point) {
    return point[0] * 2 + point[1] * (dx + 1) * 4;
  }

  function smoothLinear(ring, values, value) {
    ring.forEach(function(point) {
      var x =3D point[0],
          y =3D point[1],
          xt =3D x | 0,
          yt =3D y | 0,
          v0,
          v1 =3D values[yt * dx + xt];
      if (x > 0 && x < dx && xt =3D=3D=3D x) {
        v0 =3D values[yt * dx + xt - 1];
        point[0] =3D x + (value - v0) / (v1 - v0) - 0.5;
      }
      if (y > 0 && y < dy && yt =3D=3D=3D y) {
        v0 =3D values[(yt - 1) * dx + xt];
        point[1] =3D y + (value - v0) / (v1 - v0) - 0.5;
      }
    });
  }

  contours.contour =3D contour;

  contours.size =3D function(_) {
    if (!arguments.length) return [dx, dy];
    var _0 =3D Math.ceil(_[0]), _1 =3D Math.ceil(_[1]);
    if (!(_0 > 0) || !(_1 > 0)) throw new Error("invalid size");
    return dx =3D _0, dy =3D _1, contours;
  };

  contours.thresholds =3D function(_) {
    return arguments.length ? (threshold$$1 =3D typeof _ =3D=3D=3D "functio=
n" ? _ : Array.isArray(_) ? constant$6(slice$3.call(_)) : constant$6(_), co=
ntours) : threshold$$1;
  };

  contours.smooth =3D function(_) {
    return arguments.length ? (smooth =3D _ ? smoothLinear : noop$1, contou=
rs) : smooth =3D=3D=3D smoothLinear;
  };

  return contours;
}

// TODO Optimize edge cases.
// TODO Optimize index calculation.
// TODO Optimize arguments.
function blurX(source, target, r) {
  var n =3D source.width,
      m =3D source.height,
      w =3D (r << 1) + 1;
  for (var j =3D 0; j < m; ++j) {
    for (var i =3D 0, sr =3D 0; i < n + r; ++i) {
      if (i < n) {
        sr +=3D source.data[i + j * n];
      }
      if (i >=3D r) {
        if (i >=3D w) {
          sr -=3D source.data[i - w + j * n];
        }
        target.data[i - r + j * n] =3D sr / Math.min(i + 1, n - 1 + w - i, =
w);
      }
    }
  }
}

// TODO Optimize edge cases.
// TODO Optimize index calculation.
// TODO Optimize arguments.
function blurY(source, target, r) {
  var n =3D source.width,
      m =3D source.height,
      w =3D (r << 1) + 1;
  for (var i =3D 0; i < n; ++i) {
    for (var j =3D 0, sr =3D 0; j < m + r; ++j) {
      if (j < m) {
        sr +=3D source.data[i + j * n];
      }
      if (j >=3D r) {
        if (j >=3D w) {
          sr -=3D source.data[i + (j - w) * n];
        }
        target.data[i + (j - r) * n] =3D sr / Math.min(j + 1, m - 1 + w - j=
, w);
      }
    }
  }
}

function defaultX(d) {
  return d[0];
}

function defaultY(d) {
  return d[1];
}

function defaultWeight() {
  return 1;
}

function density() {
  var x =3D defaultX,
      y =3D defaultY,
      weight =3D defaultWeight,
      dx =3D 960,
      dy =3D 500,
      r =3D 20, // blur radius
      k =3D 2, // log2(grid cell size)
      o =3D r * 3, // grid offset, to pad for blur
      n =3D (dx + o * 2) >> k, // grid width
      m =3D (dy + o * 2) >> k, // grid height
      threshold$$1 =3D constant$6(20);

  function density(data) {
    var values0 =3D new Float32Array(n * m),
        values1 =3D new Float32Array(n * m);

    data.forEach(function(d, i, data) {
      var xi =3D (+x(d, i, data) + o) >> k,
          yi =3D (+y(d, i, data) + o) >> k,
          wi =3D +weight(d, i, data);
      if (xi >=3D 0 && xi < n && yi >=3D 0 && yi < m) {
        values0[xi + yi * n] +=3D wi;
      }
    });

    // TODO Optimize.
    blurX({width: n, height: m, data: values0}, {width: n, height: m, data:=
 values1}, r >> k);
    blurY({width: n, height: m, data: values1}, {width: n, height: m, data:=
 values0}, r >> k);
    blurX({width: n, height: m, data: values0}, {width: n, height: m, data:=
 values1}, r >> k);
    blurY({width: n, height: m, data: values1}, {width: n, height: m, data:=
 values0}, r >> k);
    blurX({width: n, height: m, data: values0}, {width: n, height: m, data:=
 values1}, r >> k);
    blurY({width: n, height: m, data: values1}, {width: n, height: m, data:=
 values0}, r >> k);

    var tz =3D threshold$$1(values0);

    // Convert number of thresholds into uniform thresholds.
    if (!Array.isArray(tz)) {
      var stop =3D max(values0);
      tz =3D tickStep(0, stop, tz);
      tz =3D sequence(0, Math.floor(stop / tz) * tz, tz);
      tz.shift();
    }

    return contours()
        .thresholds(tz)
        .size([n, m])
      (values0)
        .map(transform);
  }

  function transform(geometry) {
    geometry.value *=3D Math.pow(2, -2 * k); // Density in points per squar=
e pixel.
    geometry.coordinates.forEach(transformPolygon);
    return geometry;
  }

  function transformPolygon(coordinates) {
    coordinates.forEach(transformRing);
  }

  function transformRing(coordinates) {
    coordinates.forEach(transformPoint);
  }

  // TODO Optimize.
  function transformPoint(coordinates) {
    coordinates[0] =3D coordinates[0] * Math.pow(2, k) - o;
    coordinates[1] =3D coordinates[1] * Math.pow(2, k) - o;
  }

  function resize() {
    o =3D r * 3;
    n =3D (dx + o * 2) >> k;
    m =3D (dy + o * 2) >> k;
    return density;
  }

  density.x =3D function(_) {
    return arguments.length ? (x =3D typeof _ =3D=3D=3D "function" ? _ : co=
nstant$6(+_), density) : x;
  };

  density.y =3D function(_) {
    return arguments.length ? (y =3D typeof _ =3D=3D=3D "function" ? _ : co=
nstant$6(+_), density) : y;
  };

  density.weight =3D function(_) {
    return arguments.length ? (weight =3D typeof _ =3D=3D=3D "function" ? _=
 : constant$6(+_), density) : weight;
  };

  density.size =3D function(_) {
    if (!arguments.length) return [dx, dy];
    var _0 =3D Math.ceil(_[0]), _1 =3D Math.ceil(_[1]);
    if (!(_0 >=3D 0) && !(_0 >=3D 0)) throw new Error("invalid size");
    return dx =3D _0, dy =3D _1, resize();
  };

  density.cellSize =3D function(_) {
    if (!arguments.length) return 1 << k;
    if (!((_ =3D +_) >=3D 1)) throw new Error("invalid cell size");
    return k =3D Math.floor(Math.log(_) / Math.LN2), resize();
  };

  density.thresholds =3D function(_) {
    return arguments.length ? (threshold$$1 =3D typeof _ =3D=3D=3D "functio=
n" ? _ : Array.isArray(_) ? constant$6(slice$3.call(_)) : constant$6(_), de=
nsity) : threshold$$1;
  };

  density.bandwidth =3D function(_) {
    if (!arguments.length) return Math.sqrt(r * (r + 1));
    if (!((_ =3D +_) >=3D 0)) throw new Error("invalid bandwidth");
    return r =3D Math.round((Math.sqrt(4 * _ * _ + 1) - 1) / 2), resize();
  };

  return density;
}

var EOL =3D {},
    EOF =3D {},
    QUOTE =3D 34,
    NEWLINE =3D 10,
    RETURN =3D 13;

function objectConverter(columns) {
  return new Function("d", "return {" + columns.map(function(name, i) {
    return JSON.stringify(name) + ": d[" + i + "]";
  }).join(",") + "}");
}

function customConverter(columns, f) {
  var object =3D objectConverter(columns);
  return function(row, i) {
    return f(object(row), i, columns);
  };
}

// Compute unique columns in order of discovery.
function inferColumns(rows) {
  var columnSet =3D Object.create(null),
      columns =3D [];

  rows.forEach(function(row) {
    for (var column in row) {
      if (!(column in columnSet)) {
        columns.push(columnSet[column] =3D column);
      }
    }
  });

  return columns;
}

function pad(value, width) {
  var s =3D value + "", length =3D s.length;
  return length < width ? new Array(width - length + 1).join(0) + s : s;
}

function formatYear(year) {
  return year < 0 ? "-" + pad(-year, 6)
    : year > 9999 ? "+" + pad(year, 6)
    : pad(year, 4);
}

function formatDate(date) {
  var hours =3D date.getUTCHours(),
      minutes =3D date.getUTCMinutes(),
      seconds =3D date.getUTCSeconds(),
      milliseconds =3D date.getUTCMilliseconds();
  return isNaN(date) ? "Invalid Date"
      : formatYear(date.getUTCFullYear(), 4) + "-" + pad(date.getUTCMonth()=
 + 1, 2) + "-" + pad(date.getUTCDate(), 2)
      + (milliseconds ? "T" + pad(hours, 2) + ":" + pad(minutes, 2) + ":" +=
 pad(seconds, 2) + "." + pad(milliseconds, 3) + "Z"
      : seconds ? "T" + pad(hours, 2) + ":" + pad(minutes, 2) + ":" + pad(s=
econds, 2) + "Z"
      : minutes || hours ? "T" + pad(hours, 2) + ":" + pad(minutes, 2) + "Z"
      : "");
}

function dsvFormat(delimiter) {
  var reFormat =3D new RegExp("[\"" + delimiter + "\n\r]"),
      DELIMITER =3D delimiter.charCodeAt(0);

  function parse(text, f) {
    var convert, columns, rows =3D parseRows(text, function(row, i) {
      if (convert) return convert(row, i - 1);
      columns =3D row, convert =3D f ? customConverter(row, f) : objectConv=
erter(row);
    });
    rows.columns =3D columns || [];
    return rows;
  }

  function parseRows(text, f) {
    var rows =3D [], // output rows
        N =3D text.length,
        I =3D 0, // current character index
        n =3D 0, // current line number
        t, // current token
        eof =3D N <=3D 0, // current token followed by EOF?
        eol =3D false; // current token followed by EOL?

    // Strip the trailing newline.
    if (text.charCodeAt(N - 1) =3D=3D=3D NEWLINE) --N;
    if (text.charCodeAt(N - 1) =3D=3D=3D RETURN) --N;

    function token() {
      if (eof) return EOF;
      if (eol) return eol =3D false, EOL;

      // Unescape quotes.
      var i, j =3D I, c;
      if (text.charCodeAt(j) =3D=3D=3D QUOTE) {
        while (I++ < N && text.charCodeAt(I) !=3D=3D QUOTE || text.charCode=
At(++I) =3D=3D=3D QUOTE);
        if ((i =3D I) >=3D N) eof =3D true;
        else if ((c =3D text.charCodeAt(I++)) =3D=3D=3D NEWLINE) eol =3D tr=
ue;
        else if (c =3D=3D=3D RETURN) { eol =3D true; if (text.charCodeAt(I)=
 =3D=3D=3D NEWLINE) ++I; }
        return text.slice(j + 1, i - 1).replace(/""/g, "\"");
      }

      // Find next delimiter or newline.
      while (I < N) {
        if ((c =3D text.charCodeAt(i =3D I++)) =3D=3D=3D NEWLINE) eol =3D t=
rue;
        else if (c =3D=3D=3D RETURN) { eol =3D true; if (text.charCodeAt(I)=
 =3D=3D=3D NEWLINE) ++I; }
        else if (c !=3D=3D DELIMITER) continue;
        return text.slice(j, i);
      }

      // Return last token before EOF.
      return eof =3D true, text.slice(j, N);
    }

    while ((t =3D token()) !=3D=3D EOF) {
      var row =3D [];
      while (t !=3D=3D EOL && t !=3D=3D EOF) row.push(t), t =3D token();
      if (f && (row =3D f(row, n++)) =3D=3D null) continue;
      rows.push(row);
    }

    return rows;
  }

  function preformatBody(rows, columns) {
    return rows.map(function(row) {
      return columns.map(function(column) {
        return formatValue(row[column]);
      }).join(delimiter);
    });
  }

  function format(rows, columns) {
    if (columns =3D=3D null) columns =3D inferColumns(rows);
    return [columns.map(formatValue).join(delimiter)].concat(preformatBody(=
rows, columns)).join("\n");
  }

  function formatBody(rows, columns) {
    if (columns =3D=3D null) columns =3D inferColumns(rows);
    return preformatBody(rows, columns).join("\n");
  }

  function formatRows(rows) {
    return rows.map(formatRow).join("\n");
  }

  function formatRow(row) {
    return row.map(formatValue).join(delimiter);
  }

  function formatValue(value) {
    return value =3D=3D null ? ""
        : value instanceof Date ? formatDate(value)
        : reFormat.test(value +=3D "") ? "\"" + value.replace(/"/g, "\"\"")=
 + "\""
        : value;
  }

  return {
    parse: parse,
    parseRows: parseRows,
    format: format,
    formatBody: formatBody,
    formatRows: formatRows
  };
}

var csv =3D dsvFormat(",");

var csvParse =3D csv.parse;
var csvParseRows =3D csv.parseRows;
var csvFormat =3D csv.format;
var csvFormatBody =3D csv.formatBody;
var csvFormatRows =3D csv.formatRows;

var tsv =3D dsvFormat("\t");

var tsvParse =3D tsv.parse;
var tsvParseRows =3D tsv.parseRows;
var tsvFormat =3D tsv.format;
var tsvFormatBody =3D tsv.formatBody;
var tsvFormatRows =3D tsv.formatRows;

function autoType(object) {
  for (var key in object) {
    var value =3D object[key].trim(), number;
    if (!value) value =3D null;
    else if (value =3D=3D=3D "true") value =3D true;
    else if (value =3D=3D=3D "false") value =3D false;
    else if (value =3D=3D=3D "NaN") value =3D NaN;
    else if (!isNaN(number =3D +value)) value =3D number;
    else if (/^([-+]\d{2})?\d{4}(-\d{2}(-\d{2})?)?(T\d{2}:\d{2}(:\d{2}(\.\d=
{3})?)?(Z|[-+]\d{2}:\d{2})?)?$/.test(value)) value =3D new Date(value);
    else continue;
    object[key] =3D value;
  }
  return object;
}

function responseBlob(response) {
  if (!response.ok) throw new Error(response.status + " " + response.status=
Text);
  return response.blob();
}

function blob(input, init) {
  return fetch(input, init).then(responseBlob);
}

function responseArrayBuffer(response) {
  if (!response.ok) throw new Error(response.status + " " + response.status=
Text);
  return response.arrayBuffer();
}

function buffer(input, init) {
  return fetch(input, init).then(responseArrayBuffer);
}

function responseText(response) {
  if (!response.ok) throw new Error(response.status + " " + response.status=
Text);
  return response.text();
}

function text(input, init) {
  return fetch(input, init).then(responseText);
}

function dsvParse(parse) {
  return function(input, init, row) {
    if (arguments.length =3D=3D=3D 2 && typeof init =3D=3D=3D "function") r=
ow =3D init, init =3D undefined;
    return text(input, init).then(function(response) {
      return parse(response, row);
    });
  };
}

function dsv(delimiter, input, init, row) {
  if (arguments.length =3D=3D=3D 3 && typeof init =3D=3D=3D "function") row=
 =3D init, init =3D undefined;
  var format =3D dsvFormat(delimiter);
  return text(input, init).then(function(response) {
    return format.parse(response, row);
  });
}

var csv$1 =3D dsvParse(csvParse);
var tsv$1 =3D dsvParse(tsvParse);

function image(input, init) {
  return new Promise(function(resolve, reject) {
    var image =3D new Image;
    for (var key in init) image[key] =3D init[key];
    image.onerror =3D reject;
    image.onload =3D function() { resolve(image); };
    image.src =3D input;
  });
}

function responseJson(response) {
  if (!response.ok) throw new Error(response.status + " " + response.status=
Text);
  return response.json();
}

function json(input, init) {
  return fetch(input, init).then(responseJson);
}

function parser(type) {
  return function(input, init)  {
    return text(input, init).then(function(text$$1) {
      return (new DOMParser).parseFromString(text$$1, type);
    });
  };
}

var xml =3D parser("application/xml");

var html =3D parser("text/html");

var svg =3D parser("image/svg+xml");

function center$1(x, y) {
  var nodes;

  if (x =3D=3D null) x =3D 0;
  if (y =3D=3D null) y =3D 0;

  function force() {
    var i,
        n =3D nodes.length,
        node,
        sx =3D 0,
        sy =3D 0;

    for (i =3D 0; i < n; ++i) {
      node =3D nodes[i], sx +=3D node.x, sy +=3D node.y;
    }

    for (sx =3D sx / n - x, sy =3D sy / n - y, i =3D 0; i < n; ++i) {
      node =3D nodes[i], node.x -=3D sx, node.y -=3D sy;
    }
  }

  force.initialize =3D function(_) {
    nodes =3D _;
  };

  force.x =3D function(_) {
    return arguments.length ? (x =3D +_, force) : x;
  };

  force.y =3D function(_) {
    return arguments.length ? (y =3D +_, force) : y;
  };

  return force;
}

function constant$7(x) {
  return function() {
    return x;
  };
}

function jiggle() {
  return (Math.random() - 0.5) * 1e-6;
}

function tree_add(d) {
  var x =3D +this._x.call(null, d),
      y =3D +this._y.call(null, d);
  return add(this.cover(x, y), x, y, d);
}

function add(tree, x, y, d) {
  if (isNaN(x) || isNaN(y)) return tree; // ignore invalid points

  var parent,
      node =3D tree._root,
      leaf =3D {data: d},
      x0 =3D tree._x0,
      y0 =3D tree._y0,
      x1 =3D tree._x1,
      y1 =3D tree._y1,
      xm,
      ym,
      xp,
      yp,
      right,
      bottom,
      i,
      j;

  // If the tree is empty, initialize the root as a leaf.
  if (!node) return tree._root =3D leaf, tree;

  // Find the existing leaf for the new point, or add it.
  while (node.length) {
    if (right =3D x >=3D (xm =3D (x0 + x1) / 2)) x0 =3D xm; else x1 =3D xm;
    if (bottom =3D y >=3D (ym =3D (y0 + y1) / 2)) y0 =3D ym; else y1 =3D ym;
    if (parent =3D node, !(node =3D node[i =3D bottom << 1 | right])) retur=
n parent[i] =3D leaf, tree;
  }

  // Is the new point is exactly coincident with the existing point?
  xp =3D +tree._x.call(null, node.data);
  yp =3D +tree._y.call(null, node.data);
  if (x =3D=3D=3D xp && y =3D=3D=3D yp) return leaf.next =3D node, parent ?=
 parent[i] =3D leaf : tree._root =3D leaf, tree;

  // Otherwise, split the leaf node until the old and new point are separat=
ed.
  do {
    parent =3D parent ? parent[i] =3D new Array(4) : tree._root =3D new Arr=
ay(4);
    if (right =3D x >=3D (xm =3D (x0 + x1) / 2)) x0 =3D xm; else x1 =3D xm;
    if (bottom =3D y >=3D (ym =3D (y0 + y1) / 2)) y0 =3D ym; else y1 =3D ym;
  } while ((i =3D bottom << 1 | right) =3D=3D=3D (j =3D (yp >=3D ym) << 1 |=
 (xp >=3D xm)));
  return parent[j] =3D node, parent[i] =3D leaf, tree;
}

function addAll(data) {
  var d, i, n =3D data.length,
      x,
      y,
      xz =3D new Array(n),
      yz =3D new Array(n),
      x0 =3D Infinity,
      y0 =3D Infinity,
      x1 =3D -Infinity,
      y1 =3D -Infinity;

  // Compute the points and their extent.
  for (i =3D 0; i < n; ++i) {
    if (isNaN(x =3D +this._x.call(null, d =3D data[i])) || isNaN(y =3D +thi=
s._y.call(null, d))) continue;
    xz[i] =3D x;
    yz[i] =3D y;
    if (x < x0) x0 =3D x;
    if (x > x1) x1 =3D x;
    if (y < y0) y0 =3D y;
    if (y > y1) y1 =3D y;
  }

  // If there were no (valid) points, abort.
  if (x0 > x1 || y0 > y1) return this;

  // Expand the tree to cover the new points.
  this.cover(x0, y0).cover(x1, y1);

  // Add the new points.
  for (i =3D 0; i < n; ++i) {
    add(this, xz[i], yz[i], data[i]);
  }

  return this;
}

function tree_cover(x, y) {
  if (isNaN(x =3D +x) || isNaN(y =3D +y)) return this; // ignore invalid po=
ints

  var x0 =3D this._x0,
      y0 =3D this._y0,
      x1 =3D this._x1,
      y1 =3D this._y1;

  // If the quadtree has no extent, initialize them.
  // Integer extent are necessary so that if we later double the extent,
  // the existing quadrant boundaries don=E2=80=99t change due to floating =
point error!
  if (isNaN(x0)) {
    x1 =3D (x0 =3D Math.floor(x)) + 1;
    y1 =3D (y0 =3D Math.floor(y)) + 1;
  }

  // Otherwise, double repeatedly to cover.
  else {
    var z =3D x1 - x0,
        node =3D this._root,
        parent,
        i;

    while (x0 > x || x >=3D x1 || y0 > y || y >=3D y1) {
      i =3D (y < y0) << 1 | (x < x0);
      parent =3D new Array(4), parent[i] =3D node, node =3D parent, z *=3D =
2;
      switch (i) {
        case 0: x1 =3D x0 + z, y1 =3D y0 + z; break;
        case 1: x0 =3D x1 - z, y1 =3D y0 + z; break;
        case 2: x1 =3D x0 + z, y0 =3D y1 - z; break;
        case 3: x0 =3D x1 - z, y0 =3D y1 - z; break;
      }
    }

    if (this._root && this._root.length) this._root =3D node;
  }

  this._x0 =3D x0;
  this._y0 =3D y0;
  this._x1 =3D x1;
  this._y1 =3D y1;
  return this;
}

function tree_data() {
  var data =3D [];
  this.visit(function(node) {
    if (!node.length) do data.push(node.data); while (node =3D node.next)
  });
  return data;
}

function tree_extent(_) {
  return arguments.length
      ? this.cover(+_[0][0], +_[0][1]).cover(+_[1][0], +_[1][1])
      : isNaN(this._x0) ? undefined : [[this._x0, this._y0], [this._x1, thi=
s._y1]];
}

function Quad(node, x0, y0, x1, y1) {
  this.node =3D node;
  this.x0 =3D x0;
  this.y0 =3D y0;
  this.x1 =3D x1;
  this.y1 =3D y1;
}

function tree_find(x, y, radius) {
  var data,
      x0 =3D this._x0,
      y0 =3D this._y0,
      x1,
      y1,
      x2,
      y2,
      x3 =3D this._x1,
      y3 =3D this._y1,
      quads =3D [],
      node =3D this._root,
      q,
      i;

  if (node) quads.push(new Quad(node, x0, y0, x3, y3));
  if (radius =3D=3D null) radius =3D Infinity;
  else {
    x0 =3D x - radius, y0 =3D y - radius;
    x3 =3D x + radius, y3 =3D y + radius;
    radius *=3D radius;
  }

  while (q =3D quads.pop()) {

    // Stop searching if this quadrant can=E2=80=99t contain a closer node.
    if (!(node =3D q.node)
        || (x1 =3D q.x0) > x3
        || (y1 =3D q.y0) > y3
        || (x2 =3D q.x1) < x0
        || (y2 =3D q.y1) < y0) continue;

    // Bisect the current quadrant.
    if (node.length) {
      var xm =3D (x1 + x2) / 2,
          ym =3D (y1 + y2) / 2;

      quads.push(
        new Quad(node[3], xm, ym, x2, y2),
        new Quad(node[2], x1, ym, xm, y2),
        new Quad(node[1], xm, y1, x2, ym),
        new Quad(node[0], x1, y1, xm, ym)
      );

      // Visit the closest quadrant first.
      if (i =3D (y >=3D ym) << 1 | (x >=3D xm)) {
        q =3D quads[quads.length - 1];
        quads[quads.length - 1] =3D quads[quads.length - 1 - i];
        quads[quads.length - 1 - i] =3D q;
      }
    }

    // Visit this point. (Visiting coincident points isn=E2=80=99t necessar=
y!)
    else {
      var dx =3D x - +this._x.call(null, node.data),
          dy =3D y - +this._y.call(null, node.data),
          d2 =3D dx * dx + dy * dy;
      if (d2 < radius) {
        var d =3D Math.sqrt(radius =3D d2);
        x0 =3D x - d, y0 =3D y - d;
        x3 =3D x + d, y3 =3D y + d;
        data =3D node.data;
      }
    }
  }

  return data;
}

function tree_remove(d) {
  if (isNaN(x =3D +this._x.call(null, d)) || isNaN(y =3D +this._y.call(null=
, d))) return this; // ignore invalid points

  var parent,
      node =3D this._root,
      retainer,
      previous,
      next,
      x0 =3D this._x0,
      y0 =3D this._y0,
      x1 =3D this._x1,
      y1 =3D this._y1,
      x,
      y,
      xm,
      ym,
      right,
      bottom,
      i,
      j;

  // If the tree is empty, initialize the root as a leaf.
  if (!node) return this;

  // Find the leaf node for the point.
  // While descending, also retain the deepest parent with a non-removed si=
bling.
  if (node.length) while (true) {
    if (right =3D x >=3D (xm =3D (x0 + x1) / 2)) x0 =3D xm; else x1 =3D xm;
    if (bottom =3D y >=3D (ym =3D (y0 + y1) / 2)) y0 =3D ym; else y1 =3D ym;
    if (!(parent =3D node, node =3D node[i =3D bottom << 1 | right])) retur=
n this;
    if (!node.length) break;
    if (parent[(i + 1) & 3] || parent[(i + 2) & 3] || parent[(i + 3) & 3]) =
retainer =3D parent, j =3D i;
  }

  // Find the point to remove.
  while (node.data !=3D=3D d) if (!(previous =3D node, node =3D node.next))=
 return this;
  if (next =3D node.next) delete node.next;

  // If there are multiple coincident points, remove just the point.
  if (previous) return (next ? previous.next =3D next : delete previous.nex=
t), this;

  // If this is the root point, remove it.
  if (!parent) return this._root =3D next, this;

  // Remove this leaf.
  next ? parent[i] =3D next : delete parent[i];

  // If the parent now contains exactly one leaf, collapse superfluous pare=
nts.
  if ((node =3D parent[0] || parent[1] || parent[2] || parent[3])
      && node =3D=3D=3D (parent[3] || parent[2] || parent[1] || parent[0])
      && !node.length) {
    if (retainer) retainer[j] =3D node;
    else this._root =3D node;
  }

  return this;
}

function removeAll(data) {
  for (var i =3D 0, n =3D data.length; i < n; ++i) this.remove(data[i]);
  return this;
}

function tree_root() {
  return this._root;
}

function tree_size() {
  var size =3D 0;
  this.visit(function(node) {
    if (!node.length) do ++size; while (node =3D node.next)
  });
  return size;
}

function tree_visit(callback) {
  var quads =3D [], q, node =3D this._root, child, x0, y0, x1, y1;
  if (node) quads.push(new Quad(node, this._x0, this._y0, this._x1, this._y=
1));
  while (q =3D quads.pop()) {
    if (!callback(node =3D q.node, x0 =3D q.x0, y0 =3D q.y0, x1 =3D q.x1, y=
1 =3D q.y1) && node.length) {
      var xm =3D (x0 + x1) / 2, ym =3D (y0 + y1) / 2;
      if (child =3D node[3]) quads.push(new Quad(child, xm, ym, x1, y1));
      if (child =3D node[2]) quads.push(new Quad(child, x0, ym, xm, y1));
      if (child =3D node[1]) quads.push(new Quad(child, xm, y0, x1, ym));
      if (child =3D node[0]) quads.push(new Quad(child, x0, y0, xm, ym));
    }
  }
  return this;
}

function tree_visitAfter(callback) {
  var quads =3D [], next =3D [], q;
  if (this._root) quads.push(new Quad(this._root, this._x0, this._y0, this.=
_x1, this._y1));
  while (q =3D quads.pop()) {
    var node =3D q.node;
    if (node.length) {
      var child, x0 =3D q.x0, y0 =3D q.y0, x1 =3D q.x1, y1 =3D q.y1, xm =3D=
 (x0 + x1) / 2, ym =3D (y0 + y1) / 2;
      if (child =3D node[0]) quads.push(new Quad(child, x0, y0, xm, ym));
      if (child =3D node[1]) quads.push(new Quad(child, xm, y0, x1, ym));
      if (child =3D node[2]) quads.push(new Quad(child, x0, ym, xm, y1));
      if (child =3D node[3]) quads.push(new Quad(child, xm, ym, x1, y1));
    }
    next.push(q);
  }
  while (q =3D next.pop()) {
    callback(q.node, q.x0, q.y0, q.x1, q.y1);
  }
  return this;
}

function defaultX$1(d) {
  return d[0];
}

function tree_x(_) {
  return arguments.length ? (this._x =3D _, this) : this._x;
}

function defaultY$1(d) {
  return d[1];
}

function tree_y(_) {
  return arguments.length ? (this._y =3D _, this) : this._y;
}

function quadtree(nodes, x, y) {
  var tree =3D new Quadtree(x =3D=3D null ? defaultX$1 : x, y =3D=3D null ?=
 defaultY$1 : y, NaN, NaN, NaN, NaN);
  return nodes =3D=3D null ? tree : tree.addAll(nodes);
}

function Quadtree(x, y, x0, y0, x1, y1) {
  this._x =3D x;
  this._y =3D y;
  this._x0 =3D x0;
  this._y0 =3D y0;
  this._x1 =3D x1;
  this._y1 =3D y1;
  this._root =3D undefined;
}

function leaf_copy(leaf) {
  var copy =3D {data: leaf.data}, next =3D copy;
  while (leaf =3D leaf.next) next =3D next.next =3D {data: leaf.data};
  return copy;
}

var treeProto =3D quadtree.prototype =3D Quadtree.prototype;

treeProto.copy =3D function() {
  var copy =3D new Quadtree(this._x, this._y, this._x0, this._y0, this._x1,=
 this._y1),
      node =3D this._root,
      nodes,
      child;

  if (!node) return copy;

  if (!node.length) return copy._root =3D leaf_copy(node), copy;

  nodes =3D [{source: node, target: copy._root =3D new Array(4)}];
  while (node =3D nodes.pop()) {
    for (var i =3D 0; i < 4; ++i) {
      if (child =3D node.source[i]) {
        if (child.length) nodes.push({source: child, target: node.target[i]=
 =3D new Array(4)});
        else node.target[i] =3D leaf_copy(child);
      }
    }
  }

  return copy;
};

treeProto.add =3D tree_add;
treeProto.addAll =3D addAll;
treeProto.cover =3D tree_cover;
treeProto.data =3D tree_data;
treeProto.extent =3D tree_extent;
treeProto.find =3D tree_find;
treeProto.remove =3D tree_remove;
treeProto.removeAll =3D removeAll;
treeProto.root =3D tree_root;
treeProto.size =3D tree_size;
treeProto.visit =3D tree_visit;
treeProto.visitAfter =3D tree_visitAfter;
treeProto.x =3D tree_x;
treeProto.y =3D tree_y;

function x(d) {
  return d.x + d.vx;
}

function y(d) {
  return d.y + d.vy;
}

function collide(radius) {
  var nodes,
      radii,
      strength =3D 1,
      iterations =3D 1;

  if (typeof radius !=3D=3D "function") radius =3D constant$7(radius =3D=3D=
 null ? 1 : +radius);

  function force() {
    var i, n =3D nodes.length,
        tree,
        node,
        xi,
        yi,
        ri,
        ri2;

    for (var k =3D 0; k < iterations; ++k) {
      tree =3D quadtree(nodes, x, y).visitAfter(prepare);
      for (i =3D 0; i < n; ++i) {
        node =3D nodes[i];
        ri =3D radii[node.index], ri2 =3D ri * ri;
        xi =3D node.x + node.vx;
        yi =3D node.y + node.vy;
        tree.visit(apply);
      }
    }

    function apply(quad, x0, y0, x1, y1) {
      var data =3D quad.data, rj =3D quad.r, r =3D ri + rj;
      if (data) {
        if (data.index > node.index) {
          var x =3D xi - data.x - data.vx,
              y =3D yi - data.y - data.vy,
              l =3D x * x + y * y;
          if (l < r * r) {
            if (x =3D=3D=3D 0) x =3D jiggle(), l +=3D x * x;
            if (y =3D=3D=3D 0) y =3D jiggle(), l +=3D y * y;
            l =3D (r - (l =3D Math.sqrt(l))) / l * strength;
            node.vx +=3D (x *=3D l) * (r =3D (rj *=3D rj) / (ri2 + rj));
            node.vy +=3D (y *=3D l) * r;
            data.vx -=3D x * (r =3D 1 - r);
            data.vy -=3D y * r;
          }
        }
        return;
      }
      return x0 > xi + r || x1 < xi - r || y0 > yi + r || y1 < yi - r;
    }
  }

  function prepare(quad) {
    if (quad.data) return quad.r =3D radii[quad.data.index];
    for (var i =3D quad.r =3D 0; i < 4; ++i) {
      if (quad[i] && quad[i].r > quad.r) {
        quad.r =3D quad[i].r;
      }
    }
  }

  function initialize() {
    if (!nodes) return;
    var i, n =3D nodes.length, node;
    radii =3D new Array(n);
    for (i =3D 0; i < n; ++i) node =3D nodes[i], radii[node.index] =3D +rad=
ius(node, i, nodes);
  }

  force.initialize =3D function(_) {
    nodes =3D _;
    initialize();
  };

  force.iterations =3D function(_) {
    return arguments.length ? (iterations =3D +_, force) : iterations;
  };

  force.strength =3D function(_) {
    return arguments.length ? (strength =3D +_, force) : strength;
  };

  force.radius =3D function(_) {
    return arguments.length ? (radius =3D typeof _ =3D=3D=3D "function" ? _=
 : constant$7(+_), initialize(), force) : radius;
  };

  return force;
}

function index(d) {
  return d.index;
}

function find(nodeById, nodeId) {
  var node =3D nodeById.get(nodeId);
  if (!node) throw new Error("missing: " + nodeId);
  return node;
}

function link(links) {
  var id =3D index,
      strength =3D defaultStrength,
      strengths,
      distance =3D constant$7(30),
      distances,
      nodes,
      count,
      bias,
      iterations =3D 1;

  if (links =3D=3D null) links =3D [];

  function defaultStrength(link) {
    return 1 / Math.min(count[link.source.index], count[link.target.index]);
  }

  function force(alpha) {
    for (var k =3D 0, n =3D links.length; k < iterations; ++k) {
      for (var i =3D 0, link, source, target, x, y, l, b; i < n; ++i) {
        link =3D links[i], source =3D link.source, target =3D link.target;
        x =3D target.x + target.vx - source.x - source.vx || jiggle();
        y =3D target.y + target.vy - source.y - source.vy || jiggle();
        l =3D Math.sqrt(x * x + y * y);
        l =3D (l - distances[i]) / l * alpha * strengths[i];
        x *=3D l, y *=3D l;
        target.vx -=3D x * (b =3D bias[i]);
        target.vy -=3D y * b;
        source.vx +=3D x * (b =3D 1 - b);
        source.vy +=3D y * b;
      }
    }
  }

  function initialize() {
    if (!nodes) return;

    var i,
        n =3D nodes.length,
        m =3D links.length,
        nodeById =3D map$1(nodes, id),
        link;

    for (i =3D 0, count =3D new Array(n); i < m; ++i) {
      link =3D links[i], link.index =3D i;
      if (typeof link.source !=3D=3D "object") link.source =3D find(nodeByI=
d, link.source);
      if (typeof link.target !=3D=3D "object") link.target =3D find(nodeByI=
d, link.target);
      count[link.source.index] =3D (count[link.source.index] || 0) + 1;
      count[link.target.index] =3D (count[link.target.index] || 0) + 1;
    }

    for (i =3D 0, bias =3D new Array(m); i < m; ++i) {
      link =3D links[i], bias[i] =3D count[link.source.index] / (count[link=
=2Esource.index] + count[link.target.index]);
    }

    strengths =3D new Array(m), initializeStrength();
    distances =3D new Array(m), initializeDistance();
  }

  function initializeStrength() {
    if (!nodes) return;

    for (var i =3D 0, n =3D links.length; i < n; ++i) {
      strengths[i] =3D +strength(links[i], i, links);
    }
  }

  function initializeDistance() {
    if (!nodes) return;

    for (var i =3D 0, n =3D links.length; i < n; ++i) {
      distances[i] =3D +distance(links[i], i, links);
    }
  }

  force.initialize =3D function(_) {
    nodes =3D _;
    initialize();
  };

  force.links =3D function(_) {
    return arguments.length ? (links =3D _, initialize(), force) : links;
  };

  force.id =3D function(_) {
    return arguments.length ? (id =3D _, force) : id;
  };

  force.iterations =3D function(_) {
    return arguments.length ? (iterations =3D +_, force) : iterations;
  };

  force.strength =3D function(_) {
    return arguments.length ? (strength =3D typeof _ =3D=3D=3D "function" ?=
 _ : constant$7(+_), initializeStrength(), force) : strength;
  };

  force.distance =3D function(_) {
    return arguments.length ? (distance =3D typeof _ =3D=3D=3D "function" ?=
 _ : constant$7(+_), initializeDistance(), force) : distance;
  };

  return force;
}

function x$1(d) {
  return d.x;
}

function y$1(d) {
  return d.y;
}

var initialRadius =3D 10,
    initialAngle =3D Math.PI * (3 - Math.sqrt(5));

function simulation(nodes) {
  var simulation,
      alpha =3D 1,
      alphaMin =3D 0.001,
      alphaDecay =3D 1 - Math.pow(alphaMin, 1 / 300),
      alphaTarget =3D 0,
      velocityDecay =3D 0.6,
      forces =3D map$1(),
      stepper =3D timer(step),
      event =3D dispatch("tick", "end");

  if (nodes =3D=3D null) nodes =3D [];

  function step() {
    tick();
    event.call("tick", simulation);
    if (alpha < alphaMin) {
      stepper.stop();
      event.call("end", simulation);
    }
  }

  function tick(iterations) {
    var i, n =3D nodes.length, node;

    if (iterations =3D=3D=3D undefined) iterations =3D 1;

    for (var k =3D 0; k < iterations; ++k) {
      alpha +=3D (alphaTarget - alpha) * alphaDecay;

      forces.each(function (force) {
        force(alpha);
      });

      for (i =3D 0; i < n; ++i) {
        node =3D nodes[i];
        if (node.fx =3D=3D null) node.x +=3D node.vx *=3D velocityDecay;
        else node.x =3D node.fx, node.vx =3D 0;
        if (node.fy =3D=3D null) node.y +=3D node.vy *=3D velocityDecay;
        else node.y =3D node.fy, node.vy =3D 0;
      }
    }

    return simulation;
  }

  function initializeNodes() {
    for (var i =3D 0, n =3D nodes.length, node; i < n; ++i) {
      node =3D nodes[i], node.index =3D i;
      if (node.fx !=3D null) node.x =3D node.fx;
      if (node.fy !=3D null) node.y =3D node.fy;
      if (isNaN(node.x) || isNaN(node.y)) {
        var radius =3D initialRadius * Math.sqrt(i), angle =3D i * initialA=
ngle;
        node.x =3D radius * Math.cos(angle);
        node.y =3D radius * Math.sin(angle);
      }
      if (isNaN(node.vx) || isNaN(node.vy)) {
        node.vx =3D node.vy =3D 0;
      }
    }
  }

  function initializeForce(force) {
    if (force.initialize) force.initialize(nodes);
    return force;
  }

  initializeNodes();

  return simulation =3D {
    tick: tick,

    restart: function() {
      return stepper.restart(step), simulation;
    },

    stop: function() {
      return stepper.stop(), simulation;
    },

    nodes: function(_) {
      return arguments.length ? (nodes =3D _, initializeNodes(), forces.eac=
h(initializeForce), simulation) : nodes;
    },

    alpha: function(_) {
      return arguments.length ? (alpha =3D +_, simulation) : alpha;
    },

    alphaMin: function(_) {
      return arguments.length ? (alphaMin =3D +_, simulation) : alphaMin;
    },

    alphaDecay: function(_) {
      return arguments.length ? (alphaDecay =3D +_, simulation) : +alphaDec=
ay;
    },

    alphaTarget: function(_) {
      return arguments.length ? (alphaTarget =3D +_, simulation) : alphaTar=
get;
    },

    velocityDecay: function(_) {
      return arguments.length ? (velocityDecay =3D 1 - _, simulation) : 1 -=
 velocityDecay;
    },

    force: function(name, _) {
      return arguments.length > 1 ? ((_ =3D=3D null ? forces.remove(name) :=
 forces.set(name, initializeForce(_))), simulation) : forces.get(name);
    },

    find: function(x, y, radius) {
      var i =3D 0,
          n =3D nodes.length,
          dx,
          dy,
          d2,
          node,
          closest;

      if (radius =3D=3D null) radius =3D Infinity;
      else radius *=3D radius;

      for (i =3D 0; i < n; ++i) {
        node =3D nodes[i];
        dx =3D x - node.x;
        dy =3D y - node.y;
        d2 =3D dx * dx + dy * dy;
        if (d2 < radius) closest =3D node, radius =3D d2;
      }

      return closest;
    },

    on: function(name, _) {
      return arguments.length > 1 ? (event.on(name, _), simulation) : event=
=2Eon(name);
    }
  };
}

function manyBody() {
  var nodes,
      node,
      alpha,
      strength =3D constant$7(-30),
      strengths,
      distanceMin2 =3D 1,
      distanceMax2 =3D Infinity,
      theta2 =3D 0.81;

  function force(_) {
    var i, n =3D nodes.length, tree =3D quadtree(nodes, x$1, y$1).visitAfte=
r(accumulate);
    for (alpha =3D _, i =3D 0; i < n; ++i) node =3D nodes[i], tree.visit(ap=
ply);
  }

  function initialize() {
    if (!nodes) return;
    var i, n =3D nodes.length, node;
    strengths =3D new Array(n);
    for (i =3D 0; i < n; ++i) node =3D nodes[i], strengths[node.index] =3D =
+strength(node, i, nodes);
  }

  function accumulate(quad) {
    var strength =3D 0, q, c, weight =3D 0, x, y, i;

    // For internal nodes, accumulate forces from child quadrants.
    if (quad.length) {
      for (x =3D y =3D i =3D 0; i < 4; ++i) {
        if ((q =3D quad[i]) && (c =3D Math.abs(q.value))) {
          strength +=3D q.value, weight +=3D c, x +=3D c * q.x, y +=3D c * =
q.y;
        }
      }
      quad.x =3D x / weight;
      quad.y =3D y / weight;
    }

    // For leaf nodes, accumulate forces from coincident quadrants.
    else {
      q =3D quad;
      q.x =3D q.data.x;
      q.y =3D q.data.y;
      do strength +=3D strengths[q.data.index];
      while (q =3D q.next);
    }

    quad.value =3D strength;
  }

  function apply(quad, x1, _, x2) {
    if (!quad.value) return true;

    var x =3D quad.x - node.x,
        y =3D quad.y - node.y,
        w =3D x2 - x1,
        l =3D x * x + y * y;

    // Apply the Barnes-Hut approximation if possible.
    // Limit forces for very close nodes; randomize direction if coincident.
    if (w * w / theta2 < l) {
      if (l < distanceMax2) {
        if (x =3D=3D=3D 0) x =3D jiggle(), l +=3D x * x;
        if (y =3D=3D=3D 0) y =3D jiggle(), l +=3D y * y;
        if (l < distanceMin2) l =3D Math.sqrt(distanceMin2 * l);
        node.vx +=3D x * quad.value * alpha / l;
        node.vy +=3D y * quad.value * alpha / l;
      }
      return true;
    }

    // Otherwise, process points directly.
    else if (quad.length || l >=3D distanceMax2) return;

    // Limit forces for very close nodes; randomize direction if coincident.
    if (quad.data !=3D=3D node || quad.next) {
      if (x =3D=3D=3D 0) x =3D jiggle(), l +=3D x * x;
      if (y =3D=3D=3D 0) y =3D jiggle(), l +=3D y * y;
      if (l < distanceMin2) l =3D Math.sqrt(distanceMin2 * l);
    }

    do if (quad.data !=3D=3D node) {
      w =3D strengths[quad.data.index] * alpha / l;
      node.vx +=3D x * w;
      node.vy +=3D y * w;
    } while (quad =3D quad.next);
  }

  force.initialize =3D function(_) {
    nodes =3D _;
    initialize();
  };

  force.strength =3D function(_) {
    return arguments.length ? (strength =3D typeof _ =3D=3D=3D "function" ?=
 _ : constant$7(+_), initialize(), force) : strength;
  };

  force.distanceMin =3D function(_) {
    return arguments.length ? (distanceMin2 =3D _ * _, force) : Math.sqrt(d=
istanceMin2);
  };

  force.distanceMax =3D function(_) {
    return arguments.length ? (distanceMax2 =3D _ * _, force) : Math.sqrt(d=
istanceMax2);
  };

  force.theta =3D function(_) {
    return arguments.length ? (theta2 =3D _ * _, force) : Math.sqrt(theta2);
  };

  return force;
}

function radial(radius, x, y) {
  var nodes,
      strength =3D constant$7(0.1),
      strengths,
      radiuses;

  if (typeof radius !=3D=3D "function") radius =3D constant$7(+radius);
  if (x =3D=3D null) x =3D 0;
  if (y =3D=3D null) y =3D 0;

  function force(alpha) {
    for (var i =3D 0, n =3D nodes.length; i < n; ++i) {
      var node =3D nodes[i],
          dx =3D node.x - x || 1e-6,
          dy =3D node.y - y || 1e-6,
          r =3D Math.sqrt(dx * dx + dy * dy),
          k =3D (radiuses[i] - r) * strengths[i] * alpha / r;
      node.vx +=3D dx * k;
      node.vy +=3D dy * k;
    }
  }

  function initialize() {
    if (!nodes) return;
    var i, n =3D nodes.length;
    strengths =3D new Array(n);
    radiuses =3D new Array(n);
    for (i =3D 0; i < n; ++i) {
      radiuses[i] =3D +radius(nodes[i], i, nodes);
      strengths[i] =3D isNaN(radiuses[i]) ? 0 : +strength(nodes[i], i, node=
s);
    }
  }

  force.initialize =3D function(_) {
    nodes =3D _, initialize();
  };

  force.strength =3D function(_) {
    return arguments.length ? (strength =3D typeof _ =3D=3D=3D "function" ?=
 _ : constant$7(+_), initialize(), force) : strength;
  };

  force.radius =3D function(_) {
    return arguments.length ? (radius =3D typeof _ =3D=3D=3D "function" ? _=
 : constant$7(+_), initialize(), force) : radius;
  };

  force.x =3D function(_) {
    return arguments.length ? (x =3D +_, force) : x;
  };

  force.y =3D function(_) {
    return arguments.length ? (y =3D +_, force) : y;
  };

  return force;
}

function x$2(x) {
  var strength =3D constant$7(0.1),
      nodes,
      strengths,
      xz;

  if (typeof x !=3D=3D "function") x =3D constant$7(x =3D=3D null ? 0 : +x);

  function force(alpha) {
    for (var i =3D 0, n =3D nodes.length, node; i < n; ++i) {
      node =3D nodes[i], node.vx +=3D (xz[i] - node.x) * strengths[i] * alp=
ha;
    }
  }

  function initialize() {
    if (!nodes) return;
    var i, n =3D nodes.length;
    strengths =3D new Array(n);
    xz =3D new Array(n);
    for (i =3D 0; i < n; ++i) {
      strengths[i] =3D isNaN(xz[i] =3D +x(nodes[i], i, nodes)) ? 0 : +stren=
gth(nodes[i], i, nodes);
    }
  }

  force.initialize =3D function(_) {
    nodes =3D _;
    initialize();
  };

  force.strength =3D function(_) {
    return arguments.length ? (strength =3D typeof _ =3D=3D=3D "function" ?=
 _ : constant$7(+_), initialize(), force) : strength;
  };

  force.x =3D function(_) {
    return arguments.length ? (x =3D typeof _ =3D=3D=3D "function" ? _ : co=
nstant$7(+_), initialize(), force) : x;
  };

  return force;
}

function y$2(y) {
  var strength =3D constant$7(0.1),
      nodes,
      strengths,
      yz;

  if (typeof y !=3D=3D "function") y =3D constant$7(y =3D=3D null ? 0 : +y);

  function force(alpha) {
    for (var i =3D 0, n =3D nodes.length, node; i < n; ++i) {
      node =3D nodes[i], node.vy +=3D (yz[i] - node.y) * strengths[i] * alp=
ha;
    }
  }

  function initialize() {
    if (!nodes) return;
    var i, n =3D nodes.length;
    strengths =3D new Array(n);
    yz =3D new Array(n);
    for (i =3D 0; i < n; ++i) {
      strengths[i] =3D isNaN(yz[i] =3D +y(nodes[i], i, nodes)) ? 0 : +stren=
gth(nodes[i], i, nodes);
    }
  }

  force.initialize =3D function(_) {
    nodes =3D _;
    initialize();
  };

  force.strength =3D function(_) {
    return arguments.length ? (strength =3D typeof _ =3D=3D=3D "function" ?=
 _ : constant$7(+_), initialize(), force) : strength;
  };

  force.y =3D function(_) {
    return arguments.length ? (y =3D typeof _ =3D=3D=3D "function" ? _ : co=
nstant$7(+_), initialize(), force) : y;
  };

  return force;
}

// Computes the decimal coefficient and exponent of the specified number x =
with
// significant digits p, where x is positive and p is in [1, 21] or undefin=
ed.
// For example, formatDecimal(1.23) returns ["123", 0].
function formatDecimal(x, p) {
  if ((i =3D (x =3D p ? x.toExponential(p - 1) : x.toExponential()).indexOf=
("e")) < 0) return null; // NaN, =C2=B1Infinity
  var i, coefficient =3D x.slice(0, i);

  // The string returned by toExponential either has the form \d\.\d+e[-+]\=
d+
  // (e.g., 1.2e+3) or the form \de[-+]\d+ (e.g., 1e+3).
  return [
    coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coeffi=
cient,
    +x.slice(i + 1)
  ];
}

function exponent$1(x) {
  return x =3D formatDecimal(Math.abs(x)), x ? x[1] : NaN;
}

function formatGroup(grouping, thousands) {
  return function(value, width) {
    var i =3D value.length,
        t =3D [],
        j =3D 0,
        g =3D grouping[0],
        length =3D 0;

    while (i > 0 && g > 0) {
      if (length + g + 1 > width) g =3D Math.max(1, width - length);
      t.push(value.substring(i -=3D g, i + g));
      if ((length +=3D g + 1) > width) break;
      g =3D grouping[j =3D (j + 1) % grouping.length];
    }

    return t.reverse().join(thousands);
  };
}

function formatNumerals(numerals) {
  return function(value) {
    return value.replace(/[0-9]/g, function(i) {
      return numerals[+i];
    });
  };
}

// [[fill]align][sign][symbol][0][width][,][.precision][~][type]
var re =3D /^(?:(.)?([<>=3D^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?=
([a-z%])?$/i;

function formatSpecifier(specifier) {
  return new FormatSpecifier(specifier);
}

formatSpecifier.prototype =3D FormatSpecifier.prototype; // instanceof

function FormatSpecifier(specifier) {
  if (!(match =3D re.exec(specifier))) throw new Error("invalid format: " +=
 specifier);
  var match;
  this.fill =3D match[1] || " ";
  this.align =3D match[2] || ">";
  this.sign =3D match[3] || "-";
  this.symbol =3D match[4] || "";
  this.zero =3D !!match[5];
  this.width =3D match[6] && +match[6];
  this.comma =3D !!match[7];
  this.precision =3D match[8] && +match[8].slice(1);
  this.trim =3D !!match[9];
  this.type =3D match[10] || "";
}

FormatSpecifier.prototype.toString =3D function() {
  return this.fill
      + this.align
      + this.sign
      + this.symbol
      + (this.zero ? "0" : "")
      + (this.width =3D=3D null ? "" : Math.max(1, this.width | 0))
      + (this.comma ? "," : "")
      + (this.precision =3D=3D null ? "" : "." + Math.max(0, this.precision=
 | 0))
      + (this.trim ? "~" : "")
      + this.type;
};

// Trims insignificant zeros, e.g., replaces 1.2000k with 1.2k.
function formatTrim(s) {
  out: for (var n =3D s.length, i =3D 1, i0 =3D -1, i1; i < n; ++i) {
    switch (s[i]) {
      case ".": i0 =3D i1 =3D i; break;
      case "0": if (i0 =3D=3D=3D 0) i0 =3D i; i1 =3D i; break;
      default: if (i0 > 0) { if (!+s[i]) break out; i0 =3D 0; } break;
    }
  }
  return i0 > 0 ? s.slice(0, i0) + s.slice(i1 + 1) : s;
}

var prefixExponent;

function formatPrefixAuto(x, p) {
  var d =3D formatDecimal(x, p);
  if (!d) return x + "";
  var coefficient =3D d[0],
      exponent =3D d[1],
      i =3D exponent - (prefixExponent =3D Math.max(-8, Math.min(8, Math.fl=
oor(exponent / 3))) * 3) + 1,
      n =3D coefficient.length;
  return i =3D=3D=3D n ? coefficient
      : i > n ? coefficient + new Array(i - n + 1).join("0")
      : i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i)
      : "0." + new Array(1 - i).join("0") + formatDecimal(x, Math.max(0, p =
+ i - 1))[0]; // less than 1y!
}

function formatRounded(x, p) {
  var d =3D formatDecimal(x, p);
  if (!d) return x + "";
  var coefficient =3D d[0],
      exponent =3D d[1];
  return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient
      : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent +=
 1) + "." + coefficient.slice(exponent + 1)
      : coefficient + new Array(exponent - coefficient.length + 2).join("0"=
);
}

var formatTypes =3D {
  "%": function(x, p) { return (x * 100).toFixed(p); },
  "b": function(x) { return Math.round(x).toString(2); },
  "c": function(x) { return x + ""; },
  "d": function(x) { return Math.round(x).toString(10); },
  "e": function(x, p) { return x.toExponential(p); },
  "f": function(x, p) { return x.toFixed(p); },
  "g": function(x, p) { return x.toPrecision(p); },
  "o": function(x) { return Math.round(x).toString(8); },
  "p": function(x, p) { return formatRounded(x * 100, p); },
  "r": formatRounded,
  "s": formatPrefixAuto,
  "X": function(x) { return Math.round(x).toString(16).toUpperCase(); },
  "x": function(x) { return Math.round(x).toString(16); }
};

function identity$3(x) {
  return x;
}

var prefixes =3D ["y","z","a","f","p","n","\xB5","m","","k","M","G","T","P"=
,"E","Z","Y"];

function formatLocale(locale) {
  var group =3D locale.grouping && locale.thousands ? formatGroup(locale.gr=
ouping, locale.thousands) : identity$3,
      currency =3D locale.currency,
      decimal =3D locale.decimal,
      numerals =3D locale.numerals ? formatNumerals(locale.numerals) : iden=
tity$3,
      percent =3D locale.percent || "%";

  function newFormat(specifier) {
    specifier =3D formatSpecifier(specifier);

    var fill =3D specifier.fill,
        align =3D specifier.align,
        sign =3D specifier.sign,
        symbol =3D specifier.symbol,
        zero =3D specifier.zero,
        width =3D specifier.width,
        comma =3D specifier.comma,
        precision =3D specifier.precision,
        trim =3D specifier.trim,
        type =3D specifier.type;

    // The "n" type is an alias for ",g".
    if (type =3D=3D=3D "n") comma =3D true, type =3D "g";

    // The "" type, and any invalid type, is an alias for ".12~g".
    else if (!formatTypes[type]) precision =3D=3D null && (precision =3D 12=
), trim =3D true, type =3D "g";

    // If zero fill is specified, padding goes after sign and before digits.
    if (zero || (fill =3D=3D=3D "0" && align =3D=3D=3D "=3D")) zero =3D tru=
e, fill =3D "0", align =3D "=3D";

    // Compute the prefix and suffix.
    // For SI-prefix, the suffix is lazily computed.
    var prefix =3D symbol =3D=3D=3D "$" ? currency[0] : symbol =3D=3D=3D "#=
" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "",
        suffix =3D symbol =3D=3D=3D "$" ? currency[1] : /[%p]/.test(type) ?=
 percent : "";

    // What format function should we use?
    // Is this an integer type?
    // Can this type generate exponential notation?
    var formatType =3D formatTypes[type],
        maybeSuffix =3D /[defgprs%]/.test(type);

    // Set the default precision if not specified,
    // or clamp the specified precision to the supported range.
    // For significant precision, it must be in [1, 21].
    // For fixed precision, it must be in [0, 20].
    precision =3D precision =3D=3D null ? 6
        : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision))
        : Math.max(0, Math.min(20, precision));

    function format(value) {
      var valuePrefix =3D prefix,
          valueSuffix =3D suffix,
          i, n, c;

      if (type =3D=3D=3D "c") {
        valueSuffix =3D formatType(value) + valueSuffix;
        value =3D "";
      } else {
        value =3D +value;

        // Perform the initial formatting.
        var valueNegative =3D value < 0;
        value =3D formatType(Math.abs(value), precision);

        // Trim insignificant zeros.
        if (trim) value =3D formatTrim(value);

        // If a negative value rounds to zero during formatting, treat as p=
ositive.
        if (valueNegative && +value =3D=3D=3D 0) valueNegative =3D false;

        // Compute the prefix and suffix.
        valuePrefix =3D (valueNegative ? (sign =3D=3D=3D "(" ? sign : "-") =
: sign =3D=3D=3D "-" || sign =3D=3D=3D "(" ? "" : sign) + valuePrefix;
        valueSuffix =3D (type =3D=3D=3D "s" ? prefixes[8 + prefixExponent /=
 3] : "") + valueSuffix + (valueNegative && sign =3D=3D=3D "(" ? ")" : "");

        // Break the formatted value into the integer =E2=80=9Cvalue=E2=80=
=9D part that can be
        // grouped, and fractional or exponential =E2=80=9Csuffix=E2=80=9D =
part that is not.
        if (maybeSuffix) {
          i =3D -1, n =3D value.length;
          while (++i < n) {
            if (c =3D value.charCodeAt(i), 48 > c || c > 57) {
              valueSuffix =3D (c =3D=3D=3D 46 ? decimal + value.slice(i + 1=
) : value.slice(i)) + valueSuffix;
              value =3D value.slice(0, i);
              break;
            }
          }
        }
      }

      // If the fill character is not "0", grouping is applied before paddi=
ng.
      if (comma && !zero) value =3D group(value, Infinity);

      // Compute the padding.
      var length =3D valuePrefix.length + value.length + valueSuffix.length,
          padding =3D length < width ? new Array(width - length + 1).join(f=
ill) : "";

      // If the fill character is "0", grouping is applied after padding.
      if (comma && zero) value =3D group(padding + value, padding.length ? =
width - valueSuffix.length : Infinity), padding =3D "";

      // Reconstruct the final output based on the desired alignment.
      switch (align) {
        case "<": value =3D valuePrefix + value + valueSuffix + padding; br=
eak;
        case "=3D": value =3D valuePrefix + padding + value + valueSuffix; =
break;
        case "^": value =3D padding.slice(0, length =3D padding.length >> 1=
) + valuePrefix + value + valueSuffix + padding.slice(length); break;
        default: value =3D padding + valuePrefix + value + valueSuffix; bre=
ak;
      }

      return numerals(value);
    }

    format.toString =3D function() {
      return specifier + "";
    };

    return format;
  }

  function formatPrefix(specifier, value) {
    var f =3D newFormat((specifier =3D formatSpecifier(specifier), specifie=
r.type =3D "f", specifier)),
        e =3D Math.max(-8, Math.min(8, Math.floor(exponent$1(value) / 3))) =
* 3,
        k =3D Math.pow(10, -e),
        prefix =3D prefixes[8 + e / 3];
    return function(value) {
      return f(k * value) + prefix;
    };
  }

  return {
    format: newFormat,
    formatPrefix: formatPrefix
  };
}

var locale;

defaultLocale({
  decimal: ".",
  thousands: ",",
  grouping: [3],
  currency: ["$", ""]
});

function defaultLocale(definition) {
  locale =3D formatLocale(definition);
  exports.format =3D locale.format;
  exports.formatPrefix =3D locale.formatPrefix;
  return locale;
}

function precisionFixed(step) {
  return Math.max(0, -exponent$1(Math.abs(step)));
}

function precisionPrefix(step, value) {
  return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent$1(value) =
/ 3))) * 3 - exponent$1(Math.abs(step)));
}

function precisionRound(step, max) {
  step =3D Math.abs(step), max =3D Math.abs(max) - step;
  return Math.max(0, exponent$1(max) - exponent$1(step)) + 1;
}

// Adds floating point numbers with twice the normal precision.
// Reference: J. R. Shewchuk, Adaptive Precision Floating-Point Arithmetic =
and
// Fast Robust Geometric Predicates, Discrete & Computational Geometry 18(3)
// 305=E2=80=93363 (1997).
// Code adapted from GeographicLib by Charles F. F. Karney,
// http://geographiclib.sourceforge.net/

function adder() {
  return new Adder;
}

function Adder() {
  this.reset();
}

Adder.prototype =3D {
  constructor: Adder,
  reset: function() {
    this.s =3D // rounded value
    this.t =3D 0; // exact error
  },
  add: function(y) {
    add$1(temp, y, this.t);
    add$1(this, temp.s, this.s);
    if (this.s) this.t +=3D temp.t;
    else this.s =3D temp.t;
  },
  valueOf: function() {
    return this.s;
  }
};

var temp =3D new Adder;

function add$1(adder, a, b) {
  var x =3D adder.s =3D a + b,
      bv =3D x - a,
      av =3D x - bv;
  adder.t =3D (a - av) + (b - bv);
}

var epsilon$2 =3D 1e-6;
var epsilon2$1 =3D 1e-12;
var pi$3 =3D Math.PI;
var halfPi$2 =3D pi$3 / 2;
var quarterPi =3D pi$3 / 4;
var tau$3 =3D pi$3 * 2;

var degrees$1 =3D 180 / pi$3;
var radians =3D pi$3 / 180;

var abs =3D Math.abs;
var atan =3D Math.atan;
var atan2 =3D Math.atan2;
var cos$1 =3D Math.cos;
var ceil =3D Math.ceil;
var exp =3D Math.exp;
var log =3D Math.log;
var pow =3D Math.pow;
var sin$1 =3D Math.sin;
var sign =3D Math.sign || function(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; =
};
var sqrt =3D Math.sqrt;
var tan =3D Math.tan;

function acos(x) {
  return x > 1 ? 0 : x < -1 ? pi$3 : Math.acos(x);
}

function asin(x) {
  return x > 1 ? halfPi$2 : x < -1 ? -halfPi$2 : Math.asin(x);
}

function haversin(x) {
  return (x =3D sin$1(x / 2)) * x;
}

function noop$2() {}

function streamGeometry(geometry, stream) {
  if (geometry && streamGeometryType.hasOwnProperty(geometry.type)) {
    streamGeometryType[geometry.type](geometry, stream);
  }
}

var streamObjectType =3D {
  Feature: function(object, stream) {
    streamGeometry(object.geometry, stream);
  },
  FeatureCollection: function(object, stream) {
    var features =3D object.features, i =3D -1, n =3D features.length;
    while (++i < n) streamGeometry(features[i].geometry, stream);
  }
};

var streamGeometryType =3D {
  Sphere: function(object, stream) {
    stream.sphere();
  },
  Point: function(object, stream) {
    object =3D object.coordinates;
    stream.point(object[0], object[1], object[2]);
  },
  MultiPoint: function(object, stream) {
    var coordinates =3D object.coordinates, i =3D -1, n =3D coordinates.len=
gth;
    while (++i < n) object =3D coordinates[i], stream.point(object[0], obje=
ct[1], object[2]);
  },
  LineString: function(object, stream) {
    streamLine(object.coordinates, stream, 0);
  },
  MultiLineString: function(object, stream) {
    var coordinates =3D object.coordinates, i =3D -1, n =3D coordinates.len=
gth;
    while (++i < n) streamLine(coordinates[i], stream, 0);
  },
  Polygon: function(object, stream) {
    streamPolygon(object.coordinates, stream);
  },
  MultiPolygon: function(object, stream) {
    var coordinates =3D object.coordinates, i =3D -1, n =3D coordinates.len=
gth;
    while (++i < n) streamPolygon(coordinates[i], stream);
  },
  GeometryCollection: function(object, stream) {
    var geometries =3D object.geometries, i =3D -1, n =3D geometries.length;
    while (++i < n) streamGeometry(geometries[i], stream);
  }
};

function streamLine(coordinates, stream, closed) {
  var i =3D -1, n =3D coordinates.length - closed, coordinate;
  stream.lineStart();
  while (++i < n) coordinate =3D coordinates[i], stream.point(coordinate[0]=
, coordinate[1], coordinate[2]);
  stream.lineEnd();
}

function streamPolygon(coordinates, stream) {
  var i =3D -1, n =3D coordinates.length;
  stream.polygonStart();
  while (++i < n) streamLine(coordinates[i], stream, 1);
  stream.polygonEnd();
}

function geoStream(object, stream) {
  if (object && streamObjectType.hasOwnProperty(object.type)) {
    streamObjectType[object.type](object, stream);
  } else {
    streamGeometry(object, stream);
  }
}

var areaRingSum =3D adder();

var areaSum =3D adder(),
    lambda00,
    phi00,
    lambda0,
    cosPhi0,
    sinPhi0;

var areaStream =3D {
  point: noop$2,
  lineStart: noop$2,
  lineEnd: noop$2,
  polygonStart: function() {
    areaRingSum.reset();
    areaStream.lineStart =3D areaRingStart;
    areaStream.lineEnd =3D areaRingEnd;
  },
  polygonEnd: function() {
    var areaRing =3D +areaRingSum;
    areaSum.add(areaRing < 0 ? tau$3 + areaRing : areaRing);
    this.lineStart =3D this.lineEnd =3D this.point =3D noop$2;
  },
  sphere: function() {
    areaSum.add(tau$3);
  }
};

function areaRingStart() {
  areaStream.point =3D areaPointFirst;
}

function areaRingEnd() {
  areaPoint(lambda00, phi00);
}

function areaPointFirst(lambda, phi) {
  areaStream.point =3D areaPoint;
  lambda00 =3D lambda, phi00 =3D phi;
  lambda *=3D radians, phi *=3D radians;
  lambda0 =3D lambda, cosPhi0 =3D cos$1(phi =3D phi / 2 + quarterPi), sinPh=
i0 =3D sin$1(phi);
}

function areaPoint(lambda, phi) {
  lambda *=3D radians, phi *=3D radians;
  phi =3D phi / 2 + quarterPi; // half the angular distance from south pole

  // Spherical excess E for a spherical triangle with vertices: south pole,
  // previous point, current point.  Uses a formula derived from Cagnoli=E2=
=80=99s
  // theorem.  See Todhunter, Spherical Trig. (1871), Sec. 103, Eq. (2).
  var dLambda =3D lambda - lambda0,
      sdLambda =3D dLambda >=3D 0 ? 1 : -1,
      adLambda =3D sdLambda * dLambda,
      cosPhi =3D cos$1(phi),
      sinPhi =3D sin$1(phi),
      k =3D sinPhi0 * sinPhi,
      u =3D cosPhi0 * cosPhi + k * cos$1(adLambda),
      v =3D k * sdLambda * sin$1(adLambda);
  areaRingSum.add(atan2(v, u));

  // Advance the previous points.
  lambda0 =3D lambda, cosPhi0 =3D cosPhi, sinPhi0 =3D sinPhi;
}

function area$1(object) {
  areaSum.reset();
  geoStream(object, areaStream);
  return areaSum * 2;
}

function spherical(cartesian) {
  return [atan2(cartesian[1], cartesian[0]), asin(cartesian[2])];
}

function cartesian(spherical) {
  var lambda =3D spherical[0], phi =3D spherical[1], cosPhi =3D cos$1(phi);
  return [cosPhi * cos$1(lambda), cosPhi * sin$1(lambda), sin$1(phi)];
}

function cartesianDot(a, b) {
  return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
}

function cartesianCross(a, b) {
  return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1]=
 - a[1] * b[0]];
}

// TODO return a
function cartesianAddInPlace(a, b) {
  a[0] +=3D b[0], a[1] +=3D b[1], a[2] +=3D b[2];
}

function cartesianScale(vector, k) {
  return [vector[0] * k, vector[1] * k, vector[2] * k];
}

// TODO return d
function cartesianNormalizeInPlace(d) {
  var l =3D sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);
  d[0] /=3D l, d[1] /=3D l, d[2] /=3D l;
}

var lambda0$1, phi0, lambda1, phi1, // bounds
    lambda2, // previous lambda-coordinate
    lambda00$1, phi00$1, // first point
    p0, // previous 3D point
    deltaSum =3D adder(),
    ranges,
    range;

var boundsStream =3D {
  point: boundsPoint,
  lineStart: boundsLineStart,
  lineEnd: boundsLineEnd,
  polygonStart: function() {
    boundsStream.point =3D boundsRingPoint;
    boundsStream.lineStart =3D boundsRingStart;
    boundsStream.lineEnd =3D boundsRingEnd;
    deltaSum.reset();
    areaStream.polygonStart();
  },
  polygonEnd: function() {
    areaStream.polygonEnd();
    boundsStream.point =3D boundsPoint;
    boundsStream.lineStart =3D boundsLineStart;
    boundsStream.lineEnd =3D boundsLineEnd;
    if (areaRingSum < 0) lambda0$1 =3D -(lambda1 =3D 180), phi0 =3D -(phi1 =
=3D 90);
    else if (deltaSum > epsilon$2) phi1 =3D 90;
    else if (deltaSum < -epsilon$2) phi0 =3D -90;
    range[0] =3D lambda0$1, range[1] =3D lambda1;
  },
  sphere: function() {
    lambda0$1 =3D -(lambda1 =3D 180), phi0 =3D -(phi1 =3D 90);
  }
};

function boundsPoint(lambda, phi) {
  ranges.push(range =3D [lambda0$1 =3D lambda, lambda1 =3D lambda]);
  if (phi < phi0) phi0 =3D phi;
  if (phi > phi1) phi1 =3D phi;
}

function linePoint(lambda, phi) {
  var p =3D cartesian([lambda * radians, phi * radians]);
  if (p0) {
    var normal =3D cartesianCross(p0, p),
        equatorial =3D [normal[1], -normal[0], 0],
        inflection =3D cartesianCross(equatorial, normal);
    cartesianNormalizeInPlace(inflection);
    inflection =3D spherical(inflection);
    var delta =3D lambda - lambda2,
        sign$$1 =3D delta > 0 ? 1 : -1,
        lambdai =3D inflection[0] * degrees$1 * sign$$1,
        phii,
        antimeridian =3D abs(delta) > 180;
    if (antimeridian ^ (sign$$1 * lambda2 < lambdai && lambdai < sign$$1 * =
lambda)) {
      phii =3D inflection[1] * degrees$1;
      if (phii > phi1) phi1 =3D phii;
    } else if (lambdai =3D (lambdai + 360) % 360 - 180, antimeridian ^ (sig=
n$$1 * lambda2 < lambdai && lambdai < sign$$1 * lambda)) {
      phii =3D -inflection[1] * degrees$1;
      if (phii < phi0) phi0 =3D phii;
    } else {
      if (phi < phi0) phi0 =3D phi;
      if (phi > phi1) phi1 =3D phi;
    }
    if (antimeridian) {
      if (lambda < lambda2) {
        if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 =
=3D lambda;
      } else {
        if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 =
=3D lambda;
      }
    } else {
      if (lambda1 >=3D lambda0$1) {
        if (lambda < lambda0$1) lambda0$1 =3D lambda;
        if (lambda > lambda1) lambda1 =3D lambda;
      } else {
        if (lambda > lambda2) {
          if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1=
 =3D lambda;
        } else {
          if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1=
 =3D lambda;
        }
      }
    }
  } else {
    ranges.push(range =3D [lambda0$1 =3D lambda, lambda1 =3D lambda]);
  }
  if (phi < phi0) phi0 =3D phi;
  if (phi > phi1) phi1 =3D phi;
  p0 =3D p, lambda2 =3D lambda;
}

function boundsLineStart() {
  boundsStream.point =3D linePoint;
}

function boundsLineEnd() {
  range[0] =3D lambda0$1, range[1] =3D lambda1;
  boundsStream.point =3D boundsPoint;
  p0 =3D null;
}

function boundsRingPoint(lambda, phi) {
  if (p0) {
    var delta =3D lambda - lambda2;
    deltaSum.add(abs(delta) > 180 ? delta + (delta > 0 ? 360 : -360) : delt=
a);
  } else {
    lambda00$1 =3D lambda, phi00$1 =3D phi;
  }
  areaStream.point(lambda, phi);
  linePoint(lambda, phi);
}

function boundsRingStart() {
  areaStream.lineStart();
}

function boundsRingEnd() {
  boundsRingPoint(lambda00$1, phi00$1);
  areaStream.lineEnd();
  if (abs(deltaSum) > epsilon$2) lambda0$1 =3D -(lambda1 =3D 180);
  range[0] =3D lambda0$1, range[1] =3D lambda1;
  p0 =3D null;
}

// Finds the left-right distance between two longitudes.
// This is almost the same as (lambda1 - lambda0 + 360=C2=B0) % 360=C2=B0, =
except that we want
// the distance between =C2=B1180=C2=B0 to be 360=C2=B0.
function angle(lambda0, lambda1) {
  return (lambda1 -=3D lambda0) < 0 ? lambda1 + 360 : lambda1;
}

function rangeCompare(a, b) {
  return a[0] - b[0];
}

function rangeContains(range, x) {
  return range[0] <=3D range[1] ? range[0] <=3D x && x <=3D range[1] : x < =
range[0] || range[1] < x;
}

function bounds(feature) {
  var i, n, a, b, merged, deltaMax, delta;

  phi1 =3D lambda1 =3D -(lambda0$1 =3D phi0 =3D Infinity);
  ranges =3D [];
  geoStream(feature, boundsStream);

  // First, sort ranges by their minimum longitudes.
  if (n =3D ranges.length) {
    ranges.sort(rangeCompare);

    // Then, merge any ranges that overlap.
    for (i =3D 1, a =3D ranges[0], merged =3D [a]; i < n; ++i) {
      b =3D ranges[i];
      if (rangeContains(a, b[0]) || rangeContains(a, b[1])) {
        if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] =3D b[1];
        if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] =3D b[0];
      } else {
        merged.push(a =3D b);
      }
    }

    // Finally, find the largest gap between the merged ranges.
    // The final bounding box will be the inverse of this gap.
    for (deltaMax =3D -Infinity, n =3D merged.length - 1, i =3D 0, a =3D me=
rged[n]; i <=3D n; a =3D b, ++i) {
      b =3D merged[i];
      if ((delta =3D angle(a[1], b[0])) > deltaMax) deltaMax =3D delta, lam=
bda0$1 =3D b[0], lambda1 =3D a[1];
    }
  }

  ranges =3D range =3D null;

  return lambda0$1 =3D=3D=3D Infinity || phi0 =3D=3D=3D Infinity
      ? [[NaN, NaN], [NaN, NaN]]
      : [[lambda0$1, phi0], [lambda1, phi1]];
}

var W0, W1,
    X0, Y0, Z0,
    X1, Y1, Z1,
    X2, Y2, Z2,
    lambda00$2, phi00$2, // first point
    x0, y0, z0; // previous point

var centroidStream =3D {
  sphere: noop$2,
  point: centroidPoint,
  lineStart: centroidLineStart,
  lineEnd: centroidLineEnd,
  polygonStart: function() {
    centroidStream.lineStart =3D centroidRingStart;
    centroidStream.lineEnd =3D centroidRingEnd;
  },
  polygonEnd: function() {
    centroidStream.lineStart =3D centroidLineStart;
    centroidStream.lineEnd =3D centroidLineEnd;
  }
};

// Arithmetic mean of Cartesian vectors.
function centroidPoint(lambda, phi) {
  lambda *=3D radians, phi *=3D radians;
  var cosPhi =3D cos$1(phi);
  centroidPointCartesian(cosPhi * cos$1(lambda), cosPhi * sin$1(lambda), si=
n$1(phi));
}

function centroidPointCartesian(x, y, z) {
  ++W0;
  X0 +=3D (x - X0) / W0;
  Y0 +=3D (y - Y0) / W0;
  Z0 +=3D (z - Z0) / W0;
}

function centroidLineStart() {
  centroidStream.point =3D centroidLinePointFirst;
}

function centroidLinePointFirst(lambda, phi) {
  lambda *=3D radians, phi *=3D radians;
  var cosPhi =3D cos$1(phi);
  x0 =3D cosPhi * cos$1(lambda);
  y0 =3D cosPhi * sin$1(lambda);
  z0 =3D sin$1(phi);
  centroidStream.point =3D centroidLinePoint;
  centroidPointCartesian(x0, y0, z0);
}

function centroidLinePoint(lambda, phi) {
  lambda *=3D radians, phi *=3D radians;
  var cosPhi =3D cos$1(phi),
      x =3D cosPhi * cos$1(lambda),
      y =3D cosPhi * sin$1(lambda),
      z =3D sin$1(phi),
      w =3D atan2(sqrt((w =3D y0 * z - z0 * y) * w + (w =3D z0 * x - x0 * z=
) * w + (w =3D x0 * y - y0 * x) * w), x0 * x + y0 * y + z0 * z);
  W1 +=3D w;
  X1 +=3D w * (x0 + (x0 =3D x));
  Y1 +=3D w * (y0 + (y0 =3D y));
  Z1 +=3D w * (z0 + (z0 =3D z));
  centroidPointCartesian(x0, y0, z0);
}

function centroidLineEnd() {
  centroidStream.point =3D centroidPoint;
}

// See J. E. Brock, The Inertia Tensor for a Spherical Triangle,
// J. Applied Mechanics 42, 239 (1975).
function centroidRingStart() {
  centroidStream.point =3D centroidRingPointFirst;
}

function centroidRingEnd() {
  centroidRingPoint(lambda00$2, phi00$2);
  centroidStream.point =3D centroidPoint;
}

function centroidRingPointFirst(lambda, phi) {
  lambda00$2 =3D lambda, phi00$2 =3D phi;
  lambda *=3D radians, phi *=3D radians;
  centroidStream.point =3D centroidRingPoint;
  var cosPhi =3D cos$1(phi);
  x0 =3D cosPhi * cos$1(lambda);
  y0 =3D cosPhi * sin$1(lambda);
  z0 =3D sin$1(phi);
  centroidPointCartesian(x0, y0, z0);
}

function centroidRingPoint(lambda, phi) {
  lambda *=3D radians, phi *=3D radians;
  var cosPhi =3D cos$1(phi),
      x =3D cosPhi * cos$1(lambda),
      y =3D cosPhi * sin$1(lambda),
      z =3D sin$1(phi),
      cx =3D y0 * z - z0 * y,
      cy =3D z0 * x - x0 * z,
      cz =3D x0 * y - y0 * x,
      m =3D sqrt(cx * cx + cy * cy + cz * cz),
      w =3D asin(m), // line weight =3D angle
      v =3D m && -w / m; // area weight multiplier
  X2 +=3D v * cx;
  Y2 +=3D v * cy;
  Z2 +=3D v * cz;
  W1 +=3D w;
  X1 +=3D w * (x0 + (x0 =3D x));
  Y1 +=3D w * (y0 + (y0 =3D y));
  Z1 +=3D w * (z0 + (z0 =3D z));
  centroidPointCartesian(x0, y0, z0);
}

function centroid(object) {
  W0 =3D W1 =3D
  X0 =3D Y0 =3D Z0 =3D
  X1 =3D Y1 =3D Z1 =3D
  X2 =3D Y2 =3D Z2 =3D 0;
  geoStream(object, centroidStream);

  var x =3D X2,
      y =3D Y2,
      z =3D Z2,
      m =3D x * x + y * y + z * z;

  // If the area-weighted ccentroid is undefined, fall back to length-weigh=
ted ccentroid.
  if (m < epsilon2$1) {
    x =3D X1, y =3D Y1, z =3D Z1;
    // If the feature has zero length, fall back to arithmetic mean of poin=
t vectors.
    if (W1 < epsilon$2) x =3D X0, y =3D Y0, z =3D Z0;
    m =3D x * x + y * y + z * z;
    // If the feature still has an undefined ccentroid, then return.
    if (m < epsilon2$1) return [NaN, NaN];
  }

  return [atan2(y, x) * degrees$1, asin(z / sqrt(m)) * degrees$1];
}

function constant$8(x) {
  return function() {
    return x;
  };
}

function compose(a, b) {

  function compose(x, y) {
    return x =3D a(x, y), b(x[0], x[1]);
  }

  if (a.invert && b.invert) compose.invert =3D function(x, y) {
    return x =3D b.invert(x, y), x && a.invert(x[0], x[1]);
  };

  return compose;
}

function rotationIdentity(lambda, phi) {
  return [abs(lambda) > pi$3 ? lambda + Math.round(-lambda / tau$3) * tau$3=
 : lambda, phi];
}

rotationIdentity.invert =3D rotationIdentity;

function rotateRadians(deltaLambda, deltaPhi, deltaGamma) {
  return (deltaLambda %=3D tau$3) ? (deltaPhi || deltaGamma ? compose(rotat=
ionLambda(deltaLambda), rotationPhiGamma(deltaPhi, deltaGamma))
    : rotationLambda(deltaLambda))
    : (deltaPhi || deltaGamma ? rotationPhiGamma(deltaPhi, deltaGamma)
    : rotationIdentity);
}

function forwardRotationLambda(deltaLambda) {
  return function(lambda, phi) {
    return lambda +=3D deltaLambda, [lambda > pi$3 ? lambda - tau$3 : lambd=
a < -pi$3 ? lambda + tau$3 : lambda, phi];
  };
}

function rotationLambda(deltaLambda) {
  var rotation =3D forwardRotationLambda(deltaLambda);
  rotation.invert =3D forwardRotationLambda(-deltaLambda);
  return rotation;
}

function rotationPhiGamma(deltaPhi, deltaGamma) {
  var cosDeltaPhi =3D cos$1(deltaPhi),
      sinDeltaPhi =3D sin$1(deltaPhi),
      cosDeltaGamma =3D cos$1(deltaGamma),
      sinDeltaGamma =3D sin$1(deltaGamma);

  function rotation(lambda, phi) {
    var cosPhi =3D cos$1(phi),
        x =3D cos$1(lambda) * cosPhi,
        y =3D sin$1(lambda) * cosPhi,
        z =3D sin$1(phi),
        k =3D z * cosDeltaPhi + x * sinDeltaPhi;
    return [
      atan2(y * cosDeltaGamma - k * sinDeltaGamma, x * cosDeltaPhi - z * si=
nDeltaPhi),
      asin(k * cosDeltaGamma + y * sinDeltaGamma)
    ];
  }

  rotation.invert =3D function(lambda, phi) {
    var cosPhi =3D cos$1(phi),
        x =3D cos$1(lambda) * cosPhi,
        y =3D sin$1(lambda) * cosPhi,
        z =3D sin$1(phi),
        k =3D z * cosDeltaGamma - y * sinDeltaGamma;
    return [
      atan2(y * cosDeltaGamma + z * sinDeltaGamma, x * cosDeltaPhi + k * si=
nDeltaPhi),
      asin(k * cosDeltaPhi - x * sinDeltaPhi)
    ];
  };

  return rotation;
}

function rotation(rotate) {
  rotate =3D rotateRadians(rotate[0] * radians, rotate[1] * radians, rotate=
=2Elength > 2 ? rotate[2] * radians : 0);

  function forward(coordinates) {
    coordinates =3D rotate(coordinates[0] * radians, coordinates[1] * radia=
ns);
    return coordinates[0] *=3D degrees$1, coordinates[1] *=3D degrees$1, co=
ordinates;
  }

  forward.invert =3D function(coordinates) {
    coordinates =3D rotate.invert(coordinates[0] * radians, coordinates[1] =
* radians);
    return coordinates[0] *=3D degrees$1, coordinates[1] *=3D degrees$1, co=
ordinates;
  };

  return forward;
}

// Generates a circle centered at [0=C2=B0, 0=C2=B0], with a given radius a=
nd precision.
function circleStream(stream, radius, delta, direction, t0, t1) {
  if (!delta) return;
  var cosRadius =3D cos$1(radius),
      sinRadius =3D sin$1(radius),
      step =3D direction * delta;
  if (t0 =3D=3D null) {
    t0 =3D radius + direction * tau$3;
    t1 =3D radius - step / 2;
  } else {
    t0 =3D circleRadius(cosRadius, t0);
    t1 =3D circleRadius(cosRadius, t1);
    if (direction > 0 ? t0 < t1 : t0 > t1) t0 +=3D direction * tau$3;
  }
  for (var point, t =3D t0; direction > 0 ? t > t1 : t < t1; t -=3D step) {
    point =3D spherical([cosRadius, -sinRadius * cos$1(t), -sinRadius * sin=
$1(t)]);
    stream.point(point[0], point[1]);
  }
}

// Returns the signed angle of a cartesian point relative to [cosRadius, 0,=
 0].
function circleRadius(cosRadius, point) {
  point =3D cartesian(point), point[0] -=3D cosRadius;
  cartesianNormalizeInPlace(point);
  var radius =3D acos(-point[1]);
  return ((-point[2] < 0 ? -radius : radius) + tau$3 - epsilon$2) % tau$3;
}

function circle() {
  var center =3D constant$8([0, 0]),
      radius =3D constant$8(90),
      precision =3D constant$8(6),
      ring,
      rotate,
      stream =3D {point: point};

  function point(x, y) {
    ring.push(x =3D rotate(x, y));
    x[0] *=3D degrees$1, x[1] *=3D degrees$1;
  }

  function circle() {
    var c =3D center.apply(this, arguments),
        r =3D radius.apply(this, arguments) * radians,
        p =3D precision.apply(this, arguments) * radians;
    ring =3D [];
    rotate =3D rotateRadians(-c[0] * radians, -c[1] * radians, 0).invert;
    circleStream(stream, r, p, 1);
    c =3D {type: "Polygon", coordinates: [ring]};
    ring =3D rotate =3D null;
    return c;
  }

  circle.center =3D function(_) {
    return arguments.length ? (center =3D typeof _ =3D=3D=3D "function" ? _=
 : constant$8([+_[0], +_[1]]), circle) : center;
  };

  circle.radius =3D function(_) {
    return arguments.length ? (radius =3D typeof _ =3D=3D=3D "function" ? _=
 : constant$8(+_), circle) : radius;
  };

  circle.precision =3D function(_) {
    return arguments.length ? (precision =3D typeof _ =3D=3D=3D "function" =
? _ : constant$8(+_), circle) : precision;
  };

  return circle;
}

function clipBuffer() {
  var lines =3D [],
      line;
  return {
    point: function(x, y) {
      line.push([x, y]);
    },
    lineStart: function() {
      lines.push(line =3D []);
    },
    lineEnd: noop$2,
    rejoin: function() {
      if (lines.length > 1) lines.push(lines.pop().concat(lines.shift()));
    },
    result: function() {
      var result =3D lines;
      lines =3D [];
      line =3D null;
      return result;
    }
  };
}

function pointEqual(a, b) {
  return abs(a[0] - b[0]) < epsilon$2 && abs(a[1] - b[1]) < epsilon$2;
}

function Intersection(point, points, other, entry) {
  this.x =3D point;
  this.z =3D points;
  this.o =3D other; // another intersection
  this.e =3D entry; // is an entry?
  this.v =3D false; // visited
  this.n =3D this.p =3D null; // next & previous
}

// A generalized polygon clipping algorithm: given a polygon that has been =
cut
// into its visible line segments, and rejoins the segments by interpolating
// along the clip edge.
function clipRejoin(segments, compareIntersection, startInside, interpolate=
, stream) {
  var subject =3D [],
      clip =3D [],
      i,
      n;

  segments.forEach(function(segment) {
    if ((n =3D segment.length - 1) <=3D 0) return;
    var n, p0 =3D segment[0], p1 =3D segment[n], x;

    // If the first and last points of a segment are coincident, then treat=
 as a
    // closed ring. TODO if all rings are closed, then the winding order of=
 the
    // exterior ring should be checked.
    if (pointEqual(p0, p1)) {
      stream.lineStart();
      for (i =3D 0; i < n; ++i) stream.point((p0 =3D segment[i])[0], p0[1]);
      stream.lineEnd();
      return;
    }

    subject.push(x =3D new Intersection(p0, segment, null, true));
    clip.push(x.o =3D new Intersection(p0, null, x, false));
    subject.push(x =3D new Intersection(p1, segment, null, false));
    clip.push(x.o =3D new Intersection(p1, null, x, true));
  });

  if (!subject.length) return;

  clip.sort(compareIntersection);
  link$1(subject);
  link$1(clip);

  for (i =3D 0, n =3D clip.length; i < n; ++i) {
    clip[i].e =3D startInside =3D !startInside;
  }

  var start =3D subject[0],
      points,
      point;

  while (1) {
    // Find first unvisited intersection.
    var current =3D start,
        isSubject =3D true;
    while (current.v) if ((current =3D current.n) =3D=3D=3D start) return;
    points =3D current.z;
    stream.lineStart();
    do {
      current.v =3D current.o.v =3D true;
      if (current.e) {
        if (isSubject) {
          for (i =3D 0, n =3D points.length; i < n; ++i) stream.point((poin=
t =3D points[i])[0], point[1]);
        } else {
          interpolate(current.x, current.n.x, 1, stream);
        }
        current =3D current.n;
      } else {
        if (isSubject) {
          points =3D current.p.z;
          for (i =3D points.length - 1; i >=3D 0; --i) stream.point((point =
=3D points[i])[0], point[1]);
        } else {
          interpolate(current.x, current.p.x, -1, stream);
        }
        current =3D current.p;
      }
      current =3D current.o;
      points =3D current.z;
      isSubject =3D !isSubject;
    } while (!current.v);
    stream.lineEnd();
  }
}

function link$1(array) {
  if (!(n =3D array.length)) return;
  var n,
      i =3D 0,
      a =3D array[0],
      b;
  while (++i < n) {
    a.n =3D b =3D array[i];
    b.p =3D a;
    a =3D b;
  }
  a.n =3D b =3D array[0];
  b.p =3D a;
}

var sum$1 =3D adder();

function longitude(point) {
  if (abs(point[0]) <=3D pi$3)
    return point[0];
  else
    return sign(point[0]) * ((abs(point[0]) + pi$3) % tau$3 - pi$3);
}

function polygonContains(polygon, point) {
  var lambda =3D longitude(point),
      phi =3D point[1],
      sinPhi =3D sin$1(phi),
      normal =3D [sin$1(lambda), -cos$1(lambda), 0],
      angle =3D 0,
      winding =3D 0;

  sum$1.reset();

  if (sinPhi =3D=3D=3D 1) phi =3D halfPi$2 + epsilon$2;
  else if (sinPhi =3D=3D=3D -1) phi =3D -halfPi$2 - epsilon$2;

  for (var i =3D 0, n =3D polygon.length; i < n; ++i) {
    if (!(m =3D (ring =3D polygon[i]).length)) continue;
    var ring,
        m,
        point0 =3D ring[m - 1],
        lambda0 =3D longitude(point0),
        phi0 =3D point0[1] / 2 + quarterPi,
        sinPhi0 =3D sin$1(phi0),
        cosPhi0 =3D cos$1(phi0);

    for (var j =3D 0; j < m; ++j, lambda0 =3D lambda1, sinPhi0 =3D sinPhi1,=
 cosPhi0 =3D cosPhi1, point0 =3D point1) {
      var point1 =3D ring[j],
          lambda1 =3D longitude(point1),
          phi1 =3D point1[1] / 2 + quarterPi,
          sinPhi1 =3D sin$1(phi1),
          cosPhi1 =3D cos$1(phi1),
          delta =3D lambda1 - lambda0,
          sign$$1 =3D delta >=3D 0 ? 1 : -1,
          absDelta =3D sign$$1 * delta,
          antimeridian =3D absDelta > pi$3,
          k =3D sinPhi0 * sinPhi1;

      sum$1.add(atan2(k * sign$$1 * sin$1(absDelta), cosPhi0 * cosPhi1 + k =
* cos$1(absDelta)));
      angle +=3D antimeridian ? delta + sign$$1 * tau$3 : delta;

      // Are the longitudes either side of the point=E2=80=99s meridian (la=
mbda),
      // and are the latitudes smaller than the parallel (phi)?
      if (antimeridian ^ lambda0 >=3D lambda ^ lambda1 >=3D lambda) {
        var arc =3D cartesianCross(cartesian(point0), cartesian(point1));
        cartesianNormalizeInPlace(arc);
        var intersection =3D cartesianCross(normal, arc);
        cartesianNormalizeInPlace(intersection);
        var phiArc =3D (antimeridian ^ delta >=3D 0 ? -1 : 1) * asin(inters=
ection[2]);
        if (phi > phiArc || phi =3D=3D=3D phiArc && (arc[0] || arc[1])) {
          winding +=3D antimeridian ^ delta >=3D 0 ? 1 : -1;
        }
      }
    }
  }

  // First, determine whether the South pole is inside or outside:
  //
  // It is inside if:
  // * the polygon winds around it in a clockwise direction.
  // * the polygon does not (cumulatively) wind around it, but has a negati=
ve
  //   (counter-clockwise) area.
  //
  // Second, count the (signed) number of times a segment crosses a lambda
  // from the point to the South pole.  If it is zero, then the point is the
  // same side as the South pole.

  return (angle < -epsilon$2 || angle < epsilon$2 && sum$1 < -epsilon$2) ^ =
(winding & 1);
}

function clip(pointVisible, clipLine, interpolate, start) {
  return function(sink) {
    var line =3D clipLine(sink),
        ringBuffer =3D clipBuffer(),
        ringSink =3D clipLine(ringBuffer),
        polygonStarted =3D false,
        polygon,
        segments,
        ring;

    var clip =3D {
      point: point,
      lineStart: lineStart,
      lineEnd: lineEnd,
      polygonStart: function() {
        clip.point =3D pointRing;
        clip.lineStart =3D ringStart;
        clip.lineEnd =3D ringEnd;
        segments =3D [];
        polygon =3D [];
      },
      polygonEnd: function() {
        clip.point =3D point;
        clip.lineStart =3D lineStart;
        clip.lineEnd =3D lineEnd;
        segments =3D merge(segments);
        var startInside =3D polygonContains(polygon, start);
        if (segments.length) {
          if (!polygonStarted) sink.polygonStart(), polygonStarted =3D true;
          clipRejoin(segments, compareIntersection, startInside, interpolat=
e, sink);
        } else if (startInside) {
          if (!polygonStarted) sink.polygonStart(), polygonStarted =3D true;
          sink.lineStart();
          interpolate(null, null, 1, sink);
          sink.lineEnd();
        }
        if (polygonStarted) sink.polygonEnd(), polygonStarted =3D false;
        segments =3D polygon =3D null;
      },
      sphere: function() {
        sink.polygonStart();
        sink.lineStart();
        interpolate(null, null, 1, sink);
        sink.lineEnd();
        sink.polygonEnd();
      }
    };

    function point(lambda, phi) {
      if (pointVisible(lambda, phi)) sink.point(lambda, phi);
    }

    function pointLine(lambda, phi) {
      line.point(lambda, phi);
    }

    function lineStart() {
      clip.point =3D pointLine;
      line.lineStart();
    }

    function lineEnd() {
      clip.point =3D point;
      line.lineEnd();
    }

    function pointRing(lambda, phi) {
      ring.push([lambda, phi]);
      ringSink.point(lambda, phi);
    }

    function ringStart() {
      ringSink.lineStart();
      ring =3D [];
    }

    function ringEnd() {
      pointRing(ring[0][0], ring[0][1]);
      ringSink.lineEnd();

      var clean =3D ringSink.clean(),
          ringSegments =3D ringBuffer.result(),
          i, n =3D ringSegments.length, m,
          segment,
          point;

      ring.pop();
      polygon.push(ring);
      ring =3D null;

      if (!n) return;

      // No intersections.
      if (clean & 1) {
        segment =3D ringSegments[0];
        if ((m =3D segment.length - 1) > 0) {
          if (!polygonStarted) sink.polygonStart(), polygonStarted =3D true;
          sink.lineStart();
          for (i =3D 0; i < m; ++i) sink.point((point =3D segment[i])[0], p=
oint[1]);
          sink.lineEnd();
        }
        return;
      }

      // Rejoin connected segments.
      // TODO reuse ringBuffer.rejoin()?
      if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(r=
ingSegments.shift()));

      segments.push(ringSegments.filter(validSegment));
    }

    return clip;
  };
}

function validSegment(segment) {
  return segment.length > 1;
}

// Intersections are sorted along the clip edge. For both antimeridian cutt=
ing
// and circle clipping, the same comparison is used.
function compareIntersection(a, b) {
  return ((a =3D a.x)[0] < 0 ? a[1] - halfPi$2 - epsilon$2 : halfPi$2 - a[1=
])
       - ((b =3D b.x)[0] < 0 ? b[1] - halfPi$2 - epsilon$2 : halfPi$2 - b[1=
]);
}

var clipAntimeridian =3D clip(
  function() { return true; },
  clipAntimeridianLine,
  clipAntimeridianInterpolate,
  [-pi$3, -halfPi$2]
);

// Takes a line and cuts into visible segments. Return values: 0 - there we=
re
// intersections or the line was empty; 1 - no intersections; 2 - there were
// intersections, and the first and last segments should be rejoined.
function clipAntimeridianLine(stream) {
  var lambda0 =3D NaN,
      phi0 =3D NaN,
      sign0 =3D NaN,
      clean; // no intersections

  return {
    lineStart: function() {
      stream.lineStart();
      clean =3D 1;
    },
    point: function(lambda1, phi1) {
      var sign1 =3D lambda1 > 0 ? pi$3 : -pi$3,
          delta =3D abs(lambda1 - lambda0);
      if (abs(delta - pi$3) < epsilon$2) { // line crosses a pole
        stream.point(lambda0, phi0 =3D (phi0 + phi1) / 2 > 0 ? halfPi$2 : -=
halfPi$2);
        stream.point(sign0, phi0);
        stream.lineEnd();
        stream.lineStart();
        stream.point(sign1, phi0);
        stream.point(lambda1, phi0);
        clean =3D 0;
      } else if (sign0 !=3D=3D sign1 && delta >=3D pi$3) { // line crosses =
antimeridian
        if (abs(lambda0 - sign0) < epsilon$2) lambda0 -=3D sign0 * epsilon$=
2; // handle degeneracies
        if (abs(lambda1 - sign1) < epsilon$2) lambda1 -=3D sign1 * epsilon$=
2;
        phi0 =3D clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1);
        stream.point(sign0, phi0);
        stream.lineEnd();
        stream.lineStart();
        stream.point(sign1, phi0);
        clean =3D 0;
      }
      stream.point(lambda0 =3D lambda1, phi0 =3D phi1);
      sign0 =3D sign1;
    },
    lineEnd: function() {
      stream.lineEnd();
      lambda0 =3D phi0 =3D NaN;
    },
    clean: function() {
      return 2 - clean; // if intersections, rejoin first and last segments
    }
  };
}

function clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1) {
  var cosPhi0,
      cosPhi1,
      sinLambda0Lambda1 =3D sin$1(lambda0 - lambda1);
  return abs(sinLambda0Lambda1) > epsilon$2
      ? atan((sin$1(phi0) * (cosPhi1 =3D cos$1(phi1)) * sin$1(lambda1)
          - sin$1(phi1) * (cosPhi0 =3D cos$1(phi0)) * sin$1(lambda0))
          / (cosPhi0 * cosPhi1 * sinLambda0Lambda1))
      : (phi0 + phi1) / 2;
}

function clipAntimeridianInterpolate(from, to, direction, stream) {
  var phi;
  if (from =3D=3D null) {
    phi =3D direction * halfPi$2;
    stream.point(-pi$3, phi);
    stream.point(0, phi);
    stream.point(pi$3, phi);
    stream.point(pi$3, 0);
    stream.point(pi$3, -phi);
    stream.point(0, -phi);
    stream.point(-pi$3, -phi);
    stream.point(-pi$3, 0);
    stream.point(-pi$3, phi);
  } else if (abs(from[0] - to[0]) > epsilon$2) {
    var lambda =3D from[0] < to[0] ? pi$3 : -pi$3;
    phi =3D direction * lambda / 2;
    stream.point(-lambda, phi);
    stream.point(0, phi);
    stream.point(lambda, phi);
  } else {
    stream.point(to[0], to[1]);
  }
}

function clipCircle(radius) {
  var cr =3D cos$1(radius),
      delta =3D 6 * radians,
      smallRadius =3D cr > 0,
      notHemisphere =3D abs(cr) > epsilon$2; // TODO optimise for this comm=
on case

  function interpolate(from, to, direction, stream) {
    circleStream(stream, radius, delta, direction, from, to);
  }

  function visible(lambda, phi) {
    return cos$1(lambda) * cos$1(phi) > cr;
  }

  // Takes a line and cuts into visible segments. Return values used for po=
lygon
  // clipping: 0 - there were intersections or the line was empty; 1 - no
  // intersections 2 - there were intersections, and the first and last seg=
ments
  // should be rejoined.
  function clipLine(stream) {
    var point0, // previous point
        c0, // code for previous point
        v0, // visibility of previous point
        v00, // visibility of first point
        clean; // no intersections
    return {
      lineStart: function() {
        v00 =3D v0 =3D false;
        clean =3D 1;
      },
      point: function(lambda, phi) {
        var point1 =3D [lambda, phi],
            point2,
            v =3D visible(lambda, phi),
            c =3D smallRadius
              ? v ? 0 : code(lambda, phi)
              : v ? code(lambda + (lambda < 0 ? pi$3 : -pi$3), phi) : 0;
        if (!point0 && (v00 =3D v0 =3D v)) stream.lineStart();
        // Handle degeneracies.
        // TODO ignore if not clipping polygons.
        if (v !=3D=3D v0) {
          point2 =3D intersect(point0, point1);
          if (!point2 || pointEqual(point0, point2) || pointEqual(point1, p=
oint2)) {
            point1[0] +=3D epsilon$2;
            point1[1] +=3D epsilon$2;
            v =3D visible(point1[0], point1[1]);
          }
        }
        if (v !=3D=3D v0) {
          clean =3D 0;
          if (v) {
            // outside going in
            stream.lineStart();
            point2 =3D intersect(point1, point0);
            stream.point(point2[0], point2[1]);
          } else {
            // inside going out
            point2 =3D intersect(point0, point1);
            stream.point(point2[0], point2[1]);
            stream.lineEnd();
          }
          point0 =3D point2;
        } else if (notHemisphere && point0 && smallRadius ^ v) {
          var t;
          // If the codes for two points are different, or are both zero,
          // and there this segment intersects with the small circle.
          if (!(c & c0) && (t =3D intersect(point1, point0, true))) {
            clean =3D 0;
            if (smallRadius) {
              stream.lineStart();
              stream.point(t[0][0], t[0][1]);
              stream.point(t[1][0], t[1][1]);
              stream.lineEnd();
            } else {
              stream.point(t[1][0], t[1][1]);
              stream.lineEnd();
              stream.lineStart();
              stream.point(t[0][0], t[0][1]);
            }
          }
        }
        if (v && (!point0 || !pointEqual(point0, point1))) {
          stream.point(point1[0], point1[1]);
        }
        point0 =3D point1, v0 =3D v, c0 =3D c;
      },
      lineEnd: function() {
        if (v0) stream.lineEnd();
        point0 =3D null;
      },
      // Rejoin first and last segments if there were intersections and the=
 first
      // and last points were visible.
      clean: function() {
        return clean | ((v00 && v0) << 1);
      }
    };
  }

  // Intersects the great circle between a and b with the clip circle.
  function intersect(a, b, two) {
    var pa =3D cartesian(a),
        pb =3D cartesian(b);

    // We have two planes, n1.p =3D d1 and n2.p =3D d2.
    // Find intersection line p(t) =3D c1 n1 + c2 n2 + t (n1 =E2=A8=AF n2).
    var n1 =3D [1, 0, 0], // normal
        n2 =3D cartesianCross(pa, pb),
        n2n2 =3D cartesianDot(n2, n2),
        n1n2 =3D n2[0], // cartesianDot(n1, n2),
        determinant =3D n2n2 - n1n2 * n1n2;

    // Two polar points.
    if (!determinant) return !two && a;

    var c1 =3D  cr * n2n2 / determinant,
        c2 =3D -cr * n1n2 / determinant,
        n1xn2 =3D cartesianCross(n1, n2),
        A =3D cartesianScale(n1, c1),
        B =3D cartesianScale(n2, c2);
    cartesianAddInPlace(A, B);

    // Solve |p(t)|^2 =3D 1.
    var u =3D n1xn2,
        w =3D cartesianDot(A, u),
        uu =3D cartesianDot(u, u),
        t2 =3D w * w - uu * (cartesianDot(A, A) - 1);

    if (t2 < 0) return;

    var t =3D sqrt(t2),
        q =3D cartesianScale(u, (-w - t) / uu);
    cartesianAddInPlace(q, A);
    q =3D spherical(q);

    if (!two) return q;

    // Two intersection points.
    var lambda0 =3D a[0],
        lambda1 =3D b[0],
        phi0 =3D a[1],
        phi1 =3D b[1],
        z;

    if (lambda1 < lambda0) z =3D lambda0, lambda0 =3D lambda1, lambda1 =3D =
z;

    var delta =3D lambda1 - lambda0,
        polar =3D abs(delta - pi$3) < epsilon$2,
        meridian =3D polar || delta < epsilon$2;

    if (!polar && phi1 < phi0) z =3D phi0, phi0 =3D phi1, phi1 =3D z;

    // Check that the first point is between a and b.
    if (meridian
        ? polar
          ? phi0 + phi1 > 0 ^ q[1] < (abs(q[0] - lambda0) < epsilon$2 ? phi=
0 : phi1)
          : phi0 <=3D q[1] && q[1] <=3D phi1
        : delta > pi$3 ^ (lambda0 <=3D q[0] && q[0] <=3D lambda1)) {
      var q1 =3D cartesianScale(u, (-w + t) / uu);
      cartesianAddInPlace(q1, A);
      return [q, spherical(q1)];
    }
  }

  // Generates a 4-bit vector representing the location of a point relative=
 to
  // the small circle's bounding box.
  function code(lambda, phi) {
    var r =3D smallRadius ? radius : pi$3 - radius,
        code =3D 0;
    if (lambda < -r) code |=3D 1; // left
    else if (lambda > r) code |=3D 2; // right
    if (phi < -r) code |=3D 4; // below
    else if (phi > r) code |=3D 8; // above
    return code;
  }

  return clip(visible, clipLine, interpolate, smallRadius ? [0, -radius] : =
[-pi$3, radius - pi$3]);
}

function clipLine(a, b, x0, y0, x1, y1) {
  var ax =3D a[0],
      ay =3D a[1],
      bx =3D b[0],
      by =3D b[1],
      t0 =3D 0,
      t1 =3D 1,
      dx =3D bx - ax,
      dy =3D by - ay,
      r;

  r =3D x0 - ax;
  if (!dx && r > 0) return;
  r /=3D dx;
  if (dx < 0) {
    if (r < t0) return;
    if (r < t1) t1 =3D r;
  } else if (dx > 0) {
    if (r > t1) return;
    if (r > t0) t0 =3D r;
  }

  r =3D x1 - ax;
  if (!dx && r < 0) return;
  r /=3D dx;
  if (dx < 0) {
    if (r > t1) return;
    if (r > t0) t0 =3D r;
  } else if (dx > 0) {
    if (r < t0) return;
    if (r < t1) t1 =3D r;
  }

  r =3D y0 - ay;
  if (!dy && r > 0) return;
  r /=3D dy;
  if (dy < 0) {
    if (r < t0) return;
    if (r < t1) t1 =3D r;
  } else if (dy > 0) {
    if (r > t1) return;
    if (r > t0) t0 =3D r;
  }

  r =3D y1 - ay;
  if (!dy && r < 0) return;
  r /=3D dy;
  if (dy < 0) {
    if (r > t1) return;
    if (r > t0) t0 =3D r;
  } else if (dy > 0) {
    if (r < t0) return;
    if (r < t1) t1 =3D r;
  }

  if (t0 > 0) a[0] =3D ax + t0 * dx, a[1] =3D ay + t0 * dy;
  if (t1 < 1) b[0] =3D ax + t1 * dx, b[1] =3D ay + t1 * dy;
  return true;
}

var clipMax =3D 1e9, clipMin =3D -clipMax;

// TODO Use d3-polygon=E2=80=99s polygonContains here for the ring check?
// TODO Eliminate duplicate buffering in clipBuffer and polygon.push?

function clipRectangle(x0, y0, x1, y1) {

  function visible(x, y) {
    return x0 <=3D x && x <=3D x1 && y0 <=3D y && y <=3D y1;
  }

  function interpolate(from, to, direction, stream) {
    var a =3D 0, a1 =3D 0;
    if (from =3D=3D null
        || (a =3D corner(from, direction)) !=3D=3D (a1 =3D corner(to, direc=
tion))
        || comparePoint(from, to) < 0 ^ direction > 0) {
      do stream.point(a =3D=3D=3D 0 || a =3D=3D=3D 3 ? x0 : x1, a > 1 ? y1 =
: y0);
      while ((a =3D (a + direction + 4) % 4) !=3D=3D a1);
    } else {
      stream.point(to[0], to[1]);
    }
  }

  function corner(p, direction) {
    return abs(p[0] - x0) < epsilon$2 ? direction > 0 ? 0 : 3
        : abs(p[0] - x1) < epsilon$2 ? direction > 0 ? 2 : 1
        : abs(p[1] - y0) < epsilon$2 ? direction > 0 ? 1 : 0
        : direction > 0 ? 3 : 2; // abs(p[1] - y1) < epsilon
  }

  function compareIntersection(a, b) {
    return comparePoint(a.x, b.x);
  }

  function comparePoint(a, b) {
    var ca =3D corner(a, 1),
        cb =3D corner(b, 1);
    return ca !=3D=3D cb ? ca - cb
        : ca =3D=3D=3D 0 ? b[1] - a[1]
        : ca =3D=3D=3D 1 ? a[0] - b[0]
        : ca =3D=3D=3D 2 ? a[1] - b[1]
        : b[0] - a[0];
  }

  return function(stream) {
    var activeStream =3D stream,
        bufferStream =3D clipBuffer(),
        segments,
        polygon,
        ring,
        x__, y__, v__, // first point
        x_, y_, v_, // previous point
        first,
        clean;

    var clipStream =3D {
      point: point,
      lineStart: lineStart,
      lineEnd: lineEnd,
      polygonStart: polygonStart,
      polygonEnd: polygonEnd
    };

    function point(x, y) {
      if (visible(x, y)) activeStream.point(x, y);
    }

    function polygonInside() {
      var winding =3D 0;

      for (var i =3D 0, n =3D polygon.length; i < n; ++i) {
        for (var ring =3D polygon[i], j =3D 1, m =3D ring.length, point =3D=
 ring[0], a0, a1, b0 =3D point[0], b1 =3D point[1]; j < m; ++j) {
          a0 =3D b0, a1 =3D b1, point =3D ring[j], b0 =3D point[0], b1 =3D =
point[1];
          if (a1 <=3D y1) { if (b1 > y1 && (b0 - a0) * (y1 - a1) > (b1 - a1=
) * (x0 - a0)) ++winding; }
          else { if (b1 <=3D y1 && (b0 - a0) * (y1 - a1) < (b1 - a1) * (x0 =
- a0)) --winding; }
        }
      }

      return winding;
    }

    // Buffer geometry within a polygon and then clip it en masse.
    function polygonStart() {
      activeStream =3D bufferStream, segments =3D [], polygon =3D [], clean=
 =3D true;
    }

    function polygonEnd() {
      var startInside =3D polygonInside(),
          cleanInside =3D clean && startInside,
          visible =3D (segments =3D merge(segments)).length;
      if (cleanInside || visible) {
        stream.polygonStart();
        if (cleanInside) {
          stream.lineStart();
          interpolate(null, null, 1, stream);
          stream.lineEnd();
        }
        if (visible) {
          clipRejoin(segments, compareIntersection, startInside, interpolat=
e, stream);
        }
        stream.polygonEnd();
      }
      activeStream =3D stream, segments =3D polygon =3D ring =3D null;
    }

    function lineStart() {
      clipStream.point =3D linePoint;
      if (polygon) polygon.push(ring =3D []);
      first =3D true;
      v_ =3D false;
      x_ =3D y_ =3D NaN;
    }

    // TODO rather than special-case polygons, simply handle them separatel=
y.
    // Ideally, coincident intersection points should be jittered to avoid
    // clipping issues.
    function lineEnd() {
      if (segments) {
        linePoint(x__, y__);
        if (v__ && v_) bufferStream.rejoin();
        segments.push(bufferStream.result());
      }
      clipStream.point =3D point;
      if (v_) activeStream.lineEnd();
    }

    function linePoint(x, y) {
      var v =3D visible(x, y);
      if (polygon) ring.push([x, y]);
      if (first) {
        x__ =3D x, y__ =3D y, v__ =3D v;
        first =3D false;
        if (v) {
          activeStream.lineStart();
          activeStream.point(x, y);
        }
      } else {
        if (v && v_) activeStream.point(x, y);
        else {
          var a =3D [x_ =3D Math.max(clipMin, Math.min(clipMax, x_)), y_ =
=3D Math.max(clipMin, Math.min(clipMax, y_))],
              b =3D [x =3D Math.max(clipMin, Math.min(clipMax, x)), y =3D M=
ath.max(clipMin, Math.min(clipMax, y))];
          if (clipLine(a, b, x0, y0, x1, y1)) {
            if (!v_) {
              activeStream.lineStart();
              activeStream.point(a[0], a[1]);
            }
            activeStream.point(b[0], b[1]);
            if (!v) activeStream.lineEnd();
            clean =3D false;
          } else if (v) {
            activeStream.lineStart();
            activeStream.point(x, y);
            clean =3D false;
          }
        }
      }
      x_ =3D x, y_ =3D y, v_ =3D v;
    }

    return clipStream;
  };
}

function extent$1() {
  var x0 =3D 0,
      y0 =3D 0,
      x1 =3D 960,
      y1 =3D 500,
      cache,
      cacheStream,
      clip;

  return clip =3D {
    stream: function(stream) {
      return cache && cacheStream =3D=3D=3D stream ? cache : cache =3D clip=
Rectangle(x0, y0, x1, y1)(cacheStream =3D stream);
    },
    extent: function(_) {
      return arguments.length ? (x0 =3D +_[0][0], y0 =3D +_[0][1], x1 =3D +=
_[1][0], y1 =3D +_[1][1], cache =3D cacheStream =3D null, clip) : [[x0, y0]=
, [x1, y1]];
    }
  };
}

var lengthSum =3D adder(),
    lambda0$2,
    sinPhi0$1,
    cosPhi0$1;

var lengthStream =3D {
  sphere: noop$2,
  point: noop$2,
  lineStart: lengthLineStart,
  lineEnd: noop$2,
  polygonStart: noop$2,
  polygonEnd: noop$2
};

function lengthLineStart() {
  lengthStream.point =3D lengthPointFirst;
  lengthStream.lineEnd =3D lengthLineEnd;
}

function lengthLineEnd() {
  lengthStream.point =3D lengthStream.lineEnd =3D noop$2;
}

function lengthPointFirst(lambda, phi) {
  lambda *=3D radians, phi *=3D radians;
  lambda0$2 =3D lambda, sinPhi0$1 =3D sin$1(phi), cosPhi0$1 =3D cos$1(phi);
  lengthStream.point =3D lengthPoint;
}

function lengthPoint(lambda, phi) {
  lambda *=3D radians, phi *=3D radians;
  var sinPhi =3D sin$1(phi),
      cosPhi =3D cos$1(phi),
      delta =3D abs(lambda - lambda0$2),
      cosDelta =3D cos$1(delta),
      sinDelta =3D sin$1(delta),
      x =3D cosPhi * sinDelta,
      y =3D cosPhi0$1 * sinPhi - sinPhi0$1 * cosPhi * cosDelta,
      z =3D sinPhi0$1 * sinPhi + cosPhi0$1 * cosPhi * cosDelta;
  lengthSum.add(atan2(sqrt(x * x + y * y), z));
  lambda0$2 =3D lambda, sinPhi0$1 =3D sinPhi, cosPhi0$1 =3D cosPhi;
}

function length$1(object) {
  lengthSum.reset();
  geoStream(object, lengthStream);
  return +lengthSum;
}

var coordinates =3D [null, null],
    object$1 =3D {type: "LineString", coordinates: coordinates};

function distance(a, b) {
  coordinates[0] =3D a;
  coordinates[1] =3D b;
  return length$1(object$1);
}

var containsObjectType =3D {
  Feature: function(object, point) {
    return containsGeometry(object.geometry, point);
  },
  FeatureCollection: function(object, point) {
    var features =3D object.features, i =3D -1, n =3D features.length;
    while (++i < n) if (containsGeometry(features[i].geometry, point)) retu=
rn true;
    return false;
  }
};

var containsGeometryType =3D {
  Sphere: function() {
    return true;
  },
  Point: function(object, point) {
    return containsPoint(object.coordinates, point);
  },
  MultiPoint: function(object, point) {
    var coordinates =3D object.coordinates, i =3D -1, n =3D coordinates.len=
gth;
    while (++i < n) if (containsPoint(coordinates[i], point)) return true;
    return false;
  },
  LineString: function(object, point) {
    return containsLine(object.coordinates, point);
  },
  MultiLineString: function(object, point) {
    var coordinates =3D object.coordinates, i =3D -1, n =3D coordinates.len=
gth;
    while (++i < n) if (containsLine(coordinates[i], point)) return true;
    return false;
  },
  Polygon: function(object, point) {
    return containsPolygon(object.coordinates, point);
  },
  MultiPolygon: function(object, point) {
    var coordinates =3D object.coordinates, i =3D -1, n =3D coordinates.len=
gth;
    while (++i < n) if (containsPolygon(coordinates[i], point)) return true;
    return false;
  },
  GeometryCollection: function(object, point) {
    var geometries =3D object.geometries, i =3D -1, n =3D geometries.length;
    while (++i < n) if (containsGeometry(geometries[i], point)) return true;
    return false;
  }
};

function containsGeometry(geometry, point) {
  return geometry && containsGeometryType.hasOwnProperty(geometry.type)
      ? containsGeometryType[geometry.type](geometry, point)
      : false;
}

function containsPoint(coordinates, point) {
  return distance(coordinates, point) =3D=3D=3D 0;
}

function containsLine(coordinates, point) {
  var ao, bo, ab;
  for (var i =3D 0, n =3D coordinates.length; i < n; i++) {
    bo =3D distance(coordinates[i], point);
    if (bo =3D=3D=3D 0) return true;
    if (i > 0) {
      ab =3D distance(coordinates[i], coordinates[i - 1]);
      if (
        ab > 0 &&
        ao <=3D ab &&
        bo <=3D ab &&
        (ao + bo - ab) * (1 - Math.pow((ao - bo) / ab, 2)) < epsilon2$1 * ab
      )
        return true;
    }
    ao =3D bo;
  }
  return false;
}

function containsPolygon(coordinates, point) {
  return !!polygonContains(coordinates.map(ringRadians), pointRadians(point=
));
}

function ringRadians(ring) {
  return ring =3D ring.map(pointRadians), ring.pop(), ring;
}

function pointRadians(point) {
  return [point[0] * radians, point[1] * radians];
}

function contains$1(object, point) {
  return (object && containsObjectType.hasOwnProperty(object.type)
      ? containsObjectType[object.type]
      : containsGeometry)(object, point);
}

function graticuleX(y0, y1, dy) {
  var y =3D sequence(y0, y1 - epsilon$2, dy).concat(y1);
  return function(x) { return y.map(function(y) { return [x, y]; }); };
}

function graticuleY(x0, x1, dx) {
  var x =3D sequence(x0, x1 - epsilon$2, dx).concat(x1);
  return function(y) { return x.map(function(x) { return [x, y]; }); };
}

function graticule() {
  var x1, x0, X1, X0,
      y1, y0, Y1, Y0,
      dx =3D 10, dy =3D dx, DX =3D 90, DY =3D 360,
      x, y, X, Y,
      precision =3D 2.5;

  function graticule() {
    return {type: "MultiLineString", coordinates: lines()};
  }

  function lines() {
    return sequence(ceil(X0 / DX) * DX, X1, DX).map(X)
        .concat(sequence(ceil(Y0 / DY) * DY, Y1, DY).map(Y))
        .concat(sequence(ceil(x0 / dx) * dx, x1, dx).filter(function(x) { r=
eturn abs(x % DX) > epsilon$2; }).map(x))
        .concat(sequence(ceil(y0 / dy) * dy, y1, dy).filter(function(y) { r=
eturn abs(y % DY) > epsilon$2; }).map(y));
  }

  graticule.lines =3D function() {
    return lines().map(function(coordinates) { return {type: "LineString", =
coordinates: coordinates}; });
  };

  graticule.outline =3D function() {
    return {
      type: "Polygon",
      coordinates: [
        X(X0).concat(
        Y(Y1).slice(1),
        X(X1).reverse().slice(1),
        Y(Y0).reverse().slice(1))
      ]
    };
  };

  graticule.extent =3D function(_) {
    if (!arguments.length) return graticule.extentMinor();
    return graticule.extentMajor(_).extentMinor(_);
  };

  graticule.extentMajor =3D function(_) {
    if (!arguments.length) return [[X0, Y0], [X1, Y1]];
    X0 =3D +_[0][0], X1 =3D +_[1][0];
    Y0 =3D +_[0][1], Y1 =3D +_[1][1];
    if (X0 > X1) _ =3D X0, X0 =3D X1, X1 =3D _;
    if (Y0 > Y1) _ =3D Y0, Y0 =3D Y1, Y1 =3D _;
    return graticule.precision(precision);
  };

  graticule.extentMinor =3D function(_) {
    if (!arguments.length) return [[x0, y0], [x1, y1]];
    x0 =3D +_[0][0], x1 =3D +_[1][0];
    y0 =3D +_[0][1], y1 =3D +_[1][1];
    if (x0 > x1) _ =3D x0, x0 =3D x1, x1 =3D _;
    if (y0 > y1) _ =3D y0, y0 =3D y1, y1 =3D _;
    return graticule.precision(precision);
  };

  graticule.step =3D function(_) {
    if (!arguments.length) return graticule.stepMinor();
    return graticule.stepMajor(_).stepMinor(_);
  };

  graticule.stepMajor =3D function(_) {
    if (!arguments.length) return [DX, DY];
    DX =3D +_[0], DY =3D +_[1];
    return graticule;
  };

  graticule.stepMinor =3D function(_) {
    if (!arguments.length) return [dx, dy];
    dx =3D +_[0], dy =3D +_[1];
    return graticule;
  };

  graticule.precision =3D function(_) {
    if (!arguments.length) return precision;
    precision =3D +_;
    x =3D graticuleX(y0, y1, 90);
    y =3D graticuleY(x0, x1, precision);
    X =3D graticuleX(Y0, Y1, 90);
    Y =3D graticuleY(X0, X1, precision);
    return graticule;
  };

  return graticule
      .extentMajor([[-180, -90 + epsilon$2], [180, 90 - epsilon$2]])
      .extentMinor([[-180, -80 - epsilon$2], [180, 80 + epsilon$2]]);
}

function graticule10() {
  return graticule()();
}

function interpolate$1(a, b) {
  var x0 =3D a[0] * radians,
      y0 =3D a[1] * radians,
      x1 =3D b[0] * radians,
      y1 =3D b[1] * radians,
      cy0 =3D cos$1(y0),
      sy0 =3D sin$1(y0),
      cy1 =3D cos$1(y1),
      sy1 =3D sin$1(y1),
      kx0 =3D cy0 * cos$1(x0),
      ky0 =3D cy0 * sin$1(x0),
      kx1 =3D cy1 * cos$1(x1),
      ky1 =3D cy1 * sin$1(x1),
      d =3D 2 * asin(sqrt(haversin(y1 - y0) + cy0 * cy1 * haversin(x1 - x0)=
)),
      k =3D sin$1(d);

  var interpolate =3D d ? function(t) {
    var B =3D sin$1(t *=3D d) / k,
        A =3D sin$1(d - t) / k,
        x =3D A * kx0 + B * kx1,
        y =3D A * ky0 + B * ky1,
        z =3D A * sy0 + B * sy1;
    return [
      atan2(y, x) * degrees$1,
      atan2(z, sqrt(x * x + y * y)) * degrees$1
    ];
  } : function() {
    return [x0 * degrees$1, y0 * degrees$1];
  };

  interpolate.distance =3D d;

  return interpolate;
}

function identity$4(x) {
  return x;
}

var areaSum$1 =3D adder(),
    areaRingSum$1 =3D adder(),
    x00,
    y00,
    x0$1,
    y0$1;

var areaStream$1 =3D {
  point: noop$2,
  lineStart: noop$2,
  lineEnd: noop$2,
  polygonStart: function() {
    areaStream$1.lineStart =3D areaRingStart$1;
    areaStream$1.lineEnd =3D areaRingEnd$1;
  },
  polygonEnd: function() {
    areaStream$1.lineStart =3D areaStream$1.lineEnd =3D areaStream$1.point =
=3D noop$2;
    areaSum$1.add(abs(areaRingSum$1));
    areaRingSum$1.reset();
  },
  result: function() {
    var area =3D areaSum$1 / 2;
    areaSum$1.reset();
    return area;
  }
};

function areaRingStart$1() {
  areaStream$1.point =3D areaPointFirst$1;
}

function areaPointFirst$1(x, y) {
  areaStream$1.point =3D areaPoint$1;
  x00 =3D x0$1 =3D x, y00 =3D y0$1 =3D y;
}

function areaPoint$1(x, y) {
  areaRingSum$1.add(y0$1 * x - x0$1 * y);
  x0$1 =3D x, y0$1 =3D y;
}

function areaRingEnd$1() {
  areaPoint$1(x00, y00);
}

var x0$2 =3D Infinity,
    y0$2 =3D x0$2,
    x1 =3D -x0$2,
    y1 =3D x1;

var boundsStream$1 =3D {
  point: boundsPoint$1,
  lineStart: noop$2,
  lineEnd: noop$2,
  polygonStart: noop$2,
  polygonEnd: noop$2,
  result: function() {
    var bounds =3D [[x0$2, y0$2], [x1, y1]];
    x1 =3D y1 =3D -(y0$2 =3D x0$2 =3D Infinity);
    return bounds;
  }
};

function boundsPoint$1(x, y) {
  if (x < x0$2) x0$2 =3D x;
  if (x > x1) x1 =3D x;
  if (y < y0$2) y0$2 =3D y;
  if (y > y1) y1 =3D y;
}

// TODO Enforce positive area for exterior, negative area for interior?

var X0$1 =3D 0,
    Y0$1 =3D 0,
    Z0$1 =3D 0,
    X1$1 =3D 0,
    Y1$1 =3D 0,
    Z1$1 =3D 0,
    X2$1 =3D 0,
    Y2$1 =3D 0,
    Z2$1 =3D 0,
    x00$1,
    y00$1,
    x0$3,
    y0$3;

var centroidStream$1 =3D {
  point: centroidPoint$1,
  lineStart: centroidLineStart$1,
  lineEnd: centroidLineEnd$1,
  polygonStart: function() {
    centroidStream$1.lineStart =3D centroidRingStart$1;
    centroidStream$1.lineEnd =3D centroidRingEnd$1;
  },
  polygonEnd: function() {
    centroidStream$1.point =3D centroidPoint$1;
    centroidStream$1.lineStart =3D centroidLineStart$1;
    centroidStream$1.lineEnd =3D centroidLineEnd$1;
  },
  result: function() {
    var centroid =3D Z2$1 ? [X2$1 / Z2$1, Y2$1 / Z2$1]
        : Z1$1 ? [X1$1 / Z1$1, Y1$1 / Z1$1]
        : Z0$1 ? [X0$1 / Z0$1, Y0$1 / Z0$1]
        : [NaN, NaN];
    X0$1 =3D Y0$1 =3D Z0$1 =3D
    X1$1 =3D Y1$1 =3D Z1$1 =3D
    X2$1 =3D Y2$1 =3D Z2$1 =3D 0;
    return centroid;
  }
};

function centroidPoint$1(x, y) {
  X0$1 +=3D x;
  Y0$1 +=3D y;
  ++Z0$1;
}

function centroidLineStart$1() {
  centroidStream$1.point =3D centroidPointFirstLine;
}

function centroidPointFirstLine(x, y) {
  centroidStream$1.point =3D centroidPointLine;
  centroidPoint$1(x0$3 =3D x, y0$3 =3D y);
}

function centroidPointLine(x, y) {
  var dx =3D x - x0$3, dy =3D y - y0$3, z =3D sqrt(dx * dx + dy * dy);
  X1$1 +=3D z * (x0$3 + x) / 2;
  Y1$1 +=3D z * (y0$3 + y) / 2;
  Z1$1 +=3D z;
  centroidPoint$1(x0$3 =3D x, y0$3 =3D y);
}

function centroidLineEnd$1() {
  centroidStream$1.point =3D centroidPoint$1;
}

function centroidRingStart$1() {
  centroidStream$1.point =3D centroidPointFirstRing;
}

function centroidRingEnd$1() {
  centroidPointRing(x00$1, y00$1);
}

function centroidPointFirstRing(x, y) {
  centroidStream$1.point =3D centroidPointRing;
  centroidPoint$1(x00$1 =3D x0$3 =3D x, y00$1 =3D y0$3 =3D y);
}

function centroidPointRing(x, y) {
  var dx =3D x - x0$3,
      dy =3D y - y0$3,
      z =3D sqrt(dx * dx + dy * dy);

  X1$1 +=3D z * (x0$3 + x) / 2;
  Y1$1 +=3D z * (y0$3 + y) / 2;
  Z1$1 +=3D z;

  z =3D y0$3 * x - x0$3 * y;
  X2$1 +=3D z * (x0$3 + x);
  Y2$1 +=3D z * (y0$3 + y);
  Z2$1 +=3D z * 3;
  centroidPoint$1(x0$3 =3D x, y0$3 =3D y);
}

function PathContext(context) {
  this._context =3D context;
}

PathContext.prototype =3D {
  _radius: 4.5,
  pointRadius: function(_) {
    return this._radius =3D _, this;
  },
  polygonStart: function() {
    this._line =3D 0;
  },
  polygonEnd: function() {
    this._line =3D NaN;
  },
  lineStart: function() {
    this._point =3D 0;
  },
  lineEnd: function() {
    if (this._line =3D=3D=3D 0) this._context.closePath();
    this._point =3D NaN;
  },
  point: function(x, y) {
    switch (this._point) {
      case 0: {
        this._context.moveTo(x, y);
        this._point =3D 1;
        break;
      }
      case 1: {
        this._context.lineTo(x, y);
        break;
      }
      default: {
        this._context.moveTo(x + this._radius, y);
        this._context.arc(x, y, this._radius, 0, tau$3);
        break;
      }
    }
  },
  result: noop$2
};

var lengthSum$1 =3D adder(),
    lengthRing,
    x00$2,
    y00$2,
    x0$4,
    y0$4;

var lengthStream$1 =3D {
  point: noop$2,
  lineStart: function() {
    lengthStream$1.point =3D lengthPointFirst$1;
  },
  lineEnd: function() {
    if (lengthRing) lengthPoint$1(x00$2, y00$2);
    lengthStream$1.point =3D noop$2;
  },
  polygonStart: function() {
    lengthRing =3D true;
  },
  polygonEnd: function() {
    lengthRing =3D null;
  },
  result: function() {
    var length =3D +lengthSum$1;
    lengthSum$1.reset();
    return length;
  }
};

function lengthPointFirst$1(x, y) {
  lengthStream$1.point =3D lengthPoint$1;
  x00$2 =3D x0$4 =3D x, y00$2 =3D y0$4 =3D y;
}

function lengthPoint$1(x, y) {
  x0$4 -=3D x, y0$4 -=3D y;
  lengthSum$1.add(sqrt(x0$4 * x0$4 + y0$4 * y0$4));
  x0$4 =3D x, y0$4 =3D y;
}

function PathString() {
  this._string =3D [];
}

PathString.prototype =3D {
  _radius: 4.5,
  _circle: circle$1(4.5),
  pointRadius: function(_) {
    if ((_ =3D +_) !=3D=3D this._radius) this._radius =3D _, this._circle =
=3D null;
    return this;
  },
  polygonStart: function() {
    this._line =3D 0;
  },
  polygonEnd: function() {
    this._line =3D NaN;
  },
  lineStart: function() {
    this._point =3D 0;
  },
  lineEnd: function() {
    if (this._line =3D=3D=3D 0) this._string.push("Z");
    this._point =3D NaN;
  },
  point: function(x, y) {
    switch (this._point) {
      case 0: {
        this._string.push("M", x, ",", y);
        this._point =3D 1;
        break;
      }
      case 1: {
        this._string.push("L", x, ",", y);
        break;
      }
      default: {
        if (this._circle =3D=3D null) this._circle =3D circle$1(this._radiu=
s);
        this._string.push("M", x, ",", y, this._circle);
        break;
      }
    }
  },
  result: function() {
    if (this._string.length) {
      var result =3D this._string.join("");
      this._string =3D [];
      return result;
    } else {
      return null;
    }
  }
};

function circle$1(radius) {
  return "m0," + radius
      + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius
      + "a" + radius + "," + radius + " 0 1,1 0," + 2 * radius
      + "z";
}

function index$1(projection, context) {
  var pointRadius =3D 4.5,
      projectionStream,
      contextStream;

  function path(object) {
    if (object) {
      if (typeof pointRadius =3D=3D=3D "function") contextStream.pointRadiu=
s(+pointRadius.apply(this, arguments));
      geoStream(object, projectionStream(contextStream));
    }
    return contextStream.result();
  }

  path.area =3D function(object) {
    geoStream(object, projectionStream(areaStream$1));
    return areaStream$1.result();
  };

  path.measure =3D function(object) {
    geoStream(object, projectionStream(lengthStream$1));
    return lengthStream$1.result();
  };

  path.bounds =3D function(object) {
    geoStream(object, projectionStream(boundsStream$1));
    return boundsStream$1.result();
  };

  path.centroid =3D function(object) {
    geoStream(object, projectionStream(centroidStream$1));
    return centroidStream$1.result();
  };

  path.projection =3D function(_) {
    return arguments.length ? (projectionStream =3D _ =3D=3D null ? (projec=
tion =3D null, identity$4) : (projection =3D _).stream, path) : projection;
  };

  path.context =3D function(_) {
    if (!arguments.length) return context;
    contextStream =3D _ =3D=3D null ? (context =3D null, new PathString) : =
new PathContext(context =3D _);
    if (typeof pointRadius !=3D=3D "function") contextStream.pointRadius(po=
intRadius);
    return path;
  };

  path.pointRadius =3D function(_) {
    if (!arguments.length) return pointRadius;
    pointRadius =3D typeof _ =3D=3D=3D "function" ? _ : (contextStream.poin=
tRadius(+_), +_);
    return path;
  };

  return path.projection(projection).context(context);
}

function transform(methods) {
  return {
    stream: transformer(methods)
  };
}

function transformer(methods) {
  return function(stream) {
    var s =3D new TransformStream;
    for (var key in methods) s[key] =3D methods[key];
    s.stream =3D stream;
    return s;
  };
}

function TransformStream() {}

TransformStream.prototype =3D {
  constructor: TransformStream,
  point: function(x, y) { this.stream.point(x, y); },
  sphere: function() { this.stream.sphere(); },
  lineStart: function() { this.stream.lineStart(); },
  lineEnd: function() { this.stream.lineEnd(); },
  polygonStart: function() { this.stream.polygonStart(); },
  polygonEnd: function() { this.stream.polygonEnd(); }
};

function fit(projection, fitBounds, object) {
  var clip =3D projection.clipExtent && projection.clipExtent();
  projection.scale(150).translate([0, 0]);
  if (clip !=3D null) projection.clipExtent(null);
  geoStream(object, projection.stream(boundsStream$1));
  fitBounds(boundsStream$1.result());
  if (clip !=3D null) projection.clipExtent(clip);
  return projection;
}

function fitExtent(projection, extent, object) {
  return fit(projection, function(b) {
    var w =3D extent[1][0] - extent[0][0],
        h =3D extent[1][1] - extent[0][1],
        k =3D Math.min(w / (b[1][0] - b[0][0]), h / (b[1][1] - b[0][1])),
        x =3D +extent[0][0] + (w - k * (b[1][0] + b[0][0])) / 2,
        y =3D +extent[0][1] + (h - k * (b[1][1] + b[0][1])) / 2;
    projection.scale(150 * k).translate([x, y]);
  }, object);
}

function fitSize(projection, size, object) {
  return fitExtent(projection, [[0, 0], size], object);
}

function fitWidth(projection, width, object) {
  return fit(projection, function(b) {
    var w =3D +width,
        k =3D w / (b[1][0] - b[0][0]),
        x =3D (w - k * (b[1][0] + b[0][0])) / 2,
        y =3D -k * b[0][1];
    projection.scale(150 * k).translate([x, y]);
  }, object);
}

function fitHeight(projection, height, object) {
  return fit(projection, function(b) {
    var h =3D +height,
        k =3D h / (b[1][1] - b[0][1]),
        x =3D -k * b[0][0],
        y =3D (h - k * (b[1][1] + b[0][1])) / 2;
    projection.scale(150 * k).translate([x, y]);
  }, object);
}

var maxDepth =3D 16, // maximum depth of subdivision
    cosMinDistance =3D cos$1(30 * radians); // cos(minimum angular distance)

function resample(project, delta2) {
  return +delta2 ? resample$1(project, delta2) : resampleNone(project);
}

function resampleNone(project) {
  return transformer({
    point: function(x, y) {
      x =3D project(x, y);
      this.stream.point(x[0], x[1]);
    }
  });
}

function resample$1(project, delta2) {

  function resampleLineTo(x0, y0, lambda0, a0, b0, c0, x1, y1, lambda1, a1,=
 b1, c1, depth, stream) {
    var dx =3D x1 - x0,
        dy =3D y1 - y0,
        d2 =3D dx * dx + dy * dy;
    if (d2 > 4 * delta2 && depth--) {
      var a =3D a0 + a1,
          b =3D b0 + b1,
          c =3D c0 + c1,
          m =3D sqrt(a * a + b * b + c * c),
          phi2 =3D asin(c /=3D m),
          lambda2 =3D abs(abs(c) - 1) < epsilon$2 || abs(lambda0 - lambda1)=
 < epsilon$2 ? (lambda0 + lambda1) / 2 : atan2(b, a),
          p =3D project(lambda2, phi2),
          x2 =3D p[0],
          y2 =3D p[1],
          dx2 =3D x2 - x0,
          dy2 =3D y2 - y0,
          dz =3D dy * dx2 - dx * dy2;
      if (dz * dz / d2 > delta2 // perpendicular projected distance
          || abs((dx * dx2 + dy * dy2) / d2 - 0.5) > 0.3 // midpoint close =
to an end
          || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { // angular dis=
tance
        resampleLineTo(x0, y0, lambda0, a0, b0, c0, x2, y2, lambda2, a /=3D=
 m, b /=3D m, c, depth, stream);
        stream.point(x2, y2);
        resampleLineTo(x2, y2, lambda2, a, b, c, x1, y1, lambda1, a1, b1, c=
1, depth, stream);
      }
    }
  }
  return function(stream) {
    var lambda00, x00, y00, a00, b00, c00, // first point
        lambda0, x0, y0, a0, b0, c0; // previous point

    var resampleStream =3D {
      point: point,
      lineStart: lineStart,
      lineEnd: lineEnd,
      polygonStart: function() { stream.polygonStart(); resampleStream.line=
Start =3D ringStart; },
      polygonEnd: function() { stream.polygonEnd(); resampleStream.lineStar=
t =3D lineStart; }
    };

    function point(x, y) {
      x =3D project(x, y);
      stream.point(x[0], x[1]);
    }

    function lineStart() {
      x0 =3D NaN;
      resampleStream.point =3D linePoint;
      stream.lineStart();
    }

    function linePoint(lambda, phi) {
      var c =3D cartesian([lambda, phi]), p =3D project(lambda, phi);
      resampleLineTo(x0, y0, lambda0, a0, b0, c0, x0 =3D p[0], y0 =3D p[1],=
 lambda0 =3D lambda, a0 =3D c[0], b0 =3D c[1], c0 =3D c[2], maxDepth, strea=
m);
      stream.point(x0, y0);
    }

    function lineEnd() {
      resampleStream.point =3D point;
      stream.lineEnd();
    }

    function ringStart() {
      lineStart();
      resampleStream.point =3D ringPoint;
      resampleStream.lineEnd =3D ringEnd;
    }

    function ringPoint(lambda, phi) {
      linePoint(lambda00 =3D lambda, phi), x00 =3D x0, y00 =3D y0, a00 =3D =
a0, b00 =3D b0, c00 =3D c0;
      resampleStream.point =3D linePoint;
    }

    function ringEnd() {
      resampleLineTo(x0, y0, lambda0, a0, b0, c0, x00, y00, lambda00, a00, =
b00, c00, maxDepth, stream);
      resampleStream.lineEnd =3D lineEnd;
      lineEnd();
    }

    return resampleStream;
  };
}

var transformRadians =3D transformer({
  point: function(x, y) {
    this.stream.point(x * radians, y * radians);
  }
});

function transformRotate(rotate) {
  return transformer({
    point: function(x, y) {
      var r =3D rotate(x, y);
      return this.stream.point(r[0], r[1]);
    }
  });
}

function scaleTranslate(k, dx, dy) {
  function transform$$1(x, y) {
    return [dx + k * x, dy - k * y];
  }
  transform$$1.invert =3D function(x, y) {
    return [(x - dx) / k, (dy - y) / k];
  };
  return transform$$1;
}

function scaleTranslateRotate(k, dx, dy, alpha) {
  var cosAlpha =3D cos$1(alpha),
      sinAlpha =3D sin$1(alpha),
      a =3D cosAlpha * k,
      b =3D sinAlpha * k,
      ai =3D cosAlpha / k,
      bi =3D sinAlpha / k,
      ci =3D (sinAlpha * dy - cosAlpha * dx) / k,
      fi =3D (sinAlpha * dx + cosAlpha * dy) / k;
  function transform$$1(x, y) {
    return [a * x - b * y + dx, dy - b * x - a * y];
  }
  transform$$1.invert =3D function(x, y) {
    return [ai * x - bi * y + ci, fi - bi * x - ai * y];
  };
  return transform$$1;
}

function projection(project) {
  return projectionMutator(function() { return project; })();
}

function projectionMutator(projectAt) {
  var project,
      k =3D 150, // scale
      x =3D 480, y =3D 250, // translate
      lambda =3D 0, phi =3D 0, // center
      deltaLambda =3D 0, deltaPhi =3D 0, deltaGamma =3D 0, rotate, // pre-r=
otate
      alpha =3D 0, // post-rotate
      theta =3D null, preclip =3D clipAntimeridian, // pre-clip angle
      x0 =3D null, y0, x1, y1, postclip =3D identity$4, // post-clip extent
      delta2 =3D 0.5, // precision
      projectResample,
      projectTransform,
      projectRotateTransform,
      cache,
      cacheStream;

  function projection(point) {
    return projectRotateTransform(point[0] * radians, point[1] * radians);
  }

  function invert(point) {
    point =3D projectRotateTransform.invert(point[0], point[1]);
    return point && [point[0] * degrees$1, point[1] * degrees$1];
  }

  projection.stream =3D function(stream) {
    return cache && cacheStream =3D=3D=3D stream ? cache : cache =3D transf=
ormRadians(transformRotate(rotate)(preclip(projectResample(postclip(cacheSt=
ream =3D stream)))));
  };

  projection.preclip =3D function(_) {
    return arguments.length ? (preclip =3D _, theta =3D undefined, reset())=
 : preclip;
  };

  projection.postclip =3D function(_) {
    return arguments.length ? (postclip =3D _, x0 =3D y0 =3D x1 =3D y1 =3D =
null, reset()) : postclip;
  };

  projection.clipAngle =3D function(_) {
    return arguments.length ? (preclip =3D +_ ? clipCircle(theta =3D _ * ra=
dians) : (theta =3D null, clipAntimeridian), reset()) : theta * degrees$1;
  };

  projection.clipExtent =3D function(_) {
    return arguments.length ? (postclip =3D _ =3D=3D null ? (x0 =3D y0 =3D =
x1 =3D y1 =3D null, identity$4) : clipRectangle(x0 =3D +_[0][0], y0 =3D +_[=
0][1], x1 =3D +_[1][0], y1 =3D +_[1][1]), reset()) : x0 =3D=3D null ? null =
: [[x0, y0], [x1, y1]];
  };

  projection.scale =3D function(_) {
    return arguments.length ? (k =3D +_, recenter()) : k;
  };

  projection.translate =3D function(_) {
    return arguments.length ? (x =3D +_[0], y =3D +_[1], recenter()) : [x, =
y];
  };

  projection.center =3D function(_) {
    return arguments.length ? (lambda =3D _[0] % 360 * radians, phi =3D _[1=
] % 360 * radians, recenter()) : [lambda * degrees$1, phi * degrees$1];
  };

  projection.rotate =3D function(_) {
    return arguments.length ? (deltaLambda =3D _[0] % 360 * radians, deltaP=
hi =3D _[1] % 360 * radians, deltaGamma =3D _.length > 2 ? _[2] % 360 * rad=
ians : 0, recenter()) : [deltaLambda * degrees$1, deltaPhi * degrees$1, del=
taGamma * degrees$1];
  };

  projection.angle =3D function(_) {
    return arguments.length ? (alpha =3D _ % 360 * radians, recenter()) : a=
lpha * degrees$1;
  };

  projection.precision =3D function(_) {
    return arguments.length ? (projectResample =3D resample(projectTransfor=
m, delta2 =3D _ * _), reset()) : sqrt(delta2);
  };

  projection.fitExtent =3D function(extent, object) {
    return fitExtent(projection, extent, object);
  };

  projection.fitSize =3D function(size, object) {
    return fitSize(projection, size, object);
  };

  projection.fitWidth =3D function(width, object) {
    return fitWidth(projection, width, object);
  };

  projection.fitHeight =3D function(height, object) {
    return fitHeight(projection, height, object);
  };

  function recenter() {
    var center =3D scaleTranslateRotate(k, 0, 0, alpha).apply(null, project=
(lambda, phi)),
        transform$$1 =3D (alpha ? scaleTranslateRotate : scaleTranslate)(k,=
 x - center[0], y - center[1], alpha);
    rotate =3D rotateRadians(deltaLambda, deltaPhi, deltaGamma);
    projectTransform =3D compose(project, transform$$1);
    projectRotateTransform =3D compose(rotate, projectTransform);
    projectResample =3D resample(projectTransform, delta2);
    return reset();
  }

  function reset() {
    cache =3D cacheStream =3D null;
    return projection;
  }

  return function() {
    project =3D projectAt.apply(this, arguments);
    projection.invert =3D project.invert && invert;
    return recenter();
  };
}

function conicProjection(projectAt) {
  var phi0 =3D 0,
      phi1 =3D pi$3 / 3,
      m =3D projectionMutator(projectAt),
      p =3D m(phi0, phi1);

  p.parallels =3D function(_) {
    return arguments.length ? m(phi0 =3D _[0] * radians, phi1 =3D _[1] * ra=
dians) : [phi0 * degrees$1, phi1 * degrees$1];
  };

  return p;
}

function cylindricalEqualAreaRaw(phi0) {
  var cosPhi0 =3D cos$1(phi0);

  function forward(lambda, phi) {
    return [lambda * cosPhi0, sin$1(phi) / cosPhi0];
  }

  forward.invert =3D function(x, y) {
    return [x / cosPhi0, asin(y * cosPhi0)];
  };

  return forward;
}

function conicEqualAreaRaw(y0, y1) {
  var sy0 =3D sin$1(y0), n =3D (sy0 + sin$1(y1)) / 2;

  // Are the parallels symmetrical around the Equator?
  if (abs(n) < epsilon$2) return cylindricalEqualAreaRaw(y0);

  var c =3D 1 + sy0 * (2 * n - sy0), r0 =3D sqrt(c) / n;

  function project(x, y) {
    var r =3D sqrt(c - 2 * n * sin$1(y)) / n;
    return [r * sin$1(x *=3D n), r0 - r * cos$1(x)];
  }

  project.invert =3D function(x, y) {
    var r0y =3D r0 - y;
    return [atan2(x, abs(r0y)) / n * sign(r0y), asin((c - (x * x + r0y * r0=
y) * n * n) / (2 * n))];
  };

  return project;
}

function conicEqualArea() {
  return conicProjection(conicEqualAreaRaw)
      .scale(155.424)
      .center([0, 33.6442]);
}

function albers() {
  return conicEqualArea()
      .parallels([29.5, 45.5])
      .scale(1070)
      .translate([480, 250])
      .rotate([96, 0])
      .center([-0.6, 38.7]);
}

// The projections must have mutually exclusive clip regions on the sphere,
// as this will avoid emitting interleaving lines and polygons.
function multiplex(streams) {
  var n =3D streams.length;
  return {
    point: function(x, y) { var i =3D -1; while (++i < n) streams[i].point(=
x, y); },
    sphere: function() { var i =3D -1; while (++i < n) streams[i].sphere();=
 },
    lineStart: function() { var i =3D -1; while (++i < n) streams[i].lineSt=
art(); },
    lineEnd: function() { var i =3D -1; while (++i < n) streams[i].lineEnd(=
); },
    polygonStart: function() { var i =3D -1; while (++i < n) streams[i].pol=
ygonStart(); },
    polygonEnd: function() { var i =3D -1; while (++i < n) streams[i].polyg=
onEnd(); }
  };
}

// A composite projection for the United States, configured by default for
// 960=C3=97500. The projection also works quite well at 960=C3=97600 if yo=
u change the
// scale to 1285 and adjust the translate accordingly. The set of standard
// parallels for each region comes from USGS, which is published here:
// http://egsc.usgs.gov/isb/pubs/MapProjections/projections.html#albers
function albersUsa() {
  var cache,
      cacheStream,
      lower48 =3D albers(), lower48Point,
      alaska =3D conicEqualArea().rotate([154, 0]).center([-2, 58.5]).paral=
lels([55, 65]), alaskaPoint, // EPSG:3338
      hawaii =3D conicEqualArea().rotate([157, 0]).center([-3, 19.9]).paral=
lels([8, 18]), hawaiiPoint, // ESRI:102007
      point, pointStream =3D {point: function(x, y) { point =3D [x, y]; }};

  function albersUsa(coordinates) {
    var x =3D coordinates[0], y =3D coordinates[1];
    return point =3D null,
        (lower48Point.point(x, y), point)
        || (alaskaPoint.point(x, y), point)
        || (hawaiiPoint.point(x, y), point);
  }

  albersUsa.invert =3D function(coordinates) {
    var k =3D lower48.scale(),
        t =3D lower48.translate(),
        x =3D (coordinates[0] - t[0]) / k,
        y =3D (coordinates[1] - t[1]) / k;
    return (y >=3D 0.120 && y < 0.234 && x >=3D -0.425 && x < -0.214 ? alas=
ka
        : y >=3D 0.166 && y < 0.234 && x >=3D -0.214 && x < -0.115 ? hawaii
        : lower48).invert(coordinates);
  };

  albersUsa.stream =3D function(stream) {
    return cache && cacheStream =3D=3D=3D stream ? cache : cache =3D multip=
lex([lower48.stream(cacheStream =3D stream), alaska.stream(stream), hawaii.=
stream(stream)]);
  };

  albersUsa.precision =3D function(_) {
    if (!arguments.length) return lower48.precision();
    lower48.precision(_), alaska.precision(_), hawaii.precision(_);
    return reset();
  };

  albersUsa.scale =3D function(_) {
    if (!arguments.length) return lower48.scale();
    lower48.scale(_), alaska.scale(_ * 0.35), hawaii.scale(_);
    return albersUsa.translate(lower48.translate());
  };

  albersUsa.translate =3D function(_) {
    if (!arguments.length) return lower48.translate();
    var k =3D lower48.scale(), x =3D +_[0], y =3D +_[1];

    lower48Point =3D lower48
        .translate(_)
        .clipExtent([[x - 0.455 * k, y - 0.238 * k], [x + 0.455 * k, y + 0.=
238 * k]])
        .stream(pointStream);

    alaskaPoint =3D alaska
        .translate([x - 0.307 * k, y + 0.201 * k])
        .clipExtent([[x - 0.425 * k + epsilon$2, y + 0.120 * k + epsilon$2]=
, [x - 0.214 * k - epsilon$2, y + 0.234 * k - epsilon$2]])
        .stream(pointStream);

    hawaiiPoint =3D hawaii
        .translate([x - 0.205 * k, y + 0.212 * k])
        .clipExtent([[x - 0.214 * k + epsilon$2, y + 0.166 * k + epsilon$2]=
, [x - 0.115 * k - epsilon$2, y + 0.234 * k - epsilon$2]])
        .stream(pointStream);

    return reset();
  };

  albersUsa.fitExtent =3D function(extent, object) {
    return fitExtent(albersUsa, extent, object);
  };

  albersUsa.fitSize =3D function(size, object) {
    return fitSize(albersUsa, size, object);
  };

  albersUsa.fitWidth =3D function(width, object) {
    return fitWidth(albersUsa, width, object);
  };

  albersUsa.fitHeight =3D function(height, object) {
    return fitHeight(albersUsa, height, object);
  };

  function reset() {
    cache =3D cacheStream =3D null;
    return albersUsa;
  }

  return albersUsa.scale(1070);
}

function azimuthalRaw(scale) {
  return function(x, y) {
    var cx =3D cos$1(x),
        cy =3D cos$1(y),
        k =3D scale(cx * cy);
    return [
      k * cy * sin$1(x),
      k * sin$1(y)
    ];
  }
}

function azimuthalInvert(angle) {
  return function(x, y) {
    var z =3D sqrt(x * x + y * y),
        c =3D angle(z),
        sc =3D sin$1(c),
        cc =3D cos$1(c);
    return [
      atan2(x * sc, z * cc),
      asin(z && y * sc / z)
    ];
  }
}

var azimuthalEqualAreaRaw =3D azimuthalRaw(function(cxcy) {
  return sqrt(2 / (1 + cxcy));
});

azimuthalEqualAreaRaw.invert =3D azimuthalInvert(function(z) {
  return 2 * asin(z / 2);
});

function azimuthalEqualArea() {
  return projection(azimuthalEqualAreaRaw)
      .scale(124.75)
      .clipAngle(180 - 1e-3);
}

var azimuthalEquidistantRaw =3D azimuthalRaw(function(c) {
  return (c =3D acos(c)) && c / sin$1(c);
});

azimuthalEquidistantRaw.invert =3D azimuthalInvert(function(z) {
  return z;
});

function azimuthalEquidistant() {
  return projection(azimuthalEquidistantRaw)
      .scale(79.4188)
      .clipAngle(180 - 1e-3);
}

function mercatorRaw(lambda, phi) {
  return [lambda, log(tan((halfPi$2 + phi) / 2))];
}

mercatorRaw.invert =3D function(x, y) {
  return [x, 2 * atan(exp(y)) - halfPi$2];
};

function mercator() {
  return mercatorProjection(mercatorRaw)
      .scale(961 / tau$3);
}

function mercatorProjection(project) {
  var m =3D projection(project),
      center =3D m.center,
      scale =3D m.scale,
      translate =3D m.translate,
      clipExtent =3D m.clipExtent,
      x0 =3D null, y0, x1, y1; // clip extent

  m.scale =3D function(_) {
    return arguments.length ? (scale(_), reclip()) : scale();
  };

  m.translate =3D function(_) {
    return arguments.length ? (translate(_), reclip()) : translate();
  };

  m.center =3D function(_) {
    return arguments.length ? (center(_), reclip()) : center();
  };

  m.clipExtent =3D function(_) {
    return arguments.length ? ((_ =3D=3D null ? x0 =3D y0 =3D x1 =3D y1 =3D=
 null : (x0 =3D +_[0][0], y0 =3D +_[0][1], x1 =3D +_[1][0], y1 =3D +_[1][1]=
)), reclip()) : x0 =3D=3D null ? null : [[x0, y0], [x1, y1]];
  };

  function reclip() {
    var k =3D pi$3 * scale(),
        t =3D m(rotation(m.rotate()).invert([0, 0]));
    return clipExtent(x0 =3D=3D null
        ? [[t[0] - k, t[1] - k], [t[0] + k, t[1] + k]] : project =3D=3D=3D =
mercatorRaw
        ? [[Math.max(t[0] - k, x0), y0], [Math.min(t[0] + k, x1), y1]]
        : [[x0, Math.max(t[1] - k, y0)], [x1, Math.min(t[1] + k, y1)]]);
  }

  return reclip();
}

function tany(y) {
  return tan((halfPi$2 + y) / 2);
}

function conicConformalRaw(y0, y1) {
  var cy0 =3D cos$1(y0),
      n =3D y0 =3D=3D=3D y1 ? sin$1(y0) : log(cy0 / cos$1(y1)) / log(tany(y=
1) / tany(y0)),
      f =3D cy0 * pow(tany(y0), n) / n;

  if (!n) return mercatorRaw;

  function project(x, y) {
    if (f > 0) { if (y < -halfPi$2 + epsilon$2) y =3D -halfPi$2 + epsilon$2=
; }
    else { if (y > halfPi$2 - epsilon$2) y =3D halfPi$2 - epsilon$2; }
    var r =3D f / pow(tany(y), n);
    return [r * sin$1(n * x), f - r * cos$1(n * x)];
  }

  project.invert =3D function(x, y) {
    var fy =3D f - y, r =3D sign(n) * sqrt(x * x + fy * fy);
    return [atan2(x, abs(fy)) / n * sign(fy), 2 * atan(pow(f / r, 1 / n)) -=
 halfPi$2];
  };

  return project;
}

function conicConformal() {
  return conicProjection(conicConformalRaw)
      .scale(109.5)
      .parallels([30, 30]);
}

function equirectangularRaw(lambda, phi) {
  return [lambda, phi];
}

equirectangularRaw.invert =3D equirectangularRaw;

function equirectangular() {
  return projection(equirectangularRaw)
      .scale(152.63);
}

function conicEquidistantRaw(y0, y1) {
  var cy0 =3D cos$1(y0),
      n =3D y0 =3D=3D=3D y1 ? sin$1(y0) : (cy0 - cos$1(y1)) / (y1 - y0),
      g =3D cy0 / n + y0;

  if (abs(n) < epsilon$2) return equirectangularRaw;

  function project(x, y) {
    var gy =3D g - y, nx =3D n * x;
    return [gy * sin$1(nx), g - gy * cos$1(nx)];
  }

  project.invert =3D function(x, y) {
    var gy =3D g - y;
    return [atan2(x, abs(gy)) / n * sign(gy), g - sign(n) * sqrt(x * x + gy=
 * gy)];
  };

  return project;
}

function conicEquidistant() {
  return conicProjection(conicEquidistantRaw)
      .scale(131.154)
      .center([0, 13.9389]);
}

var A1 =3D 1.340264,
    A2 =3D -0.081106,
    A3 =3D 0.000893,
    A4 =3D 0.003796,
    M =3D sqrt(3) / 2,
    iterations =3D 12;

function equalEarthRaw(lambda, phi) {
  var l =3D asin(M * sin$1(phi)), l2 =3D l * l, l6 =3D l2 * l2 * l2;
  return [
    lambda * cos$1(l) / (M * (A1 + 3 * A2 * l2 + l6 * (7 * A3 + 9 * A4 * l2=
))),
    l * (A1 + A2 * l2 + l6 * (A3 + A4 * l2))
  ];
}

equalEarthRaw.invert =3D function(x, y) {
  var l =3D y, l2 =3D l * l, l6 =3D l2 * l2 * l2;
  for (var i =3D 0, delta, fy, fpy; i < iterations; ++i) {
    fy =3D l * (A1 + A2 * l2 + l6 * (A3 + A4 * l2)) - y;
    fpy =3D A1 + 3 * A2 * l2 + l6 * (7 * A3 + 9 * A4 * l2);
    l -=3D delta =3D fy / fpy, l2 =3D l * l, l6 =3D l2 * l2 * l2;
    if (abs(delta) < epsilon2$1) break;
  }
  return [
    M * x * (A1 + 3 * A2 * l2 + l6 * (7 * A3 + 9 * A4 * l2)) / cos$1(l),
    asin(sin$1(l) / M)
  ];
};

function equalEarth() {
  return projection(equalEarthRaw)
      .scale(177.158);
}

function gnomonicRaw(x, y) {
  var cy =3D cos$1(y), k =3D cos$1(x) * cy;
  return [cy * sin$1(x) / k, sin$1(y) / k];
}

gnomonicRaw.invert =3D azimuthalInvert(atan);

function gnomonic() {
  return projection(gnomonicRaw)
      .scale(144.049)
      .clipAngle(60);
}

function scaleTranslate$1(kx, ky, tx, ty) {
  return kx =3D=3D=3D 1 && ky =3D=3D=3D 1 && tx =3D=3D=3D 0 && ty =3D=3D=3D=
 0 ? identity$4 : transformer({
    point: function(x, y) {
      this.stream.point(x * kx + tx, y * ky + ty);
    }
  });
}

function identity$5() {
  var k =3D 1, tx =3D 0, ty =3D 0, sx =3D 1, sy =3D 1, transform$$1 =3D ide=
ntity$4, // scale, translate and reflect
      x0 =3D null, y0, x1, y1, // clip extent
      postclip =3D identity$4,
      cache,
      cacheStream,
      projection;

  function reset() {
    cache =3D cacheStream =3D null;
    return projection;
  }

  return projection =3D {
    stream: function(stream) {
      return cache && cacheStream =3D=3D=3D stream ? cache : cache =3D tran=
sform$$1(postclip(cacheStream =3D stream));
    },
    postclip: function(_) {
      return arguments.length ? (postclip =3D _, x0 =3D y0 =3D x1 =3D y1 =
=3D null, reset()) : postclip;
    },
    clipExtent: function(_) {
      return arguments.length ? (postclip =3D _ =3D=3D null ? (x0 =3D y0 =
=3D x1 =3D y1 =3D null, identity$4) : clipRectangle(x0 =3D +_[0][0], y0 =3D=
 +_[0][1], x1 =3D +_[1][0], y1 =3D +_[1][1]), reset()) : x0 =3D=3D null ? n=
ull : [[x0, y0], [x1, y1]];
    },
    scale: function(_) {
      return arguments.length ? (transform$$1 =3D scaleTranslate$1((k =3D +=
_) * sx, k * sy, tx, ty), reset()) : k;
    },
    translate: function(_) {
      return arguments.length ? (transform$$1 =3D scaleTranslate$1(k * sx, =
k * sy, tx =3D +_[0], ty =3D +_[1]), reset()) : [tx, ty];
    },
    reflectX: function(_) {
      return arguments.length ? (transform$$1 =3D scaleTranslate$1(k * (sx =
=3D _ ? -1 : 1), k * sy, tx, ty), reset()) : sx < 0;
    },
    reflectY: function(_) {
      return arguments.length ? (transform$$1 =3D scaleTranslate$1(k * sx, =
k * (sy =3D _ ? -1 : 1), tx, ty), reset()) : sy < 0;
    },
    fitExtent: function(extent, object) {
      return fitExtent(projection, extent, object);
    },
    fitSize: function(size, object) {
      return fitSize(projection, size, object);
    },
    fitWidth: function(width, object) {
      return fitWidth(projection, width, object);
    },
    fitHeight: function(height, object) {
      return fitHeight(projection, height, object);
    }
  };
}

function naturalEarth1Raw(lambda, phi) {
  var phi2 =3D phi * phi, phi4 =3D phi2 * phi2;
  return [
    lambda * (0.8707 - 0.131979 * phi2 + phi4 * (-0.013791 + phi4 * (0.0039=
71 * phi2 - 0.001529 * phi4))),
    phi * (1.007226 + phi2 * (0.015085 + phi4 * (-0.044475 + 0.028874 * phi=
2 - 0.005916 * phi4)))
  ];
}

naturalEarth1Raw.invert =3D function(x, y) {
  var phi =3D y, i =3D 25, delta;
  do {
    var phi2 =3D phi * phi, phi4 =3D phi2 * phi2;
    phi -=3D delta =3D (phi * (1.007226 + phi2 * (0.015085 + phi4 * (-0.044=
475 + 0.028874 * phi2 - 0.005916 * phi4))) - y) /
        (1.007226 + phi2 * (0.015085 * 3 + phi4 * (-0.044475 * 7 + 0.028874=
 * 9 * phi2 - 0.005916 * 11 * phi4)));
  } while (abs(delta) > epsilon$2 && --i > 0);
  return [
    x / (0.8707 + (phi2 =3D phi * phi) * (-0.131979 + phi2 * (-0.013791 + p=
hi2 * phi2 * phi2 * (0.003971 - 0.001529 * phi2)))),
    phi
  ];
};

function naturalEarth1() {
  return projection(naturalEarth1Raw)
      .scale(175.295);
}

function orthographicRaw(x, y) {
  return [cos$1(y) * sin$1(x), sin$1(y)];
}

orthographicRaw.invert =3D azimuthalInvert(asin);

function orthographic() {
  return projection(orthographicRaw)
      .scale(249.5)
      .clipAngle(90 + epsilon$2);
}

function stereographicRaw(x, y) {
  var cy =3D cos$1(y), k =3D 1 + cos$1(x) * cy;
  return [cy * sin$1(x) / k, sin$1(y) / k];
}

stereographicRaw.invert =3D azimuthalInvert(function(z) {
  return 2 * atan(z);
});

function stereographic() {
  return projection(stereographicRaw)
      .scale(250)
      .clipAngle(142);
}

function transverseMercatorRaw(lambda, phi) {
  return [log(tan((halfPi$2 + phi) / 2)), -lambda];
}

transverseMercatorRaw.invert =3D function(x, y) {
  return [-y, 2 * atan(exp(x)) - halfPi$2];
};

function transverseMercator() {
  var m =3D mercatorProjection(transverseMercatorRaw),
      center =3D m.center,
      rotate =3D m.rotate;

  m.center =3D function(_) {
    return arguments.length ? center([-_[1], _[0]]) : (_ =3D center(), [_[1=
], -_[0]]);
  };

  m.rotate =3D function(_) {
    return arguments.length ? rotate([_[0], _[1], _.length > 2 ? _[2] + 90 =
: 90]) : (_ =3D rotate(), [_[0], _[1], _[2] - 90]);
  };

  return rotate([0, 0, 90])
      .scale(159.155);
}

function defaultSeparation(a, b) {
  return a.parent =3D=3D=3D b.parent ? 1 : 2;
}

function meanX(children) {
  return children.reduce(meanXReduce, 0) / children.length;
}

function meanXReduce(x, c) {
  return x + c.x;
}

function maxY(children) {
  return 1 + children.reduce(maxYReduce, 0);
}

function maxYReduce(y, c) {
  return Math.max(y, c.y);
}

function leafLeft(node) {
  var children;
  while (children =3D node.children) node =3D children[0];
  return node;
}

function leafRight(node) {
  var children;
  while (children =3D node.children) node =3D children[children.length - 1];
  return node;
}

function cluster() {
  var separation =3D defaultSeparation,
      dx =3D 1,
      dy =3D 1,
      nodeSize =3D false;

  function cluster(root) {
    var previousNode,
        x =3D 0;

    // First walk, computing the initial x & y values.
    root.eachAfter(function(node) {
      var children =3D node.children;
      if (children) {
        node.x =3D meanX(children);
        node.y =3D maxY(children);
      } else {
        node.x =3D previousNode ? x +=3D separation(node, previousNode) : 0;
        node.y =3D 0;
        previousNode =3D node;
      }
    });

    var left =3D leafLeft(root),
        right =3D leafRight(root),
        x0 =3D left.x - separation(left, right) / 2,
        x1 =3D right.x + separation(right, left) / 2;

    // Second walk, normalizing x & y to the desired size.
    return root.eachAfter(nodeSize ? function(node) {
      node.x =3D (node.x - root.x) * dx;
      node.y =3D (root.y - node.y) * dy;
    } : function(node) {
      node.x =3D (node.x - x0) / (x1 - x0) * dx;
      node.y =3D (1 - (root.y ? node.y / root.y : 1)) * dy;
    });
  }

  cluster.separation =3D function(x) {
    return arguments.length ? (separation =3D x, cluster) : separation;
  };

  cluster.size =3D function(x) {
    return arguments.length ? (nodeSize =3D false, dx =3D +x[0], dy =3D +x[=
1], cluster) : (nodeSize ? null : [dx, dy]);
  };

  cluster.nodeSize =3D function(x) {
    return arguments.length ? (nodeSize =3D true, dx =3D +x[0], dy =3D +x[1=
], cluster) : (nodeSize ? [dx, dy] : null);
  };

  return cluster;
}

function count(node) {
  var sum =3D 0,
      children =3D node.children,
      i =3D children && children.length;
  if (!i) sum =3D 1;
  else while (--i >=3D 0) sum +=3D children[i].value;
  node.value =3D sum;
}

function node_count() {
  return this.eachAfter(count);
}

function node_each(callback) {
  var node =3D this, current, next =3D [node], children, i, n;
  do {
    current =3D next.reverse(), next =3D [];
    while (node =3D current.pop()) {
      callback(node), children =3D node.children;
      if (children) for (i =3D 0, n =3D children.length; i < n; ++i) {
        next.push(children[i]);
      }
    }
  } while (next.length);
  return this;
}

function node_eachBefore(callback) {
  var node =3D this, nodes =3D [node], children, i;
  while (node =3D nodes.pop()) {
    callback(node), children =3D node.children;
    if (children) for (i =3D children.length - 1; i >=3D 0; --i) {
      nodes.push(children[i]);
    }
  }
  return this;
}

function node_eachAfter(callback) {
  var node =3D this, nodes =3D [node], next =3D [], children, i, n;
  while (node =3D nodes.pop()) {
    next.push(node), children =3D node.children;
    if (children) for (i =3D 0, n =3D children.length; i < n; ++i) {
      nodes.push(children[i]);
    }
  }
  while (node =3D next.pop()) {
    callback(node);
  }
  return this;
}

function node_sum(value) {
  return this.eachAfter(function(node) {
    var sum =3D +value(node.data) || 0,
        children =3D node.children,
        i =3D children && children.length;
    while (--i >=3D 0) sum +=3D children[i].value;
    node.value =3D sum;
  });
}

function node_sort(compare) {
  return this.eachBefore(function(node) {
    if (node.children) {
      node.children.sort(compare);
    }
  });
}

function node_path(end) {
  var start =3D this,
      ancestor =3D leastCommonAncestor(start, end),
      nodes =3D [start];
  while (start !=3D=3D ancestor) {
    start =3D start.parent;
    nodes.push(start);
  }
  var k =3D nodes.length;
  while (end !=3D=3D ancestor) {
    nodes.splice(k, 0, end);
    end =3D end.parent;
  }
  return nodes;
}

function leastCommonAncestor(a, b) {
  if (a =3D=3D=3D b) return a;
  var aNodes =3D a.ancestors(),
      bNodes =3D b.ancestors(),
      c =3D null;
  a =3D aNodes.pop();
  b =3D bNodes.pop();
  while (a =3D=3D=3D b) {
    c =3D a;
    a =3D aNodes.pop();
    b =3D bNodes.pop();
  }
  return c;
}

function node_ancestors() {
  var node =3D this, nodes =3D [node];
  while (node =3D node.parent) {
    nodes.push(node);
  }
  return nodes;
}

function node_descendants() {
  var nodes =3D [];
  this.each(function(node) {
    nodes.push(node);
  });
  return nodes;
}

function node_leaves() {
  var leaves =3D [];
  this.eachBefore(function(node) {
    if (!node.children) {
      leaves.push(node);
    }
  });
  return leaves;
}

function node_links() {
  var root =3D this, links =3D [];
  root.each(function(node) {
    if (node !=3D=3D root) { // Don=E2=80=99t include the root=E2=80=99s pa=
rent, if any.
      links.push({source: node.parent, target: node});
    }
  });
  return links;
}

function hierarchy(data, children) {
  var root =3D new Node(data),
      valued =3D +data.value && (root.value =3D data.value),
      node,
      nodes =3D [root],
      child,
      childs,
      i,
      n;

  if (children =3D=3D null) children =3D defaultChildren;

  while (node =3D nodes.pop()) {
    if (valued) node.value =3D +node.data.value;
    if ((childs =3D children(node.data)) && (n =3D childs.length)) {
      node.children =3D new Array(n);
      for (i =3D n - 1; i >=3D 0; --i) {
        nodes.push(child =3D node.children[i] =3D new Node(childs[i]));
        child.parent =3D node;
        child.depth =3D node.depth + 1;
      }
    }
  }

  return root.eachBefore(computeHeight);
}

function node_copy() {
  return hierarchy(this).eachBefore(copyData);
}

function defaultChildren(d) {
  return d.children;
}

function copyData(node) {
  node.data =3D node.data.data;
}

function computeHeight(node) {
  var height =3D 0;
  do node.height =3D height;
  while ((node =3D node.parent) && (node.height < ++height));
}

function Node(data) {
  this.data =3D data;
  this.depth =3D
  this.height =3D 0;
  this.parent =3D null;
}

Node.prototype =3D hierarchy.prototype =3D {
  constructor: Node,
  count: node_count,
  each: node_each,
  eachAfter: node_eachAfter,
  eachBefore: node_eachBefore,
  sum: node_sum,
  sort: node_sort,
  path: node_path,
  ancestors: node_ancestors,
  descendants: node_descendants,
  leaves: node_leaves,
  links: node_links,
  copy: node_copy
};

var slice$4 =3D Array.prototype.slice;

function shuffle$1(array) {
  var m =3D array.length,
      t,
      i;

  while (m) {
    i =3D Math.random() * m-- | 0;
    t =3D array[m];
    array[m] =3D array[i];
    array[i] =3D t;
  }

  return array;
}

function enclose(circles) {
  var i =3D 0, n =3D (circles =3D shuffle$1(slice$4.call(circles))).length,=
 B =3D [], p, e;

  while (i < n) {
    p =3D circles[i];
    if (e && enclosesWeak(e, p)) ++i;
    else e =3D encloseBasis(B =3D extendBasis(B, p)), i =3D 0;
  }

  return e;
}

function extendBasis(B, p) {
  var i, j;

  if (enclosesWeakAll(p, B)) return [p];

  // If we get here then B must have at least one element.
  for (i =3D 0; i < B.length; ++i) {
    if (enclosesNot(p, B[i])
        && enclosesWeakAll(encloseBasis2(B[i], p), B)) {
      return [B[i], p];
    }
  }

  // If we get here then B must have at least two elements.
  for (i =3D 0; i < B.length - 1; ++i) {
    for (j =3D i + 1; j < B.length; ++j) {
      if (enclosesNot(encloseBasis2(B[i], B[j]), p)
          && enclosesNot(encloseBasis2(B[i], p), B[j])
          && enclosesNot(encloseBasis2(B[j], p), B[i])
          && enclosesWeakAll(encloseBasis3(B[i], B[j], p), B)) {
        return [B[i], B[j], p];
      }
    }
  }

  // If we get here then something is very wrong.
  throw new Error;
}

function enclosesNot(a, b) {
  var dr =3D a.r - b.r, dx =3D b.x - a.x, dy =3D b.y - a.y;
  return dr < 0 || dr * dr < dx * dx + dy * dy;
}

function enclosesWeak(a, b) {
  var dr =3D a.r - b.r + 1e-6, dx =3D b.x - a.x, dy =3D b.y - a.y;
  return dr > 0 && dr * dr > dx * dx + dy * dy;
}

function enclosesWeakAll(a, B) {
  for (var i =3D 0; i < B.length; ++i) {
    if (!enclosesWeak(a, B[i])) {
      return false;
    }
  }
  return true;
}

function encloseBasis(B) {
  switch (B.length) {
    case 1: return encloseBasis1(B[0]);
    case 2: return encloseBasis2(B[0], B[1]);
    case 3: return encloseBasis3(B[0], B[1], B[2]);
  }
}

function encloseBasis1(a) {
  return {
    x: a.x,
    y: a.y,
    r: a.r
  };
}

function encloseBasis2(a, b) {
  var x1 =3D a.x, y1 =3D a.y, r1 =3D a.r,
      x2 =3D b.x, y2 =3D b.y, r2 =3D b.r,
      x21 =3D x2 - x1, y21 =3D y2 - y1, r21 =3D r2 - r1,
      l =3D Math.sqrt(x21 * x21 + y21 * y21);
  return {
    x: (x1 + x2 + x21 / l * r21) / 2,
    y: (y1 + y2 + y21 / l * r21) / 2,
    r: (l + r1 + r2) / 2
  };
}

function encloseBasis3(a, b, c) {
  var x1 =3D a.x, y1 =3D a.y, r1 =3D a.r,
      x2 =3D b.x, y2 =3D b.y, r2 =3D b.r,
      x3 =3D c.x, y3 =3D c.y, r3 =3D c.r,
      a2 =3D x1 - x2,
      a3 =3D x1 - x3,
      b2 =3D y1 - y2,
      b3 =3D y1 - y3,
      c2 =3D r2 - r1,
      c3 =3D r3 - r1,
      d1 =3D x1 * x1 + y1 * y1 - r1 * r1,
      d2 =3D d1 - x2 * x2 - y2 * y2 + r2 * r2,
      d3 =3D d1 - x3 * x3 - y3 * y3 + r3 * r3,
      ab =3D a3 * b2 - a2 * b3,
      xa =3D (b2 * d3 - b3 * d2) / (ab * 2) - x1,
      xb =3D (b3 * c2 - b2 * c3) / ab,
      ya =3D (a3 * d2 - a2 * d3) / (ab * 2) - y1,
      yb =3D (a2 * c3 - a3 * c2) / ab,
      A =3D xb * xb + yb * yb - 1,
      B =3D 2 * (r1 + xa * xb + ya * yb),
      C =3D xa * xa + ya * ya - r1 * r1,
      r =3D -(A ? (B + Math.sqrt(B * B - 4 * A * C)) / (2 * A) : C / B);
  return {
    x: x1 + xa + xb * r,
    y: y1 + ya + yb * r,
    r: r
  };
}

function place(b, a, c) {
  var dx =3D b.x - a.x, x, a2,
      dy =3D b.y - a.y, y, b2,
      d2 =3D dx * dx + dy * dy;
  if (d2) {
    a2 =3D a.r + c.r, a2 *=3D a2;
    b2 =3D b.r + c.r, b2 *=3D b2;
    if (a2 > b2) {
      x =3D (d2 + b2 - a2) / (2 * d2);
      y =3D Math.sqrt(Math.max(0, b2 / d2 - x * x));
      c.x =3D b.x - x * dx - y * dy;
      c.y =3D b.y - x * dy + y * dx;
    } else {
      x =3D (d2 + a2 - b2) / (2 * d2);
      y =3D Math.sqrt(Math.max(0, a2 / d2 - x * x));
      c.x =3D a.x + x * dx - y * dy;
      c.y =3D a.y + x * dy + y * dx;
    }
  } else {
    c.x =3D a.x + c.r;
    c.y =3D a.y;
  }
}

function intersects(a, b) {
  var dr =3D a.r + b.r - 1e-6, dx =3D b.x - a.x, dy =3D b.y - a.y;
  return dr > 0 && dr * dr > dx * dx + dy * dy;
}

function score(node) {
  var a =3D node._,
      b =3D node.next._,
      ab =3D a.r + b.r,
      dx =3D (a.x * b.r + b.x * a.r) / ab,
      dy =3D (a.y * b.r + b.y * a.r) / ab;
  return dx * dx + dy * dy;
}

function Node$1(circle) {
  this._ =3D circle;
  this.next =3D null;
  this.previous =3D null;
}

function packEnclose(circles) {
  if (!(n =3D circles.length)) return 0;

  var a, b, c, n, aa, ca, i, j, k, sj, sk;

  // Place the first circle.
  a =3D circles[0], a.x =3D 0, a.y =3D 0;
  if (!(n > 1)) return a.r;

  // Place the second circle.
  b =3D circles[1], a.x =3D -b.r, b.x =3D a.r, b.y =3D 0;
  if (!(n > 2)) return a.r + b.r;

  // Place the third circle.
  place(b, a, c =3D circles[2]);

  // Initialize the front-chain using the first three circles a, b and c.
  a =3D new Node$1(a), b =3D new Node$1(b), c =3D new Node$1(c);
  a.next =3D c.previous =3D b;
  b.next =3D a.previous =3D c;
  c.next =3D b.previous =3D a;

  // Attempt to place each remaining circle=E2=80=A6
  pack: for (i =3D 3; i < n; ++i) {
    place(a._, b._, c =3D circles[i]), c =3D new Node$1(c);

    // Find the closest intersecting circle on the front-chain, if any.
    // =E2=80=9CCloseness=E2=80=9D is determined by linear distance along t=
he front-chain.
    // =E2=80=9CAhead=E2=80=9D or =E2=80=9Cbehind=E2=80=9D is likewise dete=
rmined by linear distance.
    j =3D b.next, k =3D a.previous, sj =3D b._.r, sk =3D a._.r;
    do {
      if (sj <=3D sk) {
        if (intersects(j._, c._)) {
          b =3D j, a.next =3D b, b.previous =3D a, --i;
          continue pack;
        }
        sj +=3D j._.r, j =3D j.next;
      } else {
        if (intersects(k._, c._)) {
          a =3D k, a.next =3D b, b.previous =3D a, --i;
          continue pack;
        }
        sk +=3D k._.r, k =3D k.previous;
      }
    } while (j !=3D=3D k.next);

    // Success! Insert the new circle c between a and b.
    c.previous =3D a, c.next =3D b, a.next =3D b.previous =3D b =3D c;

    // Compute the new closest circle pair to the centroid.
    aa =3D score(a);
    while ((c =3D c.next) !=3D=3D b) {
      if ((ca =3D score(c)) < aa) {
        a =3D c, aa =3D ca;
      }
    }
    b =3D a.next;
  }

  // Compute the enclosing circle of the front chain.
  a =3D [b._], c =3D b; while ((c =3D c.next) !=3D=3D b) a.push(c._); c =3D=
 enclose(a);

  // Translate the circles to put the enclosing circle around the origin.
  for (i =3D 0; i < n; ++i) a =3D circles[i], a.x -=3D c.x, a.y -=3D c.y;

  return c.r;
}

function siblings(circles) {
  packEnclose(circles);
  return circles;
}

function optional(f) {
  return f =3D=3D null ? null : required(f);
}

function required(f) {
  if (typeof f !=3D=3D "function") throw new Error;
  return f;
}

function constantZero() {
  return 0;
}

function constant$9(x) {
  return function() {
    return x;
  };
}

function defaultRadius$1(d) {
  return Math.sqrt(d.value);
}

function index$2() {
  var radius =3D null,
      dx =3D 1,
      dy =3D 1,
      padding =3D constantZero;

  function pack(root) {
    root.x =3D dx / 2, root.y =3D dy / 2;
    if (radius) {
      root.eachBefore(radiusLeaf(radius))
          .eachAfter(packChildren(padding, 0.5))
          .eachBefore(translateChild(1));
    } else {
      root.eachBefore(radiusLeaf(defaultRadius$1))
          .eachAfter(packChildren(constantZero, 1))
          .eachAfter(packChildren(padding, root.r / Math.min(dx, dy)))
          .eachBefore(translateChild(Math.min(dx, dy) / (2 * root.r)));
    }
    return root;
  }

  pack.radius =3D function(x) {
    return arguments.length ? (radius =3D optional(x), pack) : radius;
  };

  pack.size =3D function(x) {
    return arguments.length ? (dx =3D +x[0], dy =3D +x[1], pack) : [dx, dy];
  };

  pack.padding =3D function(x) {
    return arguments.length ? (padding =3D typeof x =3D=3D=3D "function" ? =
x : constant$9(+x), pack) : padding;
  };

  return pack;
}

function radiusLeaf(radius) {
  return function(node) {
    if (!node.children) {
      node.r =3D Math.max(0, +radius(node) || 0);
    }
  };
}

function packChildren(padding, k) {
  return function(node) {
    if (children =3D node.children) {
      var children,
          i,
          n =3D children.length,
          r =3D padding(node) * k || 0,
          e;

      if (r) for (i =3D 0; i < n; ++i) children[i].r +=3D r;
      e =3D packEnclose(children);
      if (r) for (i =3D 0; i < n; ++i) children[i].r -=3D r;
      node.r =3D e + r;
    }
  };
}

function translateChild(k) {
  return function(node) {
    var parent =3D node.parent;
    node.r *=3D k;
    if (parent) {
      node.x =3D parent.x + k * node.x;
      node.y =3D parent.y + k * node.y;
    }
  };
}

function roundNode(node) {
  node.x0 =3D Math.round(node.x0);
  node.y0 =3D Math.round(node.y0);
  node.x1 =3D Math.round(node.x1);
  node.y1 =3D Math.round(node.y1);
}

function treemapDice(parent, x0, y0, x1, y1) {
  var nodes =3D parent.children,
      node,
      i =3D -1,
      n =3D nodes.length,
      k =3D parent.value && (x1 - x0) / parent.value;

  while (++i < n) {
    node =3D nodes[i], node.y0 =3D y0, node.y1 =3D y1;
    node.x0 =3D x0, node.x1 =3D x0 +=3D node.value * k;
  }
}

function partition() {
  var dx =3D 1,
      dy =3D 1,
      padding =3D 0,
      round =3D false;

  function partition(root) {
    var n =3D root.height + 1;
    root.x0 =3D
    root.y0 =3D padding;
    root.x1 =3D dx;
    root.y1 =3D dy / n;
    root.eachBefore(positionNode(dy, n));
    if (round) root.eachBefore(roundNode);
    return root;
  }

  function positionNode(dy, n) {
    return function(node) {
      if (node.children) {
        treemapDice(node, node.x0, dy * (node.depth + 1) / n, node.x1, dy *=
 (node.depth + 2) / n);
      }
      var x0 =3D node.x0,
          y0 =3D node.y0,
          x1 =3D node.x1 - padding,
          y1 =3D node.y1 - padding;
      if (x1 < x0) x0 =3D x1 =3D (x0 + x1) / 2;
      if (y1 < y0) y0 =3D y1 =3D (y0 + y1) / 2;
      node.x0 =3D x0;
      node.y0 =3D y0;
      node.x1 =3D x1;
      node.y1 =3D y1;
    };
  }

  partition.round =3D function(x) {
    return arguments.length ? (round =3D !!x, partition) : round;
  };

  partition.size =3D function(x) {
    return arguments.length ? (dx =3D +x[0], dy =3D +x[1], partition) : [dx=
, dy];
  };

  partition.padding =3D function(x) {
    return arguments.length ? (padding =3D +x, partition) : padding;
  };

  return partition;
}

var keyPrefix$1 =3D "$", // Protect against keys like =E2=80=9C__proto__=E2=
=80=9D.
    preroot =3D {depth: -1},
    ambiguous =3D {};

function defaultId(d) {
  return d.id;
}

function defaultParentId(d) {
  return d.parentId;
}

function stratify() {
  var id =3D defaultId,
      parentId =3D defaultParentId;

  function stratify(data) {
    var d,
        i,
        n =3D data.length,
        root,
        parent,
        node,
        nodes =3D new Array(n),
        nodeId,
        nodeKey,
        nodeByKey =3D {};

    for (i =3D 0; i < n; ++i) {
      d =3D data[i], node =3D nodes[i] =3D new Node(d);
      if ((nodeId =3D id(d, i, data)) !=3D null && (nodeId +=3D "")) {
        nodeKey =3D keyPrefix$1 + (node.id =3D nodeId);
        nodeByKey[nodeKey] =3D nodeKey in nodeByKey ? ambiguous : node;
      }
    }

    for (i =3D 0; i < n; ++i) {
      node =3D nodes[i], nodeId =3D parentId(data[i], i, data);
      if (nodeId =3D=3D null || !(nodeId +=3D "")) {
        if (root) throw new Error("multiple roots");
        root =3D node;
      } else {
        parent =3D nodeByKey[keyPrefix$1 + nodeId];
        if (!parent) throw new Error("missing: " + nodeId);
        if (parent =3D=3D=3D ambiguous) throw new Error("ambiguous: " + nod=
eId);
        if (parent.children) parent.children.push(node);
        else parent.children =3D [node];
        node.parent =3D parent;
      }
    }

    if (!root) throw new Error("no root");
    root.parent =3D preroot;
    root.eachBefore(function(node) { node.depth =3D node.parent.depth + 1; =
--n; }).eachBefore(computeHeight);
    root.parent =3D null;
    if (n > 0) throw new Error("cycle");

    return root;
  }

  stratify.id =3D function(x) {
    return arguments.length ? (id =3D required(x), stratify) : id;
  };

  stratify.parentId =3D function(x) {
    return arguments.length ? (parentId =3D required(x), stratify) : parent=
Id;
  };

  return stratify;
}

function defaultSeparation$1(a, b) {
  return a.parent =3D=3D=3D b.parent ? 1 : 2;
}

// function radialSeparation(a, b) {
//   return (a.parent =3D=3D=3D b.parent ? 1 : 2) / a.depth;
// }

// This function is used to traverse the left contour of a subtree (or
// subforest). It returns the successor of v on this contour. This successo=
r is
// either given by the leftmost child of v or by the thread of v. The funct=
ion
// returns null if and only if v is on the highest level of its subtree.
function nextLeft(v) {
  var children =3D v.children;
  return children ? children[0] : v.t;
}

// This function works analogously to nextLeft.
function nextRight(v) {
  var children =3D v.children;
  return children ? children[children.length - 1] : v.t;
}

// Shifts the current subtree rooted at w+. This is done by increasing
// prelim(w+) and mod(w+) by shift.
function moveSubtree(wm, wp, shift) {
  var change =3D shift / (wp.i - wm.i);
  wp.c -=3D change;
  wp.s +=3D shift;
  wm.c +=3D change;
  wp.z +=3D shift;
  wp.m +=3D shift;
}

// All other shifts, applied to the smaller subtrees between w- and w+, are
// performed by this function. To prepare the shifts, we have to adjust
// change(w+), shift(w+), and change(w-).
function executeShifts(v) {
  var shift =3D 0,
      change =3D 0,
      children =3D v.children,
      i =3D children.length,
      w;
  while (--i >=3D 0) {
    w =3D children[i];
    w.z +=3D shift;
    w.m +=3D shift;
    shift +=3D w.s + (change +=3D w.c);
  }
}

// If vi-=E2=80=99s ancestor is a sibling of v, returns vi-=E2=80=99s ances=
tor. Otherwise,
// returns the specified (default) ancestor.
function nextAncestor(vim, v, ancestor) {
  return vim.a.parent =3D=3D=3D v.parent ? vim.a : ancestor;
}

function TreeNode(node, i) {
  this._ =3D node;
  this.parent =3D null;
  this.children =3D null;
  this.A =3D null; // default ancestor
  this.a =3D this; // ancestor
  this.z =3D 0; // prelim
  this.m =3D 0; // mod
  this.c =3D 0; // change
  this.s =3D 0; // shift
  this.t =3D null; // thread
  this.i =3D i; // number
}

TreeNode.prototype =3D Object.create(Node.prototype);

function treeRoot(root) {
  var tree =3D new TreeNode(root, 0),
      node,
      nodes =3D [tree],
      child,
      children,
      i,
      n;

  while (node =3D nodes.pop()) {
    if (children =3D node._.children) {
      node.children =3D new Array(n =3D children.length);
      for (i =3D n - 1; i >=3D 0; --i) {
        nodes.push(child =3D node.children[i] =3D new TreeNode(children[i],=
 i));
        child.parent =3D node;
      }
    }
  }

  (tree.parent =3D new TreeNode(null, 0)).children =3D [tree];
  return tree;
}

// Node-link tree diagram using the Reingold-Tilford "tidy" algorithm
function tree() {
  var separation =3D defaultSeparation$1,
      dx =3D 1,
      dy =3D 1,
      nodeSize =3D null;

  function tree(root) {
    var t =3D treeRoot(root);

    // Compute the layout using Buchheim et al.=E2=80=99s algorithm.
    t.eachAfter(firstWalk), t.parent.m =3D -t.z;
    t.eachBefore(secondWalk);

    // If a fixed node size is specified, scale x and y.
    if (nodeSize) root.eachBefore(sizeNode);

    // If a fixed tree size is specified, scale x and y based on the extent.
    // Compute the left-most, right-most, and depth-most nodes for extents.
    else {
      var left =3D root,
          right =3D root,
          bottom =3D root;
      root.eachBefore(function(node) {
        if (node.x < left.x) left =3D node;
        if (node.x > right.x) right =3D node;
        if (node.depth > bottom.depth) bottom =3D node;
      });
      var s =3D left =3D=3D=3D right ? 1 : separation(left, right) / 2,
          tx =3D s - left.x,
          kx =3D dx / (right.x + s + tx),
          ky =3D dy / (bottom.depth || 1);
      root.eachBefore(function(node) {
        node.x =3D (node.x + tx) * kx;
        node.y =3D node.depth * ky;
      });
    }

    return root;
  }

  // Computes a preliminary x-coordinate for v. Before that, FIRST WALK is
  // applied recursively to the children of v, as well as the function
  // APPORTION. After spacing out the children by calling EXECUTE SHIFTS, t=
he
  // node v is placed to the midpoint of its outermost children.
  function firstWalk(v) {
    var children =3D v.children,
        siblings =3D v.parent.children,
        w =3D v.i ? siblings[v.i - 1] : null;
    if (children) {
      executeShifts(v);
      var midpoint =3D (children[0].z + children[children.length - 1].z) / =
2;
      if (w) {
        v.z =3D w.z + separation(v._, w._);
        v.m =3D v.z - midpoint;
      } else {
        v.z =3D midpoint;
      }
    } else if (w) {
      v.z =3D w.z + separation(v._, w._);
    }
    v.parent.A =3D apportion(v, w, v.parent.A || siblings[0]);
  }

  // Computes all real x-coordinates by summing up the modifiers recursivel=
y.
  function secondWalk(v) {
    v._.x =3D v.z + v.parent.m;
    v.m +=3D v.parent.m;
  }

  // The core of the algorithm. Here, a new subtree is combined with the
  // previous subtrees. Threads are used to traverse the inside and outside
  // contours of the left and right subtree up to the highest common level.=
 The
  // vertices used for the traversals are vi+, vi-, vo-, and vo+, where the
  // superscript o means outside and i means inside, the subscript - means =
left
  // subtree and + means right subtree. For summing up the modifiers along =
the
  // contour, we use respective variables si+, si-, so-, and so+. Whenever =
two
  // nodes of the inside contours conflict, we compute the left one of the
  // greatest uncommon ancestors using the function ANCESTOR and call MOVE
  // SUBTREE to shift the subtree and prepare the shifts of smaller subtree=
s.
  // Finally, we add a new thread (if necessary).
  function apportion(v, w, ancestor) {
    if (w) {
      var vip =3D v,
          vop =3D v,
          vim =3D w,
          vom =3D vip.parent.children[0],
          sip =3D vip.m,
          sop =3D vop.m,
          sim =3D vim.m,
          som =3D vom.m,
          shift;
      while (vim =3D nextRight(vim), vip =3D nextLeft(vip), vim && vip) {
        vom =3D nextLeft(vom);
        vop =3D nextRight(vop);
        vop.a =3D v;
        shift =3D vim.z + sim - vip.z - sip + separation(vim._, vip._);
        if (shift > 0) {
          moveSubtree(nextAncestor(vim, v, ancestor), v, shift);
          sip +=3D shift;
          sop +=3D shift;
        }
        sim +=3D vim.m;
        sip +=3D vip.m;
        som +=3D vom.m;
        sop +=3D vop.m;
      }
      if (vim && !nextRight(vop)) {
        vop.t =3D vim;
        vop.m +=3D sim - sop;
      }
      if (vip && !nextLeft(vom)) {
        vom.t =3D vip;
        vom.m +=3D sip - som;
        ancestor =3D v;
      }
    }
    return ancestor;
  }

  function sizeNode(node) {
    node.x *=3D dx;
    node.y =3D node.depth * dy;
  }

  tree.separation =3D function(x) {
    return arguments.length ? (separation =3D x, tree) : separation;
  };

  tree.size =3D function(x) {
    return arguments.length ? (nodeSize =3D false, dx =3D +x[0], dy =3D +x[=
1], tree) : (nodeSize ? null : [dx, dy]);
  };

  tree.nodeSize =3D function(x) {
    return arguments.length ? (nodeSize =3D true, dx =3D +x[0], dy =3D +x[1=
], tree) : (nodeSize ? [dx, dy] : null);
  };

  return tree;
}

function treemapSlice(parent, x0, y0, x1, y1) {
  var nodes =3D parent.children,
      node,
      i =3D -1,
      n =3D nodes.length,
      k =3D parent.value && (y1 - y0) / parent.value;

  while (++i < n) {
    node =3D nodes[i], node.x0 =3D x0, node.x1 =3D x1;
    node.y0 =3D y0, node.y1 =3D y0 +=3D node.value * k;
  }
}

var phi =3D (1 + Math.sqrt(5)) / 2;

function squarifyRatio(ratio, parent, x0, y0, x1, y1) {
  var rows =3D [],
      nodes =3D parent.children,
      row,
      nodeValue,
      i0 =3D 0,
      i1 =3D 0,
      n =3D nodes.length,
      dx, dy,
      value =3D parent.value,
      sumValue,
      minValue,
      maxValue,
      newRatio,
      minRatio,
      alpha,
      beta;

  while (i0 < n) {
    dx =3D x1 - x0, dy =3D y1 - y0;

    // Find the next non-empty node.
    do sumValue =3D nodes[i1++].value; while (!sumValue && i1 < n);
    minValue =3D maxValue =3D sumValue;
    alpha =3D Math.max(dy / dx, dx / dy) / (value * ratio);
    beta =3D sumValue * sumValue * alpha;
    minRatio =3D Math.max(maxValue / beta, beta / minValue);

    // Keep adding nodes while the aspect ratio maintains or improves.
    for (; i1 < n; ++i1) {
      sumValue +=3D nodeValue =3D nodes[i1].value;
      if (nodeValue < minValue) minValue =3D nodeValue;
      if (nodeValue > maxValue) maxValue =3D nodeValue;
      beta =3D sumValue * sumValue * alpha;
      newRatio =3D Math.max(maxValue / beta, beta / minValue);
      if (newRatio > minRatio) { sumValue -=3D nodeValue; break; }
      minRatio =3D newRatio;
    }

    // Position and record the row orientation.
    rows.push(row =3D {value: sumValue, dice: dx < dy, children: nodes.slic=
e(i0, i1)});
    if (row.dice) treemapDice(row, x0, y0, x1, value ? y0 +=3D dy * sumValu=
e / value : y1);
    else treemapSlice(row, x0, y0, value ? x0 +=3D dx * sumValue / value : =
x1, y1);
    value -=3D sumValue, i0 =3D i1;
  }

  return rows;
}

var squarify =3D (function custom(ratio) {

  function squarify(parent, x0, y0, x1, y1) {
    squarifyRatio(ratio, parent, x0, y0, x1, y1);
  }

  squarify.ratio =3D function(x) {
    return custom((x =3D +x) > 1 ? x : 1);
  };

  return squarify;
})(phi);

function index$3() {
  var tile =3D squarify,
      round =3D false,
      dx =3D 1,
      dy =3D 1,
      paddingStack =3D [0],
      paddingInner =3D constantZero,
      paddingTop =3D constantZero,
      paddingRight =3D constantZero,
      paddingBottom =3D constantZero,
      paddingLeft =3D constantZero;

  function treemap(root) {
    root.x0 =3D
    root.y0 =3D 0;
    root.x1 =3D dx;
    root.y1 =3D dy;
    root.eachBefore(positionNode);
    paddingStack =3D [0];
    if (round) root.eachBefore(roundNode);
    return root;
  }

  function positionNode(node) {
    var p =3D paddingStack[node.depth],
        x0 =3D node.x0 + p,
        y0 =3D node.y0 + p,
        x1 =3D node.x1 - p,
        y1 =3D node.y1 - p;
    if (x1 < x0) x0 =3D x1 =3D (x0 + x1) / 2;
    if (y1 < y0) y0 =3D y1 =3D (y0 + y1) / 2;
    node.x0 =3D x0;
    node.y0 =3D y0;
    node.x1 =3D x1;
    node.y1 =3D y1;
    if (node.children) {
      p =3D paddingStack[node.depth + 1] =3D paddingInner(node) / 2;
      x0 +=3D paddingLeft(node) - p;
      y0 +=3D paddingTop(node) - p;
      x1 -=3D paddingRight(node) - p;
      y1 -=3D paddingBottom(node) - p;
      if (x1 < x0) x0 =3D x1 =3D (x0 + x1) / 2;
      if (y1 < y0) y0 =3D y1 =3D (y0 + y1) / 2;
      tile(node, x0, y0, x1, y1);
    }
  }

  treemap.round =3D function(x) {
    return arguments.length ? (round =3D !!x, treemap) : round;
  };

  treemap.size =3D function(x) {
    return arguments.length ? (dx =3D +x[0], dy =3D +x[1], treemap) : [dx, =
dy];
  };

  treemap.tile =3D function(x) {
    return arguments.length ? (tile =3D required(x), treemap) : tile;
  };

  treemap.padding =3D function(x) {
    return arguments.length ? treemap.paddingInner(x).paddingOuter(x) : tre=
emap.paddingInner();
  };

  treemap.paddingInner =3D function(x) {
    return arguments.length ? (paddingInner =3D typeof x =3D=3D=3D "functio=
n" ? x : constant$9(+x), treemap) : paddingInner;
  };

  treemap.paddingOuter =3D function(x) {
    return arguments.length ? treemap.paddingTop(x).paddingRight(x).padding=
Bottom(x).paddingLeft(x) : treemap.paddingTop();
  };

  treemap.paddingTop =3D function(x) {
    return arguments.length ? (paddingTop =3D typeof x =3D=3D=3D "function"=
 ? x : constant$9(+x), treemap) : paddingTop;
  };

  treemap.paddingRight =3D function(x) {
    return arguments.length ? (paddingRight =3D typeof x =3D=3D=3D "functio=
n" ? x : constant$9(+x), treemap) : paddingRight;
  };

  treemap.paddingBottom =3D function(x) {
    return arguments.length ? (paddingBottom =3D typeof x =3D=3D=3D "functi=
on" ? x : constant$9(+x), treemap) : paddingBottom;
  };

  treemap.paddingLeft =3D function(x) {
    return arguments.length ? (paddingLeft =3D typeof x =3D=3D=3D "function=
" ? x : constant$9(+x), treemap) : paddingLeft;
  };

  return treemap;
}

function binary(parent, x0, y0, x1, y1) {
  var nodes =3D parent.children,
      i, n =3D nodes.length,
      sum, sums =3D new Array(n + 1);

  for (sums[0] =3D sum =3D i =3D 0; i < n; ++i) {
    sums[i + 1] =3D sum +=3D nodes[i].value;
  }

  partition(0, n, parent.value, x0, y0, x1, y1);

  function partition(i, j, value, x0, y0, x1, y1) {
    if (i >=3D j - 1) {
      var node =3D nodes[i];
      node.x0 =3D x0, node.y0 =3D y0;
      node.x1 =3D x1, node.y1 =3D y1;
      return;
    }

    var valueOffset =3D sums[i],
        valueTarget =3D (value / 2) + valueOffset,
        k =3D i + 1,
        hi =3D j - 1;

    while (k < hi) {
      var mid =3D k + hi >>> 1;
      if (sums[mid] < valueTarget) k =3D mid + 1;
      else hi =3D mid;
    }

    if ((valueTarget - sums[k - 1]) < (sums[k] - valueTarget) && i + 1 < k)=
 --k;

    var valueLeft =3D sums[k] - valueOffset,
        valueRight =3D value - valueLeft;

    if ((x1 - x0) > (y1 - y0)) {
      var xk =3D (x0 * valueRight + x1 * valueLeft) / value;
      partition(i, k, valueLeft, x0, y0, xk, y1);
      partition(k, j, valueRight, xk, y0, x1, y1);
    } else {
      var yk =3D (y0 * valueRight + y1 * valueLeft) / value;
      partition(i, k, valueLeft, x0, y0, x1, yk);
      partition(k, j, valueRight, x0, yk, x1, y1);
    }
  }
}

function sliceDice(parent, x0, y0, x1, y1) {
  (parent.depth & 1 ? treemapSlice : treemapDice)(parent, x0, y0, x1, y1);
}

var resquarify =3D (function custom(ratio) {

  function resquarify(parent, x0, y0, x1, y1) {
    if ((rows =3D parent._squarify) && (rows.ratio =3D=3D=3D ratio)) {
      var rows,
          row,
          nodes,
          i,
          j =3D -1,
          n,
          m =3D rows.length,
          value =3D parent.value;

      while (++j < m) {
        row =3D rows[j], nodes =3D row.children;
        for (i =3D row.value =3D 0, n =3D nodes.length; i < n; ++i) row.val=
ue +=3D nodes[i].value;
        if (row.dice) treemapDice(row, x0, y0, x1, y0 +=3D (y1 - y0) * row.=
value / value);
        else treemapSlice(row, x0, y0, x0 +=3D (x1 - x0) * row.value / valu=
e, y1);
        value -=3D row.value;
      }
    } else {
      parent._squarify =3D rows =3D squarifyRatio(ratio, parent, x0, y0, x1=
, y1);
      rows.ratio =3D ratio;
    }
  }

  resquarify.ratio =3D function(x) {
    return custom((x =3D +x) > 1 ? x : 1);
  };

  return resquarify;
})(phi);

function area$2(polygon) {
  var i =3D -1,
      n =3D polygon.length,
      a,
      b =3D polygon[n - 1],
      area =3D 0;

  while (++i < n) {
    a =3D b;
    b =3D polygon[i];
    area +=3D a[1] * b[0] - a[0] * b[1];
  }

  return area / 2;
}

function centroid$1(polygon) {
  var i =3D -1,
      n =3D polygon.length,
      x =3D 0,
      y =3D 0,
      a,
      b =3D polygon[n - 1],
      c,
      k =3D 0;

  while (++i < n) {
    a =3D b;
    b =3D polygon[i];
    k +=3D c =3D a[0] * b[1] - b[0] * a[1];
    x +=3D (a[0] + b[0]) * c;
    y +=3D (a[1] + b[1]) * c;
  }

  return k *=3D 3, [x / k, y / k];
}

// Returns the 2D cross product of AB and AC vectors, i.e., the z-component=
 of
// the 3D cross product in a quadrant I Cartesian coordinate system (+x is
// right, +y is up). Returns a positive value if ABC is counter-clockwise,
// negative if clockwise, and zero if the points are collinear.
function cross$1(a, b, c) {
  return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);
}

function lexicographicOrder(a, b) {
  return a[0] - b[0] || a[1] - b[1];
}

// Computes the upper convex hull per the monotone chain algorithm.
// Assumes points.length >=3D 3, is sorted by x, unique in y.
// Returns an array of indices into points in left-to-right order.
function computeUpperHullIndexes(points) {
  var n =3D points.length,
      indexes =3D [0, 1],
      size =3D 2;

  for (var i =3D 2; i < n; ++i) {
    while (size > 1 && cross$1(points[indexes[size - 2]], points[indexes[si=
ze - 1]], points[i]) <=3D 0) --size;
    indexes[size++] =3D i;
  }

  return indexes.slice(0, size); // remove popped points
}

function hull(points) {
  if ((n =3D points.length) < 3) return null;

  var i,
      n,
      sortedPoints =3D new Array(n),
      flippedPoints =3D new Array(n);

  for (i =3D 0; i < n; ++i) sortedPoints[i] =3D [+points[i][0], +points[i][=
1], i];
  sortedPoints.sort(lexicographicOrder);
  for (i =3D 0; i < n; ++i) flippedPoints[i] =3D [sortedPoints[i][0], -sort=
edPoints[i][1]];

  var upperIndexes =3D computeUpperHullIndexes(sortedPoints),
      lowerIndexes =3D computeUpperHullIndexes(flippedPoints);

  // Construct the hull polygon, removing possible duplicate endpoints.
  var skipLeft =3D lowerIndexes[0] =3D=3D=3D upperIndexes[0],
      skipRight =3D lowerIndexes[lowerIndexes.length - 1] =3D=3D=3D upperIn=
dexes[upperIndexes.length - 1],
      hull =3D [];

  // Add upper hull in right-to-l order.
  // Then add lower hull in left-to-right order.
  for (i =3D upperIndexes.length - 1; i >=3D 0; --i) hull.push(points[sorte=
dPoints[upperIndexes[i]][2]]);
  for (i =3D +skipLeft; i < lowerIndexes.length - skipRight; ++i) hull.push=
(points[sortedPoints[lowerIndexes[i]][2]]);

  return hull;
}

function contains$2(polygon, point) {
  var n =3D polygon.length,
      p =3D polygon[n - 1],
      x =3D point[0], y =3D point[1],
      x0 =3D p[0], y0 =3D p[1],
      x1, y1,
      inside =3D false;

  for (var i =3D 0; i < n; ++i) {
    p =3D polygon[i], x1 =3D p[0], y1 =3D p[1];
    if (((y1 > y) !=3D=3D (y0 > y)) && (x < (x0 - x1) * (y - y1) / (y0 - y1=
) + x1)) inside =3D !inside;
    x0 =3D x1, y0 =3D y1;
  }

  return inside;
}

function length$2(polygon) {
  var i =3D -1,
      n =3D polygon.length,
      b =3D polygon[n - 1],
      xa,
      ya,
      xb =3D b[0],
      yb =3D b[1],
      perimeter =3D 0;

  while (++i < n) {
    xa =3D xb;
    ya =3D yb;
    b =3D polygon[i];
    xb =3D b[0];
    yb =3D b[1];
    xa -=3D xb;
    ya -=3D yb;
    perimeter +=3D Math.sqrt(xa * xa + ya * ya);
  }

  return perimeter;
}

function defaultSource$1() {
  return Math.random();
}

var uniform =3D (function sourceRandomUniform(source) {
  function randomUniform(min, max) {
    min =3D min =3D=3D null ? 0 : +min;
    max =3D max =3D=3D null ? 1 : +max;
    if (arguments.length =3D=3D=3D 1) max =3D min, min =3D 0;
    else max -=3D min;
    return function() {
      return source() * max + min;
    };
  }

  randomUniform.source =3D sourceRandomUniform;

  return randomUniform;
})(defaultSource$1);

var normal =3D (function sourceRandomNormal(source) {
  function randomNormal(mu, sigma) {
    var x, r;
    mu =3D mu =3D=3D null ? 0 : +mu;
    sigma =3D sigma =3D=3D null ? 1 : +sigma;
    return function() {
      var y;

      // If available, use the second previously-generated uniform random.
      if (x !=3D null) y =3D x, x =3D null;

      // Otherwise, generate a new x and y.
      else do {
        x =3D source() * 2 - 1;
        y =3D source() * 2 - 1;
        r =3D x * x + y * y;
      } while (!r || r > 1);

      return mu + sigma * y * Math.sqrt(-2 * Math.log(r) / r);
    };
  }

  randomNormal.source =3D sourceRandomNormal;

  return randomNormal;
})(defaultSource$1);

var logNormal =3D (function sourceRandomLogNormal(source) {
  function randomLogNormal() {
    var randomNormal =3D normal.source(source).apply(this, arguments);
    return function() {
      return Math.exp(randomNormal());
    };
  }

  randomLogNormal.source =3D sourceRandomLogNormal;

  return randomLogNormal;
})(defaultSource$1);

var irwinHall =3D (function sourceRandomIrwinHall(source) {
  function randomIrwinHall(n) {
    return function() {
      for (var sum =3D 0, i =3D 0; i < n; ++i) sum +=3D source();
      return sum;
    };
  }

  randomIrwinHall.source =3D sourceRandomIrwinHall;

  return randomIrwinHall;
})(defaultSource$1);

var bates =3D (function sourceRandomBates(source) {
  function randomBates(n) {
    var randomIrwinHall =3D irwinHall.source(source)(n);
    return function() {
      return randomIrwinHall() / n;
    };
  }

  randomBates.source =3D sourceRandomBates;

  return randomBates;
})(defaultSource$1);

var exponential$1 =3D (function sourceRandomExponential(source) {
  function randomExponential(lambda) {
    return function() {
      return -Math.log(1 - source()) / lambda;
    };
  }

  randomExponential.source =3D sourceRandomExponential;

  return randomExponential;
})(defaultSource$1);

function initRange(domain, range) {
  switch (arguments.length) {
    case 0: break;
    case 1: this.range(domain); break;
    default: this.range(range).domain(domain); break;
  }
  return this;
}

function initInterpolator(domain, interpolator) {
  switch (arguments.length) {
    case 0: break;
    case 1: this.interpolator(domain); break;
    default: this.interpolator(interpolator).domain(domain); break;
  }
  return this;
}

var array$3 =3D Array.prototype;

var map$2 =3D array$3.map;
var slice$5 =3D array$3.slice;

var implicit =3D {name: "implicit"};

function ordinal() {
  var index =3D map$1(),
      domain =3D [],
      range =3D [],
      unknown =3D implicit;

  function scale(d) {
    var key =3D d + "", i =3D index.get(key);
    if (!i) {
      if (unknown !=3D=3D implicit) return unknown;
      index.set(key, i =3D domain.push(d));
    }
    return range[(i - 1) % range.length];
  }

  scale.domain =3D function(_) {
    if (!arguments.length) return domain.slice();
    domain =3D [], index =3D map$1();
    var i =3D -1, n =3D _.length, d, key;
    while (++i < n) if (!index.has(key =3D (d =3D _[i]) + "")) index.set(ke=
y, domain.push(d));
    return scale;
  };

  scale.range =3D function(_) {
    return arguments.length ? (range =3D slice$5.call(_), scale) : range.sl=
ice();
  };

  scale.unknown =3D function(_) {
    return arguments.length ? (unknown =3D _, scale) : unknown;
  };

  scale.copy =3D function() {
    return ordinal(domain, range).unknown(unknown);
  };

  initRange.apply(scale, arguments);

  return scale;
}

function band() {
  var scale =3D ordinal().unknown(undefined),
      domain =3D scale.domain,
      ordinalRange =3D scale.range,
      range$$1 =3D [0, 1],
      step,
      bandwidth,
      round =3D false,
      paddingInner =3D 0,
      paddingOuter =3D 0,
      align =3D 0.5;

  delete scale.unknown;

  function rescale() {
    var n =3D domain().length,
        reverse =3D range$$1[1] < range$$1[0],
        start =3D range$$1[reverse - 0],
        stop =3D range$$1[1 - reverse];
    step =3D (stop - start) / Math.max(1, n - paddingInner + paddingOuter *=
 2);
    if (round) step =3D Math.floor(step);
    start +=3D (stop - start - step * (n - paddingInner)) * align;
    bandwidth =3D step * (1 - paddingInner);
    if (round) start =3D Math.round(start), bandwidth =3D Math.round(bandwi=
dth);
    var values =3D sequence(n).map(function(i) { return start + step * i; }=
);
    return ordinalRange(reverse ? values.reverse() : values);
  }

  scale.domain =3D function(_) {
    return arguments.length ? (domain(_), rescale()) : domain();
  };

  scale.range =3D function(_) {
    return arguments.length ? (range$$1 =3D [+_[0], +_[1]], rescale()) : ra=
nge$$1.slice();
  };

  scale.rangeRound =3D function(_) {
    return range$$1 =3D [+_[0], +_[1]], round =3D true, rescale();
  };

  scale.bandwidth =3D function() {
    return bandwidth;
  };

  scale.step =3D function() {
    return step;
  };

  scale.round =3D function(_) {
    return arguments.length ? (round =3D !!_, rescale()) : round;
  };

  scale.padding =3D function(_) {
    return arguments.length ? (paddingInner =3D Math.min(1, paddingOuter =
=3D +_), rescale()) : paddingInner;
  };

  scale.paddingInner =3D function(_) {
    return arguments.length ? (paddingInner =3D Math.min(1, _), rescale()) =
: paddingInner;
  };

  scale.paddingOuter =3D function(_) {
    return arguments.length ? (paddingOuter =3D +_, rescale()) : paddingOut=
er;
  };

  scale.align =3D function(_) {
    return arguments.length ? (align =3D Math.max(0, Math.min(1, _)), resca=
le()) : align;
  };

  scale.copy =3D function() {
    return band(domain(), range$$1)
        .round(round)
        .paddingInner(paddingInner)
        .paddingOuter(paddingOuter)
        .align(align);
  };

  return initRange.apply(rescale(), arguments);
}

function pointish(scale) {
  var copy =3D scale.copy;

  scale.padding =3D scale.paddingOuter;
  delete scale.paddingInner;
  delete scale.paddingOuter;

  scale.copy =3D function() {
    return pointish(copy());
  };

  return scale;
}

function point$1() {
  return pointish(band.apply(null, arguments).paddingInner(1));
}

function constant$a(x) {
  return function() {
    return x;
  };
}

function number$2(x) {
  return +x;
}

var unit =3D [0, 1];

function identity$6(x) {
  return x;
}

function normalize(a, b) {
  return (b -=3D (a =3D +a))
      ? function(x) { return (x - a) / b; }
      : constant$a(isNaN(b) ? NaN : 0.5);
}

function clamper(domain) {
  var a =3D domain[0], b =3D domain[domain.length - 1], t;
  if (a > b) t =3D a, a =3D b, b =3D t;
  return function(x) { return Math.max(a, Math.min(b, x)); };
}

// normalize(a, b)(x) takes a domain value x in [a,b] and returns the corre=
sponding parameter t in [0,1].
// interpolate(a, b)(t) takes a parameter t in [0,1] and returns the corres=
ponding range value x in [a,b].
function bimap(domain, range, interpolate$$1) {
  var d0 =3D domain[0], d1 =3D domain[1], r0 =3D range[0], r1 =3D range[1];
  if (d1 < d0) d0 =3D normalize(d1, d0), r0 =3D interpolate$$1(r1, r0);
  else d0 =3D normalize(d0, d1), r0 =3D interpolate$$1(r0, r1);
  return function(x) { return r0(d0(x)); };
}

function polymap(domain, range, interpolate$$1) {
  var j =3D Math.min(domain.length, range.length) - 1,
      d =3D new Array(j),
      r =3D new Array(j),
      i =3D -1;

  // Reverse descending domains.
  if (domain[j] < domain[0]) {
    domain =3D domain.slice().reverse();
    range =3D range.slice().reverse();
  }

  while (++i < j) {
    d[i] =3D normalize(domain[i], domain[i + 1]);
    r[i] =3D interpolate$$1(range[i], range[i + 1]);
  }

  return function(x) {
    var i =3D bisectRight(domain, x, 1, j) - 1;
    return r[i](d[i](x));
  };
}

function copy(source, target) {
  return target
      .domain(source.domain())
      .range(source.range())
      .interpolate(source.interpolate())
      .clamp(source.clamp())
      .unknown(source.unknown());
}

function transformer$1() {
  var domain =3D unit,
      range =3D unit,
      interpolate$$1 =3D interpolateValue,
      transform,
      untransform,
      unknown,
      clamp =3D identity$6,
      piecewise$$1,
      output,
      input;

  function rescale() {
    piecewise$$1 =3D Math.min(domain.length, range.length) > 2 ? polymap : =
bimap;
    output =3D input =3D null;
    return scale;
  }

  function scale(x) {
    return isNaN(x =3D +x) ? unknown : (output || (output =3D piecewise$$1(=
domain.map(transform), range, interpolate$$1)))(transform(clamp(x)));
  }

  scale.invert =3D function(y) {
    return clamp(untransform((input || (input =3D piecewise$$1(range, domai=
n.map(transform), interpolateNumber)))(y)));
  };

  scale.domain =3D function(_) {
    return arguments.length ? (domain =3D map$2.call(_, number$2), clamp =
=3D=3D=3D identity$6 || (clamp =3D clamper(domain)), rescale()) : domain.sl=
ice();
  };

  scale.range =3D function(_) {
    return arguments.length ? (range =3D slice$5.call(_), rescale()) : rang=
e.slice();
  };

  scale.rangeRound =3D function(_) {
    return range =3D slice$5.call(_), interpolate$$1 =3D interpolateRound, =
rescale();
  };

  scale.clamp =3D function(_) {
    return arguments.length ? (clamp =3D _ ? clamper(domain) : identity$6, =
scale) : clamp !=3D=3D identity$6;
  };

  scale.interpolate =3D function(_) {
    return arguments.length ? (interpolate$$1 =3D _, rescale()) : interpola=
te$$1;
  };

  scale.unknown =3D function(_) {
    return arguments.length ? (unknown =3D _, scale) : unknown;
  };

  return function(t, u) {
    transform =3D t, untransform =3D u;
    return rescale();
  };
}

function continuous(transform, untransform) {
  return transformer$1()(transform, untransform);
}

function tickFormat(start, stop, count, specifier) {
  var step =3D tickStep(start, stop, count),
      precision;
  specifier =3D formatSpecifier(specifier =3D=3D null ? ",f" : specifier);
  switch (specifier.type) {
    case "s": {
      var value =3D Math.max(Math.abs(start), Math.abs(stop));
      if (specifier.precision =3D=3D null && !isNaN(precision =3D precision=
Prefix(step, value))) specifier.precision =3D precision;
      return exports.formatPrefix(specifier, value);
    }
    case "":
    case "e":
    case "g":
    case "p":
    case "r": {
      if (specifier.precision =3D=3D null && !isNaN(precision =3D precision=
Round(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precisio=
n =3D precision - (specifier.type =3D=3D=3D "e");
      break;
    }
    case "f":
    case "%": {
      if (specifier.precision =3D=3D null && !isNaN(precision =3D precision=
Fixed(step))) specifier.precision =3D precision - (specifier.type =3D=3D=3D=
 "%") * 2;
      break;
    }
  }
  return exports.format(specifier);
}

function linearish(scale) {
  var domain =3D scale.domain;

  scale.ticks =3D function(count) {
    var d =3D domain();
    return ticks(d[0], d[d.length - 1], count =3D=3D null ? 10 : count);
  };

  scale.tickFormat =3D function(count, specifier) {
    var d =3D domain();
    return tickFormat(d[0], d[d.length - 1], count =3D=3D null ? 10 : count=
, specifier);
  };

  scale.nice =3D function(count) {
    if (count =3D=3D null) count =3D 10;

    var d =3D domain(),
        i0 =3D 0,
        i1 =3D d.length - 1,
        start =3D d[i0],
        stop =3D d[i1],
        step;

    if (stop < start) {
      step =3D start, start =3D stop, stop =3D step;
      step =3D i0, i0 =3D i1, i1 =3D step;
    }

    step =3D tickIncrement(start, stop, count);

    if (step > 0) {
      start =3D Math.floor(start / step) * step;
      stop =3D Math.ceil(stop / step) * step;
      step =3D tickIncrement(start, stop, count);
    } else if (step < 0) {
      start =3D Math.ceil(start * step) / step;
      stop =3D Math.floor(stop * step) / step;
      step =3D tickIncrement(start, stop, count);
    }

    if (step > 0) {
      d[i0] =3D Math.floor(start / step) * step;
      d[i1] =3D Math.ceil(stop / step) * step;
      domain(d);
    } else if (step < 0) {
      d[i0] =3D Math.ceil(start * step) / step;
      d[i1] =3D Math.floor(stop * step) / step;
      domain(d);
    }

    return scale;
  };

  return scale;
}

function linear$2() {
  var scale =3D continuous(identity$6, identity$6);

  scale.copy =3D function() {
    return copy(scale, linear$2());
  };

  initRange.apply(scale, arguments);

  return linearish(scale);
}

function identity$7(domain) {
  var unknown;

  function scale(x) {
    return isNaN(x =3D +x) ? unknown : x;
  }

  scale.invert =3D scale;

  scale.domain =3D scale.range =3D function(_) {
    return arguments.length ? (domain =3D map$2.call(_, number$2), scale) :=
 domain.slice();
  };

  scale.unknown =3D function(_) {
    return arguments.length ? (unknown =3D _, scale) : unknown;
  };

  scale.copy =3D function() {
    return identity$7(domain).unknown(unknown);
  };

  domain =3D arguments.length ? map$2.call(domain, number$2) : [0, 1];

  return linearish(scale);
}

function nice(domain, interval) {
  domain =3D domain.slice();

  var i0 =3D 0,
      i1 =3D domain.length - 1,
      x0 =3D domain[i0],
      x1 =3D domain[i1],
      t;

  if (x1 < x0) {
    t =3D i0, i0 =3D i1, i1 =3D t;
    t =3D x0, x0 =3D x1, x1 =3D t;
  }

  domain[i0] =3D interval.floor(x0);
  domain[i1] =3D interval.ceil(x1);
  return domain;
}

function transformLog(x) {
  return Math.log(x);
}

function transformExp(x) {
  return Math.exp(x);
}

function transformLogn(x) {
  return -Math.log(-x);
}

function transformExpn(x) {
  return -Math.exp(-x);
}

function pow10(x) {
  return isFinite(x) ? +("1e" + x) : x < 0 ? 0 : x;
}

function powp(base) {
  return base =3D=3D=3D 10 ? pow10
      : base =3D=3D=3D Math.E ? Math.exp
      : function(x) { return Math.pow(base, x); };
}

function logp(base) {
  return base =3D=3D=3D Math.E ? Math.log
      : base =3D=3D=3D 10 && Math.log10
      || base =3D=3D=3D 2 && Math.log2
      || (base =3D Math.log(base), function(x) { return Math.log(x) / base;=
 });
}

function reflect(f) {
  return function(x) {
    return -f(-x);
  };
}

function loggish(transform) {
  var scale =3D transform(transformLog, transformExp),
      domain =3D scale.domain,
      base =3D 10,
      logs,
      pows;

  function rescale() {
    logs =3D logp(base), pows =3D powp(base);
    if (domain()[0] < 0) {
      logs =3D reflect(logs), pows =3D reflect(pows);
      transform(transformLogn, transformExpn);
    } else {
      transform(transformLog, transformExp);
    }
    return scale;
  }

  scale.base =3D function(_) {
    return arguments.length ? (base =3D +_, rescale()) : base;
  };

  scale.domain =3D function(_) {
    return arguments.length ? (domain(_), rescale()) : domain();
  };

  scale.ticks =3D function(count) {
    var d =3D domain(),
        u =3D d[0],
        v =3D d[d.length - 1],
        r;

    if (r =3D v < u) i =3D u, u =3D v, v =3D i;

    var i =3D logs(u),
        j =3D logs(v),
        p,
        k,
        t,
        n =3D count =3D=3D null ? 10 : +count,
        z =3D [];

    if (!(base % 1) && j - i < n) {
      i =3D Math.round(i) - 1, j =3D Math.round(j) + 1;
      if (u > 0) for (; i < j; ++i) {
        for (k =3D 1, p =3D pows(i); k < base; ++k) {
          t =3D p * k;
          if (t < u) continue;
          if (t > v) break;
          z.push(t);
        }
      } else for (; i < j; ++i) {
        for (k =3D base - 1, p =3D pows(i); k >=3D 1; --k) {
          t =3D p * k;
          if (t < u) continue;
          if (t > v) break;
          z.push(t);
        }
      }
    } else {
      z =3D ticks(i, j, Math.min(j - i, n)).map(pows);
    }

    return r ? z.reverse() : z;
  };

  scale.tickFormat =3D function(count, specifier) {
    if (specifier =3D=3D null) specifier =3D base =3D=3D=3D 10 ? ".0e" : ",=
";
    if (typeof specifier !=3D=3D "function") specifier =3D exports.format(s=
pecifier);
    if (count =3D=3D=3D Infinity) return specifier;
    if (count =3D=3D null) count =3D 10;
    var k =3D Math.max(1, base * count / scale.ticks().length); // TODO fas=
t estimate?
    return function(d) {
      var i =3D d / pows(Math.round(logs(d)));
      if (i * base < base - 0.5) i *=3D base;
      return i <=3D k ? specifier(d) : "";
    };
  };

  scale.nice =3D function() {
    return domain(nice(domain(), {
      floor: function(x) { return pows(Math.floor(logs(x))); },
      ceil: function(x) { return pows(Math.ceil(logs(x))); }
    }));
  };

  return scale;
}

function log$1() {
  var scale =3D loggish(transformer$1()).domain([1, 10]);

  scale.copy =3D function() {
    return copy(scale, log$1()).base(scale.base());
  };

  initRange.apply(scale, arguments);

  return scale;
}

function transformSymlog(c) {
  return function(x) {
    return Math.sign(x) * Math.log1p(Math.abs(x / c));
  };
}

function transformSymexp(c) {
  return function(x) {
    return Math.sign(x) * Math.expm1(Math.abs(x)) * c;
  };
}

function symlogish(transform) {
  var c =3D 1, scale =3D transform(transformSymlog(c), transformSymexp(c));

  scale.constant =3D function(_) {
    return arguments.length ? transform(transformSymlog(c =3D +_), transfor=
mSymexp(c)) : c;
  };

  return linearish(scale);
}

function symlog() {
  var scale =3D symlogish(transformer$1());

  scale.copy =3D function() {
    return copy(scale, symlog()).constant(scale.constant());
  };

  return initRange.apply(scale, arguments);
}

function transformPow(exponent) {
  return function(x) {
    return x < 0 ? -Math.pow(-x, exponent) : Math.pow(x, exponent);
  };
}

function transformSqrt(x) {
  return x < 0 ? -Math.sqrt(-x) : Math.sqrt(x);
}

function transformSquare(x) {
  return x < 0 ? -x * x : x * x;
}

function powish(transform) {
  var scale =3D transform(identity$6, identity$6),
      exponent =3D 1;

  function rescale() {
    return exponent =3D=3D=3D 1 ? transform(identity$6, identity$6)
        : exponent =3D=3D=3D 0.5 ? transform(transformSqrt, transformSquare)
        : transform(transformPow(exponent), transformPow(1 / exponent));
  }

  scale.exponent =3D function(_) {
    return arguments.length ? (exponent =3D +_, rescale()) : exponent;
  };

  return linearish(scale);
}

function pow$1() {
  var scale =3D powish(transformer$1());

  scale.copy =3D function() {
    return copy(scale, pow$1()).exponent(scale.exponent());
  };

  initRange.apply(scale, arguments);

  return scale;
}

function sqrt$1() {
  return pow$1.apply(null, arguments).exponent(0.5);
}

function quantile$$1() {
  var domain =3D [],
      range =3D [],
      thresholds =3D [],
      unknown;

  function rescale() {
    var i =3D 0, n =3D Math.max(1, range.length);
    thresholds =3D new Array(n - 1);
    while (++i < n) thresholds[i - 1] =3D threshold(domain, i / n);
    return scale;
  }

  function scale(x) {
    return isNaN(x =3D +x) ? unknown : range[bisectRight(thresholds, x)];
  }

  scale.invertExtent =3D function(y) {
    var i =3D range.indexOf(y);
    return i < 0 ? [NaN, NaN] : [
      i > 0 ? thresholds[i - 1] : domain[0],
      i < thresholds.length ? thresholds[i] : domain[domain.length - 1]
    ];
  };

  scale.domain =3D function(_) {
    if (!arguments.length) return domain.slice();
    domain =3D [];
    for (var i =3D 0, n =3D _.length, d; i < n; ++i) if (d =3D _[i], d !=3D=
 null && !isNaN(d =3D +d)) domain.push(d);
    domain.sort(ascending);
    return rescale();
  };

  scale.range =3D function(_) {
    return arguments.length ? (range =3D slice$5.call(_), rescale()) : rang=
e.slice();
  };

  scale.unknown =3D function(_) {
    return arguments.length ? (unknown =3D _, scale) : unknown;
  };

  scale.quantiles =3D function() {
    return thresholds.slice();
  };

  scale.copy =3D function() {
    return quantile$$1()
        .domain(domain)
        .range(range)
        .unknown(unknown);
  };

  return initRange.apply(scale, arguments);
}

function quantize$1() {
  var x0 =3D 0,
      x1 =3D 1,
      n =3D 1,
      domain =3D [0.5],
      range =3D [0, 1],
      unknown;

  function scale(x) {
    return x <=3D x ? range[bisectRight(domain, x, 0, n)] : unknown;
  }

  function rescale() {
    var i =3D -1;
    domain =3D new Array(n);
    while (++i < n) domain[i] =3D ((i + 1) * x1 - (i - n) * x0) / (n + 1);
    return scale;
  }

  scale.domain =3D function(_) {
    return arguments.length ? (x0 =3D +_[0], x1 =3D +_[1], rescale()) : [x0=
, x1];
  };

  scale.range =3D function(_) {
    return arguments.length ? (n =3D (range =3D slice$5.call(_)).length - 1=
, rescale()) : range.slice();
  };

  scale.invertExtent =3D function(y) {
    var i =3D range.indexOf(y);
    return i < 0 ? [NaN, NaN]
        : i < 1 ? [x0, domain[0]]
        : i >=3D n ? [domain[n - 1], x1]
        : [domain[i - 1], domain[i]];
  };

  scale.unknown =3D function(_) {
    return arguments.length ? (unknown =3D _, scale) : scale;
  };

  scale.thresholds =3D function() {
    return domain.slice();
  };

  scale.copy =3D function() {
    return quantize$1()
        .domain([x0, x1])
        .range(range)
        .unknown(unknown);
  };

  return initRange.apply(linearish(scale), arguments);
}

function threshold$1() {
  var domain =3D [0.5],
      range =3D [0, 1],
      unknown,
      n =3D 1;

  function scale(x) {
    return x <=3D x ? range[bisectRight(domain, x, 0, n)] : unknown;
  }

  scale.domain =3D function(_) {
    return arguments.length ? (domain =3D slice$5.call(_), n =3D Math.min(d=
omain.length, range.length - 1), scale) : domain.slice();
  };

  scale.range =3D function(_) {
    return arguments.length ? (range =3D slice$5.call(_), n =3D Math.min(do=
main.length, range.length - 1), scale) : range.slice();
  };

  scale.invertExtent =3D function(y) {
    var i =3D range.indexOf(y);
    return [domain[i - 1], domain[i]];
  };

  scale.unknown =3D function(_) {
    return arguments.length ? (unknown =3D _, scale) : unknown;
  };

  scale.copy =3D function() {
    return threshold$1()
        .domain(domain)
        .range(range)
        .unknown(unknown);
  };

  return initRange.apply(scale, arguments);
}

var t0$1 =3D new Date,
    t1$1 =3D new Date;

function newInterval(floori, offseti, count, field) {

  function interval(date) {
    return floori(date =3D new Date(+date)), date;
  }

  interval.floor =3D interval;

  interval.ceil =3D function(date) {
    return floori(date =3D new Date(date - 1)), offseti(date, 1), floori(da=
te), date;
  };

  interval.round =3D function(date) {
    var d0 =3D interval(date),
        d1 =3D interval.ceil(date);
    return date - d0 < d1 - date ? d0 : d1;
  };

  interval.offset =3D function(date, step) {
    return offseti(date =3D new Date(+date), step =3D=3D null ? 1 : Math.fl=
oor(step)), date;
  };

  interval.range =3D function(start, stop, step) {
    var range =3D [], previous;
    start =3D interval.ceil(start);
    step =3D step =3D=3D null ? 1 : Math.floor(step);
    if (!(start < stop) || !(step > 0)) return range; // also handles Inval=
id Date
    do range.push(previous =3D new Date(+start)), offseti(start, step), flo=
ori(start);
    while (previous < start && start < stop);
    return range;
  };

  interval.filter =3D function(test) {
    return newInterval(function(date) {
      if (date >=3D date) while (floori(date), !test(date)) date.setTime(da=
te - 1);
    }, function(date, step) {
      if (date >=3D date) {
        if (step < 0) while (++step <=3D 0) {
          while (offseti(date, -1), !test(date)) {} // eslint-disable-line =
no-empty
        } else while (--step >=3D 0) {
          while (offseti(date, +1), !test(date)) {} // eslint-disable-line =
no-empty
        }
      }
    });
  };

  if (count) {
    interval.count =3D function(start, end) {
      t0$1.setTime(+start), t1$1.setTime(+end);
      floori(t0$1), floori(t1$1);
      return Math.floor(count(t0$1, t1$1));
    };

    interval.every =3D function(step) {
      step =3D Math.floor(step);
      return !isFinite(step) || !(step > 0) ? null
          : !(step > 1) ? interval
          : interval.filter(field
              ? function(d) { return field(d) % step =3D=3D=3D 0; }
              : function(d) { return interval.count(0, d) % step =3D=3D=3D =
0; });
    };
  }

  return interval;
}

var millisecond =3D newInterval(function() {
  // noop
}, function(date, step) {
  date.setTime(+date + step);
}, function(start, end) {
  return end - start;
});

// An optimized implementation for this simple case.
millisecond.every =3D function(k) {
  k =3D Math.floor(k);
  if (!isFinite(k) || !(k > 0)) return null;
  if (!(k > 1)) return millisecond;
  return newInterval(function(date) {
    date.setTime(Math.floor(date / k) * k);
  }, function(date, step) {
    date.setTime(+date + step * k);
  }, function(start, end) {
    return (end - start) / k;
  });
};
var milliseconds =3D millisecond.range;

var durationSecond =3D 1e3;
var durationMinute =3D 6e4;
var durationHour =3D 36e5;
var durationDay =3D 864e5;
var durationWeek =3D 6048e5;

var second =3D newInterval(function(date) {
  date.setTime(date - date.getMilliseconds());
}, function(date, step) {
  date.setTime(+date + step * durationSecond);
}, function(start, end) {
  return (end - start) / durationSecond;
}, function(date) {
  return date.getUTCSeconds();
});
var seconds =3D second.range;

var minute =3D newInterval(function(date) {
  date.setTime(date - date.getMilliseconds() - date.getSeconds() * duration=
Second);
}, function(date, step) {
  date.setTime(+date + step * durationMinute);
}, function(start, end) {
  return (end - start) / durationMinute;
}, function(date) {
  return date.getMinutes();
});
var minutes =3D minute.range;

var hour =3D newInterval(function(date) {
  date.setTime(date - date.getMilliseconds() - date.getSeconds() * duration=
Second - date.getMinutes() * durationMinute);
}, function(date, step) {
  date.setTime(+date + step * durationHour);
}, function(start, end) {
  return (end - start) / durationHour;
}, function(date) {
  return date.getHours();
});
var hours =3D hour.range;

var day =3D newInterval(function(date) {
  date.setHours(0, 0, 0, 0);
}, function(date, step) {
  date.setDate(date.getDate() + step);
}, function(start, end) {
  return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset(=
)) * durationMinute) / durationDay;
}, function(date) {
  return date.getDate() - 1;
});
var days =3D day.range;

function weekday(i) {
  return newInterval(function(date) {
    date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7);
    date.setHours(0, 0, 0, 0);
  }, function(date, step) {
    date.setDate(date.getDate() + step * 7);
  }, function(start, end) {
    return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffse=
t()) * durationMinute) / durationWeek;
  });
}

var sunday =3D weekday(0);
var monday =3D weekday(1);
var tuesday =3D weekday(2);
var wednesday =3D weekday(3);
var thursday =3D weekday(4);
var friday =3D weekday(5);
var saturday =3D weekday(6);

var sundays =3D sunday.range;
var mondays =3D monday.range;
var tuesdays =3D tuesday.range;
var wednesdays =3D wednesday.range;
var thursdays =3D thursday.range;
var fridays =3D friday.range;
var saturdays =3D saturday.range;

var month =3D newInterval(function(date) {
  date.setDate(1);
  date.setHours(0, 0, 0, 0);
}, function(date, step) {
  date.setMonth(date.getMonth() + step);
}, function(start, end) {
  return end.getMonth() - start.getMonth() + (end.getFullYear() - start.get=
FullYear()) * 12;
}, function(date) {
  return date.getMonth();
});
var months =3D month.range;

var year =3D newInterval(function(date) {
  date.setMonth(0, 1);
  date.setHours(0, 0, 0, 0);
}, function(date, step) {
  date.setFullYear(date.getFullYear() + step);
}, function(start, end) {
  return end.getFullYear() - start.getFullYear();
}, function(date) {
  return date.getFullYear();
});

// An optimized implementation for this simple case.
year.every =3D function(k) {
  return !isFinite(k =3D Math.floor(k)) || !(k > 0) ? null : newInterval(fu=
nction(date) {
    date.setFullYear(Math.floor(date.getFullYear() / k) * k);
    date.setMonth(0, 1);
    date.setHours(0, 0, 0, 0);
  }, function(date, step) {
    date.setFullYear(date.getFullYear() + step * k);
  });
};
var years =3D year.range;

var utcMinute =3D newInterval(function(date) {
  date.setUTCSeconds(0, 0);
}, function(date, step) {
  date.setTime(+date + step * durationMinute);
}, function(start, end) {
  return (end - start) / durationMinute;
}, function(date) {
  return date.getUTCMinutes();
});
var utcMinutes =3D utcMinute.range;

var utcHour =3D newInterval(function(date) {
  date.setUTCMinutes(0, 0, 0);
}, function(date, step) {
  date.setTime(+date + step * durationHour);
}, function(start, end) {
  return (end - start) / durationHour;
}, function(date) {
  return date.getUTCHours();
});
var utcHours =3D utcHour.range;

var utcDay =3D newInterval(function(date) {
  date.setUTCHours(0, 0, 0, 0);
}, function(date, step) {
  date.setUTCDate(date.getUTCDate() + step);
}, function(start, end) {
  return (end - start) / durationDay;
}, function(date) {
  return date.getUTCDate() - 1;
});
var utcDays =3D utcDay.range;

function utcWeekday(i) {
  return newInterval(function(date) {
    date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7);
    date.setUTCHours(0, 0, 0, 0);
  }, function(date, step) {
    date.setUTCDate(date.getUTCDate() + step * 7);
  }, function(start, end) {
    return (end - start) / durationWeek;
  });
}

var utcSunday =3D utcWeekday(0);
var utcMonday =3D utcWeekday(1);
var utcTuesday =3D utcWeekday(2);
var utcWednesday =3D utcWeekday(3);
var utcThursday =3D utcWeekday(4);
var utcFriday =3D utcWeekday(5);
var utcSaturday =3D utcWeekday(6);

var utcSundays =3D utcSunday.range;
var utcMondays =3D utcMonday.range;
var utcTuesdays =3D utcTuesday.range;
var utcWednesdays =3D utcWednesday.range;
var utcThursdays =3D utcThursday.range;
var utcFridays =3D utcFriday.range;
var utcSaturdays =3D utcSaturday.range;

var utcMonth =3D newInterval(function(date) {
  date.setUTCDate(1);
  date.setUTCHours(0, 0, 0, 0);
}, function(date, step) {
  date.setUTCMonth(date.getUTCMonth() + step);
}, function(start, end) {
  return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - =
start.getUTCFullYear()) * 12;
}, function(date) {
  return date.getUTCMonth();
});
var utcMonths =3D utcMonth.range;

var utcYear =3D newInterval(function(date) {
  date.setUTCMonth(0, 1);
  date.setUTCHours(0, 0, 0, 0);
}, function(date, step) {
  date.setUTCFullYear(date.getUTCFullYear() + step);
}, function(start, end) {
  return end.getUTCFullYear() - start.getUTCFullYear();
}, function(date) {
  return date.getUTCFullYear();
});

// An optimized implementation for this simple case.
utcYear.every =3D function(k) {
  return !isFinite(k =3D Math.floor(k)) || !(k > 0) ? null : newInterval(fu=
nction(date) {
    date.setUTCFullYear(Math.floor(date.getUTCFullYear() / k) * k);
    date.setUTCMonth(0, 1);
    date.setUTCHours(0, 0, 0, 0);
  }, function(date, step) {
    date.setUTCFullYear(date.getUTCFullYear() + step * k);
  });
};
var utcYears =3D utcYear.range;

function localDate(d) {
  if (0 <=3D d.y && d.y < 100) {
    var date =3D new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L);
    date.setFullYear(d.y);
    return date;
  }
  return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L);
}

function utcDate(d) {
  if (0 <=3D d.y && d.y < 100) {
    var date =3D new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L));
    date.setUTCFullYear(d.y);
    return date;
  }
  return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L));
}

function newYear(y) {
  return {y: y, m: 0, d: 1, H: 0, M: 0, S: 0, L: 0};
}

function formatLocale$1(locale) {
  var locale_dateTime =3D locale.dateTime,
      locale_date =3D locale.date,
      locale_time =3D locale.time,
      locale_periods =3D locale.periods,
      locale_weekdays =3D locale.days,
      locale_shortWeekdays =3D locale.shortDays,
      locale_months =3D locale.months,
      locale_shortMonths =3D locale.shortMonths;

  var periodRe =3D formatRe(locale_periods),
      periodLookup =3D formatLookup(locale_periods),
      weekdayRe =3D formatRe(locale_weekdays),
      weekdayLookup =3D formatLookup(locale_weekdays),
      shortWeekdayRe =3D formatRe(locale_shortWeekdays),
      shortWeekdayLookup =3D formatLookup(locale_shortWeekdays),
      monthRe =3D formatRe(locale_months),
      monthLookup =3D formatLookup(locale_months),
      shortMonthRe =3D formatRe(locale_shortMonths),
      shortMonthLookup =3D formatLookup(locale_shortMonths);

  var formats =3D {
    "a": formatShortWeekday,
    "A": formatWeekday,
    "b": formatShortMonth,
    "B": formatMonth,
    "c": null,
    "d": formatDayOfMonth,
    "e": formatDayOfMonth,
    "f": formatMicroseconds,
    "H": formatHour24,
    "I": formatHour12,
    "j": formatDayOfYear,
    "L": formatMilliseconds,
    "m": formatMonthNumber,
    "M": formatMinutes,
    "p": formatPeriod,
    "Q": formatUnixTimestamp,
    "s": formatUnixTimestampSeconds,
    "S": formatSeconds,
    "u": formatWeekdayNumberMonday,
    "U": formatWeekNumberSunday,
    "V": formatWeekNumberISO,
    "w": formatWeekdayNumberSunday,
    "W": formatWeekNumberMonday,
    "x": null,
    "X": null,
    "y": formatYear$1,
    "Y": formatFullYear,
    "Z": formatZone,
    "%": formatLiteralPercent
  };

  var utcFormats =3D {
    "a": formatUTCShortWeekday,
    "A": formatUTCWeekday,
    "b": formatUTCShortMonth,
    "B": formatUTCMonth,
    "c": null,
    "d": formatUTCDayOfMonth,
    "e": formatUTCDayOfMonth,
    "f": formatUTCMicroseconds,
    "H": formatUTCHour24,
    "I": formatUTCHour12,
    "j": formatUTCDayOfYear,
    "L": formatUTCMilliseconds,
    "m": formatUTCMonthNumber,
    "M": formatUTCMinutes,
    "p": formatUTCPeriod,
    "Q": formatUnixTimestamp,
    "s": formatUnixTimestampSeconds,
    "S": formatUTCSeconds,
    "u": formatUTCWeekdayNumberMonday,
    "U": formatUTCWeekNumberSunday,
    "V": formatUTCWeekNumberISO,
    "w": formatUTCWeekdayNumberSunday,
    "W": formatUTCWeekNumberMonday,
    "x": null,
    "X": null,
    "y": formatUTCYear,
    "Y": formatUTCFullYear,
    "Z": formatUTCZone,
    "%": formatLiteralPercent
  };

  var parses =3D {
    "a": parseShortWeekday,
    "A": parseWeekday,
    "b": parseShortMonth,
    "B": parseMonth,
    "c": parseLocaleDateTime,
    "d": parseDayOfMonth,
    "e": parseDayOfMonth,
    "f": parseMicroseconds,
    "H": parseHour24,
    "I": parseHour24,
    "j": parseDayOfYear,
    "L": parseMilliseconds,
    "m": parseMonthNumber,
    "M": parseMinutes,
    "p": parsePeriod,
    "Q": parseUnixTimestamp,
    "s": parseUnixTimestampSeconds,
    "S": parseSeconds,
    "u": parseWeekdayNumberMonday,
    "U": parseWeekNumberSunday,
    "V": parseWeekNumberISO,
    "w": parseWeekdayNumberSunday,
    "W": parseWeekNumberMonday,
    "x": parseLocaleDate,
    "X": parseLocaleTime,
    "y": parseYear,
    "Y": parseFullYear,
    "Z": parseZone,
    "%": parseLiteralPercent
  };

  // These recursive directive definitions must be deferred.
  formats.x =3D newFormat(locale_date, formats);
  formats.X =3D newFormat(locale_time, formats);
  formats.c =3D newFormat(locale_dateTime, formats);
  utcFormats.x =3D newFormat(locale_date, utcFormats);
  utcFormats.X =3D newFormat(locale_time, utcFormats);
  utcFormats.c =3D newFormat(locale_dateTime, utcFormats);

  function newFormat(specifier, formats) {
    return function(date) {
      var string =3D [],
          i =3D -1,
          j =3D 0,
          n =3D specifier.length,
          c,
          pad,
          format;

      if (!(date instanceof Date)) date =3D new Date(+date);

      while (++i < n) {
        if (specifier.charCodeAt(i) =3D=3D=3D 37) {
          string.push(specifier.slice(j, i));
          if ((pad =3D pads[c =3D specifier.charAt(++i)]) !=3D null) c =3D =
specifier.charAt(++i);
          else pad =3D c =3D=3D=3D "e" ? " " : "0";
          if (format =3D formats[c]) c =3D format(date, pad);
          string.push(c);
          j =3D i + 1;
        }
      }

      string.push(specifier.slice(j, i));
      return string.join("");
    };
  }

  function newParse(specifier, newDate) {
    return function(string) {
      var d =3D newYear(1900),
          i =3D parseSpecifier(d, specifier, string +=3D "", 0),
          week, day$$1;
      if (i !=3D string.length) return null;

      // If a UNIX timestamp is specified, return it.
      if ("Q" in d) return new Date(d.Q);

      // The am-pm flag is 0 for AM, and 1 for PM.
      if ("p" in d) d.H =3D d.H % 12 + d.p * 12;

      // Convert day-of-week and week-of-year to day-of-year.
      if ("V" in d) {
        if (d.V < 1 || d.V > 53) return null;
        if (!("w" in d)) d.w =3D 1;
        if ("Z" in d) {
          week =3D utcDate(newYear(d.y)), day$$1 =3D week.getUTCDay();
          week =3D day$$1 > 4 || day$$1 =3D=3D=3D 0 ? utcMonday.ceil(week) =
: utcMonday(week);
          week =3D utcDay.offset(week, (d.V - 1) * 7);
          d.y =3D week.getUTCFullYear();
          d.m =3D week.getUTCMonth();
          d.d =3D week.getUTCDate() + (d.w + 6) % 7;
        } else {
          week =3D newDate(newYear(d.y)), day$$1 =3D week.getDay();
          week =3D day$$1 > 4 || day$$1 =3D=3D=3D 0 ? monday.ceil(week) : m=
onday(week);
          week =3D day.offset(week, (d.V - 1) * 7);
          d.y =3D week.getFullYear();
          d.m =3D week.getMonth();
          d.d =3D week.getDate() + (d.w + 6) % 7;
        }
      } else if ("W" in d || "U" in d) {
        if (!("w" in d)) d.w =3D "u" in d ? d.u % 7 : "W" in d ? 1 : 0;
        day$$1 =3D "Z" in d ? utcDate(newYear(d.y)).getUTCDay() : newDate(n=
ewYear(d.y)).getDay();
        d.m =3D 0;
        d.d =3D "W" in d ? (d.w + 6) % 7 + d.W * 7 - (day$$1 + 5) % 7 : d.w=
 + d.U * 7 - (day$$1 + 6) % 7;
      }

      // If a time zone is specified, all fields are interpreted as UTC and=
 then
      // offset according to the specified time zone.
      if ("Z" in d) {
        d.H +=3D d.Z / 100 | 0;
        d.M +=3D d.Z % 100;
        return utcDate(d);
      }

      // Otherwise, all fields are in local time.
      return newDate(d);
    };
  }

  function parseSpecifier(d, specifier, string, j) {
    var i =3D 0,
        n =3D specifier.length,
        m =3D string.length,
        c,
        parse;

    while (i < n) {
      if (j >=3D m) return -1;
      c =3D specifier.charCodeAt(i++);
      if (c =3D=3D=3D 37) {
        c =3D specifier.charAt(i++);
        parse =3D parses[c in pads ? specifier.charAt(i++) : c];
        if (!parse || ((j =3D parse(d, string, j)) < 0)) return -1;
      } else if (c !=3D string.charCodeAt(j++)) {
        return -1;
      }
    }

    return j;
  }

  function parsePeriod(d, string, i) {
    var n =3D periodRe.exec(string.slice(i));
    return n ? (d.p =3D periodLookup[n[0].toLowerCase()], i + n[0].length) =
: -1;
  }

  function parseShortWeekday(d, string, i) {
    var n =3D shortWeekdayRe.exec(string.slice(i));
    return n ? (d.w =3D shortWeekdayLookup[n[0].toLowerCase()], i + n[0].le=
ngth) : -1;
  }

  function parseWeekday(d, string, i) {
    var n =3D weekdayRe.exec(string.slice(i));
    return n ? (d.w =3D weekdayLookup[n[0].toLowerCase()], i + n[0].length)=
 : -1;
  }

  function parseShortMonth(d, string, i) {
    var n =3D shortMonthRe.exec(string.slice(i));
    return n ? (d.m =3D shortMonthLookup[n[0].toLowerCase()], i + n[0].leng=
th) : -1;
  }

  function parseMonth(d, string, i) {
    var n =3D monthRe.exec(string.slice(i));
    return n ? (d.m =3D monthLookup[n[0].toLowerCase()], i + n[0].length) :=
 -1;
  }

  function parseLocaleDateTime(d, string, i) {
    return parseSpecifier(d, locale_dateTime, string, i);
  }

  function parseLocaleDate(d, string, i) {
    return parseSpecifier(d, locale_date, string, i);
  }

  function parseLocaleTime(d, string, i) {
    return parseSpecifier(d, locale_time, string, i);
  }

  function formatShortWeekday(d) {
    return locale_shortWeekdays[d.getDay()];
  }

  function formatWeekday(d) {
    return locale_weekdays[d.getDay()];
  }

  function formatShortMonth(d) {
    return locale_shortMonths[d.getMonth()];
  }

  function formatMonth(d) {
    return locale_months[d.getMonth()];
  }

  function formatPeriod(d) {
    return locale_periods[+(d.getHours() >=3D 12)];
  }

  function formatUTCShortWeekday(d) {
    return locale_shortWeekdays[d.getUTCDay()];
  }

  function formatUTCWeekday(d) {
    return locale_weekdays[d.getUTCDay()];
  }

  function formatUTCShortMonth(d) {
    return locale_shortMonths[d.getUTCMonth()];
  }

  function formatUTCMonth(d) {
    return locale_months[d.getUTCMonth()];
  }

  function formatUTCPeriod(d) {
    return locale_periods[+(d.getUTCHours() >=3D 12)];
  }

  return {
    format: function(specifier) {
      var f =3D newFormat(specifier +=3D "", formats);
      f.toString =3D function() { return specifier; };
      return f;
    },
    parse: function(specifier) {
      var p =3D newParse(specifier +=3D "", localDate);
      p.toString =3D function() { return specifier; };
      return p;
    },
    utcFormat: function(specifier) {
      var f =3D newFormat(specifier +=3D "", utcFormats);
      f.toString =3D function() { return specifier; };
      return f;
    },
    utcParse: function(specifier) {
      var p =3D newParse(specifier, utcDate);
      p.toString =3D function() { return specifier; };
      return p;
    }
  };
}

var pads =3D {"-": "", "_": " ", "0": "0"},
    numberRe =3D /^\s*\d+/, // note: ignores next directive
    percentRe =3D /^%/,
    requoteRe =3D /[\\^$*+?|[\]().{}]/g;

function pad$1(value, fill, width) {
  var sign =3D value < 0 ? "-" : "",
      string =3D (sign ? -value : value) + "",
      length =3D string.length;
  return sign + (length < width ? new Array(width - length + 1).join(fill) =
+ string : string);
}

function requote(s) {
  return s.replace(requoteRe, "\\$&");
}

function formatRe(names) {
  return new RegExp("^(?:" + names.map(requote).join("|") + ")", "i");
}

function formatLookup(names) {
  var map =3D {}, i =3D -1, n =3D names.length;
  while (++i < n) map[names[i].toLowerCase()] =3D i;
  return map;
}

function parseWeekdayNumberSunday(d, string, i) {
  var n =3D numberRe.exec(string.slice(i, i + 1));
  return n ? (d.w =3D +n[0], i + n[0].length) : -1;
}

function parseWeekdayNumberMonday(d, string, i) {
  var n =3D numberRe.exec(string.slice(i, i + 1));
  return n ? (d.u =3D +n[0], i + n[0].length) : -1;
}

function parseWeekNumberSunday(d, string, i) {
  var n =3D numberRe.exec(string.slice(i, i + 2));
  return n ? (d.U =3D +n[0], i + n[0].length) : -1;
}

function parseWeekNumberISO(d, string, i) {
  var n =3D numberRe.exec(string.slice(i, i + 2));
  return n ? (d.V =3D +n[0], i + n[0].length) : -1;
}

function parseWeekNumberMonday(d, string, i) {
  var n =3D numberRe.exec(string.slice(i, i + 2));
  return n ? (d.W =3D +n[0], i + n[0].length) : -1;
}

function parseFullYear(d, string, i) {
  var n =3D numberRe.exec(string.slice(i, i + 4));
  return n ? (d.y =3D +n[0], i + n[0].length) : -1;
}

function parseYear(d, string, i) {
  var n =3D numberRe.exec(string.slice(i, i + 2));
  return n ? (d.y =3D +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) =
: -1;
}

function parseZone(d, string, i) {
  var n =3D /^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(string.slice(i, i + 6));
  return n ? (d.Z =3D n[1] ? 0 : -(n[2] + (n[3] || "00")), i + n[0].length)=
 : -1;
}

function parseMonthNumber(d, string, i) {
  var n =3D numberRe.exec(string.slice(i, i + 2));
  return n ? (d.m =3D n[0] - 1, i + n[0].length) : -1;
}

function parseDayOfMonth(d, string, i) {
  var n =3D numberRe.exec(string.slice(i, i + 2));
  return n ? (d.d =3D +n[0], i + n[0].length) : -1;
}

function parseDayOfYear(d, string, i) {
  var n =3D numberRe.exec(string.slice(i, i + 3));
  return n ? (d.m =3D 0, d.d =3D +n[0], i + n[0].length) : -1;
}

function parseHour24(d, string, i) {
  var n =3D numberRe.exec(string.slice(i, i + 2));
  return n ? (d.H =3D +n[0], i + n[0].length) : -1;
}

function parseMinutes(d, string, i) {
  var n =3D numberRe.exec(string.slice(i, i + 2));
  return n ? (d.M =3D +n[0], i + n[0].length) : -1;
}

function parseSeconds(d, string, i) {
  var n =3D numberRe.exec(string.slice(i, i + 2));
  return n ? (d.S =3D +n[0], i + n[0].length) : -1;
}

function parseMilliseconds(d, string, i) {
  var n =3D numberRe.exec(string.slice(i, i + 3));
  return n ? (d.L =3D +n[0], i + n[0].length) : -1;
}

function parseMicroseconds(d, string, i) {
  var n =3D numberRe.exec(string.slice(i, i + 6));
  return n ? (d.L =3D Math.floor(n[0] / 1000), i + n[0].length) : -1;
}

function parseLiteralPercent(d, string, i) {
  var n =3D percentRe.exec(string.slice(i, i + 1));
  return n ? i + n[0].length : -1;
}

function parseUnixTimestamp(d, string, i) {
  var n =3D numberRe.exec(string.slice(i));
  return n ? (d.Q =3D +n[0], i + n[0].length) : -1;
}

function parseUnixTimestampSeconds(d, string, i) {
  var n =3D numberRe.exec(string.slice(i));
  return n ? (d.Q =3D (+n[0]) * 1000, i + n[0].length) : -1;
}

function formatDayOfMonth(d, p) {
  return pad$1(d.getDate(), p, 2);
}

function formatHour24(d, p) {
  return pad$1(d.getHours(), p, 2);
}

function formatHour12(d, p) {
  return pad$1(d.getHours() % 12 || 12, p, 2);
}

function formatDayOfYear(d, p) {
  return pad$1(1 + day.count(year(d), d), p, 3);
}

function formatMilliseconds(d, p) {
  return pad$1(d.getMilliseconds(), p, 3);
}

function formatMicroseconds(d, p) {
  return formatMilliseconds(d, p) + "000";
}

function formatMonthNumber(d, p) {
  return pad$1(d.getMonth() + 1, p, 2);
}

function formatMinutes(d, p) {
  return pad$1(d.getMinutes(), p, 2);
}

function formatSeconds(d, p) {
  return pad$1(d.getSeconds(), p, 2);
}

function formatWeekdayNumberMonday(d) {
  var day$$1 =3D d.getDay();
  return day$$1 =3D=3D=3D 0 ? 7 : day$$1;
}

function formatWeekNumberSunday(d, p) {
  return pad$1(sunday.count(year(d), d), p, 2);
}

function formatWeekNumberISO(d, p) {
  var day$$1 =3D d.getDay();
  d =3D (day$$1 >=3D 4 || day$$1 =3D=3D=3D 0) ? thursday(d) : thursday.ceil=
(d);
  return pad$1(thursday.count(year(d), d) + (year(d).getDay() =3D=3D=3D 4),=
 p, 2);
}

function formatWeekdayNumberSunday(d) {
  return d.getDay();
}

function formatWeekNumberMonday(d, p) {
  return pad$1(monday.count(year(d), d), p, 2);
}

function formatYear$1(d, p) {
  return pad$1(d.getFullYear() % 100, p, 2);
}

function formatFullYear(d, p) {
  return pad$1(d.getFullYear() % 10000, p, 4);
}

function formatZone(d) {
  var z =3D d.getTimezoneOffset();
  return (z > 0 ? "-" : (z *=3D -1, "+"))
      + pad$1(z / 60 | 0, "0", 2)
      + pad$1(z % 60, "0", 2);
}

function formatUTCDayOfMonth(d, p) {
  return pad$1(d.getUTCDate(), p, 2);
}

function formatUTCHour24(d, p) {
  return pad$1(d.getUTCHours(), p, 2);
}

function formatUTCHour12(d, p) {
  return pad$1(d.getUTCHours() % 12 || 12, p, 2);
}

function formatUTCDayOfYear(d, p) {
  return pad$1(1 + utcDay.count(utcYear(d), d), p, 3);
}

function formatUTCMilliseconds(d, p) {
  return pad$1(d.getUTCMilliseconds(), p, 3);
}

function formatUTCMicroseconds(d, p) {
  return formatUTCMilliseconds(d, p) + "000";
}

function formatUTCMonthNumber(d, p) {
  return pad$1(d.getUTCMonth() + 1, p, 2);
}

function formatUTCMinutes(d, p) {
  return pad$1(d.getUTCMinutes(), p, 2);
}

function formatUTCSeconds(d, p) {
  return pad$1(d.getUTCSeconds(), p, 2);
}

function formatUTCWeekdayNumberMonday(d) {
  var dow =3D d.getUTCDay();
  return dow =3D=3D=3D 0 ? 7 : dow;
}

function formatUTCWeekNumberSunday(d, p) {
  return pad$1(utcSunday.count(utcYear(d), d), p, 2);
}

function formatUTCWeekNumberISO(d, p) {
  var day$$1 =3D d.getUTCDay();
  d =3D (day$$1 >=3D 4 || day$$1 =3D=3D=3D 0) ? utcThursday(d) : utcThursda=
y.ceil(d);
  return pad$1(utcThursday.count(utcYear(d), d) + (utcYear(d).getUTCDay() =
=3D=3D=3D 4), p, 2);
}

function formatUTCWeekdayNumberSunday(d) {
  return d.getUTCDay();
}

function formatUTCWeekNumberMonday(d, p) {
  return pad$1(utcMonday.count(utcYear(d), d), p, 2);
}

function formatUTCYear(d, p) {
  return pad$1(d.getUTCFullYear() % 100, p, 2);
}

function formatUTCFullYear(d, p) {
  return pad$1(d.getUTCFullYear() % 10000, p, 4);
}

function formatUTCZone() {
  return "+0000";
}

function formatLiteralPercent() {
  return "%";
}

function formatUnixTimestamp(d) {
  return +d;
}

function formatUnixTimestampSeconds(d) {
  return Math.floor(+d / 1000);
}

var locale$1;

defaultLocale$1({
  dateTime: "%x, %X",
  date: "%-m/%-d/%Y",
  time: "%-I:%M:%S %p",
  periods: ["AM", "PM"],
  days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", =
"Saturday"],
  shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
  months: ["January", "February", "March", "April", "May", "June", "July", =
"August", "September", "October", "November", "December"],
  shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Se=
p", "Oct", "Nov", "Dec"]
});

function defaultLocale$1(definition) {
  locale$1 =3D formatLocale$1(definition);
  exports.timeFormat =3D locale$1.format;
  exports.timeParse =3D locale$1.parse;
  exports.utcFormat =3D locale$1.utcFormat;
  exports.utcParse =3D locale$1.utcParse;
  return locale$1;
}

var isoSpecifier =3D "%Y-%m-%dT%H:%M:%S.%LZ";

function formatIsoNative(date) {
  return date.toISOString();
}

var formatIso =3D Date.prototype.toISOString
    ? formatIsoNative
    : exports.utcFormat(isoSpecifier);

function parseIsoNative(string) {
  var date =3D new Date(string);
  return isNaN(date) ? null : date;
}

var parseIso =3D +new Date("2000-01-01T00:00:00.000Z")
    ? parseIsoNative
    : exports.utcParse(isoSpecifier);

var durationSecond$1 =3D 1000,
    durationMinute$1 =3D durationSecond$1 * 60,
    durationHour$1 =3D durationMinute$1 * 60,
    durationDay$1 =3D durationHour$1 * 24,
    durationWeek$1 =3D durationDay$1 * 7,
    durationMonth =3D durationDay$1 * 30,
    durationYear =3D durationDay$1 * 365;

function date$1(t) {
  return new Date(t);
}

function number$3(t) {
  return t instanceof Date ? +t : +new Date(+t);
}

function calendar(year$$1, month$$1, week, day$$1, hour$$1, minute$$1, seco=
nd$$1, millisecond$$1, format) {
  var scale =3D continuous(identity$6, identity$6),
      invert =3D scale.invert,
      domain =3D scale.domain;

  var formatMillisecond =3D format(".%L"),
      formatSecond =3D format(":%S"),
      formatMinute =3D format("%I:%M"),
      formatHour =3D format("%I %p"),
      formatDay =3D format("%a %d"),
      formatWeek =3D format("%b %d"),
      formatMonth =3D format("%B"),
      formatYear =3D format("%Y");

  var tickIntervals =3D [
    [second$$1,  1,      durationSecond$1],
    [second$$1,  5,  5 * durationSecond$1],
    [second$$1, 15, 15 * durationSecond$1],
    [second$$1, 30, 30 * durationSecond$1],
    [minute$$1,  1,      durationMinute$1],
    [minute$$1,  5,  5 * durationMinute$1],
    [minute$$1, 15, 15 * durationMinute$1],
    [minute$$1, 30, 30 * durationMinute$1],
    [  hour$$1,  1,      durationHour$1  ],
    [  hour$$1,  3,  3 * durationHour$1  ],
    [  hour$$1,  6,  6 * durationHour$1  ],
    [  hour$$1, 12, 12 * durationHour$1  ],
    [   day$$1,  1,      durationDay$1   ],
    [   day$$1,  2,  2 * durationDay$1   ],
    [  week,  1,      durationWeek$1  ],
    [ month$$1,  1,      durationMonth ],
    [ month$$1,  3,  3 * durationMonth ],
    [  year$$1,  1,      durationYear  ]
  ];

  function tickFormat(date) {
    return (second$$1(date) < date ? formatMillisecond
        : minute$$1(date) < date ? formatSecond
        : hour$$1(date) < date ? formatMinute
        : day$$1(date) < date ? formatHour
        : month$$1(date) < date ? (week(date) < date ? formatDay : formatWe=
ek)
        : year$$1(date) < date ? formatMonth
        : formatYear)(date);
  }

  function tickInterval(interval, start, stop, step) {
    if (interval =3D=3D null) interval =3D 10;

    // If a desired tick count is specified, pick a reasonable tick interval
    // based on the extent of the domain and a rough estimate of tick size.
    // Otherwise, assume interval is already a time interval and use it.
    if (typeof interval =3D=3D=3D "number") {
      var target =3D Math.abs(stop - start) / interval,
          i =3D bisector(function(i) { return i[2]; }).right(tickIntervals,=
 target);
      if (i =3D=3D=3D tickIntervals.length) {
        step =3D tickStep(start / durationYear, stop / durationYear, interv=
al);
        interval =3D year$$1;
      } else if (i) {
        i =3D tickIntervals[target / tickIntervals[i - 1][2] < tickInterval=
s[i][2] / target ? i - 1 : i];
        step =3D i[1];
        interval =3D i[0];
      } else {
        step =3D Math.max(tickStep(start, stop, interval), 1);
        interval =3D millisecond$$1;
      }
    }

    return step =3D=3D null ? interval : interval.every(step);
  }

  scale.invert =3D function(y) {
    return new Date(invert(y));
  };

  scale.domain =3D function(_) {
    return arguments.length ? domain(map$2.call(_, number$3)) : domain().ma=
p(date$1);
  };

  scale.ticks =3D function(interval, step) {
    var d =3D domain(),
        t0 =3D d[0],
        t1 =3D d[d.length - 1],
        r =3D t1 < t0,
        t;
    if (r) t =3D t0, t0 =3D t1, t1 =3D t;
    t =3D tickInterval(interval, t0, t1, step);
    t =3D t ? t.range(t0, t1 + 1) : []; // inclusive stop
    return r ? t.reverse() : t;
  };

  scale.tickFormat =3D function(count, specifier) {
    return specifier =3D=3D null ? tickFormat : format(specifier);
  };

  scale.nice =3D function(interval, step) {
    var d =3D domain();
    return (interval =3D tickInterval(interval, d[0], d[d.length - 1], step=
))
        ? domain(nice(d, interval))
        : scale;
  };

  scale.copy =3D function() {
    return copy(scale, calendar(year$$1, month$$1, week, day$$1, hour$$1, m=
inute$$1, second$$1, millisecond$$1, format));
  };

  return scale;
}

function time() {
  return initRange.apply(calendar(year, month, sunday, day, hour, minute, s=
econd, millisecond, exports.timeFormat).domain([new Date(2000, 0, 1), new D=
ate(2000, 0, 2)]), arguments);
}

function utcTime() {
  return initRange.apply(calendar(utcYear, utcMonth, utcSunday, utcDay, utc=
Hour, utcMinute, second, millisecond, exports.utcFormat).domain([Date.UTC(2=
000, 0, 1), Date.UTC(2000, 0, 2)]), arguments);
}

function transformer$2() {
  var x0 =3D 0,
      x1 =3D 1,
      t0,
      t1,
      k10,
      transform,
      interpolator =3D identity$6,
      clamp =3D false,
      unknown;

  function scale(x) {
    return isNaN(x =3D +x) ? unknown : interpolator(k10 =3D=3D=3D 0 ? 0.5 :=
 (x =3D (transform(x) - t0) * k10, clamp ? Math.max(0, Math.min(1, x)) : x)=
);
  }

  scale.domain =3D function(_) {
    return arguments.length ? (t0 =3D transform(x0 =3D +_[0]), t1 =3D trans=
form(x1 =3D +_[1]), k10 =3D t0 =3D=3D=3D t1 ? 0 : 1 / (t1 - t0), scale) : [=
x0, x1];
  };

  scale.clamp =3D function(_) {
    return arguments.length ? (clamp =3D !!_, scale) : clamp;
  };

  scale.interpolator =3D function(_) {
    return arguments.length ? (interpolator =3D _, scale) : interpolator;
  };

  scale.unknown =3D function(_) {
    return arguments.length ? (unknown =3D _, scale) : unknown;
  };

  return function(t) {
    transform =3D t, t0 =3D t(x0), t1 =3D t(x1), k10 =3D t0 =3D=3D=3D t1 ? =
0 : 1 / (t1 - t0);
    return scale;
  };
}

function copy$1(source, target) {
  return target
      .domain(source.domain())
      .interpolator(source.interpolator())
      .clamp(source.clamp())
      .unknown(source.unknown());
}

function sequential() {
  var scale =3D linearish(transformer$2()(identity$6));

  scale.copy =3D function() {
    return copy$1(scale, sequential());
  };

  return initInterpolator.apply(scale, arguments);
}

function sequentialLog() {
  var scale =3D loggish(transformer$2()).domain([1, 10]);

  scale.copy =3D function() {
    return copy$1(scale, sequentialLog()).base(scale.base());
  };

  return initInterpolator.apply(scale, arguments);
}

function sequentialSymlog() {
  var scale =3D symlogish(transformer$2());

  scale.copy =3D function() {
    return copy$1(scale, sequentialSymlog()).constant(scale.constant());
  };

  return initInterpolator.apply(scale, arguments);
}

function sequentialPow() {
  var scale =3D powish(transformer$2());

  scale.copy =3D function() {
    return copy$1(scale, sequentialPow()).exponent(scale.exponent());
  };

  return initInterpolator.apply(scale, arguments);
}

function sequentialSqrt() {
  return sequentialPow.apply(null, arguments).exponent(0.5);
}

function sequentialQuantile() {
  var domain =3D [],
      interpolator =3D identity$6;

  function scale(x) {
    if (!isNaN(x =3D +x)) return interpolator((bisectRight(domain, x) - 1) =
/ (domain.length - 1));
  }

  scale.domain =3D function(_) {
    if (!arguments.length) return domain.slice();
    domain =3D [];
    for (var i =3D 0, n =3D _.length, d; i < n; ++i) if (d =3D _[i], d !=3D=
 null && !isNaN(d =3D +d)) domain.push(d);
    domain.sort(ascending);
    return scale;
  };

  scale.interpolator =3D function(_) {
    return arguments.length ? (interpolator =3D _, scale) : interpolator;
  };

  scale.copy =3D function() {
    return sequentialQuantile(interpolator).domain(domain);
  };

  return initInterpolator.apply(scale, arguments);
}

function transformer$3() {
  var x0 =3D 0,
      x1 =3D 0.5,
      x2 =3D 1,
      t0,
      t1,
      t2,
      k10,
      k21,
      interpolator =3D identity$6,
      transform,
      clamp =3D false,
      unknown;

  function scale(x) {
    return isNaN(x =3D +x) ? unknown : (x =3D 0.5 + ((x =3D +transform(x)) =
- t1) * (x < t1 ? k10 : k21), interpolator(clamp ? Math.max(0, Math.min(1, =
x)) : x));
  }

  scale.domain =3D function(_) {
    return arguments.length ? (t0 =3D transform(x0 =3D +_[0]), t1 =3D trans=
form(x1 =3D +_[1]), t2 =3D transform(x2 =3D +_[2]), k10 =3D t0 =3D=3D=3D t1=
 ? 0 : 0.5 / (t1 - t0), k21 =3D t1 =3D=3D=3D t2 ? 0 : 0.5 / (t2 - t1), scal=
e) : [x0, x1, x2];
  };

  scale.clamp =3D function(_) {
    return arguments.length ? (clamp =3D !!_, scale) : clamp;
  };

  scale.interpolator =3D function(_) {
    return arguments.length ? (interpolator =3D _, scale) : interpolator;
  };

  scale.unknown =3D function(_) {
    return arguments.length ? (unknown =3D _, scale) : unknown;
  };

  return function(t) {
    transform =3D t, t0 =3D t(x0), t1 =3D t(x1), t2 =3D t(x2), k10 =3D t0 =
=3D=3D=3D t1 ? 0 : 0.5 / (t1 - t0), k21 =3D t1 =3D=3D=3D t2 ? 0 : 0.5 / (t2=
 - t1);
    return scale;
  };
}

function diverging() {
  var scale =3D linearish(transformer$3()(identity$6));

  scale.copy =3D function() {
    return copy$1(scale, diverging());
  };

  return initInterpolator.apply(scale, arguments);
}

function divergingLog() {
  var scale =3D loggish(transformer$3()).domain([0.1, 1, 10]);

  scale.copy =3D function() {
    return copy$1(scale, divergingLog()).base(scale.base());
  };

  return initInterpolator.apply(scale, arguments);
}

function divergingSymlog() {
  var scale =3D symlogish(transformer$3());

  scale.copy =3D function() {
    return copy$1(scale, divergingSymlog()).constant(scale.constant());
  };

  return initInterpolator.apply(scale, arguments);
}

function divergingPow() {
  var scale =3D powish(transformer$3());

  scale.copy =3D function() {
    return copy$1(scale, divergingPow()).exponent(scale.exponent());
  };

  return initInterpolator.apply(scale, arguments);
}

function divergingSqrt() {
  return divergingPow.apply(null, arguments).exponent(0.5);
}

function colors(specifier) {
  var n =3D specifier.length / 6 | 0, colors =3D new Array(n), i =3D 0;
  while (i < n) colors[i] =3D "#" + specifier.slice(i * 6, ++i * 6);
  return colors;
}

var category10 =3D colors("1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7f=
bcbd2217becf");

var Accent =3D colors("7fc97fbeaed4fdc086ffff99386cb0f0027fbf5b17666666");

var Dark2 =3D colors("1b9e77d95f027570b3e7298a66a61ee6ab02a6761d666666");

var Paired =3D colors("a6cee31f78b4b2df8a33a02cfb9a99e31a1cfdbf6fff7f00cab2=
d66a3d9affff99b15928");

var Pastel1 =3D colors("fbb4aeb3cde3ccebc5decbe4fed9a6ffffcce5d8bdfddaecf2f=
2f2");

var Pastel2 =3D colors("b3e2cdfdcdaccbd5e8f4cae4e6f5c9fff2aef1e2cccccccc");

var Set1 =3D colors("e41a1c377eb84daf4a984ea3ff7f00ffff33a65628f781bf999999=
");

var Set2 =3D colors("66c2a5fc8d628da0cbe78ac3a6d854ffd92fe5c494b3b3b3");

var Set3 =3D colors("8dd3c7ffffb3bebadafb807280b1d3fdb462b3de69fccde5d9d9d9=
bc80bdccebc5ffed6f");

function ramp(scheme) {
  return rgbBasis(scheme[scheme.length - 1]);
}

var scheme =3D new Array(3).concat(
  "d8b365f5f5f55ab4ac",
  "a6611adfc27d80cdc1018571",
  "a6611adfc27df5f5f580cdc1018571",
  "8c510ad8b365f6e8c3c7eae55ab4ac01665e",
  "8c510ad8b365f6e8c3f5f5f5c7eae55ab4ac01665e",
  "8c510abf812ddfc27df6e8c3c7eae580cdc135978f01665e",
  "8c510abf812ddfc27df6e8c3f5f5f5c7eae580cdc135978f01665e",
  "5430058c510abf812ddfc27df6e8c3c7eae580cdc135978f01665e003c30",
  "5430058c510abf812ddfc27df6e8c3f5f5f5c7eae580cdc135978f01665e003c30"
).map(colors);

var BrBG =3D ramp(scheme);

var scheme$1 =3D new Array(3).concat(
  "af8dc3f7f7f77fbf7b",
  "7b3294c2a5cfa6dba0008837",
  "7b3294c2a5cff7f7f7a6dba0008837",
  "762a83af8dc3e7d4e8d9f0d37fbf7b1b7837",
  "762a83af8dc3e7d4e8f7f7f7d9f0d37fbf7b1b7837",
  "762a839970abc2a5cfe7d4e8d9f0d3a6dba05aae611b7837",
  "762a839970abc2a5cfe7d4e8f7f7f7d9f0d3a6dba05aae611b7837",
  "40004b762a839970abc2a5cfe7d4e8d9f0d3a6dba05aae611b783700441b",
  "40004b762a839970abc2a5cfe7d4e8f7f7f7d9f0d3a6dba05aae611b783700441b"
).map(colors);

var PRGn =3D ramp(scheme$1);

var scheme$2 =3D new Array(3).concat(
  "e9a3c9f7f7f7a1d76a",
  "d01c8bf1b6dab8e1864dac26",
  "d01c8bf1b6daf7f7f7b8e1864dac26",
  "c51b7de9a3c9fde0efe6f5d0a1d76a4d9221",
  "c51b7de9a3c9fde0eff7f7f7e6f5d0a1d76a4d9221",
  "c51b7dde77aef1b6dafde0efe6f5d0b8e1867fbc414d9221",
  "c51b7dde77aef1b6dafde0eff7f7f7e6f5d0b8e1867fbc414d9221",
  "8e0152c51b7dde77aef1b6dafde0efe6f5d0b8e1867fbc414d9221276419",
  "8e0152c51b7dde77aef1b6dafde0eff7f7f7e6f5d0b8e1867fbc414d9221276419"
).map(colors);

var PiYG =3D ramp(scheme$2);

var scheme$3 =3D new Array(3).concat(
  "998ec3f7f7f7f1a340",
  "5e3c99b2abd2fdb863e66101",
  "5e3c99b2abd2f7f7f7fdb863e66101",
  "542788998ec3d8daebfee0b6f1a340b35806",
  "542788998ec3d8daebf7f7f7fee0b6f1a340b35806",
  "5427888073acb2abd2d8daebfee0b6fdb863e08214b35806",
  "5427888073acb2abd2d8daebf7f7f7fee0b6fdb863e08214b35806",
  "2d004b5427888073acb2abd2d8daebfee0b6fdb863e08214b358067f3b08",
  "2d004b5427888073acb2abd2d8daebf7f7f7fee0b6fdb863e08214b358067f3b08"
).map(colors);

var PuOr =3D ramp(scheme$3);

var scheme$4 =3D new Array(3).concat(
  "ef8a62f7f7f767a9cf",
  "ca0020f4a58292c5de0571b0",
  "ca0020f4a582f7f7f792c5de0571b0",
  "b2182bef8a62fddbc7d1e5f067a9cf2166ac",
  "b2182bef8a62fddbc7f7f7f7d1e5f067a9cf2166ac",
  "b2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac",
  "b2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac",
  "67001fb2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac053061",
  "67001fb2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac053061"
).map(colors);

var RdBu =3D ramp(scheme$4);

var scheme$5 =3D new Array(3).concat(
  "ef8a62ffffff999999",
  "ca0020f4a582bababa404040",
  "ca0020f4a582ffffffbababa404040",
  "b2182bef8a62fddbc7e0e0e09999994d4d4d",
  "b2182bef8a62fddbc7ffffffe0e0e09999994d4d4d",
  "b2182bd6604df4a582fddbc7e0e0e0bababa8787874d4d4d",
  "b2182bd6604df4a582fddbc7ffffffe0e0e0bababa8787874d4d4d",
  "67001fb2182bd6604df4a582fddbc7e0e0e0bababa8787874d4d4d1a1a1a",
  "67001fb2182bd6604df4a582fddbc7ffffffe0e0e0bababa8787874d4d4d1a1a1a"
).map(colors);

var RdGy =3D ramp(scheme$5);

var scheme$6 =3D new Array(3).concat(
  "fc8d59ffffbf91bfdb",
  "d7191cfdae61abd9e92c7bb6",
  "d7191cfdae61ffffbfabd9e92c7bb6",
  "d73027fc8d59fee090e0f3f891bfdb4575b4",
  "d73027fc8d59fee090ffffbfe0f3f891bfdb4575b4",
  "d73027f46d43fdae61fee090e0f3f8abd9e974add14575b4",
  "d73027f46d43fdae61fee090ffffbfe0f3f8abd9e974add14575b4",
  "a50026d73027f46d43fdae61fee090e0f3f8abd9e974add14575b4313695",
  "a50026d73027f46d43fdae61fee090ffffbfe0f3f8abd9e974add14575b4313695"
).map(colors);

var RdYlBu =3D ramp(scheme$6);

var scheme$7 =3D new Array(3).concat(
  "fc8d59ffffbf91cf60",
  "d7191cfdae61a6d96a1a9641",
  "d7191cfdae61ffffbfa6d96a1a9641",
  "d73027fc8d59fee08bd9ef8b91cf601a9850",
  "d73027fc8d59fee08bffffbfd9ef8b91cf601a9850",
  "d73027f46d43fdae61fee08bd9ef8ba6d96a66bd631a9850",
  "d73027f46d43fdae61fee08bffffbfd9ef8ba6d96a66bd631a9850",
  "a50026d73027f46d43fdae61fee08bd9ef8ba6d96a66bd631a9850006837",
  "a50026d73027f46d43fdae61fee08bffffbfd9ef8ba6d96a66bd631a9850006837"
).map(colors);

var RdYlGn =3D ramp(scheme$7);

var scheme$8 =3D new Array(3).concat(
  "fc8d59ffffbf99d594",
  "d7191cfdae61abdda42b83ba",
  "d7191cfdae61ffffbfabdda42b83ba",
  "d53e4ffc8d59fee08be6f59899d5943288bd",
  "d53e4ffc8d59fee08bffffbfe6f59899d5943288bd",
  "d53e4ff46d43fdae61fee08be6f598abdda466c2a53288bd",
  "d53e4ff46d43fdae61fee08bffffbfe6f598abdda466c2a53288bd",
  "9e0142d53e4ff46d43fdae61fee08be6f598abdda466c2a53288bd5e4fa2",
  "9e0142d53e4ff46d43fdae61fee08bffffbfe6f598abdda466c2a53288bd5e4fa2"
).map(colors);

var Spectral =3D ramp(scheme$8);

var scheme$9 =3D new Array(3).concat(
  "e5f5f999d8c92ca25f",
  "edf8fbb2e2e266c2a4238b45",
  "edf8fbb2e2e266c2a42ca25f006d2c",
  "edf8fbccece699d8c966c2a42ca25f006d2c",
  "edf8fbccece699d8c966c2a441ae76238b45005824",
  "f7fcfde5f5f9ccece699d8c966c2a441ae76238b45005824",
  "f7fcfde5f5f9ccece699d8c966c2a441ae76238b45006d2c00441b"
).map(colors);

var BuGn =3D ramp(scheme$9);

var scheme$a =3D new Array(3).concat(
  "e0ecf49ebcda8856a7",
  "edf8fbb3cde38c96c688419d",
  "edf8fbb3cde38c96c68856a7810f7c",
  "edf8fbbfd3e69ebcda8c96c68856a7810f7c",
  "edf8fbbfd3e69ebcda8c96c68c6bb188419d6e016b",
  "f7fcfde0ecf4bfd3e69ebcda8c96c68c6bb188419d6e016b",
  "f7fcfde0ecf4bfd3e69ebcda8c96c68c6bb188419d810f7c4d004b"
).map(colors);

var BuPu =3D ramp(scheme$a);

var scheme$b =3D new Array(3).concat(
  "e0f3dba8ddb543a2ca",
  "f0f9e8bae4bc7bccc42b8cbe",
  "f0f9e8bae4bc7bccc443a2ca0868ac",
  "f0f9e8ccebc5a8ddb57bccc443a2ca0868ac",
  "f0f9e8ccebc5a8ddb57bccc44eb3d32b8cbe08589e",
  "f7fcf0e0f3dbccebc5a8ddb57bccc44eb3d32b8cbe08589e",
  "f7fcf0e0f3dbccebc5a8ddb57bccc44eb3d32b8cbe0868ac084081"
).map(colors);

var GnBu =3D ramp(scheme$b);

var scheme$c =3D new Array(3).concat(
  "fee8c8fdbb84e34a33",
  "fef0d9fdcc8afc8d59d7301f",
  "fef0d9fdcc8afc8d59e34a33b30000",
  "fef0d9fdd49efdbb84fc8d59e34a33b30000",
  "fef0d9fdd49efdbb84fc8d59ef6548d7301f990000",
  "fff7ecfee8c8fdd49efdbb84fc8d59ef6548d7301f990000",
  "fff7ecfee8c8fdd49efdbb84fc8d59ef6548d7301fb300007f0000"
).map(colors);

var OrRd =3D ramp(scheme$c);

var scheme$d =3D new Array(3).concat(
  "ece2f0a6bddb1c9099",
  "f6eff7bdc9e167a9cf02818a",
  "f6eff7bdc9e167a9cf1c9099016c59",
  "f6eff7d0d1e6a6bddb67a9cf1c9099016c59",
  "f6eff7d0d1e6a6bddb67a9cf3690c002818a016450",
  "fff7fbece2f0d0d1e6a6bddb67a9cf3690c002818a016450",
  "fff7fbece2f0d0d1e6a6bddb67a9cf3690c002818a016c59014636"
).map(colors);

var PuBuGn =3D ramp(scheme$d);

var scheme$e =3D new Array(3).concat(
  "ece7f2a6bddb2b8cbe",
  "f1eef6bdc9e174a9cf0570b0",
  "f1eef6bdc9e174a9cf2b8cbe045a8d",
  "f1eef6d0d1e6a6bddb74a9cf2b8cbe045a8d",
  "f1eef6d0d1e6a6bddb74a9cf3690c00570b0034e7b",
  "fff7fbece7f2d0d1e6a6bddb74a9cf3690c00570b0034e7b",
  "fff7fbece7f2d0d1e6a6bddb74a9cf3690c00570b0045a8d023858"
).map(colors);

var PuBu =3D ramp(scheme$e);

var scheme$f =3D new Array(3).concat(
  "e7e1efc994c7dd1c77",
  "f1eef6d7b5d8df65b0ce1256",
  "f1eef6d7b5d8df65b0dd1c77980043",
  "f1eef6d4b9dac994c7df65b0dd1c77980043",
  "f1eef6d4b9dac994c7df65b0e7298ace125691003f",
  "f7f4f9e7e1efd4b9dac994c7df65b0e7298ace125691003f",
  "f7f4f9e7e1efd4b9dac994c7df65b0e7298ace125698004367001f"
).map(colors);

var PuRd =3D ramp(scheme$f);

var scheme$g =3D new Array(3).concat(
  "fde0ddfa9fb5c51b8a",
  "feebe2fbb4b9f768a1ae017e",
  "feebe2fbb4b9f768a1c51b8a7a0177",
  "feebe2fcc5c0fa9fb5f768a1c51b8a7a0177",
  "feebe2fcc5c0fa9fb5f768a1dd3497ae017e7a0177",
  "fff7f3fde0ddfcc5c0fa9fb5f768a1dd3497ae017e7a0177",
  "fff7f3fde0ddfcc5c0fa9fb5f768a1dd3497ae017e7a017749006a"
).map(colors);

var RdPu =3D ramp(scheme$g);

var scheme$h =3D new Array(3).concat(
  "edf8b17fcdbb2c7fb8",
  "ffffcca1dab441b6c4225ea8",
  "ffffcca1dab441b6c42c7fb8253494",
  "ffffccc7e9b47fcdbb41b6c42c7fb8253494",
  "ffffccc7e9b47fcdbb41b6c41d91c0225ea80c2c84",
  "ffffd9edf8b1c7e9b47fcdbb41b6c41d91c0225ea80c2c84",
  "ffffd9edf8b1c7e9b47fcdbb41b6c41d91c0225ea8253494081d58"
).map(colors);

var YlGnBu =3D ramp(scheme$h);

var scheme$i =3D new Array(3).concat(
  "f7fcb9addd8e31a354",
  "ffffccc2e69978c679238443",
  "ffffccc2e69978c67931a354006837",
  "ffffccd9f0a3addd8e78c67931a354006837",
  "ffffccd9f0a3addd8e78c67941ab5d238443005a32",
  "ffffe5f7fcb9d9f0a3addd8e78c67941ab5d238443005a32",
  "ffffe5f7fcb9d9f0a3addd8e78c67941ab5d238443006837004529"
).map(colors);

var YlGn =3D ramp(scheme$i);

var scheme$j =3D new Array(3).concat(
  "fff7bcfec44fd95f0e",
  "ffffd4fed98efe9929cc4c02",
  "ffffd4fed98efe9929d95f0e993404",
  "ffffd4fee391fec44ffe9929d95f0e993404",
  "ffffd4fee391fec44ffe9929ec7014cc4c028c2d04",
  "ffffe5fff7bcfee391fec44ffe9929ec7014cc4c028c2d04",
  "ffffe5fff7bcfee391fec44ffe9929ec7014cc4c02993404662506"
).map(colors);

var YlOrBr =3D ramp(scheme$j);

var scheme$k =3D new Array(3).concat(
  "ffeda0feb24cf03b20",
  "ffffb2fecc5cfd8d3ce31a1c",
  "ffffb2fecc5cfd8d3cf03b20bd0026",
  "ffffb2fed976feb24cfd8d3cf03b20bd0026",
  "ffffb2fed976feb24cfd8d3cfc4e2ae31a1cb10026",
  "ffffccffeda0fed976feb24cfd8d3cfc4e2ae31a1cb10026",
  "ffffccffeda0fed976feb24cfd8d3cfc4e2ae31a1cbd0026800026"
).map(colors);

var YlOrRd =3D ramp(scheme$k);

var scheme$l =3D new Array(3).concat(
  "deebf79ecae13182bd",
  "eff3ffbdd7e76baed62171b5",
  "eff3ffbdd7e76baed63182bd08519c",
  "eff3ffc6dbef9ecae16baed63182bd08519c",
  "eff3ffc6dbef9ecae16baed64292c62171b5084594",
  "f7fbffdeebf7c6dbef9ecae16baed64292c62171b5084594",
  "f7fbffdeebf7c6dbef9ecae16baed64292c62171b508519c08306b"
).map(colors);

var Blues =3D ramp(scheme$l);

var scheme$m =3D new Array(3).concat(
  "e5f5e0a1d99b31a354",
  "edf8e9bae4b374c476238b45",
  "edf8e9bae4b374c47631a354006d2c",
  "edf8e9c7e9c0a1d99b74c47631a354006d2c",
  "edf8e9c7e9c0a1d99b74c47641ab5d238b45005a32",
  "f7fcf5e5f5e0c7e9c0a1d99b74c47641ab5d238b45005a32",
  "f7fcf5e5f5e0c7e9c0a1d99b74c47641ab5d238b45006d2c00441b"
).map(colors);

var Greens =3D ramp(scheme$m);

var scheme$n =3D new Array(3).concat(
  "f0f0f0bdbdbd636363",
  "f7f7f7cccccc969696525252",
  "f7f7f7cccccc969696636363252525",
  "f7f7f7d9d9d9bdbdbd969696636363252525",
  "f7f7f7d9d9d9bdbdbd969696737373525252252525",
  "fffffff0f0f0d9d9d9bdbdbd969696737373525252252525",
  "fffffff0f0f0d9d9d9bdbdbd969696737373525252252525000000"
).map(colors);

var Greys =3D ramp(scheme$n);

var scheme$o =3D new Array(3).concat(
  "efedf5bcbddc756bb1",
  "f2f0f7cbc9e29e9ac86a51a3",
  "f2f0f7cbc9e29e9ac8756bb154278f",
  "f2f0f7dadaebbcbddc9e9ac8756bb154278f",
  "f2f0f7dadaebbcbddc9e9ac8807dba6a51a34a1486",
  "fcfbfdefedf5dadaebbcbddc9e9ac8807dba6a51a34a1486",
  "fcfbfdefedf5dadaebbcbddc9e9ac8807dba6a51a354278f3f007d"
).map(colors);

var Purples =3D ramp(scheme$o);

var scheme$p =3D new Array(3).concat(
  "fee0d2fc9272de2d26",
  "fee5d9fcae91fb6a4acb181d",
  "fee5d9fcae91fb6a4ade2d26a50f15",
  "fee5d9fcbba1fc9272fb6a4ade2d26a50f15",
  "fee5d9fcbba1fc9272fb6a4aef3b2ccb181d99000d",
  "fff5f0fee0d2fcbba1fc9272fb6a4aef3b2ccb181d99000d",
  "fff5f0fee0d2fcbba1fc9272fb6a4aef3b2ccb181da50f1567000d"
).map(colors);

var Reds =3D ramp(scheme$p);

var scheme$q =3D new Array(3).concat(
  "fee6cefdae6be6550d",
  "feeddefdbe85fd8d3cd94701",
  "feeddefdbe85fd8d3ce6550da63603",
  "feeddefdd0a2fdae6bfd8d3ce6550da63603",
  "feeddefdd0a2fdae6bfd8d3cf16913d948018c2d04",
  "fff5ebfee6cefdd0a2fdae6bfd8d3cf16913d948018c2d04",
  "fff5ebfee6cefdd0a2fdae6bfd8d3cf16913d94801a636037f2704"
).map(colors);

var Oranges =3D ramp(scheme$q);

var cubehelix$3 =3D cubehelixLong(cubehelix(300, 0.5, 0.0), cubehelix(-240,=
 0.5, 1.0));

var warm =3D cubehelixLong(cubehelix(-100, 0.75, 0.35), cubehelix(80, 1.50,=
 0.8));

var cool =3D cubehelixLong(cubehelix(260, 0.75, 0.35), cubehelix(80, 1.50, =
0.8));

var c =3D cubehelix();

function rainbow(t) {
  if (t < 0 || t > 1) t -=3D Math.floor(t);
  var ts =3D Math.abs(t - 0.5);
  c.h =3D 360 * t - 100;
  c.s =3D 1.5 - 1.5 * ts;
  c.l =3D 0.8 - 0.9 * ts;
  return c + "";
}

var c$1 =3D rgb(),
    pi_1_3 =3D Math.PI / 3,
    pi_2_3 =3D Math.PI * 2 / 3;

function sinebow(t) {
  var x;
  t =3D (0.5 - t) * Math.PI;
  c$1.r =3D 255 * (x =3D Math.sin(t)) * x;
  c$1.g =3D 255 * (x =3D Math.sin(t + pi_1_3)) * x;
  c$1.b =3D 255 * (x =3D Math.sin(t + pi_2_3)) * x;
  return c$1 + "";
}

function ramp$1(range) {
  var n =3D range.length;
  return function(t) {
    return range[Math.max(0, Math.min(n - 1, Math.floor(t * n)))];
  };
}

var viridis =3D ramp$1(colors("44015444025645045745055946075a46085c460a5d46=
0b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6=
e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a47=
2d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b8=
4433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e=
4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588=
c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32=
658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718=
e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e28=
7d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888=
e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f=
948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa08=
81fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225=
ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67=
935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4a=
c16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5=
f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81=
d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da3=
9a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2=
df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e41=
8e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725"));

var magma =3D ramp$1(colors("00000401000501010601010802010902020b02020d0303=
0f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290=
e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11=
471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f11633=
1116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510=
774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5=
a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d=
816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828=
125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c=
80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327da=
a337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd39=
77bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd=
2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e=
65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef=
1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf876=
5cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63f=
c8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea5=
71fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81f=
ebd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed3=
95fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aaf=
debacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf"));

var inferno =3D ramp$1(colors("00000401000501010601010802010a02020c02020e03=
021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092=
b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c4821=
0c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f36096=
13809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c=
0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136=
e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e74=
1a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216=
b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b=
29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305=
cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c1=
3a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d2464=
4d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e1=
5635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec672=
6ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f5=
7d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa920=
7fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfc=
aa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac22=
8fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5=
db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f17=
9f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4"));

var plasma =3D ramp$1(colors("0d088710078813078916078a19068c1b068d1d068e200=
68f2206902406912605912805922a05932c05942e05952f0596310597330597350498370499=
38049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c0=
2a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a6=
6100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a8740=
1a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a6=
8707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a1981=
4a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197=
a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb63=
08bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80=
c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4=
c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6a=
da5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe46=
95ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754=
ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48=
849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983e=
f99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fda=
b33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2a=
febe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd=
225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626=
f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921"));

function constant$b(x) {
  return function constant() {
    return x;
  };
}

var abs$1 =3D Math.abs;
var atan2$1 =3D Math.atan2;
var cos$2 =3D Math.cos;
var max$2 =3D Math.max;
var min$1 =3D Math.min;
var sin$2 =3D Math.sin;
var sqrt$2 =3D Math.sqrt;

var epsilon$3 =3D 1e-12;
var pi$4 =3D Math.PI;
var halfPi$3 =3D pi$4 / 2;
var tau$4 =3D 2 * pi$4;

function acos$1(x) {
  return x > 1 ? 0 : x < -1 ? pi$4 : Math.acos(x);
}

function asin$1(x) {
  return x >=3D 1 ? halfPi$3 : x <=3D -1 ? -halfPi$3 : Math.asin(x);
}

function arcInnerRadius(d) {
  return d.innerRadius;
}

function arcOuterRadius(d) {
  return d.outerRadius;
}

function arcStartAngle(d) {
  return d.startAngle;
}

function arcEndAngle(d) {
  return d.endAngle;
}

function arcPadAngle(d) {
  return d && d.padAngle; // Note: optional!
}

function intersect(x0, y0, x1, y1, x2, y2, x3, y3) {
  var x10 =3D x1 - x0, y10 =3D y1 - y0,
      x32 =3D x3 - x2, y32 =3D y3 - y2,
      t =3D y32 * x10 - x32 * y10;
  if (t * t < epsilon$3) return;
  t =3D (x32 * (y0 - y2) - y32 * (x0 - x2)) / t;
  return [x0 + t * x10, y0 + t * y10];
}

// Compute perpendicular offset line of length rc.
// http://mathworld.wolfram.com/Circle-LineIntersection.html
function cornerTangents(x0, y0, x1, y1, r1, rc, cw) {
  var x01 =3D x0 - x1,
      y01 =3D y0 - y1,
      lo =3D (cw ? rc : -rc) / sqrt$2(x01 * x01 + y01 * y01),
      ox =3D lo * y01,
      oy =3D -lo * x01,
      x11 =3D x0 + ox,
      y11 =3D y0 + oy,
      x10 =3D x1 + ox,
      y10 =3D y1 + oy,
      x00 =3D (x11 + x10) / 2,
      y00 =3D (y11 + y10) / 2,
      dx =3D x10 - x11,
      dy =3D y10 - y11,
      d2 =3D dx * dx + dy * dy,
      r =3D r1 - rc,
      D =3D x11 * y10 - x10 * y11,
      d =3D (dy < 0 ? -1 : 1) * sqrt$2(max$2(0, r * r * d2 - D * D)),
      cx0 =3D (D * dy - dx * d) / d2,
      cy0 =3D (-D * dx - dy * d) / d2,
      cx1 =3D (D * dy + dx * d) / d2,
      cy1 =3D (-D * dx + dy * d) / d2,
      dx0 =3D cx0 - x00,
      dy0 =3D cy0 - y00,
      dx1 =3D cx1 - x00,
      dy1 =3D cy1 - y00;

  // Pick the closer of the two intersection points.
  // TODO Is there a faster way to determine which intersection to use?
  if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 =3D cx1, cy0 =3D c=
y1;

  return {
    cx: cx0,
    cy: cy0,
    x01: -ox,
    y01: -oy,
    x11: cx0 * (r1 / r - 1),
    y11: cy0 * (r1 / r - 1)
  };
}

function arc() {
  var innerRadius =3D arcInnerRadius,
      outerRadius =3D arcOuterRadius,
      cornerRadius =3D constant$b(0),
      padRadius =3D null,
      startAngle =3D arcStartAngle,
      endAngle =3D arcEndAngle,
      padAngle =3D arcPadAngle,
      context =3D null;

  function arc() {
    var buffer,
        r,
        r0 =3D +innerRadius.apply(this, arguments),
        r1 =3D +outerRadius.apply(this, arguments),
        a0 =3D startAngle.apply(this, arguments) - halfPi$3,
        a1 =3D endAngle.apply(this, arguments) - halfPi$3,
        da =3D abs$1(a1 - a0),
        cw =3D a1 > a0;

    if (!context) context =3D buffer =3D path();

    // Ensure that the outer radius is always larger than the inner radius.
    if (r1 < r0) r =3D r1, r1 =3D r0, r0 =3D r;

    // Is it a point?
    if (!(r1 > epsilon$3)) context.moveTo(0, 0);

    // Or is it a circle or annulus?
    else if (da > tau$4 - epsilon$3) {
      context.moveTo(r1 * cos$2(a0), r1 * sin$2(a0));
      context.arc(0, 0, r1, a0, a1, !cw);
      if (r0 > epsilon$3) {
        context.moveTo(r0 * cos$2(a1), r0 * sin$2(a1));
        context.arc(0, 0, r0, a1, a0, cw);
      }
    }

    // Or is it a circular or annular sector?
    else {
      var a01 =3D a0,
          a11 =3D a1,
          a00 =3D a0,
          a10 =3D a1,
          da0 =3D da,
          da1 =3D da,
          ap =3D padAngle.apply(this, arguments) / 2,
          rp =3D (ap > epsilon$3) && (padRadius ? +padRadius.apply(this, ar=
guments) : sqrt$2(r0 * r0 + r1 * r1)),
          rc =3D min$1(abs$1(r1 - r0) / 2, +cornerRadius.apply(this, argume=
nts)),
          rc0 =3D rc,
          rc1 =3D rc,
          t0,
          t1;

      // Apply padding? Note that since r1 =E2=89=A5 r0, da1 =E2=89=A5 da0.
      if (rp > epsilon$3) {
        var p0 =3D asin$1(rp / r0 * sin$2(ap)),
            p1 =3D asin$1(rp / r1 * sin$2(ap));
        if ((da0 -=3D p0 * 2) > epsilon$3) p0 *=3D (cw ? 1 : -1), a00 +=3D =
p0, a10 -=3D p0;
        else da0 =3D 0, a00 =3D a10 =3D (a0 + a1) / 2;
        if ((da1 -=3D p1 * 2) > epsilon$3) p1 *=3D (cw ? 1 : -1), a01 +=3D =
p1, a11 -=3D p1;
        else da1 =3D 0, a01 =3D a11 =3D (a0 + a1) / 2;
      }

      var x01 =3D r1 * cos$2(a01),
          y01 =3D r1 * sin$2(a01),
          x10 =3D r0 * cos$2(a10),
          y10 =3D r0 * sin$2(a10);

      // Apply rounded corners?
      if (rc > epsilon$3) {
        var x11 =3D r1 * cos$2(a11),
            y11 =3D r1 * sin$2(a11),
            x00 =3D r0 * cos$2(a00),
            y00 =3D r0 * sin$2(a00),
            oc;

        // Restrict the corner radius according to the sector angle.
        if (da < pi$4 && (oc =3D intersect(x01, y01, x00, y00, x11, y11, x1=
0, y10))) {
          var ax =3D x01 - oc[0],
              ay =3D y01 - oc[1],
              bx =3D x11 - oc[0],
              by =3D y11 - oc[1],
              kc =3D 1 / sin$2(acos$1((ax * bx + ay * by) / (sqrt$2(ax * ax=
 + ay * ay) * sqrt$2(bx * bx + by * by))) / 2),
              lc =3D sqrt$2(oc[0] * oc[0] + oc[1] * oc[1]);
          rc0 =3D min$1(rc, (r0 - lc) / (kc - 1));
          rc1 =3D min$1(rc, (r1 - lc) / (kc + 1));
        }
      }

      // Is the sector collapsed to a line?
      if (!(da1 > epsilon$3)) context.moveTo(x01, y01);

      // Does the sector=E2=80=99s outer ring have rounded corners?
      else if (rc1 > epsilon$3) {
        t0 =3D cornerTangents(x00, y00, x01, y01, r1, rc1, cw);
        t1 =3D cornerTangents(x11, y11, x10, y10, r1, rc1, cw);

        context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01);

        // Have the corners merged?
        if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, atan2$1(t0.y01, t0.x01=
), atan2$1(t1.y01, t1.x01), !cw);

        // Otherwise, draw the two corners and the ring.
        else {
          context.arc(t0.cx, t0.cy, rc1, atan2$1(t0.y01, t0.x01), atan2$1(t=
0.y11, t0.x11), !cw);
          context.arc(0, 0, r1, atan2$1(t0.cy + t0.y11, t0.cx + t0.x11), at=
an2$1(t1.cy + t1.y11, t1.cx + t1.x11), !cw);
          context.arc(t1.cx, t1.cy, rc1, atan2$1(t1.y11, t1.x11), atan2$1(t=
1.y01, t1.x01), !cw);
        }
      }

      // Or is the outer ring just a circular arc?
      else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw);

      // Is there no inner ring, and it=E2=80=99s a circular sector?
      // Or perhaps it=E2=80=99s an annular sector collapsed due to padding?
      if (!(r0 > epsilon$3) || !(da0 > epsilon$3)) context.lineTo(x10, y10);

      // Does the sector=E2=80=99s inner ring (or point) have rounded corne=
rs?
      else if (rc0 > epsilon$3) {
        t0 =3D cornerTangents(x10, y10, x11, y11, r0, -rc0, cw);
        t1 =3D cornerTangents(x01, y01, x00, y00, r0, -rc0, cw);

        context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01);

        // Have the corners merged?
        if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, atan2$1(t0.y01, t0.x01=
), atan2$1(t1.y01, t1.x01), !cw);

        // Otherwise, draw the two corners and the ring.
        else {
          context.arc(t0.cx, t0.cy, rc0, atan2$1(t0.y01, t0.x01), atan2$1(t=
0.y11, t0.x11), !cw);
          context.arc(0, 0, r0, atan2$1(t0.cy + t0.y11, t0.cx + t0.x11), at=
an2$1(t1.cy + t1.y11, t1.cx + t1.x11), cw);
          context.arc(t1.cx, t1.cy, rc0, atan2$1(t1.y11, t1.x11), atan2$1(t=
1.y01, t1.x01), !cw);
        }
      }

      // Or is the inner ring just a circular arc?
      else context.arc(0, 0, r0, a10, a00, cw);
    }

    context.closePath();

    if (buffer) return context =3D null, buffer + "" || null;
  }

  arc.centroid =3D function() {
    var r =3D (+innerRadius.apply(this, arguments) + +outerRadius.apply(thi=
s, arguments)) / 2,
        a =3D (+startAngle.apply(this, arguments) + +endAngle.apply(this, a=
rguments)) / 2 - pi$4 / 2;
    return [cos$2(a) * r, sin$2(a) * r];
  };

  arc.innerRadius =3D function(_) {
    return arguments.length ? (innerRadius =3D typeof _ =3D=3D=3D "function=
" ? _ : constant$b(+_), arc) : innerRadius;
  };

  arc.outerRadius =3D function(_) {
    return arguments.length ? (outerRadius =3D typeof _ =3D=3D=3D "function=
" ? _ : constant$b(+_), arc) : outerRadius;
  };

  arc.cornerRadius =3D function(_) {
    return arguments.length ? (cornerRadius =3D typeof _ =3D=3D=3D "functio=
n" ? _ : constant$b(+_), arc) : cornerRadius;
  };

  arc.padRadius =3D function(_) {
    return arguments.length ? (padRadius =3D _ =3D=3D null ? null : typeof =
_ =3D=3D=3D "function" ? _ : constant$b(+_), arc) : padRadius;
  };

  arc.startAngle =3D function(_) {
    return arguments.length ? (startAngle =3D typeof _ =3D=3D=3D "function"=
 ? _ : constant$b(+_), arc) : startAngle;
  };

  arc.endAngle =3D function(_) {
    return arguments.length ? (endAngle =3D typeof _ =3D=3D=3D "function" ?=
 _ : constant$b(+_), arc) : endAngle;
  };

  arc.padAngle =3D function(_) {
    return arguments.length ? (padAngle =3D typeof _ =3D=3D=3D "function" ?=
 _ : constant$b(+_), arc) : padAngle;
  };

  arc.context =3D function(_) {
    return arguments.length ? ((context =3D _ =3D=3D null ? null : _), arc)=
 : context;
  };

  return arc;
}

function Linear(context) {
  this._context =3D context;
}

Linear.prototype =3D {
  areaStart: function() {
    this._line =3D 0;
  },
  areaEnd: function() {
    this._line =3D NaN;
  },
  lineStart: function() {
    this._point =3D 0;
  },
  lineEnd: function() {
    if (this._line || (this._line !=3D=3D 0 && this._point =3D=3D=3D 1)) th=
is._context.closePath();
    this._line =3D 1 - this._line;
  },
  point: function(x, y) {
    x =3D +x, y =3D +y;
    switch (this._point) {
      case 0: this._point =3D 1; this._line ? this._context.lineTo(x, y) : =
this._context.moveTo(x, y); break;
      case 1: this._point =3D 2; // proceed
      default: this._context.lineTo(x, y); break;
    }
  }
};

function curveLinear(context) {
  return new Linear(context);
}

function x$3(p) {
  return p[0];
}

function y$3(p) {
  return p[1];
}

function line() {
  var x$$1 =3D x$3,
      y$$1 =3D y$3,
      defined =3D constant$b(true),
      context =3D null,
      curve =3D curveLinear,
      output =3D null;

  function line(data) {
    var i,
        n =3D data.length,
        d,
        defined0 =3D false,
        buffer;

    if (context =3D=3D null) output =3D curve(buffer =3D path());

    for (i =3D 0; i <=3D n; ++i) {
      if (!(i < n && defined(d =3D data[i], i, data)) =3D=3D=3D defined0) {
        if (defined0 =3D !defined0) output.lineStart();
        else output.lineEnd();
      }
      if (defined0) output.point(+x$$1(d, i, data), +y$$1(d, i, data));
    }

    if (buffer) return output =3D null, buffer + "" || null;
  }

  line.x =3D function(_) {
    return arguments.length ? (x$$1 =3D typeof _ =3D=3D=3D "function" ? _ :=
 constant$b(+_), line) : x$$1;
  };

  line.y =3D function(_) {
    return arguments.length ? (y$$1 =3D typeof _ =3D=3D=3D "function" ? _ :=
 constant$b(+_), line) : y$$1;
  };

  line.defined =3D function(_) {
    return arguments.length ? (defined =3D typeof _ =3D=3D=3D "function" ? =
_ : constant$b(!!_), line) : defined;
  };

  line.curve =3D function(_) {
    return arguments.length ? (curve =3D _, context !=3D null && (output =
=3D curve(context)), line) : curve;
  };

  line.context =3D function(_) {
    return arguments.length ? (_ =3D=3D null ? context =3D output =3D null =
: output =3D curve(context =3D _), line) : context;
  };

  return line;
}

function area$3() {
  var x0 =3D x$3,
      x1 =3D null,
      y0 =3D constant$b(0),
      y1 =3D y$3,
      defined =3D constant$b(true),
      context =3D null,
      curve =3D curveLinear,
      output =3D null;

  function area(data) {
    var i,
        j,
        k,
        n =3D data.length,
        d,
        defined0 =3D false,
        buffer,
        x0z =3D new Array(n),
        y0z =3D new Array(n);

    if (context =3D=3D null) output =3D curve(buffer =3D path());

    for (i =3D 0; i <=3D n; ++i) {
      if (!(i < n && defined(d =3D data[i], i, data)) =3D=3D=3D defined0) {
        if (defined0 =3D !defined0) {
          j =3D i;
          output.areaStart();
          output.lineStart();
        } else {
          output.lineEnd();
          output.lineStart();
          for (k =3D i - 1; k >=3D j; --k) {
            output.point(x0z[k], y0z[k]);
          }
          output.lineEnd();
          output.areaEnd();
        }
      }
      if (defined0) {
        x0z[i] =3D +x0(d, i, data), y0z[i] =3D +y0(d, i, data);
        output.point(x1 ? +x1(d, i, data) : x0z[i], y1 ? +y1(d, i, data) : =
y0z[i]);
      }
    }

    if (buffer) return output =3D null, buffer + "" || null;
  }

  function arealine() {
    return line().defined(defined).curve(curve).context(context);
  }

  area.x =3D function(_) {
    return arguments.length ? (x0 =3D typeof _ =3D=3D=3D "function" ? _ : c=
onstant$b(+_), x1 =3D null, area) : x0;
  };

  area.x0 =3D function(_) {
    return arguments.length ? (x0 =3D typeof _ =3D=3D=3D "function" ? _ : c=
onstant$b(+_), area) : x0;
  };

  area.x1 =3D function(_) {
    return arguments.length ? (x1 =3D _ =3D=3D null ? null : typeof _ =3D=
=3D=3D "function" ? _ : constant$b(+_), area) : x1;
  };

  area.y =3D function(_) {
    return arguments.length ? (y0 =3D typeof _ =3D=3D=3D "function" ? _ : c=
onstant$b(+_), y1 =3D null, area) : y0;
  };

  area.y0 =3D function(_) {
    return arguments.length ? (y0 =3D typeof _ =3D=3D=3D "function" ? _ : c=
onstant$b(+_), area) : y0;
  };

  area.y1 =3D function(_) {
    return arguments.length ? (y1 =3D _ =3D=3D null ? null : typeof _ =3D=
=3D=3D "function" ? _ : constant$b(+_), area) : y1;
  };

  area.lineX0 =3D
  area.lineY0 =3D function() {
    return arealine().x(x0).y(y0);
  };

  area.lineY1 =3D function() {
    return arealine().x(x0).y(y1);
  };

  area.lineX1 =3D function() {
    return arealine().x(x1).y(y0);
  };

  area.defined =3D function(_) {
    return arguments.length ? (defined =3D typeof _ =3D=3D=3D "function" ? =
_ : constant$b(!!_), area) : defined;
  };

  area.curve =3D function(_) {
    return arguments.length ? (curve =3D _, context !=3D null && (output =
=3D curve(context)), area) : curve;
  };

  area.context =3D function(_) {
    return arguments.length ? (_ =3D=3D null ? context =3D output =3D null =
: output =3D curve(context =3D _), area) : context;
  };

  return area;
}

function descending$1(a, b) {
  return b < a ? -1 : b > a ? 1 : b >=3D a ? 0 : NaN;
}

function identity$8(d) {
  return d;
}

function pie() {
  var value =3D identity$8,
      sortValues =3D descending$1,
      sort =3D null,
      startAngle =3D constant$b(0),
      endAngle =3D constant$b(tau$4),
      padAngle =3D constant$b(0);

  function pie(data) {
    var i,
        n =3D data.length,
        j,
        k,
        sum =3D 0,
        index =3D new Array(n),
        arcs =3D new Array(n),
        a0 =3D +startAngle.apply(this, arguments),
        da =3D Math.min(tau$4, Math.max(-tau$4, endAngle.apply(this, argume=
nts) - a0)),
        a1,
        p =3D Math.min(Math.abs(da) / n, padAngle.apply(this, arguments)),
        pa =3D p * (da < 0 ? -1 : 1),
        v;

    for (i =3D 0; i < n; ++i) {
      if ((v =3D arcs[index[i] =3D i] =3D +value(data[i], i, data)) > 0) {
        sum +=3D v;
      }
    }

    // Optionally sort the arcs by previously-computed values or by data.
    if (sortValues !=3D null) index.sort(function(i, j) { return sortValues=
(arcs[i], arcs[j]); });
    else if (sort !=3D null) index.sort(function(i, j) { return sort(data[i=
], data[j]); });

    // Compute the arcs! They are stored in the original data's order.
    for (i =3D 0, k =3D sum ? (da - n * pa) / sum : 0; i < n; ++i, a0 =3D a=
1) {
      j =3D index[i], v =3D arcs[j], a1 =3D a0 + (v > 0 ? v * k : 0) + pa, =
arcs[j] =3D {
        data: data[j],
        index: i,
        value: v,
        startAngle: a0,
        endAngle: a1,
        padAngle: p
      };
    }

    return arcs;
  }

  pie.value =3D function(_) {
    return arguments.length ? (value =3D typeof _ =3D=3D=3D "function" ? _ =
: constant$b(+_), pie) : value;
  };

  pie.sortValues =3D function(_) {
    return arguments.length ? (sortValues =3D _, sort =3D null, pie) : sort=
Values;
  };

  pie.sort =3D function(_) {
    return arguments.length ? (sort =3D _, sortValues =3D null, pie) : sort;
  };

  pie.startAngle =3D function(_) {
    return arguments.length ? (startAngle =3D typeof _ =3D=3D=3D "function"=
 ? _ : constant$b(+_), pie) : startAngle;
  };

  pie.endAngle =3D function(_) {
    return arguments.length ? (endAngle =3D typeof _ =3D=3D=3D "function" ?=
 _ : constant$b(+_), pie) : endAngle;
  };

  pie.padAngle =3D function(_) {
    return arguments.length ? (padAngle =3D typeof _ =3D=3D=3D "function" ?=
 _ : constant$b(+_), pie) : padAngle;
  };

  return pie;
}

var curveRadialLinear =3D curveRadial(curveLinear);

function Radial(curve) {
  this._curve =3D curve;
}

Radial.prototype =3D {
  areaStart: function() {
    this._curve.areaStart();
  },
  areaEnd: function() {
    this._curve.areaEnd();
  },
  lineStart: function() {
    this._curve.lineStart();
  },
  lineEnd: function() {
    this._curve.lineEnd();
  },
  point: function(a, r) {
    this._curve.point(r * Math.sin(a), r * -Math.cos(a));
  }
};

function curveRadial(curve) {

  function radial(context) {
    return new Radial(curve(context));
  }

  radial._curve =3D curve;

  return radial;
}

function lineRadial(l) {
  var c =3D l.curve;

  l.angle =3D l.x, delete l.x;
  l.radius =3D l.y, delete l.y;

  l.curve =3D function(_) {
    return arguments.length ? c(curveRadial(_)) : c()._curve;
  };

  return l;
}

function lineRadial$1() {
  return lineRadial(line().curve(curveRadialLinear));
}

function areaRadial() {
  var a =3D area$3().curve(curveRadialLinear),
      c =3D a.curve,
      x0 =3D a.lineX0,
      x1 =3D a.lineX1,
      y0 =3D a.lineY0,
      y1 =3D a.lineY1;

  a.angle =3D a.x, delete a.x;
  a.startAngle =3D a.x0, delete a.x0;
  a.endAngle =3D a.x1, delete a.x1;
  a.radius =3D a.y, delete a.y;
  a.innerRadius =3D a.y0, delete a.y0;
  a.outerRadius =3D a.y1, delete a.y1;
  a.lineStartAngle =3D function() { return lineRadial(x0()); }, delete a.li=
neX0;
  a.lineEndAngle =3D function() { return lineRadial(x1()); }, delete a.line=
X1;
  a.lineInnerRadius =3D function() { return lineRadial(y0()); }, delete a.l=
ineY0;
  a.lineOuterRadius =3D function() { return lineRadial(y1()); }, delete a.l=
ineY1;

  a.curve =3D function(_) {
    return arguments.length ? c(curveRadial(_)) : c()._curve;
  };

  return a;
}

function pointRadial(x, y) {
  return [(y =3D +y) * Math.cos(x -=3D Math.PI / 2), y * Math.sin(x)];
}

var slice$6 =3D Array.prototype.slice;

function linkSource(d) {
  return d.source;
}

function linkTarget(d) {
  return d.target;
}

function link$2(curve) {
  var source =3D linkSource,
      target =3D linkTarget,
      x$$1 =3D x$3,
      y$$1 =3D y$3,
      context =3D null;

  function link() {
    var buffer, argv =3D slice$6.call(arguments), s =3D source.apply(this, =
argv), t =3D target.apply(this, argv);
    if (!context) context =3D buffer =3D path();
    curve(context, +x$$1.apply(this, (argv[0] =3D s, argv)), +y$$1.apply(th=
is, argv), +x$$1.apply(this, (argv[0] =3D t, argv)), +y$$1.apply(this, argv=
));
    if (buffer) return context =3D null, buffer + "" || null;
  }

  link.source =3D function(_) {
    return arguments.length ? (source =3D _, link) : source;
  };

  link.target =3D function(_) {
    return arguments.length ? (target =3D _, link) : target;
  };

  link.x =3D function(_) {
    return arguments.length ? (x$$1 =3D typeof _ =3D=3D=3D "function" ? _ :=
 constant$b(+_), link) : x$$1;
  };

  link.y =3D function(_) {
    return arguments.length ? (y$$1 =3D typeof _ =3D=3D=3D "function" ? _ :=
 constant$b(+_), link) : y$$1;
  };

  link.context =3D function(_) {
    return arguments.length ? ((context =3D _ =3D=3D null ? null : _), link=
) : context;
  };

  return link;
}

function curveHorizontal(context, x0, y0, x1, y1) {
  context.moveTo(x0, y0);
  context.bezierCurveTo(x0 =3D (x0 + x1) / 2, y0, x0, y1, x1, y1);
}

function curveVertical(context, x0, y0, x1, y1) {
  context.moveTo(x0, y0);
  context.bezierCurveTo(x0, y0 =3D (y0 + y1) / 2, x1, y0, x1, y1);
}

function curveRadial$1(context, x0, y0, x1, y1) {
  var p0 =3D pointRadial(x0, y0),
      p1 =3D pointRadial(x0, y0 =3D (y0 + y1) / 2),
      p2 =3D pointRadial(x1, y0),
      p3 =3D pointRadial(x1, y1);
  context.moveTo(p0[0], p0[1]);
  context.bezierCurveTo(p1[0], p1[1], p2[0], p2[1], p3[0], p3[1]);
}

function linkHorizontal() {
  return link$2(curveHorizontal);
}

function linkVertical() {
  return link$2(curveVertical);
}

function linkRadial() {
  var l =3D link$2(curveRadial$1);
  l.angle =3D l.x, delete l.x;
  l.radius =3D l.y, delete l.y;
  return l;
}

var circle$2 =3D {
  draw: function(context, size) {
    var r =3D Math.sqrt(size / pi$4);
    context.moveTo(r, 0);
    context.arc(0, 0, r, 0, tau$4);
  }
};

var cross$2 =3D {
  draw: function(context, size) {
    var r =3D Math.sqrt(size / 5) / 2;
    context.moveTo(-3 * r, -r);
    context.lineTo(-r, -r);
    context.lineTo(-r, -3 * r);
    context.lineTo(r, -3 * r);
    context.lineTo(r, -r);
    context.lineTo(3 * r, -r);
    context.lineTo(3 * r, r);
    context.lineTo(r, r);
    context.lineTo(r, 3 * r);
    context.lineTo(-r, 3 * r);
    context.lineTo(-r, r);
    context.lineTo(-3 * r, r);
    context.closePath();
  }
};

var tan30 =3D Math.sqrt(1 / 3),
    tan30_2 =3D tan30 * 2;

var diamond =3D {
  draw: function(context, size) {
    var y =3D Math.sqrt(size / tan30_2),
        x =3D y * tan30;
    context.moveTo(0, -y);
    context.lineTo(x, 0);
    context.lineTo(0, y);
    context.lineTo(-x, 0);
    context.closePath();
  }
};

var ka =3D 0.89081309152928522810,
    kr =3D Math.sin(pi$4 / 10) / Math.sin(7 * pi$4 / 10),
    kx =3D Math.sin(tau$4 / 10) * kr,
    ky =3D -Math.cos(tau$4 / 10) * kr;

var star =3D {
  draw: function(context, size) {
    var r =3D Math.sqrt(size * ka),
        x =3D kx * r,
        y =3D ky * r;
    context.moveTo(0, -r);
    context.lineTo(x, y);
    for (var i =3D 1; i < 5; ++i) {
      var a =3D tau$4 * i / 5,
          c =3D Math.cos(a),
          s =3D Math.sin(a);
      context.lineTo(s * r, -c * r);
      context.lineTo(c * x - s * y, s * x + c * y);
    }
    context.closePath();
  }
};

var square =3D {
  draw: function(context, size) {
    var w =3D Math.sqrt(size),
        x =3D -w / 2;
    context.rect(x, x, w, w);
  }
};

var sqrt3 =3D Math.sqrt(3);

var triangle =3D {
  draw: function(context, size) {
    var y =3D -Math.sqrt(size / (sqrt3 * 3));
    context.moveTo(0, y * 2);
    context.lineTo(-sqrt3 * y, -y);
    context.lineTo(sqrt3 * y, -y);
    context.closePath();
  }
};

var c$2 =3D -0.5,
    s =3D Math.sqrt(3) / 2,
    k =3D 1 / Math.sqrt(12),
    a =3D (k / 2 + 1) * 3;

var wye =3D {
  draw: function(context, size) {
    var r =3D Math.sqrt(size / a),
        x0 =3D r / 2,
        y0 =3D r * k,
        x1 =3D x0,
        y1 =3D r * k + r,
        x2 =3D -x1,
        y2 =3D y1;
    context.moveTo(x0, y0);
    context.lineTo(x1, y1);
    context.lineTo(x2, y2);
    context.lineTo(c$2 * x0 - s * y0, s * x0 + c$2 * y0);
    context.lineTo(c$2 * x1 - s * y1, s * x1 + c$2 * y1);
    context.lineTo(c$2 * x2 - s * y2, s * x2 + c$2 * y2);
    context.lineTo(c$2 * x0 + s * y0, c$2 * y0 - s * x0);
    context.lineTo(c$2 * x1 + s * y1, c$2 * y1 - s * x1);
    context.lineTo(c$2 * x2 + s * y2, c$2 * y2 - s * x2);
    context.closePath();
  }
};

var symbols =3D [
  circle$2,
  cross$2,
  diamond,
  square,
  star,
  triangle,
  wye
];

function symbol() {
  var type =3D constant$b(circle$2),
      size =3D constant$b(64),
      context =3D null;

  function symbol() {
    var buffer;
    if (!context) context =3D buffer =3D path();
    type.apply(this, arguments).draw(context, +size.apply(this, arguments));
    if (buffer) return context =3D null, buffer + "" || null;
  }

  symbol.type =3D function(_) {
    return arguments.length ? (type =3D typeof _ =3D=3D=3D "function" ? _ :=
 constant$b(_), symbol) : type;
  };

  symbol.size =3D function(_) {
    return arguments.length ? (size =3D typeof _ =3D=3D=3D "function" ? _ :=
 constant$b(+_), symbol) : size;
  };

  symbol.context =3D function(_) {
    return arguments.length ? (context =3D _ =3D=3D null ? null : _, symbol=
) : context;
  };

  return symbol;
}

function noop$3() {}

function point$2(that, x, y) {
  that._context.bezierCurveTo(
    (2 * that._x0 + that._x1) / 3,
    (2 * that._y0 + that._y1) / 3,
    (that._x0 + 2 * that._x1) / 3,
    (that._y0 + 2 * that._y1) / 3,
    (that._x0 + 4 * that._x1 + x) / 6,
    (that._y0 + 4 * that._y1 + y) / 6
  );
}

function Basis(context) {
  this._context =3D context;
}

Basis.prototype =3D {
  areaStart: function() {
    this._line =3D 0;
  },
  areaEnd: function() {
    this._line =3D NaN;
  },
  lineStart: function() {
    this._x0 =3D this._x1 =3D
    this._y0 =3D this._y1 =3D NaN;
    this._point =3D 0;
  },
  lineEnd: function() {
    switch (this._point) {
      case 3: point$2(this, this._x1, this._y1); // proceed
      case 2: this._context.lineTo(this._x1, this._y1); break;
    }
    if (this._line || (this._line !=3D=3D 0 && this._point =3D=3D=3D 1)) th=
is._context.closePath();
    this._line =3D 1 - this._line;
  },
  point: function(x, y) {
    x =3D +x, y =3D +y;
    switch (this._point) {
      case 0: this._point =3D 1; this._line ? this._context.lineTo(x, y) : =
this._context.moveTo(x, y); break;
      case 1: this._point =3D 2; break;
      case 2: this._point =3D 3; this._context.lineTo((5 * this._x0 + this.=
_x1) / 6, (5 * this._y0 + this._y1) / 6); // proceed
      default: point$2(this, x, y); break;
    }
    this._x0 =3D this._x1, this._x1 =3D x;
    this._y0 =3D this._y1, this._y1 =3D y;
  }
};

function basis$2(context) {
  return new Basis(context);
}

function BasisClosed(context) {
  this._context =3D context;
}

BasisClosed.prototype =3D {
  areaStart: noop$3,
  areaEnd: noop$3,
  lineStart: function() {
    this._x0 =3D this._x1 =3D this._x2 =3D this._x3 =3D this._x4 =3D
    this._y0 =3D this._y1 =3D this._y2 =3D this._y3 =3D this._y4 =3D NaN;
    this._point =3D 0;
  },
  lineEnd: function() {
    switch (this._point) {
      case 1: {
        this._context.moveTo(this._x2, this._y2);
        this._context.closePath();
        break;
      }
      case 2: {
        this._context.moveTo((this._x2 + 2 * this._x3) / 3, (this._y2 + 2 *=
 this._y3) / 3);
        this._context.lineTo((this._x3 + 2 * this._x2) / 3, (this._y3 + 2 *=
 this._y2) / 3);
        this._context.closePath();
        break;
      }
      case 3: {
        this.point(this._x2, this._y2);
        this.point(this._x3, this._y3);
        this.point(this._x4, this._y4);
        break;
      }
    }
  },
  point: function(x, y) {
    x =3D +x, y =3D +y;
    switch (this._point) {
      case 0: this._point =3D 1; this._x2 =3D x, this._y2 =3D y; break;
      case 1: this._point =3D 2; this._x3 =3D x, this._y3 =3D y; break;
      case 2: this._point =3D 3; this._x4 =3D x, this._y4 =3D y; this._cont=
ext.moveTo((this._x0 + 4 * this._x1 + x) / 6, (this._y0 + 4 * this._y1 + y)=
 / 6); break;
      default: point$2(this, x, y); break;
    }
    this._x0 =3D this._x1, this._x1 =3D x;
    this._y0 =3D this._y1, this._y1 =3D y;
  }
};

function basisClosed$1(context) {
  return new BasisClosed(context);
}

function BasisOpen(context) {
  this._context =3D context;
}

BasisOpen.prototype =3D {
  areaStart: function() {
    this._line =3D 0;
  },
  areaEnd: function() {
    this._line =3D NaN;
  },
  lineStart: function() {
    this._x0 =3D this._x1 =3D
    this._y0 =3D this._y1 =3D NaN;
    this._point =3D 0;
  },
  lineEnd: function() {
    if (this._line || (this._line !=3D=3D 0 && this._point =3D=3D=3D 3)) th=
is._context.closePath();
    this._line =3D 1 - this._line;
  },
  point: function(x, y) {
    x =3D +x, y =3D +y;
    switch (this._point) {
      case 0: this._point =3D 1; break;
      case 1: this._point =3D 2; break;
      case 2: this._point =3D 3; var x0 =3D (this._x0 + 4 * this._x1 + x) /=
 6, y0 =3D (this._y0 + 4 * this._y1 + y) / 6; this._line ? this._context.li=
neTo(x0, y0) : this._context.moveTo(x0, y0); break;
      case 3: this._point =3D 4; // proceed
      default: point$2(this, x, y); break;
    }
    this._x0 =3D this._x1, this._x1 =3D x;
    this._y0 =3D this._y1, this._y1 =3D y;
  }
};

function basisOpen(context) {
  return new BasisOpen(context);
}

function Bundle(context, beta) {
  this._basis =3D new Basis(context);
  this._beta =3D beta;
}

Bundle.prototype =3D {
  lineStart: function() {
    this._x =3D [];
    this._y =3D [];
    this._basis.lineStart();
  },
  lineEnd: function() {
    var x =3D this._x,
        y =3D this._y,
        j =3D x.length - 1;

    if (j > 0) {
      var x0 =3D x[0],
          y0 =3D y[0],
          dx =3D x[j] - x0,
          dy =3D y[j] - y0,
          i =3D -1,
          t;

      while (++i <=3D j) {
        t =3D i / j;
        this._basis.point(
          this._beta * x[i] + (1 - this._beta) * (x0 + t * dx),
          this._beta * y[i] + (1 - this._beta) * (y0 + t * dy)
        );
      }
    }

    this._x =3D this._y =3D null;
    this._basis.lineEnd();
  },
  point: function(x, y) {
    this._x.push(+x);
    this._y.push(+y);
  }
};

var bundle =3D (function custom(beta) {

  function bundle(context) {
    return beta =3D=3D=3D 1 ? new Basis(context) : new Bundle(context, beta=
);
  }

  bundle.beta =3D function(beta) {
    return custom(+beta);
  };

  return bundle;
})(0.85);

function point$3(that, x, y) {
  that._context.bezierCurveTo(
    that._x1 + that._k * (that._x2 - that._x0),
    that._y1 + that._k * (that._y2 - that._y0),
    that._x2 + that._k * (that._x1 - x),
    that._y2 + that._k * (that._y1 - y),
    that._x2,
    that._y2
  );
}

function Cardinal(context, tension) {
  this._context =3D context;
  this._k =3D (1 - tension) / 6;
}

Cardinal.prototype =3D {
  areaStart: function() {
    this._line =3D 0;
  },
  areaEnd: function() {
    this._line =3D NaN;
  },
  lineStart: function() {
    this._x0 =3D this._x1 =3D this._x2 =3D
    this._y0 =3D this._y1 =3D this._y2 =3D NaN;
    this._point =3D 0;
  },
  lineEnd: function() {
    switch (this._point) {
      case 2: this._context.lineTo(this._x2, this._y2); break;
      case 3: point$3(this, this._x1, this._y1); break;
    }
    if (this._line || (this._line !=3D=3D 0 && this._point =3D=3D=3D 1)) th=
is._context.closePath();
    this._line =3D 1 - this._line;
  },
  point: function(x, y) {
    x =3D +x, y =3D +y;
    switch (this._point) {
      case 0: this._point =3D 1; this._line ? this._context.lineTo(x, y) : =
this._context.moveTo(x, y); break;
      case 1: this._point =3D 2; this._x1 =3D x, this._y1 =3D y; break;
      case 2: this._point =3D 3; // proceed
      default: point$3(this, x, y); break;
    }
    this._x0 =3D this._x1, this._x1 =3D this._x2, this._x2 =3D x;
    this._y0 =3D this._y1, this._y1 =3D this._y2, this._y2 =3D y;
  }
};

var cardinal =3D (function custom(tension) {

  function cardinal(context) {
    return new Cardinal(context, tension);
  }

  cardinal.tension =3D function(tension) {
    return custom(+tension);
  };

  return cardinal;
})(0);

function CardinalClosed(context, tension) {
  this._context =3D context;
  this._k =3D (1 - tension) / 6;
}

CardinalClosed.prototype =3D {
  areaStart: noop$3,
  areaEnd: noop$3,
  lineStart: function() {
    this._x0 =3D this._x1 =3D this._x2 =3D this._x3 =3D this._x4 =3D this._=
x5 =3D
    this._y0 =3D this._y1 =3D this._y2 =3D this._y3 =3D this._y4 =3D this._=
y5 =3D NaN;
    this._point =3D 0;
  },
  lineEnd: function() {
    switch (this._point) {
      case 1: {
        this._context.moveTo(this._x3, this._y3);
        this._context.closePath();
        break;
      }
      case 2: {
        this._context.lineTo(this._x3, this._y3);
        this._context.closePath();
        break;
      }
      case 3: {
        this.point(this._x3, this._y3);
        this.point(this._x4, this._y4);
        this.point(this._x5, this._y5);
        break;
      }
    }
  },
  point: function(x, y) {
    x =3D +x, y =3D +y;
    switch (this._point) {
      case 0: this._point =3D 1; this._x3 =3D x, this._y3 =3D y; break;
      case 1: this._point =3D 2; this._context.moveTo(this._x4 =3D x, this.=
_y4 =3D y); break;
      case 2: this._point =3D 3; this._x5 =3D x, this._y5 =3D y; break;
      default: point$3(this, x, y); break;
    }
    this._x0 =3D this._x1, this._x1 =3D this._x2, this._x2 =3D x;
    this._y0 =3D this._y1, this._y1 =3D this._y2, this._y2 =3D y;
  }
};

var cardinalClosed =3D (function custom(tension) {

  function cardinal$$1(context) {
    return new CardinalClosed(context, tension);
  }

  cardinal$$1.tension =3D function(tension) {
    return custom(+tension);
  };

  return cardinal$$1;
})(0);

function CardinalOpen(context, tension) {
  this._context =3D context;
  this._k =3D (1 - tension) / 6;
}

CardinalOpen.prototype =3D {
  areaStart: function() {
    this._line =3D 0;
  },
  areaEnd: function() {
    this._line =3D NaN;
  },
  lineStart: function() {
    this._x0 =3D this._x1 =3D this._x2 =3D
    this._y0 =3D this._y1 =3D this._y2 =3D NaN;
    this._point =3D 0;
  },
  lineEnd: function() {
    if (this._line || (this._line !=3D=3D 0 && this._point =3D=3D=3D 3)) th=
is._context.closePath();
    this._line =3D 1 - this._line;
  },
  point: function(x, y) {
    x =3D +x, y =3D +y;
    switch (this._point) {
      case 0: this._point =3D 1; break;
      case 1: this._point =3D 2; break;
      case 2: this._point =3D 3; this._line ? this._context.lineTo(this._x2=
, this._y2) : this._context.moveTo(this._x2, this._y2); break;
      case 3: this._point =3D 4; // proceed
      default: point$3(this, x, y); break;
    }
    this._x0 =3D this._x1, this._x1 =3D this._x2, this._x2 =3D x;
    this._y0 =3D this._y1, this._y1 =3D this._y2, this._y2 =3D y;
  }
};

var cardinalOpen =3D (function custom(tension) {

  function cardinal$$1(context) {
    return new CardinalOpen(context, tension);
  }

  cardinal$$1.tension =3D function(tension) {
    return custom(+tension);
  };

  return cardinal$$1;
})(0);

function point$4(that, x, y) {
  var x1 =3D that._x1,
      y1 =3D that._y1,
      x2 =3D that._x2,
      y2 =3D that._y2;

  if (that._l01_a > epsilon$3) {
    var a =3D 2 * that._l01_2a + 3 * that._l01_a * that._l12_a + that._l12_=
2a,
        n =3D 3 * that._l01_a * (that._l01_a + that._l12_a);
    x1 =3D (x1 * a - that._x0 * that._l12_2a + that._x2 * that._l01_2a) / n;
    y1 =3D (y1 * a - that._y0 * that._l12_2a + that._y2 * that._l01_2a) / n;
  }

  if (that._l23_a > epsilon$3) {
    var b =3D 2 * that._l23_2a + 3 * that._l23_a * that._l12_a + that._l12_=
2a,
        m =3D 3 * that._l23_a * (that._l23_a + that._l12_a);
    x2 =3D (x2 * b + that._x1 * that._l23_2a - x * that._l12_2a) / m;
    y2 =3D (y2 * b + that._y1 * that._l23_2a - y * that._l12_2a) / m;
  }

  that._context.bezierCurveTo(x1, y1, x2, y2, that._x2, that._y2);
}

function CatmullRom(context, alpha) {
  this._context =3D context;
  this._alpha =3D alpha;
}

CatmullRom.prototype =3D {
  areaStart: function() {
    this._line =3D 0;
  },
  areaEnd: function() {
    this._line =3D NaN;
  },
  lineStart: function() {
    this._x0 =3D this._x1 =3D this._x2 =3D
    this._y0 =3D this._y1 =3D this._y2 =3D NaN;
    this._l01_a =3D this._l12_a =3D this._l23_a =3D
    this._l01_2a =3D this._l12_2a =3D this._l23_2a =3D
    this._point =3D 0;
  },
  lineEnd: function() {
    switch (this._point) {
      case 2: this._context.lineTo(this._x2, this._y2); break;
      case 3: this.point(this._x2, this._y2); break;
    }
    if (this._line || (this._line !=3D=3D 0 && this._point =3D=3D=3D 1)) th=
is._context.closePath();
    this._line =3D 1 - this._line;
  },
  point: function(x, y) {
    x =3D +x, y =3D +y;

    if (this._point) {
      var x23 =3D this._x2 - x,
          y23 =3D this._y2 - y;
      this._l23_a =3D Math.sqrt(this._l23_2a =3D Math.pow(x23 * x23 + y23 *=
 y23, this._alpha));
    }

    switch (this._point) {
      case 0: this._point =3D 1; this._line ? this._context.lineTo(x, y) : =
this._context.moveTo(x, y); break;
      case 1: this._point =3D 2; break;
      case 2: this._point =3D 3; // proceed
      default: point$4(this, x, y); break;
    }

    this._l01_a =3D this._l12_a, this._l12_a =3D this._l23_a;
    this._l01_2a =3D this._l12_2a, this._l12_2a =3D this._l23_2a;
    this._x0 =3D this._x1, this._x1 =3D this._x2, this._x2 =3D x;
    this._y0 =3D this._y1, this._y1 =3D this._y2, this._y2 =3D y;
  }
};

var catmullRom =3D (function custom(alpha) {

  function catmullRom(context) {
    return alpha ? new CatmullRom(context, alpha) : new Cardinal(context, 0=
);
  }

  catmullRom.alpha =3D function(alpha) {
    return custom(+alpha);
  };

  return catmullRom;
})(0.5);

function CatmullRomClosed(context, alpha) {
  this._context =3D context;
  this._alpha =3D alpha;
}

CatmullRomClosed.prototype =3D {
  areaStart: noop$3,
  areaEnd: noop$3,
  lineStart: function() {
    this._x0 =3D this._x1 =3D this._x2 =3D this._x3 =3D this._x4 =3D this._=
x5 =3D
    this._y0 =3D this._y1 =3D this._y2 =3D this._y3 =3D this._y4 =3D this._=
y5 =3D NaN;
    this._l01_a =3D this._l12_a =3D this._l23_a =3D
    this._l01_2a =3D this._l12_2a =3D this._l23_2a =3D
    this._point =3D 0;
  },
  lineEnd: function() {
    switch (this._point) {
      case 1: {
        this._context.moveTo(this._x3, this._y3);
        this._context.closePath();
        break;
      }
      case 2: {
        this._context.lineTo(this._x3, this._y3);
        this._context.closePath();
        break;
      }
      case 3: {
        this.point(this._x3, this._y3);
        this.point(this._x4, this._y4);
        this.point(this._x5, this._y5);
        break;
      }
    }
  },
  point: function(x, y) {
    x =3D +x, y =3D +y;

    if (this._point) {
      var x23 =3D this._x2 - x,
          y23 =3D this._y2 - y;
      this._l23_a =3D Math.sqrt(this._l23_2a =3D Math.pow(x23 * x23 + y23 *=
 y23, this._alpha));
    }

    switch (this._point) {
      case 0: this._point =3D 1; this._x3 =3D x, this._y3 =3D y; break;
      case 1: this._point =3D 2; this._context.moveTo(this._x4 =3D x, this.=
_y4 =3D y); break;
      case 2: this._point =3D 3; this._x5 =3D x, this._y5 =3D y; break;
      default: point$4(this, x, y); break;
    }

    this._l01_a =3D this._l12_a, this._l12_a =3D this._l23_a;
    this._l01_2a =3D this._l12_2a, this._l12_2a =3D this._l23_2a;
    this._x0 =3D this._x1, this._x1 =3D this._x2, this._x2 =3D x;
    this._y0 =3D this._y1, this._y1 =3D this._y2, this._y2 =3D y;
  }
};

var catmullRomClosed =3D (function custom(alpha) {

  function catmullRom$$1(context) {
    return alpha ? new CatmullRomClosed(context, alpha) : new CardinalClose=
d(context, 0);
  }

  catmullRom$$1.alpha =3D function(alpha) {
    return custom(+alpha);
  };

  return catmullRom$$1;
})(0.5);

function CatmullRomOpen(context, alpha) {
  this._context =3D context;
  this._alpha =3D alpha;
}

CatmullRomOpen.prototype =3D {
  areaStart: function() {
    this._line =3D 0;
  },
  areaEnd: function() {
    this._line =3D NaN;
  },
  lineStart: function() {
    this._x0 =3D this._x1 =3D this._x2 =3D
    this._y0 =3D this._y1 =3D this._y2 =3D NaN;
    this._l01_a =3D this._l12_a =3D this._l23_a =3D
    this._l01_2a =3D this._l12_2a =3D this._l23_2a =3D
    this._point =3D 0;
  },
  lineEnd: function() {
    if (this._line || (this._line !=3D=3D 0 && this._point =3D=3D=3D 3)) th=
is._context.closePath();
    this._line =3D 1 - this._line;
  },
  point: function(x, y) {
    x =3D +x, y =3D +y;

    if (this._point) {
      var x23 =3D this._x2 - x,
          y23 =3D this._y2 - y;
      this._l23_a =3D Math.sqrt(this._l23_2a =3D Math.pow(x23 * x23 + y23 *=
 y23, this._alpha));
    }

    switch (this._point) {
      case 0: this._point =3D 1; break;
      case 1: this._point =3D 2; break;
      case 2: this._point =3D 3; this._line ? this._context.lineTo(this._x2=
, this._y2) : this._context.moveTo(this._x2, this._y2); break;
      case 3: this._point =3D 4; // proceed
      default: point$4(this, x, y); break;
    }

    this._l01_a =3D this._l12_a, this._l12_a =3D this._l23_a;
    this._l01_2a =3D this._l12_2a, this._l12_2a =3D this._l23_2a;
    this._x0 =3D this._x1, this._x1 =3D this._x2, this._x2 =3D x;
    this._y0 =3D this._y1, this._y1 =3D this._y2, this._y2 =3D y;
  }
};

var catmullRomOpen =3D (function custom(alpha) {

  function catmullRom$$1(context) {
    return alpha ? new CatmullRomOpen(context, alpha) : new CardinalOpen(co=
ntext, 0);
  }

  catmullRom$$1.alpha =3D function(alpha) {
    return custom(+alpha);
  };

  return catmullRom$$1;
})(0.5);

function LinearClosed(context) {
  this._context =3D context;
}

LinearClosed.prototype =3D {
  areaStart: noop$3,
  areaEnd: noop$3,
  lineStart: function() {
    this._point =3D 0;
  },
  lineEnd: function() {
    if (this._point) this._context.closePath();
  },
  point: function(x, y) {
    x =3D +x, y =3D +y;
    if (this._point) this._context.lineTo(x, y);
    else this._point =3D 1, this._context.moveTo(x, y);
  }
};

function linearClosed(context) {
  return new LinearClosed(context);
}

function sign$1(x) {
  return x < 0 ? -1 : 1;
}

// Calculate the slopes of the tangents (Hermite-type interpolation) based =
on
// the following paper: Steffen, M. 1990. A Simple Method for Monotonic
// Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO.
// NOV(II), P. 443, 1990.
function slope3(that, x2, y2) {
  var h0 =3D that._x1 - that._x0,
      h1 =3D x2 - that._x1,
      s0 =3D (that._y1 - that._y0) / (h0 || h1 < 0 && -0),
      s1 =3D (y2 - that._y1) / (h1 || h0 < 0 && -0),
      p =3D (s0 * h1 + s1 * h0) / (h0 + h1);
  return (sign$1(s0) + sign$1(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0=
=2E5 * Math.abs(p)) || 0;
}

// Calculate a one-sided slope.
function slope2(that, t) {
  var h =3D that._x1 - that._x0;
  return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t;
}

// According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Represen=
tations
// "you can express cubic Hermite interpolation in terms of cubic B=C3=A9zi=
er curves
// with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1".
function point$5(that, t0, t1) {
  var x0 =3D that._x0,
      y0 =3D that._y0,
      x1 =3D that._x1,
      y1 =3D that._y1,
      dx =3D (x1 - x0) / 3;
  that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1,=
 x1, y1);
}

function MonotoneX(context) {
  this._context =3D context;
}

MonotoneX.prototype =3D {
  areaStart: function() {
    this._line =3D 0;
  },
  areaEnd: function() {
    this._line =3D NaN;
  },
  lineStart: function() {
    this._x0 =3D this._x1 =3D
    this._y0 =3D this._y1 =3D
    this._t0 =3D NaN;
    this._point =3D 0;
  },
  lineEnd: function() {
    switch (this._point) {
      case 2: this._context.lineTo(this._x1, this._y1); break;
      case 3: point$5(this, this._t0, slope2(this, this._t0)); break;
    }
    if (this._line || (this._line !=3D=3D 0 && this._point =3D=3D=3D 1)) th=
is._context.closePath();
    this._line =3D 1 - this._line;
  },
  point: function(x, y) {
    var t1 =3D NaN;

    x =3D +x, y =3D +y;
    if (x =3D=3D=3D this._x1 && y =3D=3D=3D this._y1) return; // Ignore coi=
ncident points.
    switch (this._point) {
      case 0: this._point =3D 1; this._line ? this._context.lineTo(x, y) : =
this._context.moveTo(x, y); break;
      case 1: this._point =3D 2; break;
      case 2: this._point =3D 3; point$5(this, slope2(this, t1 =3D slope3(t=
his, x, y)), t1); break;
      default: point$5(this, this._t0, t1 =3D slope3(this, x, y)); break;
    }

    this._x0 =3D this._x1, this._x1 =3D x;
    this._y0 =3D this._y1, this._y1 =3D y;
    this._t0 =3D t1;
  }
};

function MonotoneY(context) {
  this._context =3D new ReflectContext(context);
}

(MonotoneY.prototype =3D Object.create(MonotoneX.prototype)).point =3D func=
tion(x, y) {
  MonotoneX.prototype.point.call(this, y, x);
};

function ReflectContext(context) {
  this._context =3D context;
}

ReflectContext.prototype =3D {
  moveTo: function(x, y) { this._context.moveTo(y, x); },
  closePath: function() { this._context.closePath(); },
  lineTo: function(x, y) { this._context.lineTo(y, x); },
  bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._context.bezierCurve=
To(y1, x1, y2, x2, y, x); }
};

function monotoneX(context) {
  return new MonotoneX(context);
}

function monotoneY(context) {
  return new MonotoneY(context);
}

function Natural(context) {
  this._context =3D context;
}

Natural.prototype =3D {
  areaStart: function() {
    this._line =3D 0;
  },
  areaEnd: function() {
    this._line =3D NaN;
  },
  lineStart: function() {
    this._x =3D [];
    this._y =3D [];
  },
  lineEnd: function() {
    var x =3D this._x,
        y =3D this._y,
        n =3D x.length;

    if (n) {
      this._line ? this._context.lineTo(x[0], y[0]) : this._context.moveTo(=
x[0], y[0]);
      if (n =3D=3D=3D 2) {
        this._context.lineTo(x[1], y[1]);
      } else {
        var px =3D controlPoints(x),
            py =3D controlPoints(y);
        for (var i0 =3D 0, i1 =3D 1; i1 < n; ++i0, ++i1) {
          this._context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1=
][i0], x[i1], y[i1]);
        }
      }
    }

    if (this._line || (this._line !=3D=3D 0 && n =3D=3D=3D 1)) this._contex=
t.closePath();
    this._line =3D 1 - this._line;
    this._x =3D this._y =3D null;
  },
  point: function(x, y) {
    this._x.push(+x);
    this._y.push(+y);
  }
};

// See https://www.particleincell.com/2012/bezier-splines/ for derivation.
function controlPoints(x) {
  var i,
      n =3D x.length - 1,
      m,
      a =3D new Array(n),
      b =3D new Array(n),
      r =3D new Array(n);
  a[0] =3D 0, b[0] =3D 2, r[0] =3D x[0] + 2 * x[1];
  for (i =3D 1; i < n - 1; ++i) a[i] =3D 1, b[i] =3D 4, r[i] =3D 4 * x[i] +=
 2 * x[i + 1];
  a[n - 1] =3D 2, b[n - 1] =3D 7, r[n - 1] =3D 8 * x[n - 1] + x[n];
  for (i =3D 1; i < n; ++i) m =3D a[i] / b[i - 1], b[i] -=3D m, r[i] -=3D m=
 * r[i - 1];
  a[n - 1] =3D r[n - 1] / b[n - 1];
  for (i =3D n - 2; i >=3D 0; --i) a[i] =3D (r[i] - a[i + 1]) / b[i];
  b[n - 1] =3D (x[n] + a[n - 1]) / 2;
  for (i =3D 0; i < n - 1; ++i) b[i] =3D 2 * x[i + 1] - a[i + 1];
  return [a, b];
}

function natural(context) {
  return new Natural(context);
}

function Step(context, t) {
  this._context =3D context;
  this._t =3D t;
}

Step.prototype =3D {
  areaStart: function() {
    this._line =3D 0;
  },
  areaEnd: function() {
    this._line =3D NaN;
  },
  lineStart: function() {
    this._x =3D this._y =3D NaN;
    this._point =3D 0;
  },
  lineEnd: function() {
    if (0 < this._t && this._t < 1 && this._point =3D=3D=3D 2) this._contex=
t.lineTo(this._x, this._y);
    if (this._line || (this._line !=3D=3D 0 && this._point =3D=3D=3D 1)) th=
is._context.closePath();
    if (this._line >=3D 0) this._t =3D 1 - this._t, this._line =3D 1 - this=
=2E_line;
  },
  point: function(x, y) {
    x =3D +x, y =3D +y;
    switch (this._point) {
      case 0: this._point =3D 1; this._line ? this._context.lineTo(x, y) : =
this._context.moveTo(x, y); break;
      case 1: this._point =3D 2; // proceed
      default: {
        if (this._t <=3D 0) {
          this._context.lineTo(this._x, y);
          this._context.lineTo(x, y);
        } else {
          var x1 =3D this._x * (1 - this._t) + x * this._t;
          this._context.lineTo(x1, this._y);
          this._context.lineTo(x1, y);
        }
        break;
      }
    }
    this._x =3D x, this._y =3D y;
  }
};

function step(context) {
  return new Step(context, 0.5);
}

function stepBefore(context) {
  return new Step(context, 0);
}

function stepAfter(context) {
  return new Step(context, 1);
}

function none$1(series, order) {
  if (!((n =3D series.length) > 1)) return;
  for (var i =3D 1, j, s0, s1 =3D series[order[0]], n, m =3D s1.length; i <=
 n; ++i) {
    s0 =3D s1, s1 =3D series[order[i]];
    for (j =3D 0; j < m; ++j) {
      s1[j][1] +=3D s1[j][0] =3D isNaN(s0[j][1]) ? s0[j][0] : s0[j][1];
    }
  }
}

function none$2(series) {
  var n =3D series.length, o =3D new Array(n);
  while (--n >=3D 0) o[n] =3D n;
  return o;
}

function stackValue(d, key) {
  return d[key];
}

function stack() {
  var keys =3D constant$b([]),
      order =3D none$2,
      offset =3D none$1,
      value =3D stackValue;

  function stack(data) {
    var kz =3D keys.apply(this, arguments),
        i,
        m =3D data.length,
        n =3D kz.length,
        sz =3D new Array(n),
        oz;

    for (i =3D 0; i < n; ++i) {
      for (var ki =3D kz[i], si =3D sz[i] =3D new Array(m), j =3D 0, sij; j=
 < m; ++j) {
        si[j] =3D sij =3D [0, +value(data[j], ki, j, data)];
        sij.data =3D data[j];
      }
      si.key =3D ki;
    }

    for (i =3D 0, oz =3D order(sz); i < n; ++i) {
      sz[oz[i]].index =3D i;
    }

    offset(sz, oz);
    return sz;
  }

  stack.keys =3D function(_) {
    return arguments.length ? (keys =3D typeof _ =3D=3D=3D "function" ? _ :=
 constant$b(slice$6.call(_)), stack) : keys;
  };

  stack.value =3D function(_) {
    return arguments.length ? (value =3D typeof _ =3D=3D=3D "function" ? _ =
: constant$b(+_), stack) : value;
  };

  stack.order =3D function(_) {
    return arguments.length ? (order =3D _ =3D=3D null ? none$2 : typeof _ =
=3D=3D=3D "function" ? _ : constant$b(slice$6.call(_)), stack) : order;
  };

  stack.offset =3D function(_) {
    return arguments.length ? (offset =3D _ =3D=3D null ? none$1 : _, stack=
) : offset;
  };

  return stack;
}

function expand(series, order) {
  if (!((n =3D series.length) > 0)) return;
  for (var i, n, j =3D 0, m =3D series[0].length, y; j < m; ++j) {
    for (y =3D i =3D 0; i < n; ++i) y +=3D series[i][j][1] || 0;
    if (y) for (i =3D 0; i < n; ++i) series[i][j][1] /=3D y;
  }
  none$1(series, order);
}

function diverging$1(series, order) {
  if (!((n =3D series.length) > 0)) return;
  for (var i, j =3D 0, d, dy, yp, yn, n, m =3D series[order[0]].length; j <=
 m; ++j) {
    for (yp =3D yn =3D 0, i =3D 0; i < n; ++i) {
      if ((dy =3D (d =3D series[order[i]][j])[1] - d[0]) >=3D 0) {
        d[0] =3D yp, d[1] =3D yp +=3D dy;
      } else if (dy < 0) {
        d[1] =3D yn, d[0] =3D yn +=3D dy;
      } else {
        d[0] =3D yp;
      }
    }
  }
}

function silhouette(series, order) {
  if (!((n =3D series.length) > 0)) return;
  for (var j =3D 0, s0 =3D series[order[0]], n, m =3D s0.length; j < m; ++j=
) {
    for (var i =3D 0, y =3D 0; i < n; ++i) y +=3D series[i][j][1] || 0;
    s0[j][1] +=3D s0[j][0] =3D -y / 2;
  }
  none$1(series, order);
}

function wiggle(series, order) {
  if (!((n =3D series.length) > 0) || !((m =3D (s0 =3D series[order[0]]).le=
ngth) > 0)) return;
  for (var y =3D 0, j =3D 1, s0, m, n; j < m; ++j) {
    for (var i =3D 0, s1 =3D 0, s2 =3D 0; i < n; ++i) {
      var si =3D series[order[i]],
          sij0 =3D si[j][1] || 0,
          sij1 =3D si[j - 1][1] || 0,
          s3 =3D (sij0 - sij1) / 2;
      for (var k =3D 0; k < i; ++k) {
        var sk =3D series[order[k]],
            skj0 =3D sk[j][1] || 0,
            skj1 =3D sk[j - 1][1] || 0;
        s3 +=3D skj0 - skj1;
      }
      s1 +=3D sij0, s2 +=3D s3 * sij0;
    }
    s0[j - 1][1] +=3D s0[j - 1][0] =3D y;
    if (s1) y -=3D s2 / s1;
  }
  s0[j - 1][1] +=3D s0[j - 1][0] =3D y;
  none$1(series, order);
}

function appearance(series) {
  var peaks =3D series.map(peak);
  return none$2(series).sort(function(a, b) { return peaks[a] - peaks[b]; }=
);
}

function peak(series) {
  var i =3D -1, j =3D 0, n =3D series.length, vi, vj =3D -Infinity;
  while (++i < n) if ((vi =3D +series[i][1]) > vj) vj =3D vi, j =3D i;
  return j;
}

function ascending$3(series) {
  var sums =3D series.map(sum$2);
  return none$2(series).sort(function(a, b) { return sums[a] - sums[b]; });
}

function sum$2(series) {
  var s =3D 0, i =3D -1, n =3D series.length, v;
  while (++i < n) if (v =3D +series[i][1]) s +=3D v;
  return s;
}

function descending$2(series) {
  return ascending$3(series).reverse();
}

function insideOut(series) {
  var n =3D series.length,
      i,
      j,
      sums =3D series.map(sum$2),
      order =3D appearance(series),
      top =3D 0,
      bottom =3D 0,
      tops =3D [],
      bottoms =3D [];

  for (i =3D 0; i < n; ++i) {
    j =3D order[i];
    if (top < bottom) {
      top +=3D sums[j];
      tops.push(j);
    } else {
      bottom +=3D sums[j];
      bottoms.push(j);
    }
  }

  return bottoms.reverse().concat(tops);
}

function reverse(series) {
  return none$2(series).reverse();
}

function constant$c(x) {
  return function() {
    return x;
  };
}

function x$4(d) {
  return d[0];
}

function y$4(d) {
  return d[1];
}

function RedBlackTree() {
  this._ =3D null; // root node
}

function RedBlackNode(node) {
  node.U =3D // parent node
  node.C =3D // color - true for red, false for black
  node.L =3D // left node
  node.R =3D // right node
  node.P =3D // previous node
  node.N =3D null; // next node
}

RedBlackTree.prototype =3D {
  constructor: RedBlackTree,

  insert: function(after, node) {
    var parent, grandpa, uncle;

    if (after) {
      node.P =3D after;
      node.N =3D after.N;
      if (after.N) after.N.P =3D node;
      after.N =3D node;
      if (after.R) {
        after =3D after.R;
        while (after.L) after =3D after.L;
        after.L =3D node;
      } else {
        after.R =3D node;
      }
      parent =3D after;
    } else if (this._) {
      after =3D RedBlackFirst(this._);
      node.P =3D null;
      node.N =3D after;
      after.P =3D after.L =3D node;
      parent =3D after;
    } else {
      node.P =3D node.N =3D null;
      this._ =3D node;
      parent =3D null;
    }
    node.L =3D node.R =3D null;
    node.U =3D parent;
    node.C =3D true;

    after =3D node;
    while (parent && parent.C) {
      grandpa =3D parent.U;
      if (parent =3D=3D=3D grandpa.L) {
        uncle =3D grandpa.R;
        if (uncle && uncle.C) {
          parent.C =3D uncle.C =3D false;
          grandpa.C =3D true;
          after =3D grandpa;
        } else {
          if (after =3D=3D=3D parent.R) {
            RedBlackRotateLeft(this, parent);
            after =3D parent;
            parent =3D after.U;
          }
          parent.C =3D false;
          grandpa.C =3D true;
          RedBlackRotateRight(this, grandpa);
        }
      } else {
        uncle =3D grandpa.L;
        if (uncle && uncle.C) {
          parent.C =3D uncle.C =3D false;
          grandpa.C =3D true;
          after =3D grandpa;
        } else {
          if (after =3D=3D=3D parent.L) {
            RedBlackRotateRight(this, parent);
            after =3D parent;
            parent =3D after.U;
          }
          parent.C =3D false;
          grandpa.C =3D true;
          RedBlackRotateLeft(this, grandpa);
        }
      }
      parent =3D after.U;
    }
    this._.C =3D false;
  },

  remove: function(node) {
    if (node.N) node.N.P =3D node.P;
    if (node.P) node.P.N =3D node.N;
    node.N =3D node.P =3D null;

    var parent =3D node.U,
        sibling,
        left =3D node.L,
        right =3D node.R,
        next,
        red;

    if (!left) next =3D right;
    else if (!right) next =3D left;
    else next =3D RedBlackFirst(right);

    if (parent) {
      if (parent.L =3D=3D=3D node) parent.L =3D next;
      else parent.R =3D next;
    } else {
      this._ =3D next;
    }

    if (left && right) {
      red =3D next.C;
      next.C =3D node.C;
      next.L =3D left;
      left.U =3D next;
      if (next !=3D=3D right) {
        parent =3D next.U;
        next.U =3D node.U;
        node =3D next.R;
        parent.L =3D node;
        next.R =3D right;
        right.U =3D next;
      } else {
        next.U =3D parent;
        parent =3D next;
        node =3D next.R;
      }
    } else {
      red =3D node.C;
      node =3D next;
    }

    if (node) node.U =3D parent;
    if (red) return;
    if (node && node.C) { node.C =3D false; return; }

    do {
      if (node =3D=3D=3D this._) break;
      if (node =3D=3D=3D parent.L) {
        sibling =3D parent.R;
        if (sibling.C) {
          sibling.C =3D false;
          parent.C =3D true;
          RedBlackRotateLeft(this, parent);
          sibling =3D parent.R;
        }
        if ((sibling.L && sibling.L.C)
            || (sibling.R && sibling.R.C)) {
          if (!sibling.R || !sibling.R.C) {
            sibling.L.C =3D false;
            sibling.C =3D true;
            RedBlackRotateRight(this, sibling);
            sibling =3D parent.R;
          }
          sibling.C =3D parent.C;
          parent.C =3D sibling.R.C =3D false;
          RedBlackRotateLeft(this, parent);
          node =3D this._;
          break;
        }
      } else {
        sibling =3D parent.L;
        if (sibling.C) {
          sibling.C =3D false;
          parent.C =3D true;
          RedBlackRotateRight(this, parent);
          sibling =3D parent.L;
        }
        if ((sibling.L && sibling.L.C)
          || (sibling.R && sibling.R.C)) {
          if (!sibling.L || !sibling.L.C) {
            sibling.R.C =3D false;
            sibling.C =3D true;
            RedBlackRotateLeft(this, sibling);
            sibling =3D parent.L;
          }
          sibling.C =3D parent.C;
          parent.C =3D sibling.L.C =3D false;
          RedBlackRotateRight(this, parent);
          node =3D this._;
          break;
        }
      }
      sibling.C =3D true;
      node =3D parent;
      parent =3D parent.U;
    } while (!node.C);

    if (node) node.C =3D false;
  }
};

function RedBlackRotateLeft(tree, node) {
  var p =3D node,
      q =3D node.R,
      parent =3D p.U;

  if (parent) {
    if (parent.L =3D=3D=3D p) parent.L =3D q;
    else parent.R =3D q;
  } else {
    tree._ =3D q;
  }

  q.U =3D parent;
  p.U =3D q;
  p.R =3D q.L;
  if (p.R) p.R.U =3D p;
  q.L =3D p;
}

function RedBlackRotateRight(tree, node) {
  var p =3D node,
      q =3D node.L,
      parent =3D p.U;

  if (parent) {
    if (parent.L =3D=3D=3D p) parent.L =3D q;
    else parent.R =3D q;
  } else {
    tree._ =3D q;
  }

  q.U =3D parent;
  p.U =3D q;
  p.L =3D q.R;
  if (p.L) p.L.U =3D p;
  q.R =3D p;
}

function RedBlackFirst(node) {
  while (node.L) node =3D node.L;
  return node;
}

function createEdge(left, right, v0, v1) {
  var edge =3D [null, null],
      index =3D edges.push(edge) - 1;
  edge.left =3D left;
  edge.right =3D right;
  if (v0) setEdgeEnd(edge, left, right, v0);
  if (v1) setEdgeEnd(edge, right, left, v1);
  cells[left.index].halfedges.push(index);
  cells[right.index].halfedges.push(index);
  return edge;
}

function createBorderEdge(left, v0, v1) {
  var edge =3D [v0, v1];
  edge.left =3D left;
  return edge;
}

function setEdgeEnd(edge, left, right, vertex) {
  if (!edge[0] && !edge[1]) {
    edge[0] =3D vertex;
    edge.left =3D left;
    edge.right =3D right;
  } else if (edge.left =3D=3D=3D right) {
    edge[1] =3D vertex;
  } else {
    edge[0] =3D vertex;
  }
}

// Liang=E2=80=93Barsky line clipping.
function clipEdge(edge, x0, y0, x1, y1) {
  var a =3D edge[0],
      b =3D edge[1],
      ax =3D a[0],
      ay =3D a[1],
      bx =3D b[0],
      by =3D b[1],
      t0 =3D 0,
      t1 =3D 1,
      dx =3D bx - ax,
      dy =3D by - ay,
      r;

  r =3D x0 - ax;
  if (!dx && r > 0) return;
  r /=3D dx;
  if (dx < 0) {
    if (r < t0) return;
    if (r < t1) t1 =3D r;
  } else if (dx > 0) {
    if (r > t1) return;
    if (r > t0) t0 =3D r;
  }

  r =3D x1 - ax;
  if (!dx && r < 0) return;
  r /=3D dx;
  if (dx < 0) {
    if (r > t1) return;
    if (r > t0) t0 =3D r;
  } else if (dx > 0) {
    if (r < t0) return;
    if (r < t1) t1 =3D r;
  }

  r =3D y0 - ay;
  if (!dy && r > 0) return;
  r /=3D dy;
  if (dy < 0) {
    if (r < t0) return;
    if (r < t1) t1 =3D r;
  } else if (dy > 0) {
    if (r > t1) return;
    if (r > t0) t0 =3D r;
  }

  r =3D y1 - ay;
  if (!dy && r < 0) return;
  r /=3D dy;
  if (dy < 0) {
    if (r > t1) return;
    if (r > t0) t0 =3D r;
  } else if (dy > 0) {
    if (r < t0) return;
    if (r < t1) t1 =3D r;
  }

  if (!(t0 > 0) && !(t1 < 1)) return true; // TODO Better check?

  if (t0 > 0) edge[0] =3D [ax + t0 * dx, ay + t0 * dy];
  if (t1 < 1) edge[1] =3D [ax + t1 * dx, ay + t1 * dy];
  return true;
}

function connectEdge(edge, x0, y0, x1, y1) {
  var v1 =3D edge[1];
  if (v1) return true;

  var v0 =3D edge[0],
      left =3D edge.left,
      right =3D edge.right,
      lx =3D left[0],
      ly =3D left[1],
      rx =3D right[0],
      ry =3D right[1],
      fx =3D (lx + rx) / 2,
      fy =3D (ly + ry) / 2,
      fm,
      fb;

  if (ry =3D=3D=3D ly) {
    if (fx < x0 || fx >=3D x1) return;
    if (lx > rx) {
      if (!v0) v0 =3D [fx, y0];
      else if (v0[1] >=3D y1) return;
      v1 =3D [fx, y1];
    } else {
      if (!v0) v0 =3D [fx, y1];
      else if (v0[1] < y0) return;
      v1 =3D [fx, y0];
    }
  } else {
    fm =3D (lx - rx) / (ry - ly);
    fb =3D fy - fm * fx;
    if (fm < -1 || fm > 1) {
      if (lx > rx) {
        if (!v0) v0 =3D [(y0 - fb) / fm, y0];
        else if (v0[1] >=3D y1) return;
        v1 =3D [(y1 - fb) / fm, y1];
      } else {
        if (!v0) v0 =3D [(y1 - fb) / fm, y1];
        else if (v0[1] < y0) return;
        v1 =3D [(y0 - fb) / fm, y0];
      }
    } else {
      if (ly < ry) {
        if (!v0) v0 =3D [x0, fm * x0 + fb];
        else if (v0[0] >=3D x1) return;
        v1 =3D [x1, fm * x1 + fb];
      } else {
        if (!v0) v0 =3D [x1, fm * x1 + fb];
        else if (v0[0] < x0) return;
        v1 =3D [x0, fm * x0 + fb];
      }
    }
  }

  edge[0] =3D v0;
  edge[1] =3D v1;
  return true;
}

function clipEdges(x0, y0, x1, y1) {
  var i =3D edges.length,
      edge;

  while (i--) {
    if (!connectEdge(edge =3D edges[i], x0, y0, x1, y1)
        || !clipEdge(edge, x0, y0, x1, y1)
        || !(Math.abs(edge[0][0] - edge[1][0]) > epsilon$4
            || Math.abs(edge[0][1] - edge[1][1]) > epsilon$4)) {
      delete edges[i];
    }
  }
}

function createCell(site) {
  return cells[site.index] =3D {
    site: site,
    halfedges: []
  };
}

function cellHalfedgeAngle(cell, edge) {
  var site =3D cell.site,
      va =3D edge.left,
      vb =3D edge.right;
  if (site =3D=3D=3D vb) vb =3D va, va =3D site;
  if (vb) return Math.atan2(vb[1] - va[1], vb[0] - va[0]);
  if (site =3D=3D=3D va) va =3D edge[1], vb =3D edge[0];
  else va =3D edge[0], vb =3D edge[1];
  return Math.atan2(va[0] - vb[0], vb[1] - va[1]);
}

function cellHalfedgeStart(cell, edge) {
  return edge[+(edge.left !=3D=3D cell.site)];
}

function cellHalfedgeEnd(cell, edge) {
  return edge[+(edge.left =3D=3D=3D cell.site)];
}

function sortCellHalfedges() {
  for (var i =3D 0, n =3D cells.length, cell, halfedges, j, m; i < n; ++i) {
    if ((cell =3D cells[i]) && (m =3D (halfedges =3D cell.halfedges).length=
)) {
      var index =3D new Array(m),
          array =3D new Array(m);
      for (j =3D 0; j < m; ++j) index[j] =3D j, array[j] =3D cellHalfedgeAn=
gle(cell, edges[halfedges[j]]);
      index.sort(function(i, j) { return array[j] - array[i]; });
      for (j =3D 0; j < m; ++j) array[j] =3D halfedges[index[j]];
      for (j =3D 0; j < m; ++j) halfedges[j] =3D array[j];
    }
  }
}

function clipCells(x0, y0, x1, y1) {
  var nCells =3D cells.length,
      iCell,
      cell,
      site,
      iHalfedge,
      halfedges,
      nHalfedges,
      start,
      startX,
      startY,
      end,
      endX,
      endY,
      cover =3D true;

  for (iCell =3D 0; iCell < nCells; ++iCell) {
    if (cell =3D cells[iCell]) {
      site =3D cell.site;
      halfedges =3D cell.halfedges;
      iHalfedge =3D halfedges.length;

      // Remove any dangling clipped edges.
      while (iHalfedge--) {
        if (!edges[halfedges[iHalfedge]]) {
          halfedges.splice(iHalfedge, 1);
        }
      }

      // Insert any border edges as necessary.
      iHalfedge =3D 0, nHalfedges =3D halfedges.length;
      while (iHalfedge < nHalfedges) {
        end =3D cellHalfedgeEnd(cell, edges[halfedges[iHalfedge]]), endX =
=3D end[0], endY =3D end[1];
        start =3D cellHalfedgeStart(cell, edges[halfedges[++iHalfedge % nHa=
lfedges]]), startX =3D start[0], startY =3D start[1];
        if (Math.abs(endX - startX) > epsilon$4 || Math.abs(endY - startY) =
> epsilon$4) {
          halfedges.splice(iHalfedge, 0, edges.push(createBorderEdge(site, =
end,
              Math.abs(endX - x0) < epsilon$4 && y1 - endY > epsilon$4 ? [x=
0, Math.abs(startX - x0) < epsilon$4 ? startY : y1]
              : Math.abs(endY - y1) < epsilon$4 && x1 - endX > epsilon$4 ? =
[Math.abs(startY - y1) < epsilon$4 ? startX : x1, y1]
              : Math.abs(endX - x1) < epsilon$4 && endY - y0 > epsilon$4 ? =
[x1, Math.abs(startX - x1) < epsilon$4 ? startY : y0]
              : Math.abs(endY - y0) < epsilon$4 && endX - x0 > epsilon$4 ? =
[Math.abs(startY - y0) < epsilon$4 ? startX : x0, y0]
              : null)) - 1);
          ++nHalfedges;
        }
      }

      if (nHalfedges) cover =3D false;
    }
  }

  // If there weren=E2=80=99t any edges, have the closest site cover the ex=
tent.
  // It doesn=E2=80=99t matter which corner of the extent we measure!
  if (cover) {
    var dx, dy, d2, dc =3D Infinity;

    for (iCell =3D 0, cover =3D null; iCell < nCells; ++iCell) {
      if (cell =3D cells[iCell]) {
        site =3D cell.site;
        dx =3D site[0] - x0;
        dy =3D site[1] - y0;
        d2 =3D dx * dx + dy * dy;
        if (d2 < dc) dc =3D d2, cover =3D cell;
      }
    }

    if (cover) {
      var v00 =3D [x0, y0], v01 =3D [x0, y1], v11 =3D [x1, y1], v10 =3D [x1=
, y0];
      cover.halfedges.push(
        edges.push(createBorderEdge(site =3D cover.site, v00, v01)) - 1,
        edges.push(createBorderEdge(site, v01, v11)) - 1,
        edges.push(createBorderEdge(site, v11, v10)) - 1,
        edges.push(createBorderEdge(site, v10, v00)) - 1
      );
    }
  }

  // Lastly delete any cells with no edges; these were entirely clipped.
  for (iCell =3D 0; iCell < nCells; ++iCell) {
    if (cell =3D cells[iCell]) {
      if (!cell.halfedges.length) {
        delete cells[iCell];
      }
    }
  }
}

var circlePool =3D [];

var firstCircle;

function Circle() {
  RedBlackNode(this);
  this.x =3D
  this.y =3D
  this.arc =3D
  this.site =3D
  this.cy =3D null;
}

function attachCircle(arc) {
  var lArc =3D arc.P,
      rArc =3D arc.N;

  if (!lArc || !rArc) return;

  var lSite =3D lArc.site,
      cSite =3D arc.site,
      rSite =3D rArc.site;

  if (lSite =3D=3D=3D rSite) return;

  var bx =3D cSite[0],
      by =3D cSite[1],
      ax =3D lSite[0] - bx,
      ay =3D lSite[1] - by,
      cx =3D rSite[0] - bx,
      cy =3D rSite[1] - by;

  var d =3D 2 * (ax * cy - ay * cx);
  if (d >=3D -epsilon2$2) return;

  var ha =3D ax * ax + ay * ay,
      hc =3D cx * cx + cy * cy,
      x =3D (cy * ha - ay * hc) / d,
      y =3D (ax * hc - cx * ha) / d;

  var circle =3D circlePool.pop() || new Circle;
  circle.arc =3D arc;
  circle.site =3D cSite;
  circle.x =3D x + bx;
  circle.y =3D (circle.cy =3D y + by) + Math.sqrt(x * x + y * y); // y bott=
om

  arc.circle =3D circle;

  var before =3D null,
      node =3D circles._;

  while (node) {
    if (circle.y < node.y || (circle.y =3D=3D=3D node.y && circle.x <=3D no=
de.x)) {
      if (node.L) node =3D node.L;
      else { before =3D node.P; break; }
    } else {
      if (node.R) node =3D node.R;
      else { before =3D node; break; }
    }
  }

  circles.insert(before, circle);
  if (!before) firstCircle =3D circle;
}

function detachCircle(arc) {
  var circle =3D arc.circle;
  if (circle) {
    if (!circle.P) firstCircle =3D circle.N;
    circles.remove(circle);
    circlePool.push(circle);
    RedBlackNode(circle);
    arc.circle =3D null;
  }
}

var beachPool =3D [];

function Beach() {
  RedBlackNode(this);
  this.edge =3D
  this.site =3D
  this.circle =3D null;
}

function createBeach(site) {
  var beach =3D beachPool.pop() || new Beach;
  beach.site =3D site;
  return beach;
}

function detachBeach(beach) {
  detachCircle(beach);
  beaches.remove(beach);
  beachPool.push(beach);
  RedBlackNode(beach);
}

function removeBeach(beach) {
  var circle =3D beach.circle,
      x =3D circle.x,
      y =3D circle.cy,
      vertex =3D [x, y],
      previous =3D beach.P,
      next =3D beach.N,
      disappearing =3D [beach];

  detachBeach(beach);

  var lArc =3D previous;
  while (lArc.circle
      && Math.abs(x - lArc.circle.x) < epsilon$4
      && Math.abs(y - lArc.circle.cy) < epsilon$4) {
    previous =3D lArc.P;
    disappearing.unshift(lArc);
    detachBeach(lArc);
    lArc =3D previous;
  }

  disappearing.unshift(lArc);
  detachCircle(lArc);

  var rArc =3D next;
  while (rArc.circle
      && Math.abs(x - rArc.circle.x) < epsilon$4
      && Math.abs(y - rArc.circle.cy) < epsilon$4) {
    next =3D rArc.N;
    disappearing.push(rArc);
    detachBeach(rArc);
    rArc =3D next;
  }

  disappearing.push(rArc);
  detachCircle(rArc);

  var nArcs =3D disappearing.length,
      iArc;
  for (iArc =3D 1; iArc < nArcs; ++iArc) {
    rArc =3D disappearing[iArc];
    lArc =3D disappearing[iArc - 1];
    setEdgeEnd(rArc.edge, lArc.site, rArc.site, vertex);
  }

  lArc =3D disappearing[0];
  rArc =3D disappearing[nArcs - 1];
  rArc.edge =3D createEdge(lArc.site, rArc.site, null, vertex);

  attachCircle(lArc);
  attachCircle(rArc);
}

function addBeach(site) {
  var x =3D site[0],
      directrix =3D site[1],
      lArc,
      rArc,
      dxl,
      dxr,
      node =3D beaches._;

  while (node) {
    dxl =3D leftBreakPoint(node, directrix) - x;
    if (dxl > epsilon$4) node =3D node.L; else {
      dxr =3D x - rightBreakPoint(node, directrix);
      if (dxr > epsilon$4) {
        if (!node.R) {
          lArc =3D node;
          break;
        }
        node =3D node.R;
      } else {
        if (dxl > -epsilon$4) {
          lArc =3D node.P;
          rArc =3D node;
        } else if (dxr > -epsilon$4) {
          lArc =3D node;
          rArc =3D node.N;
        } else {
          lArc =3D rArc =3D node;
        }
        break;
      }
    }
  }

  createCell(site);
  var newArc =3D createBeach(site);
  beaches.insert(lArc, newArc);

  if (!lArc && !rArc) return;

  if (lArc =3D=3D=3D rArc) {
    detachCircle(lArc);
    rArc =3D createBeach(lArc.site);
    beaches.insert(newArc, rArc);
    newArc.edge =3D rArc.edge =3D createEdge(lArc.site, newArc.site);
    attachCircle(lArc);
    attachCircle(rArc);
    return;
  }

  if (!rArc) { // && lArc
    newArc.edge =3D createEdge(lArc.site, newArc.site);
    return;
  }

  // else lArc !=3D=3D rArc
  detachCircle(lArc);
  detachCircle(rArc);

  var lSite =3D lArc.site,
      ax =3D lSite[0],
      ay =3D lSite[1],
      bx =3D site[0] - ax,
      by =3D site[1] - ay,
      rSite =3D rArc.site,
      cx =3D rSite[0] - ax,
      cy =3D rSite[1] - ay,
      d =3D 2 * (bx * cy - by * cx),
      hb =3D bx * bx + by * by,
      hc =3D cx * cx + cy * cy,
      vertex =3D [(cy * hb - by * hc) / d + ax, (bx * hc - cx * hb) / d + a=
y];

  setEdgeEnd(rArc.edge, lSite, rSite, vertex);
  newArc.edge =3D createEdge(lSite, site, null, vertex);
  rArc.edge =3D createEdge(site, rSite, null, vertex);
  attachCircle(lArc);
  attachCircle(rArc);
}

function leftBreakPoint(arc, directrix) {
  var site =3D arc.site,
      rfocx =3D site[0],
      rfocy =3D site[1],
      pby2 =3D rfocy - directrix;

  if (!pby2) return rfocx;

  var lArc =3D arc.P;
  if (!lArc) return -Infinity;

  site =3D lArc.site;
  var lfocx =3D site[0],
      lfocy =3D site[1],
      plby2 =3D lfocy - directrix;

  if (!plby2) return lfocx;

  var hl =3D lfocx - rfocx,
      aby2 =3D 1 / pby2 - 1 / plby2,
      b =3D hl / plby2;

  if (aby2) return (-b + Math.sqrt(b * b - 2 * aby2 * (hl * hl / (-2 * plby=
2) - lfocy + plby2 / 2 + rfocy - pby2 / 2))) / aby2 + rfocx;

  return (rfocx + lfocx) / 2;
}

function rightBreakPoint(arc, directrix) {
  var rArc =3D arc.N;
  if (rArc) return leftBreakPoint(rArc, directrix);
  var site =3D arc.site;
  return site[1] =3D=3D=3D directrix ? site[0] : Infinity;
}

var epsilon$4 =3D 1e-6;
var epsilon2$2 =3D 1e-12;
var beaches;
var cells;
var circles;
var edges;

function triangleArea(a, b, c) {
  return (a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1]);
}

function lexicographic(a, b) {
  return b[1] - a[1]
      || b[0] - a[0];
}

function Diagram(sites, extent) {
  var site =3D sites.sort(lexicographic).pop(),
      x,
      y,
      circle;

  edges =3D [];
  cells =3D new Array(sites.length);
  beaches =3D new RedBlackTree;
  circles =3D new RedBlackTree;

  while (true) {
    circle =3D firstCircle;
    if (site && (!circle || site[1] < circle.y || (site[1] =3D=3D=3D circle=
=2Ey && site[0] < circle.x))) {
      if (site[0] !=3D=3D x || site[1] !=3D=3D y) {
        addBeach(site);
        x =3D site[0], y =3D site[1];
      }
      site =3D sites.pop();
    } else if (circle) {
      removeBeach(circle.arc);
    } else {
      break;
    }
  }

  sortCellHalfedges();

  if (extent) {
    var x0 =3D +extent[0][0],
        y0 =3D +extent[0][1],
        x1 =3D +extent[1][0],
        y1 =3D +extent[1][1];
    clipEdges(x0, y0, x1, y1);
    clipCells(x0, y0, x1, y1);
  }

  this.edges =3D edges;
  this.cells =3D cells;

  beaches =3D
  circles =3D
  edges =3D
  cells =3D null;
}

Diagram.prototype =3D {
  constructor: Diagram,

  polygons: function() {
    var edges =3D this.edges;

    return this.cells.map(function(cell) {
      var polygon =3D cell.halfedges.map(function(i) { return cellHalfedgeS=
tart(cell, edges[i]); });
      polygon.data =3D cell.site.data;
      return polygon;
    });
  },

  triangles: function() {
    var triangles =3D [],
        edges =3D this.edges;

    this.cells.forEach(function(cell, i) {
      if (!(m =3D (halfedges =3D cell.halfedges).length)) return;
      var site =3D cell.site,
          halfedges,
          j =3D -1,
          m,
          s0,
          e1 =3D edges[halfedges[m - 1]],
          s1 =3D e1.left =3D=3D=3D site ? e1.right : e1.left;

      while (++j < m) {
        s0 =3D s1;
        e1 =3D edges[halfedges[j]];
        s1 =3D e1.left =3D=3D=3D site ? e1.right : e1.left;
        if (s0 && s1 && i < s0.index && i < s1.index && triangleArea(site, =
s0, s1) < 0) {
          triangles.push([site.data, s0.data, s1.data]);
        }
      }
    });

    return triangles;
  },

  links: function() {
    return this.edges.filter(function(edge) {
      return edge.right;
    }).map(function(edge) {
      return {
        source: edge.left.data,
        target: edge.right.data
      };
    });
  },

  find: function(x, y, radius) {
    var that =3D this, i0, i1 =3D that._found || 0, n =3D that.cells.length=
, cell;

    // Use the previously-found cell, or start with an arbitrary one.
    while (!(cell =3D that.cells[i1])) if (++i1 >=3D n) return null;
    var dx =3D x - cell.site[0], dy =3D y - cell.site[1], d2 =3D dx * dx + =
dy * dy;

    // Traverse the half-edges to find a closer cell, if any.
    do {
      cell =3D that.cells[i0 =3D i1], i1 =3D null;
      cell.halfedges.forEach(function(e) {
        var edge =3D that.edges[e], v =3D edge.left;
        if ((v =3D=3D=3D cell.site || !v) && !(v =3D edge.right)) return;
        var vx =3D x - v[0], vy =3D y - v[1], v2 =3D vx * vx + vy * vy;
        if (v2 < d2) d2 =3D v2, i1 =3D v.index;
      });
    } while (i1 !=3D=3D null);

    that._found =3D i0;

    return radius =3D=3D null || d2 <=3D radius * radius ? cell.site : null;
  }
};

function voronoi() {
  var x$$1 =3D x$4,
      y$$1 =3D y$4,
      extent =3D null;

  function voronoi(data) {
    return new Diagram(data.map(function(d, i) {
      var s =3D [Math.round(x$$1(d, i, data) / epsilon$4) * epsilon$4, Math=
=2Eround(y$$1(d, i, data) / epsilon$4) * epsilon$4];
      s.index =3D i;
      s.data =3D d;
      return s;
    }), extent);
  }

  voronoi.polygons =3D function(data) {
    return voronoi(data).polygons();
  };

  voronoi.links =3D function(data) {
    return voronoi(data).links();
  };

  voronoi.triangles =3D function(data) {
    return voronoi(data).triangles();
  };

  voronoi.x =3D function(_) {
    return arguments.length ? (x$$1 =3D typeof _ =3D=3D=3D "function" ? _ :=
 constant$c(+_), voronoi) : x$$1;
  };

  voronoi.y =3D function(_) {
    return arguments.length ? (y$$1 =3D typeof _ =3D=3D=3D "function" ? _ :=
 constant$c(+_), voronoi) : y$$1;
  };

  voronoi.extent =3D function(_) {
    return arguments.length ? (extent =3D _ =3D=3D null ? null : [[+_[0][0]=
, +_[0][1]], [+_[1][0], +_[1][1]]], voronoi) : extent && [[extent[0][0], ex=
tent[0][1]], [extent[1][0], extent[1][1]]];
  };

  voronoi.size =3D function(_) {
    return arguments.length ? (extent =3D _ =3D=3D null ? null : [[0, 0], [=
+_[0], +_[1]]], voronoi) : extent && [extent[1][0] - extent[0][0], extent[1=
][1] - extent[0][1]];
  };

  return voronoi;
}

function constant$d(x) {
  return function() {
    return x;
  };
}

function ZoomEvent(target, type, transform) {
  this.target =3D target;
  this.type =3D type;
  this.transform =3D transform;
}

function Transform(k, x, y) {
  this.k =3D k;
  this.x =3D x;
  this.y =3D y;
}

Transform.prototype =3D {
  constructor: Transform,
  scale: function(k) {
    return k =3D=3D=3D 1 ? this : new Transform(this.k * k, this.x, this.y);
  },
  translate: function(x, y) {
    return x =3D=3D=3D 0 & y =3D=3D=3D 0 ? this : new Transform(this.k, thi=
s.x + this.k * x, this.y + this.k * y);
  },
  apply: function(point) {
    return [point[0] * this.k + this.x, point[1] * this.k + this.y];
  },
  applyX: function(x) {
    return x * this.k + this.x;
  },
  applyY: function(y) {
    return y * this.k + this.y;
  },
  invert: function(location) {
    return [(location[0] - this.x) / this.k, (location[1] - this.y) / this.=
k];
  },
  invertX: function(x) {
    return (x - this.x) / this.k;
  },
  invertY: function(y) {
    return (y - this.y) / this.k;
  },
  rescaleX: function(x) {
    return x.copy().domain(x.range().map(this.invertX, this).map(x.invert, =
x));
  },
  rescaleY: function(y) {
    return y.copy().domain(y.range().map(this.invertY, this).map(y.invert, =
y));
  },
  toString: function() {
    return "translate(" + this.x + "," + this.y + ") scale(" + this.k + ")";
  }
};

var identity$9 =3D new Transform(1, 0, 0);

transform$1.prototype =3D Transform.prototype;

function transform$1(node) {
  return node.__zoom || identity$9;
}

function nopropagation$2() {
  exports.event.stopImmediatePropagation();
}

function noevent$2() {
  exports.event.preventDefault();
  exports.event.stopImmediatePropagation();
}

// Ignore right-click, since that should open the context menu.
function defaultFilter$2() {
  return !exports.event.button;
}

function defaultExtent$1() {
  var e =3D this, w, h;
  if (e instanceof SVGElement) {
    e =3D e.ownerSVGElement || e;
    w =3D e.width.baseVal.value;
    h =3D e.height.baseVal.value;
  } else {
    w =3D e.clientWidth;
    h =3D e.clientHeight;
  }
  return [[0, 0], [w, h]];
}

function defaultTransform() {
  return this.__zoom || identity$9;
}

function defaultWheelDelta() {
  return -exports.event.deltaY * (exports.event.deltaMode ? 120 : 1) / 500;
}

function defaultTouchable$1() {
  return "ontouchstart" in this;
}

function defaultConstrain(transform, extent, translateExtent) {
  var dx0 =3D transform.invertX(extent[0][0]) - translateExtent[0][0],
      dx1 =3D transform.invertX(extent[1][0]) - translateExtent[1][0],
      dy0 =3D transform.invertY(extent[0][1]) - translateExtent[0][1],
      dy1 =3D transform.invertY(extent[1][1]) - translateExtent[1][1];
  return transform.translate(
    dx1 > dx0 ? (dx0 + dx1) / 2 : Math.min(0, dx0) || Math.max(0, dx1),
    dy1 > dy0 ? (dy0 + dy1) / 2 : Math.min(0, dy0) || Math.max(0, dy1)
  );
}

function zoom() {
  var filter =3D defaultFilter$2,
      extent =3D defaultExtent$1,
      constrain =3D defaultConstrain,
      wheelDelta =3D defaultWheelDelta,
      touchable =3D defaultTouchable$1,
      scaleExtent =3D [0, Infinity],
      translateExtent =3D [[-Infinity, -Infinity], [Infinity, Infinity]],
      duration =3D 250,
      interpolate =3D interpolateZoom,
      gestures =3D [],
      listeners =3D dispatch("start", "zoom", "end"),
      touchstarting,
      touchending,
      touchDelay =3D 500,
      wheelDelay =3D 150,
      clickDistance2 =3D 0;

  function zoom(selection$$1) {
    selection$$1
        .property("__zoom", defaultTransform)
        .on("wheel.zoom", wheeled)
        .on("mousedown.zoom", mousedowned)
        .on("dblclick.zoom", dblclicked)
      .filter(touchable)
        .on("touchstart.zoom", touchstarted)
        .on("touchmove.zoom", touchmoved)
        .on("touchend.zoom touchcancel.zoom", touchended)
        .style("touch-action", "none")
        .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)");
  }

  zoom.transform =3D function(collection, transform) {
    var selection$$1 =3D collection.selection ? collection.selection() : co=
llection;
    selection$$1.property("__zoom", defaultTransform);
    if (collection !=3D=3D selection$$1) {
      schedule(collection, transform);
    } else {
      selection$$1.interrupt().each(function() {
        gesture(this, arguments)
            .start()
            .zoom(null, typeof transform =3D=3D=3D "function" ? transform.a=
pply(this, arguments) : transform)
            .end();
      });
    }
  };

  zoom.scaleBy =3D function(selection$$1, k) {
    zoom.scaleTo(selection$$1, function() {
      var k0 =3D this.__zoom.k,
          k1 =3D typeof k =3D=3D=3D "function" ? k.apply(this, arguments) :=
 k;
      return k0 * k1;
    });
  };

  zoom.scaleTo =3D function(selection$$1, k) {
    zoom.transform(selection$$1, function() {
      var e =3D extent.apply(this, arguments),
          t0 =3D this.__zoom,
          p0 =3D centroid(e),
          p1 =3D t0.invert(p0),
          k1 =3D typeof k =3D=3D=3D "function" ? k.apply(this, arguments) :=
 k;
      return constrain(translate(scale(t0, k1), p0, p1), e, translateExtent=
);
    });
  };

  zoom.translateBy =3D function(selection$$1, x, y) {
    zoom.transform(selection$$1, function() {
      return constrain(this.__zoom.translate(
        typeof x =3D=3D=3D "function" ? x.apply(this, arguments) : x,
        typeof y =3D=3D=3D "function" ? y.apply(this, arguments) : y
      ), extent.apply(this, arguments), translateExtent);
    });
  };

  zoom.translateTo =3D function(selection$$1, x, y) {
    zoom.transform(selection$$1, function() {
      var e =3D extent.apply(this, arguments),
          t =3D this.__zoom,
          p =3D centroid(e);
      return constrain(identity$9.translate(p[0], p[1]).scale(t.k).translat=
e(
        typeof x =3D=3D=3D "function" ? -x.apply(this, arguments) : -x,
        typeof y =3D=3D=3D "function" ? -y.apply(this, arguments) : -y
      ), e, translateExtent);
    });
  };

  function scale(transform, k) {
    k =3D Math.max(scaleExtent[0], Math.min(scaleExtent[1], k));
    return k =3D=3D=3D transform.k ? transform : new Transform(k, transform=
=2Ex, transform.y);
  }

  function translate(transform, p0, p1) {
    var x =3D p0[0] - p1[0] * transform.k, y =3D p0[1] - p1[1] * transform.=
k;
    return x =3D=3D=3D transform.x && y =3D=3D=3D transform.y ? transform :=
 new Transform(transform.k, x, y);
  }

  function centroid(extent) {
    return [(+extent[0][0] + +extent[1][0]) / 2, (+extent[0][1] + +extent[1=
][1]) / 2];
  }

  function schedule(transition$$1, transform, center) {
    transition$$1
        .on("start.zoom", function() { gesture(this, arguments).start(); })
        .on("interrupt.zoom end.zoom", function() { gesture(this, arguments=
).end(); })
        .tween("zoom", function() {
          var that =3D this,
              args =3D arguments,
              g =3D gesture(that, args),
              e =3D extent.apply(that, args),
              p =3D center || centroid(e),
              w =3D Math.max(e[1][0] - e[0][0], e[1][1] - e[0][1]),
              a =3D that.__zoom,
              b =3D typeof transform =3D=3D=3D "function" ? transform.apply=
(that, args) : transform,
              i =3D interpolate(a.invert(p).concat(w / a.k), b.invert(p).co=
ncat(w / b.k));
          return function(t) {
            if (t =3D=3D=3D 1) t =3D b; // Avoid rounding error on end.
            else { var l =3D i(t), k =3D w / l[2]; t =3D new Transform(k, p=
[0] - l[0] * k, p[1] - l[1] * k); }
            g.zoom(null, t);
          };
        });
  }

  function gesture(that, args) {
    for (var i =3D 0, n =3D gestures.length, g; i < n; ++i) {
      if ((g =3D gestures[i]).that =3D=3D=3D that) {
        return g;
      }
    }
    return new Gesture(that, args);
  }

  function Gesture(that, args) {
    this.that =3D that;
    this.args =3D args;
    this.index =3D -1;
    this.active =3D 0;
    this.extent =3D extent.apply(that, args);
  }

  Gesture.prototype =3D {
    start: function() {
      if (++this.active =3D=3D=3D 1) {
        this.index =3D gestures.push(this) - 1;
        this.emit("start");
      }
      return this;
    },
    zoom: function(key, transform) {
      if (this.mouse && key !=3D=3D "mouse") this.mouse[1] =3D transform.in=
vert(this.mouse[0]);
      if (this.touch0 && key !=3D=3D "touch") this.touch0[1] =3D transform.=
invert(this.touch0[0]);
      if (this.touch1 && key !=3D=3D "touch") this.touch1[1] =3D transform.=
invert(this.touch1[0]);
      this.that.__zoom =3D transform;
      this.emit("zoom");
      return this;
    },
    end: function() {
      if (--this.active =3D=3D=3D 0) {
        gestures.splice(this.index, 1);
        this.index =3D -1;
        this.emit("end");
      }
      return this;
    },
    emit: function(type) {
      customEvent(new ZoomEvent(zoom, type, this.that.__zoom), listeners.ap=
ply, listeners, [type, this.that, this.args]);
    }
  };

  function wheeled() {
    if (!filter.apply(this, arguments)) return;
    var g =3D gesture(this, arguments),
        t =3D this.__zoom,
        k =3D Math.max(scaleExtent[0], Math.min(scaleExtent[1], t.k * Math.=
pow(2, wheelDelta.apply(this, arguments)))),
        p =3D mouse(this);

    // If the mouse is in the same location as before, reuse it.
    // If there were recent wheel events, reset the wheel idle timeout.
    if (g.wheel) {
      if (g.mouse[0][0] !=3D=3D p[0] || g.mouse[0][1] !=3D=3D p[1]) {
        g.mouse[1] =3D t.invert(g.mouse[0] =3D p);
      }
      clearTimeout(g.wheel);
    }

    // If this wheel event won=E2=80=99t trigger a transform change, ignore=
 it.
    else if (t.k =3D=3D=3D k) return;

    // Otherwise, capture the mouse point and location at the start.
    else {
      g.mouse =3D [p, t.invert(p)];
      interrupt(this);
      g.start();
    }

    noevent$2();
    g.wheel =3D setTimeout(wheelidled, wheelDelay);
    g.zoom("mouse", constrain(translate(scale(t, k), g.mouse[0], g.mouse[1]=
), g.extent, translateExtent));

    function wheelidled() {
      g.wheel =3D null;
      g.end();
    }
  }

  function mousedowned() {
    if (touchending || !filter.apply(this, arguments)) return;
    var g =3D gesture(this, arguments),
        v =3D select(exports.event.view).on("mousemove.zoom", mousemoved, t=
rue).on("mouseup.zoom", mouseupped, true),
        p =3D mouse(this),
        x0 =3D exports.event.clientX,
        y0 =3D exports.event.clientY;

    dragDisable(exports.event.view);
    nopropagation$2();
    g.mouse =3D [p, this.__zoom.invert(p)];
    interrupt(this);
    g.start();

    function mousemoved() {
      noevent$2();
      if (!g.moved) {
        var dx =3D exports.event.clientX - x0, dy =3D exports.event.clientY=
 - y0;
        g.moved =3D dx * dx + dy * dy > clickDistance2;
      }
      g.zoom("mouse", constrain(translate(g.that.__zoom, g.mouse[0] =3D mou=
se(g.that), g.mouse[1]), g.extent, translateExtent));
    }

    function mouseupped() {
      v.on("mousemove.zoom mouseup.zoom", null);
      yesdrag(exports.event.view, g.moved);
      noevent$2();
      g.end();
    }
  }

  function dblclicked() {
    if (!filter.apply(this, arguments)) return;
    var t0 =3D this.__zoom,
        p0 =3D mouse(this),
        p1 =3D t0.invert(p0),
        k1 =3D t0.k * (exports.event.shiftKey ? 0.5 : 2),
        t1 =3D constrain(translate(scale(t0, k1), p0, p1), extent.apply(thi=
s, arguments), translateExtent);

    noevent$2();
    if (duration > 0) select(this).transition().duration(duration).call(sch=
edule, t1, p0);
    else select(this).call(zoom.transform, t1);
  }

  function touchstarted() {
    if (!filter.apply(this, arguments)) return;
    var g =3D gesture(this, arguments),
        touches$$1 =3D exports.event.changedTouches,
        started,
        n =3D touches$$1.length, i, t, p;

    nopropagation$2();
    for (i =3D 0; i < n; ++i) {
      t =3D touches$$1[i], p =3D touch(this, touches$$1, t.identifier);
      p =3D [p, this.__zoom.invert(p), t.identifier];
      if (!g.touch0) g.touch0 =3D p, started =3D true;
      else if (!g.touch1) g.touch1 =3D p;
    }

    // If this is a dbltap, reroute to the (optional) dblclick.zoom handler.
    if (touchstarting) {
      touchstarting =3D clearTimeout(touchstarting);
      if (!g.touch1) {
        g.end();
        p =3D select(this).on("dblclick.zoom");
        if (p) p.apply(this, arguments);
        return;
      }
    }

    if (started) {
      touchstarting =3D setTimeout(function() { touchstarting =3D null; }, =
touchDelay);
      interrupt(this);
      g.start();
    }
  }

  function touchmoved() {
    var g =3D gesture(this, arguments),
        touches$$1 =3D exports.event.changedTouches,
        n =3D touches$$1.length, i, t, p, l;

    noevent$2();
    if (touchstarting) touchstarting =3D clearTimeout(touchstarting);
    for (i =3D 0; i < n; ++i) {
      t =3D touches$$1[i], p =3D touch(this, touches$$1, t.identifier);
      if (g.touch0 && g.touch0[2] =3D=3D=3D t.identifier) g.touch0[0] =3D p;
      else if (g.touch1 && g.touch1[2] =3D=3D=3D t.identifier) g.touch1[0] =
=3D p;
    }
    t =3D g.that.__zoom;
    if (g.touch1) {
      var p0 =3D g.touch0[0], l0 =3D g.touch0[1],
          p1 =3D g.touch1[0], l1 =3D g.touch1[1],
          dp =3D (dp =3D p1[0] - p0[0]) * dp + (dp =3D p1[1] - p0[1]) * dp,
          dl =3D (dl =3D l1[0] - l0[0]) * dl + (dl =3D l1[1] - l0[1]) * dl;
      t =3D scale(t, Math.sqrt(dp / dl));
      p =3D [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2];
      l =3D [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2];
    }
    else if (g.touch0) p =3D g.touch0[0], l =3D g.touch0[1];
    else return;
    g.zoom("touch", constrain(translate(t, p, l), g.extent, translateExtent=
));
  }

  function touchended() {
    var g =3D gesture(this, arguments),
        touches$$1 =3D exports.event.changedTouches,
        n =3D touches$$1.length, i, t;

    nopropagation$2();
    if (touchending) clearTimeout(touchending);
    touchending =3D setTimeout(function() { touchending =3D null; }, touchD=
elay);
    for (i =3D 0; i < n; ++i) {
      t =3D touches$$1[i];
      if (g.touch0 && g.touch0[2] =3D=3D=3D t.identifier) delete g.touch0;
      else if (g.touch1 && g.touch1[2] =3D=3D=3D t.identifier) delete g.tou=
ch1;
    }
    if (g.touch1 && !g.touch0) g.touch0 =3D g.touch1, delete g.touch1;
    if (g.touch0) g.touch0[1] =3D this.__zoom.invert(g.touch0[0]);
    else g.end();
  }

  zoom.wheelDelta =3D function(_) {
    return arguments.length ? (wheelDelta =3D typeof _ =3D=3D=3D "function"=
 ? _ : constant$d(+_), zoom) : wheelDelta;
  };

  zoom.filter =3D function(_) {
    return arguments.length ? (filter =3D typeof _ =3D=3D=3D "function" ? _=
 : constant$d(!!_), zoom) : filter;
  };

  zoom.touchable =3D function(_) {
    return arguments.length ? (touchable =3D typeof _ =3D=3D=3D "function" =
? _ : constant$d(!!_), zoom) : touchable;
  };

  zoom.extent =3D function(_) {
    return arguments.length ? (extent =3D typeof _ =3D=3D=3D "function" ? _=
 : constant$d([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), zoom) : extent;
  };

  zoom.scaleExtent =3D function(_) {
    return arguments.length ? (scaleExtent[0] =3D +_[0], scaleExtent[1] =3D=
 +_[1], zoom) : [scaleExtent[0], scaleExtent[1]];
  };

  zoom.translateExtent =3D function(_) {
    return arguments.length ? (translateExtent[0][0] =3D +_[0][0], translat=
eExtent[1][0] =3D +_[1][0], translateExtent[0][1] =3D +_[0][1], translateEx=
tent[1][1] =3D +_[1][1], zoom) : [[translateExtent[0][0], translateExtent[0=
][1]], [translateExtent[1][0], translateExtent[1][1]]];
  };

  zoom.constrain =3D function(_) {
    return arguments.length ? (constrain =3D _, zoom) : constrain;
  };

  zoom.duration =3D function(_) {
    return arguments.length ? (duration =3D +_, zoom) : duration;
  };

  zoom.interpolate =3D function(_) {
    return arguments.length ? (interpolate =3D _, zoom) : interpolate;
  };

  zoom.on =3D function() {
    var value =3D listeners.on.apply(listeners, arguments);
    return value =3D=3D=3D listeners ? zoom : value;
  };

  zoom.clickDistance =3D function(_) {
    return arguments.length ? (clickDistance2 =3D (_ =3D +_) * _, zoom) : M=
ath.sqrt(clickDistance2);
  };

  return zoom;
}

exports.version =3D version;
exports.bisect =3D bisectRight;
exports.bisectRight =3D bisectRight;
exports.bisectLeft =3D bisectLeft;
exports.ascending =3D ascending;
exports.bisector =3D bisector;
exports.cross =3D cross;
exports.descending =3D descending;
exports.deviation =3D deviation;
exports.extent =3D extent;
exports.histogram =3D histogram;
exports.thresholdFreedmanDiaconis =3D freedmanDiaconis;
exports.thresholdScott =3D scott;
exports.thresholdSturges =3D thresholdSturges;
exports.max =3D max;
exports.mean =3D mean;
exports.median =3D median;
exports.merge =3D merge;
exports.min =3D min;
exports.pairs =3D pairs;
exports.permute =3D permute;
exports.quantile =3D threshold;
exports.range =3D sequence;
exports.scan =3D scan;
exports.shuffle =3D shuffle;
exports.sum =3D sum;
exports.ticks =3D ticks;
exports.tickIncrement =3D tickIncrement;
exports.tickStep =3D tickStep;
exports.transpose =3D transpose;
exports.variance =3D variance;
exports.zip =3D zip;
exports.axisTop =3D axisTop;
exports.axisRight =3D axisRight;
exports.axisBottom =3D axisBottom;
exports.axisLeft =3D axisLeft;
exports.brush =3D brush;
exports.brushX =3D brushX;
exports.brushY =3D brushY;
exports.brushSelection =3D brushSelection;
exports.chord =3D chord;
exports.ribbon =3D ribbon;
exports.nest =3D nest;
exports.set =3D set$2;
exports.map =3D map$1;
exports.keys =3D keys;
exports.values =3D values;
exports.entries =3D entries;
exports.color =3D color;
exports.rgb =3D rgb;
exports.hsl =3D hsl;
exports.lab =3D lab;
exports.hcl =3D hcl;
exports.lch =3D lch;
exports.gray =3D gray;
exports.cubehelix =3D cubehelix;
exports.contours =3D contours;
exports.contourDensity =3D density;
exports.dispatch =3D dispatch;
exports.drag =3D drag;
exports.dragDisable =3D dragDisable;
exports.dragEnable =3D yesdrag;
exports.dsvFormat =3D dsvFormat;
exports.csvParse =3D csvParse;
exports.csvParseRows =3D csvParseRows;
exports.csvFormat =3D csvFormat;
exports.csvFormatBody =3D csvFormatBody;
exports.csvFormatRows =3D csvFormatRows;
exports.tsvParse =3D tsvParse;
exports.tsvParseRows =3D tsvParseRows;
exports.tsvFormat =3D tsvFormat;
exports.tsvFormatBody =3D tsvFormatBody;
exports.tsvFormatRows =3D tsvFormatRows;
exports.autoType =3D autoType;
exports.easeLinear =3D linear$1;
exports.easeQuad =3D quadInOut;
exports.easeQuadIn =3D quadIn;
exports.easeQuadOut =3D quadOut;
exports.easeQuadInOut =3D quadInOut;
exports.easeCubic =3D cubicInOut;
exports.easeCubicIn =3D cubicIn;
exports.easeCubicOut =3D cubicOut;
exports.easeCubicInOut =3D cubicInOut;
exports.easePoly =3D polyInOut;
exports.easePolyIn =3D polyIn;
exports.easePolyOut =3D polyOut;
exports.easePolyInOut =3D polyInOut;
exports.easeSin =3D sinInOut;
exports.easeSinIn =3D sinIn;
exports.easeSinOut =3D sinOut;
exports.easeSinInOut =3D sinInOut;
exports.easeExp =3D expInOut;
exports.easeExpIn =3D expIn;
exports.easeExpOut =3D expOut;
exports.easeExpInOut =3D expInOut;
exports.easeCircle =3D circleInOut;
exports.easeCircleIn =3D circleIn;
exports.easeCircleOut =3D circleOut;
exports.easeCircleInOut =3D circleInOut;
exports.easeBounce =3D bounceOut;
exports.easeBounceIn =3D bounceIn;
exports.easeBounceOut =3D bounceOut;
exports.easeBounceInOut =3D bounceInOut;
exports.easeBack =3D backInOut;
exports.easeBackIn =3D backIn;
exports.easeBackOut =3D backOut;
exports.easeBackInOut =3D backInOut;
exports.easeElastic =3D elasticOut;
exports.easeElasticIn =3D elasticIn;
exports.easeElasticOut =3D elasticOut;
exports.easeElasticInOut =3D elasticInOut;
exports.blob =3D blob;
exports.buffer =3D buffer;
exports.dsv =3D dsv;
exports.csv =3D csv$1;
exports.tsv =3D tsv$1;
exports.image =3D image;
exports.json =3D json;
exports.text =3D text;
exports.xml =3D xml;
exports.html =3D html;
exports.svg =3D svg;
exports.forceCenter =3D center$1;
exports.forceCollide =3D collide;
exports.forceLink =3D link;
exports.forceManyBody =3D manyBody;
exports.forceRadial =3D radial;
exports.forceSimulation =3D simulation;
exports.forceX =3D x$2;
exports.forceY =3D y$2;
exports.formatDefaultLocale =3D defaultLocale;
exports.formatLocale =3D formatLocale;
exports.formatSpecifier =3D formatSpecifier;
exports.precisionFixed =3D precisionFixed;
exports.precisionPrefix =3D precisionPrefix;
exports.precisionRound =3D precisionRound;
exports.geoArea =3D area$1;
exports.geoBounds =3D bounds;
exports.geoCentroid =3D centroid;
exports.geoCircle =3D circle;
exports.geoClipAntimeridian =3D clipAntimeridian;
exports.geoClipCircle =3D clipCircle;
exports.geoClipExtent =3D extent$1;
exports.geoClipRectangle =3D clipRectangle;
exports.geoContains =3D contains$1;
exports.geoDistance =3D distance;
exports.geoGraticule =3D graticule;
exports.geoGraticule10 =3D graticule10;
exports.geoInterpolate =3D interpolate$1;
exports.geoLength =3D length$1;
exports.geoPath =3D index$1;
exports.geoAlbers =3D albers;
exports.geoAlbersUsa =3D albersUsa;
exports.geoAzimuthalEqualArea =3D azimuthalEqualArea;
exports.geoAzimuthalEqualAreaRaw =3D azimuthalEqualAreaRaw;
exports.geoAzimuthalEquidistant =3D azimuthalEquidistant;
exports.geoAzimuthalEquidistantRaw =3D azimuthalEquidistantRaw;
exports.geoConicConformal =3D conicConformal;
exports.geoConicConformalRaw =3D conicConformalRaw;
exports.geoConicEqualArea =3D conicEqualArea;
exports.geoConicEqualAreaRaw =3D conicEqualAreaRaw;
exports.geoConicEquidistant =3D conicEquidistant;
exports.geoConicEquidistantRaw =3D conicEquidistantRaw;
exports.geoEqualEarth =3D equalEarth;
exports.geoEqualEarthRaw =3D equalEarthRaw;
exports.geoEquirectangular =3D equirectangular;
exports.geoEquirectangularRaw =3D equirectangularRaw;
exports.geoGnomonic =3D gnomonic;
exports.geoGnomonicRaw =3D gnomonicRaw;
exports.geoIdentity =3D identity$5;
exports.geoProjection =3D projection;
exports.geoProjectionMutator =3D projectionMutator;
exports.geoMercator =3D mercator;
exports.geoMercatorRaw =3D mercatorRaw;
exports.geoNaturalEarth1 =3D naturalEarth1;
exports.geoNaturalEarth1Raw =3D naturalEarth1Raw;
exports.geoOrthographic =3D orthographic;
exports.geoOrthographicRaw =3D orthographicRaw;
exports.geoStereographic =3D stereographic;
exports.geoStereographicRaw =3D stereographicRaw;
exports.geoTransverseMercator =3D transverseMercator;
exports.geoTransverseMercatorRaw =3D transverseMercatorRaw;
exports.geoRotation =3D rotation;
exports.geoStream =3D geoStream;
exports.geoTransform =3D transform;
exports.cluster =3D cluster;
exports.hierarchy =3D hierarchy;
exports.pack =3D index$2;
exports.packSiblings =3D siblings;
exports.packEnclose =3D enclose;
exports.partition =3D partition;
exports.stratify =3D stratify;
exports.tree =3D tree;
exports.treemap =3D index$3;
exports.treemapBinary =3D binary;
exports.treemapDice =3D treemapDice;
exports.treemapSlice =3D treemapSlice;
exports.treemapSliceDice =3D sliceDice;
exports.treemapSquarify =3D squarify;
exports.treemapResquarify =3D resquarify;
exports.interpolate =3D interpolateValue;
exports.interpolateArray =3D array$1;
exports.interpolateBasis =3D basis$1;
exports.interpolateBasisClosed =3D basisClosed;
exports.interpolateDate =3D date;
exports.interpolateDiscrete =3D discrete;
exports.interpolateHue =3D hue$1;
exports.interpolateNumber =3D interpolateNumber;
exports.interpolateObject =3D object;
exports.interpolateRound =3D interpolateRound;
exports.interpolateString =3D interpolateString;
exports.interpolateTransformCss =3D interpolateTransformCss;
exports.interpolateTransformSvg =3D interpolateTransformSvg;
exports.interpolateZoom =3D interpolateZoom;
exports.interpolateRgb =3D interpolateRgb;
exports.interpolateRgbBasis =3D rgbBasis;
exports.interpolateRgbBasisClosed =3D rgbBasisClosed;
exports.interpolateHsl =3D hsl$2;
exports.interpolateHslLong =3D hslLong;
exports.interpolateLab =3D lab$1;
exports.interpolateHcl =3D hcl$2;
exports.interpolateHclLong =3D hclLong;
exports.interpolateCubehelix =3D cubehelix$2;
exports.interpolateCubehelixLong =3D cubehelixLong;
exports.piecewise =3D piecewise;
exports.quantize =3D quantize;
exports.path =3D path;
exports.polygonArea =3D area$2;
exports.polygonCentroid =3D centroid$1;
exports.polygonHull =3D hull;
exports.polygonContains =3D contains$2;
exports.polygonLength =3D length$2;
exports.quadtree =3D quadtree;
exports.randomUniform =3D uniform;
exports.randomNormal =3D normal;
exports.randomLogNormal =3D logNormal;
exports.randomBates =3D bates;
exports.randomIrwinHall =3D irwinHall;
exports.randomExponential =3D exponential$1;
exports.scaleBand =3D band;
exports.scalePoint =3D point$1;
exports.scaleIdentity =3D identity$7;
exports.scaleLinear =3D linear$2;
exports.scaleLog =3D log$1;
exports.scaleSymlog =3D symlog;
exports.scaleOrdinal =3D ordinal;
exports.scaleImplicit =3D implicit;
exports.scalePow =3D pow$1;
exports.scaleSqrt =3D sqrt$1;
exports.scaleQuantile =3D quantile$$1;
exports.scaleQuantize =3D quantize$1;
exports.scaleThreshold =3D threshold$1;
exports.scaleTime =3D time;
exports.scaleUtc =3D utcTime;
exports.scaleSequential =3D sequential;
exports.scaleSequentialLog =3D sequentialLog;
exports.scaleSequentialPow =3D sequentialPow;
exports.scaleSequentialSqrt =3D sequentialSqrt;
exports.scaleSequentialSymlog =3D sequentialSymlog;
exports.scaleSequentialQuantile =3D sequentialQuantile;
exports.scaleDiverging =3D diverging;
exports.scaleDivergingLog =3D divergingLog;
exports.scaleDivergingPow =3D divergingPow;
exports.scaleDivergingSqrt =3D divergingSqrt;
exports.scaleDivergingSymlog =3D divergingSymlog;
exports.tickFormat =3D tickFormat;
exports.schemeCategory10 =3D category10;
exports.schemeAccent =3D Accent;
exports.schemeDark2 =3D Dark2;
exports.schemePaired =3D Paired;
exports.schemePastel1 =3D Pastel1;
exports.schemePastel2 =3D Pastel2;
exports.schemeSet1 =3D Set1;
exports.schemeSet2 =3D Set2;
exports.schemeSet3 =3D Set3;
exports.interpolateBrBG =3D BrBG;
exports.schemeBrBG =3D scheme;
exports.interpolatePRGn =3D PRGn;
exports.schemePRGn =3D scheme$1;
exports.interpolatePiYG =3D PiYG;
exports.schemePiYG =3D scheme$2;
exports.interpolatePuOr =3D PuOr;
exports.schemePuOr =3D scheme$3;
exports.interpolateRdBu =3D RdBu;
exports.schemeRdBu =3D scheme$4;
exports.interpolateRdGy =3D RdGy;
exports.schemeRdGy =3D scheme$5;
exports.interpolateRdYlBu =3D RdYlBu;
exports.schemeRdYlBu =3D scheme$6;
exports.interpolateRdYlGn =3D RdYlGn;
exports.schemeRdYlGn =3D scheme$7;
exports.interpolateSpectral =3D Spectral;
exports.schemeSpectral =3D scheme$8;
exports.interpolateBuGn =3D BuGn;
exports.schemeBuGn =3D scheme$9;
exports.interpolateBuPu =3D BuPu;
exports.schemeBuPu =3D scheme$a;
exports.interpolateGnBu =3D GnBu;
exports.schemeGnBu =3D scheme$b;
exports.interpolateOrRd =3D OrRd;
exports.schemeOrRd =3D scheme$c;
exports.interpolatePuBuGn =3D PuBuGn;
exports.schemePuBuGn =3D scheme$d;
exports.interpolatePuBu =3D PuBu;
exports.schemePuBu =3D scheme$e;
exports.interpolatePuRd =3D PuRd;
exports.schemePuRd =3D scheme$f;
exports.interpolateRdPu =3D RdPu;
exports.schemeRdPu =3D scheme$g;
exports.interpolateYlGnBu =3D YlGnBu;
exports.schemeYlGnBu =3D scheme$h;
exports.interpolateYlGn =3D YlGn;
exports.schemeYlGn =3D scheme$i;
exports.interpolateYlOrBr =3D YlOrBr;
exports.schemeYlOrBr =3D scheme$j;
exports.interpolateYlOrRd =3D YlOrRd;
exports.schemeYlOrRd =3D scheme$k;
exports.interpolateBlues =3D Blues;
exports.schemeBlues =3D scheme$l;
exports.interpolateGreens =3D Greens;
exports.schemeGreens =3D scheme$m;
exports.interpolateGreys =3D Greys;
exports.schemeGreys =3D scheme$n;
exports.interpolatePurples =3D Purples;
exports.schemePurples =3D scheme$o;
exports.interpolateReds =3D Reds;
exports.schemeReds =3D scheme$p;
exports.interpolateOranges =3D Oranges;
exports.schemeOranges =3D scheme$q;
exports.interpolateCubehelixDefault =3D cubehelix$3;
exports.interpolateRainbow =3D rainbow;
exports.interpolateWarm =3D warm;
exports.interpolateCool =3D cool;
exports.interpolateSinebow =3D sinebow;
exports.interpolateViridis =3D viridis;
exports.interpolateMagma =3D magma;
exports.interpolateInferno =3D inferno;
exports.interpolatePlasma =3D plasma;
exports.create =3D create;
exports.creator =3D creator;
exports.local =3D local;
exports.matcher =3D matcher;
exports.mouse =3D mouse;
exports.namespace =3D namespace;
exports.namespaces =3D namespaces;
exports.clientPoint =3D point;
exports.select =3D select;
exports.selectAll =3D selectAll;
exports.selection =3D selection;
exports.selector =3D selector;
exports.selectorAll =3D selectorAll;
exports.style =3D styleValue;
exports.touch =3D touch;
exports.touches =3D touches;
exports.window =3D defaultView;
exports.customEvent =3D customEvent;
exports.arc =3D arc;
exports.area =3D area$3;
exports.line =3D line;
exports.pie =3D pie;
exports.areaRadial =3D areaRadial;
exports.radialArea =3D areaRadial;
exports.lineRadial =3D lineRadial$1;
exports.radialLine =3D lineRadial$1;
exports.pointRadial =3D pointRadial;
exports.linkHorizontal =3D linkHorizontal;
exports.linkVertical =3D linkVertical;
exports.linkRadial =3D linkRadial;
exports.symbol =3D symbol;
exports.symbols =3D symbols;
exports.symbolCircle =3D circle$2;
exports.symbolCross =3D cross$2;
exports.symbolDiamond =3D diamond;
exports.symbolSquare =3D square;
exports.symbolStar =3D star;
exports.symbolTriangle =3D triangle;
exports.symbolWye =3D wye;
exports.curveBasisClosed =3D basisClosed$1;
exports.curveBasisOpen =3D basisOpen;
exports.curveBasis =3D basis$2;
exports.curveBundle =3D bundle;
exports.curveCardinalClosed =3D cardinalClosed;
exports.curveCardinalOpen =3D cardinalOpen;
exports.curveCardinal =3D cardinal;
exports.curveCatmullRomClosed =3D catmullRomClosed;
exports.curveCatmullRomOpen =3D catmullRomOpen;
exports.curveCatmullRom =3D catmullRom;
exports.curveLinearClosed =3D linearClosed;
exports.curveLinear =3D curveLinear;
exports.curveMonotoneX =3D monotoneX;
exports.curveMonotoneY =3D monotoneY;
exports.curveNatural =3D natural;
exports.curveStep =3D step;
exports.curveStepAfter =3D stepAfter;
exports.curveStepBefore =3D stepBefore;
exports.stack =3D stack;
exports.stackOffsetExpand =3D expand;
exports.stackOffsetDiverging =3D diverging$1;
exports.stackOffsetNone =3D none$1;
exports.stackOffsetSilhouette =3D silhouette;
exports.stackOffsetWiggle =3D wiggle;
exports.stackOrderAppearance =3D appearance;
exports.stackOrderAscending =3D ascending$3;
exports.stackOrderDescending =3D descending$2;
exports.stackOrderInsideOut =3D insideOut;
exports.stackOrderNone =3D none$2;
exports.stackOrderReverse =3D reverse;
exports.timeInterval =3D newInterval;
exports.timeMillisecond =3D millisecond;
exports.timeMilliseconds =3D milliseconds;
exports.utcMillisecond =3D millisecond;
exports.utcMilliseconds =3D milliseconds;
exports.timeSecond =3D second;
exports.timeSeconds =3D seconds;
exports.utcSecond =3D second;
exports.utcSeconds =3D seconds;
exports.timeMinute =3D minute;
exports.timeMinutes =3D minutes;
exports.timeHour =3D hour;
exports.timeHours =3D hours;
exports.timeDay =3D day;
exports.timeDays =3D days;
exports.timeWeek =3D sunday;
exports.timeWeeks =3D sundays;
exports.timeSunday =3D sunday;
exports.timeSundays =3D sundays;
exports.timeMonday =3D monday;
exports.timeMondays =3D mondays;
exports.timeTuesday =3D tuesday;
exports.timeTuesdays =3D tuesdays;
exports.timeWednesday =3D wednesday;
exports.timeWednesdays =3D wednesdays;
exports.timeThursday =3D thursday;
exports.timeThursdays =3D thursdays;
exports.timeFriday =3D friday;
exports.timeFridays =3D fridays;
exports.timeSaturday =3D saturday;
exports.timeSaturdays =3D saturdays;
exports.timeMonth =3D month;
exports.timeMonths =3D months;
exports.timeYear =3D year;
exports.timeYears =3D years;
exports.utcMinute =3D utcMinute;
exports.utcMinutes =3D utcMinutes;
exports.utcHour =3D utcHour;
exports.utcHours =3D utcHours;
exports.utcDay =3D utcDay;
exports.utcDays =3D utcDays;
exports.utcWeek =3D utcSunday;
exports.utcWeeks =3D utcSundays;
exports.utcSunday =3D utcSunday;
exports.utcSundays =3D utcSundays;
exports.utcMonday =3D utcMonday;
exports.utcMondays =3D utcMondays;
exports.utcTuesday =3D utcTuesday;
exports.utcTuesdays =3D utcTuesdays;
exports.utcWednesday =3D utcWednesday;
exports.utcWednesdays =3D utcWednesdays;
exports.utcThursday =3D utcThursday;
exports.utcThursdays =3D utcThursdays;
exports.utcFriday =3D utcFriday;
exports.utcFridays =3D utcFridays;
exports.utcSaturday =3D utcSaturday;
exports.utcSaturdays =3D utcSaturdays;
exports.utcMonth =3D utcMonth;
exports.utcMonths =3D utcMonths;
exports.utcYear =3D utcYear;
exports.utcYears =3D utcYears;
exports.timeFormatDefaultLocale =3D defaultLocale$1;
exports.timeFormatLocale =3D formatLocale$1;
exports.isoFormat =3D formatIso;
exports.isoParse =3D parseIso;
exports.now =3D now;
exports.timer =3D timer;
exports.timerFlush =3D timerFlush;
exports.timeout =3D timeout$1;
exports.interval =3D interval$1;
exports.transition =3D transition;
exports.active =3D active;
exports.interrupt =3D interrupt;
exports.voronoi =3D voronoi;
exports.zoom =3D zoom;
exports.zoomTransform =3D transform$1;
exports.zoomIdentity =3D identity$9;

Object.defineProperty(exports, '__esModule', { value: true });

})));

--kLqR5wKUBEbm+NQl--

--Ax9lNzlugw8JBjpt
Content-Type: application/pgp-signature; name="signature.asc"

-----BEGIN PGP SIGNATURE-----

iQIzBAABCAAdFiEEsFFZSPHn08G5gDigJkb6MLrKfwgFAmAmxZ4ACgkQJkb6MLrK
fwhbohAA4NjAlfe+EHYyDBkUs3qD+7YuiivhEK3jXbkcGVE6i8KK4OHtN0PXReaM
1f7jIJ7iMbpFMMCsUkbacH8RM1Cq9PspPNhEPiSTTygjN3qXmQCsHtKLQoBaq53t
j5LGwJwRUlcunNfU6fjhiMQWpLMkfBxjtJYLcFLgc65AuBkqqk8A3uHx+4b8pem7
tMP23MKYrVtO1dSldjuAUz9KGPvl69B6kL++im56czeYt3Bqn7/ru4i3a5R9nmKt
qDODodenxt9FLq+C/r5ubdrENeVAiXyTvDxTfhP7iqUknIxhod6f9l+heiisBLLW
RFl87j/KDMQCgwtecs8OKPK2qkYK0K06j/LeuDy8zEPua/R2HDp/aMFbs//Mg5ZJ
Xc/bcbYlfbirxsgAZYk7VWlDP4y5eaI5OJyLCstHfwvgUZhU1DVLT5TVVp4yEf9O
SZeIuCcSTZkaNOrpNMsC+JidqiKtZZvHZSr11CsNgGumTVtJiNe1SAYRYD1Ap+bD
Ja5MFtR4EtEkU5eUvxUBOs6qamdRb4KGTBpZlWrHoOfKRtp6Vojd0mpZCRsKfy2l
wbe2K/2xdJ3V7yVb9AYn7cQUgt7tUZfbhvoFD6bJwOthseSvalvmyrnrSiTUl9mz
SN67DQstbOJLBI6GrJTD2M6IUuzZkMF5v7JNbdqEU7lS2F4aIfk=
=PCKV
-----END PGP SIGNATURE-----

--Ax9lNzlugw8JBjpt--




Information forwarded to bug-guix@HIDDEN:
bug#46456; Package guix. Full text available.

Message received at submit <at> debbugs.gnu.org:


Received: (at submit) by debbugs.gnu.org; 12 Feb 2021 03:53:29 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Thu Feb 11 22:53:29 2021
Received: from localhost ([127.0.0.1]:59704 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1lAPWL-0007i3-DD
	for submit <at> debbugs.gnu.org; Thu, 11 Feb 2021 22:53:29 -0500
Received: from lists.gnu.org ([209.51.188.17]:35164)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <dannym@HIDDEN>) id 1lAPWJ-0007hw-JK
 for submit <at> debbugs.gnu.org; Thu, 11 Feb 2021 22:53:27 -0500
Received: from eggs.gnu.org ([2001:470:142:3::10]:60488)
 by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.90_1) (envelope-from <dannym@HIDDEN>)
 id 1lAPWJ-0003P4-7E
 for bug-guix@HIDDEN; Thu, 11 Feb 2021 22:53:27 -0500
Received: from dd26836.kasserver.com ([85.13.145.193]:53900)
 by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.90_1) (envelope-from <dannym@HIDDEN>)
 id 1lAPWF-0003YZ-4v
 for bug-guix@HIDDEN; Thu, 11 Feb 2021 22:53:26 -0500
Received: from localhost (80-110-127-104.cgn.dynamic.surfer.at
 [80.110.127.104])
 by dd26836.kasserver.com (Postfix) with ESMTPSA id 8724D3363970
 for <bug-guix@HIDDEN>; Fri, 12 Feb 2021 04:53:19 +0100 (CET)
Date: Fri, 12 Feb 2021 04:53:15 +0100
From: Danny Milosavljevic <dannym@HIDDEN>
To: <bug-guix@HIDDEN>
Subject: [core-updates] d3.v5.js source checksum changed
Message-ID: <20210212045315.3f4e0a82@HIDDEN>
X-Mailer: Claws Mail 3.17.8 (GTK+ 2.24.32; x86_64-pc-linux-gnu)
MIME-Version: 1.0
Content-Type: multipart/signed; boundary="Sig_/ahh=buR+DkTF93fKWPzRP2H";
 protocol="application/pgp-signature"; micalg=pgp-sha512
Received-SPF: none client-ip=85.13.145.193;
 envelope-from=dannym@HIDDEN; helo=dd26836.kasserver.com
X-Spam_score_int: -25
X-Spam_score: -2.6
X-Spam_bar: --
X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_LOW=-0.7,
 SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no
X-Spam_action: no action
X-Debbugs-Envelope-To: submit
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>

--Sig_/ahh=buR+DkTF93fKWPzRP2H
Content-Type: multipart/mixed; boundary="MP_/huV/jc.jjRG1tiqg+FFlax7"

--MP_/huV/jc.jjRG1tiqg+FFlax7
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Starting download of /gnu/store/bf496ni94ik19gdxkgp0vddkfxbid2vf-d3.v5.js
=46rom https://d3js.org/d3.v5.js...
downloading from https://d3js.org/d3.v5.js ...
 d3.v5.js                                                                  =
                                                2.22GiB/s 00:00 | 504KiB tr=
ansferred
sha256 hash mismatch for /gnu/store/bf496ni94ik19gdxkgp0vddkfxbid2vf-d3.v5.=
js:
  expected hash: 0kxvx5pfagxn6nhavdwsdnzyd26g0z5dsfi1pi5dvcmb0c8ipcdn
  actual hash:   177ypw6mjrp2ch9lj6znibwacwrvm4ypjxflsxsnl2sigx5dcwic
hash mismatch for store item '/gnu/store/bf496ni94ik19gdxkgp0vddkfxbid2vf-d=
3.v5.js'
build of /gnu/store/wqv41s7q5hxmx1am1000nm66rgkbljz0-d3.v5.js.drv failed
View build log at '/var/log/guix/drvs/wq/v41s7q5hxmx1am1000nm66rgkbljz0-d3.=
v5.js.drv.bz2'.
building /gnu/store/7adynsyb7524qxkjxymyysva7dlslbvm-d3Network_0.5.2.1.tar.=
gz.drv...
cannot build derivation `/gnu/store/ahvcirzbb60xxy1mk1dk1shp2yfghcyy-r-d3r-=
0.9.1.drv': 1 dependencies couldn't be built

Attached is the file I got.

--MP_/huV/jc.jjRG1tiqg+FFlax7
Content-Type: application/javascript
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
 filename=bf496ni94ik19gdxkgp0vddkfxbid2vf-d3.v5.js

Ly8gaHR0cHM6Ly9kM2pzLm9yZyB2NS4xNi4wIENvcHlyaWdodCAyMDIwIE1pa2UgQm9zdG9jawoo
ZnVuY3Rpb24gKGdsb2JhbCwgZmFjdG9yeSkgewp0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcg
JiYgdHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgPyBmYWN0b3J5KGV4cG9ydHMpIDoKdHlw
ZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kID8gZGVmaW5lKFsnZXhwb3J0
cyddLCBmYWN0b3J5KSA6CihnbG9iYWwgPSBnbG9iYWwgfHwgc2VsZiwgZmFjdG9yeShnbG9iYWwu
ZDMgPSBnbG9iYWwuZDMgfHwge30pKTsKfSh0aGlzLCBmdW5jdGlvbiAoZXhwb3J0cykgeyAndXNl
IHN0cmljdCc7Cgp2YXIgdmVyc2lvbiA9ICI1LjE2LjAiOwoKZnVuY3Rpb24gYXNjZW5kaW5nKGEs
IGIpIHsKICByZXR1cm4gYSA8IGIgPyAtMSA6IGEgPiBiID8gMSA6IGEgPj0gYiA/IDAgOiBOYU47
Cn0KCmZ1bmN0aW9uIGJpc2VjdG9yKGNvbXBhcmUpIHsKICBpZiAoY29tcGFyZS5sZW5ndGggPT09
IDEpIGNvbXBhcmUgPSBhc2NlbmRpbmdDb21wYXJhdG9yKGNvbXBhcmUpOwogIHJldHVybiB7CiAg
ICBsZWZ0OiBmdW5jdGlvbihhLCB4LCBsbywgaGkpIHsKICAgICAgaWYgKGxvID09IG51bGwpIGxv
ID0gMDsKICAgICAgaWYgKGhpID09IG51bGwpIGhpID0gYS5sZW5ndGg7CiAgICAgIHdoaWxlIChs
byA8IGhpKSB7CiAgICAgICAgdmFyIG1pZCA9IGxvICsgaGkgPj4+IDE7CiAgICAgICAgaWYgKGNv
bXBhcmUoYVttaWRdLCB4KSA8IDApIGxvID0gbWlkICsgMTsKICAgICAgICBlbHNlIGhpID0gbWlk
OwogICAgICB9CiAgICAgIHJldHVybiBsbzsKICAgIH0sCiAgICByaWdodDogZnVuY3Rpb24oYSwg
eCwgbG8sIGhpKSB7CiAgICAgIGlmIChsbyA9PSBudWxsKSBsbyA9IDA7CiAgICAgIGlmIChoaSA9
PSBudWxsKSBoaSA9IGEubGVuZ3RoOwogICAgICB3aGlsZSAobG8gPCBoaSkgewogICAgICAgIHZh
ciBtaWQgPSBsbyArIGhpID4+PiAxOwogICAgICAgIGlmIChjb21wYXJlKGFbbWlkXSwgeCkgPiAw
KSBoaSA9IG1pZDsKICAgICAgICBlbHNlIGxvID0gbWlkICsgMTsKICAgICAgfQogICAgICByZXR1
cm4gbG87CiAgICB9CiAgfTsKfQoKZnVuY3Rpb24gYXNjZW5kaW5nQ29tcGFyYXRvcihmKSB7CiAg
cmV0dXJuIGZ1bmN0aW9uKGQsIHgpIHsKICAgIHJldHVybiBhc2NlbmRpbmcoZihkKSwgeCk7CiAg
fTsKfQoKdmFyIGFzY2VuZGluZ0Jpc2VjdCA9IGJpc2VjdG9yKGFzY2VuZGluZyk7CnZhciBiaXNl
Y3RSaWdodCA9IGFzY2VuZGluZ0Jpc2VjdC5yaWdodDsKdmFyIGJpc2VjdExlZnQgPSBhc2NlbmRp
bmdCaXNlY3QubGVmdDsKCmZ1bmN0aW9uIHBhaXJzKGFycmF5LCBmKSB7CiAgaWYgKGYgPT0gbnVs
bCkgZiA9IHBhaXI7CiAgdmFyIGkgPSAwLCBuID0gYXJyYXkubGVuZ3RoIC0gMSwgcCA9IGFycmF5
WzBdLCBwYWlycyA9IG5ldyBBcnJheShuIDwgMCA/IDAgOiBuKTsKICB3aGlsZSAoaSA8IG4pIHBh
aXJzW2ldID0gZihwLCBwID0gYXJyYXlbKytpXSk7CiAgcmV0dXJuIHBhaXJzOwp9CgpmdW5jdGlv
biBwYWlyKGEsIGIpIHsKICByZXR1cm4gW2EsIGJdOwp9CgpmdW5jdGlvbiBjcm9zcyh2YWx1ZXMw
LCB2YWx1ZXMxLCByZWR1Y2UpIHsKICB2YXIgbjAgPSB2YWx1ZXMwLmxlbmd0aCwKICAgICAgbjEg
PSB2YWx1ZXMxLmxlbmd0aCwKICAgICAgdmFsdWVzID0gbmV3IEFycmF5KG4wICogbjEpLAogICAg
ICBpMCwKICAgICAgaTEsCiAgICAgIGksCiAgICAgIHZhbHVlMDsKCiAgaWYgKHJlZHVjZSA9PSBu
dWxsKSByZWR1Y2UgPSBwYWlyOwoKICBmb3IgKGkwID0gaSA9IDA7IGkwIDwgbjA7ICsraTApIHsK
ICAgIGZvciAodmFsdWUwID0gdmFsdWVzMFtpMF0sIGkxID0gMDsgaTEgPCBuMTsgKytpMSwgKytp
KSB7CiAgICAgIHZhbHVlc1tpXSA9IHJlZHVjZSh2YWx1ZTAsIHZhbHVlczFbaTFdKTsKICAgIH0K
ICB9CgogIHJldHVybiB2YWx1ZXM7Cn0KCmZ1bmN0aW9uIGRlc2NlbmRpbmcoYSwgYikgewogIHJl
dHVybiBiIDwgYSA/IC0xIDogYiA+IGEgPyAxIDogYiA+PSBhID8gMCA6IE5hTjsKfQoKZnVuY3Rp
b24gbnVtYmVyKHgpIHsKICByZXR1cm4geCA9PT0gbnVsbCA/IE5hTiA6ICt4Owp9CgpmdW5jdGlv
biB2YXJpYW5jZSh2YWx1ZXMsIHZhbHVlb2YpIHsKICB2YXIgbiA9IHZhbHVlcy5sZW5ndGgsCiAg
ICAgIG0gPSAwLAogICAgICBpID0gLTEsCiAgICAgIG1lYW4gPSAwLAogICAgICB2YWx1ZSwKICAg
ICAgZGVsdGEsCiAgICAgIHN1bSA9IDA7CgogIGlmICh2YWx1ZW9mID09IG51bGwpIHsKICAgIHdo
aWxlICgrK2kgPCBuKSB7CiAgICAgIGlmICghaXNOYU4odmFsdWUgPSBudW1iZXIodmFsdWVzW2ld
KSkpIHsKICAgICAgICBkZWx0YSA9IHZhbHVlIC0gbWVhbjsKICAgICAgICBtZWFuICs9IGRlbHRh
IC8gKyttOwogICAgICAgIHN1bSArPSBkZWx0YSAqICh2YWx1ZSAtIG1lYW4pOwogICAgICB9CiAg
ICB9CiAgfQoKICBlbHNlIHsKICAgIHdoaWxlICgrK2kgPCBuKSB7CiAgICAgIGlmICghaXNOYU4o
dmFsdWUgPSBudW1iZXIodmFsdWVvZih2YWx1ZXNbaV0sIGksIHZhbHVlcykpKSkgewogICAgICAg
IGRlbHRhID0gdmFsdWUgLSBtZWFuOwogICAgICAgIG1lYW4gKz0gZGVsdGEgLyArK207CiAgICAg
ICAgc3VtICs9IGRlbHRhICogKHZhbHVlIC0gbWVhbik7CiAgICAgIH0KICAgIH0KICB9CgogIGlm
IChtID4gMSkgcmV0dXJuIHN1bSAvIChtIC0gMSk7Cn0KCmZ1bmN0aW9uIGRldmlhdGlvbihhcnJh
eSwgZikgewogIHZhciB2ID0gdmFyaWFuY2UoYXJyYXksIGYpOwogIHJldHVybiB2ID8gTWF0aC5z
cXJ0KHYpIDogdjsKfQoKZnVuY3Rpb24gZXh0ZW50KHZhbHVlcywgdmFsdWVvZikgewogIHZhciBu
ID0gdmFsdWVzLmxlbmd0aCwKICAgICAgaSA9IC0xLAogICAgICB2YWx1ZSwKICAgICAgbWluLAog
ICAgICBtYXg7CgogIGlmICh2YWx1ZW9mID09IG51bGwpIHsKICAgIHdoaWxlICgrK2kgPCBuKSB7
IC8vIEZpbmQgdGhlIGZpcnN0IGNvbXBhcmFibGUgdmFsdWUuCiAgICAgIGlmICgodmFsdWUgPSB2
YWx1ZXNbaV0pICE9IG51bGwgJiYgdmFsdWUgPj0gdmFsdWUpIHsKICAgICAgICBtaW4gPSBtYXgg
PSB2YWx1ZTsKICAgICAgICB3aGlsZSAoKytpIDwgbikgeyAvLyBDb21wYXJlIHRoZSByZW1haW5p
bmcgdmFsdWVzLgogICAgICAgICAgaWYgKCh2YWx1ZSA9IHZhbHVlc1tpXSkgIT0gbnVsbCkgewog
ICAgICAgICAgICBpZiAobWluID4gdmFsdWUpIG1pbiA9IHZhbHVlOwogICAgICAgICAgICBpZiAo
bWF4IDwgdmFsdWUpIG1heCA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQog
ICAgfQogIH0KCiAgZWxzZSB7CiAgICB3aGlsZSAoKytpIDwgbikgeyAvLyBGaW5kIHRoZSBmaXJz
dCBjb21wYXJhYmxlIHZhbHVlLgogICAgICBpZiAoKHZhbHVlID0gdmFsdWVvZih2YWx1ZXNbaV0s
IGksIHZhbHVlcykpICE9IG51bGwgJiYgdmFsdWUgPj0gdmFsdWUpIHsKICAgICAgICBtaW4gPSBt
YXggPSB2YWx1ZTsKICAgICAgICB3aGlsZSAoKytpIDwgbikgeyAvLyBDb21wYXJlIHRoZSByZW1h
aW5pbmcgdmFsdWVzLgogICAgICAgICAgaWYgKCh2YWx1ZSA9IHZhbHVlb2YodmFsdWVzW2ldLCBp
LCB2YWx1ZXMpKSAhPSBudWxsKSB7CiAgICAgICAgICAgIGlmIChtaW4gPiB2YWx1ZSkgbWluID0g
dmFsdWU7CiAgICAgICAgICAgIGlmIChtYXggPCB2YWx1ZSkgbWF4ID0gdmFsdWU7CiAgICAgICAg
ICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQoKICByZXR1cm4gW21pbiwgbWF4XTsKfQoK
dmFyIGFycmF5ID0gQXJyYXkucHJvdG90eXBlOwoKdmFyIHNsaWNlID0gYXJyYXkuc2xpY2U7CnZh
ciBtYXAgPSBhcnJheS5tYXA7CgpmdW5jdGlvbiBjb25zdGFudCh4KSB7CiAgcmV0dXJuIGZ1bmN0
aW9uKCkgewogICAgcmV0dXJuIHg7CiAgfTsKfQoKZnVuY3Rpb24gaWRlbnRpdHkoeCkgewogIHJl
dHVybiB4Owp9CgpmdW5jdGlvbiBzZXF1ZW5jZShzdGFydCwgc3RvcCwgc3RlcCkgewogIHN0YXJ0
ID0gK3N0YXJ0LCBzdG9wID0gK3N0b3AsIHN0ZXAgPSAobiA9IGFyZ3VtZW50cy5sZW5ndGgpIDwg
MiA/IChzdG9wID0gc3RhcnQsIHN0YXJ0ID0gMCwgMSkgOiBuIDwgMyA/IDEgOiArc3RlcDsKCiAg
dmFyIGkgPSAtMSwKICAgICAgbiA9IE1hdGgubWF4KDAsIE1hdGguY2VpbCgoc3RvcCAtIHN0YXJ0
KSAvIHN0ZXApKSB8IDAsCiAgICAgIHJhbmdlID0gbmV3IEFycmF5KG4pOwoKICB3aGlsZSAoKytp
IDwgbikgewogICAgcmFuZ2VbaV0gPSBzdGFydCArIGkgKiBzdGVwOwogIH0KCiAgcmV0dXJuIHJh
bmdlOwp9Cgp2YXIgZTEwID0gTWF0aC5zcXJ0KDUwKSwKICAgIGU1ID0gTWF0aC5zcXJ0KDEwKSwK
ICAgIGUyID0gTWF0aC5zcXJ0KDIpOwoKZnVuY3Rpb24gdGlja3Moc3RhcnQsIHN0b3AsIGNvdW50
KSB7CiAgdmFyIHJldmVyc2UsCiAgICAgIGkgPSAtMSwKICAgICAgbiwKICAgICAgdGlja3MsCiAg
ICAgIHN0ZXA7CgogIHN0b3AgPSArc3RvcCwgc3RhcnQgPSArc3RhcnQsIGNvdW50ID0gK2NvdW50
OwogIGlmIChzdGFydCA9PT0gc3RvcCAmJiBjb3VudCA+IDApIHJldHVybiBbc3RhcnRdOwogIGlm
IChyZXZlcnNlID0gc3RvcCA8IHN0YXJ0KSBuID0gc3RhcnQsIHN0YXJ0ID0gc3RvcCwgc3RvcCA9
IG47CiAgaWYgKChzdGVwID0gdGlja0luY3JlbWVudChzdGFydCwgc3RvcCwgY291bnQpKSA9PT0g
MCB8fCAhaXNGaW5pdGUoc3RlcCkpIHJldHVybiBbXTsKCiAgaWYgKHN0ZXAgPiAwKSB7CiAgICBz
dGFydCA9IE1hdGguY2VpbChzdGFydCAvIHN0ZXApOwogICAgc3RvcCA9IE1hdGguZmxvb3Ioc3Rv
cCAvIHN0ZXApOwogICAgdGlja3MgPSBuZXcgQXJyYXkobiA9IE1hdGguY2VpbChzdG9wIC0gc3Rh
cnQgKyAxKSk7CiAgICB3aGlsZSAoKytpIDwgbikgdGlja3NbaV0gPSAoc3RhcnQgKyBpKSAqIHN0
ZXA7CiAgfSBlbHNlIHsKICAgIHN0YXJ0ID0gTWF0aC5mbG9vcihzdGFydCAqIHN0ZXApOwogICAg
c3RvcCA9IE1hdGguY2VpbChzdG9wICogc3RlcCk7CiAgICB0aWNrcyA9IG5ldyBBcnJheShuID0g
TWF0aC5jZWlsKHN0YXJ0IC0gc3RvcCArIDEpKTsKICAgIHdoaWxlICgrK2kgPCBuKSB0aWNrc1tp
XSA9IChzdGFydCAtIGkpIC8gc3RlcDsKICB9CgogIGlmIChyZXZlcnNlKSB0aWNrcy5yZXZlcnNl
KCk7CgogIHJldHVybiB0aWNrczsKfQoKZnVuY3Rpb24gdGlja0luY3JlbWVudChzdGFydCwgc3Rv
cCwgY291bnQpIHsKICB2YXIgc3RlcCA9IChzdG9wIC0gc3RhcnQpIC8gTWF0aC5tYXgoMCwgY291
bnQpLAogICAgICBwb3dlciA9IE1hdGguZmxvb3IoTWF0aC5sb2coc3RlcCkgLyBNYXRoLkxOMTAp
LAogICAgICBlcnJvciA9IHN0ZXAgLyBNYXRoLnBvdygxMCwgcG93ZXIpOwogIHJldHVybiBwb3dl
ciA+PSAwCiAgICAgID8gKGVycm9yID49IGUxMCA/IDEwIDogZXJyb3IgPj0gZTUgPyA1IDogZXJy
b3IgPj0gZTIgPyAyIDogMSkgKiBNYXRoLnBvdygxMCwgcG93ZXIpCiAgICAgIDogLU1hdGgucG93
KDEwLCAtcG93ZXIpIC8gKGVycm9yID49IGUxMCA/IDEwIDogZXJyb3IgPj0gZTUgPyA1IDogZXJy
b3IgPj0gZTIgPyAyIDogMSk7Cn0KCmZ1bmN0aW9uIHRpY2tTdGVwKHN0YXJ0LCBzdG9wLCBjb3Vu
dCkgewogIHZhciBzdGVwMCA9IE1hdGguYWJzKHN0b3AgLSBzdGFydCkgLyBNYXRoLm1heCgwLCBj
b3VudCksCiAgICAgIHN0ZXAxID0gTWF0aC5wb3coMTAsIE1hdGguZmxvb3IoTWF0aC5sb2coc3Rl
cDApIC8gTWF0aC5MTjEwKSksCiAgICAgIGVycm9yID0gc3RlcDAgLyBzdGVwMTsKICBpZiAoZXJy
b3IgPj0gZTEwKSBzdGVwMSAqPSAxMDsKICBlbHNlIGlmIChlcnJvciA+PSBlNSkgc3RlcDEgKj0g
NTsKICBlbHNlIGlmIChlcnJvciA+PSBlMikgc3RlcDEgKj0gMjsKICByZXR1cm4gc3RvcCA8IHN0
YXJ0ID8gLXN0ZXAxIDogc3RlcDE7Cn0KCmZ1bmN0aW9uIHRocmVzaG9sZFN0dXJnZXModmFsdWVz
KSB7CiAgcmV0dXJuIE1hdGguY2VpbChNYXRoLmxvZyh2YWx1ZXMubGVuZ3RoKSAvIE1hdGguTE4y
KSArIDE7Cn0KCmZ1bmN0aW9uIGhpc3RvZ3JhbSgpIHsKICB2YXIgdmFsdWUgPSBpZGVudGl0eSwK
ICAgICAgZG9tYWluID0gZXh0ZW50LAogICAgICB0aHJlc2hvbGQgPSB0aHJlc2hvbGRTdHVyZ2Vz
OwoKICBmdW5jdGlvbiBoaXN0b2dyYW0oZGF0YSkgewogICAgdmFyIGksCiAgICAgICAgbiA9IGRh
dGEubGVuZ3RoLAogICAgICAgIHgsCiAgICAgICAgdmFsdWVzID0gbmV3IEFycmF5KG4pOwoKICAg
IGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIHsKICAgICAgdmFsdWVzW2ldID0gdmFsdWUoZGF0YVtp
XSwgaSwgZGF0YSk7CiAgICB9CgogICAgdmFyIHh6ID0gZG9tYWluKHZhbHVlcyksCiAgICAgICAg
eDAgPSB4elswXSwKICAgICAgICB4MSA9IHh6WzFdLAogICAgICAgIHR6ID0gdGhyZXNob2xkKHZh
bHVlcywgeDAsIHgxKTsKCiAgICAvLyBDb252ZXJ0IG51bWJlciBvZiB0aHJlc2hvbGRzIGludG8g
dW5pZm9ybSB0aHJlc2hvbGRzLgogICAgaWYgKCFBcnJheS5pc0FycmF5KHR6KSkgewogICAgICB0
eiA9IHRpY2tTdGVwKHgwLCB4MSwgdHopOwogICAgICB0eiA9IHNlcXVlbmNlKE1hdGguY2VpbCh4
MCAvIHR6KSAqIHR6LCB4MSwgdHopOyAvLyBleGNsdXNpdmUKICAgIH0KCiAgICAvLyBSZW1vdmUg
YW55IHRocmVzaG9sZHMgb3V0c2lkZSB0aGUgZG9tYWluLgogICAgdmFyIG0gPSB0ei5sZW5ndGg7
CiAgICB3aGlsZSAodHpbMF0gPD0geDApIHR6LnNoaWZ0KCksIC0tbTsKICAgIHdoaWxlICh0eltt
IC0gMV0gPiB4MSkgdHoucG9wKCksIC0tbTsKCiAgICB2YXIgYmlucyA9IG5ldyBBcnJheShtICsg
MSksCiAgICAgICAgYmluOwoKICAgIC8vIEluaXRpYWxpemUgYmlucy4KICAgIGZvciAoaSA9IDA7
IGkgPD0gbTsgKytpKSB7CiAgICAgIGJpbiA9IGJpbnNbaV0gPSBbXTsKICAgICAgYmluLngwID0g
aSA+IDAgPyB0eltpIC0gMV0gOiB4MDsKICAgICAgYmluLngxID0gaSA8IG0gPyB0eltpXSA6IHgx
OwogICAgfQoKICAgIC8vIEFzc2lnbiBkYXRhIHRvIGJpbnMgYnkgdmFsdWUsIGlnbm9yaW5nIGFu
eSBvdXRzaWRlIHRoZSBkb21haW4uCiAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSB7CiAgICAg
IHggPSB2YWx1ZXNbaV07CiAgICAgIGlmICh4MCA8PSB4ICYmIHggPD0geDEpIHsKICAgICAgICBi
aW5zW2Jpc2VjdFJpZ2h0KHR6LCB4LCAwLCBtKV0ucHVzaChkYXRhW2ldKTsKICAgICAgfQogICAg
fQoKICAgIHJldHVybiBiaW5zOwogIH0KCiAgaGlzdG9ncmFtLnZhbHVlID0gZnVuY3Rpb24oXykg
ewogICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAodmFsdWUgPSB0eXBlb2YgXyA9PT0gImZ1
bmN0aW9uIiA/IF8gOiBjb25zdGFudChfKSwgaGlzdG9ncmFtKSA6IHZhbHVlOwogIH07CgogIGhp
c3RvZ3JhbS5kb21haW4gPSBmdW5jdGlvbihfKSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0
aCA/IChkb21haW4gPSB0eXBlb2YgXyA9PT0gImZ1bmN0aW9uIiA/IF8gOiBjb25zdGFudChbX1sw
XSwgX1sxXV0pLCBoaXN0b2dyYW0pIDogZG9tYWluOwogIH07CgogIGhpc3RvZ3JhbS50aHJlc2hv
bGRzID0gZnVuY3Rpb24oXykgewogICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAodGhyZXNo
b2xkID0gdHlwZW9mIF8gPT09ICJmdW5jdGlvbiIgPyBfIDogQXJyYXkuaXNBcnJheShfKSA/IGNv
bnN0YW50KHNsaWNlLmNhbGwoXykpIDogY29uc3RhbnQoXyksIGhpc3RvZ3JhbSkgOiB0aHJlc2hv
bGQ7CiAgfTsKCiAgcmV0dXJuIGhpc3RvZ3JhbTsKfQoKZnVuY3Rpb24gdGhyZXNob2xkKHZhbHVl
cywgcCwgdmFsdWVvZikgewogIGlmICh2YWx1ZW9mID09IG51bGwpIHZhbHVlb2YgPSBudW1iZXI7
CiAgaWYgKCEobiA9IHZhbHVlcy5sZW5ndGgpKSByZXR1cm47CiAgaWYgKChwID0gK3ApIDw9IDAg
fHwgbiA8IDIpIHJldHVybiArdmFsdWVvZih2YWx1ZXNbMF0sIDAsIHZhbHVlcyk7CiAgaWYgKHAg
Pj0gMSkgcmV0dXJuICt2YWx1ZW9mKHZhbHVlc1tuIC0gMV0sIG4gLSAxLCB2YWx1ZXMpOwogIHZh
ciBuLAogICAgICBpID0gKG4gLSAxKSAqIHAsCiAgICAgIGkwID0gTWF0aC5mbG9vcihpKSwKICAg
ICAgdmFsdWUwID0gK3ZhbHVlb2YodmFsdWVzW2kwXSwgaTAsIHZhbHVlcyksCiAgICAgIHZhbHVl
MSA9ICt2YWx1ZW9mKHZhbHVlc1tpMCArIDFdLCBpMCArIDEsIHZhbHVlcyk7CiAgcmV0dXJuIHZh
bHVlMCArICh2YWx1ZTEgLSB2YWx1ZTApICogKGkgLSBpMCk7Cn0KCmZ1bmN0aW9uIGZyZWVkbWFu
RGlhY29uaXModmFsdWVzLCBtaW4sIG1heCkgewogIHZhbHVlcyA9IG1hcC5jYWxsKHZhbHVlcywg
bnVtYmVyKS5zb3J0KGFzY2VuZGluZyk7CiAgcmV0dXJuIE1hdGguY2VpbCgobWF4IC0gbWluKSAv
ICgyICogKHRocmVzaG9sZCh2YWx1ZXMsIDAuNzUpIC0gdGhyZXNob2xkKHZhbHVlcywgMC4yNSkp
ICogTWF0aC5wb3codmFsdWVzLmxlbmd0aCwgLTEgLyAzKSkpOwp9CgpmdW5jdGlvbiBzY290dCh2
YWx1ZXMsIG1pbiwgbWF4KSB7CiAgcmV0dXJuIE1hdGguY2VpbCgobWF4IC0gbWluKSAvICgzLjUg
KiBkZXZpYXRpb24odmFsdWVzKSAqIE1hdGgucG93KHZhbHVlcy5sZW5ndGgsIC0xIC8gMykpKTsK
fQoKZnVuY3Rpb24gbWF4KHZhbHVlcywgdmFsdWVvZikgewogIHZhciBuID0gdmFsdWVzLmxlbmd0
aCwKICAgICAgaSA9IC0xLAogICAgICB2YWx1ZSwKICAgICAgbWF4OwoKICBpZiAodmFsdWVvZiA9
PSBudWxsKSB7CiAgICB3aGlsZSAoKytpIDwgbikgeyAvLyBGaW5kIHRoZSBmaXJzdCBjb21wYXJh
YmxlIHZhbHVlLgogICAgICBpZiAoKHZhbHVlID0gdmFsdWVzW2ldKSAhPSBudWxsICYmIHZhbHVl
ID49IHZhbHVlKSB7CiAgICAgICAgbWF4ID0gdmFsdWU7CiAgICAgICAgd2hpbGUgKCsraSA8IG4p
IHsgLy8gQ29tcGFyZSB0aGUgcmVtYWluaW5nIHZhbHVlcy4KICAgICAgICAgIGlmICgodmFsdWUg
PSB2YWx1ZXNbaV0pICE9IG51bGwgJiYgdmFsdWUgPiBtYXgpIHsKICAgICAgICAgICAgbWF4ID0g
dmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQoKICBlbHNlIHsK
ICAgIHdoaWxlICgrK2kgPCBuKSB7IC8vIEZpbmQgdGhlIGZpcnN0IGNvbXBhcmFibGUgdmFsdWUu
CiAgICAgIGlmICgodmFsdWUgPSB2YWx1ZW9mKHZhbHVlc1tpXSwgaSwgdmFsdWVzKSkgIT0gbnVs
bCAmJiB2YWx1ZSA+PSB2YWx1ZSkgewogICAgICAgIG1heCA9IHZhbHVlOwogICAgICAgIHdoaWxl
ICgrK2kgPCBuKSB7IC8vIENvbXBhcmUgdGhlIHJlbWFpbmluZyB2YWx1ZXMuCiAgICAgICAgICBp
ZiAoKHZhbHVlID0gdmFsdWVvZih2YWx1ZXNbaV0sIGksIHZhbHVlcykpICE9IG51bGwgJiYgdmFs
dWUgPiBtYXgpIHsKICAgICAgICAgICAgbWF4ID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAg
fQogICAgICB9CiAgICB9CiAgfQoKICByZXR1cm4gbWF4Owp9CgpmdW5jdGlvbiBtZWFuKHZhbHVl
cywgdmFsdWVvZikgewogIHZhciBuID0gdmFsdWVzLmxlbmd0aCwKICAgICAgbSA9IG4sCiAgICAg
IGkgPSAtMSwKICAgICAgdmFsdWUsCiAgICAgIHN1bSA9IDA7CgogIGlmICh2YWx1ZW9mID09IG51
bGwpIHsKICAgIHdoaWxlICgrK2kgPCBuKSB7CiAgICAgIGlmICghaXNOYU4odmFsdWUgPSBudW1i
ZXIodmFsdWVzW2ldKSkpIHN1bSArPSB2YWx1ZTsKICAgICAgZWxzZSAtLW07CiAgICB9CiAgfQoK
ICBlbHNlIHsKICAgIHdoaWxlICgrK2kgPCBuKSB7CiAgICAgIGlmICghaXNOYU4odmFsdWUgPSBu
dW1iZXIodmFsdWVvZih2YWx1ZXNbaV0sIGksIHZhbHVlcykpKSkgc3VtICs9IHZhbHVlOwogICAg
ICBlbHNlIC0tbTsKICAgIH0KICB9CgogIGlmIChtKSByZXR1cm4gc3VtIC8gbTsKfQoKZnVuY3Rp
b24gbWVkaWFuKHZhbHVlcywgdmFsdWVvZikgewogIHZhciBuID0gdmFsdWVzLmxlbmd0aCwKICAg
ICAgaSA9IC0xLAogICAgICB2YWx1ZSwKICAgICAgbnVtYmVycyA9IFtdOwoKICBpZiAodmFsdWVv
ZiA9PSBudWxsKSB7CiAgICB3aGlsZSAoKytpIDwgbikgewogICAgICBpZiAoIWlzTmFOKHZhbHVl
ID0gbnVtYmVyKHZhbHVlc1tpXSkpKSB7CiAgICAgICAgbnVtYmVycy5wdXNoKHZhbHVlKTsKICAg
ICAgfQogICAgfQogIH0KCiAgZWxzZSB7CiAgICB3aGlsZSAoKytpIDwgbikgewogICAgICBpZiAo
IWlzTmFOKHZhbHVlID0gbnVtYmVyKHZhbHVlb2YodmFsdWVzW2ldLCBpLCB2YWx1ZXMpKSkpIHsK
ICAgICAgICBudW1iZXJzLnB1c2godmFsdWUpOwogICAgICB9CiAgICB9CiAgfQoKICByZXR1cm4g
dGhyZXNob2xkKG51bWJlcnMuc29ydChhc2NlbmRpbmcpLCAwLjUpOwp9CgpmdW5jdGlvbiBtZXJn
ZShhcnJheXMpIHsKICB2YXIgbiA9IGFycmF5cy5sZW5ndGgsCiAgICAgIG0sCiAgICAgIGkgPSAt
MSwKICAgICAgaiA9IDAsCiAgICAgIG1lcmdlZCwKICAgICAgYXJyYXk7CgogIHdoaWxlICgrK2kg
PCBuKSBqICs9IGFycmF5c1tpXS5sZW5ndGg7CiAgbWVyZ2VkID0gbmV3IEFycmF5KGopOwoKICB3
aGlsZSAoLS1uID49IDApIHsKICAgIGFycmF5ID0gYXJyYXlzW25dOwogICAgbSA9IGFycmF5Lmxl
bmd0aDsKICAgIHdoaWxlICgtLW0gPj0gMCkgewogICAgICBtZXJnZWRbLS1qXSA9IGFycmF5W21d
OwogICAgfQogIH0KCiAgcmV0dXJuIG1lcmdlZDsKfQoKZnVuY3Rpb24gbWluKHZhbHVlcywgdmFs
dWVvZikgewogIHZhciBuID0gdmFsdWVzLmxlbmd0aCwKICAgICAgaSA9IC0xLAogICAgICB2YWx1
ZSwKICAgICAgbWluOwoKICBpZiAodmFsdWVvZiA9PSBudWxsKSB7CiAgICB3aGlsZSAoKytpIDwg
bikgeyAvLyBGaW5kIHRoZSBmaXJzdCBjb21wYXJhYmxlIHZhbHVlLgogICAgICBpZiAoKHZhbHVl
ID0gdmFsdWVzW2ldKSAhPSBudWxsICYmIHZhbHVlID49IHZhbHVlKSB7CiAgICAgICAgbWluID0g
dmFsdWU7CiAgICAgICAgd2hpbGUgKCsraSA8IG4pIHsgLy8gQ29tcGFyZSB0aGUgcmVtYWluaW5n
IHZhbHVlcy4KICAgICAgICAgIGlmICgodmFsdWUgPSB2YWx1ZXNbaV0pICE9IG51bGwgJiYgbWlu
ID4gdmFsdWUpIHsKICAgICAgICAgICAgbWluID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAg
fQogICAgICB9CiAgICB9CiAgfQoKICBlbHNlIHsKICAgIHdoaWxlICgrK2kgPCBuKSB7IC8vIEZp
bmQgdGhlIGZpcnN0IGNvbXBhcmFibGUgdmFsdWUuCiAgICAgIGlmICgodmFsdWUgPSB2YWx1ZW9m
KHZhbHVlc1tpXSwgaSwgdmFsdWVzKSkgIT0gbnVsbCAmJiB2YWx1ZSA+PSB2YWx1ZSkgewogICAg
ICAgIG1pbiA9IHZhbHVlOwogICAgICAgIHdoaWxlICgrK2kgPCBuKSB7IC8vIENvbXBhcmUgdGhl
IHJlbWFpbmluZyB2YWx1ZXMuCiAgICAgICAgICBpZiAoKHZhbHVlID0gdmFsdWVvZih2YWx1ZXNb
aV0sIGksIHZhbHVlcykpICE9IG51bGwgJiYgbWluID4gdmFsdWUpIHsKICAgICAgICAgICAgbWlu
ID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQoKICByZXR1
cm4gbWluOwp9CgpmdW5jdGlvbiBwZXJtdXRlKGFycmF5LCBpbmRleGVzKSB7CiAgdmFyIGkgPSBp
bmRleGVzLmxlbmd0aCwgcGVybXV0ZXMgPSBuZXcgQXJyYXkoaSk7CiAgd2hpbGUgKGktLSkgcGVy
bXV0ZXNbaV0gPSBhcnJheVtpbmRleGVzW2ldXTsKICByZXR1cm4gcGVybXV0ZXM7Cn0KCmZ1bmN0
aW9uIHNjYW4odmFsdWVzLCBjb21wYXJlKSB7CiAgaWYgKCEobiA9IHZhbHVlcy5sZW5ndGgpKSBy
ZXR1cm47CiAgdmFyIG4sCiAgICAgIGkgPSAwLAogICAgICBqID0gMCwKICAgICAgeGksCiAgICAg
IHhqID0gdmFsdWVzW2pdOwoKICBpZiAoY29tcGFyZSA9PSBudWxsKSBjb21wYXJlID0gYXNjZW5k
aW5nOwoKICB3aGlsZSAoKytpIDwgbikgewogICAgaWYgKGNvbXBhcmUoeGkgPSB2YWx1ZXNbaV0s
IHhqKSA8IDAgfHwgY29tcGFyZSh4aiwgeGopICE9PSAwKSB7CiAgICAgIHhqID0geGksIGogPSBp
OwogICAgfQogIH0KCiAgaWYgKGNvbXBhcmUoeGosIHhqKSA9PT0gMCkgcmV0dXJuIGo7Cn0KCmZ1
bmN0aW9uIHNodWZmbGUoYXJyYXksIGkwLCBpMSkgewogIHZhciBtID0gKGkxID09IG51bGwgPyBh
cnJheS5sZW5ndGggOiBpMSkgLSAoaTAgPSBpMCA9PSBudWxsID8gMCA6ICtpMCksCiAgICAgIHQs
CiAgICAgIGk7CgogIHdoaWxlIChtKSB7CiAgICBpID0gTWF0aC5yYW5kb20oKSAqIG0tLSB8IDA7
CiAgICB0ID0gYXJyYXlbbSArIGkwXTsKICAgIGFycmF5W20gKyBpMF0gPSBhcnJheVtpICsgaTBd
OwogICAgYXJyYXlbaSArIGkwXSA9IHQ7CiAgfQoKICByZXR1cm4gYXJyYXk7Cn0KCmZ1bmN0aW9u
IHN1bSh2YWx1ZXMsIHZhbHVlb2YpIHsKICB2YXIgbiA9IHZhbHVlcy5sZW5ndGgsCiAgICAgIGkg
PSAtMSwKICAgICAgdmFsdWUsCiAgICAgIHN1bSA9IDA7CgogIGlmICh2YWx1ZW9mID09IG51bGwp
IHsKICAgIHdoaWxlICgrK2kgPCBuKSB7CiAgICAgIGlmICh2YWx1ZSA9ICt2YWx1ZXNbaV0pIHN1
bSArPSB2YWx1ZTsgLy8gTm90ZTogemVybyBhbmQgbnVsbCBhcmUgZXF1aXZhbGVudC4KICAgIH0K
ICB9CgogIGVsc2UgewogICAgd2hpbGUgKCsraSA8IG4pIHsKICAgICAgaWYgKHZhbHVlID0gK3Zh
bHVlb2YodmFsdWVzW2ldLCBpLCB2YWx1ZXMpKSBzdW0gKz0gdmFsdWU7CiAgICB9CiAgfQoKICBy
ZXR1cm4gc3VtOwp9CgpmdW5jdGlvbiB0cmFuc3Bvc2UobWF0cml4KSB7CiAgaWYgKCEobiA9IG1h
dHJpeC5sZW5ndGgpKSByZXR1cm4gW107CiAgZm9yICh2YXIgaSA9IC0xLCBtID0gbWluKG1hdHJp
eCwgbGVuZ3RoKSwgdHJhbnNwb3NlID0gbmV3IEFycmF5KG0pOyArK2kgPCBtOykgewogICAgZm9y
ICh2YXIgaiA9IC0xLCBuLCByb3cgPSB0cmFuc3Bvc2VbaV0gPSBuZXcgQXJyYXkobik7ICsraiA8
IG47KSB7CiAgICAgIHJvd1tqXSA9IG1hdHJpeFtqXVtpXTsKICAgIH0KICB9CiAgcmV0dXJuIHRy
YW5zcG9zZTsKfQoKZnVuY3Rpb24gbGVuZ3RoKGQpIHsKICByZXR1cm4gZC5sZW5ndGg7Cn0KCmZ1
bmN0aW9uIHppcCgpIHsKICByZXR1cm4gdHJhbnNwb3NlKGFyZ3VtZW50cyk7Cn0KCnZhciBzbGlj
ZSQxID0gQXJyYXkucHJvdG90eXBlLnNsaWNlOwoKZnVuY3Rpb24gaWRlbnRpdHkkMSh4KSB7CiAg
cmV0dXJuIHg7Cn0KCnZhciB0b3AgPSAxLAogICAgcmlnaHQgPSAyLAogICAgYm90dG9tID0gMywK
ICAgIGxlZnQgPSA0LAogICAgZXBzaWxvbiA9IDFlLTY7CgpmdW5jdGlvbiB0cmFuc2xhdGVYKHgp
IHsKICByZXR1cm4gInRyYW5zbGF0ZSgiICsgKHggKyAwLjUpICsgIiwwKSI7Cn0KCmZ1bmN0aW9u
IHRyYW5zbGF0ZVkoeSkgewogIHJldHVybiAidHJhbnNsYXRlKDAsIiArICh5ICsgMC41KSArICIp
IjsKfQoKZnVuY3Rpb24gbnVtYmVyJDEoc2NhbGUpIHsKICByZXR1cm4gZnVuY3Rpb24oZCkgewog
ICAgcmV0dXJuICtzY2FsZShkKTsKICB9Owp9CgpmdW5jdGlvbiBjZW50ZXIoc2NhbGUpIHsKICB2
YXIgb2Zmc2V0ID0gTWF0aC5tYXgoMCwgc2NhbGUuYmFuZHdpZHRoKCkgLSAxKSAvIDI7IC8vIEFk
anVzdCBmb3IgMC41cHggb2Zmc2V0LgogIGlmIChzY2FsZS5yb3VuZCgpKSBvZmZzZXQgPSBNYXRo
LnJvdW5kKG9mZnNldCk7CiAgcmV0dXJuIGZ1bmN0aW9uKGQpIHsKICAgIHJldHVybiArc2NhbGUo
ZCkgKyBvZmZzZXQ7CiAgfTsKfQoKZnVuY3Rpb24gZW50ZXJpbmcoKSB7CiAgcmV0dXJuICF0aGlz
Ll9fYXhpczsKfQoKZnVuY3Rpb24gYXhpcyhvcmllbnQsIHNjYWxlKSB7CiAgdmFyIHRpY2tBcmd1
bWVudHMgPSBbXSwKICAgICAgdGlja1ZhbHVlcyA9IG51bGwsCiAgICAgIHRpY2tGb3JtYXQgPSBu
dWxsLAogICAgICB0aWNrU2l6ZUlubmVyID0gNiwKICAgICAgdGlja1NpemVPdXRlciA9IDYsCiAg
ICAgIHRpY2tQYWRkaW5nID0gMywKICAgICAgayA9IG9yaWVudCA9PT0gdG9wIHx8IG9yaWVudCA9
PT0gbGVmdCA/IC0xIDogMSwKICAgICAgeCA9IG9yaWVudCA9PT0gbGVmdCB8fCBvcmllbnQgPT09
IHJpZ2h0ID8gIngiIDogInkiLAogICAgICB0cmFuc2Zvcm0gPSBvcmllbnQgPT09IHRvcCB8fCBv
cmllbnQgPT09IGJvdHRvbSA/IHRyYW5zbGF0ZVggOiB0cmFuc2xhdGVZOwoKICBmdW5jdGlvbiBh
eGlzKGNvbnRleHQpIHsKICAgIHZhciB2YWx1ZXMgPSB0aWNrVmFsdWVzID09IG51bGwgPyAoc2Nh
bGUudGlja3MgPyBzY2FsZS50aWNrcy5hcHBseShzY2FsZSwgdGlja0FyZ3VtZW50cykgOiBzY2Fs
ZS5kb21haW4oKSkgOiB0aWNrVmFsdWVzLAogICAgICAgIGZvcm1hdCA9IHRpY2tGb3JtYXQgPT0g
bnVsbCA/IChzY2FsZS50aWNrRm9ybWF0ID8gc2NhbGUudGlja0Zvcm1hdC5hcHBseShzY2FsZSwg
dGlja0FyZ3VtZW50cykgOiBpZGVudGl0eSQxKSA6IHRpY2tGb3JtYXQsCiAgICAgICAgc3BhY2lu
ZyA9IE1hdGgubWF4KHRpY2tTaXplSW5uZXIsIDApICsgdGlja1BhZGRpbmcsCiAgICAgICAgcmFu
Z2UgPSBzY2FsZS5yYW5nZSgpLAogICAgICAgIHJhbmdlMCA9ICtyYW5nZVswXSArIDAuNSwKICAg
ICAgICByYW5nZTEgPSArcmFuZ2VbcmFuZ2UubGVuZ3RoIC0gMV0gKyAwLjUsCiAgICAgICAgcG9z
aXRpb24gPSAoc2NhbGUuYmFuZHdpZHRoID8gY2VudGVyIDogbnVtYmVyJDEpKHNjYWxlLmNvcHko
KSksCiAgICAgICAgc2VsZWN0aW9uID0gY29udGV4dC5zZWxlY3Rpb24gPyBjb250ZXh0LnNlbGVj
dGlvbigpIDogY29udGV4dCwKICAgICAgICBwYXRoID0gc2VsZWN0aW9uLnNlbGVjdEFsbCgiLmRv
bWFpbiIpLmRhdGEoW251bGxdKSwKICAgICAgICB0aWNrID0gc2VsZWN0aW9uLnNlbGVjdEFsbCgi
LnRpY2siKS5kYXRhKHZhbHVlcywgc2NhbGUpLm9yZGVyKCksCiAgICAgICAgdGlja0V4aXQgPSB0
aWNrLmV4aXQoKSwKICAgICAgICB0aWNrRW50ZXIgPSB0aWNrLmVudGVyKCkuYXBwZW5kKCJnIiku
YXR0cigiY2xhc3MiLCAidGljayIpLAogICAgICAgIGxpbmUgPSB0aWNrLnNlbGVjdCgibGluZSIp
LAogICAgICAgIHRleHQgPSB0aWNrLnNlbGVjdCgidGV4dCIpOwoKICAgIHBhdGggPSBwYXRoLm1l
cmdlKHBhdGguZW50ZXIoKS5pbnNlcnQoInBhdGgiLCAiLnRpY2siKQogICAgICAgIC5hdHRyKCJj
bGFzcyIsICJkb21haW4iKQogICAgICAgIC5hdHRyKCJzdHJva2UiLCAiY3VycmVudENvbG9yIikp
OwoKICAgIHRpY2sgPSB0aWNrLm1lcmdlKHRpY2tFbnRlcik7CgogICAgbGluZSA9IGxpbmUubWVy
Z2UodGlja0VudGVyLmFwcGVuZCgibGluZSIpCiAgICAgICAgLmF0dHIoInN0cm9rZSIsICJjdXJy
ZW50Q29sb3IiKQogICAgICAgIC5hdHRyKHggKyAiMiIsIGsgKiB0aWNrU2l6ZUlubmVyKSk7Cgog
ICAgdGV4dCA9IHRleHQubWVyZ2UodGlja0VudGVyLmFwcGVuZCgidGV4dCIpCiAgICAgICAgLmF0
dHIoImZpbGwiLCAiY3VycmVudENvbG9yIikKICAgICAgICAuYXR0cih4LCBrICogc3BhY2luZykK
ICAgICAgICAuYXR0cigiZHkiLCBvcmllbnQgPT09IHRvcCA/ICIwZW0iIDogb3JpZW50ID09PSBi
b3R0b20gPyAiMC43MWVtIiA6ICIwLjMyZW0iKSk7CgogICAgaWYgKGNvbnRleHQgIT09IHNlbGVj
dGlvbikgewogICAgICBwYXRoID0gcGF0aC50cmFuc2l0aW9uKGNvbnRleHQpOwogICAgICB0aWNr
ID0gdGljay50cmFuc2l0aW9uKGNvbnRleHQpOwogICAgICBsaW5lID0gbGluZS50cmFuc2l0aW9u
KGNvbnRleHQpOwogICAgICB0ZXh0ID0gdGV4dC50cmFuc2l0aW9uKGNvbnRleHQpOwoKICAgICAg
dGlja0V4aXQgPSB0aWNrRXhpdC50cmFuc2l0aW9uKGNvbnRleHQpCiAgICAgICAgICAuYXR0cigi
b3BhY2l0eSIsIGVwc2lsb24pCiAgICAgICAgICAuYXR0cigidHJhbnNmb3JtIiwgZnVuY3Rpb24o
ZCkgeyByZXR1cm4gaXNGaW5pdGUoZCA9IHBvc2l0aW9uKGQpKSA/IHRyYW5zZm9ybShkKSA6IHRo
aXMuZ2V0QXR0cmlidXRlKCJ0cmFuc2Zvcm0iKTsgfSk7CgogICAgICB0aWNrRW50ZXIKICAgICAg
ICAgIC5hdHRyKCJvcGFjaXR5IiwgZXBzaWxvbikKICAgICAgICAgIC5hdHRyKCJ0cmFuc2Zvcm0i
LCBmdW5jdGlvbihkKSB7IHZhciBwID0gdGhpcy5wYXJlbnROb2RlLl9fYXhpczsgcmV0dXJuIHRy
YW5zZm9ybShwICYmIGlzRmluaXRlKHAgPSBwKGQpKSA/IHAgOiBwb3NpdGlvbihkKSk7IH0pOwog
ICAgfQoKICAgIHRpY2tFeGl0LnJlbW92ZSgpOwoKICAgIHBhdGgKICAgICAgICAuYXR0cigiZCIs
IG9yaWVudCA9PT0gbGVmdCB8fCBvcmllbnQgPT0gcmlnaHQKICAgICAgICAgICAgPyAodGlja1Np
emVPdXRlciA/ICJNIiArIGsgKiB0aWNrU2l6ZU91dGVyICsgIiwiICsgcmFuZ2UwICsgIkgwLjVW
IiArIHJhbmdlMSArICJIIiArIGsgKiB0aWNrU2l6ZU91dGVyIDogIk0wLjUsIiArIHJhbmdlMCAr
ICJWIiArIHJhbmdlMSkKICAgICAgICAgICAgOiAodGlja1NpemVPdXRlciA/ICJNIiArIHJhbmdl
MCArICIsIiArIGsgKiB0aWNrU2l6ZU91dGVyICsgIlYwLjVIIiArIHJhbmdlMSArICJWIiArIGsg
KiB0aWNrU2l6ZU91dGVyIDogIk0iICsgcmFuZ2UwICsgIiwwLjVIIiArIHJhbmdlMSkpOwoKICAg
IHRpY2sKICAgICAgICAuYXR0cigib3BhY2l0eSIsIDEpCiAgICAgICAgLmF0dHIoInRyYW5zZm9y
bSIsIGZ1bmN0aW9uKGQpIHsgcmV0dXJuIHRyYW5zZm9ybShwb3NpdGlvbihkKSk7IH0pOwoKICAg
IGxpbmUKICAgICAgICAuYXR0cih4ICsgIjIiLCBrICogdGlja1NpemVJbm5lcik7CgogICAgdGV4
dAogICAgICAgIC5hdHRyKHgsIGsgKiBzcGFjaW5nKQogICAgICAgIC50ZXh0KGZvcm1hdCk7Cgog
ICAgc2VsZWN0aW9uLmZpbHRlcihlbnRlcmluZykKICAgICAgICAuYXR0cigiZmlsbCIsICJub25l
IikKICAgICAgICAuYXR0cigiZm9udC1zaXplIiwgMTApCiAgICAgICAgLmF0dHIoImZvbnQtZmFt
aWx5IiwgInNhbnMtc2VyaWYiKQogICAgICAgIC5hdHRyKCJ0ZXh0LWFuY2hvciIsIG9yaWVudCA9
PT0gcmlnaHQgPyAic3RhcnQiIDogb3JpZW50ID09PSBsZWZ0ID8gImVuZCIgOiAibWlkZGxlIik7
CgogICAgc2VsZWN0aW9uCiAgICAgICAgLmVhY2goZnVuY3Rpb24oKSB7IHRoaXMuX19heGlzID0g
cG9zaXRpb247IH0pOwogIH0KCiAgYXhpcy5zY2FsZSA9IGZ1bmN0aW9uKF8pIHsKICAgIHJldHVy
biBhcmd1bWVudHMubGVuZ3RoID8gKHNjYWxlID0gXywgYXhpcykgOiBzY2FsZTsKICB9OwoKICBh
eGlzLnRpY2tzID0gZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gdGlja0FyZ3VtZW50cyA9IHNsaWNl
JDEuY2FsbChhcmd1bWVudHMpLCBheGlzOwogIH07CgogIGF4aXMudGlja0FyZ3VtZW50cyA9IGZ1
bmN0aW9uKF8pIHsKICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHRpY2tBcmd1bWVudHMg
PSBfID09IG51bGwgPyBbXSA6IHNsaWNlJDEuY2FsbChfKSwgYXhpcykgOiB0aWNrQXJndW1lbnRz
LnNsaWNlKCk7CiAgfTsKCiAgYXhpcy50aWNrVmFsdWVzID0gZnVuY3Rpb24oXykgewogICAgcmV0
dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAodGlja1ZhbHVlcyA9IF8gPT0gbnVsbCA/IG51bGwgOiBz
bGljZSQxLmNhbGwoXyksIGF4aXMpIDogdGlja1ZhbHVlcyAmJiB0aWNrVmFsdWVzLnNsaWNlKCk7
CiAgfTsKCiAgYXhpcy50aWNrRm9ybWF0ID0gZnVuY3Rpb24oXykgewogICAgcmV0dXJuIGFyZ3Vt
ZW50cy5sZW5ndGggPyAodGlja0Zvcm1hdCA9IF8sIGF4aXMpIDogdGlja0Zvcm1hdDsKICB9OwoK
ICBheGlzLnRpY2tTaXplID0gZnVuY3Rpb24oXykgewogICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5n
dGggPyAodGlja1NpemVJbm5lciA9IHRpY2tTaXplT3V0ZXIgPSArXywgYXhpcykgOiB0aWNrU2l6
ZUlubmVyOwogIH07CgogIGF4aXMudGlja1NpemVJbm5lciA9IGZ1bmN0aW9uKF8pIHsKICAgIHJl
dHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHRpY2tTaXplSW5uZXIgPSArXywgYXhpcykgOiB0aWNr
U2l6ZUlubmVyOwogIH07CgogIGF4aXMudGlja1NpemVPdXRlciA9IGZ1bmN0aW9uKF8pIHsKICAg
IHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHRpY2tTaXplT3V0ZXIgPSArXywgYXhpcykgOiB0
aWNrU2l6ZU91dGVyOwogIH07CgogIGF4aXMudGlja1BhZGRpbmcgPSBmdW5jdGlvbihfKSB7CiAg
ICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh0aWNrUGFkZGluZyA9ICtfLCBheGlzKSA6IHRp
Y2tQYWRkaW5nOwogIH07CgogIHJldHVybiBheGlzOwp9CgpmdW5jdGlvbiBheGlzVG9wKHNjYWxl
KSB7CiAgcmV0dXJuIGF4aXModG9wLCBzY2FsZSk7Cn0KCmZ1bmN0aW9uIGF4aXNSaWdodChzY2Fs
ZSkgewogIHJldHVybiBheGlzKHJpZ2h0LCBzY2FsZSk7Cn0KCmZ1bmN0aW9uIGF4aXNCb3R0b20o
c2NhbGUpIHsKICByZXR1cm4gYXhpcyhib3R0b20sIHNjYWxlKTsKfQoKZnVuY3Rpb24gYXhpc0xl
ZnQoc2NhbGUpIHsKICByZXR1cm4gYXhpcyhsZWZ0LCBzY2FsZSk7Cn0KCnZhciBub29wID0ge3Zh
bHVlOiBmdW5jdGlvbigpIHt9fTsKCmZ1bmN0aW9uIGRpc3BhdGNoKCkgewogIGZvciAodmFyIGkg
PSAwLCBuID0gYXJndW1lbnRzLmxlbmd0aCwgXyA9IHt9LCB0OyBpIDwgbjsgKytpKSB7CiAgICBp
ZiAoISh0ID0gYXJndW1lbnRzW2ldICsgIiIpIHx8ICh0IGluIF8pIHx8IC9bXHMuXS8udGVzdCh0
KSkgdGhyb3cgbmV3IEVycm9yKCJpbGxlZ2FsIHR5cGU6ICIgKyB0KTsKICAgIF9bdF0gPSBbXTsK
ICB9CiAgcmV0dXJuIG5ldyBEaXNwYXRjaChfKTsKfQoKZnVuY3Rpb24gRGlzcGF0Y2goXykgewog
IHRoaXMuXyA9IF87Cn0KCmZ1bmN0aW9uIHBhcnNlVHlwZW5hbWVzKHR5cGVuYW1lcywgdHlwZXMp
IHsKICByZXR1cm4gdHlwZW5hbWVzLnRyaW0oKS5zcGxpdCgvXnxccysvKS5tYXAoZnVuY3Rpb24o
dCkgewogICAgdmFyIG5hbWUgPSAiIiwgaSA9IHQuaW5kZXhPZigiLiIpOwogICAgaWYgKGkgPj0g
MCkgbmFtZSA9IHQuc2xpY2UoaSArIDEpLCB0ID0gdC5zbGljZSgwLCBpKTsKICAgIGlmICh0ICYm
ICF0eXBlcy5oYXNPd25Qcm9wZXJ0eSh0KSkgdGhyb3cgbmV3IEVycm9yKCJ1bmtub3duIHR5cGU6
ICIgKyB0KTsKICAgIHJldHVybiB7dHlwZTogdCwgbmFtZTogbmFtZX07CiAgfSk7Cn0KCkRpc3Bh
dGNoLnByb3RvdHlwZSA9IGRpc3BhdGNoLnByb3RvdHlwZSA9IHsKICBjb25zdHJ1Y3RvcjogRGlz
cGF0Y2gsCiAgb246IGZ1bmN0aW9uKHR5cGVuYW1lLCBjYWxsYmFjaykgewogICAgdmFyIF8gPSB0
aGlzLl8sCiAgICAgICAgVCA9IHBhcnNlVHlwZW5hbWVzKHR5cGVuYW1lICsgIiIsIF8pLAogICAg
ICAgIHQsCiAgICAgICAgaSA9IC0xLAogICAgICAgIG4gPSBULmxlbmd0aDsKCiAgICAvLyBJZiBu
byBjYWxsYmFjayB3YXMgc3BlY2lmaWVkLCByZXR1cm4gdGhlIGNhbGxiYWNrIG9mIHRoZSBnaXZl
biB0eXBlIGFuZCBuYW1lLgogICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAyKSB7CiAgICAgIHdo
aWxlICgrK2kgPCBuKSBpZiAoKHQgPSAodHlwZW5hbWUgPSBUW2ldKS50eXBlKSAmJiAodCA9IGdl
dChfW3RdLCB0eXBlbmFtZS5uYW1lKSkpIHJldHVybiB0OwogICAgICByZXR1cm47CiAgICB9Cgog
ICAgLy8gSWYgYSB0eXBlIHdhcyBzcGVjaWZpZWQsIHNldCB0aGUgY2FsbGJhY2sgZm9yIHRoZSBn
aXZlbiB0eXBlIGFuZCBuYW1lLgogICAgLy8gT3RoZXJ3aXNlLCBpZiBhIG51bGwgY2FsbGJhY2sg
d2FzIHNwZWNpZmllZCwgcmVtb3ZlIGNhbGxiYWNrcyBvZiB0aGUgZ2l2ZW4gbmFtZS4KICAgIGlm
IChjYWxsYmFjayAhPSBudWxsICYmIHR5cGVvZiBjYWxsYmFjayAhPT0gImZ1bmN0aW9uIikgdGhy
b3cgbmV3IEVycm9yKCJpbnZhbGlkIGNhbGxiYWNrOiAiICsgY2FsbGJhY2spOwogICAgd2hpbGUg
KCsraSA8IG4pIHsKICAgICAgaWYgKHQgPSAodHlwZW5hbWUgPSBUW2ldKS50eXBlKSBfW3RdID0g
c2V0KF9bdF0sIHR5cGVuYW1lLm5hbWUsIGNhbGxiYWNrKTsKICAgICAgZWxzZSBpZiAoY2FsbGJh
Y2sgPT0gbnVsbCkgZm9yICh0IGluIF8pIF9bdF0gPSBzZXQoX1t0XSwgdHlwZW5hbWUubmFtZSwg
bnVsbCk7CiAgICB9CgogICAgcmV0dXJuIHRoaXM7CiAgfSwKICBjb3B5OiBmdW5jdGlvbigpIHsK
ICAgIHZhciBjb3B5ID0ge30sIF8gPSB0aGlzLl87CiAgICBmb3IgKHZhciB0IGluIF8pIGNvcHlb
dF0gPSBfW3RdLnNsaWNlKCk7CiAgICByZXR1cm4gbmV3IERpc3BhdGNoKGNvcHkpOwogIH0sCiAg
Y2FsbDogZnVuY3Rpb24odHlwZSwgdGhhdCkgewogICAgaWYgKChuID0gYXJndW1lbnRzLmxlbmd0
aCAtIDIpID4gMCkgZm9yICh2YXIgYXJncyA9IG5ldyBBcnJheShuKSwgaSA9IDAsIG4sIHQ7IGkg
PCBuOyArK2kpIGFyZ3NbaV0gPSBhcmd1bWVudHNbaSArIDJdOwogICAgaWYgKCF0aGlzLl8uaGFz
T3duUHJvcGVydHkodHlwZSkpIHRocm93IG5ldyBFcnJvcigidW5rbm93biB0eXBlOiAiICsgdHlw
ZSk7CiAgICBmb3IgKHQgPSB0aGlzLl9bdHlwZV0sIGkgPSAwLCBuID0gdC5sZW5ndGg7IGkgPCBu
OyArK2kpIHRbaV0udmFsdWUuYXBwbHkodGhhdCwgYXJncyk7CiAgfSwKICBhcHBseTogZnVuY3Rp
b24odHlwZSwgdGhhdCwgYXJncykgewogICAgaWYgKCF0aGlzLl8uaGFzT3duUHJvcGVydHkodHlw
ZSkpIHRocm93IG5ldyBFcnJvcigidW5rbm93biB0eXBlOiAiICsgdHlwZSk7CiAgICBmb3IgKHZh
ciB0ID0gdGhpcy5fW3R5cGVdLCBpID0gMCwgbiA9IHQubGVuZ3RoOyBpIDwgbjsgKytpKSB0W2ld
LnZhbHVlLmFwcGx5KHRoYXQsIGFyZ3MpOwogIH0KfTsKCmZ1bmN0aW9uIGdldCh0eXBlLCBuYW1l
KSB7CiAgZm9yICh2YXIgaSA9IDAsIG4gPSB0eXBlLmxlbmd0aCwgYzsgaSA8IG47ICsraSkgewog
ICAgaWYgKChjID0gdHlwZVtpXSkubmFtZSA9PT0gbmFtZSkgewogICAgICByZXR1cm4gYy52YWx1
ZTsKICAgIH0KICB9Cn0KCmZ1bmN0aW9uIHNldCh0eXBlLCBuYW1lLCBjYWxsYmFjaykgewogIGZv
ciAodmFyIGkgPSAwLCBuID0gdHlwZS5sZW5ndGg7IGkgPCBuOyArK2kpIHsKICAgIGlmICh0eXBl
W2ldLm5hbWUgPT09IG5hbWUpIHsKICAgICAgdHlwZVtpXSA9IG5vb3AsIHR5cGUgPSB0eXBlLnNs
aWNlKDAsIGkpLmNvbmNhdCh0eXBlLnNsaWNlKGkgKyAxKSk7CiAgICAgIGJyZWFrOwogICAgfQog
IH0KICBpZiAoY2FsbGJhY2sgIT0gbnVsbCkgdHlwZS5wdXNoKHtuYW1lOiBuYW1lLCB2YWx1ZTog
Y2FsbGJhY2t9KTsKICByZXR1cm4gdHlwZTsKfQoKdmFyIHhodG1sID0gImh0dHA6Ly93d3cudzMu
b3JnLzE5OTkveGh0bWwiOwoKdmFyIG5hbWVzcGFjZXMgPSB7CiAgc3ZnOiAiaHR0cDovL3d3dy53
My5vcmcvMjAwMC9zdmciLAogIHhodG1sOiB4aHRtbCwKICB4bGluazogImh0dHA6Ly93d3cudzMu
b3JnLzE5OTkveGxpbmsiLAogIHhtbDogImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVz
cGFjZSIsCiAgeG1sbnM6ICJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyIKfTsKCmZ1bmN0
aW9uIG5hbWVzcGFjZShuYW1lKSB7CiAgdmFyIHByZWZpeCA9IG5hbWUgKz0gIiIsIGkgPSBwcmVm
aXguaW5kZXhPZigiOiIpOwogIGlmIChpID49IDAgJiYgKHByZWZpeCA9IG5hbWUuc2xpY2UoMCwg
aSkpICE9PSAieG1sbnMiKSBuYW1lID0gbmFtZS5zbGljZShpICsgMSk7CiAgcmV0dXJuIG5hbWVz
cGFjZXMuaGFzT3duUHJvcGVydHkocHJlZml4KSA/IHtzcGFjZTogbmFtZXNwYWNlc1twcmVmaXhd
LCBsb2NhbDogbmFtZX0gOiBuYW1lOwp9CgpmdW5jdGlvbiBjcmVhdG9ySW5oZXJpdChuYW1lKSB7
CiAgcmV0dXJuIGZ1bmN0aW9uKCkgewogICAgdmFyIGRvY3VtZW50ID0gdGhpcy5vd25lckRvY3Vt
ZW50LAogICAgICAgIHVyaSA9IHRoaXMubmFtZXNwYWNlVVJJOwogICAgcmV0dXJuIHVyaSA9PT0g
eGh0bWwgJiYgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50Lm5hbWVzcGFjZVVSSSA9PT0geGh0bWwK
ICAgICAgICA/IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQobmFtZSkKICAgICAgICA6IGRvY3VtZW50
LmNyZWF0ZUVsZW1lbnROUyh1cmksIG5hbWUpOwogIH07Cn0KCmZ1bmN0aW9uIGNyZWF0b3JGaXhl
ZChmdWxsbmFtZSkgewogIHJldHVybiBmdW5jdGlvbigpIHsKICAgIHJldHVybiB0aGlzLm93bmVy
RG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKGZ1bGxuYW1lLnNwYWNlLCBmdWxsbmFtZS5sb2NhbCk7
CiAgfTsKfQoKZnVuY3Rpb24gY3JlYXRvcihuYW1lKSB7CiAgdmFyIGZ1bGxuYW1lID0gbmFtZXNw
YWNlKG5hbWUpOwogIHJldHVybiAoZnVsbG5hbWUubG9jYWwKICAgICAgPyBjcmVhdG9yRml4ZWQK
ICAgICAgOiBjcmVhdG9ySW5oZXJpdCkoZnVsbG5hbWUpOwp9CgpmdW5jdGlvbiBub25lKCkge30K
CmZ1bmN0aW9uIHNlbGVjdG9yKHNlbGVjdG9yKSB7CiAgcmV0dXJuIHNlbGVjdG9yID09IG51bGwg
PyBub25lIDogZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gdGhpcy5xdWVyeVNlbGVjdG9yKHNlbGVj
dG9yKTsKICB9Owp9CgpmdW5jdGlvbiBzZWxlY3Rpb25fc2VsZWN0KHNlbGVjdCkgewogIGlmICh0
eXBlb2Ygc2VsZWN0ICE9PSAiZnVuY3Rpb24iKSBzZWxlY3QgPSBzZWxlY3RvcihzZWxlY3QpOwoK
ICBmb3IgKHZhciBncm91cHMgPSB0aGlzLl9ncm91cHMsIG0gPSBncm91cHMubGVuZ3RoLCBzdWJn
cm91cHMgPSBuZXcgQXJyYXkobSksIGogPSAwOyBqIDwgbTsgKytqKSB7CiAgICBmb3IgKHZhciBn
cm91cCA9IGdyb3Vwc1tqXSwgbiA9IGdyb3VwLmxlbmd0aCwgc3ViZ3JvdXAgPSBzdWJncm91cHNb
al0gPSBuZXcgQXJyYXkobiksIG5vZGUsIHN1Ym5vZGUsIGkgPSAwOyBpIDwgbjsgKytpKSB7CiAg
ICAgIGlmICgobm9kZSA9IGdyb3VwW2ldKSAmJiAoc3Vibm9kZSA9IHNlbGVjdC5jYWxsKG5vZGUs
IG5vZGUuX19kYXRhX18sIGksIGdyb3VwKSkpIHsKICAgICAgICBpZiAoIl9fZGF0YV9fIiBpbiBu
b2RlKSBzdWJub2RlLl9fZGF0YV9fID0gbm9kZS5fX2RhdGFfXzsKICAgICAgICBzdWJncm91cFtp
XSA9IHN1Ym5vZGU7CiAgICAgIH0KICAgIH0KICB9CgogIHJldHVybiBuZXcgU2VsZWN0aW9uKHN1
Ymdyb3VwcywgdGhpcy5fcGFyZW50cyk7Cn0KCmZ1bmN0aW9uIGVtcHR5KCkgewogIHJldHVybiBb
XTsKfQoKZnVuY3Rpb24gc2VsZWN0b3JBbGwoc2VsZWN0b3IpIHsKICByZXR1cm4gc2VsZWN0b3Ig
PT0gbnVsbCA/IGVtcHR5IDogZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gdGhpcy5xdWVyeVNlbGVj
dG9yQWxsKHNlbGVjdG9yKTsKICB9Owp9CgpmdW5jdGlvbiBzZWxlY3Rpb25fc2VsZWN0QWxsKHNl
bGVjdCkgewogIGlmICh0eXBlb2Ygc2VsZWN0ICE9PSAiZnVuY3Rpb24iKSBzZWxlY3QgPSBzZWxl
Y3RvckFsbChzZWxlY3QpOwoKICBmb3IgKHZhciBncm91cHMgPSB0aGlzLl9ncm91cHMsIG0gPSBn
cm91cHMubGVuZ3RoLCBzdWJncm91cHMgPSBbXSwgcGFyZW50cyA9IFtdLCBqID0gMDsgaiA8IG07
ICsraikgewogICAgZm9yICh2YXIgZ3JvdXAgPSBncm91cHNbal0sIG4gPSBncm91cC5sZW5ndGgs
IG5vZGUsIGkgPSAwOyBpIDwgbjsgKytpKSB7CiAgICAgIGlmIChub2RlID0gZ3JvdXBbaV0pIHsK
ICAgICAgICBzdWJncm91cHMucHVzaChzZWxlY3QuY2FsbChub2RlLCBub2RlLl9fZGF0YV9fLCBp
LCBncm91cCkpOwogICAgICAgIHBhcmVudHMucHVzaChub2RlKTsKICAgICAgfQogICAgfQogIH0K
CiAgcmV0dXJuIG5ldyBTZWxlY3Rpb24oc3ViZ3JvdXBzLCBwYXJlbnRzKTsKfQoKZnVuY3Rpb24g
bWF0Y2hlcihzZWxlY3RvcikgewogIHJldHVybiBmdW5jdGlvbigpIHsKICAgIHJldHVybiB0aGlz
Lm1hdGNoZXMoc2VsZWN0b3IpOwogIH07Cn0KCmZ1bmN0aW9uIHNlbGVjdGlvbl9maWx0ZXIobWF0
Y2gpIHsKICBpZiAodHlwZW9mIG1hdGNoICE9PSAiZnVuY3Rpb24iKSBtYXRjaCA9IG1hdGNoZXIo
bWF0Y2gpOwoKICBmb3IgKHZhciBncm91cHMgPSB0aGlzLl9ncm91cHMsIG0gPSBncm91cHMubGVu
Z3RoLCBzdWJncm91cHMgPSBuZXcgQXJyYXkobSksIGogPSAwOyBqIDwgbTsgKytqKSB7CiAgICBm
b3IgKHZhciBncm91cCA9IGdyb3Vwc1tqXSwgbiA9IGdyb3VwLmxlbmd0aCwgc3ViZ3JvdXAgPSBz
dWJncm91cHNbal0gPSBbXSwgbm9kZSwgaSA9IDA7IGkgPCBuOyArK2kpIHsKICAgICAgaWYgKChu
b2RlID0gZ3JvdXBbaV0pICYmIG1hdGNoLmNhbGwobm9kZSwgbm9kZS5fX2RhdGFfXywgaSwgZ3Jv
dXApKSB7CiAgICAgICAgc3ViZ3JvdXAucHVzaChub2RlKTsKICAgICAgfQogICAgfQogIH0KCiAg
cmV0dXJuIG5ldyBTZWxlY3Rpb24oc3ViZ3JvdXBzLCB0aGlzLl9wYXJlbnRzKTsKfQoKZnVuY3Rp
b24gc3BhcnNlKHVwZGF0ZSkgewogIHJldHVybiBuZXcgQXJyYXkodXBkYXRlLmxlbmd0aCk7Cn0K
CmZ1bmN0aW9uIHNlbGVjdGlvbl9lbnRlcigpIHsKICByZXR1cm4gbmV3IFNlbGVjdGlvbih0aGlz
Ll9lbnRlciB8fCB0aGlzLl9ncm91cHMubWFwKHNwYXJzZSksIHRoaXMuX3BhcmVudHMpOwp9Cgpm
dW5jdGlvbiBFbnRlck5vZGUocGFyZW50LCBkYXR1bSkgewogIHRoaXMub3duZXJEb2N1bWVudCA9
IHBhcmVudC5vd25lckRvY3VtZW50OwogIHRoaXMubmFtZXNwYWNlVVJJID0gcGFyZW50Lm5hbWVz
cGFjZVVSSTsKICB0aGlzLl9uZXh0ID0gbnVsbDsKICB0aGlzLl9wYXJlbnQgPSBwYXJlbnQ7CiAg
dGhpcy5fX2RhdGFfXyA9IGRhdHVtOwp9CgpFbnRlck5vZGUucHJvdG90eXBlID0gewogIGNvbnN0
cnVjdG9yOiBFbnRlck5vZGUsCiAgYXBwZW5kQ2hpbGQ6IGZ1bmN0aW9uKGNoaWxkKSB7IHJldHVy
biB0aGlzLl9wYXJlbnQuaW5zZXJ0QmVmb3JlKGNoaWxkLCB0aGlzLl9uZXh0KTsgfSwKICBpbnNl
cnRCZWZvcmU6IGZ1bmN0aW9uKGNoaWxkLCBuZXh0KSB7IHJldHVybiB0aGlzLl9wYXJlbnQuaW5z
ZXJ0QmVmb3JlKGNoaWxkLCBuZXh0KTsgfSwKICBxdWVyeVNlbGVjdG9yOiBmdW5jdGlvbihzZWxl
Y3RvcikgeyByZXR1cm4gdGhpcy5fcGFyZW50LnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3IpOyB9LAog
IHF1ZXJ5U2VsZWN0b3JBbGw6IGZ1bmN0aW9uKHNlbGVjdG9yKSB7IHJldHVybiB0aGlzLl9wYXJl
bnQucXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcik7IH0KfTsKCmZ1bmN0aW9uIGNvbnN0YW50JDEo
eCkgewogIHJldHVybiBmdW5jdGlvbigpIHsKICAgIHJldHVybiB4OwogIH07Cn0KCnZhciBrZXlQ
cmVmaXggPSAiJCI7IC8vIFByb3RlY3QgYWdhaW5zdCBrZXlzIGxpa2Ug4oCcX19wcm90b19f4oCd
LgoKZnVuY3Rpb24gYmluZEluZGV4KHBhcmVudCwgZ3JvdXAsIGVudGVyLCB1cGRhdGUsIGV4aXQs
IGRhdGEpIHsKICB2YXIgaSA9IDAsCiAgICAgIG5vZGUsCiAgICAgIGdyb3VwTGVuZ3RoID0gZ3Jv
dXAubGVuZ3RoLAogICAgICBkYXRhTGVuZ3RoID0gZGF0YS5sZW5ndGg7CgogIC8vIFB1dCBhbnkg
bm9uLW51bGwgbm9kZXMgdGhhdCBmaXQgaW50byB1cGRhdGUuCiAgLy8gUHV0IGFueSBudWxsIG5v
ZGVzIGludG8gZW50ZXIuCiAgLy8gUHV0IGFueSByZW1haW5pbmcgZGF0YSBpbnRvIGVudGVyLgog
IGZvciAoOyBpIDwgZGF0YUxlbmd0aDsgKytpKSB7CiAgICBpZiAobm9kZSA9IGdyb3VwW2ldKSB7
CiAgICAgIG5vZGUuX19kYXRhX18gPSBkYXRhW2ldOwogICAgICB1cGRhdGVbaV0gPSBub2RlOwog
ICAgfSBlbHNlIHsKICAgICAgZW50ZXJbaV0gPSBuZXcgRW50ZXJOb2RlKHBhcmVudCwgZGF0YVtp
XSk7CiAgICB9CiAgfQoKICAvLyBQdXQgYW55IG5vbi1udWxsIG5vZGVzIHRoYXQgZG9u4oCZdCBm
aXQgaW50byBleGl0LgogIGZvciAoOyBpIDwgZ3JvdXBMZW5ndGg7ICsraSkgewogICAgaWYgKG5v
ZGUgPSBncm91cFtpXSkgewogICAgICBleGl0W2ldID0gbm9kZTsKICAgIH0KICB9Cn0KCmZ1bmN0
aW9uIGJpbmRLZXkocGFyZW50LCBncm91cCwgZW50ZXIsIHVwZGF0ZSwgZXhpdCwgZGF0YSwga2V5
KSB7CiAgdmFyIGksCiAgICAgIG5vZGUsCiAgICAgIG5vZGVCeUtleVZhbHVlID0ge30sCiAgICAg
IGdyb3VwTGVuZ3RoID0gZ3JvdXAubGVuZ3RoLAogICAgICBkYXRhTGVuZ3RoID0gZGF0YS5sZW5n
dGgsCiAgICAgIGtleVZhbHVlcyA9IG5ldyBBcnJheShncm91cExlbmd0aCksCiAgICAgIGtleVZh
bHVlOwoKICAvLyBDb21wdXRlIHRoZSBrZXkgZm9yIGVhY2ggbm9kZS4KICAvLyBJZiBtdWx0aXBs
ZSBub2RlcyBoYXZlIHRoZSBzYW1lIGtleSwgdGhlIGR1cGxpY2F0ZXMgYXJlIGFkZGVkIHRvIGV4
aXQuCiAgZm9yIChpID0gMDsgaSA8IGdyb3VwTGVuZ3RoOyArK2kpIHsKICAgIGlmIChub2RlID0g
Z3JvdXBbaV0pIHsKICAgICAga2V5VmFsdWVzW2ldID0ga2V5VmFsdWUgPSBrZXlQcmVmaXggKyBr
ZXkuY2FsbChub2RlLCBub2RlLl9fZGF0YV9fLCBpLCBncm91cCk7CiAgICAgIGlmIChrZXlWYWx1
ZSBpbiBub2RlQnlLZXlWYWx1ZSkgewogICAgICAgIGV4aXRbaV0gPSBub2RlOwogICAgICB9IGVs
c2UgewogICAgICAgIG5vZGVCeUtleVZhbHVlW2tleVZhbHVlXSA9IG5vZGU7CiAgICAgIH0KICAg
IH0KICB9CgogIC8vIENvbXB1dGUgdGhlIGtleSBmb3IgZWFjaCBkYXR1bS4KICAvLyBJZiB0aGVy
ZSBhIG5vZGUgYXNzb2NpYXRlZCB3aXRoIHRoaXMga2V5LCBqb2luIGFuZCBhZGQgaXQgdG8gdXBk
YXRlLgogIC8vIElmIHRoZXJlIGlzIG5vdCAob3IgdGhlIGtleSBpcyBhIGR1cGxpY2F0ZSksIGFk
ZCBpdCB0byBlbnRlci4KICBmb3IgKGkgPSAwOyBpIDwgZGF0YUxlbmd0aDsgKytpKSB7CiAgICBr
ZXlWYWx1ZSA9IGtleVByZWZpeCArIGtleS5jYWxsKHBhcmVudCwgZGF0YVtpXSwgaSwgZGF0YSk7
CiAgICBpZiAobm9kZSA9IG5vZGVCeUtleVZhbHVlW2tleVZhbHVlXSkgewogICAgICB1cGRhdGVb
aV0gPSBub2RlOwogICAgICBub2RlLl9fZGF0YV9fID0gZGF0YVtpXTsKICAgICAgbm9kZUJ5S2V5
VmFsdWVba2V5VmFsdWVdID0gbnVsbDsKICAgIH0gZWxzZSB7CiAgICAgIGVudGVyW2ldID0gbmV3
IEVudGVyTm9kZShwYXJlbnQsIGRhdGFbaV0pOwogICAgfQogIH0KCiAgLy8gQWRkIGFueSByZW1h
aW5pbmcgbm9kZXMgdGhhdCB3ZXJlIG5vdCBib3VuZCB0byBkYXRhIHRvIGV4aXQuCiAgZm9yIChp
ID0gMDsgaSA8IGdyb3VwTGVuZ3RoOyArK2kpIHsKICAgIGlmICgobm9kZSA9IGdyb3VwW2ldKSAm
JiAobm9kZUJ5S2V5VmFsdWVba2V5VmFsdWVzW2ldXSA9PT0gbm9kZSkpIHsKICAgICAgZXhpdFtp
XSA9IG5vZGU7CiAgICB9CiAgfQp9CgpmdW5jdGlvbiBzZWxlY3Rpb25fZGF0YSh2YWx1ZSwga2V5
KSB7CiAgaWYgKCF2YWx1ZSkgewogICAgZGF0YSA9IG5ldyBBcnJheSh0aGlzLnNpemUoKSksIGog
PSAtMTsKICAgIHRoaXMuZWFjaChmdW5jdGlvbihkKSB7IGRhdGFbKytqXSA9IGQ7IH0pOwogICAg
cmV0dXJuIGRhdGE7CiAgfQoKICB2YXIgYmluZCA9IGtleSA/IGJpbmRLZXkgOiBiaW5kSW5kZXgs
CiAgICAgIHBhcmVudHMgPSB0aGlzLl9wYXJlbnRzLAogICAgICBncm91cHMgPSB0aGlzLl9ncm91
cHM7CgogIGlmICh0eXBlb2YgdmFsdWUgIT09ICJmdW5jdGlvbiIpIHZhbHVlID0gY29uc3RhbnQk
MSh2YWx1ZSk7CgogIGZvciAodmFyIG0gPSBncm91cHMubGVuZ3RoLCB1cGRhdGUgPSBuZXcgQXJy
YXkobSksIGVudGVyID0gbmV3IEFycmF5KG0pLCBleGl0ID0gbmV3IEFycmF5KG0pLCBqID0gMDsg
aiA8IG07ICsraikgewogICAgdmFyIHBhcmVudCA9IHBhcmVudHNbal0sCiAgICAgICAgZ3JvdXAg
PSBncm91cHNbal0sCiAgICAgICAgZ3JvdXBMZW5ndGggPSBncm91cC5sZW5ndGgsCiAgICAgICAg
ZGF0YSA9IHZhbHVlLmNhbGwocGFyZW50LCBwYXJlbnQgJiYgcGFyZW50Ll9fZGF0YV9fLCBqLCBw
YXJlbnRzKSwKICAgICAgICBkYXRhTGVuZ3RoID0gZGF0YS5sZW5ndGgsCiAgICAgICAgZW50ZXJH
cm91cCA9IGVudGVyW2pdID0gbmV3IEFycmF5KGRhdGFMZW5ndGgpLAogICAgICAgIHVwZGF0ZUdy
b3VwID0gdXBkYXRlW2pdID0gbmV3IEFycmF5KGRhdGFMZW5ndGgpLAogICAgICAgIGV4aXRHcm91
cCA9IGV4aXRbal0gPSBuZXcgQXJyYXkoZ3JvdXBMZW5ndGgpOwoKICAgIGJpbmQocGFyZW50LCBn
cm91cCwgZW50ZXJHcm91cCwgdXBkYXRlR3JvdXAsIGV4aXRHcm91cCwgZGF0YSwga2V5KTsKCiAg
ICAvLyBOb3cgY29ubmVjdCB0aGUgZW50ZXIgbm9kZXMgdG8gdGhlaXIgZm9sbG93aW5nIHVwZGF0
ZSBub2RlLCBzdWNoIHRoYXQKICAgIC8vIGFwcGVuZENoaWxkIGNhbiBpbnNlcnQgdGhlIG1hdGVy
aWFsaXplZCBlbnRlciBub2RlIGJlZm9yZSB0aGlzIG5vZGUsCiAgICAvLyByYXRoZXIgdGhhbiBh
dCB0aGUgZW5kIG9mIHRoZSBwYXJlbnQgbm9kZS4KICAgIGZvciAodmFyIGkwID0gMCwgaTEgPSAw
LCBwcmV2aW91cywgbmV4dDsgaTAgPCBkYXRhTGVuZ3RoOyArK2kwKSB7CiAgICAgIGlmIChwcmV2
aW91cyA9IGVudGVyR3JvdXBbaTBdKSB7CiAgICAgICAgaWYgKGkwID49IGkxKSBpMSA9IGkwICsg
MTsKICAgICAgICB3aGlsZSAoIShuZXh0ID0gdXBkYXRlR3JvdXBbaTFdKSAmJiArK2kxIDwgZGF0
YUxlbmd0aCk7CiAgICAgICAgcHJldmlvdXMuX25leHQgPSBuZXh0IHx8IG51bGw7CiAgICAgIH0K
ICAgIH0KICB9CgogIHVwZGF0ZSA9IG5ldyBTZWxlY3Rpb24odXBkYXRlLCBwYXJlbnRzKTsKICB1
cGRhdGUuX2VudGVyID0gZW50ZXI7CiAgdXBkYXRlLl9leGl0ID0gZXhpdDsKICByZXR1cm4gdXBk
YXRlOwp9CgpmdW5jdGlvbiBzZWxlY3Rpb25fZXhpdCgpIHsKICByZXR1cm4gbmV3IFNlbGVjdGlv
bih0aGlzLl9leGl0IHx8IHRoaXMuX2dyb3Vwcy5tYXAoc3BhcnNlKSwgdGhpcy5fcGFyZW50cyk7
Cn0KCmZ1bmN0aW9uIHNlbGVjdGlvbl9qb2luKG9uZW50ZXIsIG9udXBkYXRlLCBvbmV4aXQpIHsK
ICB2YXIgZW50ZXIgPSB0aGlzLmVudGVyKCksIHVwZGF0ZSA9IHRoaXMsIGV4aXQgPSB0aGlzLmV4
aXQoKTsKICBlbnRlciA9IHR5cGVvZiBvbmVudGVyID09PSAiZnVuY3Rpb24iID8gb25lbnRlcihl
bnRlcikgOiBlbnRlci5hcHBlbmQob25lbnRlciArICIiKTsKICBpZiAob251cGRhdGUgIT0gbnVs
bCkgdXBkYXRlID0gb251cGRhdGUodXBkYXRlKTsKICBpZiAob25leGl0ID09IG51bGwpIGV4aXQu
cmVtb3ZlKCk7IGVsc2Ugb25leGl0KGV4aXQpOwogIHJldHVybiBlbnRlciAmJiB1cGRhdGUgPyBl
bnRlci5tZXJnZSh1cGRhdGUpLm9yZGVyKCkgOiB1cGRhdGU7Cn0KCmZ1bmN0aW9uIHNlbGVjdGlv
bl9tZXJnZShzZWxlY3Rpb24pIHsKCiAgZm9yICh2YXIgZ3JvdXBzMCA9IHRoaXMuX2dyb3Vwcywg
Z3JvdXBzMSA9IHNlbGVjdGlvbi5fZ3JvdXBzLCBtMCA9IGdyb3VwczAubGVuZ3RoLCBtMSA9IGdy
b3VwczEubGVuZ3RoLCBtID0gTWF0aC5taW4obTAsIG0xKSwgbWVyZ2VzID0gbmV3IEFycmF5KG0w
KSwgaiA9IDA7IGogPCBtOyArK2opIHsKICAgIGZvciAodmFyIGdyb3VwMCA9IGdyb3VwczBbal0s
IGdyb3VwMSA9IGdyb3VwczFbal0sIG4gPSBncm91cDAubGVuZ3RoLCBtZXJnZSA9IG1lcmdlc1tq
XSA9IG5ldyBBcnJheShuKSwgbm9kZSwgaSA9IDA7IGkgPCBuOyArK2kpIHsKICAgICAgaWYgKG5v
ZGUgPSBncm91cDBbaV0gfHwgZ3JvdXAxW2ldKSB7CiAgICAgICAgbWVyZ2VbaV0gPSBub2RlOwog
ICAgICB9CiAgICB9CiAgfQoKICBmb3IgKDsgaiA8IG0wOyArK2opIHsKICAgIG1lcmdlc1tqXSA9
IGdyb3VwczBbal07CiAgfQoKICByZXR1cm4gbmV3IFNlbGVjdGlvbihtZXJnZXMsIHRoaXMuX3Bh
cmVudHMpOwp9CgpmdW5jdGlvbiBzZWxlY3Rpb25fb3JkZXIoKSB7CgogIGZvciAodmFyIGdyb3Vw
cyA9IHRoaXMuX2dyb3VwcywgaiA9IC0xLCBtID0gZ3JvdXBzLmxlbmd0aDsgKytqIDwgbTspIHsK
ICAgIGZvciAodmFyIGdyb3VwID0gZ3JvdXBzW2pdLCBpID0gZ3JvdXAubGVuZ3RoIC0gMSwgbmV4
dCA9IGdyb3VwW2ldLCBub2RlOyAtLWkgPj0gMDspIHsKICAgICAgaWYgKG5vZGUgPSBncm91cFtp
XSkgewogICAgICAgIGlmIChuZXh0ICYmIG5vZGUuY29tcGFyZURvY3VtZW50UG9zaXRpb24obmV4
dCkgXiA0KSBuZXh0LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKG5vZGUsIG5leHQpOwogICAgICAg
IG5leHQgPSBub2RlOwogICAgICB9CiAgICB9CiAgfQoKICByZXR1cm4gdGhpczsKfQoKZnVuY3Rp
b24gc2VsZWN0aW9uX3NvcnQoY29tcGFyZSkgewogIGlmICghY29tcGFyZSkgY29tcGFyZSA9IGFz
Y2VuZGluZyQxOwoKICBmdW5jdGlvbiBjb21wYXJlTm9kZShhLCBiKSB7CiAgICByZXR1cm4gYSAm
JiBiID8gY29tcGFyZShhLl9fZGF0YV9fLCBiLl9fZGF0YV9fKSA6ICFhIC0gIWI7CiAgfQoKICBm
b3IgKHZhciBncm91cHMgPSB0aGlzLl9ncm91cHMsIG0gPSBncm91cHMubGVuZ3RoLCBzb3J0Z3Jv
dXBzID0gbmV3IEFycmF5KG0pLCBqID0gMDsgaiA8IG07ICsraikgewogICAgZm9yICh2YXIgZ3Jv
dXAgPSBncm91cHNbal0sIG4gPSBncm91cC5sZW5ndGgsIHNvcnRncm91cCA9IHNvcnRncm91cHNb
al0gPSBuZXcgQXJyYXkobiksIG5vZGUsIGkgPSAwOyBpIDwgbjsgKytpKSB7CiAgICAgIGlmIChu
b2RlID0gZ3JvdXBbaV0pIHsKICAgICAgICBzb3J0Z3JvdXBbaV0gPSBub2RlOwogICAgICB9CiAg
ICB9CiAgICBzb3J0Z3JvdXAuc29ydChjb21wYXJlTm9kZSk7CiAgfQoKICByZXR1cm4gbmV3IFNl
bGVjdGlvbihzb3J0Z3JvdXBzLCB0aGlzLl9wYXJlbnRzKS5vcmRlcigpOwp9CgpmdW5jdGlvbiBh
c2NlbmRpbmckMShhLCBiKSB7CiAgcmV0dXJuIGEgPCBiID8gLTEgOiBhID4gYiA/IDEgOiBhID49
IGIgPyAwIDogTmFOOwp9CgpmdW5jdGlvbiBzZWxlY3Rpb25fY2FsbCgpIHsKICB2YXIgY2FsbGJh
Y2sgPSBhcmd1bWVudHNbMF07CiAgYXJndW1lbnRzWzBdID0gdGhpczsKICBjYWxsYmFjay5hcHBs
eShudWxsLCBhcmd1bWVudHMpOwogIHJldHVybiB0aGlzOwp9CgpmdW5jdGlvbiBzZWxlY3Rpb25f
bm9kZXMoKSB7CiAgdmFyIG5vZGVzID0gbmV3IEFycmF5KHRoaXMuc2l6ZSgpKSwgaSA9IC0xOwog
IHRoaXMuZWFjaChmdW5jdGlvbigpIHsgbm9kZXNbKytpXSA9IHRoaXM7IH0pOwogIHJldHVybiBu
b2RlczsKfQoKZnVuY3Rpb24gc2VsZWN0aW9uX25vZGUoKSB7CgogIGZvciAodmFyIGdyb3VwcyA9
IHRoaXMuX2dyb3VwcywgaiA9IDAsIG0gPSBncm91cHMubGVuZ3RoOyBqIDwgbTsgKytqKSB7CiAg
ICBmb3IgKHZhciBncm91cCA9IGdyb3Vwc1tqXSwgaSA9IDAsIG4gPSBncm91cC5sZW5ndGg7IGkg
PCBuOyArK2kpIHsKICAgICAgdmFyIG5vZGUgPSBncm91cFtpXTsKICAgICAgaWYgKG5vZGUpIHJl
dHVybiBub2RlOwogICAgfQogIH0KCiAgcmV0dXJuIG51bGw7Cn0KCmZ1bmN0aW9uIHNlbGVjdGlv
bl9zaXplKCkgewogIHZhciBzaXplID0gMDsKICB0aGlzLmVhY2goZnVuY3Rpb24oKSB7ICsrc2l6
ZTsgfSk7CiAgcmV0dXJuIHNpemU7Cn0KCmZ1bmN0aW9uIHNlbGVjdGlvbl9lbXB0eSgpIHsKICBy
ZXR1cm4gIXRoaXMubm9kZSgpOwp9CgpmdW5jdGlvbiBzZWxlY3Rpb25fZWFjaChjYWxsYmFjaykg
ewoKICBmb3IgKHZhciBncm91cHMgPSB0aGlzLl9ncm91cHMsIGogPSAwLCBtID0gZ3JvdXBzLmxl
bmd0aDsgaiA8IG07ICsraikgewogICAgZm9yICh2YXIgZ3JvdXAgPSBncm91cHNbal0sIGkgPSAw
LCBuID0gZ3JvdXAubGVuZ3RoLCBub2RlOyBpIDwgbjsgKytpKSB7CiAgICAgIGlmIChub2RlID0g
Z3JvdXBbaV0pIGNhbGxiYWNrLmNhbGwobm9kZSwgbm9kZS5fX2RhdGFfXywgaSwgZ3JvdXApOwog
ICAgfQogIH0KCiAgcmV0dXJuIHRoaXM7Cn0KCmZ1bmN0aW9uIGF0dHJSZW1vdmUobmFtZSkgewog
IHJldHVybiBmdW5jdGlvbigpIHsKICAgIHRoaXMucmVtb3ZlQXR0cmlidXRlKG5hbWUpOwogIH07
Cn0KCmZ1bmN0aW9uIGF0dHJSZW1vdmVOUyhmdWxsbmFtZSkgewogIHJldHVybiBmdW5jdGlvbigp
IHsKICAgIHRoaXMucmVtb3ZlQXR0cmlidXRlTlMoZnVsbG5hbWUuc3BhY2UsIGZ1bGxuYW1lLmxv
Y2FsKTsKICB9Owp9CgpmdW5jdGlvbiBhdHRyQ29uc3RhbnQobmFtZSwgdmFsdWUpIHsKICByZXR1
cm4gZnVuY3Rpb24oKSB7CiAgICB0aGlzLnNldEF0dHJpYnV0ZShuYW1lLCB2YWx1ZSk7CiAgfTsK
fQoKZnVuY3Rpb24gYXR0ckNvbnN0YW50TlMoZnVsbG5hbWUsIHZhbHVlKSB7CiAgcmV0dXJuIGZ1
bmN0aW9uKCkgewogICAgdGhpcy5zZXRBdHRyaWJ1dGVOUyhmdWxsbmFtZS5zcGFjZSwgZnVsbG5h
bWUubG9jYWwsIHZhbHVlKTsKICB9Owp9CgpmdW5jdGlvbiBhdHRyRnVuY3Rpb24obmFtZSwgdmFs
dWUpIHsKICByZXR1cm4gZnVuY3Rpb24oKSB7CiAgICB2YXIgdiA9IHZhbHVlLmFwcGx5KHRoaXMs
IGFyZ3VtZW50cyk7CiAgICBpZiAodiA9PSBudWxsKSB0aGlzLnJlbW92ZUF0dHJpYnV0ZShuYW1l
KTsKICAgIGVsc2UgdGhpcy5zZXRBdHRyaWJ1dGUobmFtZSwgdik7CiAgfTsKfQoKZnVuY3Rpb24g
YXR0ckZ1bmN0aW9uTlMoZnVsbG5hbWUsIHZhbHVlKSB7CiAgcmV0dXJuIGZ1bmN0aW9uKCkgewog
ICAgdmFyIHYgPSB2YWx1ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgaWYgKHYgPT0gbnVs
bCkgdGhpcy5yZW1vdmVBdHRyaWJ1dGVOUyhmdWxsbmFtZS5zcGFjZSwgZnVsbG5hbWUubG9jYWwp
OwogICAgZWxzZSB0aGlzLnNldEF0dHJpYnV0ZU5TKGZ1bGxuYW1lLnNwYWNlLCBmdWxsbmFtZS5s
b2NhbCwgdik7CiAgfTsKfQoKZnVuY3Rpb24gc2VsZWN0aW9uX2F0dHIobmFtZSwgdmFsdWUpIHsK
ICB2YXIgZnVsbG5hbWUgPSBuYW1lc3BhY2UobmFtZSk7CgogIGlmIChhcmd1bWVudHMubGVuZ3Ro
IDwgMikgewogICAgdmFyIG5vZGUgPSB0aGlzLm5vZGUoKTsKICAgIHJldHVybiBmdWxsbmFtZS5s
b2NhbAogICAgICAgID8gbm9kZS5nZXRBdHRyaWJ1dGVOUyhmdWxsbmFtZS5zcGFjZSwgZnVsbG5h
bWUubG9jYWwpCiAgICAgICAgOiBub2RlLmdldEF0dHJpYnV0ZShmdWxsbmFtZSk7CiAgfQoKICBy
ZXR1cm4gdGhpcy5lYWNoKCh2YWx1ZSA9PSBudWxsCiAgICAgID8gKGZ1bGxuYW1lLmxvY2FsID8g
YXR0clJlbW92ZU5TIDogYXR0clJlbW92ZSkgOiAodHlwZW9mIHZhbHVlID09PSAiZnVuY3Rpb24i
CiAgICAgID8gKGZ1bGxuYW1lLmxvY2FsID8gYXR0ckZ1bmN0aW9uTlMgOiBhdHRyRnVuY3Rpb24p
CiAgICAgIDogKGZ1bGxuYW1lLmxvY2FsID8gYXR0ckNvbnN0YW50TlMgOiBhdHRyQ29uc3RhbnQp
KSkoZnVsbG5hbWUsIHZhbHVlKSk7Cn0KCmZ1bmN0aW9uIGRlZmF1bHRWaWV3KG5vZGUpIHsKICBy
ZXR1cm4gKG5vZGUub3duZXJEb2N1bWVudCAmJiBub2RlLm93bmVyRG9jdW1lbnQuZGVmYXVsdFZp
ZXcpIC8vIG5vZGUgaXMgYSBOb2RlCiAgICAgIHx8IChub2RlLmRvY3VtZW50ICYmIG5vZGUpIC8v
IG5vZGUgaXMgYSBXaW5kb3cKICAgICAgfHwgbm9kZS5kZWZhdWx0VmlldzsgLy8gbm9kZSBpcyBh
IERvY3VtZW50Cn0KCmZ1bmN0aW9uIHN0eWxlUmVtb3ZlKG5hbWUpIHsKICByZXR1cm4gZnVuY3Rp
b24oKSB7CiAgICB0aGlzLnN0eWxlLnJlbW92ZVByb3BlcnR5KG5hbWUpOwogIH07Cn0KCmZ1bmN0
aW9uIHN0eWxlQ29uc3RhbnQobmFtZSwgdmFsdWUsIHByaW9yaXR5KSB7CiAgcmV0dXJuIGZ1bmN0
aW9uKCkgewogICAgdGhpcy5zdHlsZS5zZXRQcm9wZXJ0eShuYW1lLCB2YWx1ZSwgcHJpb3JpdHkp
OwogIH07Cn0KCmZ1bmN0aW9uIHN0eWxlRnVuY3Rpb24obmFtZSwgdmFsdWUsIHByaW9yaXR5KSB7
CiAgcmV0dXJuIGZ1bmN0aW9uKCkgewogICAgdmFyIHYgPSB2YWx1ZS5hcHBseSh0aGlzLCBhcmd1
bWVudHMpOwogICAgaWYgKHYgPT0gbnVsbCkgdGhpcy5zdHlsZS5yZW1vdmVQcm9wZXJ0eShuYW1l
KTsKICAgIGVsc2UgdGhpcy5zdHlsZS5zZXRQcm9wZXJ0eShuYW1lLCB2LCBwcmlvcml0eSk7CiAg
fTsKfQoKZnVuY3Rpb24gc2VsZWN0aW9uX3N0eWxlKG5hbWUsIHZhbHVlLCBwcmlvcml0eSkgewog
IHJldHVybiBhcmd1bWVudHMubGVuZ3RoID4gMQogICAgICA/IHRoaXMuZWFjaCgodmFsdWUgPT0g
bnVsbAogICAgICAgICAgICA/IHN0eWxlUmVtb3ZlIDogdHlwZW9mIHZhbHVlID09PSAiZnVuY3Rp
b24iCiAgICAgICAgICAgID8gc3R5bGVGdW5jdGlvbgogICAgICAgICAgICA6IHN0eWxlQ29uc3Rh
bnQpKG5hbWUsIHZhbHVlLCBwcmlvcml0eSA9PSBudWxsID8gIiIgOiBwcmlvcml0eSkpCiAgICAg
IDogc3R5bGVWYWx1ZSh0aGlzLm5vZGUoKSwgbmFtZSk7Cn0KCmZ1bmN0aW9uIHN0eWxlVmFsdWUo
bm9kZSwgbmFtZSkgewogIHJldHVybiBub2RlLnN0eWxlLmdldFByb3BlcnR5VmFsdWUobmFtZSkK
ICAgICAgfHwgZGVmYXVsdFZpZXcobm9kZSkuZ2V0Q29tcHV0ZWRTdHlsZShub2RlLCBudWxsKS5n
ZXRQcm9wZXJ0eVZhbHVlKG5hbWUpOwp9CgpmdW5jdGlvbiBwcm9wZXJ0eVJlbW92ZShuYW1lKSB7
CiAgcmV0dXJuIGZ1bmN0aW9uKCkgewogICAgZGVsZXRlIHRoaXNbbmFtZV07CiAgfTsKfQoKZnVu
Y3Rpb24gcHJvcGVydHlDb25zdGFudChuYW1lLCB2YWx1ZSkgewogIHJldHVybiBmdW5jdGlvbigp
IHsKICAgIHRoaXNbbmFtZV0gPSB2YWx1ZTsKICB9Owp9CgpmdW5jdGlvbiBwcm9wZXJ0eUZ1bmN0
aW9uKG5hbWUsIHZhbHVlKSB7CiAgcmV0dXJuIGZ1bmN0aW9uKCkgewogICAgdmFyIHYgPSB2YWx1
ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgaWYgKHYgPT0gbnVsbCkgZGVsZXRlIHRoaXNb
bmFtZV07CiAgICBlbHNlIHRoaXNbbmFtZV0gPSB2OwogIH07Cn0KCmZ1bmN0aW9uIHNlbGVjdGlv
bl9wcm9wZXJ0eShuYW1lLCB2YWx1ZSkgewogIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID4gMQog
ICAgICA/IHRoaXMuZWFjaCgodmFsdWUgPT0gbnVsbAogICAgICAgICAgPyBwcm9wZXJ0eVJlbW92
ZSA6IHR5cGVvZiB2YWx1ZSA9PT0gImZ1bmN0aW9uIgogICAgICAgICAgPyBwcm9wZXJ0eUZ1bmN0
aW9uCiAgICAgICAgICA6IHByb3BlcnR5Q29uc3RhbnQpKG5hbWUsIHZhbHVlKSkKICAgICAgOiB0
aGlzLm5vZGUoKVtuYW1lXTsKfQoKZnVuY3Rpb24gY2xhc3NBcnJheShzdHJpbmcpIHsKICByZXR1
cm4gc3RyaW5nLnRyaW0oKS5zcGxpdCgvXnxccysvKTsKfQoKZnVuY3Rpb24gY2xhc3NMaXN0KG5v
ZGUpIHsKICByZXR1cm4gbm9kZS5jbGFzc0xpc3QgfHwgbmV3IENsYXNzTGlzdChub2RlKTsKfQoK
ZnVuY3Rpb24gQ2xhc3NMaXN0KG5vZGUpIHsKICB0aGlzLl9ub2RlID0gbm9kZTsKICB0aGlzLl9u
YW1lcyA9IGNsYXNzQXJyYXkobm9kZS5nZXRBdHRyaWJ1dGUoImNsYXNzIikgfHwgIiIpOwp9CgpD
bGFzc0xpc3QucHJvdG90eXBlID0gewogIGFkZDogZnVuY3Rpb24obmFtZSkgewogICAgdmFyIGkg
PSB0aGlzLl9uYW1lcy5pbmRleE9mKG5hbWUpOwogICAgaWYgKGkgPCAwKSB7CiAgICAgIHRoaXMu
X25hbWVzLnB1c2gobmFtZSk7CiAgICAgIHRoaXMuX25vZGUuc2V0QXR0cmlidXRlKCJjbGFzcyIs
IHRoaXMuX25hbWVzLmpvaW4oIiAiKSk7CiAgICB9CiAgfSwKICByZW1vdmU6IGZ1bmN0aW9uKG5h
bWUpIHsKICAgIHZhciBpID0gdGhpcy5fbmFtZXMuaW5kZXhPZihuYW1lKTsKICAgIGlmIChpID49
IDApIHsKICAgICAgdGhpcy5fbmFtZXMuc3BsaWNlKGksIDEpOwogICAgICB0aGlzLl9ub2RlLnNl
dEF0dHJpYnV0ZSgiY2xhc3MiLCB0aGlzLl9uYW1lcy5qb2luKCIgIikpOwogICAgfQogIH0sCiAg
Y29udGFpbnM6IGZ1bmN0aW9uKG5hbWUpIHsKICAgIHJldHVybiB0aGlzLl9uYW1lcy5pbmRleE9m
KG5hbWUpID49IDA7CiAgfQp9OwoKZnVuY3Rpb24gY2xhc3NlZEFkZChub2RlLCBuYW1lcykgewog
IHZhciBsaXN0ID0gY2xhc3NMaXN0KG5vZGUpLCBpID0gLTEsIG4gPSBuYW1lcy5sZW5ndGg7CiAg
d2hpbGUgKCsraSA8IG4pIGxpc3QuYWRkKG5hbWVzW2ldKTsKfQoKZnVuY3Rpb24gY2xhc3NlZFJl
bW92ZShub2RlLCBuYW1lcykgewogIHZhciBsaXN0ID0gY2xhc3NMaXN0KG5vZGUpLCBpID0gLTEs
IG4gPSBuYW1lcy5sZW5ndGg7CiAgd2hpbGUgKCsraSA8IG4pIGxpc3QucmVtb3ZlKG5hbWVzW2ld
KTsKfQoKZnVuY3Rpb24gY2xhc3NlZFRydWUobmFtZXMpIHsKICByZXR1cm4gZnVuY3Rpb24oKSB7
CiAgICBjbGFzc2VkQWRkKHRoaXMsIG5hbWVzKTsKICB9Owp9CgpmdW5jdGlvbiBjbGFzc2VkRmFs
c2UobmFtZXMpIHsKICByZXR1cm4gZnVuY3Rpb24oKSB7CiAgICBjbGFzc2VkUmVtb3ZlKHRoaXMs
IG5hbWVzKTsKICB9Owp9CgpmdW5jdGlvbiBjbGFzc2VkRnVuY3Rpb24obmFtZXMsIHZhbHVlKSB7
CiAgcmV0dXJuIGZ1bmN0aW9uKCkgewogICAgKHZhbHVlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykg
PyBjbGFzc2VkQWRkIDogY2xhc3NlZFJlbW92ZSkodGhpcywgbmFtZXMpOwogIH07Cn0KCmZ1bmN0
aW9uIHNlbGVjdGlvbl9jbGFzc2VkKG5hbWUsIHZhbHVlKSB7CiAgdmFyIG5hbWVzID0gY2xhc3NB
cnJheShuYW1lICsgIiIpOwoKICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDIpIHsKICAgIHZhciBs
aXN0ID0gY2xhc3NMaXN0KHRoaXMubm9kZSgpKSwgaSA9IC0xLCBuID0gbmFtZXMubGVuZ3RoOwog
ICAgd2hpbGUgKCsraSA8IG4pIGlmICghbGlzdC5jb250YWlucyhuYW1lc1tpXSkpIHJldHVybiBm
YWxzZTsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgcmV0dXJuIHRoaXMuZWFjaCgodHlwZW9mIHZh
bHVlID09PSAiZnVuY3Rpb24iCiAgICAgID8gY2xhc3NlZEZ1bmN0aW9uIDogdmFsdWUKICAgICAg
PyBjbGFzc2VkVHJ1ZQogICAgICA6IGNsYXNzZWRGYWxzZSkobmFtZXMsIHZhbHVlKSk7Cn0KCmZ1
bmN0aW9uIHRleHRSZW1vdmUoKSB7CiAgdGhpcy50ZXh0Q29udGVudCA9ICIiOwp9CgpmdW5jdGlv
biB0ZXh0Q29uc3RhbnQodmFsdWUpIHsKICByZXR1cm4gZnVuY3Rpb24oKSB7CiAgICB0aGlzLnRl
eHRDb250ZW50ID0gdmFsdWU7CiAgfTsKfQoKZnVuY3Rpb24gdGV4dEZ1bmN0aW9uKHZhbHVlKSB7
CiAgcmV0dXJuIGZ1bmN0aW9uKCkgewogICAgdmFyIHYgPSB2YWx1ZS5hcHBseSh0aGlzLCBhcmd1
bWVudHMpOwogICAgdGhpcy50ZXh0Q29udGVudCA9IHYgPT0gbnVsbCA/ICIiIDogdjsKICB9Owp9
CgpmdW5jdGlvbiBzZWxlY3Rpb25fdGV4dCh2YWx1ZSkgewogIHJldHVybiBhcmd1bWVudHMubGVu
Z3RoCiAgICAgID8gdGhpcy5lYWNoKHZhbHVlID09IG51bGwKICAgICAgICAgID8gdGV4dFJlbW92
ZSA6ICh0eXBlb2YgdmFsdWUgPT09ICJmdW5jdGlvbiIKICAgICAgICAgID8gdGV4dEZ1bmN0aW9u
CiAgICAgICAgICA6IHRleHRDb25zdGFudCkodmFsdWUpKQogICAgICA6IHRoaXMubm9kZSgpLnRl
eHRDb250ZW50Owp9CgpmdW5jdGlvbiBodG1sUmVtb3ZlKCkgewogIHRoaXMuaW5uZXJIVE1MID0g
IiI7Cn0KCmZ1bmN0aW9uIGh0bWxDb25zdGFudCh2YWx1ZSkgewogIHJldHVybiBmdW5jdGlvbigp
IHsKICAgIHRoaXMuaW5uZXJIVE1MID0gdmFsdWU7CiAgfTsKfQoKZnVuY3Rpb24gaHRtbEZ1bmN0
aW9uKHZhbHVlKSB7CiAgcmV0dXJuIGZ1bmN0aW9uKCkgewogICAgdmFyIHYgPSB2YWx1ZS5hcHBs
eSh0aGlzLCBhcmd1bWVudHMpOwogICAgdGhpcy5pbm5lckhUTUwgPSB2ID09IG51bGwgPyAiIiA6
IHY7CiAgfTsKfQoKZnVuY3Rpb24gc2VsZWN0aW9uX2h0bWwodmFsdWUpIHsKICByZXR1cm4gYXJn
dW1lbnRzLmxlbmd0aAogICAgICA/IHRoaXMuZWFjaCh2YWx1ZSA9PSBudWxsCiAgICAgICAgICA/
IGh0bWxSZW1vdmUgOiAodHlwZW9mIHZhbHVlID09PSAiZnVuY3Rpb24iCiAgICAgICAgICA/IGh0
bWxGdW5jdGlvbgogICAgICAgICAgOiBodG1sQ29uc3RhbnQpKHZhbHVlKSkKICAgICAgOiB0aGlz
Lm5vZGUoKS5pbm5lckhUTUw7Cn0KCmZ1bmN0aW9uIHJhaXNlKCkgewogIGlmICh0aGlzLm5leHRT
aWJsaW5nKSB0aGlzLnBhcmVudE5vZGUuYXBwZW5kQ2hpbGQodGhpcyk7Cn0KCmZ1bmN0aW9uIHNl
bGVjdGlvbl9yYWlzZSgpIHsKICByZXR1cm4gdGhpcy5lYWNoKHJhaXNlKTsKfQoKZnVuY3Rpb24g
bG93ZXIoKSB7CiAgaWYgKHRoaXMucHJldmlvdXNTaWJsaW5nKSB0aGlzLnBhcmVudE5vZGUuaW5z
ZXJ0QmVmb3JlKHRoaXMsIHRoaXMucGFyZW50Tm9kZS5maXJzdENoaWxkKTsKfQoKZnVuY3Rpb24g
c2VsZWN0aW9uX2xvd2VyKCkgewogIHJldHVybiB0aGlzLmVhY2gobG93ZXIpOwp9CgpmdW5jdGlv
biBzZWxlY3Rpb25fYXBwZW5kKG5hbWUpIHsKICB2YXIgY3JlYXRlID0gdHlwZW9mIG5hbWUgPT09
ICJmdW5jdGlvbiIgPyBuYW1lIDogY3JlYXRvcihuYW1lKTsKICByZXR1cm4gdGhpcy5zZWxlY3Qo
ZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gdGhpcy5hcHBlbmRDaGlsZChjcmVhdGUuYXBwbHkodGhp
cywgYXJndW1lbnRzKSk7CiAgfSk7Cn0KCmZ1bmN0aW9uIGNvbnN0YW50TnVsbCgpIHsKICByZXR1
cm4gbnVsbDsKfQoKZnVuY3Rpb24gc2VsZWN0aW9uX2luc2VydChuYW1lLCBiZWZvcmUpIHsKICB2
YXIgY3JlYXRlID0gdHlwZW9mIG5hbWUgPT09ICJmdW5jdGlvbiIgPyBuYW1lIDogY3JlYXRvcihu
YW1lKSwKICAgICAgc2VsZWN0ID0gYmVmb3JlID09IG51bGwgPyBjb25zdGFudE51bGwgOiB0eXBl
b2YgYmVmb3JlID09PSAiZnVuY3Rpb24iID8gYmVmb3JlIDogc2VsZWN0b3IoYmVmb3JlKTsKICBy
ZXR1cm4gdGhpcy5zZWxlY3QoZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gdGhpcy5pbnNlcnRCZWZv
cmUoY3JlYXRlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyksIHNlbGVjdC5hcHBseSh0aGlzLCBhcmd1
bWVudHMpIHx8IG51bGwpOwogIH0pOwp9CgpmdW5jdGlvbiByZW1vdmUoKSB7CiAgdmFyIHBhcmVu
dCA9IHRoaXMucGFyZW50Tm9kZTsKICBpZiAocGFyZW50KSBwYXJlbnQucmVtb3ZlQ2hpbGQodGhp
cyk7Cn0KCmZ1bmN0aW9uIHNlbGVjdGlvbl9yZW1vdmUoKSB7CiAgcmV0dXJuIHRoaXMuZWFjaChy
ZW1vdmUpOwp9CgpmdW5jdGlvbiBzZWxlY3Rpb25fY2xvbmVTaGFsbG93KCkgewogIHZhciBjbG9u
ZSA9IHRoaXMuY2xvbmVOb2RlKGZhbHNlKSwgcGFyZW50ID0gdGhpcy5wYXJlbnROb2RlOwogIHJl
dHVybiBwYXJlbnQgPyBwYXJlbnQuaW5zZXJ0QmVmb3JlKGNsb25lLCB0aGlzLm5leHRTaWJsaW5n
KSA6IGNsb25lOwp9CgpmdW5jdGlvbiBzZWxlY3Rpb25fY2xvbmVEZWVwKCkgewogIHZhciBjbG9u
ZSA9IHRoaXMuY2xvbmVOb2RlKHRydWUpLCBwYXJlbnQgPSB0aGlzLnBhcmVudE5vZGU7CiAgcmV0
dXJuIHBhcmVudCA/IHBhcmVudC5pbnNlcnRCZWZvcmUoY2xvbmUsIHRoaXMubmV4dFNpYmxpbmcp
IDogY2xvbmU7Cn0KCmZ1bmN0aW9uIHNlbGVjdGlvbl9jbG9uZShkZWVwKSB7CiAgcmV0dXJuIHRo
aXMuc2VsZWN0KGRlZXAgPyBzZWxlY3Rpb25fY2xvbmVEZWVwIDogc2VsZWN0aW9uX2Nsb25lU2hh
bGxvdyk7Cn0KCmZ1bmN0aW9uIHNlbGVjdGlvbl9kYXR1bSh2YWx1ZSkgewogIHJldHVybiBhcmd1
bWVudHMubGVuZ3RoCiAgICAgID8gdGhpcy5wcm9wZXJ0eSgiX19kYXRhX18iLCB2YWx1ZSkKICAg
ICAgOiB0aGlzLm5vZGUoKS5fX2RhdGFfXzsKfQoKdmFyIGZpbHRlckV2ZW50cyA9IHt9OwoKZXhw
b3J0cy5ldmVudCA9IG51bGw7CgppZiAodHlwZW9mIGRvY3VtZW50ICE9PSAidW5kZWZpbmVkIikg
ewogIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50OwogIGlmICghKCJvbm1v
dXNlZW50ZXIiIGluIGVsZW1lbnQpKSB7CiAgICBmaWx0ZXJFdmVudHMgPSB7bW91c2VlbnRlcjog
Im1vdXNlb3ZlciIsIG1vdXNlbGVhdmU6ICJtb3VzZW91dCJ9OwogIH0KfQoKZnVuY3Rpb24gZmls
dGVyQ29udGV4dExpc3RlbmVyKGxpc3RlbmVyLCBpbmRleCwgZ3JvdXApIHsKICBsaXN0ZW5lciA9
IGNvbnRleHRMaXN0ZW5lcihsaXN0ZW5lciwgaW5kZXgsIGdyb3VwKTsKICByZXR1cm4gZnVuY3Rp
b24oZXZlbnQpIHsKICAgIHZhciByZWxhdGVkID0gZXZlbnQucmVsYXRlZFRhcmdldDsKICAgIGlm
ICghcmVsYXRlZCB8fCAocmVsYXRlZCAhPT0gdGhpcyAmJiAhKHJlbGF0ZWQuY29tcGFyZURvY3Vt
ZW50UG9zaXRpb24odGhpcykgJiA4KSkpIHsKICAgICAgbGlzdGVuZXIuY2FsbCh0aGlzLCBldmVu
dCk7CiAgICB9CiAgfTsKfQoKZnVuY3Rpb24gY29udGV4dExpc3RlbmVyKGxpc3RlbmVyLCBpbmRl
eCwgZ3JvdXApIHsKICByZXR1cm4gZnVuY3Rpb24oZXZlbnQxKSB7CiAgICB2YXIgZXZlbnQwID0g
ZXhwb3J0cy5ldmVudDsgLy8gRXZlbnRzIGNhbiBiZSByZWVudHJhbnQgKGUuZy4sIGZvY3VzKS4K
ICAgIGV4cG9ydHMuZXZlbnQgPSBldmVudDE7CiAgICB0cnkgewogICAgICBsaXN0ZW5lci5jYWxs
KHRoaXMsIHRoaXMuX19kYXRhX18sIGluZGV4LCBncm91cCk7CiAgICB9IGZpbmFsbHkgewogICAg
ICBleHBvcnRzLmV2ZW50ID0gZXZlbnQwOwogICAgfQogIH07Cn0KCmZ1bmN0aW9uIHBhcnNlVHlw
ZW5hbWVzJDEodHlwZW5hbWVzKSB7CiAgcmV0dXJuIHR5cGVuYW1lcy50cmltKCkuc3BsaXQoL158
XHMrLykubWFwKGZ1bmN0aW9uKHQpIHsKICAgIHZhciBuYW1lID0gIiIsIGkgPSB0LmluZGV4T2Yo
Ii4iKTsKICAgIGlmIChpID49IDApIG5hbWUgPSB0LnNsaWNlKGkgKyAxKSwgdCA9IHQuc2xpY2Uo
MCwgaSk7CiAgICByZXR1cm4ge3R5cGU6IHQsIG5hbWU6IG5hbWV9OwogIH0pOwp9CgpmdW5jdGlv
biBvblJlbW92ZSh0eXBlbmFtZSkgewogIHJldHVybiBmdW5jdGlvbigpIHsKICAgIHZhciBvbiA9
IHRoaXMuX19vbjsKICAgIGlmICghb24pIHJldHVybjsKICAgIGZvciAodmFyIGogPSAwLCBpID0g
LTEsIG0gPSBvbi5sZW5ndGgsIG87IGogPCBtOyArK2opIHsKICAgICAgaWYgKG8gPSBvbltqXSwg
KCF0eXBlbmFtZS50eXBlIHx8IG8udHlwZSA9PT0gdHlwZW5hbWUudHlwZSkgJiYgby5uYW1lID09
PSB0eXBlbmFtZS5uYW1lKSB7CiAgICAgICAgdGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKG8udHlw
ZSwgby5saXN0ZW5lciwgby5jYXB0dXJlKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBvblsrK2ld
ID0gbzsKICAgICAgfQogICAgfQogICAgaWYgKCsraSkgb24ubGVuZ3RoID0gaTsKICAgIGVsc2Ug
ZGVsZXRlIHRoaXMuX19vbjsKICB9Owp9CgpmdW5jdGlvbiBvbkFkZCh0eXBlbmFtZSwgdmFsdWUs
IGNhcHR1cmUpIHsKICB2YXIgd3JhcCA9IGZpbHRlckV2ZW50cy5oYXNPd25Qcm9wZXJ0eSh0eXBl
bmFtZS50eXBlKSA/IGZpbHRlckNvbnRleHRMaXN0ZW5lciA6IGNvbnRleHRMaXN0ZW5lcjsKICBy
ZXR1cm4gZnVuY3Rpb24oZCwgaSwgZ3JvdXApIHsKICAgIHZhciBvbiA9IHRoaXMuX19vbiwgbywg
bGlzdGVuZXIgPSB3cmFwKHZhbHVlLCBpLCBncm91cCk7CiAgICBpZiAob24pIGZvciAodmFyIGog
PSAwLCBtID0gb24ubGVuZ3RoOyBqIDwgbTsgKytqKSB7CiAgICAgIGlmICgobyA9IG9uW2pdKS50
eXBlID09PSB0eXBlbmFtZS50eXBlICYmIG8ubmFtZSA9PT0gdHlwZW5hbWUubmFtZSkgewogICAg
ICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcihvLnR5cGUsIG8ubGlzdGVuZXIsIG8uY2FwdHVy
ZSk7CiAgICAgICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKG8udHlwZSwgby5saXN0ZW5lciA9IGxp
c3RlbmVyLCBvLmNhcHR1cmUgPSBjYXB0dXJlKTsKICAgICAgICBvLnZhbHVlID0gdmFsdWU7CiAg
ICAgICAgcmV0dXJuOwogICAgICB9CiAgICB9CiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIodHlw
ZW5hbWUudHlwZSwgbGlzdGVuZXIsIGNhcHR1cmUpOwogICAgbyA9IHt0eXBlOiB0eXBlbmFtZS50
eXBlLCBuYW1lOiB0eXBlbmFtZS5uYW1lLCB2YWx1ZTogdmFsdWUsIGxpc3RlbmVyOiBsaXN0ZW5l
ciwgY2FwdHVyZTogY2FwdHVyZX07CiAgICBpZiAoIW9uKSB0aGlzLl9fb24gPSBbb107CiAgICBl
bHNlIG9uLnB1c2gobyk7CiAgfTsKfQoKZnVuY3Rpb24gc2VsZWN0aW9uX29uKHR5cGVuYW1lLCB2
YWx1ZSwgY2FwdHVyZSkgewogIHZhciB0eXBlbmFtZXMgPSBwYXJzZVR5cGVuYW1lcyQxKHR5cGVu
YW1lICsgIiIpLCBpLCBuID0gdHlwZW5hbWVzLmxlbmd0aCwgdDsKCiAgaWYgKGFyZ3VtZW50cy5s
ZW5ndGggPCAyKSB7CiAgICB2YXIgb24gPSB0aGlzLm5vZGUoKS5fX29uOwogICAgaWYgKG9uKSBm
b3IgKHZhciBqID0gMCwgbSA9IG9uLmxlbmd0aCwgbzsgaiA8IG07ICsraikgewogICAgICBmb3Ig
KGkgPSAwLCBvID0gb25bal07IGkgPCBuOyArK2kpIHsKICAgICAgICBpZiAoKHQgPSB0eXBlbmFt
ZXNbaV0pLnR5cGUgPT09IG8udHlwZSAmJiB0Lm5hbWUgPT09IG8ubmFtZSkgewogICAgICAgICAg
cmV0dXJuIG8udmFsdWU7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgICByZXR1cm47CiAgfQoK
ICBvbiA9IHZhbHVlID8gb25BZGQgOiBvblJlbW92ZTsKICBpZiAoY2FwdHVyZSA9PSBudWxsKSBj
YXB0dXJlID0gZmFsc2U7CiAgZm9yIChpID0gMDsgaSA8IG47ICsraSkgdGhpcy5lYWNoKG9uKHR5
cGVuYW1lc1tpXSwgdmFsdWUsIGNhcHR1cmUpKTsKICByZXR1cm4gdGhpczsKfQoKZnVuY3Rpb24g
Y3VzdG9tRXZlbnQoZXZlbnQxLCBsaXN0ZW5lciwgdGhhdCwgYXJncykgewogIHZhciBldmVudDAg
PSBleHBvcnRzLmV2ZW50OwogIGV2ZW50MS5zb3VyY2VFdmVudCA9IGV4cG9ydHMuZXZlbnQ7CiAg
ZXhwb3J0cy5ldmVudCA9IGV2ZW50MTsKICB0cnkgewogICAgcmV0dXJuIGxpc3RlbmVyLmFwcGx5
KHRoYXQsIGFyZ3MpOwogIH0gZmluYWxseSB7CiAgICBleHBvcnRzLmV2ZW50ID0gZXZlbnQwOwog
IH0KfQoKZnVuY3Rpb24gZGlzcGF0Y2hFdmVudChub2RlLCB0eXBlLCBwYXJhbXMpIHsKICB2YXIg
d2luZG93ID0gZGVmYXVsdFZpZXcobm9kZSksCiAgICAgIGV2ZW50ID0gd2luZG93LkN1c3RvbUV2
ZW50OwoKICBpZiAodHlwZW9mIGV2ZW50ID09PSAiZnVuY3Rpb24iKSB7CiAgICBldmVudCA9IG5l
dyBldmVudCh0eXBlLCBwYXJhbXMpOwogIH0gZWxzZSB7CiAgICBldmVudCA9IHdpbmRvdy5kb2N1
bWVudC5jcmVhdGVFdmVudCgiRXZlbnQiKTsKICAgIGlmIChwYXJhbXMpIGV2ZW50LmluaXRFdmVu
dCh0eXBlLCBwYXJhbXMuYnViYmxlcywgcGFyYW1zLmNhbmNlbGFibGUpLCBldmVudC5kZXRhaWwg
PSBwYXJhbXMuZGV0YWlsOwogICAgZWxzZSBldmVudC5pbml0RXZlbnQodHlwZSwgZmFsc2UsIGZh
bHNlKTsKICB9CgogIG5vZGUuZGlzcGF0Y2hFdmVudChldmVudCk7Cn0KCmZ1bmN0aW9uIGRpc3Bh
dGNoQ29uc3RhbnQodHlwZSwgcGFyYW1zKSB7CiAgcmV0dXJuIGZ1bmN0aW9uKCkgewogICAgcmV0
dXJuIGRpc3BhdGNoRXZlbnQodGhpcywgdHlwZSwgcGFyYW1zKTsKICB9Owp9CgpmdW5jdGlvbiBk
aXNwYXRjaEZ1bmN0aW9uKHR5cGUsIHBhcmFtcykgewogIHJldHVybiBmdW5jdGlvbigpIHsKICAg
IHJldHVybiBkaXNwYXRjaEV2ZW50KHRoaXMsIHR5cGUsIHBhcmFtcy5hcHBseSh0aGlzLCBhcmd1
bWVudHMpKTsKICB9Owp9CgpmdW5jdGlvbiBzZWxlY3Rpb25fZGlzcGF0Y2godHlwZSwgcGFyYW1z
KSB7CiAgcmV0dXJuIHRoaXMuZWFjaCgodHlwZW9mIHBhcmFtcyA9PT0gImZ1bmN0aW9uIgogICAg
ICA/IGRpc3BhdGNoRnVuY3Rpb24KICAgICAgOiBkaXNwYXRjaENvbnN0YW50KSh0eXBlLCBwYXJh
bXMpKTsKfQoKdmFyIHJvb3QgPSBbbnVsbF07CgpmdW5jdGlvbiBTZWxlY3Rpb24oZ3JvdXBzLCBw
YXJlbnRzKSB7CiAgdGhpcy5fZ3JvdXBzID0gZ3JvdXBzOwogIHRoaXMuX3BhcmVudHMgPSBwYXJl
bnRzOwp9CgpmdW5jdGlvbiBzZWxlY3Rpb24oKSB7CiAgcmV0dXJuIG5ldyBTZWxlY3Rpb24oW1tk
b2N1bWVudC5kb2N1bWVudEVsZW1lbnRdXSwgcm9vdCk7Cn0KClNlbGVjdGlvbi5wcm90b3R5cGUg
PSBzZWxlY3Rpb24ucHJvdG90eXBlID0gewogIGNvbnN0cnVjdG9yOiBTZWxlY3Rpb24sCiAgc2Vs
ZWN0OiBzZWxlY3Rpb25fc2VsZWN0LAogIHNlbGVjdEFsbDogc2VsZWN0aW9uX3NlbGVjdEFsbCwK
ICBmaWx0ZXI6IHNlbGVjdGlvbl9maWx0ZXIsCiAgZGF0YTogc2VsZWN0aW9uX2RhdGEsCiAgZW50
ZXI6IHNlbGVjdGlvbl9lbnRlciwKICBleGl0OiBzZWxlY3Rpb25fZXhpdCwKICBqb2luOiBzZWxl
Y3Rpb25fam9pbiwKICBtZXJnZTogc2VsZWN0aW9uX21lcmdlLAogIG9yZGVyOiBzZWxlY3Rpb25f
b3JkZXIsCiAgc29ydDogc2VsZWN0aW9uX3NvcnQsCiAgY2FsbDogc2VsZWN0aW9uX2NhbGwsCiAg
bm9kZXM6IHNlbGVjdGlvbl9ub2RlcywKICBub2RlOiBzZWxlY3Rpb25fbm9kZSwKICBzaXplOiBz
ZWxlY3Rpb25fc2l6ZSwKICBlbXB0eTogc2VsZWN0aW9uX2VtcHR5LAogIGVhY2g6IHNlbGVjdGlv
bl9lYWNoLAogIGF0dHI6IHNlbGVjdGlvbl9hdHRyLAogIHN0eWxlOiBzZWxlY3Rpb25fc3R5bGUs
CiAgcHJvcGVydHk6IHNlbGVjdGlvbl9wcm9wZXJ0eSwKICBjbGFzc2VkOiBzZWxlY3Rpb25fY2xh
c3NlZCwKICB0ZXh0OiBzZWxlY3Rpb25fdGV4dCwKICBodG1sOiBzZWxlY3Rpb25faHRtbCwKICBy
YWlzZTogc2VsZWN0aW9uX3JhaXNlLAogIGxvd2VyOiBzZWxlY3Rpb25fbG93ZXIsCiAgYXBwZW5k
OiBzZWxlY3Rpb25fYXBwZW5kLAogIGluc2VydDogc2VsZWN0aW9uX2luc2VydCwKICByZW1vdmU6
IHNlbGVjdGlvbl9yZW1vdmUsCiAgY2xvbmU6IHNlbGVjdGlvbl9jbG9uZSwKICBkYXR1bTogc2Vs
ZWN0aW9uX2RhdHVtLAogIG9uOiBzZWxlY3Rpb25fb24sCiAgZGlzcGF0Y2g6IHNlbGVjdGlvbl9k
aXNwYXRjaAp9OwoKZnVuY3Rpb24gc2VsZWN0KHNlbGVjdG9yKSB7CiAgcmV0dXJuIHR5cGVvZiBz
ZWxlY3RvciA9PT0gInN0cmluZyIKICAgICAgPyBuZXcgU2VsZWN0aW9uKFtbZG9jdW1lbnQucXVl
cnlTZWxlY3RvcihzZWxlY3RvcildXSwgW2RvY3VtZW50LmRvY3VtZW50RWxlbWVudF0pCiAgICAg
IDogbmV3IFNlbGVjdGlvbihbW3NlbGVjdG9yXV0sIHJvb3QpOwp9CgpmdW5jdGlvbiBjcmVhdGUo
bmFtZSkgewogIHJldHVybiBzZWxlY3QoY3JlYXRvcihuYW1lKS5jYWxsKGRvY3VtZW50LmRvY3Vt
ZW50RWxlbWVudCkpOwp9Cgp2YXIgbmV4dElkID0gMDsKCmZ1bmN0aW9uIGxvY2FsKCkgewogIHJl
dHVybiBuZXcgTG9jYWw7Cn0KCmZ1bmN0aW9uIExvY2FsKCkgewogIHRoaXMuXyA9ICJAIiArICgr
K25leHRJZCkudG9TdHJpbmcoMzYpOwp9CgpMb2NhbC5wcm90b3R5cGUgPSBsb2NhbC5wcm90b3R5
cGUgPSB7CiAgY29uc3RydWN0b3I6IExvY2FsLAogIGdldDogZnVuY3Rpb24obm9kZSkgewogICAg
dmFyIGlkID0gdGhpcy5fOwogICAgd2hpbGUgKCEoaWQgaW4gbm9kZSkpIGlmICghKG5vZGUgPSBu
b2RlLnBhcmVudE5vZGUpKSByZXR1cm47CiAgICByZXR1cm4gbm9kZVtpZF07CiAgfSwKICBzZXQ6
IGZ1bmN0aW9uKG5vZGUsIHZhbHVlKSB7CiAgICByZXR1cm4gbm9kZVt0aGlzLl9dID0gdmFsdWU7
CiAgfSwKICByZW1vdmU6IGZ1bmN0aW9uKG5vZGUpIHsKICAgIHJldHVybiB0aGlzLl8gaW4gbm9k
ZSAmJiBkZWxldGUgbm9kZVt0aGlzLl9dOwogIH0sCiAgdG9TdHJpbmc6IGZ1bmN0aW9uKCkgewog
ICAgcmV0dXJuIHRoaXMuXzsKICB9Cn07CgpmdW5jdGlvbiBzb3VyY2VFdmVudCgpIHsKICB2YXIg
Y3VycmVudCA9IGV4cG9ydHMuZXZlbnQsIHNvdXJjZTsKICB3aGlsZSAoc291cmNlID0gY3VycmVu
dC5zb3VyY2VFdmVudCkgY3VycmVudCA9IHNvdXJjZTsKICByZXR1cm4gY3VycmVudDsKfQoKZnVu
Y3Rpb24gcG9pbnQobm9kZSwgZXZlbnQpIHsKICB2YXIgc3ZnID0gbm9kZS5vd25lclNWR0VsZW1l
bnQgfHwgbm9kZTsKCiAgaWYgKHN2Zy5jcmVhdGVTVkdQb2ludCkgewogICAgdmFyIHBvaW50ID0g
c3ZnLmNyZWF0ZVNWR1BvaW50KCk7CiAgICBwb2ludC54ID0gZXZlbnQuY2xpZW50WCwgcG9pbnQu
eSA9IGV2ZW50LmNsaWVudFk7CiAgICBwb2ludCA9IHBvaW50Lm1hdHJpeFRyYW5zZm9ybShub2Rl
LmdldFNjcmVlbkNUTSgpLmludmVyc2UoKSk7CiAgICByZXR1cm4gW3BvaW50LngsIHBvaW50Lnld
OwogIH0KCiAgdmFyIHJlY3QgPSBub2RlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpOwogIHJldHVy
biBbZXZlbnQuY2xpZW50WCAtIHJlY3QubGVmdCAtIG5vZGUuY2xpZW50TGVmdCwgZXZlbnQuY2xp
ZW50WSAtIHJlY3QudG9wIC0gbm9kZS5jbGllbnRUb3BdOwp9CgpmdW5jdGlvbiBtb3VzZShub2Rl
KSB7CiAgdmFyIGV2ZW50ID0gc291cmNlRXZlbnQoKTsKICBpZiAoZXZlbnQuY2hhbmdlZFRvdWNo
ZXMpIGV2ZW50ID0gZXZlbnQuY2hhbmdlZFRvdWNoZXNbMF07CiAgcmV0dXJuIHBvaW50KG5vZGUs
IGV2ZW50KTsKfQoKZnVuY3Rpb24gc2VsZWN0QWxsKHNlbGVjdG9yKSB7CiAgcmV0dXJuIHR5cGVv
ZiBzZWxlY3RvciA9PT0gInN0cmluZyIKICAgICAgPyBuZXcgU2VsZWN0aW9uKFtkb2N1bWVudC5x
dWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKV0sIFtkb2N1bWVudC5kb2N1bWVudEVsZW1lbnRdKQog
ICAgICA6IG5ldyBTZWxlY3Rpb24oW3NlbGVjdG9yID09IG51bGwgPyBbXSA6IHNlbGVjdG9yXSwg
cm9vdCk7Cn0KCmZ1bmN0aW9uIHRvdWNoKG5vZGUsIHRvdWNoZXMsIGlkZW50aWZpZXIpIHsKICBp
ZiAoYXJndW1lbnRzLmxlbmd0aCA8IDMpIGlkZW50aWZpZXIgPSB0b3VjaGVzLCB0b3VjaGVzID0g
c291cmNlRXZlbnQoKS5jaGFuZ2VkVG91Y2hlczsKCiAgZm9yICh2YXIgaSA9IDAsIG4gPSB0b3Vj
aGVzID8gdG91Y2hlcy5sZW5ndGggOiAwLCB0b3VjaDsgaSA8IG47ICsraSkgewogICAgaWYgKCh0
b3VjaCA9IHRvdWNoZXNbaV0pLmlkZW50aWZpZXIgPT09IGlkZW50aWZpZXIpIHsKICAgICAgcmV0
dXJuIHBvaW50KG5vZGUsIHRvdWNoKTsKICAgIH0KICB9CgogIHJldHVybiBudWxsOwp9CgpmdW5j
dGlvbiB0b3VjaGVzKG5vZGUsIHRvdWNoZXMpIHsKICBpZiAodG91Y2hlcyA9PSBudWxsKSB0b3Vj
aGVzID0gc291cmNlRXZlbnQoKS50b3VjaGVzOwoKICBmb3IgKHZhciBpID0gMCwgbiA9IHRvdWNo
ZXMgPyB0b3VjaGVzLmxlbmd0aCA6IDAsIHBvaW50cyA9IG5ldyBBcnJheShuKTsgaSA8IG47ICsr
aSkgewogICAgcG9pbnRzW2ldID0gcG9pbnQobm9kZSwgdG91Y2hlc1tpXSk7CiAgfQoKICByZXR1
cm4gcG9pbnRzOwp9CgpmdW5jdGlvbiBub3Byb3BhZ2F0aW9uKCkgewogIGV4cG9ydHMuZXZlbnQu
c3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7Cn0KCmZ1bmN0aW9uIG5vZXZlbnQoKSB7CiAgZXhw
b3J0cy5ldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogIGV4cG9ydHMuZXZlbnQuc3RvcEltbWVkaWF0
ZVByb3BhZ2F0aW9uKCk7Cn0KCmZ1bmN0aW9uIGRyYWdEaXNhYmxlKHZpZXcpIHsKICB2YXIgcm9v
dCA9IHZpZXcuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LAogICAgICBzZWxlY3Rpb24gPSBzZWxl
Y3Qodmlldykub24oImRyYWdzdGFydC5kcmFnIiwgbm9ldmVudCwgdHJ1ZSk7CiAgaWYgKCJvbnNl
bGVjdHN0YXJ0IiBpbiByb290KSB7CiAgICBzZWxlY3Rpb24ub24oInNlbGVjdHN0YXJ0LmRyYWci
LCBub2V2ZW50LCB0cnVlKTsKICB9IGVsc2UgewogICAgcm9vdC5fX25vc2VsZWN0ID0gcm9vdC5z
dHlsZS5Nb3pVc2VyU2VsZWN0OwogICAgcm9vdC5zdHlsZS5Nb3pVc2VyU2VsZWN0ID0gIm5vbmUi
OwogIH0KfQoKZnVuY3Rpb24geWVzZHJhZyh2aWV3LCBub2NsaWNrKSB7CiAgdmFyIHJvb3QgPSB2
aWV3LmRvY3VtZW50LmRvY3VtZW50RWxlbWVudCwKICAgICAgc2VsZWN0aW9uID0gc2VsZWN0KHZp
ZXcpLm9uKCJkcmFnc3RhcnQuZHJhZyIsIG51bGwpOwogIGlmIChub2NsaWNrKSB7CiAgICBzZWxl
Y3Rpb24ub24oImNsaWNrLmRyYWciLCBub2V2ZW50LCB0cnVlKTsKICAgIHNldFRpbWVvdXQoZnVu
Y3Rpb24oKSB7IHNlbGVjdGlvbi5vbigiY2xpY2suZHJhZyIsIG51bGwpOyB9LCAwKTsKICB9CiAg
aWYgKCJvbnNlbGVjdHN0YXJ0IiBpbiByb290KSB7CiAgICBzZWxlY3Rpb24ub24oInNlbGVjdHN0
YXJ0LmRyYWciLCBudWxsKTsKICB9IGVsc2UgewogICAgcm9vdC5zdHlsZS5Nb3pVc2VyU2VsZWN0
ID0gcm9vdC5fX25vc2VsZWN0OwogICAgZGVsZXRlIHJvb3QuX19ub3NlbGVjdDsKICB9Cn0KCmZ1
bmN0aW9uIGNvbnN0YW50JDIoeCkgewogIHJldHVybiBmdW5jdGlvbigpIHsKICAgIHJldHVybiB4
OwogIH07Cn0KCmZ1bmN0aW9uIERyYWdFdmVudCh0YXJnZXQsIHR5cGUsIHN1YmplY3QsIGlkLCBh
Y3RpdmUsIHgsIHksIGR4LCBkeSwgZGlzcGF0Y2gpIHsKICB0aGlzLnRhcmdldCA9IHRhcmdldDsK
ICB0aGlzLnR5cGUgPSB0eXBlOwogIHRoaXMuc3ViamVjdCA9IHN1YmplY3Q7CiAgdGhpcy5pZGVu
dGlmaWVyID0gaWQ7CiAgdGhpcy5hY3RpdmUgPSBhY3RpdmU7CiAgdGhpcy54ID0geDsKICB0aGlz
LnkgPSB5OwogIHRoaXMuZHggPSBkeDsKICB0aGlzLmR5ID0gZHk7CiAgdGhpcy5fID0gZGlzcGF0
Y2g7Cn0KCkRyYWdFdmVudC5wcm90b3R5cGUub24gPSBmdW5jdGlvbigpIHsKICB2YXIgdmFsdWUg
PSB0aGlzLl8ub24uYXBwbHkodGhpcy5fLCBhcmd1bWVudHMpOwogIHJldHVybiB2YWx1ZSA9PT0g
dGhpcy5fID8gdGhpcyA6IHZhbHVlOwp9OwoKLy8gSWdub3JlIHJpZ2h0LWNsaWNrLCBzaW5jZSB0
aGF0IHNob3VsZCBvcGVuIHRoZSBjb250ZXh0IG1lbnUuCmZ1bmN0aW9uIGRlZmF1bHRGaWx0ZXIo
KSB7CiAgcmV0dXJuICFleHBvcnRzLmV2ZW50LmN0cmxLZXkgJiYgIWV4cG9ydHMuZXZlbnQuYnV0
dG9uOwp9CgpmdW5jdGlvbiBkZWZhdWx0Q29udGFpbmVyKCkgewogIHJldHVybiB0aGlzLnBhcmVu
dE5vZGU7Cn0KCmZ1bmN0aW9uIGRlZmF1bHRTdWJqZWN0KGQpIHsKICByZXR1cm4gZCA9PSBudWxs
ID8ge3g6IGV4cG9ydHMuZXZlbnQueCwgeTogZXhwb3J0cy5ldmVudC55fSA6IGQ7Cn0KCmZ1bmN0
aW9uIGRlZmF1bHRUb3VjaGFibGUoKSB7CiAgcmV0dXJuIG5hdmlnYXRvci5tYXhUb3VjaFBvaW50
cyB8fCAoIm9udG91Y2hzdGFydCIgaW4gdGhpcyk7Cn0KCmZ1bmN0aW9uIGRyYWcoKSB7CiAgdmFy
IGZpbHRlciA9IGRlZmF1bHRGaWx0ZXIsCiAgICAgIGNvbnRhaW5lciA9IGRlZmF1bHRDb250YWlu
ZXIsCiAgICAgIHN1YmplY3QgPSBkZWZhdWx0U3ViamVjdCwKICAgICAgdG91Y2hhYmxlID0gZGVm
YXVsdFRvdWNoYWJsZSwKICAgICAgZ2VzdHVyZXMgPSB7fSwKICAgICAgbGlzdGVuZXJzID0gZGlz
cGF0Y2goInN0YXJ0IiwgImRyYWciLCAiZW5kIiksCiAgICAgIGFjdGl2ZSA9IDAsCiAgICAgIG1v
dXNlZG93bngsCiAgICAgIG1vdXNlZG93bnksCiAgICAgIG1vdXNlbW92aW5nLAogICAgICB0b3Vj
aGVuZGluZywKICAgICAgY2xpY2tEaXN0YW5jZTIgPSAwOwoKICBmdW5jdGlvbiBkcmFnKHNlbGVj
dGlvbikgewogICAgc2VsZWN0aW9uCiAgICAgICAgLm9uKCJtb3VzZWRvd24uZHJhZyIsIG1vdXNl
ZG93bmVkKQogICAgICAuZmlsdGVyKHRvdWNoYWJsZSkKICAgICAgICAub24oInRvdWNoc3RhcnQu
ZHJhZyIsIHRvdWNoc3RhcnRlZCkKICAgICAgICAub24oInRvdWNobW92ZS5kcmFnIiwgdG91Y2ht
b3ZlZCkKICAgICAgICAub24oInRvdWNoZW5kLmRyYWcgdG91Y2hjYW5jZWwuZHJhZyIsIHRvdWNo
ZW5kZWQpCiAgICAgICAgLnN0eWxlKCJ0b3VjaC1hY3Rpb24iLCAibm9uZSIpCiAgICAgICAgLnN0
eWxlKCItd2Via2l0LXRhcC1oaWdobGlnaHQtY29sb3IiLCAicmdiYSgwLDAsMCwwKSIpOwogIH0K
CiAgZnVuY3Rpb24gbW91c2Vkb3duZWQoKSB7CiAgICBpZiAodG91Y2hlbmRpbmcgfHwgIWZpbHRl
ci5hcHBseSh0aGlzLCBhcmd1bWVudHMpKSByZXR1cm47CiAgICB2YXIgZ2VzdHVyZSA9IGJlZm9y
ZXN0YXJ0KCJtb3VzZSIsIGNvbnRhaW5lci5hcHBseSh0aGlzLCBhcmd1bWVudHMpLCBtb3VzZSwg
dGhpcywgYXJndW1lbnRzKTsKICAgIGlmICghZ2VzdHVyZSkgcmV0dXJuOwogICAgc2VsZWN0KGV4
cG9ydHMuZXZlbnQudmlldykub24oIm1vdXNlbW92ZS5kcmFnIiwgbW91c2Vtb3ZlZCwgdHJ1ZSku
b24oIm1vdXNldXAuZHJhZyIsIG1vdXNldXBwZWQsIHRydWUpOwogICAgZHJhZ0Rpc2FibGUoZXhw
b3J0cy5ldmVudC52aWV3KTsKICAgIG5vcHJvcGFnYXRpb24oKTsKICAgIG1vdXNlbW92aW5nID0g
ZmFsc2U7CiAgICBtb3VzZWRvd254ID0gZXhwb3J0cy5ldmVudC5jbGllbnRYOwogICAgbW91c2Vk
b3dueSA9IGV4cG9ydHMuZXZlbnQuY2xpZW50WTsKICAgIGdlc3R1cmUoInN0YXJ0Iik7CiAgfQoK
ICBmdW5jdGlvbiBtb3VzZW1vdmVkKCkgewogICAgbm9ldmVudCgpOwogICAgaWYgKCFtb3VzZW1v
dmluZykgewogICAgICB2YXIgZHggPSBleHBvcnRzLmV2ZW50LmNsaWVudFggLSBtb3VzZWRvd254
LCBkeSA9IGV4cG9ydHMuZXZlbnQuY2xpZW50WSAtIG1vdXNlZG93bnk7CiAgICAgIG1vdXNlbW92
aW5nID0gZHggKiBkeCArIGR5ICogZHkgPiBjbGlja0Rpc3RhbmNlMjsKICAgIH0KICAgIGdlc3R1
cmVzLm1vdXNlKCJkcmFnIik7CiAgfQoKICBmdW5jdGlvbiBtb3VzZXVwcGVkKCkgewogICAgc2Vs
ZWN0KGV4cG9ydHMuZXZlbnQudmlldykub24oIm1vdXNlbW92ZS5kcmFnIG1vdXNldXAuZHJhZyIs
IG51bGwpOwogICAgeWVzZHJhZyhleHBvcnRzLmV2ZW50LnZpZXcsIG1vdXNlbW92aW5nKTsKICAg
IG5vZXZlbnQoKTsKICAgIGdlc3R1cmVzLm1vdXNlKCJlbmQiKTsKICB9CgogIGZ1bmN0aW9uIHRv
dWNoc3RhcnRlZCgpIHsKICAgIGlmICghZmlsdGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpIHJl
dHVybjsKICAgIHZhciB0b3VjaGVzID0gZXhwb3J0cy5ldmVudC5jaGFuZ2VkVG91Y2hlcywKICAg
ICAgICBjID0gY29udGFpbmVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyksCiAgICAgICAgbiA9IHRv
dWNoZXMubGVuZ3RoLCBpLCBnZXN0dXJlOwoKICAgIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIHsK
ICAgICAgaWYgKGdlc3R1cmUgPSBiZWZvcmVzdGFydCh0b3VjaGVzW2ldLmlkZW50aWZpZXIsIGMs
IHRvdWNoLCB0aGlzLCBhcmd1bWVudHMpKSB7CiAgICAgICAgbm9wcm9wYWdhdGlvbigpOwogICAg
ICAgIGdlc3R1cmUoInN0YXJ0Iik7CiAgICAgIH0KICAgIH0KICB9CgogIGZ1bmN0aW9uIHRvdWNo
bW92ZWQoKSB7CiAgICB2YXIgdG91Y2hlcyA9IGV4cG9ydHMuZXZlbnQuY2hhbmdlZFRvdWNoZXMs
CiAgICAgICAgbiA9IHRvdWNoZXMubGVuZ3RoLCBpLCBnZXN0dXJlOwoKICAgIGZvciAoaSA9IDA7
IGkgPCBuOyArK2kpIHsKICAgICAgaWYgKGdlc3R1cmUgPSBnZXN0dXJlc1t0b3VjaGVzW2ldLmlk
ZW50aWZpZXJdKSB7CiAgICAgICAgbm9ldmVudCgpOwogICAgICAgIGdlc3R1cmUoImRyYWciKTsK
ICAgICAgfQogICAgfQogIH0KCiAgZnVuY3Rpb24gdG91Y2hlbmRlZCgpIHsKICAgIHZhciB0b3Vj
aGVzID0gZXhwb3J0cy5ldmVudC5jaGFuZ2VkVG91Y2hlcywKICAgICAgICBuID0gdG91Y2hlcy5s
ZW5ndGgsIGksIGdlc3R1cmU7CgogICAgaWYgKHRvdWNoZW5kaW5nKSBjbGVhclRpbWVvdXQodG91
Y2hlbmRpbmcpOwogICAgdG91Y2hlbmRpbmcgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgeyB0b3Vj
aGVuZGluZyA9IG51bGw7IH0sIDUwMCk7IC8vIEdob3N0IGNsaWNrcyBhcmUgZGVsYXllZCEKICAg
IGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIHsKICAgICAgaWYgKGdlc3R1cmUgPSBnZXN0dXJlc1t0
b3VjaGVzW2ldLmlkZW50aWZpZXJdKSB7CiAgICAgICAgbm9wcm9wYWdhdGlvbigpOwogICAgICAg
IGdlc3R1cmUoImVuZCIpOwogICAgICB9CiAgICB9CiAgfQoKICBmdW5jdGlvbiBiZWZvcmVzdGFy
dChpZCwgY29udGFpbmVyLCBwb2ludCwgdGhhdCwgYXJncykgewogICAgdmFyIHAgPSBwb2ludChj
b250YWluZXIsIGlkKSwgcywgZHgsIGR5LAogICAgICAgIHN1Ymxpc3RlbmVycyA9IGxpc3RlbmVy
cy5jb3B5KCk7CgogICAgaWYgKCFjdXN0b21FdmVudChuZXcgRHJhZ0V2ZW50KGRyYWcsICJiZWZv
cmVzdGFydCIsIHMsIGlkLCBhY3RpdmUsIHBbMF0sIHBbMV0sIDAsIDAsIHN1Ymxpc3RlbmVycyks
IGZ1bmN0aW9uKCkgewogICAgICBpZiAoKGV4cG9ydHMuZXZlbnQuc3ViamVjdCA9IHMgPSBzdWJq
ZWN0LmFwcGx5KHRoYXQsIGFyZ3MpKSA9PSBudWxsKSByZXR1cm4gZmFsc2U7CiAgICAgIGR4ID0g
cy54IC0gcFswXSB8fCAwOwogICAgICBkeSA9IHMueSAtIHBbMV0gfHwgMDsKICAgICAgcmV0dXJu
IHRydWU7CiAgICB9KSkgcmV0dXJuOwoKICAgIHJldHVybiBmdW5jdGlvbiBnZXN0dXJlKHR5cGUp
IHsKICAgICAgdmFyIHAwID0gcCwgbjsKICAgICAgc3dpdGNoICh0eXBlKSB7CiAgICAgICAgY2Fz
ZSAic3RhcnQiOiBnZXN0dXJlc1tpZF0gPSBnZXN0dXJlLCBuID0gYWN0aXZlKys7IGJyZWFrOwog
ICAgICAgIGNhc2UgImVuZCI6IGRlbGV0ZSBnZXN0dXJlc1tpZF0sIC0tYWN0aXZlOyAvLyBub2Jy
ZWFrCiAgICAgICAgY2FzZSAiZHJhZyI6IHAgPSBwb2ludChjb250YWluZXIsIGlkKSwgbiA9IGFj
dGl2ZTsgYnJlYWs7CiAgICAgIH0KICAgICAgY3VzdG9tRXZlbnQobmV3IERyYWdFdmVudChkcmFn
LCB0eXBlLCBzLCBpZCwgbiwgcFswXSArIGR4LCBwWzFdICsgZHksIHBbMF0gLSBwMFswXSwgcFsx
XSAtIHAwWzFdLCBzdWJsaXN0ZW5lcnMpLCBzdWJsaXN0ZW5lcnMuYXBwbHksIHN1Ymxpc3RlbmVy
cywgW3R5cGUsIHRoYXQsIGFyZ3NdKTsKICAgIH07CiAgfQoKICBkcmFnLmZpbHRlciA9IGZ1bmN0
aW9uKF8pIHsKICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGZpbHRlciA9IHR5cGVvZiBf
ID09PSAiZnVuY3Rpb24iID8gXyA6IGNvbnN0YW50JDIoISFfKSwgZHJhZykgOiBmaWx0ZXI7CiAg
fTsKCiAgZHJhZy5jb250YWluZXIgPSBmdW5jdGlvbihfKSB7CiAgICByZXR1cm4gYXJndW1lbnRz
Lmxlbmd0aCA/IChjb250YWluZXIgPSB0eXBlb2YgXyA9PT0gImZ1bmN0aW9uIiA/IF8gOiBjb25z
dGFudCQyKF8pLCBkcmFnKSA6IGNvbnRhaW5lcjsKICB9OwoKICBkcmFnLnN1YmplY3QgPSBmdW5j
dGlvbihfKSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChzdWJqZWN0ID0gdHlwZW9m
IF8gPT09ICJmdW5jdGlvbiIgPyBfIDogY29uc3RhbnQkMihfKSwgZHJhZykgOiBzdWJqZWN0Owog
IH07CgogIGRyYWcudG91Y2hhYmxlID0gZnVuY3Rpb24oXykgewogICAgcmV0dXJuIGFyZ3VtZW50
cy5sZW5ndGggPyAodG91Y2hhYmxlID0gdHlwZW9mIF8gPT09ICJmdW5jdGlvbiIgPyBfIDogY29u
c3RhbnQkMighIV8pLCBkcmFnKSA6IHRvdWNoYWJsZTsKICB9OwoKICBkcmFnLm9uID0gZnVuY3Rp
b24oKSB7CiAgICB2YXIgdmFsdWUgPSBsaXN0ZW5lcnMub24uYXBwbHkobGlzdGVuZXJzLCBhcmd1
bWVudHMpOwogICAgcmV0dXJuIHZhbHVlID09PSBsaXN0ZW5lcnMgPyBkcmFnIDogdmFsdWU7CiAg
fTsKCiAgZHJhZy5jbGlja0Rpc3RhbmNlID0gZnVuY3Rpb24oXykgewogICAgcmV0dXJuIGFyZ3Vt
ZW50cy5sZW5ndGggPyAoY2xpY2tEaXN0YW5jZTIgPSAoXyA9ICtfKSAqIF8sIGRyYWcpIDogTWF0
aC5zcXJ0KGNsaWNrRGlzdGFuY2UyKTsKICB9OwoKICByZXR1cm4gZHJhZzsKfQoKZnVuY3Rpb24g
ZGVmaW5lKGNvbnN0cnVjdG9yLCBmYWN0b3J5LCBwcm90b3R5cGUpIHsKICBjb25zdHJ1Y3Rvci5w
cm90b3R5cGUgPSBmYWN0b3J5LnByb3RvdHlwZSA9IHByb3RvdHlwZTsKICBwcm90b3R5cGUuY29u
c3RydWN0b3IgPSBjb25zdHJ1Y3RvcjsKfQoKZnVuY3Rpb24gZXh0ZW5kKHBhcmVudCwgZGVmaW5p
dGlvbikgewogIHZhciBwcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHBhcmVudC5wcm90b3R5cGUp
OwogIGZvciAodmFyIGtleSBpbiBkZWZpbml0aW9uKSBwcm90b3R5cGVba2V5XSA9IGRlZmluaXRp
b25ba2V5XTsKICByZXR1cm4gcHJvdG90eXBlOwp9CgpmdW5jdGlvbiBDb2xvcigpIHt9Cgp2YXIg
ZGFya2VyID0gMC43Owp2YXIgYnJpZ2h0ZXIgPSAxIC8gZGFya2VyOwoKdmFyIHJlSSA9ICJcXHMq
KFsrLV0/XFxkKylcXHMqIiwKICAgIHJlTiA9ICJcXHMqKFsrLV0/XFxkKlxcLj9cXGQrKD86W2VF
XVsrLV0/XFxkKyk/KVxccyoiLAogICAgcmVQID0gIlxccyooWystXT9cXGQqXFwuP1xcZCsoPzpb
ZUVdWystXT9cXGQrKT8pJVxccyoiLAogICAgcmVIZXggPSAvXiMoWzAtOWEtZl17Myw4fSkkLywK
ICAgIHJlUmdiSW50ZWdlciA9IG5ldyBSZWdFeHAoIl5yZ2JcXCgiICsgW3JlSSwgcmVJLCByZUld
ICsgIlxcKSQiKSwKICAgIHJlUmdiUGVyY2VudCA9IG5ldyBSZWdFeHAoIl5yZ2JcXCgiICsgW3Jl
UCwgcmVQLCByZVBdICsgIlxcKSQiKSwKICAgIHJlUmdiYUludGVnZXIgPSBuZXcgUmVnRXhwKCJe
cmdiYVxcKCIgKyBbcmVJLCByZUksIHJlSSwgcmVOXSArICJcXCkkIiksCiAgICByZVJnYmFQZXJj
ZW50ID0gbmV3IFJlZ0V4cCgiXnJnYmFcXCgiICsgW3JlUCwgcmVQLCByZVAsIHJlTl0gKyAiXFwp
JCIpLAogICAgcmVIc2xQZXJjZW50ID0gbmV3IFJlZ0V4cCgiXmhzbFxcKCIgKyBbcmVOLCByZVAs
IHJlUF0gKyAiXFwpJCIpLAogICAgcmVIc2xhUGVyY2VudCA9IG5ldyBSZWdFeHAoIl5oc2xhXFwo
IiArIFtyZU4sIHJlUCwgcmVQLCByZU5dICsgIlxcKSQiKTsKCnZhciBuYW1lZCA9IHsKICBhbGlj
ZWJsdWU6IDB4ZjBmOGZmLAogIGFudGlxdWV3aGl0ZTogMHhmYWViZDcsCiAgYXF1YTogMHgwMGZm
ZmYsCiAgYXF1YW1hcmluZTogMHg3ZmZmZDQsCiAgYXp1cmU6IDB4ZjBmZmZmLAogIGJlaWdlOiAw
eGY1ZjVkYywKICBiaXNxdWU6IDB4ZmZlNGM0LAogIGJsYWNrOiAweDAwMDAwMCwKICBibGFuY2hl
ZGFsbW9uZDogMHhmZmViY2QsCiAgYmx1ZTogMHgwMDAwZmYsCiAgYmx1ZXZpb2xldDogMHg4YTJi
ZTIsCiAgYnJvd246IDB4YTUyYTJhLAogIGJ1cmx5d29vZDogMHhkZWI4ODcsCiAgY2FkZXRibHVl
OiAweDVmOWVhMCwKICBjaGFydHJldXNlOiAweDdmZmYwMCwKICBjaG9jb2xhdGU6IDB4ZDI2OTFl
LAogIGNvcmFsOiAweGZmN2Y1MCwKICBjb3JuZmxvd2VyYmx1ZTogMHg2NDk1ZWQsCiAgY29ybnNp
bGs6IDB4ZmZmOGRjLAogIGNyaW1zb246IDB4ZGMxNDNjLAogIGN5YW46IDB4MDBmZmZmLAogIGRh
cmtibHVlOiAweDAwMDA4YiwKICBkYXJrY3lhbjogMHgwMDhiOGIsCiAgZGFya2dvbGRlbnJvZDog
MHhiODg2MGIsCiAgZGFya2dyYXk6IDB4YTlhOWE5LAogIGRhcmtncmVlbjogMHgwMDY0MDAsCiAg
ZGFya2dyZXk6IDB4YTlhOWE5LAogIGRhcmtraGFraTogMHhiZGI3NmIsCiAgZGFya21hZ2VudGE6
IDB4OGIwMDhiLAogIGRhcmtvbGl2ZWdyZWVuOiAweDU1NmIyZiwKICBkYXJrb3JhbmdlOiAweGZm
OGMwMCwKICBkYXJrb3JjaGlkOiAweDk5MzJjYywKICBkYXJrcmVkOiAweDhiMDAwMCwKICBkYXJr
c2FsbW9uOiAweGU5OTY3YSwKICBkYXJrc2VhZ3JlZW46IDB4OGZiYzhmLAogIGRhcmtzbGF0ZWJs
dWU6IDB4NDgzZDhiLAogIGRhcmtzbGF0ZWdyYXk6IDB4MmY0ZjRmLAogIGRhcmtzbGF0ZWdyZXk6
IDB4MmY0ZjRmLAogIGRhcmt0dXJxdW9pc2U6IDB4MDBjZWQxLAogIGRhcmt2aW9sZXQ6IDB4OTQw
MGQzLAogIGRlZXBwaW5rOiAweGZmMTQ5MywKICBkZWVwc2t5Ymx1ZTogMHgwMGJmZmYsCiAgZGlt
Z3JheTogMHg2OTY5NjksCiAgZGltZ3JleTogMHg2OTY5NjksCiAgZG9kZ2VyYmx1ZTogMHgxZTkw
ZmYsCiAgZmlyZWJyaWNrOiAweGIyMjIyMiwKICBmbG9yYWx3aGl0ZTogMHhmZmZhZjAsCiAgZm9y
ZXN0Z3JlZW46IDB4MjI4YjIyLAogIGZ1Y2hzaWE6IDB4ZmYwMGZmLAogIGdhaW5zYm9ybzogMHhk
Y2RjZGMsCiAgZ2hvc3R3aGl0ZTogMHhmOGY4ZmYsCiAgZ29sZDogMHhmZmQ3MDAsCiAgZ29sZGVu
cm9kOiAweGRhYTUyMCwKICBncmF5OiAweDgwODA4MCwKICBncmVlbjogMHgwMDgwMDAsCiAgZ3Jl
ZW55ZWxsb3c6IDB4YWRmZjJmLAogIGdyZXk6IDB4ODA4MDgwLAogIGhvbmV5ZGV3OiAweGYwZmZm
MCwKICBob3RwaW5rOiAweGZmNjliNCwKICBpbmRpYW5yZWQ6IDB4Y2Q1YzVjLAogIGluZGlnbzog
MHg0YjAwODIsCiAgaXZvcnk6IDB4ZmZmZmYwLAogIGtoYWtpOiAweGYwZTY4YywKICBsYXZlbmRl
cjogMHhlNmU2ZmEsCiAgbGF2ZW5kZXJibHVzaDogMHhmZmYwZjUsCiAgbGF3bmdyZWVuOiAweDdj
ZmMwMCwKICBsZW1vbmNoaWZmb246IDB4ZmZmYWNkLAogIGxpZ2h0Ymx1ZTogMHhhZGQ4ZTYsCiAg
bGlnaHRjb3JhbDogMHhmMDgwODAsCiAgbGlnaHRjeWFuOiAweGUwZmZmZiwKICBsaWdodGdvbGRl
bnJvZHllbGxvdzogMHhmYWZhZDIsCiAgbGlnaHRncmF5OiAweGQzZDNkMywKICBsaWdodGdyZWVu
OiAweDkwZWU5MCwKICBsaWdodGdyZXk6IDB4ZDNkM2QzLAogIGxpZ2h0cGluazogMHhmZmI2YzEs
CiAgbGlnaHRzYWxtb246IDB4ZmZhMDdhLAogIGxpZ2h0c2VhZ3JlZW46IDB4MjBiMmFhLAogIGxp
Z2h0c2t5Ymx1ZTogMHg4N2NlZmEsCiAgbGlnaHRzbGF0ZWdyYXk6IDB4Nzc4ODk5LAogIGxpZ2h0
c2xhdGVncmV5OiAweDc3ODg5OSwKICBsaWdodHN0ZWVsYmx1ZTogMHhiMGM0ZGUsCiAgbGlnaHR5
ZWxsb3c6IDB4ZmZmZmUwLAogIGxpbWU6IDB4MDBmZjAwLAogIGxpbWVncmVlbjogMHgzMmNkMzIs
CiAgbGluZW46IDB4ZmFmMGU2LAogIG1hZ2VudGE6IDB4ZmYwMGZmLAogIG1hcm9vbjogMHg4MDAw
MDAsCiAgbWVkaXVtYXF1YW1hcmluZTogMHg2NmNkYWEsCiAgbWVkaXVtYmx1ZTogMHgwMDAwY2Qs
CiAgbWVkaXVtb3JjaGlkOiAweGJhNTVkMywKICBtZWRpdW1wdXJwbGU6IDB4OTM3MGRiLAogIG1l
ZGl1bXNlYWdyZWVuOiAweDNjYjM3MSwKICBtZWRpdW1zbGF0ZWJsdWU6IDB4N2I2OGVlLAogIG1l
ZGl1bXNwcmluZ2dyZWVuOiAweDAwZmE5YSwKICBtZWRpdW10dXJxdW9pc2U6IDB4NDhkMWNjLAog
IG1lZGl1bXZpb2xldHJlZDogMHhjNzE1ODUsCiAgbWlkbmlnaHRibHVlOiAweDE5MTk3MCwKICBt
aW50Y3JlYW06IDB4ZjVmZmZhLAogIG1pc3R5cm9zZTogMHhmZmU0ZTEsCiAgbW9jY2FzaW46IDB4
ZmZlNGI1LAogIG5hdmFqb3doaXRlOiAweGZmZGVhZCwKICBuYXZ5OiAweDAwMDA4MCwKICBvbGRs
YWNlOiAweGZkZjVlNiwKICBvbGl2ZTogMHg4MDgwMDAsCiAgb2xpdmVkcmFiOiAweDZiOGUyMywK
ICBvcmFuZ2U6IDB4ZmZhNTAwLAogIG9yYW5nZXJlZDogMHhmZjQ1MDAsCiAgb3JjaGlkOiAweGRh
NzBkNiwKICBwYWxlZ29sZGVucm9kOiAweGVlZThhYSwKICBwYWxlZ3JlZW46IDB4OThmYjk4LAog
IHBhbGV0dXJxdW9pc2U6IDB4YWZlZWVlLAogIHBhbGV2aW9sZXRyZWQ6IDB4ZGI3MDkzLAogIHBh
cGF5YXdoaXA6IDB4ZmZlZmQ1LAogIHBlYWNocHVmZjogMHhmZmRhYjksCiAgcGVydTogMHhjZDg1
M2YsCiAgcGluazogMHhmZmMwY2IsCiAgcGx1bTogMHhkZGEwZGQsCiAgcG93ZGVyYmx1ZTogMHhi
MGUwZTYsCiAgcHVycGxlOiAweDgwMDA4MCwKICByZWJlY2NhcHVycGxlOiAweDY2MzM5OSwKICBy
ZWQ6IDB4ZmYwMDAwLAogIHJvc3licm93bjogMHhiYzhmOGYsCiAgcm95YWxibHVlOiAweDQxNjll
MSwKICBzYWRkbGVicm93bjogMHg4YjQ1MTMsCiAgc2FsbW9uOiAweGZhODA3MiwKICBzYW5keWJy
b3duOiAweGY0YTQ2MCwKICBzZWFncmVlbjogMHgyZThiNTcsCiAgc2Vhc2hlbGw6IDB4ZmZmNWVl
LAogIHNpZW5uYTogMHhhMDUyMmQsCiAgc2lsdmVyOiAweGMwYzBjMCwKICBza3libHVlOiAweDg3
Y2VlYiwKICBzbGF0ZWJsdWU6IDB4NmE1YWNkLAogIHNsYXRlZ3JheTogMHg3MDgwOTAsCiAgc2xh
dGVncmV5OiAweDcwODA5MCwKICBzbm93OiAweGZmZmFmYSwKICBzcHJpbmdncmVlbjogMHgwMGZm
N2YsCiAgc3RlZWxibHVlOiAweDQ2ODJiNCwKICB0YW46IDB4ZDJiNDhjLAogIHRlYWw6IDB4MDA4
MDgwLAogIHRoaXN0bGU6IDB4ZDhiZmQ4LAogIHRvbWF0bzogMHhmZjYzNDcsCiAgdHVycXVvaXNl
OiAweDQwZTBkMCwKICB2aW9sZXQ6IDB4ZWU4MmVlLAogIHdoZWF0OiAweGY1ZGViMywKICB3aGl0
ZTogMHhmZmZmZmYsCiAgd2hpdGVzbW9rZTogMHhmNWY1ZjUsCiAgeWVsbG93OiAweGZmZmYwMCwK
ICB5ZWxsb3dncmVlbjogMHg5YWNkMzIKfTsKCmRlZmluZShDb2xvciwgY29sb3IsIHsKICBjb3B5
OiBmdW5jdGlvbihjaGFubmVscykgewogICAgcmV0dXJuIE9iamVjdC5hc3NpZ24obmV3IHRoaXMu
Y29uc3RydWN0b3IsIHRoaXMsIGNoYW5uZWxzKTsKICB9LAogIGRpc3BsYXlhYmxlOiBmdW5jdGlv
bigpIHsKICAgIHJldHVybiB0aGlzLnJnYigpLmRpc3BsYXlhYmxlKCk7CiAgfSwKICBoZXg6IGNv
bG9yX2Zvcm1hdEhleCwgLy8gRGVwcmVjYXRlZCEgVXNlIGNvbG9yLmZvcm1hdEhleC4KICBmb3Jt
YXRIZXg6IGNvbG9yX2Zvcm1hdEhleCwKICBmb3JtYXRIc2w6IGNvbG9yX2Zvcm1hdEhzbCwKICBm
b3JtYXRSZ2I6IGNvbG9yX2Zvcm1hdFJnYiwKICB0b1N0cmluZzogY29sb3JfZm9ybWF0UmdiCn0p
OwoKZnVuY3Rpb24gY29sb3JfZm9ybWF0SGV4KCkgewogIHJldHVybiB0aGlzLnJnYigpLmZvcm1h
dEhleCgpOwp9CgpmdW5jdGlvbiBjb2xvcl9mb3JtYXRIc2woKSB7CiAgcmV0dXJuIGhzbENvbnZl
cnQodGhpcykuZm9ybWF0SHNsKCk7Cn0KCmZ1bmN0aW9uIGNvbG9yX2Zvcm1hdFJnYigpIHsKICBy
ZXR1cm4gdGhpcy5yZ2IoKS5mb3JtYXRSZ2IoKTsKfQoKZnVuY3Rpb24gY29sb3IoZm9ybWF0KSB7
CiAgdmFyIG0sIGw7CiAgZm9ybWF0ID0gKGZvcm1hdCArICIiKS50cmltKCkudG9Mb3dlckNhc2Uo
KTsKICByZXR1cm4gKG0gPSByZUhleC5leGVjKGZvcm1hdCkpID8gKGwgPSBtWzFdLmxlbmd0aCwg
bSA9IHBhcnNlSW50KG1bMV0sIDE2KSwgbCA9PT0gNiA/IHJnYm4obSkgLy8gI2ZmMDAwMAogICAg
ICA6IGwgPT09IDMgPyBuZXcgUmdiKChtID4+IDggJiAweGYpIHwgKG0gPj4gNCAmIDB4ZjApLCAo
bSA+PiA0ICYgMHhmKSB8IChtICYgMHhmMCksICgobSAmIDB4ZikgPDwgNCkgfCAobSAmIDB4Ziks
IDEpIC8vICNmMDAKICAgICAgOiBsID09PSA4ID8gcmdiYShtID4+IDI0ICYgMHhmZiwgbSA+PiAx
NiAmIDB4ZmYsIG0gPj4gOCAmIDB4ZmYsIChtICYgMHhmZikgLyAweGZmKSAvLyAjZmYwMDAwMDAK
ICAgICAgOiBsID09PSA0ID8gcmdiYSgobSA+PiAxMiAmIDB4ZikgfCAobSA+PiA4ICYgMHhmMCks
IChtID4+IDggJiAweGYpIHwgKG0gPj4gNCAmIDB4ZjApLCAobSA+PiA0ICYgMHhmKSB8IChtICYg
MHhmMCksICgoKG0gJiAweGYpIDw8IDQpIHwgKG0gJiAweGYpKSAvIDB4ZmYpIC8vICNmMDAwCiAg
ICAgIDogbnVsbCkgLy8gaW52YWxpZCBoZXgKICAgICAgOiAobSA9IHJlUmdiSW50ZWdlci5leGVj
KGZvcm1hdCkpID8gbmV3IFJnYihtWzFdLCBtWzJdLCBtWzNdLCAxKSAvLyByZ2IoMjU1LCAwLCAw
KQogICAgICA6IChtID0gcmVSZ2JQZXJjZW50LmV4ZWMoZm9ybWF0KSkgPyBuZXcgUmdiKG1bMV0g
KiAyNTUgLyAxMDAsIG1bMl0gKiAyNTUgLyAxMDAsIG1bM10gKiAyNTUgLyAxMDAsIDEpIC8vIHJn
YigxMDAlLCAwJSwgMCUpCiAgICAgIDogKG0gPSByZVJnYmFJbnRlZ2VyLmV4ZWMoZm9ybWF0KSkg
PyByZ2JhKG1bMV0sIG1bMl0sIG1bM10sIG1bNF0pIC8vIHJnYmEoMjU1LCAwLCAwLCAxKQogICAg
ICA6IChtID0gcmVSZ2JhUGVyY2VudC5leGVjKGZvcm1hdCkpID8gcmdiYShtWzFdICogMjU1IC8g
MTAwLCBtWzJdICogMjU1IC8gMTAwLCBtWzNdICogMjU1IC8gMTAwLCBtWzRdKSAvLyByZ2IoMTAw
JSwgMCUsIDAlLCAxKQogICAgICA6IChtID0gcmVIc2xQZXJjZW50LmV4ZWMoZm9ybWF0KSkgPyBo
c2xhKG1bMV0sIG1bMl0gLyAxMDAsIG1bM10gLyAxMDAsIDEpIC8vIGhzbCgxMjAsIDUwJSwgNTAl
KQogICAgICA6IChtID0gcmVIc2xhUGVyY2VudC5leGVjKGZvcm1hdCkpID8gaHNsYShtWzFdLCBt
WzJdIC8gMTAwLCBtWzNdIC8gMTAwLCBtWzRdKSAvLyBoc2xhKDEyMCwgNTAlLCA1MCUsIDEpCiAg
ICAgIDogbmFtZWQuaGFzT3duUHJvcGVydHkoZm9ybWF0KSA/IHJnYm4obmFtZWRbZm9ybWF0XSkg
Ly8gZXNsaW50LWRpc2FibGUtbGluZSBuby1wcm90b3R5cGUtYnVpbHRpbnMKICAgICAgOiBmb3Jt
YXQgPT09ICJ0cmFuc3BhcmVudCIgPyBuZXcgUmdiKE5hTiwgTmFOLCBOYU4sIDApCiAgICAgIDog
bnVsbDsKfQoKZnVuY3Rpb24gcmdibihuKSB7CiAgcmV0dXJuIG5ldyBSZ2IobiA+PiAxNiAmIDB4
ZmYsIG4gPj4gOCAmIDB4ZmYsIG4gJiAweGZmLCAxKTsKfQoKZnVuY3Rpb24gcmdiYShyLCBnLCBi
LCBhKSB7CiAgaWYgKGEgPD0gMCkgciA9IGcgPSBiID0gTmFOOwogIHJldHVybiBuZXcgUmdiKHIs
IGcsIGIsIGEpOwp9CgpmdW5jdGlvbiByZ2JDb252ZXJ0KG8pIHsKICBpZiAoIShvIGluc3RhbmNl
b2YgQ29sb3IpKSBvID0gY29sb3Iobyk7CiAgaWYgKCFvKSByZXR1cm4gbmV3IFJnYjsKICBvID0g
by5yZ2IoKTsKICByZXR1cm4gbmV3IFJnYihvLnIsIG8uZywgby5iLCBvLm9wYWNpdHkpOwp9Cgpm
dW5jdGlvbiByZ2IociwgZywgYiwgb3BhY2l0eSkgewogIHJldHVybiBhcmd1bWVudHMubGVuZ3Ro
ID09PSAxID8gcmdiQ29udmVydChyKSA6IG5ldyBSZ2IociwgZywgYiwgb3BhY2l0eSA9PSBudWxs
ID8gMSA6IG9wYWNpdHkpOwp9CgpmdW5jdGlvbiBSZ2IociwgZywgYiwgb3BhY2l0eSkgewogIHRo
aXMuciA9ICtyOwogIHRoaXMuZyA9ICtnOwogIHRoaXMuYiA9ICtiOwogIHRoaXMub3BhY2l0eSA9
ICtvcGFjaXR5Owp9CgpkZWZpbmUoUmdiLCByZ2IsIGV4dGVuZChDb2xvciwgewogIGJyaWdodGVy
OiBmdW5jdGlvbihrKSB7CiAgICBrID0gayA9PSBudWxsID8gYnJpZ2h0ZXIgOiBNYXRoLnBvdyhi
cmlnaHRlciwgayk7CiAgICByZXR1cm4gbmV3IFJnYih0aGlzLnIgKiBrLCB0aGlzLmcgKiBrLCB0
aGlzLmIgKiBrLCB0aGlzLm9wYWNpdHkpOwogIH0sCiAgZGFya2VyOiBmdW5jdGlvbihrKSB7CiAg
ICBrID0gayA9PSBudWxsID8gZGFya2VyIDogTWF0aC5wb3coZGFya2VyLCBrKTsKICAgIHJldHVy
biBuZXcgUmdiKHRoaXMuciAqIGssIHRoaXMuZyAqIGssIHRoaXMuYiAqIGssIHRoaXMub3BhY2l0
eSk7CiAgfSwKICByZ2I6IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIHRoaXM7CiAgfSwKICBkaXNw
bGF5YWJsZTogZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gKC0wLjUgPD0gdGhpcy5yICYmIHRoaXMu
ciA8IDI1NS41KQogICAgICAgICYmICgtMC41IDw9IHRoaXMuZyAmJiB0aGlzLmcgPCAyNTUuNSkK
ICAgICAgICAmJiAoLTAuNSA8PSB0aGlzLmIgJiYgdGhpcy5iIDwgMjU1LjUpCiAgICAgICAgJiYg
KDAgPD0gdGhpcy5vcGFjaXR5ICYmIHRoaXMub3BhY2l0eSA8PSAxKTsKICB9LAogIGhleDogcmdi
X2Zvcm1hdEhleCwgLy8gRGVwcmVjYXRlZCEgVXNlIGNvbG9yLmZvcm1hdEhleC4KICBmb3JtYXRI
ZXg6IHJnYl9mb3JtYXRIZXgsCiAgZm9ybWF0UmdiOiByZ2JfZm9ybWF0UmdiLAogIHRvU3RyaW5n
OiByZ2JfZm9ybWF0UmdiCn0pKTsKCmZ1bmN0aW9uIHJnYl9mb3JtYXRIZXgoKSB7CiAgcmV0dXJu
ICIjIiArIGhleCh0aGlzLnIpICsgaGV4KHRoaXMuZykgKyBoZXgodGhpcy5iKTsKfQoKZnVuY3Rp
b24gcmdiX2Zvcm1hdFJnYigpIHsKICB2YXIgYSA9IHRoaXMub3BhY2l0eTsgYSA9IGlzTmFOKGEp
ID8gMSA6IE1hdGgubWF4KDAsIE1hdGgubWluKDEsIGEpKTsKICByZXR1cm4gKGEgPT09IDEgPyAi
cmdiKCIgOiAicmdiYSgiKQogICAgICArIE1hdGgubWF4KDAsIE1hdGgubWluKDI1NSwgTWF0aC5y
b3VuZCh0aGlzLnIpIHx8IDApKSArICIsICIKICAgICAgKyBNYXRoLm1heCgwLCBNYXRoLm1pbigy
NTUsIE1hdGgucm91bmQodGhpcy5nKSB8fCAwKSkgKyAiLCAiCiAgICAgICsgTWF0aC5tYXgoMCwg
TWF0aC5taW4oMjU1LCBNYXRoLnJvdW5kKHRoaXMuYikgfHwgMCkpCiAgICAgICsgKGEgPT09IDEg
PyAiKSIgOiAiLCAiICsgYSArICIpIik7Cn0KCmZ1bmN0aW9uIGhleCh2YWx1ZSkgewogIHZhbHVl
ID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oMjU1LCBNYXRoLnJvdW5kKHZhbHVlKSB8fCAwKSk7CiAg
cmV0dXJuICh2YWx1ZSA8IDE2ID8gIjAiIDogIiIpICsgdmFsdWUudG9TdHJpbmcoMTYpOwp9Cgpm
dW5jdGlvbiBoc2xhKGgsIHMsIGwsIGEpIHsKICBpZiAoYSA8PSAwKSBoID0gcyA9IGwgPSBOYU47
CiAgZWxzZSBpZiAobCA8PSAwIHx8IGwgPj0gMSkgaCA9IHMgPSBOYU47CiAgZWxzZSBpZiAocyA8
PSAwKSBoID0gTmFOOwogIHJldHVybiBuZXcgSHNsKGgsIHMsIGwsIGEpOwp9CgpmdW5jdGlvbiBo
c2xDb252ZXJ0KG8pIHsKICBpZiAobyBpbnN0YW5jZW9mIEhzbCkgcmV0dXJuIG5ldyBIc2woby5o
LCBvLnMsIG8ubCwgby5vcGFjaXR5KTsKICBpZiAoIShvIGluc3RhbmNlb2YgQ29sb3IpKSBvID0g
Y29sb3Iobyk7CiAgaWYgKCFvKSByZXR1cm4gbmV3IEhzbDsKICBpZiAobyBpbnN0YW5jZW9mIEhz
bCkgcmV0dXJuIG87CiAgbyA9IG8ucmdiKCk7CiAgdmFyIHIgPSBvLnIgLyAyNTUsCiAgICAgIGcg
PSBvLmcgLyAyNTUsCiAgICAgIGIgPSBvLmIgLyAyNTUsCiAgICAgIG1pbiA9IE1hdGgubWluKHIs
IGcsIGIpLAogICAgICBtYXggPSBNYXRoLm1heChyLCBnLCBiKSwKICAgICAgaCA9IE5hTiwKICAg
ICAgcyA9IG1heCAtIG1pbiwKICAgICAgbCA9IChtYXggKyBtaW4pIC8gMjsKICBpZiAocykgewog
ICAgaWYgKHIgPT09IG1heCkgaCA9IChnIC0gYikgLyBzICsgKGcgPCBiKSAqIDY7CiAgICBlbHNl
IGlmIChnID09PSBtYXgpIGggPSAoYiAtIHIpIC8gcyArIDI7CiAgICBlbHNlIGggPSAociAtIGcp
IC8gcyArIDQ7CiAgICBzIC89IGwgPCAwLjUgPyBtYXggKyBtaW4gOiAyIC0gbWF4IC0gbWluOwog
ICAgaCAqPSA2MDsKICB9IGVsc2UgewogICAgcyA9IGwgPiAwICYmIGwgPCAxID8gMCA6IGg7CiAg
fQogIHJldHVybiBuZXcgSHNsKGgsIHMsIGwsIG8ub3BhY2l0eSk7Cn0KCmZ1bmN0aW9uIGhzbCho
LCBzLCBsLCBvcGFjaXR5KSB7CiAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPT09IDEgPyBoc2xD
b252ZXJ0KGgpIDogbmV3IEhzbChoLCBzLCBsLCBvcGFjaXR5ID09IG51bGwgPyAxIDogb3BhY2l0
eSk7Cn0KCmZ1bmN0aW9uIEhzbChoLCBzLCBsLCBvcGFjaXR5KSB7CiAgdGhpcy5oID0gK2g7CiAg
dGhpcy5zID0gK3M7CiAgdGhpcy5sID0gK2w7CiAgdGhpcy5vcGFjaXR5ID0gK29wYWNpdHk7Cn0K
CmRlZmluZShIc2wsIGhzbCwgZXh0ZW5kKENvbG9yLCB7CiAgYnJpZ2h0ZXI6IGZ1bmN0aW9uKGsp
IHsKICAgIGsgPSBrID09IG51bGwgPyBicmlnaHRlciA6IE1hdGgucG93KGJyaWdodGVyLCBrKTsK
ICAgIHJldHVybiBuZXcgSHNsKHRoaXMuaCwgdGhpcy5zLCB0aGlzLmwgKiBrLCB0aGlzLm9wYWNp
dHkpOwogIH0sCiAgZGFya2VyOiBmdW5jdGlvbihrKSB7CiAgICBrID0gayA9PSBudWxsID8gZGFy
a2VyIDogTWF0aC5wb3coZGFya2VyLCBrKTsKICAgIHJldHVybiBuZXcgSHNsKHRoaXMuaCwgdGhp
cy5zLCB0aGlzLmwgKiBrLCB0aGlzLm9wYWNpdHkpOwogIH0sCiAgcmdiOiBmdW5jdGlvbigpIHsK
ICAgIHZhciBoID0gdGhpcy5oICUgMzYwICsgKHRoaXMuaCA8IDApICogMzYwLAogICAgICAgIHMg
PSBpc05hTihoKSB8fCBpc05hTih0aGlzLnMpID8gMCA6IHRoaXMucywKICAgICAgICBsID0gdGhp
cy5sLAogICAgICAgIG0yID0gbCArIChsIDwgMC41ID8gbCA6IDEgLSBsKSAqIHMsCiAgICAgICAg
bTEgPSAyICogbCAtIG0yOwogICAgcmV0dXJuIG5ldyBSZ2IoCiAgICAgIGhzbDJyZ2IoaCA+PSAy
NDAgPyBoIC0gMjQwIDogaCArIDEyMCwgbTEsIG0yKSwKICAgICAgaHNsMnJnYihoLCBtMSwgbTIp
LAogICAgICBoc2wycmdiKGggPCAxMjAgPyBoICsgMjQwIDogaCAtIDEyMCwgbTEsIG0yKSwKICAg
ICAgdGhpcy5vcGFjaXR5CiAgICApOwogIH0sCiAgZGlzcGxheWFibGU6IGZ1bmN0aW9uKCkgewog
ICAgcmV0dXJuICgwIDw9IHRoaXMucyAmJiB0aGlzLnMgPD0gMSB8fCBpc05hTih0aGlzLnMpKQog
ICAgICAgICYmICgwIDw9IHRoaXMubCAmJiB0aGlzLmwgPD0gMSkKICAgICAgICAmJiAoMCA8PSB0
aGlzLm9wYWNpdHkgJiYgdGhpcy5vcGFjaXR5IDw9IDEpOwogIH0sCiAgZm9ybWF0SHNsOiBmdW5j
dGlvbigpIHsKICAgIHZhciBhID0gdGhpcy5vcGFjaXR5OyBhID0gaXNOYU4oYSkgPyAxIDogTWF0
aC5tYXgoMCwgTWF0aC5taW4oMSwgYSkpOwogICAgcmV0dXJuIChhID09PSAxID8gImhzbCgiIDog
ImhzbGEoIikKICAgICAgICArICh0aGlzLmggfHwgMCkgKyAiLCAiCiAgICAgICAgKyAodGhpcy5z
IHx8IDApICogMTAwICsgIiUsICIKICAgICAgICArICh0aGlzLmwgfHwgMCkgKiAxMDAgKyAiJSIK
ICAgICAgICArIChhID09PSAxID8gIikiIDogIiwgIiArIGEgKyAiKSIpOwogIH0KfSkpOwoKLyog
RnJvbSBGdkQgMTMuMzcsIENTUyBDb2xvciBNb2R1bGUgTGV2ZWwgMyAqLwpmdW5jdGlvbiBoc2wy
cmdiKGgsIG0xLCBtMikgewogIHJldHVybiAoaCA8IDYwID8gbTEgKyAobTIgLSBtMSkgKiBoIC8g
NjAKICAgICAgOiBoIDwgMTgwID8gbTIKICAgICAgOiBoIDwgMjQwID8gbTEgKyAobTIgLSBtMSkg
KiAoMjQwIC0gaCkgLyA2MAogICAgICA6IG0xKSAqIDI1NTsKfQoKdmFyIGRlZzJyYWQgPSBNYXRo
LlBJIC8gMTgwOwp2YXIgcmFkMmRlZyA9IDE4MCAvIE1hdGguUEk7CgovLyBodHRwczovL29ic2Vy
dmFibGVocS5jb20vQG1ib3N0b2NrL2xhYi1hbmQtcmdiCnZhciBLID0gMTgsCiAgICBYbiA9IDAu
OTY0MjIsCiAgICBZbiA9IDEsCiAgICBabiA9IDAuODI1MjEsCiAgICB0MCA9IDQgLyAyOSwKICAg
IHQxID0gNiAvIDI5LAogICAgdDIgPSAzICogdDEgKiB0MSwKICAgIHQzID0gdDEgKiB0MSAqIHQx
OwoKZnVuY3Rpb24gbGFiQ29udmVydChvKSB7CiAgaWYgKG8gaW5zdGFuY2VvZiBMYWIpIHJldHVy
biBuZXcgTGFiKG8ubCwgby5hLCBvLmIsIG8ub3BhY2l0eSk7CiAgaWYgKG8gaW5zdGFuY2VvZiBI
Y2wpIHJldHVybiBoY2wybGFiKG8pOwogIGlmICghKG8gaW5zdGFuY2VvZiBSZ2IpKSBvID0gcmdi
Q29udmVydChvKTsKICB2YXIgciA9IHJnYjJscmdiKG8uciksCiAgICAgIGcgPSByZ2IybHJnYihv
LmcpLAogICAgICBiID0gcmdiMmxyZ2Ioby5iKSwKICAgICAgeSA9IHh5ejJsYWIoKDAuMjIyNTA0
NSAqIHIgKyAwLjcxNjg3ODYgKiBnICsgMC4wNjA2MTY5ICogYikgLyBZbiksIHgsIHo7CiAgaWYg
KHIgPT09IGcgJiYgZyA9PT0gYikgeCA9IHogPSB5OyBlbHNlIHsKICAgIHggPSB4eXoybGFiKCgw
LjQzNjA3NDcgKiByICsgMC4zODUwNjQ5ICogZyArIDAuMTQzMDgwNCAqIGIpIC8gWG4pOwogICAg
eiA9IHh5ejJsYWIoKDAuMDEzOTMyMiAqIHIgKyAwLjA5NzEwNDUgKiBnICsgMC43MTQxNzMzICog
YikgLyBabik7CiAgfQogIHJldHVybiBuZXcgTGFiKDExNiAqIHkgLSAxNiwgNTAwICogKHggLSB5
KSwgMjAwICogKHkgLSB6KSwgby5vcGFjaXR5KTsKfQoKZnVuY3Rpb24gZ3JheShsLCBvcGFjaXR5
KSB7CiAgcmV0dXJuIG5ldyBMYWIobCwgMCwgMCwgb3BhY2l0eSA9PSBudWxsID8gMSA6IG9wYWNp
dHkpOwp9CgpmdW5jdGlvbiBsYWIobCwgYSwgYiwgb3BhY2l0eSkgewogIHJldHVybiBhcmd1bWVu
dHMubGVuZ3RoID09PSAxID8gbGFiQ29udmVydChsKSA6IG5ldyBMYWIobCwgYSwgYiwgb3BhY2l0
eSA9PSBudWxsID8gMSA6IG9wYWNpdHkpOwp9CgpmdW5jdGlvbiBMYWIobCwgYSwgYiwgb3BhY2l0
eSkgewogIHRoaXMubCA9ICtsOwogIHRoaXMuYSA9ICthOwogIHRoaXMuYiA9ICtiOwogIHRoaXMu
b3BhY2l0eSA9ICtvcGFjaXR5Owp9CgpkZWZpbmUoTGFiLCBsYWIsIGV4dGVuZChDb2xvciwgewog
IGJyaWdodGVyOiBmdW5jdGlvbihrKSB7CiAgICByZXR1cm4gbmV3IExhYih0aGlzLmwgKyBLICog
KGsgPT0gbnVsbCA/IDEgOiBrKSwgdGhpcy5hLCB0aGlzLmIsIHRoaXMub3BhY2l0eSk7CiAgfSwK
ICBkYXJrZXI6IGZ1bmN0aW9uKGspIHsKICAgIHJldHVybiBuZXcgTGFiKHRoaXMubCAtIEsgKiAo
ayA9PSBudWxsID8gMSA6IGspLCB0aGlzLmEsIHRoaXMuYiwgdGhpcy5vcGFjaXR5KTsKICB9LAog
IHJnYjogZnVuY3Rpb24oKSB7CiAgICB2YXIgeSA9ICh0aGlzLmwgKyAxNikgLyAxMTYsCiAgICAg
ICAgeCA9IGlzTmFOKHRoaXMuYSkgPyB5IDogeSArIHRoaXMuYSAvIDUwMCwKICAgICAgICB6ID0g
aXNOYU4odGhpcy5iKSA/IHkgOiB5IC0gdGhpcy5iIC8gMjAwOwogICAgeCA9IFhuICogbGFiMnh5
eih4KTsKICAgIHkgPSBZbiAqIGxhYjJ4eXooeSk7CiAgICB6ID0gWm4gKiBsYWIyeHl6KHopOwog
ICAgcmV0dXJuIG5ldyBSZ2IoCiAgICAgIGxyZ2IycmdiKCAzLjEzMzg1NjEgKiB4IC0gMS42MTY4
NjY3ICogeSAtIDAuNDkwNjE0NiAqIHopLAogICAgICBscmdiMnJnYigtMC45Nzg3Njg0ICogeCAr
IDEuOTE2MTQxNSAqIHkgKyAwLjAzMzQ1NDAgKiB6KSwKICAgICAgbHJnYjJyZ2IoIDAuMDcxOTQ1
MyAqIHggLSAwLjIyODk5MTQgKiB5ICsgMS40MDUyNDI3ICogeiksCiAgICAgIHRoaXMub3BhY2l0
eQogICAgKTsKICB9Cn0pKTsKCmZ1bmN0aW9uIHh5ejJsYWIodCkgewogIHJldHVybiB0ID4gdDMg
PyBNYXRoLnBvdyh0LCAxIC8gMykgOiB0IC8gdDIgKyB0MDsKfQoKZnVuY3Rpb24gbGFiMnh5eih0
KSB7CiAgcmV0dXJuIHQgPiB0MSA/IHQgKiB0ICogdCA6IHQyICogKHQgLSB0MCk7Cn0KCmZ1bmN0
aW9uIGxyZ2IycmdiKHgpIHsKICByZXR1cm4gMjU1ICogKHggPD0gMC4wMDMxMzA4ID8gMTIuOTIg
KiB4IDogMS4wNTUgKiBNYXRoLnBvdyh4LCAxIC8gMi40KSAtIDAuMDU1KTsKfQoKZnVuY3Rpb24g
cmdiMmxyZ2IoeCkgewogIHJldHVybiAoeCAvPSAyNTUpIDw9IDAuMDQwNDUgPyB4IC8gMTIuOTIg
OiBNYXRoLnBvdygoeCArIDAuMDU1KSAvIDEuMDU1LCAyLjQpOwp9CgpmdW5jdGlvbiBoY2xDb252
ZXJ0KG8pIHsKICBpZiAobyBpbnN0YW5jZW9mIEhjbCkgcmV0dXJuIG5ldyBIY2woby5oLCBvLmMs
IG8ubCwgby5vcGFjaXR5KTsKICBpZiAoIShvIGluc3RhbmNlb2YgTGFiKSkgbyA9IGxhYkNvbnZl
cnQobyk7CiAgaWYgKG8uYSA9PT0gMCAmJiBvLmIgPT09IDApIHJldHVybiBuZXcgSGNsKE5hTiwg
MCA8IG8ubCAmJiBvLmwgPCAxMDAgPyAwIDogTmFOLCBvLmwsIG8ub3BhY2l0eSk7CiAgdmFyIGgg
PSBNYXRoLmF0YW4yKG8uYiwgby5hKSAqIHJhZDJkZWc7CiAgcmV0dXJuIG5ldyBIY2woaCA8IDAg
PyBoICsgMzYwIDogaCwgTWF0aC5zcXJ0KG8uYSAqIG8uYSArIG8uYiAqIG8uYiksIG8ubCwgby5v
cGFjaXR5KTsKfQoKZnVuY3Rpb24gbGNoKGwsIGMsIGgsIG9wYWNpdHkpIHsKICByZXR1cm4gYXJn
dW1lbnRzLmxlbmd0aCA9PT0gMSA/IGhjbENvbnZlcnQobCkgOiBuZXcgSGNsKGgsIGMsIGwsIG9w
YWNpdHkgPT0gbnVsbCA/IDEgOiBvcGFjaXR5KTsKfQoKZnVuY3Rpb24gaGNsKGgsIGMsIGwsIG9w
YWNpdHkpIHsKICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA9PT0gMSA/IGhjbENvbnZlcnQoaCkg
OiBuZXcgSGNsKGgsIGMsIGwsIG9wYWNpdHkgPT0gbnVsbCA/IDEgOiBvcGFjaXR5KTsKfQoKZnVu
Y3Rpb24gSGNsKGgsIGMsIGwsIG9wYWNpdHkpIHsKICB0aGlzLmggPSAraDsKICB0aGlzLmMgPSAr
YzsKICB0aGlzLmwgPSArbDsKICB0aGlzLm9wYWNpdHkgPSArb3BhY2l0eTsKfQoKZnVuY3Rpb24g
aGNsMmxhYihvKSB7CiAgaWYgKGlzTmFOKG8uaCkpIHJldHVybiBuZXcgTGFiKG8ubCwgMCwgMCwg
by5vcGFjaXR5KTsKICB2YXIgaCA9IG8uaCAqIGRlZzJyYWQ7CiAgcmV0dXJuIG5ldyBMYWIoby5s
LCBNYXRoLmNvcyhoKSAqIG8uYywgTWF0aC5zaW4oaCkgKiBvLmMsIG8ub3BhY2l0eSk7Cn0KCmRl
ZmluZShIY2wsIGhjbCwgZXh0ZW5kKENvbG9yLCB7CiAgYnJpZ2h0ZXI6IGZ1bmN0aW9uKGspIHsK
ICAgIHJldHVybiBuZXcgSGNsKHRoaXMuaCwgdGhpcy5jLCB0aGlzLmwgKyBLICogKGsgPT0gbnVs
bCA/IDEgOiBrKSwgdGhpcy5vcGFjaXR5KTsKICB9LAogIGRhcmtlcjogZnVuY3Rpb24oaykgewog
ICAgcmV0dXJuIG5ldyBIY2wodGhpcy5oLCB0aGlzLmMsIHRoaXMubCAtIEsgKiAoayA9PSBudWxs
ID8gMSA6IGspLCB0aGlzLm9wYWNpdHkpOwogIH0sCiAgcmdiOiBmdW5jdGlvbigpIHsKICAgIHJl
dHVybiBoY2wybGFiKHRoaXMpLnJnYigpOwogIH0KfSkpOwoKdmFyIEEgPSAtMC4xNDg2MSwKICAg
IEIgPSArMS43ODI3NywKICAgIEMgPSAtMC4yOTIyNywKICAgIEQgPSAtMC45MDY0OSwKICAgIEUg
PSArMS45NzI5NCwKICAgIEVEID0gRSAqIEQsCiAgICBFQiA9IEUgKiBCLAogICAgQkNfREEgPSBC
ICogQyAtIEQgKiBBOwoKZnVuY3Rpb24gY3ViZWhlbGl4Q29udmVydChvKSB7CiAgaWYgKG8gaW5z
dGFuY2VvZiBDdWJlaGVsaXgpIHJldHVybiBuZXcgQ3ViZWhlbGl4KG8uaCwgby5zLCBvLmwsIG8u
b3BhY2l0eSk7CiAgaWYgKCEobyBpbnN0YW5jZW9mIFJnYikpIG8gPSByZ2JDb252ZXJ0KG8pOwog
IHZhciByID0gby5yIC8gMjU1LAogICAgICBnID0gby5nIC8gMjU1LAogICAgICBiID0gby5iIC8g
MjU1LAogICAgICBsID0gKEJDX0RBICogYiArIEVEICogciAtIEVCICogZykgLyAoQkNfREEgKyBF
RCAtIEVCKSwKICAgICAgYmwgPSBiIC0gbCwKICAgICAgayA9IChFICogKGcgLSBsKSAtIEMgKiBi
bCkgLyBELAogICAgICBzID0gTWF0aC5zcXJ0KGsgKiBrICsgYmwgKiBibCkgLyAoRSAqIGwgKiAo
MSAtIGwpKSwgLy8gTmFOIGlmIGw9MCBvciBsPTEKICAgICAgaCA9IHMgPyBNYXRoLmF0YW4yKGss
IGJsKSAqIHJhZDJkZWcgLSAxMjAgOiBOYU47CiAgcmV0dXJuIG5ldyBDdWJlaGVsaXgoaCA8IDAg
PyBoICsgMzYwIDogaCwgcywgbCwgby5vcGFjaXR5KTsKfQoKZnVuY3Rpb24gY3ViZWhlbGl4KGgs
IHMsIGwsIG9wYWNpdHkpIHsKICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA9PT0gMSA/IGN1YmVo
ZWxpeENvbnZlcnQoaCkgOiBuZXcgQ3ViZWhlbGl4KGgsIHMsIGwsIG9wYWNpdHkgPT0gbnVsbCA/
IDEgOiBvcGFjaXR5KTsKfQoKZnVuY3Rpb24gQ3ViZWhlbGl4KGgsIHMsIGwsIG9wYWNpdHkpIHsK
ICB0aGlzLmggPSAraDsKICB0aGlzLnMgPSArczsKICB0aGlzLmwgPSArbDsKICB0aGlzLm9wYWNp
dHkgPSArb3BhY2l0eTsKfQoKZGVmaW5lKEN1YmVoZWxpeCwgY3ViZWhlbGl4LCBleHRlbmQoQ29s
b3IsIHsKICBicmlnaHRlcjogZnVuY3Rpb24oaykgewogICAgayA9IGsgPT0gbnVsbCA/IGJyaWdo
dGVyIDogTWF0aC5wb3coYnJpZ2h0ZXIsIGspOwogICAgcmV0dXJuIG5ldyBDdWJlaGVsaXgodGhp
cy5oLCB0aGlzLnMsIHRoaXMubCAqIGssIHRoaXMub3BhY2l0eSk7CiAgfSwKICBkYXJrZXI6IGZ1
bmN0aW9uKGspIHsKICAgIGsgPSBrID09IG51bGwgPyBkYXJrZXIgOiBNYXRoLnBvdyhkYXJrZXIs
IGspOwogICAgcmV0dXJuIG5ldyBDdWJlaGVsaXgodGhpcy5oLCB0aGlzLnMsIHRoaXMubCAqIGss
IHRoaXMub3BhY2l0eSk7CiAgfSwKICByZ2I6IGZ1bmN0aW9uKCkgewogICAgdmFyIGggPSBpc05h
Tih0aGlzLmgpID8gMCA6ICh0aGlzLmggKyAxMjApICogZGVnMnJhZCwKICAgICAgICBsID0gK3Ro
aXMubCwKICAgICAgICBhID0gaXNOYU4odGhpcy5zKSA/IDAgOiB0aGlzLnMgKiBsICogKDEgLSBs
KSwKICAgICAgICBjb3NoID0gTWF0aC5jb3MoaCksCiAgICAgICAgc2luaCA9IE1hdGguc2luKGgp
OwogICAgcmV0dXJuIG5ldyBSZ2IoCiAgICAgIDI1NSAqIChsICsgYSAqIChBICogY29zaCArIEIg
KiBzaW5oKSksCiAgICAgIDI1NSAqIChsICsgYSAqIChDICogY29zaCArIEQgKiBzaW5oKSksCiAg
ICAgIDI1NSAqIChsICsgYSAqIChFICogY29zaCkpLAogICAgICB0aGlzLm9wYWNpdHkKICAgICk7
CiAgfQp9KSk7CgpmdW5jdGlvbiBiYXNpcyh0MSwgdjAsIHYxLCB2MiwgdjMpIHsKICB2YXIgdDIg
PSB0MSAqIHQxLCB0MyA9IHQyICogdDE7CiAgcmV0dXJuICgoMSAtIDMgKiB0MSArIDMgKiB0MiAt
IHQzKSAqIHYwCiAgICAgICsgKDQgLSA2ICogdDIgKyAzICogdDMpICogdjEKICAgICAgKyAoMSAr
IDMgKiB0MSArIDMgKiB0MiAtIDMgKiB0MykgKiB2MgogICAgICArIHQzICogdjMpIC8gNjsKfQoK
ZnVuY3Rpb24gYmFzaXMkMSh2YWx1ZXMpIHsKICB2YXIgbiA9IHZhbHVlcy5sZW5ndGggLSAxOwog
IHJldHVybiBmdW5jdGlvbih0KSB7CiAgICB2YXIgaSA9IHQgPD0gMCA/ICh0ID0gMCkgOiB0ID49
IDEgPyAodCA9IDEsIG4gLSAxKSA6IE1hdGguZmxvb3IodCAqIG4pLAogICAgICAgIHYxID0gdmFs
dWVzW2ldLAogICAgICAgIHYyID0gdmFsdWVzW2kgKyAxXSwKICAgICAgICB2MCA9IGkgPiAwID8g
dmFsdWVzW2kgLSAxXSA6IDIgKiB2MSAtIHYyLAogICAgICAgIHYzID0gaSA8IG4gLSAxID8gdmFs
dWVzW2kgKyAyXSA6IDIgKiB2MiAtIHYxOwogICAgcmV0dXJuIGJhc2lzKCh0IC0gaSAvIG4pICog
biwgdjAsIHYxLCB2MiwgdjMpOwogIH07Cn0KCmZ1bmN0aW9uIGJhc2lzQ2xvc2VkKHZhbHVlcykg
ewogIHZhciBuID0gdmFsdWVzLmxlbmd0aDsKICByZXR1cm4gZnVuY3Rpb24odCkgewogICAgdmFy
IGkgPSBNYXRoLmZsb29yKCgodCAlPSAxKSA8IDAgPyArK3QgOiB0KSAqIG4pLAogICAgICAgIHYw
ID0gdmFsdWVzWyhpICsgbiAtIDEpICUgbl0sCiAgICAgICAgdjEgPSB2YWx1ZXNbaSAlIG5dLAog
ICAgICAgIHYyID0gdmFsdWVzWyhpICsgMSkgJSBuXSwKICAgICAgICB2MyA9IHZhbHVlc1soaSAr
IDIpICUgbl07CiAgICByZXR1cm4gYmFzaXMoKHQgLSBpIC8gbikgKiBuLCB2MCwgdjEsIHYyLCB2
Myk7CiAgfTsKfQoKZnVuY3Rpb24gY29uc3RhbnQkMyh4KSB7CiAgcmV0dXJuIGZ1bmN0aW9uKCkg
ewogICAgcmV0dXJuIHg7CiAgfTsKfQoKZnVuY3Rpb24gbGluZWFyKGEsIGQpIHsKICByZXR1cm4g
ZnVuY3Rpb24odCkgewogICAgcmV0dXJuIGEgKyB0ICogZDsKICB9Owp9CgpmdW5jdGlvbiBleHBv
bmVudGlhbChhLCBiLCB5KSB7CiAgcmV0dXJuIGEgPSBNYXRoLnBvdyhhLCB5KSwgYiA9IE1hdGgu
cG93KGIsIHkpIC0gYSwgeSA9IDEgLyB5LCBmdW5jdGlvbih0KSB7CiAgICByZXR1cm4gTWF0aC5w
b3coYSArIHQgKiBiLCB5KTsKICB9Owp9CgpmdW5jdGlvbiBodWUoYSwgYikgewogIHZhciBkID0g
YiAtIGE7CiAgcmV0dXJuIGQgPyBsaW5lYXIoYSwgZCA+IDE4MCB8fCBkIDwgLTE4MCA/IGQgLSAz
NjAgKiBNYXRoLnJvdW5kKGQgLyAzNjApIDogZCkgOiBjb25zdGFudCQzKGlzTmFOKGEpID8gYiA6
IGEpOwp9CgpmdW5jdGlvbiBnYW1tYSh5KSB7CiAgcmV0dXJuICh5ID0gK3kpID09PSAxID8gbm9n
YW1tYSA6IGZ1bmN0aW9uKGEsIGIpIHsKICAgIHJldHVybiBiIC0gYSA/IGV4cG9uZW50aWFsKGEs
IGIsIHkpIDogY29uc3RhbnQkMyhpc05hTihhKSA/IGIgOiBhKTsKICB9Owp9CgpmdW5jdGlvbiBu
b2dhbW1hKGEsIGIpIHsKICB2YXIgZCA9IGIgLSBhOwogIHJldHVybiBkID8gbGluZWFyKGEsIGQp
IDogY29uc3RhbnQkMyhpc05hTihhKSA/IGIgOiBhKTsKfQoKdmFyIGludGVycG9sYXRlUmdiID0g
KGZ1bmN0aW9uIHJnYkdhbW1hKHkpIHsKICB2YXIgY29sb3IgPSBnYW1tYSh5KTsKCiAgZnVuY3Rp
b24gcmdiJDEoc3RhcnQsIGVuZCkgewogICAgdmFyIHIgPSBjb2xvcigoc3RhcnQgPSByZ2Ioc3Rh
cnQpKS5yLCAoZW5kID0gcmdiKGVuZCkpLnIpLAogICAgICAgIGcgPSBjb2xvcihzdGFydC5nLCBl
bmQuZyksCiAgICAgICAgYiA9IGNvbG9yKHN0YXJ0LmIsIGVuZC5iKSwKICAgICAgICBvcGFjaXR5
ID0gbm9nYW1tYShzdGFydC5vcGFjaXR5LCBlbmQub3BhY2l0eSk7CiAgICByZXR1cm4gZnVuY3Rp
b24odCkgewogICAgICBzdGFydC5yID0gcih0KTsKICAgICAgc3RhcnQuZyA9IGcodCk7CiAgICAg
IHN0YXJ0LmIgPSBiKHQpOwogICAgICBzdGFydC5vcGFjaXR5ID0gb3BhY2l0eSh0KTsKICAgICAg
cmV0dXJuIHN0YXJ0ICsgIiI7CiAgICB9OwogIH0KCiAgcmdiJDEuZ2FtbWEgPSByZ2JHYW1tYTsK
CiAgcmV0dXJuIHJnYiQxOwp9KSgxKTsKCmZ1bmN0aW9uIHJnYlNwbGluZShzcGxpbmUpIHsKICBy
ZXR1cm4gZnVuY3Rpb24oY29sb3JzKSB7CiAgICB2YXIgbiA9IGNvbG9ycy5sZW5ndGgsCiAgICAg
ICAgciA9IG5ldyBBcnJheShuKSwKICAgICAgICBnID0gbmV3IEFycmF5KG4pLAogICAgICAgIGIg
PSBuZXcgQXJyYXkobiksCiAgICAgICAgaSwgY29sb3I7CiAgICBmb3IgKGkgPSAwOyBpIDwgbjsg
KytpKSB7CiAgICAgIGNvbG9yID0gcmdiKGNvbG9yc1tpXSk7CiAgICAgIHJbaV0gPSBjb2xvci5y
IHx8IDA7CiAgICAgIGdbaV0gPSBjb2xvci5nIHx8IDA7CiAgICAgIGJbaV0gPSBjb2xvci5iIHx8
IDA7CiAgICB9CiAgICByID0gc3BsaW5lKHIpOwogICAgZyA9IHNwbGluZShnKTsKICAgIGIgPSBz
cGxpbmUoYik7CiAgICBjb2xvci5vcGFjaXR5ID0gMTsKICAgIHJldHVybiBmdW5jdGlvbih0KSB7
CiAgICAgIGNvbG9yLnIgPSByKHQpOwogICAgICBjb2xvci5nID0gZyh0KTsKICAgICAgY29sb3Iu
YiA9IGIodCk7CiAgICAgIHJldHVybiBjb2xvciArICIiOwogICAgfTsKICB9Owp9Cgp2YXIgcmdi
QmFzaXMgPSByZ2JTcGxpbmUoYmFzaXMkMSk7CnZhciByZ2JCYXNpc0Nsb3NlZCA9IHJnYlNwbGlu
ZShiYXNpc0Nsb3NlZCk7CgpmdW5jdGlvbiBudW1iZXJBcnJheShhLCBiKSB7CiAgaWYgKCFiKSBi
ID0gW107CiAgdmFyIG4gPSBhID8gTWF0aC5taW4oYi5sZW5ndGgsIGEubGVuZ3RoKSA6IDAsCiAg
ICAgIGMgPSBiLnNsaWNlKCksCiAgICAgIGk7CiAgcmV0dXJuIGZ1bmN0aW9uKHQpIHsKICAgIGZv
ciAoaSA9IDA7IGkgPCBuOyArK2kpIGNbaV0gPSBhW2ldICogKDEgLSB0KSArIGJbaV0gKiB0Owog
ICAgcmV0dXJuIGM7CiAgfTsKfQoKZnVuY3Rpb24gaXNOdW1iZXJBcnJheSh4KSB7CiAgcmV0dXJu
IEFycmF5QnVmZmVyLmlzVmlldyh4KSAmJiAhKHggaW5zdGFuY2VvZiBEYXRhVmlldyk7Cn0KCmZ1
bmN0aW9uIGFycmF5JDEoYSwgYikgewogIHJldHVybiAoaXNOdW1iZXJBcnJheShiKSA/IG51bWJl
ckFycmF5IDogZ2VuZXJpY0FycmF5KShhLCBiKTsKfQoKZnVuY3Rpb24gZ2VuZXJpY0FycmF5KGEs
IGIpIHsKICB2YXIgbmIgPSBiID8gYi5sZW5ndGggOiAwLAogICAgICBuYSA9IGEgPyBNYXRoLm1p
bihuYiwgYS5sZW5ndGgpIDogMCwKICAgICAgeCA9IG5ldyBBcnJheShuYSksCiAgICAgIGMgPSBu
ZXcgQXJyYXkobmIpLAogICAgICBpOwoKICBmb3IgKGkgPSAwOyBpIDwgbmE7ICsraSkgeFtpXSA9
IGludGVycG9sYXRlVmFsdWUoYVtpXSwgYltpXSk7CiAgZm9yICg7IGkgPCBuYjsgKytpKSBjW2ld
ID0gYltpXTsKCiAgcmV0dXJuIGZ1bmN0aW9uKHQpIHsKICAgIGZvciAoaSA9IDA7IGkgPCBuYTsg
KytpKSBjW2ldID0geFtpXSh0KTsKICAgIHJldHVybiBjOwogIH07Cn0KCmZ1bmN0aW9uIGRhdGUo
YSwgYikgewogIHZhciBkID0gbmV3IERhdGU7CiAgcmV0dXJuIGEgPSArYSwgYiA9ICtiLCBmdW5j
dGlvbih0KSB7CiAgICByZXR1cm4gZC5zZXRUaW1lKGEgKiAoMSAtIHQpICsgYiAqIHQpLCBkOwog
IH07Cn0KCmZ1bmN0aW9uIGludGVycG9sYXRlTnVtYmVyKGEsIGIpIHsKICByZXR1cm4gYSA9ICth
LCBiID0gK2IsIGZ1bmN0aW9uKHQpIHsKICAgIHJldHVybiBhICogKDEgLSB0KSArIGIgKiB0Owog
IH07Cn0KCmZ1bmN0aW9uIG9iamVjdChhLCBiKSB7CiAgdmFyIGkgPSB7fSwKICAgICAgYyA9IHt9
LAogICAgICBrOwoKICBpZiAoYSA9PT0gbnVsbCB8fCB0eXBlb2YgYSAhPT0gIm9iamVjdCIpIGEg
PSB7fTsKICBpZiAoYiA9PT0gbnVsbCB8fCB0eXBlb2YgYiAhPT0gIm9iamVjdCIpIGIgPSB7fTsK
CiAgZm9yIChrIGluIGIpIHsKICAgIGlmIChrIGluIGEpIHsKICAgICAgaVtrXSA9IGludGVycG9s
YXRlVmFsdWUoYVtrXSwgYltrXSk7CiAgICB9IGVsc2UgewogICAgICBjW2tdID0gYltrXTsKICAg
IH0KICB9CgogIHJldHVybiBmdW5jdGlvbih0KSB7CiAgICBmb3IgKGsgaW4gaSkgY1trXSA9IGlb
a10odCk7CiAgICByZXR1cm4gYzsKICB9Owp9Cgp2YXIgcmVBID0gL1stK10/KD86XGQrXC4/XGQq
fFwuP1xkKykoPzpbZUVdWy0rXT9cZCspPy9nLAogICAgcmVCID0gbmV3IFJlZ0V4cChyZUEuc291
cmNlLCAiZyIpOwoKZnVuY3Rpb24gemVybyhiKSB7CiAgcmV0dXJuIGZ1bmN0aW9uKCkgewogICAg
cmV0dXJuIGI7CiAgfTsKfQoKZnVuY3Rpb24gb25lKGIpIHsKICByZXR1cm4gZnVuY3Rpb24odCkg
ewogICAgcmV0dXJuIGIodCkgKyAiIjsKICB9Owp9CgpmdW5jdGlvbiBpbnRlcnBvbGF0ZVN0cmlu
ZyhhLCBiKSB7CiAgdmFyIGJpID0gcmVBLmxhc3RJbmRleCA9IHJlQi5sYXN0SW5kZXggPSAwLCAv
LyBzY2FuIGluZGV4IGZvciBuZXh0IG51bWJlciBpbiBiCiAgICAgIGFtLCAvLyBjdXJyZW50IG1h
dGNoIGluIGEKICAgICAgYm0sIC8vIGN1cnJlbnQgbWF0Y2ggaW4gYgogICAgICBicywgLy8gc3Ry
aW5nIHByZWNlZGluZyBjdXJyZW50IG51bWJlciBpbiBiLCBpZiBhbnkKICAgICAgaSA9IC0xLCAv
LyBpbmRleCBpbiBzCiAgICAgIHMgPSBbXSwgLy8gc3RyaW5nIGNvbnN0YW50cyBhbmQgcGxhY2Vo
b2xkZXJzCiAgICAgIHEgPSBbXTsgLy8gbnVtYmVyIGludGVycG9sYXRvcnMKCiAgLy8gQ29lcmNl
IGlucHV0cyB0byBzdHJpbmdzLgogIGEgPSBhICsgIiIsIGIgPSBiICsgIiI7CgogIC8vIEludGVy
cG9sYXRlIHBhaXJzIG9mIG51bWJlcnMgaW4gYSAmIGIuCiAgd2hpbGUgKChhbSA9IHJlQS5leGVj
KGEpKQogICAgICAmJiAoYm0gPSByZUIuZXhlYyhiKSkpIHsKICAgIGlmICgoYnMgPSBibS5pbmRl
eCkgPiBiaSkgeyAvLyBhIHN0cmluZyBwcmVjZWRlcyB0aGUgbmV4dCBudW1iZXIgaW4gYgogICAg
ICBicyA9IGIuc2xpY2UoYmksIGJzKTsKICAgICAgaWYgKHNbaV0pIHNbaV0gKz0gYnM7IC8vIGNv
YWxlc2NlIHdpdGggcHJldmlvdXMgc3RyaW5nCiAgICAgIGVsc2Ugc1srK2ldID0gYnM7CiAgICB9
CiAgICBpZiAoKGFtID0gYW1bMF0pID09PSAoYm0gPSBibVswXSkpIHsgLy8gbnVtYmVycyBpbiBh
ICYgYiBtYXRjaAogICAgICBpZiAoc1tpXSkgc1tpXSArPSBibTsgLy8gY29hbGVzY2Ugd2l0aCBw
cmV2aW91cyBzdHJpbmcKICAgICAgZWxzZSBzWysraV0gPSBibTsKICAgIH0gZWxzZSB7IC8vIGlu
dGVycG9sYXRlIG5vbi1tYXRjaGluZyBudW1iZXJzCiAgICAgIHNbKytpXSA9IG51bGw7CiAgICAg
IHEucHVzaCh7aTogaSwgeDogaW50ZXJwb2xhdGVOdW1iZXIoYW0sIGJtKX0pOwogICAgfQogICAg
YmkgPSByZUIubGFzdEluZGV4OwogIH0KCiAgLy8gQWRkIHJlbWFpbnMgb2YgYi4KICBpZiAoYmkg
PCBiLmxlbmd0aCkgewogICAgYnMgPSBiLnNsaWNlKGJpKTsKICAgIGlmIChzW2ldKSBzW2ldICs9
IGJzOyAvLyBjb2FsZXNjZSB3aXRoIHByZXZpb3VzIHN0cmluZwogICAgZWxzZSBzWysraV0gPSBi
czsKICB9CgogIC8vIFNwZWNpYWwgb3B0aW1pemF0aW9uIGZvciBvbmx5IGEgc2luZ2xlIG1hdGNo
LgogIC8vIE90aGVyd2lzZSwgaW50ZXJwb2xhdGUgZWFjaCBvZiB0aGUgbnVtYmVycyBhbmQgcmVq
b2luIHRoZSBzdHJpbmcuCiAgcmV0dXJuIHMubGVuZ3RoIDwgMiA/IChxWzBdCiAgICAgID8gb25l
KHFbMF0ueCkKICAgICAgOiB6ZXJvKGIpKQogICAgICA6IChiID0gcS5sZW5ndGgsIGZ1bmN0aW9u
KHQpIHsKICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBvOyBpIDwgYjsgKytpKSBzWyhvID0gcVtp
XSkuaV0gPSBvLngodCk7CiAgICAgICAgICByZXR1cm4gcy5qb2luKCIiKTsKICAgICAgICB9KTsK
fQoKZnVuY3Rpb24gaW50ZXJwb2xhdGVWYWx1ZShhLCBiKSB7CiAgdmFyIHQgPSB0eXBlb2YgYiwg
YzsKICByZXR1cm4gYiA9PSBudWxsIHx8IHQgPT09ICJib29sZWFuIiA/IGNvbnN0YW50JDMoYikK
ICAgICAgOiAodCA9PT0gIm51bWJlciIgPyBpbnRlcnBvbGF0ZU51bWJlcgogICAgICA6IHQgPT09
ICJzdHJpbmciID8gKChjID0gY29sb3IoYikpID8gKGIgPSBjLCBpbnRlcnBvbGF0ZVJnYikgOiBp
bnRlcnBvbGF0ZVN0cmluZykKICAgICAgOiBiIGluc3RhbmNlb2YgY29sb3IgPyBpbnRlcnBvbGF0
ZVJnYgogICAgICA6IGIgaW5zdGFuY2VvZiBEYXRlID8gZGF0ZQogICAgICA6IGlzTnVtYmVyQXJy
YXkoYikgPyBudW1iZXJBcnJheQogICAgICA6IEFycmF5LmlzQXJyYXkoYikgPyBnZW5lcmljQXJy
YXkKICAgICAgOiB0eXBlb2YgYi52YWx1ZU9mICE9PSAiZnVuY3Rpb24iICYmIHR5cGVvZiBiLnRv
U3RyaW5nICE9PSAiZnVuY3Rpb24iIHx8IGlzTmFOKGIpID8gb2JqZWN0CiAgICAgIDogaW50ZXJw
b2xhdGVOdW1iZXIpKGEsIGIpOwp9CgpmdW5jdGlvbiBkaXNjcmV0ZShyYW5nZSkgewogIHZhciBu
ID0gcmFuZ2UubGVuZ3RoOwogIHJldHVybiBmdW5jdGlvbih0KSB7CiAgICByZXR1cm4gcmFuZ2Vb
TWF0aC5tYXgoMCwgTWF0aC5taW4obiAtIDEsIE1hdGguZmxvb3IodCAqIG4pKSldOwogIH07Cn0K
CmZ1bmN0aW9uIGh1ZSQxKGEsIGIpIHsKICB2YXIgaSA9IGh1ZSgrYSwgK2IpOwogIHJldHVybiBm
dW5jdGlvbih0KSB7CiAgICB2YXIgeCA9IGkodCk7CiAgICByZXR1cm4geCAtIDM2MCAqIE1hdGgu
Zmxvb3IoeCAvIDM2MCk7CiAgfTsKfQoKZnVuY3Rpb24gaW50ZXJwb2xhdGVSb3VuZChhLCBiKSB7
CiAgcmV0dXJuIGEgPSArYSwgYiA9ICtiLCBmdW5jdGlvbih0KSB7CiAgICByZXR1cm4gTWF0aC5y
b3VuZChhICogKDEgLSB0KSArIGIgKiB0KTsKICB9Owp9Cgp2YXIgZGVncmVlcyA9IDE4MCAvIE1h
dGguUEk7Cgp2YXIgaWRlbnRpdHkkMiA9IHsKICB0cmFuc2xhdGVYOiAwLAogIHRyYW5zbGF0ZVk6
IDAsCiAgcm90YXRlOiAwLAogIHNrZXdYOiAwLAogIHNjYWxlWDogMSwKICBzY2FsZVk6IDEKfTsK
CmZ1bmN0aW9uIGRlY29tcG9zZShhLCBiLCBjLCBkLCBlLCBmKSB7CiAgdmFyIHNjYWxlWCwgc2Nh
bGVZLCBza2V3WDsKICBpZiAoc2NhbGVYID0gTWF0aC5zcXJ0KGEgKiBhICsgYiAqIGIpKSBhIC89
IHNjYWxlWCwgYiAvPSBzY2FsZVg7CiAgaWYgKHNrZXdYID0gYSAqIGMgKyBiICogZCkgYyAtPSBh
ICogc2tld1gsIGQgLT0gYiAqIHNrZXdYOwogIGlmIChzY2FsZVkgPSBNYXRoLnNxcnQoYyAqIGMg
KyBkICogZCkpIGMgLz0gc2NhbGVZLCBkIC89IHNjYWxlWSwgc2tld1ggLz0gc2NhbGVZOwogIGlm
IChhICogZCA8IGIgKiBjKSBhID0gLWEsIGIgPSAtYiwgc2tld1ggPSAtc2tld1gsIHNjYWxlWCA9
IC1zY2FsZVg7CiAgcmV0dXJuIHsKICAgIHRyYW5zbGF0ZVg6IGUsCiAgICB0cmFuc2xhdGVZOiBm
LAogICAgcm90YXRlOiBNYXRoLmF0YW4yKGIsIGEpICogZGVncmVlcywKICAgIHNrZXdYOiBNYXRo
LmF0YW4oc2tld1gpICogZGVncmVlcywKICAgIHNjYWxlWDogc2NhbGVYLAogICAgc2NhbGVZOiBz
Y2FsZVkKICB9Owp9Cgp2YXIgY3NzTm9kZSwKICAgIGNzc1Jvb3QsCiAgICBjc3NWaWV3LAogICAg
c3ZnTm9kZTsKCmZ1bmN0aW9uIHBhcnNlQ3NzKHZhbHVlKSB7CiAgaWYgKHZhbHVlID09PSAibm9u
ZSIpIHJldHVybiBpZGVudGl0eSQyOwogIGlmICghY3NzTm9kZSkgY3NzTm9kZSA9IGRvY3VtZW50
LmNyZWF0ZUVsZW1lbnQoIkRJViIpLCBjc3NSb290ID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50
LCBjc3NWaWV3ID0gZG9jdW1lbnQuZGVmYXVsdFZpZXc7CiAgY3NzTm9kZS5zdHlsZS50cmFuc2Zv
cm0gPSB2YWx1ZTsKICB2YWx1ZSA9IGNzc1ZpZXcuZ2V0Q29tcHV0ZWRTdHlsZShjc3NSb290LmFw
cGVuZENoaWxkKGNzc05vZGUpLCBudWxsKS5nZXRQcm9wZXJ0eVZhbHVlKCJ0cmFuc2Zvcm0iKTsK
ICBjc3NSb290LnJlbW92ZUNoaWxkKGNzc05vZGUpOwogIHZhbHVlID0gdmFsdWUuc2xpY2UoNywg
LTEpLnNwbGl0KCIsIik7CiAgcmV0dXJuIGRlY29tcG9zZSgrdmFsdWVbMF0sICt2YWx1ZVsxXSwg
K3ZhbHVlWzJdLCArdmFsdWVbM10sICt2YWx1ZVs0XSwgK3ZhbHVlWzVdKTsKfQoKZnVuY3Rpb24g
cGFyc2VTdmcodmFsdWUpIHsKICBpZiAodmFsdWUgPT0gbnVsbCkgcmV0dXJuIGlkZW50aXR5JDI7
CiAgaWYgKCFzdmdOb2RlKSBzdmdOb2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCJodHRw
Oi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIsICJnIik7CiAgc3ZnTm9kZS5zZXRBdHRyaWJ1dGUoInRy
YW5zZm9ybSIsIHZhbHVlKTsKICBpZiAoISh2YWx1ZSA9IHN2Z05vZGUudHJhbnNmb3JtLmJhc2VW
YWwuY29uc29saWRhdGUoKSkpIHJldHVybiBpZGVudGl0eSQyOwogIHZhbHVlID0gdmFsdWUubWF0
cml4OwogIHJldHVybiBkZWNvbXBvc2UodmFsdWUuYSwgdmFsdWUuYiwgdmFsdWUuYywgdmFsdWUu
ZCwgdmFsdWUuZSwgdmFsdWUuZik7Cn0KCmZ1bmN0aW9uIGludGVycG9sYXRlVHJhbnNmb3JtKHBh
cnNlLCBweENvbW1hLCBweFBhcmVuLCBkZWdQYXJlbikgewoKICBmdW5jdGlvbiBwb3Aocykgewog
ICAgcmV0dXJuIHMubGVuZ3RoID8gcy5wb3AoKSArICIgIiA6ICIiOwogIH0KCiAgZnVuY3Rpb24g
dHJhbnNsYXRlKHhhLCB5YSwgeGIsIHliLCBzLCBxKSB7CiAgICBpZiAoeGEgIT09IHhiIHx8IHlh
ICE9PSB5YikgewogICAgICB2YXIgaSA9IHMucHVzaCgidHJhbnNsYXRlKCIsIG51bGwsIHB4Q29t
bWEsIG51bGwsIHB4UGFyZW4pOwogICAgICBxLnB1c2goe2k6IGkgLSA0LCB4OiBpbnRlcnBvbGF0
ZU51bWJlcih4YSwgeGIpfSwge2k6IGkgLSAyLCB4OiBpbnRlcnBvbGF0ZU51bWJlcih5YSwgeWIp
fSk7CiAgICB9IGVsc2UgaWYgKHhiIHx8IHliKSB7CiAgICAgIHMucHVzaCgidHJhbnNsYXRlKCIg
KyB4YiArIHB4Q29tbWEgKyB5YiArIHB4UGFyZW4pOwogICAgfQogIH0KCiAgZnVuY3Rpb24gcm90
YXRlKGEsIGIsIHMsIHEpIHsKICAgIGlmIChhICE9PSBiKSB7CiAgICAgIGlmIChhIC0gYiA+IDE4
MCkgYiArPSAzNjA7IGVsc2UgaWYgKGIgLSBhID4gMTgwKSBhICs9IDM2MDsgLy8gc2hvcnRlc3Qg
cGF0aAogICAgICBxLnB1c2goe2k6IHMucHVzaChwb3AocykgKyAicm90YXRlKCIsIG51bGwsIGRl
Z1BhcmVuKSAtIDIsIHg6IGludGVycG9sYXRlTnVtYmVyKGEsIGIpfSk7CiAgICB9IGVsc2UgaWYg
KGIpIHsKICAgICAgcy5wdXNoKHBvcChzKSArICJyb3RhdGUoIiArIGIgKyBkZWdQYXJlbik7CiAg
ICB9CiAgfQoKICBmdW5jdGlvbiBza2V3WChhLCBiLCBzLCBxKSB7CiAgICBpZiAoYSAhPT0gYikg
ewogICAgICBxLnB1c2goe2k6IHMucHVzaChwb3AocykgKyAic2tld1goIiwgbnVsbCwgZGVnUGFy
ZW4pIC0gMiwgeDogaW50ZXJwb2xhdGVOdW1iZXIoYSwgYil9KTsKICAgIH0gZWxzZSBpZiAoYikg
ewogICAgICBzLnB1c2gocG9wKHMpICsgInNrZXdYKCIgKyBiICsgZGVnUGFyZW4pOwogICAgfQog
IH0KCiAgZnVuY3Rpb24gc2NhbGUoeGEsIHlhLCB4YiwgeWIsIHMsIHEpIHsKICAgIGlmICh4YSAh
PT0geGIgfHwgeWEgIT09IHliKSB7CiAgICAgIHZhciBpID0gcy5wdXNoKHBvcChzKSArICJzY2Fs
ZSgiLCBudWxsLCAiLCIsIG51bGwsICIpIik7CiAgICAgIHEucHVzaCh7aTogaSAtIDQsIHg6IGlu
dGVycG9sYXRlTnVtYmVyKHhhLCB4Yil9LCB7aTogaSAtIDIsIHg6IGludGVycG9sYXRlTnVtYmVy
KHlhLCB5Yil9KTsKICAgIH0gZWxzZSBpZiAoeGIgIT09IDEgfHwgeWIgIT09IDEpIHsKICAgICAg
cy5wdXNoKHBvcChzKSArICJzY2FsZSgiICsgeGIgKyAiLCIgKyB5YiArICIpIik7CiAgICB9CiAg
fQoKICByZXR1cm4gZnVuY3Rpb24oYSwgYikgewogICAgdmFyIHMgPSBbXSwgLy8gc3RyaW5nIGNv
bnN0YW50cyBhbmQgcGxhY2Vob2xkZXJzCiAgICAgICAgcSA9IFtdOyAvLyBudW1iZXIgaW50ZXJw
b2xhdG9ycwogICAgYSA9IHBhcnNlKGEpLCBiID0gcGFyc2UoYik7CiAgICB0cmFuc2xhdGUoYS50
cmFuc2xhdGVYLCBhLnRyYW5zbGF0ZVksIGIudHJhbnNsYXRlWCwgYi50cmFuc2xhdGVZLCBzLCBx
KTsKICAgIHJvdGF0ZShhLnJvdGF0ZSwgYi5yb3RhdGUsIHMsIHEpOwogICAgc2tld1goYS5za2V3
WCwgYi5za2V3WCwgcywgcSk7CiAgICBzY2FsZShhLnNjYWxlWCwgYS5zY2FsZVksIGIuc2NhbGVY
LCBiLnNjYWxlWSwgcywgcSk7CiAgICBhID0gYiA9IG51bGw7IC8vIGdjCiAgICByZXR1cm4gZnVu
Y3Rpb24odCkgewogICAgICB2YXIgaSA9IC0xLCBuID0gcS5sZW5ndGgsIG87CiAgICAgIHdoaWxl
ICgrK2kgPCBuKSBzWyhvID0gcVtpXSkuaV0gPSBvLngodCk7CiAgICAgIHJldHVybiBzLmpvaW4o
IiIpOwogICAgfTsKICB9Owp9Cgp2YXIgaW50ZXJwb2xhdGVUcmFuc2Zvcm1Dc3MgPSBpbnRlcnBv
bGF0ZVRyYW5zZm9ybShwYXJzZUNzcywgInB4LCAiLCAicHgpIiwgImRlZykiKTsKdmFyIGludGVy
cG9sYXRlVHJhbnNmb3JtU3ZnID0gaW50ZXJwb2xhdGVUcmFuc2Zvcm0ocGFyc2VTdmcsICIsICIs
ICIpIiwgIikiKTsKCnZhciByaG8gPSBNYXRoLlNRUlQyLAogICAgcmhvMiA9IDIsCiAgICByaG80
ID0gNCwKICAgIGVwc2lsb24yID0gMWUtMTI7CgpmdW5jdGlvbiBjb3NoKHgpIHsKICByZXR1cm4g
KCh4ID0gTWF0aC5leHAoeCkpICsgMSAvIHgpIC8gMjsKfQoKZnVuY3Rpb24gc2luaCh4KSB7CiAg
cmV0dXJuICgoeCA9IE1hdGguZXhwKHgpKSAtIDEgLyB4KSAvIDI7Cn0KCmZ1bmN0aW9uIHRhbmgo
eCkgewogIHJldHVybiAoKHggPSBNYXRoLmV4cCgyICogeCkpIC0gMSkgLyAoeCArIDEpOwp9Cgov
LyBwMCA9IFt1eDAsIHV5MCwgdzBdCi8vIHAxID0gW3V4MSwgdXkxLCB3MV0KZnVuY3Rpb24gaW50
ZXJwb2xhdGVab29tKHAwLCBwMSkgewogIHZhciB1eDAgPSBwMFswXSwgdXkwID0gcDBbMV0sIHcw
ID0gcDBbMl0sCiAgICAgIHV4MSA9IHAxWzBdLCB1eTEgPSBwMVsxXSwgdzEgPSBwMVsyXSwKICAg
ICAgZHggPSB1eDEgLSB1eDAsCiAgICAgIGR5ID0gdXkxIC0gdXkwLAogICAgICBkMiA9IGR4ICog
ZHggKyBkeSAqIGR5LAogICAgICBpLAogICAgICBTOwoKICAvLyBTcGVjaWFsIGNhc2UgZm9yIHUw
IOKJhSB1MS4KICBpZiAoZDIgPCBlcHNpbG9uMikgewogICAgUyA9IE1hdGgubG9nKHcxIC8gdzAp
IC8gcmhvOwogICAgaSA9IGZ1bmN0aW9uKHQpIHsKICAgICAgcmV0dXJuIFsKICAgICAgICB1eDAg
KyB0ICogZHgsCiAgICAgICAgdXkwICsgdCAqIGR5LAogICAgICAgIHcwICogTWF0aC5leHAocmhv
ICogdCAqIFMpCiAgICAgIF07CiAgICB9OwogIH0KCiAgLy8gR2VuZXJhbCBjYXNlLgogIGVsc2Ug
ewogICAgdmFyIGQxID0gTWF0aC5zcXJ0KGQyKSwKICAgICAgICBiMCA9ICh3MSAqIHcxIC0gdzAg
KiB3MCArIHJobzQgKiBkMikgLyAoMiAqIHcwICogcmhvMiAqIGQxKSwKICAgICAgICBiMSA9ICh3
MSAqIHcxIC0gdzAgKiB3MCAtIHJobzQgKiBkMikgLyAoMiAqIHcxICogcmhvMiAqIGQxKSwKICAg
ICAgICByMCA9IE1hdGgubG9nKE1hdGguc3FydChiMCAqIGIwICsgMSkgLSBiMCksCiAgICAgICAg
cjEgPSBNYXRoLmxvZyhNYXRoLnNxcnQoYjEgKiBiMSArIDEpIC0gYjEpOwogICAgUyA9IChyMSAt
IHIwKSAvIHJobzsKICAgIGkgPSBmdW5jdGlvbih0KSB7CiAgICAgIHZhciBzID0gdCAqIFMsCiAg
ICAgICAgICBjb3NocjAgPSBjb3NoKHIwKSwKICAgICAgICAgIHUgPSB3MCAvIChyaG8yICogZDEp
ICogKGNvc2hyMCAqIHRhbmgocmhvICogcyArIHIwKSAtIHNpbmgocjApKTsKICAgICAgcmV0dXJu
IFsKICAgICAgICB1eDAgKyB1ICogZHgsCiAgICAgICAgdXkwICsgdSAqIGR5LAogICAgICAgIHcw
ICogY29zaHIwIC8gY29zaChyaG8gKiBzICsgcjApCiAgICAgIF07CiAgICB9OwogIH0KCiAgaS5k
dXJhdGlvbiA9IFMgKiAxMDAwOwoKICByZXR1cm4gaTsKfQoKZnVuY3Rpb24gaHNsJDEoaHVlKSB7
CiAgcmV0dXJuIGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHsKICAgIHZhciBoID0gaHVlKChzdGFydCA9
IGhzbChzdGFydCkpLmgsIChlbmQgPSBoc2woZW5kKSkuaCksCiAgICAgICAgcyA9IG5vZ2FtbWEo
c3RhcnQucywgZW5kLnMpLAogICAgICAgIGwgPSBub2dhbW1hKHN0YXJ0LmwsIGVuZC5sKSwKICAg
ICAgICBvcGFjaXR5ID0gbm9nYW1tYShzdGFydC5vcGFjaXR5LCBlbmQub3BhY2l0eSk7CiAgICBy
ZXR1cm4gZnVuY3Rpb24odCkgewogICAgICBzdGFydC5oID0gaCh0KTsKICAgICAgc3RhcnQucyA9
IHModCk7CiAgICAgIHN0YXJ0LmwgPSBsKHQpOwogICAgICBzdGFydC5vcGFjaXR5ID0gb3BhY2l0
eSh0KTsKICAgICAgcmV0dXJuIHN0YXJ0ICsgIiI7CiAgICB9OwogIH0KfQoKdmFyIGhzbCQyID0g
aHNsJDEoaHVlKTsKdmFyIGhzbExvbmcgPSBoc2wkMShub2dhbW1hKTsKCmZ1bmN0aW9uIGxhYiQx
KHN0YXJ0LCBlbmQpIHsKICB2YXIgbCA9IG5vZ2FtbWEoKHN0YXJ0ID0gbGFiKHN0YXJ0KSkubCwg
KGVuZCA9IGxhYihlbmQpKS5sKSwKICAgICAgYSA9IG5vZ2FtbWEoc3RhcnQuYSwgZW5kLmEpLAog
ICAgICBiID0gbm9nYW1tYShzdGFydC5iLCBlbmQuYiksCiAgICAgIG9wYWNpdHkgPSBub2dhbW1h
KHN0YXJ0Lm9wYWNpdHksIGVuZC5vcGFjaXR5KTsKICByZXR1cm4gZnVuY3Rpb24odCkgewogICAg
c3RhcnQubCA9IGwodCk7CiAgICBzdGFydC5hID0gYSh0KTsKICAgIHN0YXJ0LmIgPSBiKHQpOwog
ICAgc3RhcnQub3BhY2l0eSA9IG9wYWNpdHkodCk7CiAgICByZXR1cm4gc3RhcnQgKyAiIjsKICB9
Owp9CgpmdW5jdGlvbiBoY2wkMShodWUpIHsKICByZXR1cm4gZnVuY3Rpb24oc3RhcnQsIGVuZCkg
ewogICAgdmFyIGggPSBodWUoKHN0YXJ0ID0gaGNsKHN0YXJ0KSkuaCwgKGVuZCA9IGhjbChlbmQp
KS5oKSwKICAgICAgICBjID0gbm9nYW1tYShzdGFydC5jLCBlbmQuYyksCiAgICAgICAgbCA9IG5v
Z2FtbWEoc3RhcnQubCwgZW5kLmwpLAogICAgICAgIG9wYWNpdHkgPSBub2dhbW1hKHN0YXJ0Lm9w
YWNpdHksIGVuZC5vcGFjaXR5KTsKICAgIHJldHVybiBmdW5jdGlvbih0KSB7CiAgICAgIHN0YXJ0
LmggPSBoKHQpOwogICAgICBzdGFydC5jID0gYyh0KTsKICAgICAgc3RhcnQubCA9IGwodCk7CiAg
ICAgIHN0YXJ0Lm9wYWNpdHkgPSBvcGFjaXR5KHQpOwogICAgICByZXR1cm4gc3RhcnQgKyAiIjsK
ICAgIH07CiAgfQp9Cgp2YXIgaGNsJDIgPSBoY2wkMShodWUpOwp2YXIgaGNsTG9uZyA9IGhjbCQx
KG5vZ2FtbWEpOwoKZnVuY3Rpb24gY3ViZWhlbGl4JDEoaHVlKSB7CiAgcmV0dXJuIChmdW5jdGlv
biBjdWJlaGVsaXhHYW1tYSh5KSB7CiAgICB5ID0gK3k7CgogICAgZnVuY3Rpb24gY3ViZWhlbGl4
JDEoc3RhcnQsIGVuZCkgewogICAgICB2YXIgaCA9IGh1ZSgoc3RhcnQgPSBjdWJlaGVsaXgoc3Rh
cnQpKS5oLCAoZW5kID0gY3ViZWhlbGl4KGVuZCkpLmgpLAogICAgICAgICAgcyA9IG5vZ2FtbWEo
c3RhcnQucywgZW5kLnMpLAogICAgICAgICAgbCA9IG5vZ2FtbWEoc3RhcnQubCwgZW5kLmwpLAog
ICAgICAgICAgb3BhY2l0eSA9IG5vZ2FtbWEoc3RhcnQub3BhY2l0eSwgZW5kLm9wYWNpdHkpOwog
ICAgICByZXR1cm4gZnVuY3Rpb24odCkgewogICAgICAgIHN0YXJ0LmggPSBoKHQpOwogICAgICAg
IHN0YXJ0LnMgPSBzKHQpOwogICAgICAgIHN0YXJ0LmwgPSBsKE1hdGgucG93KHQsIHkpKTsKICAg
ICAgICBzdGFydC5vcGFjaXR5ID0gb3BhY2l0eSh0KTsKICAgICAgICByZXR1cm4gc3RhcnQgKyAi
IjsKICAgICAgfTsKICAgIH0KCiAgICBjdWJlaGVsaXgkMS5nYW1tYSA9IGN1YmVoZWxpeEdhbW1h
OwoKICAgIHJldHVybiBjdWJlaGVsaXgkMTsKICB9KSgxKTsKfQoKdmFyIGN1YmVoZWxpeCQyID0g
Y3ViZWhlbGl4JDEoaHVlKTsKdmFyIGN1YmVoZWxpeExvbmcgPSBjdWJlaGVsaXgkMShub2dhbW1h
KTsKCmZ1bmN0aW9uIHBpZWNld2lzZShpbnRlcnBvbGF0ZSwgdmFsdWVzKSB7CiAgdmFyIGkgPSAw
LCBuID0gdmFsdWVzLmxlbmd0aCAtIDEsIHYgPSB2YWx1ZXNbMF0sIEkgPSBuZXcgQXJyYXkobiA8
IDAgPyAwIDogbik7CiAgd2hpbGUgKGkgPCBuKSBJW2ldID0gaW50ZXJwb2xhdGUodiwgdiA9IHZh
bHVlc1srK2ldKTsKICByZXR1cm4gZnVuY3Rpb24odCkgewogICAgdmFyIGkgPSBNYXRoLm1heCgw
LCBNYXRoLm1pbihuIC0gMSwgTWF0aC5mbG9vcih0ICo9IG4pKSk7CiAgICByZXR1cm4gSVtpXSh0
IC0gaSk7CiAgfTsKfQoKZnVuY3Rpb24gcXVhbnRpemUoaW50ZXJwb2xhdG9yLCBuKSB7CiAgdmFy
IHNhbXBsZXMgPSBuZXcgQXJyYXkobik7CiAgZm9yICh2YXIgaSA9IDA7IGkgPCBuOyArK2kpIHNh
bXBsZXNbaV0gPSBpbnRlcnBvbGF0b3IoaSAvIChuIC0gMSkpOwogIHJldHVybiBzYW1wbGVzOwp9
Cgp2YXIgZnJhbWUgPSAwLCAvLyBpcyBhbiBhbmltYXRpb24gZnJhbWUgcGVuZGluZz8KICAgIHRp
bWVvdXQgPSAwLCAvLyBpcyBhIHRpbWVvdXQgcGVuZGluZz8KICAgIGludGVydmFsID0gMCwgLy8g
YXJlIGFueSB0aW1lcnMgYWN0aXZlPwogICAgcG9rZURlbGF5ID0gMTAwMCwgLy8gaG93IGZyZXF1
ZW50bHkgd2UgY2hlY2sgZm9yIGNsb2NrIHNrZXcKICAgIHRhc2tIZWFkLAogICAgdGFza1RhaWws
CiAgICBjbG9ja0xhc3QgPSAwLAogICAgY2xvY2tOb3cgPSAwLAogICAgY2xvY2tTa2V3ID0gMCwK
ICAgIGNsb2NrID0gdHlwZW9mIHBlcmZvcm1hbmNlID09PSAib2JqZWN0IiAmJiBwZXJmb3JtYW5j
ZS5ub3cgPyBwZXJmb3JtYW5jZSA6IERhdGUsCiAgICBzZXRGcmFtZSA9IHR5cGVvZiB3aW5kb3cg
PT09ICJvYmplY3QiICYmIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUgPyB3aW5kb3cucmVx
dWVzdEFuaW1hdGlvbkZyYW1lLmJpbmQod2luZG93KSA6IGZ1bmN0aW9uKGYpIHsgc2V0VGltZW91
dChmLCAxNyk7IH07CgpmdW5jdGlvbiBub3coKSB7CiAgcmV0dXJuIGNsb2NrTm93IHx8IChzZXRG
cmFtZShjbGVhck5vdyksIGNsb2NrTm93ID0gY2xvY2subm93KCkgKyBjbG9ja1NrZXcpOwp9Cgpm
dW5jdGlvbiBjbGVhck5vdygpIHsKICBjbG9ja05vdyA9IDA7Cn0KCmZ1bmN0aW9uIFRpbWVyKCkg
ewogIHRoaXMuX2NhbGwgPQogIHRoaXMuX3RpbWUgPQogIHRoaXMuX25leHQgPSBudWxsOwp9CgpU
aW1lci5wcm90b3R5cGUgPSB0aW1lci5wcm90b3R5cGUgPSB7CiAgY29uc3RydWN0b3I6IFRpbWVy
LAogIHJlc3RhcnQ6IGZ1bmN0aW9uKGNhbGxiYWNrLCBkZWxheSwgdGltZSkgewogICAgaWYgKHR5
cGVvZiBjYWxsYmFjayAhPT0gImZ1bmN0aW9uIikgdGhyb3cgbmV3IFR5cGVFcnJvcigiY2FsbGJh
Y2sgaXMgbm90IGEgZnVuY3Rpb24iKTsKICAgIHRpbWUgPSAodGltZSA9PSBudWxsID8gbm93KCkg
OiArdGltZSkgKyAoZGVsYXkgPT0gbnVsbCA/IDAgOiArZGVsYXkpOwogICAgaWYgKCF0aGlzLl9u
ZXh0ICYmIHRhc2tUYWlsICE9PSB0aGlzKSB7CiAgICAgIGlmICh0YXNrVGFpbCkgdGFza1RhaWwu
X25leHQgPSB0aGlzOwogICAgICBlbHNlIHRhc2tIZWFkID0gdGhpczsKICAgICAgdGFza1RhaWwg
PSB0aGlzOwogICAgfQogICAgdGhpcy5fY2FsbCA9IGNhbGxiYWNrOwogICAgdGhpcy5fdGltZSA9
IHRpbWU7CiAgICBzbGVlcCgpOwogIH0sCiAgc3RvcDogZnVuY3Rpb24oKSB7CiAgICBpZiAodGhp
cy5fY2FsbCkgewogICAgICB0aGlzLl9jYWxsID0gbnVsbDsKICAgICAgdGhpcy5fdGltZSA9IElu
ZmluaXR5OwogICAgICBzbGVlcCgpOwogICAgfQogIH0KfTsKCmZ1bmN0aW9uIHRpbWVyKGNhbGxi
YWNrLCBkZWxheSwgdGltZSkgewogIHZhciB0ID0gbmV3IFRpbWVyOwogIHQucmVzdGFydChjYWxs
YmFjaywgZGVsYXksIHRpbWUpOwogIHJldHVybiB0Owp9CgpmdW5jdGlvbiB0aW1lckZsdXNoKCkg
ewogIG5vdygpOyAvLyBHZXQgdGhlIGN1cnJlbnQgdGltZSwgaWYgbm90IGFscmVhZHkgc2V0Lgog
ICsrZnJhbWU7IC8vIFByZXRlbmQgd2XigJl2ZSBzZXQgYW4gYWxhcm0sIGlmIHdlIGhhdmVu4oCZ
dCBhbHJlYWR5LgogIHZhciB0ID0gdGFza0hlYWQsIGU7CiAgd2hpbGUgKHQpIHsKICAgIGlmICgo
ZSA9IGNsb2NrTm93IC0gdC5fdGltZSkgPj0gMCkgdC5fY2FsbC5jYWxsKG51bGwsIGUpOwogICAg
dCA9IHQuX25leHQ7CiAgfQogIC0tZnJhbWU7Cn0KCmZ1bmN0aW9uIHdha2UoKSB7CiAgY2xvY2tO
b3cgPSAoY2xvY2tMYXN0ID0gY2xvY2subm93KCkpICsgY2xvY2tTa2V3OwogIGZyYW1lID0gdGlt
ZW91dCA9IDA7CiAgdHJ5IHsKICAgIHRpbWVyRmx1c2goKTsKICB9IGZpbmFsbHkgewogICAgZnJh
bWUgPSAwOwogICAgbmFwKCk7CiAgICBjbG9ja05vdyA9IDA7CiAgfQp9CgpmdW5jdGlvbiBwb2tl
KCkgewogIHZhciBub3cgPSBjbG9jay5ub3coKSwgZGVsYXkgPSBub3cgLSBjbG9ja0xhc3Q7CiAg
aWYgKGRlbGF5ID4gcG9rZURlbGF5KSBjbG9ja1NrZXcgLT0gZGVsYXksIGNsb2NrTGFzdCA9IG5v
dzsKfQoKZnVuY3Rpb24gbmFwKCkgewogIHZhciB0MCwgdDEgPSB0YXNrSGVhZCwgdDIsIHRpbWUg
PSBJbmZpbml0eTsKICB3aGlsZSAodDEpIHsKICAgIGlmICh0MS5fY2FsbCkgewogICAgICBpZiAo
dGltZSA+IHQxLl90aW1lKSB0aW1lID0gdDEuX3RpbWU7CiAgICAgIHQwID0gdDEsIHQxID0gdDEu
X25leHQ7CiAgICB9IGVsc2UgewogICAgICB0MiA9IHQxLl9uZXh0LCB0MS5fbmV4dCA9IG51bGw7
CiAgICAgIHQxID0gdDAgPyB0MC5fbmV4dCA9IHQyIDogdGFza0hlYWQgPSB0MjsKICAgIH0KICB9
CiAgdGFza1RhaWwgPSB0MDsKICBzbGVlcCh0aW1lKTsKfQoKZnVuY3Rpb24gc2xlZXAodGltZSkg
ewogIGlmIChmcmFtZSkgcmV0dXJuOyAvLyBTb29uZXN0IGFsYXJtIGFscmVhZHkgc2V0LCBvciB3
aWxsIGJlLgogIGlmICh0aW1lb3V0KSB0aW1lb3V0ID0gY2xlYXJUaW1lb3V0KHRpbWVvdXQpOwog
IHZhciBkZWxheSA9IHRpbWUgLSBjbG9ja05vdzsgLy8gU3RyaWN0bHkgbGVzcyB0aGFuIGlmIHdl
IHJlY29tcHV0ZWQgY2xvY2tOb3cuCiAgaWYgKGRlbGF5ID4gMjQpIHsKICAgIGlmICh0aW1lIDwg
SW5maW5pdHkpIHRpbWVvdXQgPSBzZXRUaW1lb3V0KHdha2UsIHRpbWUgLSBjbG9jay5ub3coKSAt
IGNsb2NrU2tldyk7CiAgICBpZiAoaW50ZXJ2YWwpIGludGVydmFsID0gY2xlYXJJbnRlcnZhbChp
bnRlcnZhbCk7CiAgfSBlbHNlIHsKICAgIGlmICghaW50ZXJ2YWwpIGNsb2NrTGFzdCA9IGNsb2Nr
Lm5vdygpLCBpbnRlcnZhbCA9IHNldEludGVydmFsKHBva2UsIHBva2VEZWxheSk7CiAgICBmcmFt
ZSA9IDEsIHNldEZyYW1lKHdha2UpOwogIH0KfQoKZnVuY3Rpb24gdGltZW91dCQxKGNhbGxiYWNr
LCBkZWxheSwgdGltZSkgewogIHZhciB0ID0gbmV3IFRpbWVyOwogIGRlbGF5ID0gZGVsYXkgPT0g
bnVsbCA/IDAgOiArZGVsYXk7CiAgdC5yZXN0YXJ0KGZ1bmN0aW9uKGVsYXBzZWQpIHsKICAgIHQu
c3RvcCgpOwogICAgY2FsbGJhY2soZWxhcHNlZCArIGRlbGF5KTsKICB9LCBkZWxheSwgdGltZSk7
CiAgcmV0dXJuIHQ7Cn0KCmZ1bmN0aW9uIGludGVydmFsJDEoY2FsbGJhY2ssIGRlbGF5LCB0aW1l
KSB7CiAgdmFyIHQgPSBuZXcgVGltZXIsIHRvdGFsID0gZGVsYXk7CiAgaWYgKGRlbGF5ID09IG51
bGwpIHJldHVybiB0LnJlc3RhcnQoY2FsbGJhY2ssIGRlbGF5LCB0aW1lKSwgdDsKICBkZWxheSA9
ICtkZWxheSwgdGltZSA9IHRpbWUgPT0gbnVsbCA/IG5vdygpIDogK3RpbWU7CiAgdC5yZXN0YXJ0
KGZ1bmN0aW9uIHRpY2soZWxhcHNlZCkgewogICAgZWxhcHNlZCArPSB0b3RhbDsKICAgIHQucmVz
dGFydCh0aWNrLCB0b3RhbCArPSBkZWxheSwgdGltZSk7CiAgICBjYWxsYmFjayhlbGFwc2VkKTsK
ICB9LCBkZWxheSwgdGltZSk7CiAgcmV0dXJuIHQ7Cn0KCnZhciBlbXB0eU9uID0gZGlzcGF0Y2go
InN0YXJ0IiwgImVuZCIsICJjYW5jZWwiLCAiaW50ZXJydXB0Iik7CnZhciBlbXB0eVR3ZWVuID0g
W107Cgp2YXIgQ1JFQVRFRCA9IDA7CnZhciBTQ0hFRFVMRUQgPSAxOwp2YXIgU1RBUlRJTkcgPSAy
Owp2YXIgU1RBUlRFRCA9IDM7CnZhciBSVU5OSU5HID0gNDsKdmFyIEVORElORyA9IDU7CnZhciBF
TkRFRCA9IDY7CgpmdW5jdGlvbiBzY2hlZHVsZShub2RlLCBuYW1lLCBpZCwgaW5kZXgsIGdyb3Vw
LCB0aW1pbmcpIHsKICB2YXIgc2NoZWR1bGVzID0gbm9kZS5fX3RyYW5zaXRpb247CiAgaWYgKCFz
Y2hlZHVsZXMpIG5vZGUuX190cmFuc2l0aW9uID0ge307CiAgZWxzZSBpZiAoaWQgaW4gc2NoZWR1
bGVzKSByZXR1cm47CiAgY3JlYXRlJDEobm9kZSwgaWQsIHsKICAgIG5hbWU6IG5hbWUsCiAgICBp
bmRleDogaW5kZXgsIC8vIEZvciBjb250ZXh0IGR1cmluZyBjYWxsYmFjay4KICAgIGdyb3VwOiBn
cm91cCwgLy8gRm9yIGNvbnRleHQgZHVyaW5nIGNhbGxiYWNrLgogICAgb246IGVtcHR5T24sCiAg
ICB0d2VlbjogZW1wdHlUd2VlbiwKICAgIHRpbWU6IHRpbWluZy50aW1lLAogICAgZGVsYXk6IHRp
bWluZy5kZWxheSwKICAgIGR1cmF0aW9uOiB0aW1pbmcuZHVyYXRpb24sCiAgICBlYXNlOiB0aW1p
bmcuZWFzZSwKICAgIHRpbWVyOiBudWxsLAogICAgc3RhdGU6IENSRUFURUQKICB9KTsKfQoKZnVu
Y3Rpb24gaW5pdChub2RlLCBpZCkgewogIHZhciBzY2hlZHVsZSA9IGdldCQxKG5vZGUsIGlkKTsK
ICBpZiAoc2NoZWR1bGUuc3RhdGUgPiBDUkVBVEVEKSB0aHJvdyBuZXcgRXJyb3IoInRvbyBsYXRl
OyBhbHJlYWR5IHNjaGVkdWxlZCIpOwogIHJldHVybiBzY2hlZHVsZTsKfQoKZnVuY3Rpb24gc2V0
JDEobm9kZSwgaWQpIHsKICB2YXIgc2NoZWR1bGUgPSBnZXQkMShub2RlLCBpZCk7CiAgaWYgKHNj
aGVkdWxlLnN0YXRlID4gU1RBUlRFRCkgdGhyb3cgbmV3IEVycm9yKCJ0b28gbGF0ZTsgYWxyZWFk
eSBydW5uaW5nIik7CiAgcmV0dXJuIHNjaGVkdWxlOwp9CgpmdW5jdGlvbiBnZXQkMShub2RlLCBp
ZCkgewogIHZhciBzY2hlZHVsZSA9IG5vZGUuX190cmFuc2l0aW9uOwogIGlmICghc2NoZWR1bGUg
fHwgIShzY2hlZHVsZSA9IHNjaGVkdWxlW2lkXSkpIHRocm93IG5ldyBFcnJvcigidHJhbnNpdGlv
biBub3QgZm91bmQiKTsKICByZXR1cm4gc2NoZWR1bGU7Cn0KCmZ1bmN0aW9uIGNyZWF0ZSQxKG5v
ZGUsIGlkLCBzZWxmKSB7CiAgdmFyIHNjaGVkdWxlcyA9IG5vZGUuX190cmFuc2l0aW9uLAogICAg
ICB0d2VlbjsKCiAgLy8gSW5pdGlhbGl6ZSB0aGUgc2VsZiB0aW1lciB3aGVuIHRoZSB0cmFuc2l0
aW9uIGlzIGNyZWF0ZWQuCiAgLy8gTm90ZSB0aGUgYWN0dWFsIGRlbGF5IGlzIG5vdCBrbm93biB1
bnRpbCB0aGUgZmlyc3QgY2FsbGJhY2shCiAgc2NoZWR1bGVzW2lkXSA9IHNlbGY7CiAgc2VsZi50
aW1lciA9IHRpbWVyKHNjaGVkdWxlLCAwLCBzZWxmLnRpbWUpOwoKICBmdW5jdGlvbiBzY2hlZHVs
ZShlbGFwc2VkKSB7CiAgICBzZWxmLnN0YXRlID0gU0NIRURVTEVEOwogICAgc2VsZi50aW1lci5y
ZXN0YXJ0KHN0YXJ0LCBzZWxmLmRlbGF5LCBzZWxmLnRpbWUpOwoKICAgIC8vIElmIHRoZSBlbGFw
c2VkIGRlbGF5IGlzIGxlc3MgdGhhbiBvdXIgZmlyc3Qgc2xlZXAsIHN0YXJ0IGltbWVkaWF0ZWx5
LgogICAgaWYgKHNlbGYuZGVsYXkgPD0gZWxhcHNlZCkgc3RhcnQoZWxhcHNlZCAtIHNlbGYuZGVs
YXkpOwogIH0KCiAgZnVuY3Rpb24gc3RhcnQoZWxhcHNlZCkgewogICAgdmFyIGksIGosIG4sIG87
CgogICAgLy8gSWYgdGhlIHN0YXRlIGlzIG5vdCBTQ0hFRFVMRUQsIHRoZW4gd2UgcHJldmlvdXNs
eSBlcnJvcmVkIG9uIHN0YXJ0LgogICAgaWYgKHNlbGYuc3RhdGUgIT09IFNDSEVEVUxFRCkgcmV0
dXJuIHN0b3AoKTsKCiAgICBmb3IgKGkgaW4gc2NoZWR1bGVzKSB7CiAgICAgIG8gPSBzY2hlZHVs
ZXNbaV07CiAgICAgIGlmIChvLm5hbWUgIT09IHNlbGYubmFtZSkgY29udGludWU7CgogICAgICAv
LyBXaGlsZSB0aGlzIGVsZW1lbnQgYWxyZWFkeSBoYXMgYSBzdGFydGluZyB0cmFuc2l0aW9uIGR1
cmluZyB0aGlzIGZyYW1lLAogICAgICAvLyBkZWZlciBzdGFydGluZyBhbiBpbnRlcnJ1cHRpbmcg
dHJhbnNpdGlvbiB1bnRpbCB0aGF0IHRyYW5zaXRpb24gaGFzIGEKICAgICAgLy8gY2hhbmNlIHRv
IHRpY2sgKGFuZCBwb3NzaWJseSBlbmQpOyBzZWUgZDMvZDMtdHJhbnNpdGlvbiM1NCEKICAgICAg
aWYgKG8uc3RhdGUgPT09IFNUQVJURUQpIHJldHVybiB0aW1lb3V0JDEoc3RhcnQpOwoKICAgICAg
Ly8gSW50ZXJydXB0IHRoZSBhY3RpdmUgdHJhbnNpdGlvbiwgaWYgYW55LgogICAgICBpZiAoby5z
dGF0ZSA9PT0gUlVOTklORykgewogICAgICAgIG8uc3RhdGUgPSBFTkRFRDsKICAgICAgICBvLnRp
bWVyLnN0b3AoKTsKICAgICAgICBvLm9uLmNhbGwoImludGVycnVwdCIsIG5vZGUsIG5vZGUuX19k
YXRhX18sIG8uaW5kZXgsIG8uZ3JvdXApOwogICAgICAgIGRlbGV0ZSBzY2hlZHVsZXNbaV07CiAg
ICAgIH0KCiAgICAgIC8vIENhbmNlbCBhbnkgcHJlLWVtcHRlZCB0cmFuc2l0aW9ucy4KICAgICAg
ZWxzZSBpZiAoK2kgPCBpZCkgewogICAgICAgIG8uc3RhdGUgPSBFTkRFRDsKICAgICAgICBvLnRp
bWVyLnN0b3AoKTsKICAgICAgICBvLm9uLmNhbGwoImNhbmNlbCIsIG5vZGUsIG5vZGUuX19kYXRh
X18sIG8uaW5kZXgsIG8uZ3JvdXApOwogICAgICAgIGRlbGV0ZSBzY2hlZHVsZXNbaV07CiAgICAg
IH0KICAgIH0KCiAgICAvLyBEZWZlciB0aGUgZmlyc3QgdGljayB0byBlbmQgb2YgdGhlIGN1cnJl
bnQgZnJhbWU7IHNlZSBkMy9kMyMxNTc2LgogICAgLy8gTm90ZSB0aGUgdHJhbnNpdGlvbiBtYXkg
YmUgY2FuY2VsZWQgYWZ0ZXIgc3RhcnQgYW5kIGJlZm9yZSB0aGUgZmlyc3QgdGljayEKICAgIC8v
IE5vdGUgdGhpcyBtdXN0IGJlIHNjaGVkdWxlZCBiZWZvcmUgdGhlIHN0YXJ0IGV2ZW50OyBzZWUg
ZDMvZDMtdHJhbnNpdGlvbiMxNiEKICAgIC8vIEFzc3VtaW5nIHRoaXMgaXMgc3VjY2Vzc2Z1bCwg
c3Vic2VxdWVudCBjYWxsYmFja3MgZ28gc3RyYWlnaHQgdG8gdGljay4KICAgIHRpbWVvdXQkMShm
dW5jdGlvbigpIHsKICAgICAgaWYgKHNlbGYuc3RhdGUgPT09IFNUQVJURUQpIHsKICAgICAgICBz
ZWxmLnN0YXRlID0gUlVOTklORzsKICAgICAgICBzZWxmLnRpbWVyLnJlc3RhcnQodGljaywgc2Vs
Zi5kZWxheSwgc2VsZi50aW1lKTsKICAgICAgICB0aWNrKGVsYXBzZWQpOwogICAgICB9CiAgICB9
KTsKCiAgICAvLyBEaXNwYXRjaCB0aGUgc3RhcnQgZXZlbnQuCiAgICAvLyBOb3RlIHRoaXMgbXVz
dCBiZSBkb25lIGJlZm9yZSB0aGUgdHdlZW4gYXJlIGluaXRpYWxpemVkLgogICAgc2VsZi5zdGF0
ZSA9IFNUQVJUSU5HOwogICAgc2VsZi5vbi5jYWxsKCJzdGFydCIsIG5vZGUsIG5vZGUuX19kYXRh
X18sIHNlbGYuaW5kZXgsIHNlbGYuZ3JvdXApOwogICAgaWYgKHNlbGYuc3RhdGUgIT09IFNUQVJU
SU5HKSByZXR1cm47IC8vIGludGVycnVwdGVkCiAgICBzZWxmLnN0YXRlID0gU1RBUlRFRDsKCiAg
ICAvLyBJbml0aWFsaXplIHRoZSB0d2VlbiwgZGVsZXRpbmcgbnVsbCB0d2Vlbi4KICAgIHR3ZWVu
ID0gbmV3IEFycmF5KG4gPSBzZWxmLnR3ZWVuLmxlbmd0aCk7CiAgICBmb3IgKGkgPSAwLCBqID0g
LTE7IGkgPCBuOyArK2kpIHsKICAgICAgaWYgKG8gPSBzZWxmLnR3ZWVuW2ldLnZhbHVlLmNhbGwo
bm9kZSwgbm9kZS5fX2RhdGFfXywgc2VsZi5pbmRleCwgc2VsZi5ncm91cCkpIHsKICAgICAgICB0
d2VlblsrK2pdID0gbzsKICAgICAgfQogICAgfQogICAgdHdlZW4ubGVuZ3RoID0gaiArIDE7CiAg
fQoKICBmdW5jdGlvbiB0aWNrKGVsYXBzZWQpIHsKICAgIHZhciB0ID0gZWxhcHNlZCA8IHNlbGYu
ZHVyYXRpb24gPyBzZWxmLmVhc2UuY2FsbChudWxsLCBlbGFwc2VkIC8gc2VsZi5kdXJhdGlvbikg
OiAoc2VsZi50aW1lci5yZXN0YXJ0KHN0b3ApLCBzZWxmLnN0YXRlID0gRU5ESU5HLCAxKSwKICAg
ICAgICBpID0gLTEsCiAgICAgICAgbiA9IHR3ZWVuLmxlbmd0aDsKCiAgICB3aGlsZSAoKytpIDwg
bikgewogICAgICB0d2VlbltpXS5jYWxsKG5vZGUsIHQpOwogICAgfQoKICAgIC8vIERpc3BhdGNo
IHRoZSBlbmQgZXZlbnQuCiAgICBpZiAoc2VsZi5zdGF0ZSA9PT0gRU5ESU5HKSB7CiAgICAgIHNl
bGYub24uY2FsbCgiZW5kIiwgbm9kZSwgbm9kZS5fX2RhdGFfXywgc2VsZi5pbmRleCwgc2VsZi5n
cm91cCk7CiAgICAgIHN0b3AoKTsKICAgIH0KICB9CgogIGZ1bmN0aW9uIHN0b3AoKSB7CiAgICBz
ZWxmLnN0YXRlID0gRU5ERUQ7CiAgICBzZWxmLnRpbWVyLnN0b3AoKTsKICAgIGRlbGV0ZSBzY2hl
ZHVsZXNbaWRdOwogICAgZm9yICh2YXIgaSBpbiBzY2hlZHVsZXMpIHJldHVybjsgLy8gZXNsaW50
LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFycwogICAgZGVsZXRlIG5vZGUuX190cmFuc2l0aW9u
OwogIH0KfQoKZnVuY3Rpb24gaW50ZXJydXB0KG5vZGUsIG5hbWUpIHsKICB2YXIgc2NoZWR1bGVz
ID0gbm9kZS5fX3RyYW5zaXRpb24sCiAgICAgIHNjaGVkdWxlLAogICAgICBhY3RpdmUsCiAgICAg
IGVtcHR5ID0gdHJ1ZSwKICAgICAgaTsKCiAgaWYgKCFzY2hlZHVsZXMpIHJldHVybjsKCiAgbmFt
ZSA9IG5hbWUgPT0gbnVsbCA/IG51bGwgOiBuYW1lICsgIiI7CgogIGZvciAoaSBpbiBzY2hlZHVs
ZXMpIHsKICAgIGlmICgoc2NoZWR1bGUgPSBzY2hlZHVsZXNbaV0pLm5hbWUgIT09IG5hbWUpIHsg
ZW1wdHkgPSBmYWxzZTsgY29udGludWU7IH0KICAgIGFjdGl2ZSA9IHNjaGVkdWxlLnN0YXRlID4g
U1RBUlRJTkcgJiYgc2NoZWR1bGUuc3RhdGUgPCBFTkRJTkc7CiAgICBzY2hlZHVsZS5zdGF0ZSA9
IEVOREVEOwogICAgc2NoZWR1bGUudGltZXIuc3RvcCgpOwogICAgc2NoZWR1bGUub24uY2FsbChh
Y3RpdmUgPyAiaW50ZXJydXB0IiA6ICJjYW5jZWwiLCBub2RlLCBub2RlLl9fZGF0YV9fLCBzY2hl
ZHVsZS5pbmRleCwgc2NoZWR1bGUuZ3JvdXApOwogICAgZGVsZXRlIHNjaGVkdWxlc1tpXTsKICB9
CgogIGlmIChlbXB0eSkgZGVsZXRlIG5vZGUuX190cmFuc2l0aW9uOwp9CgpmdW5jdGlvbiBzZWxl
Y3Rpb25faW50ZXJydXB0KG5hbWUpIHsKICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCkgewog
ICAgaW50ZXJydXB0KHRoaXMsIG5hbWUpOwogIH0pOwp9CgpmdW5jdGlvbiB0d2VlblJlbW92ZShp
ZCwgbmFtZSkgewogIHZhciB0d2VlbjAsIHR3ZWVuMTsKICByZXR1cm4gZnVuY3Rpb24oKSB7CiAg
ICB2YXIgc2NoZWR1bGUgPSBzZXQkMSh0aGlzLCBpZCksCiAgICAgICAgdHdlZW4gPSBzY2hlZHVs
ZS50d2VlbjsKCiAgICAvLyBJZiB0aGlzIG5vZGUgc2hhcmVkIHR3ZWVuIHdpdGggdGhlIHByZXZp
b3VzIG5vZGUsCiAgICAvLyBqdXN0IGFzc2lnbiB0aGUgdXBkYXRlZCBzaGFyZWQgdHdlZW4gYW5k
IHdl4oCZcmUgZG9uZSEKICAgIC8vIE90aGVyd2lzZSwgY29weS1vbi13cml0ZS4KICAgIGlmICh0
d2VlbiAhPT0gdHdlZW4wKSB7CiAgICAgIHR3ZWVuMSA9IHR3ZWVuMCA9IHR3ZWVuOwogICAgICBm
b3IgKHZhciBpID0gMCwgbiA9IHR3ZWVuMS5sZW5ndGg7IGkgPCBuOyArK2kpIHsKICAgICAgICBp
ZiAodHdlZW4xW2ldLm5hbWUgPT09IG5hbWUpIHsKICAgICAgICAgIHR3ZWVuMSA9IHR3ZWVuMS5z
bGljZSgpOwogICAgICAgICAgdHdlZW4xLnNwbGljZShpLCAxKTsKICAgICAgICAgIGJyZWFrOwog
ICAgICAgIH0KICAgICAgfQogICAgfQoKICAgIHNjaGVkdWxlLnR3ZWVuID0gdHdlZW4xOwogIH07
Cn0KCmZ1bmN0aW9uIHR3ZWVuRnVuY3Rpb24oaWQsIG5hbWUsIHZhbHVlKSB7CiAgdmFyIHR3ZWVu
MCwgdHdlZW4xOwogIGlmICh0eXBlb2YgdmFsdWUgIT09ICJmdW5jdGlvbiIpIHRocm93IG5ldyBF
cnJvcjsKICByZXR1cm4gZnVuY3Rpb24oKSB7CiAgICB2YXIgc2NoZWR1bGUgPSBzZXQkMSh0aGlz
LCBpZCksCiAgICAgICAgdHdlZW4gPSBzY2hlZHVsZS50d2VlbjsKCiAgICAvLyBJZiB0aGlzIG5v
ZGUgc2hhcmVkIHR3ZWVuIHdpdGggdGhlIHByZXZpb3VzIG5vZGUsCiAgICAvLyBqdXN0IGFzc2ln
biB0aGUgdXBkYXRlZCBzaGFyZWQgdHdlZW4gYW5kIHdl4oCZcmUgZG9uZSEKICAgIC8vIE90aGVy
d2lzZSwgY29weS1vbi13cml0ZS4KICAgIGlmICh0d2VlbiAhPT0gdHdlZW4wKSB7CiAgICAgIHR3
ZWVuMSA9ICh0d2VlbjAgPSB0d2Vlbikuc2xpY2UoKTsKICAgICAgZm9yICh2YXIgdCA9IHtuYW1l
OiBuYW1lLCB2YWx1ZTogdmFsdWV9LCBpID0gMCwgbiA9IHR3ZWVuMS5sZW5ndGg7IGkgPCBuOyAr
K2kpIHsKICAgICAgICBpZiAodHdlZW4xW2ldLm5hbWUgPT09IG5hbWUpIHsKICAgICAgICAgIHR3
ZWVuMVtpXSA9IHQ7CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYg
KGkgPT09IG4pIHR3ZWVuMS5wdXNoKHQpOwogICAgfQoKICAgIHNjaGVkdWxlLnR3ZWVuID0gdHdl
ZW4xOwogIH07Cn0KCmZ1bmN0aW9uIHRyYW5zaXRpb25fdHdlZW4obmFtZSwgdmFsdWUpIHsKICB2
YXIgaWQgPSB0aGlzLl9pZDsKCiAgbmFtZSArPSAiIjsKCiAgaWYgKGFyZ3VtZW50cy5sZW5ndGgg
PCAyKSB7CiAgICB2YXIgdHdlZW4gPSBnZXQkMSh0aGlzLm5vZGUoKSwgaWQpLnR3ZWVuOwogICAg
Zm9yICh2YXIgaSA9IDAsIG4gPSB0d2Vlbi5sZW5ndGgsIHQ7IGkgPCBuOyArK2kpIHsKICAgICAg
aWYgKCh0ID0gdHdlZW5baV0pLm5hbWUgPT09IG5hbWUpIHsKICAgICAgICByZXR1cm4gdC52YWx1
ZTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIG51bGw7CiAgfQoKICByZXR1cm4gdGhpcy5lYWNo
KCh2YWx1ZSA9PSBudWxsID8gdHdlZW5SZW1vdmUgOiB0d2VlbkZ1bmN0aW9uKShpZCwgbmFtZSwg
dmFsdWUpKTsKfQoKZnVuY3Rpb24gdHdlZW5WYWx1ZSh0cmFuc2l0aW9uLCBuYW1lLCB2YWx1ZSkg
ewogIHZhciBpZCA9IHRyYW5zaXRpb24uX2lkOwoKICB0cmFuc2l0aW9uLmVhY2goZnVuY3Rpb24o
KSB7CiAgICB2YXIgc2NoZWR1bGUgPSBzZXQkMSh0aGlzLCBpZCk7CiAgICAoc2NoZWR1bGUudmFs
dWUgfHwgKHNjaGVkdWxlLnZhbHVlID0ge30pKVtuYW1lXSA9IHZhbHVlLmFwcGx5KHRoaXMsIGFy
Z3VtZW50cyk7CiAgfSk7CgogIHJldHVybiBmdW5jdGlvbihub2RlKSB7CiAgICByZXR1cm4gZ2V0
JDEobm9kZSwgaWQpLnZhbHVlW25hbWVdOwogIH07Cn0KCmZ1bmN0aW9uIGludGVycG9sYXRlKGEs
IGIpIHsKICB2YXIgYzsKICByZXR1cm4gKHR5cGVvZiBiID09PSAibnVtYmVyIiA/IGludGVycG9s
YXRlTnVtYmVyCiAgICAgIDogYiBpbnN0YW5jZW9mIGNvbG9yID8gaW50ZXJwb2xhdGVSZ2IKICAg
ICAgOiAoYyA9IGNvbG9yKGIpKSA/IChiID0gYywgaW50ZXJwb2xhdGVSZ2IpCiAgICAgIDogaW50
ZXJwb2xhdGVTdHJpbmcpKGEsIGIpOwp9CgpmdW5jdGlvbiBhdHRyUmVtb3ZlJDEobmFtZSkgewog
IHJldHVybiBmdW5jdGlvbigpIHsKICAgIHRoaXMucmVtb3ZlQXR0cmlidXRlKG5hbWUpOwogIH07
Cn0KCmZ1bmN0aW9uIGF0dHJSZW1vdmVOUyQxKGZ1bGxuYW1lKSB7CiAgcmV0dXJuIGZ1bmN0aW9u
KCkgewogICAgdGhpcy5yZW1vdmVBdHRyaWJ1dGVOUyhmdWxsbmFtZS5zcGFjZSwgZnVsbG5hbWUu
bG9jYWwpOwogIH07Cn0KCmZ1bmN0aW9uIGF0dHJDb25zdGFudCQxKG5hbWUsIGludGVycG9sYXRl
LCB2YWx1ZTEpIHsKICB2YXIgc3RyaW5nMDAsCiAgICAgIHN0cmluZzEgPSB2YWx1ZTEgKyAiIiwK
ICAgICAgaW50ZXJwb2xhdGUwOwogIHJldHVybiBmdW5jdGlvbigpIHsKICAgIHZhciBzdHJpbmcw
ID0gdGhpcy5nZXRBdHRyaWJ1dGUobmFtZSk7CiAgICByZXR1cm4gc3RyaW5nMCA9PT0gc3RyaW5n
MSA/IG51bGwKICAgICAgICA6IHN0cmluZzAgPT09IHN0cmluZzAwID8gaW50ZXJwb2xhdGUwCiAg
ICAgICAgOiBpbnRlcnBvbGF0ZTAgPSBpbnRlcnBvbGF0ZShzdHJpbmcwMCA9IHN0cmluZzAsIHZh
bHVlMSk7CiAgfTsKfQoKZnVuY3Rpb24gYXR0ckNvbnN0YW50TlMkMShmdWxsbmFtZSwgaW50ZXJw
b2xhdGUsIHZhbHVlMSkgewogIHZhciBzdHJpbmcwMCwKICAgICAgc3RyaW5nMSA9IHZhbHVlMSAr
ICIiLAogICAgICBpbnRlcnBvbGF0ZTA7CiAgcmV0dXJuIGZ1bmN0aW9uKCkgewogICAgdmFyIHN0
cmluZzAgPSB0aGlzLmdldEF0dHJpYnV0ZU5TKGZ1bGxuYW1lLnNwYWNlLCBmdWxsbmFtZS5sb2Nh
bCk7CiAgICByZXR1cm4gc3RyaW5nMCA9PT0gc3RyaW5nMSA/IG51bGwKICAgICAgICA6IHN0cmlu
ZzAgPT09IHN0cmluZzAwID8gaW50ZXJwb2xhdGUwCiAgICAgICAgOiBpbnRlcnBvbGF0ZTAgPSBp
bnRlcnBvbGF0ZShzdHJpbmcwMCA9IHN0cmluZzAsIHZhbHVlMSk7CiAgfTsKfQoKZnVuY3Rpb24g
YXR0ckZ1bmN0aW9uJDEobmFtZSwgaW50ZXJwb2xhdGUsIHZhbHVlKSB7CiAgdmFyIHN0cmluZzAw
LAogICAgICBzdHJpbmcxMCwKICAgICAgaW50ZXJwb2xhdGUwOwogIHJldHVybiBmdW5jdGlvbigp
IHsKICAgIHZhciBzdHJpbmcwLCB2YWx1ZTEgPSB2YWx1ZSh0aGlzKSwgc3RyaW5nMTsKICAgIGlm
ICh2YWx1ZTEgPT0gbnVsbCkgcmV0dXJuIHZvaWQgdGhpcy5yZW1vdmVBdHRyaWJ1dGUobmFtZSk7
CiAgICBzdHJpbmcwID0gdGhpcy5nZXRBdHRyaWJ1dGUobmFtZSk7CiAgICBzdHJpbmcxID0gdmFs
dWUxICsgIiI7CiAgICByZXR1cm4gc3RyaW5nMCA9PT0gc3RyaW5nMSA/IG51bGwKICAgICAgICA6
IHN0cmluZzAgPT09IHN0cmluZzAwICYmIHN0cmluZzEgPT09IHN0cmluZzEwID8gaW50ZXJwb2xh
dGUwCiAgICAgICAgOiAoc3RyaW5nMTAgPSBzdHJpbmcxLCBpbnRlcnBvbGF0ZTAgPSBpbnRlcnBv
bGF0ZShzdHJpbmcwMCA9IHN0cmluZzAsIHZhbHVlMSkpOwogIH07Cn0KCmZ1bmN0aW9uIGF0dHJG
dW5jdGlvbk5TJDEoZnVsbG5hbWUsIGludGVycG9sYXRlLCB2YWx1ZSkgewogIHZhciBzdHJpbmcw
MCwKICAgICAgc3RyaW5nMTAsCiAgICAgIGludGVycG9sYXRlMDsKICByZXR1cm4gZnVuY3Rpb24o
KSB7CiAgICB2YXIgc3RyaW5nMCwgdmFsdWUxID0gdmFsdWUodGhpcyksIHN0cmluZzE7CiAgICBp
ZiAodmFsdWUxID09IG51bGwpIHJldHVybiB2b2lkIHRoaXMucmVtb3ZlQXR0cmlidXRlTlMoZnVs
bG5hbWUuc3BhY2UsIGZ1bGxuYW1lLmxvY2FsKTsKICAgIHN0cmluZzAgPSB0aGlzLmdldEF0dHJp
YnV0ZU5TKGZ1bGxuYW1lLnNwYWNlLCBmdWxsbmFtZS5sb2NhbCk7CiAgICBzdHJpbmcxID0gdmFs
dWUxICsgIiI7CiAgICByZXR1cm4gc3RyaW5nMCA9PT0gc3RyaW5nMSA/IG51bGwKICAgICAgICA6
IHN0cmluZzAgPT09IHN0cmluZzAwICYmIHN0cmluZzEgPT09IHN0cmluZzEwID8gaW50ZXJwb2xh
dGUwCiAgICAgICAgOiAoc3RyaW5nMTAgPSBzdHJpbmcxLCBpbnRlcnBvbGF0ZTAgPSBpbnRlcnBv
bGF0ZShzdHJpbmcwMCA9IHN0cmluZzAsIHZhbHVlMSkpOwogIH07Cn0KCmZ1bmN0aW9uIHRyYW5z
aXRpb25fYXR0cihuYW1lLCB2YWx1ZSkgewogIHZhciBmdWxsbmFtZSA9IG5hbWVzcGFjZShuYW1l
KSwgaSA9IGZ1bGxuYW1lID09PSAidHJhbnNmb3JtIiA/IGludGVycG9sYXRlVHJhbnNmb3JtU3Zn
IDogaW50ZXJwb2xhdGU7CiAgcmV0dXJuIHRoaXMuYXR0clR3ZWVuKG5hbWUsIHR5cGVvZiB2YWx1
ZSA9PT0gImZ1bmN0aW9uIgogICAgICA/IChmdWxsbmFtZS5sb2NhbCA/IGF0dHJGdW5jdGlvbk5T
JDEgOiBhdHRyRnVuY3Rpb24kMSkoZnVsbG5hbWUsIGksIHR3ZWVuVmFsdWUodGhpcywgImF0dHIu
IiArIG5hbWUsIHZhbHVlKSkKICAgICAgOiB2YWx1ZSA9PSBudWxsID8gKGZ1bGxuYW1lLmxvY2Fs
ID8gYXR0clJlbW92ZU5TJDEgOiBhdHRyUmVtb3ZlJDEpKGZ1bGxuYW1lKQogICAgICA6IChmdWxs
bmFtZS5sb2NhbCA/IGF0dHJDb25zdGFudE5TJDEgOiBhdHRyQ29uc3RhbnQkMSkoZnVsbG5hbWUs
IGksIHZhbHVlKSk7Cn0KCmZ1bmN0aW9uIGF0dHJJbnRlcnBvbGF0ZShuYW1lLCBpKSB7CiAgcmV0
dXJuIGZ1bmN0aW9uKHQpIHsKICAgIHRoaXMuc2V0QXR0cmlidXRlKG5hbWUsIGkuY2FsbCh0aGlz
LCB0KSk7CiAgfTsKfQoKZnVuY3Rpb24gYXR0ckludGVycG9sYXRlTlMoZnVsbG5hbWUsIGkpIHsK
ICByZXR1cm4gZnVuY3Rpb24odCkgewogICAgdGhpcy5zZXRBdHRyaWJ1dGVOUyhmdWxsbmFtZS5z
cGFjZSwgZnVsbG5hbWUubG9jYWwsIGkuY2FsbCh0aGlzLCB0KSk7CiAgfTsKfQoKZnVuY3Rpb24g
YXR0clR3ZWVuTlMoZnVsbG5hbWUsIHZhbHVlKSB7CiAgdmFyIHQwLCBpMDsKICBmdW5jdGlvbiB0
d2VlbigpIHsKICAgIHZhciBpID0gdmFsdWUuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgIGlm
IChpICE9PSBpMCkgdDAgPSAoaTAgPSBpKSAmJiBhdHRySW50ZXJwb2xhdGVOUyhmdWxsbmFtZSwg
aSk7CiAgICByZXR1cm4gdDA7CiAgfQogIHR3ZWVuLl92YWx1ZSA9IHZhbHVlOwogIHJldHVybiB0
d2VlbjsKfQoKZnVuY3Rpb24gYXR0clR3ZWVuKG5hbWUsIHZhbHVlKSB7CiAgdmFyIHQwLCBpMDsK
ICBmdW5jdGlvbiB0d2VlbigpIHsKICAgIHZhciBpID0gdmFsdWUuYXBwbHkodGhpcywgYXJndW1l
bnRzKTsKICAgIGlmIChpICE9PSBpMCkgdDAgPSAoaTAgPSBpKSAmJiBhdHRySW50ZXJwb2xhdGUo
bmFtZSwgaSk7CiAgICByZXR1cm4gdDA7CiAgfQogIHR3ZWVuLl92YWx1ZSA9IHZhbHVlOwogIHJl
dHVybiB0d2VlbjsKfQoKZnVuY3Rpb24gdHJhbnNpdGlvbl9hdHRyVHdlZW4obmFtZSwgdmFsdWUp
IHsKICB2YXIga2V5ID0gImF0dHIuIiArIG5hbWU7CiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAy
KSByZXR1cm4gKGtleSA9IHRoaXMudHdlZW4oa2V5KSkgJiYga2V5Ll92YWx1ZTsKICBpZiAodmFs
dWUgPT0gbnVsbCkgcmV0dXJuIHRoaXMudHdlZW4oa2V5LCBudWxsKTsKICBpZiAodHlwZW9mIHZh
bHVlICE9PSAiZnVuY3Rpb24iKSB0aHJvdyBuZXcgRXJyb3I7CiAgdmFyIGZ1bGxuYW1lID0gbmFt
ZXNwYWNlKG5hbWUpOwogIHJldHVybiB0aGlzLnR3ZWVuKGtleSwgKGZ1bGxuYW1lLmxvY2FsID8g
YXR0clR3ZWVuTlMgOiBhdHRyVHdlZW4pKGZ1bGxuYW1lLCB2YWx1ZSkpOwp9CgpmdW5jdGlvbiBk
ZWxheUZ1bmN0aW9uKGlkLCB2YWx1ZSkgewogIHJldHVybiBmdW5jdGlvbigpIHsKICAgIGluaXQo
dGhpcywgaWQpLmRlbGF5ID0gK3ZhbHVlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgfTsKfQoK
ZnVuY3Rpb24gZGVsYXlDb25zdGFudChpZCwgdmFsdWUpIHsKICByZXR1cm4gdmFsdWUgPSArdmFs
dWUsIGZ1bmN0aW9uKCkgewogICAgaW5pdCh0aGlzLCBpZCkuZGVsYXkgPSB2YWx1ZTsKICB9Owp9
CgpmdW5jdGlvbiB0cmFuc2l0aW9uX2RlbGF5KHZhbHVlKSB7CiAgdmFyIGlkID0gdGhpcy5faWQ7
CgogIHJldHVybiBhcmd1bWVudHMubGVuZ3RoCiAgICAgID8gdGhpcy5lYWNoKCh0eXBlb2YgdmFs
dWUgPT09ICJmdW5jdGlvbiIKICAgICAgICAgID8gZGVsYXlGdW5jdGlvbgogICAgICAgICAgOiBk
ZWxheUNvbnN0YW50KShpZCwgdmFsdWUpKQogICAgICA6IGdldCQxKHRoaXMubm9kZSgpLCBpZCku
ZGVsYXk7Cn0KCmZ1bmN0aW9uIGR1cmF0aW9uRnVuY3Rpb24oaWQsIHZhbHVlKSB7CiAgcmV0dXJu
IGZ1bmN0aW9uKCkgewogICAgc2V0JDEodGhpcywgaWQpLmR1cmF0aW9uID0gK3ZhbHVlLmFwcGx5
KHRoaXMsIGFyZ3VtZW50cyk7CiAgfTsKfQoKZnVuY3Rpb24gZHVyYXRpb25Db25zdGFudChpZCwg
dmFsdWUpIHsKICByZXR1cm4gdmFsdWUgPSArdmFsdWUsIGZ1bmN0aW9uKCkgewogICAgc2V0JDEo
dGhpcywgaWQpLmR1cmF0aW9uID0gdmFsdWU7CiAgfTsKfQoKZnVuY3Rpb24gdHJhbnNpdGlvbl9k
dXJhdGlvbih2YWx1ZSkgewogIHZhciBpZCA9IHRoaXMuX2lkOwoKICByZXR1cm4gYXJndW1lbnRz
Lmxlbmd0aAogICAgICA/IHRoaXMuZWFjaCgodHlwZW9mIHZhbHVlID09PSAiZnVuY3Rpb24iCiAg
ICAgICAgICA/IGR1cmF0aW9uRnVuY3Rpb24KICAgICAgICAgIDogZHVyYXRpb25Db25zdGFudCko
aWQsIHZhbHVlKSkKICAgICAgOiBnZXQkMSh0aGlzLm5vZGUoKSwgaWQpLmR1cmF0aW9uOwp9Cgpm
dW5jdGlvbiBlYXNlQ29uc3RhbnQoaWQsIHZhbHVlKSB7CiAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0g
ImZ1bmN0aW9uIikgdGhyb3cgbmV3IEVycm9yOwogIHJldHVybiBmdW5jdGlvbigpIHsKICAgIHNl
dCQxKHRoaXMsIGlkKS5lYXNlID0gdmFsdWU7CiAgfTsKfQoKZnVuY3Rpb24gdHJhbnNpdGlvbl9l
YXNlKHZhbHVlKSB7CiAgdmFyIGlkID0gdGhpcy5faWQ7CgogIHJldHVybiBhcmd1bWVudHMubGVu
Z3RoCiAgICAgID8gdGhpcy5lYWNoKGVhc2VDb25zdGFudChpZCwgdmFsdWUpKQogICAgICA6IGdl
dCQxKHRoaXMubm9kZSgpLCBpZCkuZWFzZTsKfQoKZnVuY3Rpb24gdHJhbnNpdGlvbl9maWx0ZXIo
bWF0Y2gpIHsKICBpZiAodHlwZW9mIG1hdGNoICE9PSAiZnVuY3Rpb24iKSBtYXRjaCA9IG1hdGNo
ZXIobWF0Y2gpOwoKICBmb3IgKHZhciBncm91cHMgPSB0aGlzLl9ncm91cHMsIG0gPSBncm91cHMu
bGVuZ3RoLCBzdWJncm91cHMgPSBuZXcgQXJyYXkobSksIGogPSAwOyBqIDwgbTsgKytqKSB7CiAg
ICBmb3IgKHZhciBncm91cCA9IGdyb3Vwc1tqXSwgbiA9IGdyb3VwLmxlbmd0aCwgc3ViZ3JvdXAg
PSBzdWJncm91cHNbal0gPSBbXSwgbm9kZSwgaSA9IDA7IGkgPCBuOyArK2kpIHsKICAgICAgaWYg
KChub2RlID0gZ3JvdXBbaV0pICYmIG1hdGNoLmNhbGwobm9kZSwgbm9kZS5fX2RhdGFfXywgaSwg
Z3JvdXApKSB7CiAgICAgICAgc3ViZ3JvdXAucHVzaChub2RlKTsKICAgICAgfQogICAgfQogIH0K
CiAgcmV0dXJuIG5ldyBUcmFuc2l0aW9uKHN1Ymdyb3VwcywgdGhpcy5fcGFyZW50cywgdGhpcy5f
bmFtZSwgdGhpcy5faWQpOwp9CgpmdW5jdGlvbiB0cmFuc2l0aW9uX21lcmdlKHRyYW5zaXRpb24p
IHsKICBpZiAodHJhbnNpdGlvbi5faWQgIT09IHRoaXMuX2lkKSB0aHJvdyBuZXcgRXJyb3I7Cgog
IGZvciAodmFyIGdyb3VwczAgPSB0aGlzLl9ncm91cHMsIGdyb3VwczEgPSB0cmFuc2l0aW9uLl9n
cm91cHMsIG0wID0gZ3JvdXBzMC5sZW5ndGgsIG0xID0gZ3JvdXBzMS5sZW5ndGgsIG0gPSBNYXRo
Lm1pbihtMCwgbTEpLCBtZXJnZXMgPSBuZXcgQXJyYXkobTApLCBqID0gMDsgaiA8IG07ICsraikg
ewogICAgZm9yICh2YXIgZ3JvdXAwID0gZ3JvdXBzMFtqXSwgZ3JvdXAxID0gZ3JvdXBzMVtqXSwg
biA9IGdyb3VwMC5sZW5ndGgsIG1lcmdlID0gbWVyZ2VzW2pdID0gbmV3IEFycmF5KG4pLCBub2Rl
LCBpID0gMDsgaSA8IG47ICsraSkgewogICAgICBpZiAobm9kZSA9IGdyb3VwMFtpXSB8fCBncm91
cDFbaV0pIHsKICAgICAgICBtZXJnZVtpXSA9IG5vZGU7CiAgICAgIH0KICAgIH0KICB9CgogIGZv
ciAoOyBqIDwgbTA7ICsraikgewogICAgbWVyZ2VzW2pdID0gZ3JvdXBzMFtqXTsKICB9CgogIHJl
dHVybiBuZXcgVHJhbnNpdGlvbihtZXJnZXMsIHRoaXMuX3BhcmVudHMsIHRoaXMuX25hbWUsIHRo
aXMuX2lkKTsKfQoKZnVuY3Rpb24gc3RhcnQobmFtZSkgewogIHJldHVybiAobmFtZSArICIiKS50
cmltKCkuc3BsaXQoL158XHMrLykuZXZlcnkoZnVuY3Rpb24odCkgewogICAgdmFyIGkgPSB0Lmlu
ZGV4T2YoIi4iKTsKICAgIGlmIChpID49IDApIHQgPSB0LnNsaWNlKDAsIGkpOwogICAgcmV0dXJu
ICF0IHx8IHQgPT09ICJzdGFydCI7CiAgfSk7Cn0KCmZ1bmN0aW9uIG9uRnVuY3Rpb24oaWQsIG5h
bWUsIGxpc3RlbmVyKSB7CiAgdmFyIG9uMCwgb24xLCBzaXQgPSBzdGFydChuYW1lKSA/IGluaXQg
OiBzZXQkMTsKICByZXR1cm4gZnVuY3Rpb24oKSB7CiAgICB2YXIgc2NoZWR1bGUgPSBzaXQodGhp
cywgaWQpLAogICAgICAgIG9uID0gc2NoZWR1bGUub247CgogICAgLy8gSWYgdGhpcyBub2RlIHNo
YXJlZCBhIGRpc3BhdGNoIHdpdGggdGhlIHByZXZpb3VzIG5vZGUsCiAgICAvLyBqdXN0IGFzc2ln
biB0aGUgdXBkYXRlZCBzaGFyZWQgZGlzcGF0Y2ggYW5kIHdl4oCZcmUgZG9uZSEKICAgIC8vIE90
aGVyd2lzZSwgY29weS1vbi13cml0ZS4KICAgIGlmIChvbiAhPT0gb24wKSAob24xID0gKG9uMCA9
IG9uKS5jb3B5KCkpLm9uKG5hbWUsIGxpc3RlbmVyKTsKCiAgICBzY2hlZHVsZS5vbiA9IG9uMTsK
ICB9Owp9CgpmdW5jdGlvbiB0cmFuc2l0aW9uX29uKG5hbWUsIGxpc3RlbmVyKSB7CiAgdmFyIGlk
ID0gdGhpcy5faWQ7CgogIHJldHVybiBhcmd1bWVudHMubGVuZ3RoIDwgMgogICAgICA/IGdldCQx
KHRoaXMubm9kZSgpLCBpZCkub24ub24obmFtZSkKICAgICAgOiB0aGlzLmVhY2gob25GdW5jdGlv
bihpZCwgbmFtZSwgbGlzdGVuZXIpKTsKfQoKZnVuY3Rpb24gcmVtb3ZlRnVuY3Rpb24oaWQpIHsK
ICByZXR1cm4gZnVuY3Rpb24oKSB7CiAgICB2YXIgcGFyZW50ID0gdGhpcy5wYXJlbnROb2RlOwog
ICAgZm9yICh2YXIgaSBpbiB0aGlzLl9fdHJhbnNpdGlvbikgaWYgKCtpICE9PSBpZCkgcmV0dXJu
OwogICAgaWYgKHBhcmVudCkgcGFyZW50LnJlbW92ZUNoaWxkKHRoaXMpOwogIH07Cn0KCmZ1bmN0
aW9uIHRyYW5zaXRpb25fcmVtb3ZlKCkgewogIHJldHVybiB0aGlzLm9uKCJlbmQucmVtb3ZlIiwg
cmVtb3ZlRnVuY3Rpb24odGhpcy5faWQpKTsKfQoKZnVuY3Rpb24gdHJhbnNpdGlvbl9zZWxlY3Qo
c2VsZWN0KSB7CiAgdmFyIG5hbWUgPSB0aGlzLl9uYW1lLAogICAgICBpZCA9IHRoaXMuX2lkOwoK
ICBpZiAodHlwZW9mIHNlbGVjdCAhPT0gImZ1bmN0aW9uIikgc2VsZWN0ID0gc2VsZWN0b3Ioc2Vs
ZWN0KTsKCiAgZm9yICh2YXIgZ3JvdXBzID0gdGhpcy5fZ3JvdXBzLCBtID0gZ3JvdXBzLmxlbmd0
aCwgc3ViZ3JvdXBzID0gbmV3IEFycmF5KG0pLCBqID0gMDsgaiA8IG07ICsraikgewogICAgZm9y
ICh2YXIgZ3JvdXAgPSBncm91cHNbal0sIG4gPSBncm91cC5sZW5ndGgsIHN1Ymdyb3VwID0gc3Vi
Z3JvdXBzW2pdID0gbmV3IEFycmF5KG4pLCBub2RlLCBzdWJub2RlLCBpID0gMDsgaSA8IG47ICsr
aSkgewogICAgICBpZiAoKG5vZGUgPSBncm91cFtpXSkgJiYgKHN1Ym5vZGUgPSBzZWxlY3QuY2Fs
bChub2RlLCBub2RlLl9fZGF0YV9fLCBpLCBncm91cCkpKSB7CiAgICAgICAgaWYgKCJfX2RhdGFf
XyIgaW4gbm9kZSkgc3Vibm9kZS5fX2RhdGFfXyA9IG5vZGUuX19kYXRhX187CiAgICAgICAgc3Vi
Z3JvdXBbaV0gPSBzdWJub2RlOwogICAgICAgIHNjaGVkdWxlKHN1Ymdyb3VwW2ldLCBuYW1lLCBp
ZCwgaSwgc3ViZ3JvdXAsIGdldCQxKG5vZGUsIGlkKSk7CiAgICAgIH0KICAgIH0KICB9CgogIHJl
dHVybiBuZXcgVHJhbnNpdGlvbihzdWJncm91cHMsIHRoaXMuX3BhcmVudHMsIG5hbWUsIGlkKTsK
fQoKZnVuY3Rpb24gdHJhbnNpdGlvbl9zZWxlY3RBbGwoc2VsZWN0KSB7CiAgdmFyIG5hbWUgPSB0
aGlzLl9uYW1lLAogICAgICBpZCA9IHRoaXMuX2lkOwoKICBpZiAodHlwZW9mIHNlbGVjdCAhPT0g
ImZ1bmN0aW9uIikgc2VsZWN0ID0gc2VsZWN0b3JBbGwoc2VsZWN0KTsKCiAgZm9yICh2YXIgZ3Jv
dXBzID0gdGhpcy5fZ3JvdXBzLCBtID0gZ3JvdXBzLmxlbmd0aCwgc3ViZ3JvdXBzID0gW10sIHBh
cmVudHMgPSBbXSwgaiA9IDA7IGogPCBtOyArK2opIHsKICAgIGZvciAodmFyIGdyb3VwID0gZ3Jv
dXBzW2pdLCBuID0gZ3JvdXAubGVuZ3RoLCBub2RlLCBpID0gMDsgaSA8IG47ICsraSkgewogICAg
ICBpZiAobm9kZSA9IGdyb3VwW2ldKSB7CiAgICAgICAgZm9yICh2YXIgY2hpbGRyZW4gPSBzZWxl
Y3QuY2FsbChub2RlLCBub2RlLl9fZGF0YV9fLCBpLCBncm91cCksIGNoaWxkLCBpbmhlcml0ID0g
Z2V0JDEobm9kZSwgaWQpLCBrID0gMCwgbCA9IGNoaWxkcmVuLmxlbmd0aDsgayA8IGw7ICsraykg
ewogICAgICAgICAgaWYgKGNoaWxkID0gY2hpbGRyZW5ba10pIHsKICAgICAgICAgICAgc2NoZWR1
bGUoY2hpbGQsIG5hbWUsIGlkLCBrLCBjaGlsZHJlbiwgaW5oZXJpdCk7CiAgICAgICAgICB9CiAg
ICAgICAgfQogICAgICAgIHN1Ymdyb3Vwcy5wdXNoKGNoaWxkcmVuKTsKICAgICAgICBwYXJlbnRz
LnB1c2gobm9kZSk7CiAgICAgIH0KICAgIH0KICB9CgogIHJldHVybiBuZXcgVHJhbnNpdGlvbihz
dWJncm91cHMsIHBhcmVudHMsIG5hbWUsIGlkKTsKfQoKdmFyIFNlbGVjdGlvbiQxID0gc2VsZWN0
aW9uLnByb3RvdHlwZS5jb25zdHJ1Y3RvcjsKCmZ1bmN0aW9uIHRyYW5zaXRpb25fc2VsZWN0aW9u
KCkgewogIHJldHVybiBuZXcgU2VsZWN0aW9uJDEodGhpcy5fZ3JvdXBzLCB0aGlzLl9wYXJlbnRz
KTsKfQoKZnVuY3Rpb24gc3R5bGVOdWxsKG5hbWUsIGludGVycG9sYXRlKSB7CiAgdmFyIHN0cmlu
ZzAwLAogICAgICBzdHJpbmcxMCwKICAgICAgaW50ZXJwb2xhdGUwOwogIHJldHVybiBmdW5jdGlv
bigpIHsKICAgIHZhciBzdHJpbmcwID0gc3R5bGVWYWx1ZSh0aGlzLCBuYW1lKSwKICAgICAgICBz
dHJpbmcxID0gKHRoaXMuc3R5bGUucmVtb3ZlUHJvcGVydHkobmFtZSksIHN0eWxlVmFsdWUodGhp
cywgbmFtZSkpOwogICAgcmV0dXJuIHN0cmluZzAgPT09IHN0cmluZzEgPyBudWxsCiAgICAgICAg
OiBzdHJpbmcwID09PSBzdHJpbmcwMCAmJiBzdHJpbmcxID09PSBzdHJpbmcxMCA/IGludGVycG9s
YXRlMAogICAgICAgIDogaW50ZXJwb2xhdGUwID0gaW50ZXJwb2xhdGUoc3RyaW5nMDAgPSBzdHJp
bmcwLCBzdHJpbmcxMCA9IHN0cmluZzEpOwogIH07Cn0KCmZ1bmN0aW9uIHN0eWxlUmVtb3ZlJDEo
bmFtZSkgewogIHJldHVybiBmdW5jdGlvbigpIHsKICAgIHRoaXMuc3R5bGUucmVtb3ZlUHJvcGVy
dHkobmFtZSk7CiAgfTsKfQoKZnVuY3Rpb24gc3R5bGVDb25zdGFudCQxKG5hbWUsIGludGVycG9s
YXRlLCB2YWx1ZTEpIHsKICB2YXIgc3RyaW5nMDAsCiAgICAgIHN0cmluZzEgPSB2YWx1ZTEgKyAi
IiwKICAgICAgaW50ZXJwb2xhdGUwOwogIHJldHVybiBmdW5jdGlvbigpIHsKICAgIHZhciBzdHJp
bmcwID0gc3R5bGVWYWx1ZSh0aGlzLCBuYW1lKTsKICAgIHJldHVybiBzdHJpbmcwID09PSBzdHJp
bmcxID8gbnVsbAogICAgICAgIDogc3RyaW5nMCA9PT0gc3RyaW5nMDAgPyBpbnRlcnBvbGF0ZTAK
ICAgICAgICA6IGludGVycG9sYXRlMCA9IGludGVycG9sYXRlKHN0cmluZzAwID0gc3RyaW5nMCwg
dmFsdWUxKTsKICB9Owp9CgpmdW5jdGlvbiBzdHlsZUZ1bmN0aW9uJDEobmFtZSwgaW50ZXJwb2xh
dGUsIHZhbHVlKSB7CiAgdmFyIHN0cmluZzAwLAogICAgICBzdHJpbmcxMCwKICAgICAgaW50ZXJw
b2xhdGUwOwogIHJldHVybiBmdW5jdGlvbigpIHsKICAgIHZhciBzdHJpbmcwID0gc3R5bGVWYWx1
ZSh0aGlzLCBuYW1lKSwKICAgICAgICB2YWx1ZTEgPSB2YWx1ZSh0aGlzKSwKICAgICAgICBzdHJp
bmcxID0gdmFsdWUxICsgIiI7CiAgICBpZiAodmFsdWUxID09IG51bGwpIHN0cmluZzEgPSB2YWx1
ZTEgPSAodGhpcy5zdHlsZS5yZW1vdmVQcm9wZXJ0eShuYW1lKSwgc3R5bGVWYWx1ZSh0aGlzLCBu
YW1lKSk7CiAgICByZXR1cm4gc3RyaW5nMCA9PT0gc3RyaW5nMSA/IG51bGwKICAgICAgICA6IHN0
cmluZzAgPT09IHN0cmluZzAwICYmIHN0cmluZzEgPT09IHN0cmluZzEwID8gaW50ZXJwb2xhdGUw
CiAgICAgICAgOiAoc3RyaW5nMTAgPSBzdHJpbmcxLCBpbnRlcnBvbGF0ZTAgPSBpbnRlcnBvbGF0
ZShzdHJpbmcwMCA9IHN0cmluZzAsIHZhbHVlMSkpOwogIH07Cn0KCmZ1bmN0aW9uIHN0eWxlTWF5
YmVSZW1vdmUoaWQsIG5hbWUpIHsKICB2YXIgb24wLCBvbjEsIGxpc3RlbmVyMCwga2V5ID0gInN0
eWxlLiIgKyBuYW1lLCBldmVudCA9ICJlbmQuIiArIGtleSwgcmVtb3ZlOwogIHJldHVybiBmdW5j
dGlvbigpIHsKICAgIHZhciBzY2hlZHVsZSA9IHNldCQxKHRoaXMsIGlkKSwKICAgICAgICBvbiA9
IHNjaGVkdWxlLm9uLAogICAgICAgIGxpc3RlbmVyID0gc2NoZWR1bGUudmFsdWVba2V5XSA9PSBu
dWxsID8gcmVtb3ZlIHx8IChyZW1vdmUgPSBzdHlsZVJlbW92ZSQxKG5hbWUpKSA6IHVuZGVmaW5l
ZDsKCiAgICAvLyBJZiB0aGlzIG5vZGUgc2hhcmVkIGEgZGlzcGF0Y2ggd2l0aCB0aGUgcHJldmlv
dXMgbm9kZSwKICAgIC8vIGp1c3QgYXNzaWduIHRoZSB1cGRhdGVkIHNoYXJlZCBkaXNwYXRjaCBh
bmQgd2XigJlyZSBkb25lIQogICAgLy8gT3RoZXJ3aXNlLCBjb3B5LW9uLXdyaXRlLgogICAgaWYg
KG9uICE9PSBvbjAgfHwgbGlzdGVuZXIwICE9PSBsaXN0ZW5lcikgKG9uMSA9IChvbjAgPSBvbiku
Y29weSgpKS5vbihldmVudCwgbGlzdGVuZXIwID0gbGlzdGVuZXIpOwoKICAgIHNjaGVkdWxlLm9u
ID0gb24xOwogIH07Cn0KCmZ1bmN0aW9uIHRyYW5zaXRpb25fc3R5bGUobmFtZSwgdmFsdWUsIHBy
aW9yaXR5KSB7CiAgdmFyIGkgPSAobmFtZSArPSAiIikgPT09ICJ0cmFuc2Zvcm0iID8gaW50ZXJw
b2xhdGVUcmFuc2Zvcm1Dc3MgOiBpbnRlcnBvbGF0ZTsKICByZXR1cm4gdmFsdWUgPT0gbnVsbCA/
IHRoaXMKICAgICAgLnN0eWxlVHdlZW4obmFtZSwgc3R5bGVOdWxsKG5hbWUsIGkpKQogICAgICAu
b24oImVuZC5zdHlsZS4iICsgbmFtZSwgc3R5bGVSZW1vdmUkMShuYW1lKSkKICAgIDogdHlwZW9m
IHZhbHVlID09PSAiZnVuY3Rpb24iID8gdGhpcwogICAgICAuc3R5bGVUd2VlbihuYW1lLCBzdHls
ZUZ1bmN0aW9uJDEobmFtZSwgaSwgdHdlZW5WYWx1ZSh0aGlzLCAic3R5bGUuIiArIG5hbWUsIHZh
bHVlKSkpCiAgICAgIC5lYWNoKHN0eWxlTWF5YmVSZW1vdmUodGhpcy5faWQsIG5hbWUpKQogICAg
OiB0aGlzCiAgICAgIC5zdHlsZVR3ZWVuKG5hbWUsIHN0eWxlQ29uc3RhbnQkMShuYW1lLCBpLCB2
YWx1ZSksIHByaW9yaXR5KQogICAgICAub24oImVuZC5zdHlsZS4iICsgbmFtZSwgbnVsbCk7Cn0K
CmZ1bmN0aW9uIHN0eWxlSW50ZXJwb2xhdGUobmFtZSwgaSwgcHJpb3JpdHkpIHsKICByZXR1cm4g
ZnVuY3Rpb24odCkgewogICAgdGhpcy5zdHlsZS5zZXRQcm9wZXJ0eShuYW1lLCBpLmNhbGwodGhp
cywgdCksIHByaW9yaXR5KTsKICB9Owp9CgpmdW5jdGlvbiBzdHlsZVR3ZWVuKG5hbWUsIHZhbHVl
LCBwcmlvcml0eSkgewogIHZhciB0LCBpMDsKICBmdW5jdGlvbiB0d2VlbigpIHsKICAgIHZhciBp
ID0gdmFsdWUuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgIGlmIChpICE9PSBpMCkgdCA9IChp
MCA9IGkpICYmIHN0eWxlSW50ZXJwb2xhdGUobmFtZSwgaSwgcHJpb3JpdHkpOwogICAgcmV0dXJu
IHQ7CiAgfQogIHR3ZWVuLl92YWx1ZSA9IHZhbHVlOwogIHJldHVybiB0d2VlbjsKfQoKZnVuY3Rp
b24gdHJhbnNpdGlvbl9zdHlsZVR3ZWVuKG5hbWUsIHZhbHVlLCBwcmlvcml0eSkgewogIHZhciBr
ZXkgPSAic3R5bGUuIiArIChuYW1lICs9ICIiKTsKICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDIp
IHJldHVybiAoa2V5ID0gdGhpcy50d2VlbihrZXkpKSAmJiBrZXkuX3ZhbHVlOwogIGlmICh2YWx1
ZSA9PSBudWxsKSByZXR1cm4gdGhpcy50d2VlbihrZXksIG51bGwpOwogIGlmICh0eXBlb2YgdmFs
dWUgIT09ICJmdW5jdGlvbiIpIHRocm93IG5ldyBFcnJvcjsKICByZXR1cm4gdGhpcy50d2Vlbihr
ZXksIHN0eWxlVHdlZW4obmFtZSwgdmFsdWUsIHByaW9yaXR5ID09IG51bGwgPyAiIiA6IHByaW9y
aXR5KSk7Cn0KCmZ1bmN0aW9uIHRleHRDb25zdGFudCQxKHZhbHVlKSB7CiAgcmV0dXJuIGZ1bmN0
aW9uKCkgewogICAgdGhpcy50ZXh0Q29udGVudCA9IHZhbHVlOwogIH07Cn0KCmZ1bmN0aW9uIHRl
eHRGdW5jdGlvbiQxKHZhbHVlKSB7CiAgcmV0dXJuIGZ1bmN0aW9uKCkgewogICAgdmFyIHZhbHVl
MSA9IHZhbHVlKHRoaXMpOwogICAgdGhpcy50ZXh0Q29udGVudCA9IHZhbHVlMSA9PSBudWxsID8g
IiIgOiB2YWx1ZTE7CiAgfTsKfQoKZnVuY3Rpb24gdHJhbnNpdGlvbl90ZXh0KHZhbHVlKSB7CiAg
cmV0dXJuIHRoaXMudHdlZW4oInRleHQiLCB0eXBlb2YgdmFsdWUgPT09ICJmdW5jdGlvbiIKICAg
ICAgPyB0ZXh0RnVuY3Rpb24kMSh0d2VlblZhbHVlKHRoaXMsICJ0ZXh0IiwgdmFsdWUpKQogICAg
ICA6IHRleHRDb25zdGFudCQxKHZhbHVlID09IG51bGwgPyAiIiA6IHZhbHVlICsgIiIpKTsKfQoK
ZnVuY3Rpb24gdGV4dEludGVycG9sYXRlKGkpIHsKICByZXR1cm4gZnVuY3Rpb24odCkgewogICAg
dGhpcy50ZXh0Q29udGVudCA9IGkuY2FsbCh0aGlzLCB0KTsKICB9Owp9CgpmdW5jdGlvbiB0ZXh0
VHdlZW4odmFsdWUpIHsKICB2YXIgdDAsIGkwOwogIGZ1bmN0aW9uIHR3ZWVuKCkgewogICAgdmFy
IGkgPSB2YWx1ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgaWYgKGkgIT09IGkwKSB0MCA9
IChpMCA9IGkpICYmIHRleHRJbnRlcnBvbGF0ZShpKTsKICAgIHJldHVybiB0MDsKICB9CiAgdHdl
ZW4uX3ZhbHVlID0gdmFsdWU7CiAgcmV0dXJuIHR3ZWVuOwp9CgpmdW5jdGlvbiB0cmFuc2l0aW9u
X3RleHRUd2Vlbih2YWx1ZSkgewogIHZhciBrZXkgPSAidGV4dCI7CiAgaWYgKGFyZ3VtZW50cy5s
ZW5ndGggPCAxKSByZXR1cm4gKGtleSA9IHRoaXMudHdlZW4oa2V5KSkgJiYga2V5Ll92YWx1ZTsK
ICBpZiAodmFsdWUgPT0gbnVsbCkgcmV0dXJuIHRoaXMudHdlZW4oa2V5LCBudWxsKTsKICBpZiAo
dHlwZW9mIHZhbHVlICE9PSAiZnVuY3Rpb24iKSB0aHJvdyBuZXcgRXJyb3I7CiAgcmV0dXJuIHRo
aXMudHdlZW4oa2V5LCB0ZXh0VHdlZW4odmFsdWUpKTsKfQoKZnVuY3Rpb24gdHJhbnNpdGlvbl90
cmFuc2l0aW9uKCkgewogIHZhciBuYW1lID0gdGhpcy5fbmFtZSwKICAgICAgaWQwID0gdGhpcy5f
aWQsCiAgICAgIGlkMSA9IG5ld0lkKCk7CgogIGZvciAodmFyIGdyb3VwcyA9IHRoaXMuX2dyb3Vw
cywgbSA9IGdyb3Vwcy5sZW5ndGgsIGogPSAwOyBqIDwgbTsgKytqKSB7CiAgICBmb3IgKHZhciBn
cm91cCA9IGdyb3Vwc1tqXSwgbiA9IGdyb3VwLmxlbmd0aCwgbm9kZSwgaSA9IDA7IGkgPCBuOyAr
K2kpIHsKICAgICAgaWYgKG5vZGUgPSBncm91cFtpXSkgewogICAgICAgIHZhciBpbmhlcml0ID0g
Z2V0JDEobm9kZSwgaWQwKTsKICAgICAgICBzY2hlZHVsZShub2RlLCBuYW1lLCBpZDEsIGksIGdy
b3VwLCB7CiAgICAgICAgICB0aW1lOiBpbmhlcml0LnRpbWUgKyBpbmhlcml0LmRlbGF5ICsgaW5o
ZXJpdC5kdXJhdGlvbiwKICAgICAgICAgIGRlbGF5OiAwLAogICAgICAgICAgZHVyYXRpb246IGlu
aGVyaXQuZHVyYXRpb24sCiAgICAgICAgICBlYXNlOiBpbmhlcml0LmVhc2UKICAgICAgICB9KTsK
ICAgICAgfQogICAgfQogIH0KCiAgcmV0dXJuIG5ldyBUcmFuc2l0aW9uKGdyb3VwcywgdGhpcy5f
cGFyZW50cywgbmFtZSwgaWQxKTsKfQoKZnVuY3Rpb24gdHJhbnNpdGlvbl9lbmQoKSB7CiAgdmFy
IG9uMCwgb24xLCB0aGF0ID0gdGhpcywgaWQgPSB0aGF0Ll9pZCwgc2l6ZSA9IHRoYXQuc2l6ZSgp
OwogIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHsKICAgIHZh
ciBjYW5jZWwgPSB7dmFsdWU6IHJlamVjdH0sCiAgICAgICAgZW5kID0ge3ZhbHVlOiBmdW5jdGlv
bigpIHsgaWYgKC0tc2l6ZSA9PT0gMCkgcmVzb2x2ZSgpOyB9fTsKCiAgICB0aGF0LmVhY2goZnVu
Y3Rpb24oKSB7CiAgICAgIHZhciBzY2hlZHVsZSA9IHNldCQxKHRoaXMsIGlkKSwKICAgICAgICAg
IG9uID0gc2NoZWR1bGUub247CgogICAgICAvLyBJZiB0aGlzIG5vZGUgc2hhcmVkIGEgZGlzcGF0
Y2ggd2l0aCB0aGUgcHJldmlvdXMgbm9kZSwKICAgICAgLy8ganVzdCBhc3NpZ24gdGhlIHVwZGF0
ZWQgc2hhcmVkIGRpc3BhdGNoIGFuZCB3ZeKAmXJlIGRvbmUhCiAgICAgIC8vIE90aGVyd2lzZSwg
Y29weS1vbi13cml0ZS4KICAgICAgaWYgKG9uICE9PSBvbjApIHsKICAgICAgICBvbjEgPSAob24w
ID0gb24pLmNvcHkoKTsKICAgICAgICBvbjEuXy5jYW5jZWwucHVzaChjYW5jZWwpOwogICAgICAg
IG9uMS5fLmludGVycnVwdC5wdXNoKGNhbmNlbCk7CiAgICAgICAgb24xLl8uZW5kLnB1c2goZW5k
KTsKICAgICAgfQoKICAgICAgc2NoZWR1bGUub24gPSBvbjE7CiAgICB9KTsKICB9KTsKfQoKdmFy
IGlkID0gMDsKCmZ1bmN0aW9uIFRyYW5zaXRpb24oZ3JvdXBzLCBwYXJlbnRzLCBuYW1lLCBpZCkg
ewogIHRoaXMuX2dyb3VwcyA9IGdyb3VwczsKICB0aGlzLl9wYXJlbnRzID0gcGFyZW50czsKICB0
aGlzLl9uYW1lID0gbmFtZTsKICB0aGlzLl9pZCA9IGlkOwp9CgpmdW5jdGlvbiB0cmFuc2l0aW9u
KG5hbWUpIHsKICByZXR1cm4gc2VsZWN0aW9uKCkudHJhbnNpdGlvbihuYW1lKTsKfQoKZnVuY3Rp
b24gbmV3SWQoKSB7CiAgcmV0dXJuICsraWQ7Cn0KCnZhciBzZWxlY3Rpb25fcHJvdG90eXBlID0g
c2VsZWN0aW9uLnByb3RvdHlwZTsKClRyYW5zaXRpb24ucHJvdG90eXBlID0gdHJhbnNpdGlvbi5w
cm90b3R5cGUgPSB7CiAgY29uc3RydWN0b3I6IFRyYW5zaXRpb24sCiAgc2VsZWN0OiB0cmFuc2l0
aW9uX3NlbGVjdCwKICBzZWxlY3RBbGw6IHRyYW5zaXRpb25fc2VsZWN0QWxsLAogIGZpbHRlcjog
dHJhbnNpdGlvbl9maWx0ZXIsCiAgbWVyZ2U6IHRyYW5zaXRpb25fbWVyZ2UsCiAgc2VsZWN0aW9u
OiB0cmFuc2l0aW9uX3NlbGVjdGlvbiwKICB0cmFuc2l0aW9uOiB0cmFuc2l0aW9uX3RyYW5zaXRp
b24sCiAgY2FsbDogc2VsZWN0aW9uX3Byb3RvdHlwZS5jYWxsLAogIG5vZGVzOiBzZWxlY3Rpb25f
cHJvdG90eXBlLm5vZGVzLAogIG5vZGU6IHNlbGVjdGlvbl9wcm90b3R5cGUubm9kZSwKICBzaXpl
OiBzZWxlY3Rpb25fcHJvdG90eXBlLnNpemUsCiAgZW1wdHk6IHNlbGVjdGlvbl9wcm90b3R5cGUu
ZW1wdHksCiAgZWFjaDogc2VsZWN0aW9uX3Byb3RvdHlwZS5lYWNoLAogIG9uOiB0cmFuc2l0aW9u
X29uLAogIGF0dHI6IHRyYW5zaXRpb25fYXR0ciwKICBhdHRyVHdlZW46IHRyYW5zaXRpb25fYXR0
clR3ZWVuLAogIHN0eWxlOiB0cmFuc2l0aW9uX3N0eWxlLAogIHN0eWxlVHdlZW46IHRyYW5zaXRp
b25fc3R5bGVUd2VlbiwKICB0ZXh0OiB0cmFuc2l0aW9uX3RleHQsCiAgdGV4dFR3ZWVuOiB0cmFu
c2l0aW9uX3RleHRUd2VlbiwKICByZW1vdmU6IHRyYW5zaXRpb25fcmVtb3ZlLAogIHR3ZWVuOiB0
cmFuc2l0aW9uX3R3ZWVuLAogIGRlbGF5OiB0cmFuc2l0aW9uX2RlbGF5LAogIGR1cmF0aW9uOiB0
cmFuc2l0aW9uX2R1cmF0aW9uLAogIGVhc2U6IHRyYW5zaXRpb25fZWFzZSwKICBlbmQ6IHRyYW5z
aXRpb25fZW5kCn07CgpmdW5jdGlvbiBsaW5lYXIkMSh0KSB7CiAgcmV0dXJuICt0Owp9CgpmdW5j
dGlvbiBxdWFkSW4odCkgewogIHJldHVybiB0ICogdDsKfQoKZnVuY3Rpb24gcXVhZE91dCh0KSB7
CiAgcmV0dXJuIHQgKiAoMiAtIHQpOwp9CgpmdW5jdGlvbiBxdWFkSW5PdXQodCkgewogIHJldHVy
biAoKHQgKj0gMikgPD0gMSA/IHQgKiB0IDogLS10ICogKDIgLSB0KSArIDEpIC8gMjsKfQoKZnVu
Y3Rpb24gY3ViaWNJbih0KSB7CiAgcmV0dXJuIHQgKiB0ICogdDsKfQoKZnVuY3Rpb24gY3ViaWNP
dXQodCkgewogIHJldHVybiAtLXQgKiB0ICogdCArIDE7Cn0KCmZ1bmN0aW9uIGN1YmljSW5PdXQo
dCkgewogIHJldHVybiAoKHQgKj0gMikgPD0gMSA/IHQgKiB0ICogdCA6ICh0IC09IDIpICogdCAq
IHQgKyAyKSAvIDI7Cn0KCnZhciBleHBvbmVudCA9IDM7Cgp2YXIgcG9seUluID0gKGZ1bmN0aW9u
IGN1c3RvbShlKSB7CiAgZSA9ICtlOwoKICBmdW5jdGlvbiBwb2x5SW4odCkgewogICAgcmV0dXJu
IE1hdGgucG93KHQsIGUpOwogIH0KCiAgcG9seUluLmV4cG9uZW50ID0gY3VzdG9tOwoKICByZXR1
cm4gcG9seUluOwp9KShleHBvbmVudCk7Cgp2YXIgcG9seU91dCA9IChmdW5jdGlvbiBjdXN0b20o
ZSkgewogIGUgPSArZTsKCiAgZnVuY3Rpb24gcG9seU91dCh0KSB7CiAgICByZXR1cm4gMSAtIE1h
dGgucG93KDEgLSB0LCBlKTsKICB9CgogIHBvbHlPdXQuZXhwb25lbnQgPSBjdXN0b207CgogIHJl
dHVybiBwb2x5T3V0Owp9KShleHBvbmVudCk7Cgp2YXIgcG9seUluT3V0ID0gKGZ1bmN0aW9uIGN1
c3RvbShlKSB7CiAgZSA9ICtlOwoKICBmdW5jdGlvbiBwb2x5SW5PdXQodCkgewogICAgcmV0dXJu
ICgodCAqPSAyKSA8PSAxID8gTWF0aC5wb3codCwgZSkgOiAyIC0gTWF0aC5wb3coMiAtIHQsIGUp
KSAvIDI7CiAgfQoKICBwb2x5SW5PdXQuZXhwb25lbnQgPSBjdXN0b207CgogIHJldHVybiBwb2x5
SW5PdXQ7Cn0pKGV4cG9uZW50KTsKCnZhciBwaSA9IE1hdGguUEksCiAgICBoYWxmUGkgPSBwaSAv
IDI7CgpmdW5jdGlvbiBzaW5Jbih0KSB7CiAgcmV0dXJuIDEgLSBNYXRoLmNvcyh0ICogaGFsZlBp
KTsKfQoKZnVuY3Rpb24gc2luT3V0KHQpIHsKICByZXR1cm4gTWF0aC5zaW4odCAqIGhhbGZQaSk7
Cn0KCmZ1bmN0aW9uIHNpbkluT3V0KHQpIHsKICByZXR1cm4gKDEgLSBNYXRoLmNvcyhwaSAqIHQp
KSAvIDI7Cn0KCmZ1bmN0aW9uIGV4cEluKHQpIHsKICByZXR1cm4gTWF0aC5wb3coMiwgMTAgKiB0
IC0gMTApOwp9CgpmdW5jdGlvbiBleHBPdXQodCkgewogIHJldHVybiAxIC0gTWF0aC5wb3coMiwg
LTEwICogdCk7Cn0KCmZ1bmN0aW9uIGV4cEluT3V0KHQpIHsKICByZXR1cm4gKCh0ICo9IDIpIDw9
IDEgPyBNYXRoLnBvdygyLCAxMCAqIHQgLSAxMCkgOiAyIC0gTWF0aC5wb3coMiwgMTAgLSAxMCAq
IHQpKSAvIDI7Cn0KCmZ1bmN0aW9uIGNpcmNsZUluKHQpIHsKICByZXR1cm4gMSAtIE1hdGguc3Fy
dCgxIC0gdCAqIHQpOwp9CgpmdW5jdGlvbiBjaXJjbGVPdXQodCkgewogIHJldHVybiBNYXRoLnNx
cnQoMSAtIC0tdCAqIHQpOwp9CgpmdW5jdGlvbiBjaXJjbGVJbk91dCh0KSB7CiAgcmV0dXJuICgo
dCAqPSAyKSA8PSAxID8gMSAtIE1hdGguc3FydCgxIC0gdCAqIHQpIDogTWF0aC5zcXJ0KDEgLSAo
dCAtPSAyKSAqIHQpICsgMSkgLyAyOwp9Cgp2YXIgYjEgPSA0IC8gMTEsCiAgICBiMiA9IDYgLyAx
MSwKICAgIGIzID0gOCAvIDExLAogICAgYjQgPSAzIC8gNCwKICAgIGI1ID0gOSAvIDExLAogICAg
YjYgPSAxMCAvIDExLAogICAgYjcgPSAxNSAvIDE2LAogICAgYjggPSAyMSAvIDIyLAogICAgYjkg
PSA2MyAvIDY0LAogICAgYjAgPSAxIC8gYjEgLyBiMTsKCmZ1bmN0aW9uIGJvdW5jZUluKHQpIHsK
ICByZXR1cm4gMSAtIGJvdW5jZU91dCgxIC0gdCk7Cn0KCmZ1bmN0aW9uIGJvdW5jZU91dCh0KSB7
CiAgcmV0dXJuICh0ID0gK3QpIDwgYjEgPyBiMCAqIHQgKiB0IDogdCA8IGIzID8gYjAgKiAodCAt
PSBiMikgKiB0ICsgYjQgOiB0IDwgYjYgPyBiMCAqICh0IC09IGI1KSAqIHQgKyBiNyA6IGIwICog
KHQgLT0gYjgpICogdCArIGI5Owp9CgpmdW5jdGlvbiBib3VuY2VJbk91dCh0KSB7CiAgcmV0dXJu
ICgodCAqPSAyKSA8PSAxID8gMSAtIGJvdW5jZU91dCgxIC0gdCkgOiBib3VuY2VPdXQodCAtIDEp
ICsgMSkgLyAyOwp9Cgp2YXIgb3ZlcnNob290ID0gMS43MDE1ODsKCnZhciBiYWNrSW4gPSAoZnVu
Y3Rpb24gY3VzdG9tKHMpIHsKICBzID0gK3M7CgogIGZ1bmN0aW9uIGJhY2tJbih0KSB7CiAgICBy
ZXR1cm4gdCAqIHQgKiAoKHMgKyAxKSAqIHQgLSBzKTsKICB9CgogIGJhY2tJbi5vdmVyc2hvb3Qg
PSBjdXN0b207CgogIHJldHVybiBiYWNrSW47Cn0pKG92ZXJzaG9vdCk7Cgp2YXIgYmFja091dCA9
IChmdW5jdGlvbiBjdXN0b20ocykgewogIHMgPSArczsKCiAgZnVuY3Rpb24gYmFja091dCh0KSB7
CiAgICByZXR1cm4gLS10ICogdCAqICgocyArIDEpICogdCArIHMpICsgMTsKICB9CgogIGJhY2tP
dXQub3ZlcnNob290ID0gY3VzdG9tOwoKICByZXR1cm4gYmFja091dDsKfSkob3ZlcnNob290KTsK
CnZhciBiYWNrSW5PdXQgPSAoZnVuY3Rpb24gY3VzdG9tKHMpIHsKICBzID0gK3M7CgogIGZ1bmN0
aW9uIGJhY2tJbk91dCh0KSB7CiAgICByZXR1cm4gKCh0ICo9IDIpIDwgMSA/IHQgKiB0ICogKChz
ICsgMSkgKiB0IC0gcykgOiAodCAtPSAyKSAqIHQgKiAoKHMgKyAxKSAqIHQgKyBzKSArIDIpIC8g
MjsKICB9CgogIGJhY2tJbk91dC5vdmVyc2hvb3QgPSBjdXN0b207CgogIHJldHVybiBiYWNrSW5P
dXQ7Cn0pKG92ZXJzaG9vdCk7Cgp2YXIgdGF1ID0gMiAqIE1hdGguUEksCiAgICBhbXBsaXR1ZGUg
PSAxLAogICAgcGVyaW9kID0gMC4zOwoKdmFyIGVsYXN0aWNJbiA9IChmdW5jdGlvbiBjdXN0b20o
YSwgcCkgewogIHZhciBzID0gTWF0aC5hc2luKDEgLyAoYSA9IE1hdGgubWF4KDEsIGEpKSkgKiAo
cCAvPSB0YXUpOwoKICBmdW5jdGlvbiBlbGFzdGljSW4odCkgewogICAgcmV0dXJuIGEgKiBNYXRo
LnBvdygyLCAxMCAqIC0tdCkgKiBNYXRoLnNpbigocyAtIHQpIC8gcCk7CiAgfQoKICBlbGFzdGlj
SW4uYW1wbGl0dWRlID0gZnVuY3Rpb24oYSkgeyByZXR1cm4gY3VzdG9tKGEsIHAgKiB0YXUpOyB9
OwogIGVsYXN0aWNJbi5wZXJpb2QgPSBmdW5jdGlvbihwKSB7IHJldHVybiBjdXN0b20oYSwgcCk7
IH07CgogIHJldHVybiBlbGFzdGljSW47Cn0pKGFtcGxpdHVkZSwgcGVyaW9kKTsKCnZhciBlbGFz
dGljT3V0ID0gKGZ1bmN0aW9uIGN1c3RvbShhLCBwKSB7CiAgdmFyIHMgPSBNYXRoLmFzaW4oMSAv
IChhID0gTWF0aC5tYXgoMSwgYSkpKSAqIChwIC89IHRhdSk7CgogIGZ1bmN0aW9uIGVsYXN0aWNP
dXQodCkgewogICAgcmV0dXJuIDEgLSBhICogTWF0aC5wb3coMiwgLTEwICogKHQgPSArdCkpICog
TWF0aC5zaW4oKHQgKyBzKSAvIHApOwogIH0KCiAgZWxhc3RpY091dC5hbXBsaXR1ZGUgPSBmdW5j
dGlvbihhKSB7IHJldHVybiBjdXN0b20oYSwgcCAqIHRhdSk7IH07CiAgZWxhc3RpY091dC5wZXJp
b2QgPSBmdW5jdGlvbihwKSB7IHJldHVybiBjdXN0b20oYSwgcCk7IH07CgogIHJldHVybiBlbGFz
dGljT3V0Owp9KShhbXBsaXR1ZGUsIHBlcmlvZCk7Cgp2YXIgZWxhc3RpY0luT3V0ID0gKGZ1bmN0
aW9uIGN1c3RvbShhLCBwKSB7CiAgdmFyIHMgPSBNYXRoLmFzaW4oMSAvIChhID0gTWF0aC5tYXgo
MSwgYSkpKSAqIChwIC89IHRhdSk7CgogIGZ1bmN0aW9uIGVsYXN0aWNJbk91dCh0KSB7CiAgICBy
ZXR1cm4gKCh0ID0gdCAqIDIgLSAxKSA8IDAKICAgICAgICA/IGEgKiBNYXRoLnBvdygyLCAxMCAq
IHQpICogTWF0aC5zaW4oKHMgLSB0KSAvIHApCiAgICAgICAgOiAyIC0gYSAqIE1hdGgucG93KDIs
IC0xMCAqIHQpICogTWF0aC5zaW4oKHMgKyB0KSAvIHApKSAvIDI7CiAgfQoKICBlbGFzdGljSW5P
dXQuYW1wbGl0dWRlID0gZnVuY3Rpb24oYSkgeyByZXR1cm4gY3VzdG9tKGEsIHAgKiB0YXUpOyB9
OwogIGVsYXN0aWNJbk91dC5wZXJpb2QgPSBmdW5jdGlvbihwKSB7IHJldHVybiBjdXN0b20oYSwg
cCk7IH07CgogIHJldHVybiBlbGFzdGljSW5PdXQ7Cn0pKGFtcGxpdHVkZSwgcGVyaW9kKTsKCnZh
ciBkZWZhdWx0VGltaW5nID0gewogIHRpbWU6IG51bGwsIC8vIFNldCBvbiB1c2UuCiAgZGVsYXk6
IDAsCiAgZHVyYXRpb246IDI1MCwKICBlYXNlOiBjdWJpY0luT3V0Cn07CgpmdW5jdGlvbiBpbmhl
cml0KG5vZGUsIGlkKSB7CiAgdmFyIHRpbWluZzsKICB3aGlsZSAoISh0aW1pbmcgPSBub2RlLl9f
dHJhbnNpdGlvbikgfHwgISh0aW1pbmcgPSB0aW1pbmdbaWRdKSkgewogICAgaWYgKCEobm9kZSA9
IG5vZGUucGFyZW50Tm9kZSkpIHsKICAgICAgcmV0dXJuIGRlZmF1bHRUaW1pbmcudGltZSA9IG5v
dygpLCBkZWZhdWx0VGltaW5nOwogICAgfQogIH0KICByZXR1cm4gdGltaW5nOwp9CgpmdW5jdGlv
biBzZWxlY3Rpb25fdHJhbnNpdGlvbihuYW1lKSB7CiAgdmFyIGlkLAogICAgICB0aW1pbmc7Cgog
IGlmIChuYW1lIGluc3RhbmNlb2YgVHJhbnNpdGlvbikgewogICAgaWQgPSBuYW1lLl9pZCwgbmFt
ZSA9IG5hbWUuX25hbWU7CiAgfSBlbHNlIHsKICAgIGlkID0gbmV3SWQoKSwgKHRpbWluZyA9IGRl
ZmF1bHRUaW1pbmcpLnRpbWUgPSBub3coKSwgbmFtZSA9IG5hbWUgPT0gbnVsbCA/IG51bGwgOiBu
YW1lICsgIiI7CiAgfQoKICBmb3IgKHZhciBncm91cHMgPSB0aGlzLl9ncm91cHMsIG0gPSBncm91
cHMubGVuZ3RoLCBqID0gMDsgaiA8IG07ICsraikgewogICAgZm9yICh2YXIgZ3JvdXAgPSBncm91
cHNbal0sIG4gPSBncm91cC5sZW5ndGgsIG5vZGUsIGkgPSAwOyBpIDwgbjsgKytpKSB7CiAgICAg
IGlmIChub2RlID0gZ3JvdXBbaV0pIHsKICAgICAgICBzY2hlZHVsZShub2RlLCBuYW1lLCBpZCwg
aSwgZ3JvdXAsIHRpbWluZyB8fCBpbmhlcml0KG5vZGUsIGlkKSk7CiAgICAgIH0KICAgIH0KICB9
CgogIHJldHVybiBuZXcgVHJhbnNpdGlvbihncm91cHMsIHRoaXMuX3BhcmVudHMsIG5hbWUsIGlk
KTsKfQoKc2VsZWN0aW9uLnByb3RvdHlwZS5pbnRlcnJ1cHQgPSBzZWxlY3Rpb25faW50ZXJydXB0
OwpzZWxlY3Rpb24ucHJvdG90eXBlLnRyYW5zaXRpb24gPSBzZWxlY3Rpb25fdHJhbnNpdGlvbjsK
CnZhciByb290JDEgPSBbbnVsbF07CgpmdW5jdGlvbiBhY3RpdmUobm9kZSwgbmFtZSkgewogIHZh
ciBzY2hlZHVsZXMgPSBub2RlLl9fdHJhbnNpdGlvbiwKICAgICAgc2NoZWR1bGUsCiAgICAgIGk7
CgogIGlmIChzY2hlZHVsZXMpIHsKICAgIG5hbWUgPSBuYW1lID09IG51bGwgPyBudWxsIDogbmFt
ZSArICIiOwogICAgZm9yIChpIGluIHNjaGVkdWxlcykgewogICAgICBpZiAoKHNjaGVkdWxlID0g
c2NoZWR1bGVzW2ldKS5zdGF0ZSA+IFNDSEVEVUxFRCAmJiBzY2hlZHVsZS5uYW1lID09PSBuYW1l
KSB7CiAgICAgICAgcmV0dXJuIG5ldyBUcmFuc2l0aW9uKFtbbm9kZV1dLCByb290JDEsIG5hbWUs
ICtpKTsKICAgICAgfQogICAgfQogIH0KCiAgcmV0dXJuIG51bGw7Cn0KCmZ1bmN0aW9uIGNvbnN0
YW50JDQoeCkgewogIHJldHVybiBmdW5jdGlvbigpIHsKICAgIHJldHVybiB4OwogIH07Cn0KCmZ1
bmN0aW9uIEJydXNoRXZlbnQodGFyZ2V0LCB0eXBlLCBzZWxlY3Rpb24pIHsKICB0aGlzLnRhcmdl
dCA9IHRhcmdldDsKICB0aGlzLnR5cGUgPSB0eXBlOwogIHRoaXMuc2VsZWN0aW9uID0gc2VsZWN0
aW9uOwp9CgpmdW5jdGlvbiBub3Byb3BhZ2F0aW9uJDEoKSB7CiAgZXhwb3J0cy5ldmVudC5zdG9w
SW1tZWRpYXRlUHJvcGFnYXRpb24oKTsKfQoKZnVuY3Rpb24gbm9ldmVudCQxKCkgewogIGV4cG9y
dHMuZXZlbnQucHJldmVudERlZmF1bHQoKTsKICBleHBvcnRzLmV2ZW50LnN0b3BJbW1lZGlhdGVQ
cm9wYWdhdGlvbigpOwp9Cgp2YXIgTU9ERV9EUkFHID0ge25hbWU6ICJkcmFnIn0sCiAgICBNT0RF
X1NQQUNFID0ge25hbWU6ICJzcGFjZSJ9LAogICAgTU9ERV9IQU5ETEUgPSB7bmFtZTogImhhbmRs
ZSJ9LAogICAgTU9ERV9DRU5URVIgPSB7bmFtZTogImNlbnRlciJ9OwoKZnVuY3Rpb24gbnVtYmVy
MShlKSB7CiAgcmV0dXJuIFsrZVswXSwgK2VbMV1dOwp9CgpmdW5jdGlvbiBudW1iZXIyKGUpIHsK
ICByZXR1cm4gW251bWJlcjEoZVswXSksIG51bWJlcjEoZVsxXSldOwp9CgpmdW5jdGlvbiB0b3Vj
aGVyKGlkZW50aWZpZXIpIHsKICByZXR1cm4gZnVuY3Rpb24odGFyZ2V0KSB7CiAgICByZXR1cm4g
dG91Y2godGFyZ2V0LCBleHBvcnRzLmV2ZW50LnRvdWNoZXMsIGlkZW50aWZpZXIpOwogIH07Cn0K
CnZhciBYID0gewogIG5hbWU6ICJ4IiwKICBoYW5kbGVzOiBbInciLCAiZSJdLm1hcCh0eXBlKSwK
ICBpbnB1dDogZnVuY3Rpb24oeCwgZSkgeyByZXR1cm4geCA9PSBudWxsID8gbnVsbCA6IFtbK3hb
MF0sIGVbMF1bMV1dLCBbK3hbMV0sIGVbMV1bMV1dXTsgfSwKICBvdXRwdXQ6IGZ1bmN0aW9uKHh5
KSB7IHJldHVybiB4eSAmJiBbeHlbMF1bMF0sIHh5WzFdWzBdXTsgfQp9OwoKdmFyIFkgPSB7CiAg
bmFtZTogInkiLAogIGhhbmRsZXM6IFsibiIsICJzIl0ubWFwKHR5cGUpLAogIGlucHV0OiBmdW5j
dGlvbih5LCBlKSB7IHJldHVybiB5ID09IG51bGwgPyBudWxsIDogW1tlWzBdWzBdLCAreVswXV0s
IFtlWzFdWzBdLCAreVsxXV1dOyB9LAogIG91dHB1dDogZnVuY3Rpb24oeHkpIHsgcmV0dXJuIHh5
ICYmIFt4eVswXVsxXSwgeHlbMV1bMV1dOyB9Cn07Cgp2YXIgWFkgPSB7CiAgbmFtZTogInh5IiwK
ICBoYW5kbGVzOiBbIm4iLCAidyIsICJlIiwgInMiLCAibnciLCAibmUiLCAic3ciLCAic2UiXS5t
YXAodHlwZSksCiAgaW5wdXQ6IGZ1bmN0aW9uKHh5KSB7IHJldHVybiB4eSA9PSBudWxsID8gbnVs
bCA6IG51bWJlcjIoeHkpOyB9LAogIG91dHB1dDogZnVuY3Rpb24oeHkpIHsgcmV0dXJuIHh5OyB9
Cn07Cgp2YXIgY3Vyc29ycyA9IHsKICBvdmVybGF5OiAiY3Jvc3NoYWlyIiwKICBzZWxlY3Rpb246
ICJtb3ZlIiwKICBuOiAibnMtcmVzaXplIiwKICBlOiAiZXctcmVzaXplIiwKICBzOiAibnMtcmVz
aXplIiwKICB3OiAiZXctcmVzaXplIiwKICBudzogIm53c2UtcmVzaXplIiwKICBuZTogIm5lc3ct
cmVzaXplIiwKICBzZTogIm53c2UtcmVzaXplIiwKICBzdzogIm5lc3ctcmVzaXplIgp9OwoKdmFy
IGZsaXBYID0gewogIGU6ICJ3IiwKICB3OiAiZSIsCiAgbnc6ICJuZSIsCiAgbmU6ICJudyIsCiAg
c2U6ICJzdyIsCiAgc3c6ICJzZSIKfTsKCnZhciBmbGlwWSA9IHsKICBuOiAicyIsCiAgczogIm4i
LAogIG53OiAic3ciLAogIG5lOiAic2UiLAogIHNlOiAibmUiLAogIHN3OiAibnciCn07Cgp2YXIg
c2lnbnNYID0gewogIG92ZXJsYXk6ICsxLAogIHNlbGVjdGlvbjogKzEsCiAgbjogbnVsbCwKICBl
OiArMSwKICBzOiBudWxsLAogIHc6IC0xLAogIG53OiAtMSwKICBuZTogKzEsCiAgc2U6ICsxLAog
IHN3OiAtMQp9OwoKdmFyIHNpZ25zWSA9IHsKICBvdmVybGF5OiArMSwKICBzZWxlY3Rpb246ICsx
LAogIG46IC0xLAogIGU6IG51bGwsCiAgczogKzEsCiAgdzogbnVsbCwKICBudzogLTEsCiAgbmU6
IC0xLAogIHNlOiArMSwKICBzdzogKzEKfTsKCmZ1bmN0aW9uIHR5cGUodCkgewogIHJldHVybiB7
dHlwZTogdH07Cn0KCi8vIElnbm9yZSByaWdodC1jbGljaywgc2luY2UgdGhhdCBzaG91bGQgb3Bl
biB0aGUgY29udGV4dCBtZW51LgpmdW5jdGlvbiBkZWZhdWx0RmlsdGVyJDEoKSB7CiAgcmV0dXJu
ICFleHBvcnRzLmV2ZW50LmN0cmxLZXkgJiYgIWV4cG9ydHMuZXZlbnQuYnV0dG9uOwp9CgpmdW5j
dGlvbiBkZWZhdWx0RXh0ZW50KCkgewogIHZhciBzdmcgPSB0aGlzLm93bmVyU1ZHRWxlbWVudCB8
fCB0aGlzOwogIGlmIChzdmcuaGFzQXR0cmlidXRlKCJ2aWV3Qm94IikpIHsKICAgIHN2ZyA9IHN2
Zy52aWV3Qm94LmJhc2VWYWw7CiAgICByZXR1cm4gW1tzdmcueCwgc3ZnLnldLCBbc3ZnLnggKyBz
dmcud2lkdGgsIHN2Zy55ICsgc3ZnLmhlaWdodF1dOwogIH0KICByZXR1cm4gW1swLCAwXSwgW3N2
Zy53aWR0aC5iYXNlVmFsLnZhbHVlLCBzdmcuaGVpZ2h0LmJhc2VWYWwudmFsdWVdXTsKfQoKZnVu
Y3Rpb24gZGVmYXVsdFRvdWNoYWJsZSQxKCkgewogIHJldHVybiBuYXZpZ2F0b3IubWF4VG91Y2hQ
b2ludHMgfHwgKCJvbnRvdWNoc3RhcnQiIGluIHRoaXMpOwp9CgovLyBMaWtlIGQzLmxvY2FsLCBi
dXQgd2l0aCB0aGUgbmFtZSDigJxfX2JydXNo4oCdIHJhdGhlciB0aGFuIGF1dG8tZ2VuZXJhdGVk
LgpmdW5jdGlvbiBsb2NhbCQxKG5vZGUpIHsKICB3aGlsZSAoIW5vZGUuX19icnVzaCkgaWYgKCEo
bm9kZSA9IG5vZGUucGFyZW50Tm9kZSkpIHJldHVybjsKICByZXR1cm4gbm9kZS5fX2JydXNoOwp9
CgpmdW5jdGlvbiBlbXB0eSQxKGV4dGVudCkgewogIHJldHVybiBleHRlbnRbMF1bMF0gPT09IGV4
dGVudFsxXVswXQogICAgICB8fCBleHRlbnRbMF1bMV0gPT09IGV4dGVudFsxXVsxXTsKfQoKZnVu
Y3Rpb24gYnJ1c2hTZWxlY3Rpb24obm9kZSkgewogIHZhciBzdGF0ZSA9IG5vZGUuX19icnVzaDsK
ICByZXR1cm4gc3RhdGUgPyBzdGF0ZS5kaW0ub3V0cHV0KHN0YXRlLnNlbGVjdGlvbikgOiBudWxs
Owp9CgpmdW5jdGlvbiBicnVzaFgoKSB7CiAgcmV0dXJuIGJydXNoJDEoWCk7Cn0KCmZ1bmN0aW9u
IGJydXNoWSgpIHsKICByZXR1cm4gYnJ1c2gkMShZKTsKfQoKZnVuY3Rpb24gYnJ1c2goKSB7CiAg
cmV0dXJuIGJydXNoJDEoWFkpOwp9CgpmdW5jdGlvbiBicnVzaCQxKGRpbSkgewogIHZhciBleHRl
bnQgPSBkZWZhdWx0RXh0ZW50LAogICAgICBmaWx0ZXIgPSBkZWZhdWx0RmlsdGVyJDEsCiAgICAg
IHRvdWNoYWJsZSA9IGRlZmF1bHRUb3VjaGFibGUkMSwKICAgICAga2V5cyA9IHRydWUsCiAgICAg
IGxpc3RlbmVycyA9IGRpc3BhdGNoKCJzdGFydCIsICJicnVzaCIsICJlbmQiKSwKICAgICAgaGFu
ZGxlU2l6ZSA9IDYsCiAgICAgIHRvdWNoZW5kaW5nOwoKICBmdW5jdGlvbiBicnVzaChncm91cCkg
ewogICAgdmFyIG92ZXJsYXkgPSBncm91cAogICAgICAgIC5wcm9wZXJ0eSgiX19icnVzaCIsIGlu
aXRpYWxpemUpCiAgICAgIC5zZWxlY3RBbGwoIi5vdmVybGF5IikKICAgICAgLmRhdGEoW3R5cGUo
Im92ZXJsYXkiKV0pOwoKICAgIG92ZXJsYXkuZW50ZXIoKS5hcHBlbmQoInJlY3QiKQogICAgICAg
IC5hdHRyKCJjbGFzcyIsICJvdmVybGF5IikKICAgICAgICAuYXR0cigicG9pbnRlci1ldmVudHMi
LCAiYWxsIikKICAgICAgICAuYXR0cigiY3Vyc29yIiwgY3Vyc29ycy5vdmVybGF5KQogICAgICAu
bWVyZ2Uob3ZlcmxheSkKICAgICAgICAuZWFjaChmdW5jdGlvbigpIHsKICAgICAgICAgIHZhciBl
eHRlbnQgPSBsb2NhbCQxKHRoaXMpLmV4dGVudDsKICAgICAgICAgIHNlbGVjdCh0aGlzKQogICAg
ICAgICAgICAgIC5hdHRyKCJ4IiwgZXh0ZW50WzBdWzBdKQogICAgICAgICAgICAgIC5hdHRyKCJ5
IiwgZXh0ZW50WzBdWzFdKQogICAgICAgICAgICAgIC5hdHRyKCJ3aWR0aCIsIGV4dGVudFsxXVsw
XSAtIGV4dGVudFswXVswXSkKICAgICAgICAgICAgICAuYXR0cigiaGVpZ2h0IiwgZXh0ZW50WzFd
WzFdIC0gZXh0ZW50WzBdWzFdKTsKICAgICAgICB9KTsKCiAgICBncm91cC5zZWxlY3RBbGwoIi5z
ZWxlY3Rpb24iKQogICAgICAuZGF0YShbdHlwZSgic2VsZWN0aW9uIildKQogICAgICAuZW50ZXIo
KS5hcHBlbmQoInJlY3QiKQogICAgICAgIC5hdHRyKCJjbGFzcyIsICJzZWxlY3Rpb24iKQogICAg
ICAgIC5hdHRyKCJjdXJzb3IiLCBjdXJzb3JzLnNlbGVjdGlvbikKICAgICAgICAuYXR0cigiZmls
bCIsICIjNzc3IikKICAgICAgICAuYXR0cigiZmlsbC1vcGFjaXR5IiwgMC4zKQogICAgICAgIC5h
dHRyKCJzdHJva2UiLCAiI2ZmZiIpCiAgICAgICAgLmF0dHIoInNoYXBlLXJlbmRlcmluZyIsICJj
cmlzcEVkZ2VzIik7CgogICAgdmFyIGhhbmRsZSA9IGdyb3VwLnNlbGVjdEFsbCgiLmhhbmRsZSIp
CiAgICAgIC5kYXRhKGRpbS5oYW5kbGVzLCBmdW5jdGlvbihkKSB7IHJldHVybiBkLnR5cGU7IH0p
OwoKICAgIGhhbmRsZS5leGl0KCkucmVtb3ZlKCk7CgogICAgaGFuZGxlLmVudGVyKCkuYXBwZW5k
KCJyZWN0IikKICAgICAgICAuYXR0cigiY2xhc3MiLCBmdW5jdGlvbihkKSB7IHJldHVybiAiaGFu
ZGxlIGhhbmRsZS0tIiArIGQudHlwZTsgfSkKICAgICAgICAuYXR0cigiY3Vyc29yIiwgZnVuY3Rp
b24oZCkgeyByZXR1cm4gY3Vyc29yc1tkLnR5cGVdOyB9KTsKCiAgICBncm91cAogICAgICAgIC5l
YWNoKHJlZHJhdykKICAgICAgICAuYXR0cigiZmlsbCIsICJub25lIikKICAgICAgICAuYXR0cigi
cG9pbnRlci1ldmVudHMiLCAiYWxsIikKICAgICAgICAub24oIm1vdXNlZG93bi5icnVzaCIsIHN0
YXJ0ZWQpCiAgICAgIC5maWx0ZXIodG91Y2hhYmxlKQogICAgICAgIC5vbigidG91Y2hzdGFydC5i
cnVzaCIsIHN0YXJ0ZWQpCiAgICAgICAgLm9uKCJ0b3VjaG1vdmUuYnJ1c2giLCB0b3VjaG1vdmVk
KQogICAgICAgIC5vbigidG91Y2hlbmQuYnJ1c2ggdG91Y2hjYW5jZWwuYnJ1c2giLCB0b3VjaGVu
ZGVkKQogICAgICAgIC5zdHlsZSgidG91Y2gtYWN0aW9uIiwgIm5vbmUiKQogICAgICAgIC5zdHls
ZSgiLXdlYmtpdC10YXAtaGlnaGxpZ2h0LWNvbG9yIiwgInJnYmEoMCwwLDAsMCkiKTsKICB9Cgog
IGJydXNoLm1vdmUgPSBmdW5jdGlvbihncm91cCwgc2VsZWN0aW9uKSB7CiAgICBpZiAoZ3JvdXAu
c2VsZWN0aW9uKSB7CiAgICAgIGdyb3VwCiAgICAgICAgICAub24oInN0YXJ0LmJydXNoIiwgZnVu
Y3Rpb24oKSB7IGVtaXR0ZXIodGhpcywgYXJndW1lbnRzKS5iZWZvcmVzdGFydCgpLnN0YXJ0KCk7
IH0pCiAgICAgICAgICAub24oImludGVycnVwdC5icnVzaCBlbmQuYnJ1c2giLCBmdW5jdGlvbigp
IHsgZW1pdHRlcih0aGlzLCBhcmd1bWVudHMpLmVuZCgpOyB9KQogICAgICAgICAgLnR3ZWVuKCJi
cnVzaCIsIGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXMsCiAgICAgICAg
ICAgICAgICBzdGF0ZSA9IHRoYXQuX19icnVzaCwKICAgICAgICAgICAgICAgIGVtaXQgPSBlbWl0
dGVyKHRoYXQsIGFyZ3VtZW50cyksCiAgICAgICAgICAgICAgICBzZWxlY3Rpb24wID0gc3RhdGUu
c2VsZWN0aW9uLAogICAgICAgICAgICAgICAgc2VsZWN0aW9uMSA9IGRpbS5pbnB1dCh0eXBlb2Yg
c2VsZWN0aW9uID09PSAiZnVuY3Rpb24iID8gc2VsZWN0aW9uLmFwcGx5KHRoaXMsIGFyZ3VtZW50
cykgOiBzZWxlY3Rpb24sIHN0YXRlLmV4dGVudCksCiAgICAgICAgICAgICAgICBpID0gaW50ZXJw
b2xhdGVWYWx1ZShzZWxlY3Rpb24wLCBzZWxlY3Rpb24xKTsKCiAgICAgICAgICAgIGZ1bmN0aW9u
IHR3ZWVuKHQpIHsKICAgICAgICAgICAgICBzdGF0ZS5zZWxlY3Rpb24gPSB0ID09PSAxICYmIHNl
bGVjdGlvbjEgPT09IG51bGwgPyBudWxsIDogaSh0KTsKICAgICAgICAgICAgICByZWRyYXcuY2Fs
bCh0aGF0KTsKICAgICAgICAgICAgICBlbWl0LmJydXNoKCk7CiAgICAgICAgICAgIH0KCiAgICAg
ICAgICAgIHJldHVybiBzZWxlY3Rpb24wICE9PSBudWxsICYmIHNlbGVjdGlvbjEgIT09IG51bGwg
PyB0d2VlbiA6IHR3ZWVuKDEpOwogICAgICAgICAgfSk7CiAgICB9IGVsc2UgewogICAgICBncm91
cAogICAgICAgICAgLmVhY2goZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciB0aGF0ID0gdGhp
cywKICAgICAgICAgICAgICAgIGFyZ3MgPSBhcmd1bWVudHMsCiAgICAgICAgICAgICAgICBzdGF0
ZSA9IHRoYXQuX19icnVzaCwKICAgICAgICAgICAgICAgIHNlbGVjdGlvbjEgPSBkaW0uaW5wdXQo
dHlwZW9mIHNlbGVjdGlvbiA9PT0gImZ1bmN0aW9uIiA/IHNlbGVjdGlvbi5hcHBseSh0aGF0LCBh
cmdzKSA6IHNlbGVjdGlvbiwgc3RhdGUuZXh0ZW50KSwKICAgICAgICAgICAgICAgIGVtaXQgPSBl
bWl0dGVyKHRoYXQsIGFyZ3MpLmJlZm9yZXN0YXJ0KCk7CgogICAgICAgICAgICBpbnRlcnJ1cHQo
dGhhdCk7CiAgICAgICAgICAgIHN0YXRlLnNlbGVjdGlvbiA9IHNlbGVjdGlvbjEgPT09IG51bGwg
PyBudWxsIDogc2VsZWN0aW9uMTsKICAgICAgICAgICAgcmVkcmF3LmNhbGwodGhhdCk7CiAgICAg
ICAgICAgIGVtaXQuc3RhcnQoKS5icnVzaCgpLmVuZCgpOwogICAgICAgICAgfSk7CiAgICB9CiAg
fTsKCiAgYnJ1c2guY2xlYXIgPSBmdW5jdGlvbihncm91cCkgewogICAgYnJ1c2gubW92ZShncm91
cCwgbnVsbCk7CiAgfTsKCiAgZnVuY3Rpb24gcmVkcmF3KCkgewogICAgdmFyIGdyb3VwID0gc2Vs
ZWN0KHRoaXMpLAogICAgICAgIHNlbGVjdGlvbiA9IGxvY2FsJDEodGhpcykuc2VsZWN0aW9uOwoK
ICAgIGlmIChzZWxlY3Rpb24pIHsKICAgICAgZ3JvdXAuc2VsZWN0QWxsKCIuc2VsZWN0aW9uIikK
ICAgICAgICAgIC5zdHlsZSgiZGlzcGxheSIsIG51bGwpCiAgICAgICAgICAuYXR0cigieCIsIHNl
bGVjdGlvblswXVswXSkKICAgICAgICAgIC5hdHRyKCJ5Iiwgc2VsZWN0aW9uWzBdWzFdKQogICAg
ICAgICAgLmF0dHIoIndpZHRoIiwgc2VsZWN0aW9uWzFdWzBdIC0gc2VsZWN0aW9uWzBdWzBdKQog
ICAgICAgICAgLmF0dHIoImhlaWdodCIsIHNlbGVjdGlvblsxXVsxXSAtIHNlbGVjdGlvblswXVsx
XSk7CgogICAgICBncm91cC5zZWxlY3RBbGwoIi5oYW5kbGUiKQogICAgICAgICAgLnN0eWxlKCJk
aXNwbGF5IiwgbnVsbCkKICAgICAgICAgIC5hdHRyKCJ4IiwgZnVuY3Rpb24oZCkgeyByZXR1cm4g
ZC50eXBlW2QudHlwZS5sZW5ndGggLSAxXSA9PT0gImUiID8gc2VsZWN0aW9uWzFdWzBdIC0gaGFu
ZGxlU2l6ZSAvIDIgOiBzZWxlY3Rpb25bMF1bMF0gLSBoYW5kbGVTaXplIC8gMjsgfSkKICAgICAg
ICAgIC5hdHRyKCJ5IiwgZnVuY3Rpb24oZCkgeyByZXR1cm4gZC50eXBlWzBdID09PSAicyIgPyBz
ZWxlY3Rpb25bMV1bMV0gLSBoYW5kbGVTaXplIC8gMiA6IHNlbGVjdGlvblswXVsxXSAtIGhhbmRs
ZVNpemUgLyAyOyB9KQogICAgICAgICAgLmF0dHIoIndpZHRoIiwgZnVuY3Rpb24oZCkgeyByZXR1
cm4gZC50eXBlID09PSAibiIgfHwgZC50eXBlID09PSAicyIgPyBzZWxlY3Rpb25bMV1bMF0gLSBz
ZWxlY3Rpb25bMF1bMF0gKyBoYW5kbGVTaXplIDogaGFuZGxlU2l6ZTsgfSkKICAgICAgICAgIC5h
dHRyKCJoZWlnaHQiLCBmdW5jdGlvbihkKSB7IHJldHVybiBkLnR5cGUgPT09ICJlIiB8fCBkLnR5
cGUgPT09ICJ3IiA/IHNlbGVjdGlvblsxXVsxXSAtIHNlbGVjdGlvblswXVsxXSArIGhhbmRsZVNp
emUgOiBoYW5kbGVTaXplOyB9KTsKICAgIH0KCiAgICBlbHNlIHsKICAgICAgZ3JvdXAuc2VsZWN0
QWxsKCIuc2VsZWN0aW9uLC5oYW5kbGUiKQogICAgICAgICAgLnN0eWxlKCJkaXNwbGF5IiwgIm5v
bmUiKQogICAgICAgICAgLmF0dHIoIngiLCBudWxsKQogICAgICAgICAgLmF0dHIoInkiLCBudWxs
KQogICAgICAgICAgLmF0dHIoIndpZHRoIiwgbnVsbCkKICAgICAgICAgIC5hdHRyKCJoZWlnaHQi
LCBudWxsKTsKICAgIH0KICB9CgogIGZ1bmN0aW9uIGVtaXR0ZXIodGhhdCwgYXJncywgY2xlYW4p
IHsKICAgIHJldHVybiAoIWNsZWFuICYmIHRoYXQuX19icnVzaC5lbWl0dGVyKSB8fCBuZXcgRW1p
dHRlcih0aGF0LCBhcmdzKTsKICB9CgogIGZ1bmN0aW9uIEVtaXR0ZXIodGhhdCwgYXJncykgewog
ICAgdGhpcy50aGF0ID0gdGhhdDsKICAgIHRoaXMuYXJncyA9IGFyZ3M7CiAgICB0aGlzLnN0YXRl
ID0gdGhhdC5fX2JydXNoOwogICAgdGhpcy5hY3RpdmUgPSAwOwogIH0KCiAgRW1pdHRlci5wcm90
b3R5cGUgPSB7CiAgICBiZWZvcmVzdGFydDogZnVuY3Rpb24oKSB7CiAgICAgIGlmICgrK3RoaXMu
YWN0aXZlID09PSAxKSB0aGlzLnN0YXRlLmVtaXR0ZXIgPSB0aGlzLCB0aGlzLnN0YXJ0aW5nID0g
dHJ1ZTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9LAogICAgc3RhcnQ6IGZ1bmN0aW9uKCkgewog
ICAgICBpZiAodGhpcy5zdGFydGluZykgdGhpcy5zdGFydGluZyA9IGZhbHNlLCB0aGlzLmVtaXQo
InN0YXJ0Iik7CiAgICAgIGVsc2UgdGhpcy5lbWl0KCJicnVzaCIpOwogICAgICByZXR1cm4gdGhp
czsKICAgIH0sCiAgICBicnVzaDogZnVuY3Rpb24oKSB7CiAgICAgIHRoaXMuZW1pdCgiYnJ1c2gi
KTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9LAogICAgZW5kOiBmdW5jdGlvbigpIHsKICAgICAg
aWYgKC0tdGhpcy5hY3RpdmUgPT09IDApIGRlbGV0ZSB0aGlzLnN0YXRlLmVtaXR0ZXIsIHRoaXMu
ZW1pdCgiZW5kIik7CiAgICAgIHJldHVybiB0aGlzOwogICAgfSwKICAgIGVtaXQ6IGZ1bmN0aW9u
KHR5cGUpIHsKICAgICAgY3VzdG9tRXZlbnQobmV3IEJydXNoRXZlbnQoYnJ1c2gsIHR5cGUsIGRp
bS5vdXRwdXQodGhpcy5zdGF0ZS5zZWxlY3Rpb24pKSwgbGlzdGVuZXJzLmFwcGx5LCBsaXN0ZW5l
cnMsIFt0eXBlLCB0aGlzLnRoYXQsIHRoaXMuYXJnc10pOwogICAgfQogIH07CgogIGZ1bmN0aW9u
IHN0YXJ0ZWQoKSB7CiAgICBpZiAodG91Y2hlbmRpbmcgJiYgIWV4cG9ydHMuZXZlbnQudG91Y2hl
cykgcmV0dXJuOwogICAgaWYgKCFmaWx0ZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSkgcmV0dXJu
OwoKICAgIHZhciB0aGF0ID0gdGhpcywKICAgICAgICB0eXBlID0gZXhwb3J0cy5ldmVudC50YXJn
ZXQuX19kYXRhX18udHlwZSwKICAgICAgICBtb2RlID0gKGtleXMgJiYgZXhwb3J0cy5ldmVudC5t
ZXRhS2V5ID8gdHlwZSA9ICJvdmVybGF5IiA6IHR5cGUpID09PSAic2VsZWN0aW9uIiA/IE1PREVf
RFJBRyA6IChrZXlzICYmIGV4cG9ydHMuZXZlbnQuYWx0S2V5ID8gTU9ERV9DRU5URVIgOiBNT0RF
X0hBTkRMRSksCiAgICAgICAgc2lnblggPSBkaW0gPT09IFkgPyBudWxsIDogc2lnbnNYW3R5cGVd
LAogICAgICAgIHNpZ25ZID0gZGltID09PSBYID8gbnVsbCA6IHNpZ25zWVt0eXBlXSwKICAgICAg
ICBzdGF0ZSA9IGxvY2FsJDEodGhhdCksCiAgICAgICAgZXh0ZW50ID0gc3RhdGUuZXh0ZW50LAog
ICAgICAgIHNlbGVjdGlvbiA9IHN0YXRlLnNlbGVjdGlvbiwKICAgICAgICBXID0gZXh0ZW50WzBd
WzBdLCB3MCwgdzEsCiAgICAgICAgTiA9IGV4dGVudFswXVsxXSwgbjAsIG4xLAogICAgICAgIEUg
PSBleHRlbnRbMV1bMF0sIGUwLCBlMSwKICAgICAgICBTID0gZXh0ZW50WzFdWzFdLCBzMCwgczEs
CiAgICAgICAgZHggPSAwLAogICAgICAgIGR5ID0gMCwKICAgICAgICBtb3ZpbmcsCiAgICAgICAg
c2hpZnRpbmcgPSBzaWduWCAmJiBzaWduWSAmJiBrZXlzICYmIGV4cG9ydHMuZXZlbnQuc2hpZnRL
ZXksCiAgICAgICAgbG9ja1gsCiAgICAgICAgbG9ja1ksCiAgICAgICAgcG9pbnRlciA9IGV4cG9y
dHMuZXZlbnQudG91Y2hlcyA/IHRvdWNoZXIoZXhwb3J0cy5ldmVudC5jaGFuZ2VkVG91Y2hlc1sw
XS5pZGVudGlmaWVyKSA6IG1vdXNlLAogICAgICAgIHBvaW50MCA9IHBvaW50ZXIodGhhdCksCiAg
ICAgICAgcG9pbnQgPSBwb2ludDAsCiAgICAgICAgZW1pdCA9IGVtaXR0ZXIodGhhdCwgYXJndW1l
bnRzLCB0cnVlKS5iZWZvcmVzdGFydCgpOwoKICAgIGlmICh0eXBlID09PSAib3ZlcmxheSIpIHsK
ICAgICAgaWYgKHNlbGVjdGlvbikgbW92aW5nID0gdHJ1ZTsKICAgICAgc3RhdGUuc2VsZWN0aW9u
ID0gc2VsZWN0aW9uID0gWwogICAgICAgIFt3MCA9IGRpbSA9PT0gWSA/IFcgOiBwb2ludDBbMF0s
IG4wID0gZGltID09PSBYID8gTiA6IHBvaW50MFsxXV0sCiAgICAgICAgW2UwID0gZGltID09PSBZ
ID8gRSA6IHcwLCBzMCA9IGRpbSA9PT0gWCA/IFMgOiBuMF0KICAgICAgXTsKICAgIH0gZWxzZSB7
CiAgICAgIHcwID0gc2VsZWN0aW9uWzBdWzBdOwogICAgICBuMCA9IHNlbGVjdGlvblswXVsxXTsK
ICAgICAgZTAgPSBzZWxlY3Rpb25bMV1bMF07CiAgICAgIHMwID0gc2VsZWN0aW9uWzFdWzFdOwog
ICAgfQoKICAgIHcxID0gdzA7CiAgICBuMSA9IG4wOwogICAgZTEgPSBlMDsKICAgIHMxID0gczA7
CgogICAgdmFyIGdyb3VwID0gc2VsZWN0KHRoYXQpCiAgICAgICAgLmF0dHIoInBvaW50ZXItZXZl
bnRzIiwgIm5vbmUiKTsKCiAgICB2YXIgb3ZlcmxheSA9IGdyb3VwLnNlbGVjdEFsbCgiLm92ZXJs
YXkiKQogICAgICAgIC5hdHRyKCJjdXJzb3IiLCBjdXJzb3JzW3R5cGVdKTsKCiAgICBpZiAoZXhw
b3J0cy5ldmVudC50b3VjaGVzKSB7CiAgICAgIGVtaXQubW92ZWQgPSBtb3ZlZDsKICAgICAgZW1p
dC5lbmRlZCA9IGVuZGVkOwogICAgfSBlbHNlIHsKICAgICAgdmFyIHZpZXcgPSBzZWxlY3QoZXhw
b3J0cy5ldmVudC52aWV3KQogICAgICAgICAgLm9uKCJtb3VzZW1vdmUuYnJ1c2giLCBtb3ZlZCwg
dHJ1ZSkKICAgICAgICAgIC5vbigibW91c2V1cC5icnVzaCIsIGVuZGVkLCB0cnVlKTsKICAgICAg
aWYgKGtleXMpIHZpZXcKICAgICAgICAgIC5vbigia2V5ZG93bi5icnVzaCIsIGtleWRvd25lZCwg
dHJ1ZSkKICAgICAgICAgIC5vbigia2V5dXAuYnJ1c2giLCBrZXl1cHBlZCwgdHJ1ZSk7CgogICAg
ICBkcmFnRGlzYWJsZShleHBvcnRzLmV2ZW50LnZpZXcpOwogICAgfQoKICAgIG5vcHJvcGFnYXRp
b24kMSgpOwogICAgaW50ZXJydXB0KHRoYXQpOwogICAgcmVkcmF3LmNhbGwodGhhdCk7CiAgICBl
bWl0LnN0YXJ0KCk7CgogICAgZnVuY3Rpb24gbW92ZWQoKSB7CiAgICAgIHZhciBwb2ludDEgPSBw
b2ludGVyKHRoYXQpOwogICAgICBpZiAoc2hpZnRpbmcgJiYgIWxvY2tYICYmICFsb2NrWSkgewog
ICAgICAgIGlmIChNYXRoLmFicyhwb2ludDFbMF0gLSBwb2ludFswXSkgPiBNYXRoLmFicyhwb2lu
dDFbMV0gLSBwb2ludFsxXSkpIGxvY2tZID0gdHJ1ZTsKICAgICAgICBlbHNlIGxvY2tYID0gdHJ1
ZTsKICAgICAgfQogICAgICBwb2ludCA9IHBvaW50MTsKICAgICAgbW92aW5nID0gdHJ1ZTsKICAg
ICAgbm9ldmVudCQxKCk7CiAgICAgIG1vdmUoKTsKICAgIH0KCiAgICBmdW5jdGlvbiBtb3ZlKCkg
ewogICAgICB2YXIgdDsKCiAgICAgIGR4ID0gcG9pbnRbMF0gLSBwb2ludDBbMF07CiAgICAgIGR5
ID0gcG9pbnRbMV0gLSBwb2ludDBbMV07CgogICAgICBzd2l0Y2ggKG1vZGUpIHsKICAgICAgICBj
YXNlIE1PREVfU1BBQ0U6CiAgICAgICAgY2FzZSBNT0RFX0RSQUc6IHsKICAgICAgICAgIGlmIChz
aWduWCkgZHggPSBNYXRoLm1heChXIC0gdzAsIE1hdGgubWluKEUgLSBlMCwgZHgpKSwgdzEgPSB3
MCArIGR4LCBlMSA9IGUwICsgZHg7CiAgICAgICAgICBpZiAoc2lnblkpIGR5ID0gTWF0aC5tYXgo
TiAtIG4wLCBNYXRoLm1pbihTIC0gczAsIGR5KSksIG4xID0gbjAgKyBkeSwgczEgPSBzMCArIGR5
OwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgTU9ERV9IQU5ETEU6IHsK
ICAgICAgICAgIGlmIChzaWduWCA8IDApIGR4ID0gTWF0aC5tYXgoVyAtIHcwLCBNYXRoLm1pbihF
IC0gdzAsIGR4KSksIHcxID0gdzAgKyBkeCwgZTEgPSBlMDsKICAgICAgICAgIGVsc2UgaWYgKHNp
Z25YID4gMCkgZHggPSBNYXRoLm1heChXIC0gZTAsIE1hdGgubWluKEUgLSBlMCwgZHgpKSwgdzEg
PSB3MCwgZTEgPSBlMCArIGR4OwogICAgICAgICAgaWYgKHNpZ25ZIDwgMCkgZHkgPSBNYXRoLm1h
eChOIC0gbjAsIE1hdGgubWluKFMgLSBuMCwgZHkpKSwgbjEgPSBuMCArIGR5LCBzMSA9IHMwOwog
ICAgICAgICAgZWxzZSBpZiAoc2lnblkgPiAwKSBkeSA9IE1hdGgubWF4KE4gLSBzMCwgTWF0aC5t
aW4oUyAtIHMwLCBkeSkpLCBuMSA9IG4wLCBzMSA9IHMwICsgZHk7CiAgICAgICAgICBicmVhazsK
ICAgICAgICB9CiAgICAgICAgY2FzZSBNT0RFX0NFTlRFUjogewogICAgICAgICAgaWYgKHNpZ25Y
KSB3MSA9IE1hdGgubWF4KFcsIE1hdGgubWluKEUsIHcwIC0gZHggKiBzaWduWCkpLCBlMSA9IE1h
dGgubWF4KFcsIE1hdGgubWluKEUsIGUwICsgZHggKiBzaWduWCkpOwogICAgICAgICAgaWYgKHNp
Z25ZKSBuMSA9IE1hdGgubWF4KE4sIE1hdGgubWluKFMsIG4wIC0gZHkgKiBzaWduWSkpLCBzMSA9
IE1hdGgubWF4KE4sIE1hdGgubWluKFMsIHMwICsgZHkgKiBzaWduWSkpOwogICAgICAgICAgYnJl
YWs7CiAgICAgICAgfQogICAgICB9CgogICAgICBpZiAoZTEgPCB3MSkgewogICAgICAgIHNpZ25Y
ICo9IC0xOwogICAgICAgIHQgPSB3MCwgdzAgPSBlMCwgZTAgPSB0OwogICAgICAgIHQgPSB3MSwg
dzEgPSBlMSwgZTEgPSB0OwogICAgICAgIGlmICh0eXBlIGluIGZsaXBYKSBvdmVybGF5LmF0dHIo
ImN1cnNvciIsIGN1cnNvcnNbdHlwZSA9IGZsaXBYW3R5cGVdXSk7CiAgICAgIH0KCiAgICAgIGlm
IChzMSA8IG4xKSB7CiAgICAgICAgc2lnblkgKj0gLTE7CiAgICAgICAgdCA9IG4wLCBuMCA9IHMw
LCBzMCA9IHQ7CiAgICAgICAgdCA9IG4xLCBuMSA9IHMxLCBzMSA9IHQ7CiAgICAgICAgaWYgKHR5
cGUgaW4gZmxpcFkpIG92ZXJsYXkuYXR0cigiY3Vyc29yIiwgY3Vyc29yc1t0eXBlID0gZmxpcFlb
dHlwZV1dKTsKICAgICAgfQoKICAgICAgaWYgKHN0YXRlLnNlbGVjdGlvbikgc2VsZWN0aW9uID0g
c3RhdGUuc2VsZWN0aW9uOyAvLyBNYXkgYmUgc2V0IGJ5IGJydXNoLm1vdmUhCiAgICAgIGlmIChs
b2NrWCkgdzEgPSBzZWxlY3Rpb25bMF1bMF0sIGUxID0gc2VsZWN0aW9uWzFdWzBdOwogICAgICBp
ZiAobG9ja1kpIG4xID0gc2VsZWN0aW9uWzBdWzFdLCBzMSA9IHNlbGVjdGlvblsxXVsxXTsKCiAg
ICAgIGlmIChzZWxlY3Rpb25bMF1bMF0gIT09IHcxCiAgICAgICAgICB8fCBzZWxlY3Rpb25bMF1b
MV0gIT09IG4xCiAgICAgICAgICB8fCBzZWxlY3Rpb25bMV1bMF0gIT09IGUxCiAgICAgICAgICB8
fCBzZWxlY3Rpb25bMV1bMV0gIT09IHMxKSB7CiAgICAgICAgc3RhdGUuc2VsZWN0aW9uID0gW1t3
MSwgbjFdLCBbZTEsIHMxXV07CiAgICAgICAgcmVkcmF3LmNhbGwodGhhdCk7CiAgICAgICAgZW1p
dC5icnVzaCgpOwogICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gZW5kZWQoKSB7CiAgICAgIG5v
cHJvcGFnYXRpb24kMSgpOwogICAgICBpZiAoZXhwb3J0cy5ldmVudC50b3VjaGVzKSB7CiAgICAg
ICAgaWYgKGV4cG9ydHMuZXZlbnQudG91Y2hlcy5sZW5ndGgpIHJldHVybjsKICAgICAgICBpZiAo
dG91Y2hlbmRpbmcpIGNsZWFyVGltZW91dCh0b3VjaGVuZGluZyk7CiAgICAgICAgdG91Y2hlbmRp
bmcgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgeyB0b3VjaGVuZGluZyA9IG51bGw7IH0sIDUwMCk7
IC8vIEdob3N0IGNsaWNrcyBhcmUgZGVsYXllZCEKICAgICAgfSBlbHNlIHsKICAgICAgICB5ZXNk
cmFnKGV4cG9ydHMuZXZlbnQudmlldywgbW92aW5nKTsKICAgICAgICB2aWV3Lm9uKCJrZXlkb3du
LmJydXNoIGtleXVwLmJydXNoIG1vdXNlbW92ZS5icnVzaCBtb3VzZXVwLmJydXNoIiwgbnVsbCk7
CiAgICAgIH0KICAgICAgZ3JvdXAuYXR0cigicG9pbnRlci1ldmVudHMiLCAiYWxsIik7CiAgICAg
IG92ZXJsYXkuYXR0cigiY3Vyc29yIiwgY3Vyc29ycy5vdmVybGF5KTsKICAgICAgaWYgKHN0YXRl
LnNlbGVjdGlvbikgc2VsZWN0aW9uID0gc3RhdGUuc2VsZWN0aW9uOyAvLyBNYXkgYmUgc2V0IGJ5
IGJydXNoLm1vdmUgKG9uIHN0YXJ0KSEKICAgICAgaWYgKGVtcHR5JDEoc2VsZWN0aW9uKSkgc3Rh
dGUuc2VsZWN0aW9uID0gbnVsbCwgcmVkcmF3LmNhbGwodGhhdCk7CiAgICAgIGVtaXQuZW5kKCk7
CiAgICB9CgogICAgZnVuY3Rpb24ga2V5ZG93bmVkKCkgewogICAgICBzd2l0Y2ggKGV4cG9ydHMu
ZXZlbnQua2V5Q29kZSkgewogICAgICAgIGNhc2UgMTY6IHsgLy8gU0hJRlQKICAgICAgICAgIHNo
aWZ0aW5nID0gc2lnblggJiYgc2lnblk7CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAg
ICAgY2FzZSAxODogeyAvLyBBTFQKICAgICAgICAgIGlmIChtb2RlID09PSBNT0RFX0hBTkRMRSkg
ewogICAgICAgICAgICBpZiAoc2lnblgpIGUwID0gZTEgLSBkeCAqIHNpZ25YLCB3MCA9IHcxICsg
ZHggKiBzaWduWDsKICAgICAgICAgICAgaWYgKHNpZ25ZKSBzMCA9IHMxIC0gZHkgKiBzaWduWSwg
bjAgPSBuMSArIGR5ICogc2lnblk7CiAgICAgICAgICAgIG1vZGUgPSBNT0RFX0NFTlRFUjsKICAg
ICAgICAgICAgbW92ZSgpOwogICAgICAgICAgfQogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQog
ICAgICAgIGNhc2UgMzI6IHsgLy8gU1BBQ0U7IHRha2VzIHByaW9yaXR5IG92ZXIgQUxUCiAgICAg
ICAgICBpZiAobW9kZSA9PT0gTU9ERV9IQU5ETEUgfHwgbW9kZSA9PT0gTU9ERV9DRU5URVIpIHsK
ICAgICAgICAgICAgaWYgKHNpZ25YIDwgMCkgZTAgPSBlMSAtIGR4OyBlbHNlIGlmIChzaWduWCA+
IDApIHcwID0gdzEgLSBkeDsKICAgICAgICAgICAgaWYgKHNpZ25ZIDwgMCkgczAgPSBzMSAtIGR5
OyBlbHNlIGlmIChzaWduWSA+IDApIG4wID0gbjEgLSBkeTsKICAgICAgICAgICAgbW9kZSA9IE1P
REVfU1BBQ0U7CiAgICAgICAgICAgIG92ZXJsYXkuYXR0cigiY3Vyc29yIiwgY3Vyc29ycy5zZWxl
Y3Rpb24pOwogICAgICAgICAgICBtb3ZlKCk7CiAgICAgICAgICB9CiAgICAgICAgICBicmVhazsK
ICAgICAgICB9CiAgICAgICAgZGVmYXVsdDogcmV0dXJuOwogICAgICB9CiAgICAgIG5vZXZlbnQk
MSgpOwogICAgfQoKICAgIGZ1bmN0aW9uIGtleXVwcGVkKCkgewogICAgICBzd2l0Y2ggKGV4cG9y
dHMuZXZlbnQua2V5Q29kZSkgewogICAgICAgIGNhc2UgMTY6IHsgLy8gU0hJRlQKICAgICAgICAg
IGlmIChzaGlmdGluZykgewogICAgICAgICAgICBsb2NrWCA9IGxvY2tZID0gc2hpZnRpbmcgPSBm
YWxzZTsKICAgICAgICAgICAgbW92ZSgpOwogICAgICAgICAgfQogICAgICAgICAgYnJlYWs7CiAg
ICAgICAgfQogICAgICAgIGNhc2UgMTg6IHsgLy8gQUxUCiAgICAgICAgICBpZiAobW9kZSA9PT0g
TU9ERV9DRU5URVIpIHsKICAgICAgICAgICAgaWYgKHNpZ25YIDwgMCkgZTAgPSBlMTsgZWxzZSBp
ZiAoc2lnblggPiAwKSB3MCA9IHcxOwogICAgICAgICAgICBpZiAoc2lnblkgPCAwKSBzMCA9IHMx
OyBlbHNlIGlmIChzaWduWSA+IDApIG4wID0gbjE7CiAgICAgICAgICAgIG1vZGUgPSBNT0RFX0hB
TkRMRTsKICAgICAgICAgICAgbW92ZSgpOwogICAgICAgICAgfQogICAgICAgICAgYnJlYWs7CiAg
ICAgICAgfQogICAgICAgIGNhc2UgMzI6IHsgLy8gU1BBQ0UKICAgICAgICAgIGlmIChtb2RlID09
PSBNT0RFX1NQQUNFKSB7CiAgICAgICAgICAgIGlmIChleHBvcnRzLmV2ZW50LmFsdEtleSkgewog
ICAgICAgICAgICAgIGlmIChzaWduWCkgZTAgPSBlMSAtIGR4ICogc2lnblgsIHcwID0gdzEgKyBk
eCAqIHNpZ25YOwogICAgICAgICAgICAgIGlmIChzaWduWSkgczAgPSBzMSAtIGR5ICogc2lnblks
IG4wID0gbjEgKyBkeSAqIHNpZ25ZOwogICAgICAgICAgICAgIG1vZGUgPSBNT0RFX0NFTlRFUjsK
ICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBpZiAoc2lnblggPCAwKSBlMCA9IGUx
OyBlbHNlIGlmIChzaWduWCA+IDApIHcwID0gdzE7CiAgICAgICAgICAgICAgaWYgKHNpZ25ZIDwg
MCkgczAgPSBzMTsgZWxzZSBpZiAoc2lnblkgPiAwKSBuMCA9IG4xOwogICAgICAgICAgICAgIG1v
ZGUgPSBNT0RFX0hBTkRMRTsKICAgICAgICAgICAgfQogICAgICAgICAgICBvdmVybGF5LmF0dHIo
ImN1cnNvciIsIGN1cnNvcnNbdHlwZV0pOwogICAgICAgICAgICBtb3ZlKCk7CiAgICAgICAgICB9
CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgZGVmYXVsdDogcmV0dXJuOwogICAg
ICB9CiAgICAgIG5vZXZlbnQkMSgpOwogICAgfQogIH0KCiAgZnVuY3Rpb24gdG91Y2htb3ZlZCgp
IHsKICAgIGVtaXR0ZXIodGhpcywgYXJndW1lbnRzKS5tb3ZlZCgpOwogIH0KCiAgZnVuY3Rpb24g
dG91Y2hlbmRlZCgpIHsKICAgIGVtaXR0ZXIodGhpcywgYXJndW1lbnRzKS5lbmRlZCgpOwogIH0K
CiAgZnVuY3Rpb24gaW5pdGlhbGl6ZSgpIHsKICAgIHZhciBzdGF0ZSA9IHRoaXMuX19icnVzaCB8
fCB7c2VsZWN0aW9uOiBudWxsfTsKICAgIHN0YXRlLmV4dGVudCA9IG51bWJlcjIoZXh0ZW50LmFw
cGx5KHRoaXMsIGFyZ3VtZW50cykpOwogICAgc3RhdGUuZGltID0gZGltOwogICAgcmV0dXJuIHN0
YXRlOwogIH0KCiAgYnJ1c2guZXh0ZW50ID0gZnVuY3Rpb24oXykgewogICAgcmV0dXJuIGFyZ3Vt
ZW50cy5sZW5ndGggPyAoZXh0ZW50ID0gdHlwZW9mIF8gPT09ICJmdW5jdGlvbiIgPyBfIDogY29u
c3RhbnQkNChudW1iZXIyKF8pKSwgYnJ1c2gpIDogZXh0ZW50OwogIH07CgogIGJydXNoLmZpbHRl
ciA9IGZ1bmN0aW9uKF8pIHsKICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGZpbHRlciA9
IHR5cGVvZiBfID09PSAiZnVuY3Rpb24iID8gXyA6IGNvbnN0YW50JDQoISFfKSwgYnJ1c2gpIDog
ZmlsdGVyOwogIH07CgogIGJydXNoLnRvdWNoYWJsZSA9IGZ1bmN0aW9uKF8pIHsKICAgIHJldHVy
biBhcmd1bWVudHMubGVuZ3RoID8gKHRvdWNoYWJsZSA9IHR5cGVvZiBfID09PSAiZnVuY3Rpb24i
ID8gXyA6IGNvbnN0YW50JDQoISFfKSwgYnJ1c2gpIDogdG91Y2hhYmxlOwogIH07CgogIGJydXNo
LmhhbmRsZVNpemUgPSBmdW5jdGlvbihfKSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/
IChoYW5kbGVTaXplID0gK18sIGJydXNoKSA6IGhhbmRsZVNpemU7CiAgfTsKCiAgYnJ1c2gua2V5
TW9kaWZpZXJzID0gZnVuY3Rpb24oXykgewogICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAo
a2V5cyA9ICEhXywgYnJ1c2gpIDoga2V5czsKICB9OwoKICBicnVzaC5vbiA9IGZ1bmN0aW9uKCkg
ewogICAgdmFyIHZhbHVlID0gbGlzdGVuZXJzLm9uLmFwcGx5KGxpc3RlbmVycywgYXJndW1lbnRz
KTsKICAgIHJldHVybiB2YWx1ZSA9PT0gbGlzdGVuZXJzID8gYnJ1c2ggOiB2YWx1ZTsKICB9OwoK
ICByZXR1cm4gYnJ1c2g7Cn0KCnZhciBjb3MgPSBNYXRoLmNvczsKdmFyIHNpbiA9IE1hdGguc2lu
Owp2YXIgcGkkMSA9IE1hdGguUEk7CnZhciBoYWxmUGkkMSA9IHBpJDEgLyAyOwp2YXIgdGF1JDEg
PSBwaSQxICogMjsKdmFyIG1heCQxID0gTWF0aC5tYXg7CgpmdW5jdGlvbiBjb21wYXJlVmFsdWUo
Y29tcGFyZSkgewogIHJldHVybiBmdW5jdGlvbihhLCBiKSB7CiAgICByZXR1cm4gY29tcGFyZSgK
ICAgICAgYS5zb3VyY2UudmFsdWUgKyBhLnRhcmdldC52YWx1ZSwKICAgICAgYi5zb3VyY2UudmFs
dWUgKyBiLnRhcmdldC52YWx1ZQogICAgKTsKICB9Owp9CgpmdW5jdGlvbiBjaG9yZCgpIHsKICB2
YXIgcGFkQW5nbGUgPSAwLAogICAgICBzb3J0R3JvdXBzID0gbnVsbCwKICAgICAgc29ydFN1Ymdy
b3VwcyA9IG51bGwsCiAgICAgIHNvcnRDaG9yZHMgPSBudWxsOwoKICBmdW5jdGlvbiBjaG9yZCht
YXRyaXgpIHsKICAgIHZhciBuID0gbWF0cml4Lmxlbmd0aCwKICAgICAgICBncm91cFN1bXMgPSBb
XSwKICAgICAgICBncm91cEluZGV4ID0gc2VxdWVuY2UobiksCiAgICAgICAgc3ViZ3JvdXBJbmRl
eCA9IFtdLAogICAgICAgIGNob3JkcyA9IFtdLAogICAgICAgIGdyb3VwcyA9IGNob3Jkcy5ncm91
cHMgPSBuZXcgQXJyYXkobiksCiAgICAgICAgc3ViZ3JvdXBzID0gbmV3IEFycmF5KG4gKiBuKSwK
ICAgICAgICBrLAogICAgICAgIHgsCiAgICAgICAgeDAsCiAgICAgICAgZHgsCiAgICAgICAgaSwK
ICAgICAgICBqOwoKICAgIC8vIENvbXB1dGUgdGhlIHN1bS4KICAgIGsgPSAwLCBpID0gLTE7IHdo
aWxlICgrK2kgPCBuKSB7CiAgICAgIHggPSAwLCBqID0gLTE7IHdoaWxlICgrK2ogPCBuKSB7CiAg
ICAgICAgeCArPSBtYXRyaXhbaV1bal07CiAgICAgIH0KICAgICAgZ3JvdXBTdW1zLnB1c2goeCk7
CiAgICAgIHN1Ymdyb3VwSW5kZXgucHVzaChzZXF1ZW5jZShuKSk7CiAgICAgIGsgKz0geDsKICAg
IH0KCiAgICAvLyBTb3J0IGdyb3Vwc+KApgogICAgaWYgKHNvcnRHcm91cHMpIGdyb3VwSW5kZXgu
c29ydChmdW5jdGlvbihhLCBiKSB7CiAgICAgIHJldHVybiBzb3J0R3JvdXBzKGdyb3VwU3Vtc1th
XSwgZ3JvdXBTdW1zW2JdKTsKICAgIH0pOwoKICAgIC8vIFNvcnQgc3ViZ3JvdXBz4oCmCiAgICBp
ZiAoc29ydFN1Ymdyb3Vwcykgc3ViZ3JvdXBJbmRleC5mb3JFYWNoKGZ1bmN0aW9uKGQsIGkpIHsK
ICAgICAgZC5zb3J0KGZ1bmN0aW9uKGEsIGIpIHsKICAgICAgICByZXR1cm4gc29ydFN1Ymdyb3Vw
cyhtYXRyaXhbaV1bYV0sIG1hdHJpeFtpXVtiXSk7CiAgICAgIH0pOwogICAgfSk7CgogICAgLy8g
Q29udmVydCB0aGUgc3VtIHRvIHNjYWxpbmcgZmFjdG9yIGZvciBbMCwgMnBpXS4KICAgIC8vIFRP
RE8gQWxsb3cgc3RhcnQgYW5kIGVuZCBhbmdsZSB0byBiZSBzcGVjaWZpZWQ/CiAgICAvLyBUT0RP
IEFsbG93IHBhZGRpbmcgdG8gYmUgc3BlY2lmaWVkIGFzIHBlcmNlbnRhZ2U/CiAgICBrID0gbWF4
JDEoMCwgdGF1JDEgLSBwYWRBbmdsZSAqIG4pIC8gazsKICAgIGR4ID0gayA/IHBhZEFuZ2xlIDog
dGF1JDEgLyBuOwoKICAgIC8vIENvbXB1dGUgdGhlIHN0YXJ0IGFuZCBlbmQgYW5nbGUgZm9yIGVh
Y2ggZ3JvdXAgYW5kIHN1Ymdyb3VwLgogICAgLy8gTm90ZTogT3BlcmEgaGFzIGEgYnVnIHJlb3Jk
ZXJpbmcgb2JqZWN0IGxpdGVyYWwgcHJvcGVydGllcyEKICAgIHggPSAwLCBpID0gLTE7IHdoaWxl
ICgrK2kgPCBuKSB7CiAgICAgIHgwID0geCwgaiA9IC0xOyB3aGlsZSAoKytqIDwgbikgewogICAg
ICAgIHZhciBkaSA9IGdyb3VwSW5kZXhbaV0sCiAgICAgICAgICAgIGRqID0gc3ViZ3JvdXBJbmRl
eFtkaV1bal0sCiAgICAgICAgICAgIHYgPSBtYXRyaXhbZGldW2RqXSwKICAgICAgICAgICAgYTAg
PSB4LAogICAgICAgICAgICBhMSA9IHggKz0gdiAqIGs7CiAgICAgICAgc3ViZ3JvdXBzW2RqICog
biArIGRpXSA9IHsKICAgICAgICAgIGluZGV4OiBkaSwKICAgICAgICAgIHN1YmluZGV4OiBkaiwK
ICAgICAgICAgIHN0YXJ0QW5nbGU6IGEwLAogICAgICAgICAgZW5kQW5nbGU6IGExLAogICAgICAg
ICAgdmFsdWU6IHYKICAgICAgICB9OwogICAgICB9CiAgICAgIGdyb3Vwc1tkaV0gPSB7CiAgICAg
ICAgaW5kZXg6IGRpLAogICAgICAgIHN0YXJ0QW5nbGU6IHgwLAogICAgICAgIGVuZEFuZ2xlOiB4
LAogICAgICAgIHZhbHVlOiBncm91cFN1bXNbZGldCiAgICAgIH07CiAgICAgIHggKz0gZHg7CiAg
ICB9CgogICAgLy8gR2VuZXJhdGUgY2hvcmRzIGZvciBlYWNoIChub24tZW1wdHkpIHN1Ymdyb3Vw
LXN1Ymdyb3VwIGxpbmsuCiAgICBpID0gLTE7IHdoaWxlICgrK2kgPCBuKSB7CiAgICAgIGogPSBp
IC0gMTsgd2hpbGUgKCsraiA8IG4pIHsKICAgICAgICB2YXIgc291cmNlID0gc3ViZ3JvdXBzW2og
KiBuICsgaV0sCiAgICAgICAgICAgIHRhcmdldCA9IHN1Ymdyb3Vwc1tpICogbiArIGpdOwogICAg
ICAgIGlmIChzb3VyY2UudmFsdWUgfHwgdGFyZ2V0LnZhbHVlKSB7CiAgICAgICAgICBjaG9yZHMu
cHVzaChzb3VyY2UudmFsdWUgPCB0YXJnZXQudmFsdWUKICAgICAgICAgICAgICA/IHtzb3VyY2U6
IHRhcmdldCwgdGFyZ2V0OiBzb3VyY2V9CiAgICAgICAgICAgICAgOiB7c291cmNlOiBzb3VyY2Us
IHRhcmdldDogdGFyZ2V0fSk7CiAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgcmV0dXJuIHNv
cnRDaG9yZHMgPyBjaG9yZHMuc29ydChzb3J0Q2hvcmRzKSA6IGNob3JkczsKICB9CgogIGNob3Jk
LnBhZEFuZ2xlID0gZnVuY3Rpb24oXykgewogICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAo
cGFkQW5nbGUgPSBtYXgkMSgwLCBfKSwgY2hvcmQpIDogcGFkQW5nbGU7CiAgfTsKCiAgY2hvcmQu
c29ydEdyb3VwcyA9IGZ1bmN0aW9uKF8pIHsKICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8g
KHNvcnRHcm91cHMgPSBfLCBjaG9yZCkgOiBzb3J0R3JvdXBzOwogIH07CgogIGNob3JkLnNvcnRT
dWJncm91cHMgPSBmdW5jdGlvbihfKSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChz
b3J0U3ViZ3JvdXBzID0gXywgY2hvcmQpIDogc29ydFN1Ymdyb3VwczsKICB9OwoKICBjaG9yZC5z
b3J0Q2hvcmRzID0gZnVuY3Rpb24oXykgewogICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAo
XyA9PSBudWxsID8gc29ydENob3JkcyA9IG51bGwgOiAoc29ydENob3JkcyA9IGNvbXBhcmVWYWx1
ZShfKSkuXyA9IF8sIGNob3JkKSA6IHNvcnRDaG9yZHMgJiYgc29ydENob3Jkcy5fOwogIH07Cgog
IHJldHVybiBjaG9yZDsKfQoKdmFyIHNsaWNlJDIgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7Cgpm
dW5jdGlvbiBjb25zdGFudCQ1KHgpIHsKICByZXR1cm4gZnVuY3Rpb24oKSB7CiAgICByZXR1cm4g
eDsKICB9Owp9Cgp2YXIgcGkkMiA9IE1hdGguUEksCiAgICB0YXUkMiA9IDIgKiBwaSQyLAogICAg
ZXBzaWxvbiQxID0gMWUtNiwKICAgIHRhdUVwc2lsb24gPSB0YXUkMiAtIGVwc2lsb24kMTsKCmZ1
bmN0aW9uIFBhdGgoKSB7CiAgdGhpcy5feDAgPSB0aGlzLl95MCA9IC8vIHN0YXJ0IG9mIGN1cnJl
bnQgc3VicGF0aAogIHRoaXMuX3gxID0gdGhpcy5feTEgPSBudWxsOyAvLyBlbmQgb2YgY3VycmVu
dCBzdWJwYXRoCiAgdGhpcy5fID0gIiI7Cn0KCmZ1bmN0aW9uIHBhdGgoKSB7CiAgcmV0dXJuIG5l
dyBQYXRoOwp9CgpQYXRoLnByb3RvdHlwZSA9IHBhdGgucHJvdG90eXBlID0gewogIGNvbnN0cnVj
dG9yOiBQYXRoLAogIG1vdmVUbzogZnVuY3Rpb24oeCwgeSkgewogICAgdGhpcy5fICs9ICJNIiAr
ICh0aGlzLl94MCA9IHRoaXMuX3gxID0gK3gpICsgIiwiICsgKHRoaXMuX3kwID0gdGhpcy5feTEg
PSAreSk7CiAgfSwKICBjbG9zZVBhdGg6IGZ1bmN0aW9uKCkgewogICAgaWYgKHRoaXMuX3gxICE9
PSBudWxsKSB7CiAgICAgIHRoaXMuX3gxID0gdGhpcy5feDAsIHRoaXMuX3kxID0gdGhpcy5feTA7
CiAgICAgIHRoaXMuXyArPSAiWiI7CiAgICB9CiAgfSwKICBsaW5lVG86IGZ1bmN0aW9uKHgsIHkp
IHsKICAgIHRoaXMuXyArPSAiTCIgKyAodGhpcy5feDEgPSAreCkgKyAiLCIgKyAodGhpcy5feTEg
PSAreSk7CiAgfSwKICBxdWFkcmF0aWNDdXJ2ZVRvOiBmdW5jdGlvbih4MSwgeTEsIHgsIHkpIHsK
ICAgIHRoaXMuXyArPSAiUSIgKyAoK3gxKSArICIsIiArICgreTEpICsgIiwiICsgKHRoaXMuX3gx
ID0gK3gpICsgIiwiICsgKHRoaXMuX3kxID0gK3kpOwogIH0sCiAgYmV6aWVyQ3VydmVUbzogZnVu
Y3Rpb24oeDEsIHkxLCB4MiwgeTIsIHgsIHkpIHsKICAgIHRoaXMuXyArPSAiQyIgKyAoK3gxKSAr
ICIsIiArICgreTEpICsgIiwiICsgKCt4MikgKyAiLCIgKyAoK3kyKSArICIsIiArICh0aGlzLl94
MSA9ICt4KSArICIsIiArICh0aGlzLl95MSA9ICt5KTsKICB9LAogIGFyY1RvOiBmdW5jdGlvbih4
MSwgeTEsIHgyLCB5MiwgcikgewogICAgeDEgPSAreDEsIHkxID0gK3kxLCB4MiA9ICt4MiwgeTIg
PSAreTIsIHIgPSArcjsKICAgIHZhciB4MCA9IHRoaXMuX3gxLAogICAgICAgIHkwID0gdGhpcy5f
eTEsCiAgICAgICAgeDIxID0geDIgLSB4MSwKICAgICAgICB5MjEgPSB5MiAtIHkxLAogICAgICAg
IHgwMSA9IHgwIC0geDEsCiAgICAgICAgeTAxID0geTAgLSB5MSwKICAgICAgICBsMDFfMiA9IHgw
MSAqIHgwMSArIHkwMSAqIHkwMTsKCiAgICAvLyBJcyB0aGUgcmFkaXVzIG5lZ2F0aXZlPyBFcnJv
ci4KICAgIGlmIChyIDwgMCkgdGhyb3cgbmV3IEVycm9yKCJuZWdhdGl2ZSByYWRpdXM6ICIgKyBy
KTsKCiAgICAvLyBJcyB0aGlzIHBhdGggZW1wdHk/IE1vdmUgdG8gKHgxLHkxKS4KICAgIGlmICh0
aGlzLl94MSA9PT0gbnVsbCkgewogICAgICB0aGlzLl8gKz0gIk0iICsgKHRoaXMuX3gxID0geDEp
ICsgIiwiICsgKHRoaXMuX3kxID0geTEpOwogICAgfQoKICAgIC8vIE9yLCBpcyAoeDEseTEpIGNv
aW5jaWRlbnQgd2l0aCAoeDAseTApPyBEbyBub3RoaW5nLgogICAgZWxzZSBpZiAoIShsMDFfMiA+
IGVwc2lsb24kMSkpOwoKICAgIC8vIE9yLCBhcmUgKHgwLHkwKSwgKHgxLHkxKSBhbmQgKHgyLHky
KSBjb2xsaW5lYXI/CiAgICAvLyBFcXVpdmFsZW50bHksIGlzICh4MSx5MSkgY29pbmNpZGVudCB3
aXRoICh4Mix5Mik/CiAgICAvLyBPciwgaXMgdGhlIHJhZGl1cyB6ZXJvPyBMaW5lIHRvICh4MSx5
MSkuCiAgICBlbHNlIGlmICghKE1hdGguYWJzKHkwMSAqIHgyMSAtIHkyMSAqIHgwMSkgPiBlcHNp
bG9uJDEpIHx8ICFyKSB7CiAgICAgIHRoaXMuXyArPSAiTCIgKyAodGhpcy5feDEgPSB4MSkgKyAi
LCIgKyAodGhpcy5feTEgPSB5MSk7CiAgICB9CgogICAgLy8gT3RoZXJ3aXNlLCBkcmF3IGFuIGFy
YyEKICAgIGVsc2UgewogICAgICB2YXIgeDIwID0geDIgLSB4MCwKICAgICAgICAgIHkyMCA9IHky
IC0geTAsCiAgICAgICAgICBsMjFfMiA9IHgyMSAqIHgyMSArIHkyMSAqIHkyMSwKICAgICAgICAg
IGwyMF8yID0geDIwICogeDIwICsgeTIwICogeTIwLAogICAgICAgICAgbDIxID0gTWF0aC5zcXJ0
KGwyMV8yKSwKICAgICAgICAgIGwwMSA9IE1hdGguc3FydChsMDFfMiksCiAgICAgICAgICBsID0g
ciAqIE1hdGgudGFuKChwaSQyIC0gTWF0aC5hY29zKChsMjFfMiArIGwwMV8yIC0gbDIwXzIpIC8g
KDIgKiBsMjEgKiBsMDEpKSkgLyAyKSwKICAgICAgICAgIHQwMSA9IGwgLyBsMDEsCiAgICAgICAg
ICB0MjEgPSBsIC8gbDIxOwoKICAgICAgLy8gSWYgdGhlIHN0YXJ0IHRhbmdlbnQgaXMgbm90IGNv
aW5jaWRlbnQgd2l0aCAoeDAseTApLCBsaW5lIHRvLgogICAgICBpZiAoTWF0aC5hYnModDAxIC0g
MSkgPiBlcHNpbG9uJDEpIHsKICAgICAgICB0aGlzLl8gKz0gIkwiICsgKHgxICsgdDAxICogeDAx
KSArICIsIiArICh5MSArIHQwMSAqIHkwMSk7CiAgICAgIH0KCiAgICAgIHRoaXMuXyArPSAiQSIg
KyByICsgIiwiICsgciArICIsMCwwLCIgKyAoKyh5MDEgKiB4MjAgPiB4MDEgKiB5MjApKSArICIs
IiArICh0aGlzLl94MSA9IHgxICsgdDIxICogeDIxKSArICIsIiArICh0aGlzLl95MSA9IHkxICsg
dDIxICogeTIxKTsKICAgIH0KICB9LAogIGFyYzogZnVuY3Rpb24oeCwgeSwgciwgYTAsIGExLCBj
Y3cpIHsKICAgIHggPSAreCwgeSA9ICt5LCByID0gK3IsIGNjdyA9ICEhY2N3OwogICAgdmFyIGR4
ID0gciAqIE1hdGguY29zKGEwKSwKICAgICAgICBkeSA9IHIgKiBNYXRoLnNpbihhMCksCiAgICAg
ICAgeDAgPSB4ICsgZHgsCiAgICAgICAgeTAgPSB5ICsgZHksCiAgICAgICAgY3cgPSAxIF4gY2N3
LAogICAgICAgIGRhID0gY2N3ID8gYTAgLSBhMSA6IGExIC0gYTA7CgogICAgLy8gSXMgdGhlIHJh
ZGl1cyBuZWdhdGl2ZT8gRXJyb3IuCiAgICBpZiAociA8IDApIHRocm93IG5ldyBFcnJvcigibmVn
YXRpdmUgcmFkaXVzOiAiICsgcik7CgogICAgLy8gSXMgdGhpcyBwYXRoIGVtcHR5PyBNb3ZlIHRv
ICh4MCx5MCkuCiAgICBpZiAodGhpcy5feDEgPT09IG51bGwpIHsKICAgICAgdGhpcy5fICs9ICJN
IiArIHgwICsgIiwiICsgeTA7CiAgICB9CgogICAgLy8gT3IsIGlzICh4MCx5MCkgbm90IGNvaW5j
aWRlbnQgd2l0aCB0aGUgcHJldmlvdXMgcG9pbnQ/IExpbmUgdG8gKHgwLHkwKS4KICAgIGVsc2Ug
aWYgKE1hdGguYWJzKHRoaXMuX3gxIC0geDApID4gZXBzaWxvbiQxIHx8IE1hdGguYWJzKHRoaXMu
X3kxIC0geTApID4gZXBzaWxvbiQxKSB7CiAgICAgIHRoaXMuXyArPSAiTCIgKyB4MCArICIsIiAr
IHkwOwogICAgfQoKICAgIC8vIElzIHRoaXMgYXJjIGVtcHR5PyBXZeKAmXJlIGRvbmUuCiAgICBp
ZiAoIXIpIHJldHVybjsKCiAgICAvLyBEb2VzIHRoZSBhbmdsZSBnbyB0aGUgd3Jvbmcgd2F5PyBG
bGlwIHRoZSBkaXJlY3Rpb24uCiAgICBpZiAoZGEgPCAwKSBkYSA9IGRhICUgdGF1JDIgKyB0YXUk
MjsKCiAgICAvLyBJcyB0aGlzIGEgY29tcGxldGUgY2lyY2xlPyBEcmF3IHR3byBhcmNzIHRvIGNv
bXBsZXRlIHRoZSBjaXJjbGUuCiAgICBpZiAoZGEgPiB0YXVFcHNpbG9uKSB7CiAgICAgIHRoaXMu
XyArPSAiQSIgKyByICsgIiwiICsgciArICIsMCwxLCIgKyBjdyArICIsIiArICh4IC0gZHgpICsg
IiwiICsgKHkgLSBkeSkgKyAiQSIgKyByICsgIiwiICsgciArICIsMCwxLCIgKyBjdyArICIsIiAr
ICh0aGlzLl94MSA9IHgwKSArICIsIiArICh0aGlzLl95MSA9IHkwKTsKICAgIH0KCiAgICAvLyBJ
cyB0aGlzIGFyYyBub24tZW1wdHk/IERyYXcgYW4gYXJjIQogICAgZWxzZSBpZiAoZGEgPiBlcHNp
bG9uJDEpIHsKICAgICAgdGhpcy5fICs9ICJBIiArIHIgKyAiLCIgKyByICsgIiwwLCIgKyAoKyhk
YSA+PSBwaSQyKSkgKyAiLCIgKyBjdyArICIsIiArICh0aGlzLl94MSA9IHggKyByICogTWF0aC5j
b3MoYTEpKSArICIsIiArICh0aGlzLl95MSA9IHkgKyByICogTWF0aC5zaW4oYTEpKTsKICAgIH0K
ICB9LAogIHJlY3Q6IGZ1bmN0aW9uKHgsIHksIHcsIGgpIHsKICAgIHRoaXMuXyArPSAiTSIgKyAo
dGhpcy5feDAgPSB0aGlzLl94MSA9ICt4KSArICIsIiArICh0aGlzLl95MCA9IHRoaXMuX3kxID0g
K3kpICsgImgiICsgKCt3KSArICJ2IiArICgraCkgKyAiaCIgKyAoLXcpICsgIloiOwogIH0sCiAg
dG9TdHJpbmc6IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIHRoaXMuXzsKICB9Cn07CgpmdW5jdGlv
biBkZWZhdWx0U291cmNlKGQpIHsKICByZXR1cm4gZC5zb3VyY2U7Cn0KCmZ1bmN0aW9uIGRlZmF1
bHRUYXJnZXQoZCkgewogIHJldHVybiBkLnRhcmdldDsKfQoKZnVuY3Rpb24gZGVmYXVsdFJhZGl1
cyhkKSB7CiAgcmV0dXJuIGQucmFkaXVzOwp9CgpmdW5jdGlvbiBkZWZhdWx0U3RhcnRBbmdsZShk
KSB7CiAgcmV0dXJuIGQuc3RhcnRBbmdsZTsKfQoKZnVuY3Rpb24gZGVmYXVsdEVuZEFuZ2xlKGQp
IHsKICByZXR1cm4gZC5lbmRBbmdsZTsKfQoKZnVuY3Rpb24gcmliYm9uKCkgewogIHZhciBzb3Vy
Y2UgPSBkZWZhdWx0U291cmNlLAogICAgICB0YXJnZXQgPSBkZWZhdWx0VGFyZ2V0LAogICAgICBy
YWRpdXMgPSBkZWZhdWx0UmFkaXVzLAogICAgICBzdGFydEFuZ2xlID0gZGVmYXVsdFN0YXJ0QW5n
bGUsCiAgICAgIGVuZEFuZ2xlID0gZGVmYXVsdEVuZEFuZ2xlLAogICAgICBjb250ZXh0ID0gbnVs
bDsKCiAgZnVuY3Rpb24gcmliYm9uKCkgewogICAgdmFyIGJ1ZmZlciwKICAgICAgICBhcmd2ID0g
c2xpY2UkMi5jYWxsKGFyZ3VtZW50cyksCiAgICAgICAgcyA9IHNvdXJjZS5hcHBseSh0aGlzLCBh
cmd2KSwKICAgICAgICB0ID0gdGFyZ2V0LmFwcGx5KHRoaXMsIGFyZ3YpLAogICAgICAgIHNyID0g
K3JhZGl1cy5hcHBseSh0aGlzLCAoYXJndlswXSA9IHMsIGFyZ3YpKSwKICAgICAgICBzYTAgPSBz
dGFydEFuZ2xlLmFwcGx5KHRoaXMsIGFyZ3YpIC0gaGFsZlBpJDEsCiAgICAgICAgc2ExID0gZW5k
QW5nbGUuYXBwbHkodGhpcywgYXJndikgLSBoYWxmUGkkMSwKICAgICAgICBzeDAgPSBzciAqIGNv
cyhzYTApLAogICAgICAgIHN5MCA9IHNyICogc2luKHNhMCksCiAgICAgICAgdHIgPSArcmFkaXVz
LmFwcGx5KHRoaXMsIChhcmd2WzBdID0gdCwgYXJndikpLAogICAgICAgIHRhMCA9IHN0YXJ0QW5n
bGUuYXBwbHkodGhpcywgYXJndikgLSBoYWxmUGkkMSwKICAgICAgICB0YTEgPSBlbmRBbmdsZS5h
cHBseSh0aGlzLCBhcmd2KSAtIGhhbGZQaSQxOwoKICAgIGlmICghY29udGV4dCkgY29udGV4dCA9
IGJ1ZmZlciA9IHBhdGgoKTsKCiAgICBjb250ZXh0Lm1vdmVUbyhzeDAsIHN5MCk7CiAgICBjb250
ZXh0LmFyYygwLCAwLCBzciwgc2EwLCBzYTEpOwogICAgaWYgKHNhMCAhPT0gdGEwIHx8IHNhMSAh
PT0gdGExKSB7IC8vIFRPRE8gc3IgIT09IHRyPwogICAgICBjb250ZXh0LnF1YWRyYXRpY0N1cnZl
VG8oMCwgMCwgdHIgKiBjb3ModGEwKSwgdHIgKiBzaW4odGEwKSk7CiAgICAgIGNvbnRleHQuYXJj
KDAsIDAsIHRyLCB0YTAsIHRhMSk7CiAgICB9CiAgICBjb250ZXh0LnF1YWRyYXRpY0N1cnZlVG8o
MCwgMCwgc3gwLCBzeTApOwogICAgY29udGV4dC5jbG9zZVBhdGgoKTsKCiAgICBpZiAoYnVmZmVy
KSByZXR1cm4gY29udGV4dCA9IG51bGwsIGJ1ZmZlciArICIiIHx8IG51bGw7CiAgfQoKICByaWJi
b24ucmFkaXVzID0gZnVuY3Rpb24oXykgewogICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAo
cmFkaXVzID0gdHlwZW9mIF8gPT09ICJmdW5jdGlvbiIgPyBfIDogY29uc3RhbnQkNSgrXyksIHJp
YmJvbikgOiByYWRpdXM7CiAgfTsKCiAgcmliYm9uLnN0YXJ0QW5nbGUgPSBmdW5jdGlvbihfKSB7
CiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChzdGFydEFuZ2xlID0gdHlwZW9mIF8gPT09
ICJmdW5jdGlvbiIgPyBfIDogY29uc3RhbnQkNSgrXyksIHJpYmJvbikgOiBzdGFydEFuZ2xlOwog
IH07CgogIHJpYmJvbi5lbmRBbmdsZSA9IGZ1bmN0aW9uKF8pIHsKICAgIHJldHVybiBhcmd1bWVu
dHMubGVuZ3RoID8gKGVuZEFuZ2xlID0gdHlwZW9mIF8gPT09ICJmdW5jdGlvbiIgPyBfIDogY29u
c3RhbnQkNSgrXyksIHJpYmJvbikgOiBlbmRBbmdsZTsKICB9OwoKICByaWJib24uc291cmNlID0g
ZnVuY3Rpb24oXykgewogICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoc291cmNlID0gXywg
cmliYm9uKSA6IHNvdXJjZTsKICB9OwoKICByaWJib24udGFyZ2V0ID0gZnVuY3Rpb24oXykgewog
ICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAodGFyZ2V0ID0gXywgcmliYm9uKSA6IHRhcmdl
dDsKICB9OwoKICByaWJib24uY29udGV4dCA9IGZ1bmN0aW9uKF8pIHsKICAgIHJldHVybiBhcmd1
bWVudHMubGVuZ3RoID8gKChjb250ZXh0ID0gXyA9PSBudWxsID8gbnVsbCA6IF8pLCByaWJib24p
IDogY29udGV4dDsKICB9OwoKICByZXR1cm4gcmliYm9uOwp9Cgp2YXIgcHJlZml4ID0gIiQiOwoK
ZnVuY3Rpb24gTWFwKCkge30KCk1hcC5wcm90b3R5cGUgPSBtYXAkMS5wcm90b3R5cGUgPSB7CiAg
Y29uc3RydWN0b3I6IE1hcCwKICBoYXM6IGZ1bmN0aW9uKGtleSkgewogICAgcmV0dXJuIChwcmVm
aXggKyBrZXkpIGluIHRoaXM7CiAgfSwKICBnZXQ6IGZ1bmN0aW9uKGtleSkgewogICAgcmV0dXJu
IHRoaXNbcHJlZml4ICsga2V5XTsKICB9LAogIHNldDogZnVuY3Rpb24oa2V5LCB2YWx1ZSkgewog
ICAgdGhpc1twcmVmaXggKyBrZXldID0gdmFsdWU7CiAgICByZXR1cm4gdGhpczsKICB9LAogIHJl
bW92ZTogZnVuY3Rpb24oa2V5KSB7CiAgICB2YXIgcHJvcGVydHkgPSBwcmVmaXggKyBrZXk7CiAg
ICByZXR1cm4gcHJvcGVydHkgaW4gdGhpcyAmJiBkZWxldGUgdGhpc1twcm9wZXJ0eV07CiAgfSwK
ICBjbGVhcjogZnVuY3Rpb24oKSB7CiAgICBmb3IgKHZhciBwcm9wZXJ0eSBpbiB0aGlzKSBpZiAo
cHJvcGVydHlbMF0gPT09IHByZWZpeCkgZGVsZXRlIHRoaXNbcHJvcGVydHldOwogIH0sCiAga2V5
czogZnVuY3Rpb24oKSB7CiAgICB2YXIga2V5cyA9IFtdOwogICAgZm9yICh2YXIgcHJvcGVydHkg
aW4gdGhpcykgaWYgKHByb3BlcnR5WzBdID09PSBwcmVmaXgpIGtleXMucHVzaChwcm9wZXJ0eS5z
bGljZSgxKSk7CiAgICByZXR1cm4ga2V5czsKICB9LAogIHZhbHVlczogZnVuY3Rpb24oKSB7CiAg
ICB2YXIgdmFsdWVzID0gW107CiAgICBmb3IgKHZhciBwcm9wZXJ0eSBpbiB0aGlzKSBpZiAocHJv
cGVydHlbMF0gPT09IHByZWZpeCkgdmFsdWVzLnB1c2godGhpc1twcm9wZXJ0eV0pOwogICAgcmV0
dXJuIHZhbHVlczsKICB9LAogIGVudHJpZXM6IGZ1bmN0aW9uKCkgewogICAgdmFyIGVudHJpZXMg
PSBbXTsKICAgIGZvciAodmFyIHByb3BlcnR5IGluIHRoaXMpIGlmIChwcm9wZXJ0eVswXSA9PT0g
cHJlZml4KSBlbnRyaWVzLnB1c2goe2tleTogcHJvcGVydHkuc2xpY2UoMSksIHZhbHVlOiB0aGlz
W3Byb3BlcnR5XX0pOwogICAgcmV0dXJuIGVudHJpZXM7CiAgfSwKICBzaXplOiBmdW5jdGlvbigp
IHsKICAgIHZhciBzaXplID0gMDsKICAgIGZvciAodmFyIHByb3BlcnR5IGluIHRoaXMpIGlmIChw
cm9wZXJ0eVswXSA9PT0gcHJlZml4KSArK3NpemU7CiAgICByZXR1cm4gc2l6ZTsKICB9LAogIGVt
cHR5OiBmdW5jdGlvbigpIHsKICAgIGZvciAodmFyIHByb3BlcnR5IGluIHRoaXMpIGlmIChwcm9w
ZXJ0eVswXSA9PT0gcHJlZml4KSByZXR1cm4gZmFsc2U7CiAgICByZXR1cm4gdHJ1ZTsKICB9LAog
IGVhY2g6IGZ1bmN0aW9uKGYpIHsKICAgIGZvciAodmFyIHByb3BlcnR5IGluIHRoaXMpIGlmIChw
cm9wZXJ0eVswXSA9PT0gcHJlZml4KSBmKHRoaXNbcHJvcGVydHldLCBwcm9wZXJ0eS5zbGljZSgx
KSwgdGhpcyk7CiAgfQp9OwoKZnVuY3Rpb24gbWFwJDEob2JqZWN0LCBmKSB7CiAgdmFyIG1hcCA9
IG5ldyBNYXA7CgogIC8vIENvcHkgY29uc3RydWN0b3IuCiAgaWYgKG9iamVjdCBpbnN0YW5jZW9m
IE1hcCkgb2JqZWN0LmVhY2goZnVuY3Rpb24odmFsdWUsIGtleSkgeyBtYXAuc2V0KGtleSwgdmFs
dWUpOyB9KTsKCiAgLy8gSW5kZXggYXJyYXkgYnkgbnVtZXJpYyBpbmRleCBvciBzcGVjaWZpZWQg
a2V5IGZ1bmN0aW9uLgogIGVsc2UgaWYgKEFycmF5LmlzQXJyYXkob2JqZWN0KSkgewogICAgdmFy
IGkgPSAtMSwKICAgICAgICBuID0gb2JqZWN0Lmxlbmd0aCwKICAgICAgICBvOwoKICAgIGlmIChm
ID09IG51bGwpIHdoaWxlICgrK2kgPCBuKSBtYXAuc2V0KGksIG9iamVjdFtpXSk7CiAgICBlbHNl
IHdoaWxlICgrK2kgPCBuKSBtYXAuc2V0KGYobyA9IG9iamVjdFtpXSwgaSwgb2JqZWN0KSwgbyk7
CiAgfQoKICAvLyBDb252ZXJ0IG9iamVjdCB0byBtYXAuCiAgZWxzZSBpZiAob2JqZWN0KSBmb3Ig
KHZhciBrZXkgaW4gb2JqZWN0KSBtYXAuc2V0KGtleSwgb2JqZWN0W2tleV0pOwoKICByZXR1cm4g
bWFwOwp9CgpmdW5jdGlvbiBuZXN0KCkgewogIHZhciBrZXlzID0gW10sCiAgICAgIHNvcnRLZXlz
ID0gW10sCiAgICAgIHNvcnRWYWx1ZXMsCiAgICAgIHJvbGx1cCwKICAgICAgbmVzdDsKCiAgZnVu
Y3Rpb24gYXBwbHkoYXJyYXksIGRlcHRoLCBjcmVhdGVSZXN1bHQsIHNldFJlc3VsdCkgewogICAg
aWYgKGRlcHRoID49IGtleXMubGVuZ3RoKSB7CiAgICAgIGlmIChzb3J0VmFsdWVzICE9IG51bGwp
IGFycmF5LnNvcnQoc29ydFZhbHVlcyk7CiAgICAgIHJldHVybiByb2xsdXAgIT0gbnVsbCA/IHJv
bGx1cChhcnJheSkgOiBhcnJheTsKICAgIH0KCiAgICB2YXIgaSA9IC0xLAogICAgICAgIG4gPSBh
cnJheS5sZW5ndGgsCiAgICAgICAga2V5ID0ga2V5c1tkZXB0aCsrXSwKICAgICAgICBrZXlWYWx1
ZSwKICAgICAgICB2YWx1ZSwKICAgICAgICB2YWx1ZXNCeUtleSA9IG1hcCQxKCksCiAgICAgICAg
dmFsdWVzLAogICAgICAgIHJlc3VsdCA9IGNyZWF0ZVJlc3VsdCgpOwoKICAgIHdoaWxlICgrK2kg
PCBuKSB7CiAgICAgIGlmICh2YWx1ZXMgPSB2YWx1ZXNCeUtleS5nZXQoa2V5VmFsdWUgPSBrZXko
dmFsdWUgPSBhcnJheVtpXSkgKyAiIikpIHsKICAgICAgICB2YWx1ZXMucHVzaCh2YWx1ZSk7CiAg
ICAgIH0gZWxzZSB7CiAgICAgICAgdmFsdWVzQnlLZXkuc2V0KGtleVZhbHVlLCBbdmFsdWVdKTsK
ICAgICAgfQogICAgfQoKICAgIHZhbHVlc0J5S2V5LmVhY2goZnVuY3Rpb24odmFsdWVzLCBrZXkp
IHsKICAgICAgc2V0UmVzdWx0KHJlc3VsdCwga2V5LCBhcHBseSh2YWx1ZXMsIGRlcHRoLCBjcmVh
dGVSZXN1bHQsIHNldFJlc3VsdCkpOwogICAgfSk7CgogICAgcmV0dXJuIHJlc3VsdDsKICB9Cgog
IGZ1bmN0aW9uIGVudHJpZXMobWFwLCBkZXB0aCkgewogICAgaWYgKCsrZGVwdGggPiBrZXlzLmxl
bmd0aCkgcmV0dXJuIG1hcDsKICAgIHZhciBhcnJheSwgc29ydEtleSA9IHNvcnRLZXlzW2RlcHRo
IC0gMV07CiAgICBpZiAocm9sbHVwICE9IG51bGwgJiYgZGVwdGggPj0ga2V5cy5sZW5ndGgpIGFy
cmF5ID0gbWFwLmVudHJpZXMoKTsKICAgIGVsc2UgYXJyYXkgPSBbXSwgbWFwLmVhY2goZnVuY3Rp
b24odiwgaykgeyBhcnJheS5wdXNoKHtrZXk6IGssIHZhbHVlczogZW50cmllcyh2LCBkZXB0aCl9
KTsgfSk7CiAgICByZXR1cm4gc29ydEtleSAhPSBudWxsID8gYXJyYXkuc29ydChmdW5jdGlvbihh
LCBiKSB7IHJldHVybiBzb3J0S2V5KGEua2V5LCBiLmtleSk7IH0pIDogYXJyYXk7CiAgfQoKICBy
ZXR1cm4gbmVzdCA9IHsKICAgIG9iamVjdDogZnVuY3Rpb24oYXJyYXkpIHsgcmV0dXJuIGFwcGx5
KGFycmF5LCAwLCBjcmVhdGVPYmplY3QsIHNldE9iamVjdCk7IH0sCiAgICBtYXA6IGZ1bmN0aW9u
KGFycmF5KSB7IHJldHVybiBhcHBseShhcnJheSwgMCwgY3JlYXRlTWFwLCBzZXRNYXApOyB9LAog
ICAgZW50cmllczogZnVuY3Rpb24oYXJyYXkpIHsgcmV0dXJuIGVudHJpZXMoYXBwbHkoYXJyYXks
IDAsIGNyZWF0ZU1hcCwgc2V0TWFwKSwgMCk7IH0sCiAgICBrZXk6IGZ1bmN0aW9uKGQpIHsga2V5
cy5wdXNoKGQpOyByZXR1cm4gbmVzdDsgfSwKICAgIHNvcnRLZXlzOiBmdW5jdGlvbihvcmRlcikg
eyBzb3J0S2V5c1trZXlzLmxlbmd0aCAtIDFdID0gb3JkZXI7IHJldHVybiBuZXN0OyB9LAogICAg
c29ydFZhbHVlczogZnVuY3Rpb24ob3JkZXIpIHsgc29ydFZhbHVlcyA9IG9yZGVyOyByZXR1cm4g
bmVzdDsgfSwKICAgIHJvbGx1cDogZnVuY3Rpb24oZikgeyByb2xsdXAgPSBmOyByZXR1cm4gbmVz
dDsgfQogIH07Cn0KCmZ1bmN0aW9uIGNyZWF0ZU9iamVjdCgpIHsKICByZXR1cm4ge307Cn0KCmZ1
bmN0aW9uIHNldE9iamVjdChvYmplY3QsIGtleSwgdmFsdWUpIHsKICBvYmplY3Rba2V5XSA9IHZh
bHVlOwp9CgpmdW5jdGlvbiBjcmVhdGVNYXAoKSB7CiAgcmV0dXJuIG1hcCQxKCk7Cn0KCmZ1bmN0
aW9uIHNldE1hcChtYXAsIGtleSwgdmFsdWUpIHsKICBtYXAuc2V0KGtleSwgdmFsdWUpOwp9Cgpm
dW5jdGlvbiBTZXQoKSB7fQoKdmFyIHByb3RvID0gbWFwJDEucHJvdG90eXBlOwoKU2V0LnByb3Rv
dHlwZSA9IHNldCQyLnByb3RvdHlwZSA9IHsKICBjb25zdHJ1Y3RvcjogU2V0LAogIGhhczogcHJv
dG8uaGFzLAogIGFkZDogZnVuY3Rpb24odmFsdWUpIHsKICAgIHZhbHVlICs9ICIiOwogICAgdGhp
c1twcmVmaXggKyB2YWx1ZV0gPSB2YWx1ZTsKICAgIHJldHVybiB0aGlzOwogIH0sCiAgcmVtb3Zl
OiBwcm90by5yZW1vdmUsCiAgY2xlYXI6IHByb3RvLmNsZWFyLAogIHZhbHVlczogcHJvdG8ua2V5
cywKICBzaXplOiBwcm90by5zaXplLAogIGVtcHR5OiBwcm90by5lbXB0eSwKICBlYWNoOiBwcm90
by5lYWNoCn07CgpmdW5jdGlvbiBzZXQkMihvYmplY3QsIGYpIHsKICB2YXIgc2V0ID0gbmV3IFNl
dDsKCiAgLy8gQ29weSBjb25zdHJ1Y3Rvci4KICBpZiAob2JqZWN0IGluc3RhbmNlb2YgU2V0KSBv
YmplY3QuZWFjaChmdW5jdGlvbih2YWx1ZSkgeyBzZXQuYWRkKHZhbHVlKTsgfSk7CgogIC8vIE90
aGVyd2lzZSwgYXNzdW1lIGl04oCZcyBhbiBhcnJheS4KICBlbHNlIGlmIChvYmplY3QpIHsKICAg
IHZhciBpID0gLTEsIG4gPSBvYmplY3QubGVuZ3RoOwogICAgaWYgKGYgPT0gbnVsbCkgd2hpbGUg
KCsraSA8IG4pIHNldC5hZGQob2JqZWN0W2ldKTsKICAgIGVsc2Ugd2hpbGUgKCsraSA8IG4pIHNl
dC5hZGQoZihvYmplY3RbaV0sIGksIG9iamVjdCkpOwogIH0KCiAgcmV0dXJuIHNldDsKfQoKZnVu
Y3Rpb24ga2V5cyhtYXApIHsKICB2YXIga2V5cyA9IFtdOwogIGZvciAodmFyIGtleSBpbiBtYXAp
IGtleXMucHVzaChrZXkpOwogIHJldHVybiBrZXlzOwp9CgpmdW5jdGlvbiB2YWx1ZXMobWFwKSB7
CiAgdmFyIHZhbHVlcyA9IFtdOwogIGZvciAodmFyIGtleSBpbiBtYXApIHZhbHVlcy5wdXNoKG1h
cFtrZXldKTsKICByZXR1cm4gdmFsdWVzOwp9CgpmdW5jdGlvbiBlbnRyaWVzKG1hcCkgewogIHZh
ciBlbnRyaWVzID0gW107CiAgZm9yICh2YXIga2V5IGluIG1hcCkgZW50cmllcy5wdXNoKHtrZXk6
IGtleSwgdmFsdWU6IG1hcFtrZXldfSk7CiAgcmV0dXJuIGVudHJpZXM7Cn0KCnZhciBhcnJheSQy
ID0gQXJyYXkucHJvdG90eXBlOwoKdmFyIHNsaWNlJDMgPSBhcnJheSQyLnNsaWNlOwoKZnVuY3Rp
b24gYXNjZW5kaW5nJDIoYSwgYikgewogIHJldHVybiBhIC0gYjsKfQoKZnVuY3Rpb24gYXJlYShy
aW5nKSB7CiAgdmFyIGkgPSAwLCBuID0gcmluZy5sZW5ndGgsIGFyZWEgPSByaW5nW24gLSAxXVsx
XSAqIHJpbmdbMF1bMF0gLSByaW5nW24gLSAxXVswXSAqIHJpbmdbMF1bMV07CiAgd2hpbGUgKCsr
aSA8IG4pIGFyZWEgKz0gcmluZ1tpIC0gMV1bMV0gKiByaW5nW2ldWzBdIC0gcmluZ1tpIC0gMV1b
MF0gKiByaW5nW2ldWzFdOwogIHJldHVybiBhcmVhOwp9CgpmdW5jdGlvbiBjb25zdGFudCQ2KHgp
IHsKICByZXR1cm4gZnVuY3Rpb24oKSB7CiAgICByZXR1cm4geDsKICB9Owp9CgpmdW5jdGlvbiBj
b250YWlucyhyaW5nLCBob2xlKSB7CiAgdmFyIGkgPSAtMSwgbiA9IGhvbGUubGVuZ3RoLCBjOwog
IHdoaWxlICgrK2kgPCBuKSBpZiAoYyA9IHJpbmdDb250YWlucyhyaW5nLCBob2xlW2ldKSkgcmV0
dXJuIGM7CiAgcmV0dXJuIDA7Cn0KCmZ1bmN0aW9uIHJpbmdDb250YWlucyhyaW5nLCBwb2ludCkg
ewogIHZhciB4ID0gcG9pbnRbMF0sIHkgPSBwb2ludFsxXSwgY29udGFpbnMgPSAtMTsKICBmb3Ig
KHZhciBpID0gMCwgbiA9IHJpbmcubGVuZ3RoLCBqID0gbiAtIDE7IGkgPCBuOyBqID0gaSsrKSB7
CiAgICB2YXIgcGkgPSByaW5nW2ldLCB4aSA9IHBpWzBdLCB5aSA9IHBpWzFdLCBwaiA9IHJpbmdb
al0sIHhqID0gcGpbMF0sIHlqID0gcGpbMV07CiAgICBpZiAoc2VnbWVudENvbnRhaW5zKHBpLCBw
aiwgcG9pbnQpKSByZXR1cm4gMDsKICAgIGlmICgoKHlpID4geSkgIT09ICh5aiA+IHkpKSAmJiAo
KHggPCAoeGogLSB4aSkgKiAoeSAtIHlpKSAvICh5aiAtIHlpKSArIHhpKSkpIGNvbnRhaW5zID0g
LWNvbnRhaW5zOwogIH0KICByZXR1cm4gY29udGFpbnM7Cn0KCmZ1bmN0aW9uIHNlZ21lbnRDb250
YWlucyhhLCBiLCBjKSB7CiAgdmFyIGk7IHJldHVybiBjb2xsaW5lYXIoYSwgYiwgYykgJiYgd2l0
aGluKGFbaSA9ICsoYVswXSA9PT0gYlswXSldLCBjW2ldLCBiW2ldKTsKfQoKZnVuY3Rpb24gY29s
bGluZWFyKGEsIGIsIGMpIHsKICByZXR1cm4gKGJbMF0gLSBhWzBdKSAqIChjWzFdIC0gYVsxXSkg
PT09IChjWzBdIC0gYVswXSkgKiAoYlsxXSAtIGFbMV0pOwp9CgpmdW5jdGlvbiB3aXRoaW4ocCwg
cSwgcikgewogIHJldHVybiBwIDw9IHEgJiYgcSA8PSByIHx8IHIgPD0gcSAmJiBxIDw9IHA7Cn0K
CmZ1bmN0aW9uIG5vb3AkMSgpIHt9Cgp2YXIgY2FzZXMgPSBbCiAgW10sCiAgW1tbMS4wLCAxLjVd
LCBbMC41LCAxLjBdXV0sCiAgW1tbMS41LCAxLjBdLCBbMS4wLCAxLjVdXV0sCiAgW1tbMS41LCAx
LjBdLCBbMC41LCAxLjBdXV0sCiAgW1tbMS4wLCAwLjVdLCBbMS41LCAxLjBdXV0sCiAgW1tbMS4w
LCAxLjVdLCBbMC41LCAxLjBdXSwgW1sxLjAsIDAuNV0sIFsxLjUsIDEuMF1dXSwKICBbW1sxLjAs
IDAuNV0sIFsxLjAsIDEuNV1dXSwKICBbW1sxLjAsIDAuNV0sIFswLjUsIDEuMF1dXSwKICBbW1sw
LjUsIDEuMF0sIFsxLjAsIDAuNV1dXSwKICBbW1sxLjAsIDEuNV0sIFsxLjAsIDAuNV1dXSwKICBb
W1swLjUsIDEuMF0sIFsxLjAsIDAuNV1dLCBbWzEuNSwgMS4wXSwgWzEuMCwgMS41XV1dLAogIFtb
WzEuNSwgMS4wXSwgWzEuMCwgMC41XV1dLAogIFtbWzAuNSwgMS4wXSwgWzEuNSwgMS4wXV1dLAog
IFtbWzEuMCwgMS41XSwgWzEuNSwgMS4wXV1dLAogIFtbWzAuNSwgMS4wXSwgWzEuMCwgMS41XV1d
LAogIFtdCl07CgpmdW5jdGlvbiBjb250b3VycygpIHsKICB2YXIgZHggPSAxLAogICAgICBkeSA9
IDEsCiAgICAgIHRocmVzaG9sZCA9IHRocmVzaG9sZFN0dXJnZXMsCiAgICAgIHNtb290aCA9IHNt
b290aExpbmVhcjsKCiAgZnVuY3Rpb24gY29udG91cnModmFsdWVzKSB7CiAgICB2YXIgdHogPSB0
aHJlc2hvbGQodmFsdWVzKTsKCiAgICAvLyBDb252ZXJ0IG51bWJlciBvZiB0aHJlc2hvbGRzIGlu
dG8gdW5pZm9ybSB0aHJlc2hvbGRzLgogICAgaWYgKCFBcnJheS5pc0FycmF5KHR6KSkgewogICAg
ICB2YXIgZG9tYWluID0gZXh0ZW50KHZhbHVlcyksIHN0YXJ0ID0gZG9tYWluWzBdLCBzdG9wID0g
ZG9tYWluWzFdOwogICAgICB0eiA9IHRpY2tTdGVwKHN0YXJ0LCBzdG9wLCB0eik7CiAgICAgIHR6
ID0gc2VxdWVuY2UoTWF0aC5mbG9vcihzdGFydCAvIHR6KSAqIHR6LCBNYXRoLmZsb29yKHN0b3Ag
LyB0eikgKiB0eiwgdHopOwogICAgfSBlbHNlIHsKICAgICAgdHogPSB0ei5zbGljZSgpLnNvcnQo
YXNjZW5kaW5nJDIpOwogICAgfQoKICAgIHJldHVybiB0ei5tYXAoZnVuY3Rpb24odmFsdWUpIHsK
ICAgICAgcmV0dXJuIGNvbnRvdXIodmFsdWVzLCB2YWx1ZSk7CiAgICB9KTsKICB9CgogIC8vIEFj
Y3VtdWxhdGUsIHNtb290aCBjb250b3VyIHJpbmdzLCBhc3NpZ24gaG9sZXMgdG8gZXh0ZXJpb3Ig
cmluZ3MuCiAgLy8gQmFzZWQgb24gaHR0cHM6Ly9naXRodWIuY29tL21ib3N0b2NrL3NoYXBlZmls
ZS9ibG9iL3YwLjYuMi9zaHAvcG9seWdvbi5qcwogIGZ1bmN0aW9uIGNvbnRvdXIodmFsdWVzLCB2
YWx1ZSkgewogICAgdmFyIHBvbHlnb25zID0gW10sCiAgICAgICAgaG9sZXMgPSBbXTsKCiAgICBp
c29yaW5ncyh2YWx1ZXMsIHZhbHVlLCBmdW5jdGlvbihyaW5nKSB7CiAgICAgIHNtb290aChyaW5n
LCB2YWx1ZXMsIHZhbHVlKTsKICAgICAgaWYgKGFyZWEocmluZykgPiAwKSBwb2x5Z29ucy5wdXNo
KFtyaW5nXSk7CiAgICAgIGVsc2UgaG9sZXMucHVzaChyaW5nKTsKICAgIH0pOwoKICAgIGhvbGVz
LmZvckVhY2goZnVuY3Rpb24oaG9sZSkgewogICAgICBmb3IgKHZhciBpID0gMCwgbiA9IHBvbHln
b25zLmxlbmd0aCwgcG9seWdvbjsgaSA8IG47ICsraSkgewogICAgICAgIGlmIChjb250YWlucygo
cG9seWdvbiA9IHBvbHlnb25zW2ldKVswXSwgaG9sZSkgIT09IC0xKSB7CiAgICAgICAgICBwb2x5
Z29uLnB1c2goaG9sZSk7CiAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICB9CiAgICB9
KTsKCiAgICByZXR1cm4gewogICAgICB0eXBlOiAiTXVsdGlQb2x5Z29uIiwKICAgICAgdmFsdWU6
IHZhbHVlLAogICAgICBjb29yZGluYXRlczogcG9seWdvbnMKICAgIH07CiAgfQoKICAvLyBNYXJj
aGluZyBzcXVhcmVzIHdpdGggaXNvbGluZXMgc3RpdGNoZWQgaW50byByaW5ncy4KICAvLyBCYXNl
ZCBvbiBodHRwczovL2dpdGh1Yi5jb20vdG9wb2pzb24vdG9wb2pzb24tY2xpZW50L2Jsb2IvdjMu
MC4wL3NyYy9zdGl0Y2guanMKICBmdW5jdGlvbiBpc29yaW5ncyh2YWx1ZXMsIHZhbHVlLCBjYWxs
YmFjaykgewogICAgdmFyIGZyYWdtZW50QnlTdGFydCA9IG5ldyBBcnJheSwKICAgICAgICBmcmFn
bWVudEJ5RW5kID0gbmV3IEFycmF5LAogICAgICAgIHgsIHksIHQwLCB0MSwgdDIsIHQzOwoKICAg
IC8vIFNwZWNpYWwgY2FzZSBmb3IgdGhlIGZpcnN0IHJvdyAoeSA9IC0xLCB0MiA9IHQzID0gMCku
CiAgICB4ID0geSA9IC0xOwogICAgdDEgPSB2YWx1ZXNbMF0gPj0gdmFsdWU7CiAgICBjYXNlc1t0
MSA8PCAxXS5mb3JFYWNoKHN0aXRjaCk7CiAgICB3aGlsZSAoKyt4IDwgZHggLSAxKSB7CiAgICAg
IHQwID0gdDEsIHQxID0gdmFsdWVzW3ggKyAxXSA+PSB2YWx1ZTsKICAgICAgY2FzZXNbdDAgfCB0
MSA8PCAxXS5mb3JFYWNoKHN0aXRjaCk7CiAgICB9CiAgICBjYXNlc1t0MSA8PCAwXS5mb3JFYWNo
KHN0aXRjaCk7CgogICAgLy8gR2VuZXJhbCBjYXNlIGZvciB0aGUgaW50ZXJtZWRpYXRlIHJvd3Mu
CiAgICB3aGlsZSAoKyt5IDwgZHkgLSAxKSB7CiAgICAgIHggPSAtMTsKICAgICAgdDEgPSB2YWx1
ZXNbeSAqIGR4ICsgZHhdID49IHZhbHVlOwogICAgICB0MiA9IHZhbHVlc1t5ICogZHhdID49IHZh
bHVlOwogICAgICBjYXNlc1t0MSA8PCAxIHwgdDIgPDwgMl0uZm9yRWFjaChzdGl0Y2gpOwogICAg
ICB3aGlsZSAoKyt4IDwgZHggLSAxKSB7CiAgICAgICAgdDAgPSB0MSwgdDEgPSB2YWx1ZXNbeSAq
IGR4ICsgZHggKyB4ICsgMV0gPj0gdmFsdWU7CiAgICAgICAgdDMgPSB0MiwgdDIgPSB2YWx1ZXNb
eSAqIGR4ICsgeCArIDFdID49IHZhbHVlOwogICAgICAgIGNhc2VzW3QwIHwgdDEgPDwgMSB8IHQy
IDw8IDIgfCB0MyA8PCAzXS5mb3JFYWNoKHN0aXRjaCk7CiAgICAgIH0KICAgICAgY2FzZXNbdDEg
fCB0MiA8PCAzXS5mb3JFYWNoKHN0aXRjaCk7CiAgICB9CgogICAgLy8gU3BlY2lhbCBjYXNlIGZv
ciB0aGUgbGFzdCByb3cgKHkgPSBkeSAtIDEsIHQwID0gdDEgPSAwKS4KICAgIHggPSAtMTsKICAg
IHQyID0gdmFsdWVzW3kgKiBkeF0gPj0gdmFsdWU7CiAgICBjYXNlc1t0MiA8PCAyXS5mb3JFYWNo
KHN0aXRjaCk7CiAgICB3aGlsZSAoKyt4IDwgZHggLSAxKSB7CiAgICAgIHQzID0gdDIsIHQyID0g
dmFsdWVzW3kgKiBkeCArIHggKyAxXSA+PSB2YWx1ZTsKICAgICAgY2FzZXNbdDIgPDwgMiB8IHQz
IDw8IDNdLmZvckVhY2goc3RpdGNoKTsKICAgIH0KICAgIGNhc2VzW3QyIDw8IDNdLmZvckVhY2go
c3RpdGNoKTsKCiAgICBmdW5jdGlvbiBzdGl0Y2gobGluZSkgewogICAgICB2YXIgc3RhcnQgPSBb
bGluZVswXVswXSArIHgsIGxpbmVbMF1bMV0gKyB5XSwKICAgICAgICAgIGVuZCA9IFtsaW5lWzFd
WzBdICsgeCwgbGluZVsxXVsxXSArIHldLAogICAgICAgICAgc3RhcnRJbmRleCA9IGluZGV4KHN0
YXJ0KSwKICAgICAgICAgIGVuZEluZGV4ID0gaW5kZXgoZW5kKSwKICAgICAgICAgIGYsIGc7CiAg
ICAgIGlmIChmID0gZnJhZ21lbnRCeUVuZFtzdGFydEluZGV4XSkgewogICAgICAgIGlmIChnID0g
ZnJhZ21lbnRCeVN0YXJ0W2VuZEluZGV4XSkgewogICAgICAgICAgZGVsZXRlIGZyYWdtZW50QnlF
bmRbZi5lbmRdOwogICAgICAgICAgZGVsZXRlIGZyYWdtZW50QnlTdGFydFtnLnN0YXJ0XTsKICAg
ICAgICAgIGlmIChmID09PSBnKSB7CiAgICAgICAgICAgIGYucmluZy5wdXNoKGVuZCk7CiAgICAg
ICAgICAgIGNhbGxiYWNrKGYucmluZyk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBm
cmFnbWVudEJ5U3RhcnRbZi5zdGFydF0gPSBmcmFnbWVudEJ5RW5kW2cuZW5kXSA9IHtzdGFydDog
Zi5zdGFydCwgZW5kOiBnLmVuZCwgcmluZzogZi5yaW5nLmNvbmNhdChnLnJpbmcpfTsKICAgICAg
ICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgZGVsZXRlIGZyYWdtZW50QnlFbmRbZi5l
bmRdOwogICAgICAgICAgZi5yaW5nLnB1c2goZW5kKTsKICAgICAgICAgIGZyYWdtZW50QnlFbmRb
Zi5lbmQgPSBlbmRJbmRleF0gPSBmOwogICAgICAgIH0KICAgICAgfSBlbHNlIGlmIChmID0gZnJh
Z21lbnRCeVN0YXJ0W2VuZEluZGV4XSkgewogICAgICAgIGlmIChnID0gZnJhZ21lbnRCeUVuZFtz
dGFydEluZGV4XSkgewogICAgICAgICAgZGVsZXRlIGZyYWdtZW50QnlTdGFydFtmLnN0YXJ0XTsK
ICAgICAgICAgIGRlbGV0ZSBmcmFnbWVudEJ5RW5kW2cuZW5kXTsKICAgICAgICAgIGlmIChmID09
PSBnKSB7CiAgICAgICAgICAgIGYucmluZy5wdXNoKGVuZCk7CiAgICAgICAgICAgIGNhbGxiYWNr
KGYucmluZyk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmcmFnbWVudEJ5U3RhcnRb
Zy5zdGFydF0gPSBmcmFnbWVudEJ5RW5kW2YuZW5kXSA9IHtzdGFydDogZy5zdGFydCwgZW5kOiBm
LmVuZCwgcmluZzogZy5yaW5nLmNvbmNhdChmLnJpbmcpfTsKICAgICAgICAgIH0KICAgICAgICB9
IGVsc2UgewogICAgICAgICAgZGVsZXRlIGZyYWdtZW50QnlTdGFydFtmLnN0YXJ0XTsKICAgICAg
ICAgIGYucmluZy51bnNoaWZ0KHN0YXJ0KTsKICAgICAgICAgIGZyYWdtZW50QnlTdGFydFtmLnN0
YXJ0ID0gc3RhcnRJbmRleF0gPSBmOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBm
cmFnbWVudEJ5U3RhcnRbc3RhcnRJbmRleF0gPSBmcmFnbWVudEJ5RW5kW2VuZEluZGV4XSA9IHtz
dGFydDogc3RhcnRJbmRleCwgZW5kOiBlbmRJbmRleCwgcmluZzogW3N0YXJ0LCBlbmRdfTsKICAg
ICAgfQogICAgfQogIH0KCiAgZnVuY3Rpb24gaW5kZXgocG9pbnQpIHsKICAgIHJldHVybiBwb2lu
dFswXSAqIDIgKyBwb2ludFsxXSAqIChkeCArIDEpICogNDsKICB9CgogIGZ1bmN0aW9uIHNtb290
aExpbmVhcihyaW5nLCB2YWx1ZXMsIHZhbHVlKSB7CiAgICByaW5nLmZvckVhY2goZnVuY3Rpb24o
cG9pbnQpIHsKICAgICAgdmFyIHggPSBwb2ludFswXSwKICAgICAgICAgIHkgPSBwb2ludFsxXSwK
ICAgICAgICAgIHh0ID0geCB8IDAsCiAgICAgICAgICB5dCA9IHkgfCAwLAogICAgICAgICAgdjAs
CiAgICAgICAgICB2MSA9IHZhbHVlc1t5dCAqIGR4ICsgeHRdOwogICAgICBpZiAoeCA+IDAgJiYg
eCA8IGR4ICYmIHh0ID09PSB4KSB7CiAgICAgICAgdjAgPSB2YWx1ZXNbeXQgKiBkeCArIHh0IC0g
MV07CiAgICAgICAgcG9pbnRbMF0gPSB4ICsgKHZhbHVlIC0gdjApIC8gKHYxIC0gdjApIC0gMC41
OwogICAgICB9CiAgICAgIGlmICh5ID4gMCAmJiB5IDwgZHkgJiYgeXQgPT09IHkpIHsKICAgICAg
ICB2MCA9IHZhbHVlc1soeXQgLSAxKSAqIGR4ICsgeHRdOwogICAgICAgIHBvaW50WzFdID0geSAr
ICh2YWx1ZSAtIHYwKSAvICh2MSAtIHYwKSAtIDAuNTsKICAgICAgfQogICAgfSk7CiAgfQoKICBj
b250b3Vycy5jb250b3VyID0gY29udG91cjsKCiAgY29udG91cnMuc2l6ZSA9IGZ1bmN0aW9uKF8p
IHsKICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIFtkeCwgZHldOwogICAgdmFyIF8w
ID0gTWF0aC5jZWlsKF9bMF0pLCBfMSA9IE1hdGguY2VpbChfWzFdKTsKICAgIGlmICghKF8wID4g
MCkgfHwgIShfMSA+IDApKSB0aHJvdyBuZXcgRXJyb3IoImludmFsaWQgc2l6ZSIpOwogICAgcmV0
dXJuIGR4ID0gXzAsIGR5ID0gXzEsIGNvbnRvdXJzOwogIH07CgogIGNvbnRvdXJzLnRocmVzaG9s
ZHMgPSBmdW5jdGlvbihfKSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh0aHJlc2hv
bGQgPSB0eXBlb2YgXyA9PT0gImZ1bmN0aW9uIiA/IF8gOiBBcnJheS5pc0FycmF5KF8pID8gY29u
c3RhbnQkNihzbGljZSQzLmNhbGwoXykpIDogY29uc3RhbnQkNihfKSwgY29udG91cnMpIDogdGhy
ZXNob2xkOwogIH07CgogIGNvbnRvdXJzLnNtb290aCA9IGZ1bmN0aW9uKF8pIHsKICAgIHJldHVy
biBhcmd1bWVudHMubGVuZ3RoID8gKHNtb290aCA9IF8gPyBzbW9vdGhMaW5lYXIgOiBub29wJDEs
IGNvbnRvdXJzKSA6IHNtb290aCA9PT0gc21vb3RoTGluZWFyOwogIH07CgogIHJldHVybiBjb250
b3VyczsKfQoKLy8gVE9ETyBPcHRpbWl6ZSBlZGdlIGNhc2VzLgovLyBUT0RPIE9wdGltaXplIGlu
ZGV4IGNhbGN1bGF0aW9uLgovLyBUT0RPIE9wdGltaXplIGFyZ3VtZW50cy4KZnVuY3Rpb24gYmx1
clgoc291cmNlLCB0YXJnZXQsIHIpIHsKICB2YXIgbiA9IHNvdXJjZS53aWR0aCwKICAgICAgbSA9
IHNvdXJjZS5oZWlnaHQsCiAgICAgIHcgPSAociA8PCAxKSArIDE7CiAgZm9yICh2YXIgaiA9IDA7
IGogPCBtOyArK2opIHsKICAgIGZvciAodmFyIGkgPSAwLCBzciA9IDA7IGkgPCBuICsgcjsgKytp
KSB7CiAgICAgIGlmIChpIDwgbikgewogICAgICAgIHNyICs9IHNvdXJjZS5kYXRhW2kgKyBqICog
bl07CiAgICAgIH0KICAgICAgaWYgKGkgPj0gcikgewogICAgICAgIGlmIChpID49IHcpIHsKICAg
ICAgICAgIHNyIC09IHNvdXJjZS5kYXRhW2kgLSB3ICsgaiAqIG5dOwogICAgICAgIH0KICAgICAg
ICB0YXJnZXQuZGF0YVtpIC0gciArIGogKiBuXSA9IHNyIC8gTWF0aC5taW4oaSArIDEsIG4gLSAx
ICsgdyAtIGksIHcpOwogICAgICB9CiAgICB9CiAgfQp9CgovLyBUT0RPIE9wdGltaXplIGVkZ2Ug
Y2FzZXMuCi8vIFRPRE8gT3B0aW1pemUgaW5kZXggY2FsY3VsYXRpb24uCi8vIFRPRE8gT3B0aW1p
emUgYXJndW1lbnRzLgpmdW5jdGlvbiBibHVyWShzb3VyY2UsIHRhcmdldCwgcikgewogIHZhciBu
ID0gc291cmNlLndpZHRoLAogICAgICBtID0gc291cmNlLmhlaWdodCwKICAgICAgdyA9IChyIDw8
IDEpICsgMTsKICBmb3IgKHZhciBpID0gMDsgaSA8IG47ICsraSkgewogICAgZm9yICh2YXIgaiA9
IDAsIHNyID0gMDsgaiA8IG0gKyByOyArK2opIHsKICAgICAgaWYgKGogPCBtKSB7CiAgICAgICAg
c3IgKz0gc291cmNlLmRhdGFbaSArIGogKiBuXTsKICAgICAgfQogICAgICBpZiAoaiA+PSByKSB7
CiAgICAgICAgaWYgKGogPj0gdykgewogICAgICAgICAgc3IgLT0gc291cmNlLmRhdGFbaSArIChq
IC0gdykgKiBuXTsKICAgICAgICB9CiAgICAgICAgdGFyZ2V0LmRhdGFbaSArIChqIC0gcikgKiBu
XSA9IHNyIC8gTWF0aC5taW4oaiArIDEsIG0gLSAxICsgdyAtIGosIHcpOwogICAgICB9CiAgICB9
CiAgfQp9CgpmdW5jdGlvbiBkZWZhdWx0WChkKSB7CiAgcmV0dXJuIGRbMF07Cn0KCmZ1bmN0aW9u
IGRlZmF1bHRZKGQpIHsKICByZXR1cm4gZFsxXTsKfQoKZnVuY3Rpb24gZGVmYXVsdFdlaWdodCgp
IHsKICByZXR1cm4gMTsKfQoKZnVuY3Rpb24gZGVuc2l0eSgpIHsKICB2YXIgeCA9IGRlZmF1bHRY
LAogICAgICB5ID0gZGVmYXVsdFksCiAgICAgIHdlaWdodCA9IGRlZmF1bHRXZWlnaHQsCiAgICAg
IGR4ID0gOTYwLAogICAgICBkeSA9IDUwMCwKICAgICAgciA9IDIwLCAvLyBibHVyIHJhZGl1cwog
ICAgICBrID0gMiwgLy8gbG9nMihncmlkIGNlbGwgc2l6ZSkKICAgICAgbyA9IHIgKiAzLCAvLyBn
cmlkIG9mZnNldCwgdG8gcGFkIGZvciBibHVyCiAgICAgIG4gPSAoZHggKyBvICogMikgPj4gaywg
Ly8gZ3JpZCB3aWR0aAogICAgICBtID0gKGR5ICsgbyAqIDIpID4+IGssIC8vIGdyaWQgaGVpZ2h0
CiAgICAgIHRocmVzaG9sZCA9IGNvbnN0YW50JDYoMjApOwoKICBmdW5jdGlvbiBkZW5zaXR5KGRh
dGEpIHsKICAgIHZhciB2YWx1ZXMwID0gbmV3IEZsb2F0MzJBcnJheShuICogbSksCiAgICAgICAg
dmFsdWVzMSA9IG5ldyBGbG9hdDMyQXJyYXkobiAqIG0pOwoKICAgIGRhdGEuZm9yRWFjaChmdW5j
dGlvbihkLCBpLCBkYXRhKSB7CiAgICAgIHZhciB4aSA9ICgreChkLCBpLCBkYXRhKSArIG8pID4+
IGssCiAgICAgICAgICB5aSA9ICgreShkLCBpLCBkYXRhKSArIG8pID4+IGssCiAgICAgICAgICB3
aSA9ICt3ZWlnaHQoZCwgaSwgZGF0YSk7CiAgICAgIGlmICh4aSA+PSAwICYmIHhpIDwgbiAmJiB5
aSA+PSAwICYmIHlpIDwgbSkgewogICAgICAgIHZhbHVlczBbeGkgKyB5aSAqIG5dICs9IHdpOwog
ICAgICB9CiAgICB9KTsKCiAgICAvLyBUT0RPIE9wdGltaXplLgogICAgYmx1clgoe3dpZHRoOiBu
LCBoZWlnaHQ6IG0sIGRhdGE6IHZhbHVlczB9LCB7d2lkdGg6IG4sIGhlaWdodDogbSwgZGF0YTog
dmFsdWVzMX0sIHIgPj4gayk7CiAgICBibHVyWSh7d2lkdGg6IG4sIGhlaWdodDogbSwgZGF0YTog
dmFsdWVzMX0sIHt3aWR0aDogbiwgaGVpZ2h0OiBtLCBkYXRhOiB2YWx1ZXMwfSwgciA+PiBrKTsK
ICAgIGJsdXJYKHt3aWR0aDogbiwgaGVpZ2h0OiBtLCBkYXRhOiB2YWx1ZXMwfSwge3dpZHRoOiBu
LCBoZWlnaHQ6IG0sIGRhdGE6IHZhbHVlczF9LCByID4+IGspOwogICAgYmx1clkoe3dpZHRoOiBu
LCBoZWlnaHQ6IG0sIGRhdGE6IHZhbHVlczF9LCB7d2lkdGg6IG4sIGhlaWdodDogbSwgZGF0YTog
dmFsdWVzMH0sIHIgPj4gayk7CiAgICBibHVyWCh7d2lkdGg6IG4sIGhlaWdodDogbSwgZGF0YTog
dmFsdWVzMH0sIHt3aWR0aDogbiwgaGVpZ2h0OiBtLCBkYXRhOiB2YWx1ZXMxfSwgciA+PiBrKTsK
ICAgIGJsdXJZKHt3aWR0aDogbiwgaGVpZ2h0OiBtLCBkYXRhOiB2YWx1ZXMxfSwge3dpZHRoOiBu
LCBoZWlnaHQ6IG0sIGRhdGE6IHZhbHVlczB9LCByID4+IGspOwoKICAgIHZhciB0eiA9IHRocmVz
aG9sZCh2YWx1ZXMwKTsKCiAgICAvLyBDb252ZXJ0IG51bWJlciBvZiB0aHJlc2hvbGRzIGludG8g
dW5pZm9ybSB0aHJlc2hvbGRzLgogICAgaWYgKCFBcnJheS5pc0FycmF5KHR6KSkgewogICAgICB2
YXIgc3RvcCA9IG1heCh2YWx1ZXMwKTsKICAgICAgdHogPSB0aWNrU3RlcCgwLCBzdG9wLCB0eik7
CiAgICAgIHR6ID0gc2VxdWVuY2UoMCwgTWF0aC5mbG9vcihzdG9wIC8gdHopICogdHosIHR6KTsK
ICAgICAgdHouc2hpZnQoKTsKICAgIH0KCiAgICByZXR1cm4gY29udG91cnMoKQogICAgICAgIC50
aHJlc2hvbGRzKHR6KQogICAgICAgIC5zaXplKFtuLCBtXSkKICAgICAgKHZhbHVlczApCiAgICAg
ICAgLm1hcCh0cmFuc2Zvcm0pOwogIH0KCiAgZnVuY3Rpb24gdHJhbnNmb3JtKGdlb21ldHJ5KSB7
CiAgICBnZW9tZXRyeS52YWx1ZSAqPSBNYXRoLnBvdygyLCAtMiAqIGspOyAvLyBEZW5zaXR5IGlu
IHBvaW50cyBwZXIgc3F1YXJlIHBpeGVsLgogICAgZ2VvbWV0cnkuY29vcmRpbmF0ZXMuZm9yRWFj
aCh0cmFuc2Zvcm1Qb2x5Z29uKTsKICAgIHJldHVybiBnZW9tZXRyeTsKICB9CgogIGZ1bmN0aW9u
IHRyYW5zZm9ybVBvbHlnb24oY29vcmRpbmF0ZXMpIHsKICAgIGNvb3JkaW5hdGVzLmZvckVhY2go
dHJhbnNmb3JtUmluZyk7CiAgfQoKICBmdW5jdGlvbiB0cmFuc2Zvcm1SaW5nKGNvb3JkaW5hdGVz
KSB7CiAgICBjb29yZGluYXRlcy5mb3JFYWNoKHRyYW5zZm9ybVBvaW50KTsKICB9CgogIC8vIFRP
RE8gT3B0aW1pemUuCiAgZnVuY3Rpb24gdHJhbnNmb3JtUG9pbnQoY29vcmRpbmF0ZXMpIHsKICAg
IGNvb3JkaW5hdGVzWzBdID0gY29vcmRpbmF0ZXNbMF0gKiBNYXRoLnBvdygyLCBrKSAtIG87CiAg
ICBjb29yZGluYXRlc1sxXSA9IGNvb3JkaW5hdGVzWzFdICogTWF0aC5wb3coMiwgaykgLSBvOwog
IH0KCiAgZnVuY3Rpb24gcmVzaXplKCkgewogICAgbyA9IHIgKiAzOwogICAgbiA9IChkeCArIG8g
KiAyKSA+PiBrOwogICAgbSA9IChkeSArIG8gKiAyKSA+PiBrOwogICAgcmV0dXJuIGRlbnNpdHk7
CiAgfQoKICBkZW5zaXR5LnggPSBmdW5jdGlvbihfKSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxl
bmd0aCA/ICh4ID0gdHlwZW9mIF8gPT09ICJmdW5jdGlvbiIgPyBfIDogY29uc3RhbnQkNigrXyks
IGRlbnNpdHkpIDogeDsKICB9OwoKICBkZW5zaXR5LnkgPSBmdW5jdGlvbihfKSB7CiAgICByZXR1
cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh5ID0gdHlwZW9mIF8gPT09ICJmdW5jdGlvbiIgPyBfIDog
Y29uc3RhbnQkNigrXyksIGRlbnNpdHkpIDogeTsKICB9OwoKICBkZW5zaXR5LndlaWdodCA9IGZ1
bmN0aW9uKF8pIHsKICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHdlaWdodCA9IHR5cGVv
ZiBfID09PSAiZnVuY3Rpb24iID8gXyA6IGNvbnN0YW50JDYoK18pLCBkZW5zaXR5KSA6IHdlaWdo
dDsKICB9OwoKICBkZW5zaXR5LnNpemUgPSBmdW5jdGlvbihfKSB7CiAgICBpZiAoIWFyZ3VtZW50
cy5sZW5ndGgpIHJldHVybiBbZHgsIGR5XTsKICAgIHZhciBfMCA9IE1hdGguY2VpbChfWzBdKSwg
XzEgPSBNYXRoLmNlaWwoX1sxXSk7CiAgICBpZiAoIShfMCA+PSAwKSAmJiAhKF8wID49IDApKSB0
aHJvdyBuZXcgRXJyb3IoImludmFsaWQgc2l6ZSIpOwogICAgcmV0dXJuIGR4ID0gXzAsIGR5ID0g
XzEsIHJlc2l6ZSgpOwogIH07CgogIGRlbnNpdHkuY2VsbFNpemUgPSBmdW5jdGlvbihfKSB7CiAg
ICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiAxIDw8IGs7CiAgICBpZiAoISgoXyA9ICtf
KSA+PSAxKSkgdGhyb3cgbmV3IEVycm9yKCJpbnZhbGlkIGNlbGwgc2l6ZSIpOwogICAgcmV0dXJu
IGsgPSBNYXRoLmZsb29yKE1hdGgubG9nKF8pIC8gTWF0aC5MTjIpLCByZXNpemUoKTsKICB9OwoK
ICBkZW5zaXR5LnRocmVzaG9sZHMgPSBmdW5jdGlvbihfKSB7CiAgICByZXR1cm4gYXJndW1lbnRz
Lmxlbmd0aCA/ICh0aHJlc2hvbGQgPSB0eXBlb2YgXyA9PT0gImZ1bmN0aW9uIiA/IF8gOiBBcnJh
eS5pc0FycmF5KF8pID8gY29uc3RhbnQkNihzbGljZSQzLmNhbGwoXykpIDogY29uc3RhbnQkNihf
KSwgZGVuc2l0eSkgOiB0aHJlc2hvbGQ7CiAgfTsKCiAgZGVuc2l0eS5iYW5kd2lkdGggPSBmdW5j
dGlvbihfKSB7CiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBNYXRoLnNxcnQociAq
IChyICsgMSkpOwogICAgaWYgKCEoKF8gPSArXykgPj0gMCkpIHRocm93IG5ldyBFcnJvcigiaW52
YWxpZCBiYW5kd2lkdGgiKTsKICAgIHJldHVybiByID0gTWF0aC5yb3VuZCgoTWF0aC5zcXJ0KDQg
KiBfICogXyArIDEpIC0gMSkgLyAyKSwgcmVzaXplKCk7CiAgfTsKCiAgcmV0dXJuIGRlbnNpdHk7
Cn0KCnZhciBFT0wgPSB7fSwKICAgIEVPRiA9IHt9LAogICAgUVVPVEUgPSAzNCwKICAgIE5FV0xJ
TkUgPSAxMCwKICAgIFJFVFVSTiA9IDEzOwoKZnVuY3Rpb24gb2JqZWN0Q29udmVydGVyKGNvbHVt
bnMpIHsKICByZXR1cm4gbmV3IEZ1bmN0aW9uKCJkIiwgInJldHVybiB7IiArIGNvbHVtbnMubWFw
KGZ1bmN0aW9uKG5hbWUsIGkpIHsKICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShuYW1lKSArICI6
IGRbIiArIGkgKyAiXSB8fCBcIlwiIjsKICB9KS5qb2luKCIsIikgKyAifSIpOwp9CgpmdW5jdGlv
biBjdXN0b21Db252ZXJ0ZXIoY29sdW1ucywgZikgewogIHZhciBvYmplY3QgPSBvYmplY3RDb252
ZXJ0ZXIoY29sdW1ucyk7CiAgcmV0dXJuIGZ1bmN0aW9uKHJvdywgaSkgewogICAgcmV0dXJuIGYo
b2JqZWN0KHJvdyksIGksIGNvbHVtbnMpOwogIH07Cn0KCi8vIENvbXB1dGUgdW5pcXVlIGNvbHVt
bnMgaW4gb3JkZXIgb2YgZGlzY292ZXJ5LgpmdW5jdGlvbiBpbmZlckNvbHVtbnMocm93cykgewog
IHZhciBjb2x1bW5TZXQgPSBPYmplY3QuY3JlYXRlKG51bGwpLAogICAgICBjb2x1bW5zID0gW107
CgogIHJvd3MuZm9yRWFjaChmdW5jdGlvbihyb3cpIHsKICAgIGZvciAodmFyIGNvbHVtbiBpbiBy
b3cpIHsKICAgICAgaWYgKCEoY29sdW1uIGluIGNvbHVtblNldCkpIHsKICAgICAgICBjb2x1bW5z
LnB1c2goY29sdW1uU2V0W2NvbHVtbl0gPSBjb2x1bW4pOwogICAgICB9CiAgICB9CiAgfSk7Cgog
IHJldHVybiBjb2x1bW5zOwp9CgpmdW5jdGlvbiBwYWQodmFsdWUsIHdpZHRoKSB7CiAgdmFyIHMg
PSB2YWx1ZSArICIiLCBsZW5ndGggPSBzLmxlbmd0aDsKICByZXR1cm4gbGVuZ3RoIDwgd2lkdGgg
PyBuZXcgQXJyYXkod2lkdGggLSBsZW5ndGggKyAxKS5qb2luKDApICsgcyA6IHM7Cn0KCmZ1bmN0
aW9uIGZvcm1hdFllYXIoeWVhcikgewogIHJldHVybiB5ZWFyIDwgMCA/ICItIiArIHBhZCgteWVh
ciwgNikKICAgIDogeWVhciA+IDk5OTkgPyAiKyIgKyBwYWQoeWVhciwgNikKICAgIDogcGFkKHll
YXIsIDQpOwp9CgpmdW5jdGlvbiBmb3JtYXREYXRlKGRhdGUpIHsKICB2YXIgaG91cnMgPSBkYXRl
LmdldFVUQ0hvdXJzKCksCiAgICAgIG1pbnV0ZXMgPSBkYXRlLmdldFVUQ01pbnV0ZXMoKSwKICAg
ICAgc2Vjb25kcyA9IGRhdGUuZ2V0VVRDU2Vjb25kcygpLAogICAgICBtaWxsaXNlY29uZHMgPSBk
YXRlLmdldFVUQ01pbGxpc2Vjb25kcygpOwogIHJldHVybiBpc05hTihkYXRlKSA/ICJJbnZhbGlk
IERhdGUiCiAgICAgIDogZm9ybWF0WWVhcihkYXRlLmdldFVUQ0Z1bGxZZWFyKCkpICsgIi0iICsg
cGFkKGRhdGUuZ2V0VVRDTW9udGgoKSArIDEsIDIpICsgIi0iICsgcGFkKGRhdGUuZ2V0VVRDRGF0
ZSgpLCAyKQogICAgICArIChtaWxsaXNlY29uZHMgPyAiVCIgKyBwYWQoaG91cnMsIDIpICsgIjoi
ICsgcGFkKG1pbnV0ZXMsIDIpICsgIjoiICsgcGFkKHNlY29uZHMsIDIpICsgIi4iICsgcGFkKG1p
bGxpc2Vjb25kcywgMykgKyAiWiIKICAgICAgOiBzZWNvbmRzID8gIlQiICsgcGFkKGhvdXJzLCAy
KSArICI6IiArIHBhZChtaW51dGVzLCAyKSArICI6IiArIHBhZChzZWNvbmRzLCAyKSArICJaIgog
ICAgICA6IG1pbnV0ZXMgfHwgaG91cnMgPyAiVCIgKyBwYWQoaG91cnMsIDIpICsgIjoiICsgcGFk
KG1pbnV0ZXMsIDIpICsgIloiCiAgICAgIDogIiIpOwp9CgpmdW5jdGlvbiBkc3ZGb3JtYXQoZGVs
aW1pdGVyKSB7CiAgdmFyIHJlRm9ybWF0ID0gbmV3IFJlZ0V4cCgiW1wiIiArIGRlbGltaXRlciAr
ICJcblxyXSIpLAogICAgICBERUxJTUlURVIgPSBkZWxpbWl0ZXIuY2hhckNvZGVBdCgwKTsKCiAg
ZnVuY3Rpb24gcGFyc2UodGV4dCwgZikgewogICAgdmFyIGNvbnZlcnQsIGNvbHVtbnMsIHJvd3Mg
PSBwYXJzZVJvd3ModGV4dCwgZnVuY3Rpb24ocm93LCBpKSB7CiAgICAgIGlmIChjb252ZXJ0KSBy
ZXR1cm4gY29udmVydChyb3csIGkgLSAxKTsKICAgICAgY29sdW1ucyA9IHJvdywgY29udmVydCA9
IGYgPyBjdXN0b21Db252ZXJ0ZXIocm93LCBmKSA6IG9iamVjdENvbnZlcnRlcihyb3cpOwogICAg
fSk7CiAgICByb3dzLmNvbHVtbnMgPSBjb2x1bW5zIHx8IFtdOwogICAgcmV0dXJuIHJvd3M7CiAg
fQoKICBmdW5jdGlvbiBwYXJzZVJvd3ModGV4dCwgZikgewogICAgdmFyIHJvd3MgPSBbXSwgLy8g
b3V0cHV0IHJvd3MKICAgICAgICBOID0gdGV4dC5sZW5ndGgsCiAgICAgICAgSSA9IDAsIC8vIGN1
cnJlbnQgY2hhcmFjdGVyIGluZGV4CiAgICAgICAgbiA9IDAsIC8vIGN1cnJlbnQgbGluZSBudW1i
ZXIKICAgICAgICB0LCAvLyBjdXJyZW50IHRva2VuCiAgICAgICAgZW9mID0gTiA8PSAwLCAvLyBj
dXJyZW50IHRva2VuIGZvbGxvd2VkIGJ5IEVPRj8KICAgICAgICBlb2wgPSBmYWxzZTsgLy8gY3Vy
cmVudCB0b2tlbiBmb2xsb3dlZCBieSBFT0w/CgogICAgLy8gU3RyaXAgdGhlIHRyYWlsaW5nIG5l
d2xpbmUuCiAgICBpZiAodGV4dC5jaGFyQ29kZUF0KE4gLSAxKSA9PT0gTkVXTElORSkgLS1OOwog
ICAgaWYgKHRleHQuY2hhckNvZGVBdChOIC0gMSkgPT09IFJFVFVSTikgLS1OOwoKICAgIGZ1bmN0
aW9uIHRva2VuKCkgewogICAgICBpZiAoZW9mKSByZXR1cm4gRU9GOwogICAgICBpZiAoZW9sKSBy
ZXR1cm4gZW9sID0gZmFsc2UsIEVPTDsKCiAgICAgIC8vIFVuZXNjYXBlIHF1b3Rlcy4KICAgICAg
dmFyIGksIGogPSBJLCBjOwogICAgICBpZiAodGV4dC5jaGFyQ29kZUF0KGopID09PSBRVU9URSkg
ewogICAgICAgIHdoaWxlIChJKysgPCBOICYmIHRleHQuY2hhckNvZGVBdChJKSAhPT0gUVVPVEUg
fHwgdGV4dC5jaGFyQ29kZUF0KCsrSSkgPT09IFFVT1RFKTsKICAgICAgICBpZiAoKGkgPSBJKSA+
PSBOKSBlb2YgPSB0cnVlOwogICAgICAgIGVsc2UgaWYgKChjID0gdGV4dC5jaGFyQ29kZUF0KEkr
KykpID09PSBORVdMSU5FKSBlb2wgPSB0cnVlOwogICAgICAgIGVsc2UgaWYgKGMgPT09IFJFVFVS
TikgeyBlb2wgPSB0cnVlOyBpZiAodGV4dC5jaGFyQ29kZUF0KEkpID09PSBORVdMSU5FKSArK0k7
IH0KICAgICAgICByZXR1cm4gdGV4dC5zbGljZShqICsgMSwgaSAtIDEpLnJlcGxhY2UoLyIiL2cs
ICJcIiIpOwogICAgICB9CgogICAgICAvLyBGaW5kIG5leHQgZGVsaW1pdGVyIG9yIG5ld2xpbmUu
CiAgICAgIHdoaWxlIChJIDwgTikgewogICAgICAgIGlmICgoYyA9IHRleHQuY2hhckNvZGVBdChp
ID0gSSsrKSkgPT09IE5FV0xJTkUpIGVvbCA9IHRydWU7CiAgICAgICAgZWxzZSBpZiAoYyA9PT0g
UkVUVVJOKSB7IGVvbCA9IHRydWU7IGlmICh0ZXh0LmNoYXJDb2RlQXQoSSkgPT09IE5FV0xJTkUp
ICsrSTsgfQogICAgICAgIGVsc2UgaWYgKGMgIT09IERFTElNSVRFUikgY29udGludWU7CiAgICAg
ICAgcmV0dXJuIHRleHQuc2xpY2UoaiwgaSk7CiAgICAgIH0KCiAgICAgIC8vIFJldHVybiBsYXN0
IHRva2VuIGJlZm9yZSBFT0YuCiAgICAgIHJldHVybiBlb2YgPSB0cnVlLCB0ZXh0LnNsaWNlKGos
IE4pOwogICAgfQoKICAgIHdoaWxlICgodCA9IHRva2VuKCkpICE9PSBFT0YpIHsKICAgICAgdmFy
IHJvdyA9IFtdOwogICAgICB3aGlsZSAodCAhPT0gRU9MICYmIHQgIT09IEVPRikgcm93LnB1c2go
dCksIHQgPSB0b2tlbigpOwogICAgICBpZiAoZiAmJiAocm93ID0gZihyb3csIG4rKykpID09IG51
bGwpIGNvbnRpbnVlOwogICAgICByb3dzLnB1c2gocm93KTsKICAgIH0KCiAgICByZXR1cm4gcm93
czsKICB9CgogIGZ1bmN0aW9uIHByZWZvcm1hdEJvZHkocm93cywgY29sdW1ucykgewogICAgcmV0
dXJuIHJvd3MubWFwKGZ1bmN0aW9uKHJvdykgewogICAgICByZXR1cm4gY29sdW1ucy5tYXAoZnVu
Y3Rpb24oY29sdW1uKSB7CiAgICAgICAgcmV0dXJuIGZvcm1hdFZhbHVlKHJvd1tjb2x1bW5dKTsK
ICAgICAgfSkuam9pbihkZWxpbWl0ZXIpOwogICAgfSk7CiAgfQoKICBmdW5jdGlvbiBmb3JtYXQo
cm93cywgY29sdW1ucykgewogICAgaWYgKGNvbHVtbnMgPT0gbnVsbCkgY29sdW1ucyA9IGluZmVy
Q29sdW1ucyhyb3dzKTsKICAgIHJldHVybiBbY29sdW1ucy5tYXAoZm9ybWF0VmFsdWUpLmpvaW4o
ZGVsaW1pdGVyKV0uY29uY2F0KHByZWZvcm1hdEJvZHkocm93cywgY29sdW1ucykpLmpvaW4oIlxu
Iik7CiAgfQoKICBmdW5jdGlvbiBmb3JtYXRCb2R5KHJvd3MsIGNvbHVtbnMpIHsKICAgIGlmIChj
b2x1bW5zID09IG51bGwpIGNvbHVtbnMgPSBpbmZlckNvbHVtbnMocm93cyk7CiAgICByZXR1cm4g
cHJlZm9ybWF0Qm9keShyb3dzLCBjb2x1bW5zKS5qb2luKCJcbiIpOwogIH0KCiAgZnVuY3Rpb24g
Zm9ybWF0Um93cyhyb3dzKSB7CiAgICByZXR1cm4gcm93cy5tYXAoZm9ybWF0Um93KS5qb2luKCJc
biIpOwogIH0KCiAgZnVuY3Rpb24gZm9ybWF0Um93KHJvdykgewogICAgcmV0dXJuIHJvdy5tYXAo
Zm9ybWF0VmFsdWUpLmpvaW4oZGVsaW1pdGVyKTsKICB9CgogIGZ1bmN0aW9uIGZvcm1hdFZhbHVl
KHZhbHVlKSB7CiAgICByZXR1cm4gdmFsdWUgPT0gbnVsbCA/ICIiCiAgICAgICAgOiB2YWx1ZSBp
bnN0YW5jZW9mIERhdGUgPyBmb3JtYXREYXRlKHZhbHVlKQogICAgICAgIDogcmVGb3JtYXQudGVz
dCh2YWx1ZSArPSAiIikgPyAiXCIiICsgdmFsdWUucmVwbGFjZSgvIi9nLCAiXCJcIiIpICsgIlwi
IgogICAgICAgIDogdmFsdWU7CiAgfQoKICByZXR1cm4gewogICAgcGFyc2U6IHBhcnNlLAogICAg
cGFyc2VSb3dzOiBwYXJzZVJvd3MsCiAgICBmb3JtYXQ6IGZvcm1hdCwKICAgIGZvcm1hdEJvZHk6
IGZvcm1hdEJvZHksCiAgICBmb3JtYXRSb3dzOiBmb3JtYXRSb3dzLAogICAgZm9ybWF0Um93OiBm
b3JtYXRSb3csCiAgICBmb3JtYXRWYWx1ZTogZm9ybWF0VmFsdWUKICB9Owp9Cgp2YXIgY3N2ID0g
ZHN2Rm9ybWF0KCIsIik7Cgp2YXIgY3N2UGFyc2UgPSBjc3YucGFyc2U7CnZhciBjc3ZQYXJzZVJv
d3MgPSBjc3YucGFyc2VSb3dzOwp2YXIgY3N2Rm9ybWF0ID0gY3N2LmZvcm1hdDsKdmFyIGNzdkZv
cm1hdEJvZHkgPSBjc3YuZm9ybWF0Qm9keTsKdmFyIGNzdkZvcm1hdFJvd3MgPSBjc3YuZm9ybWF0
Um93czsKdmFyIGNzdkZvcm1hdFJvdyA9IGNzdi5mb3JtYXRSb3c7CnZhciBjc3ZGb3JtYXRWYWx1
ZSA9IGNzdi5mb3JtYXRWYWx1ZTsKCnZhciB0c3YgPSBkc3ZGb3JtYXQoIlx0Iik7Cgp2YXIgdHN2
UGFyc2UgPSB0c3YucGFyc2U7CnZhciB0c3ZQYXJzZVJvd3MgPSB0c3YucGFyc2VSb3dzOwp2YXIg
dHN2Rm9ybWF0ID0gdHN2LmZvcm1hdDsKdmFyIHRzdkZvcm1hdEJvZHkgPSB0c3YuZm9ybWF0Qm9k
eTsKdmFyIHRzdkZvcm1hdFJvd3MgPSB0c3YuZm9ybWF0Um93czsKdmFyIHRzdkZvcm1hdFJvdyA9
IHRzdi5mb3JtYXRSb3c7CnZhciB0c3ZGb3JtYXRWYWx1ZSA9IHRzdi5mb3JtYXRWYWx1ZTsKCmZ1
bmN0aW9uIGF1dG9UeXBlKG9iamVjdCkgewogIGZvciAodmFyIGtleSBpbiBvYmplY3QpIHsKICAg
IHZhciB2YWx1ZSA9IG9iamVjdFtrZXldLnRyaW0oKSwgbnVtYmVyLCBtOwogICAgaWYgKCF2YWx1
ZSkgdmFsdWUgPSBudWxsOwogICAgZWxzZSBpZiAodmFsdWUgPT09ICJ0cnVlIikgdmFsdWUgPSB0
cnVlOwogICAgZWxzZSBpZiAodmFsdWUgPT09ICJmYWxzZSIpIHZhbHVlID0gZmFsc2U7CiAgICBl
bHNlIGlmICh2YWx1ZSA9PT0gIk5hTiIpIHZhbHVlID0gTmFOOwogICAgZWxzZSBpZiAoIWlzTmFO
KG51bWJlciA9ICt2YWx1ZSkpIHZhbHVlID0gbnVtYmVyOwogICAgZWxzZSBpZiAobSA9IHZhbHVl
Lm1hdGNoKC9eKFstK11cZHsyfSk/XGR7NH0oLVxkezJ9KC1cZHsyfSk/KT8oVFxkezJ9OlxkezJ9
KDpcZHsyfShcLlxkezN9KT8pPyhafFstK11cZHsyfTpcZHsyfSk/KT8kLykpIHsKICAgICAgaWYg
KGZpeHR6ICYmICEhbVs0XSAmJiAhbVs3XSkgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKC8tL2csICIv
IikucmVwbGFjZSgvVC8sICIgIik7CiAgICAgIHZhbHVlID0gbmV3IERhdGUodmFsdWUpOwogICAg
fQogICAgZWxzZSBjb250aW51ZTsKICAgIG9iamVjdFtrZXldID0gdmFsdWU7CiAgfQogIHJldHVy
biBvYmplY3Q7Cn0KCi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9kMy9kMy1kc3YvaXNzdWVzLzQ1CnZh
ciBmaXh0eiA9IG5ldyBEYXRlKCIyMDE5LTAxLTAxVDAwOjAwIikuZ2V0SG91cnMoKSB8fCBuZXcg
RGF0ZSgiMjAxOS0wNy0wMVQwMDowMCIpLmdldEhvdXJzKCk7CgpmdW5jdGlvbiByZXNwb25zZUJs
b2IocmVzcG9uc2UpIHsKICBpZiAoIXJlc3BvbnNlLm9rKSB0aHJvdyBuZXcgRXJyb3IocmVzcG9u
c2Uuc3RhdHVzICsgIiAiICsgcmVzcG9uc2Uuc3RhdHVzVGV4dCk7CiAgcmV0dXJuIHJlc3BvbnNl
LmJsb2IoKTsKfQoKZnVuY3Rpb24gYmxvYihpbnB1dCwgaW5pdCkgewogIHJldHVybiBmZXRjaChp
bnB1dCwgaW5pdCkudGhlbihyZXNwb25zZUJsb2IpOwp9CgpmdW5jdGlvbiByZXNwb25zZUFycmF5
QnVmZmVyKHJlc3BvbnNlKSB7CiAgaWYgKCFyZXNwb25zZS5vaykgdGhyb3cgbmV3IEVycm9yKHJl
c3BvbnNlLnN0YXR1cyArICIgIiArIHJlc3BvbnNlLnN0YXR1c1RleHQpOwogIHJldHVybiByZXNw
b25zZS5hcnJheUJ1ZmZlcigpOwp9CgpmdW5jdGlvbiBidWZmZXIoaW5wdXQsIGluaXQpIHsKICBy
ZXR1cm4gZmV0Y2goaW5wdXQsIGluaXQpLnRoZW4ocmVzcG9uc2VBcnJheUJ1ZmZlcik7Cn0KCmZ1
bmN0aW9uIHJlc3BvbnNlVGV4dChyZXNwb25zZSkgewogIGlmICghcmVzcG9uc2Uub2spIHRocm93
IG5ldyBFcnJvcihyZXNwb25zZS5zdGF0dXMgKyAiICIgKyByZXNwb25zZS5zdGF0dXNUZXh0KTsK
ICByZXR1cm4gcmVzcG9uc2UudGV4dCgpOwp9CgpmdW5jdGlvbiB0ZXh0KGlucHV0LCBpbml0KSB7
CiAgcmV0dXJuIGZldGNoKGlucHV0LCBpbml0KS50aGVuKHJlc3BvbnNlVGV4dCk7Cn0KCmZ1bmN0
aW9uIGRzdlBhcnNlKHBhcnNlKSB7CiAgcmV0dXJuIGZ1bmN0aW9uKGlucHV0LCBpbml0LCByb3cp
IHsKICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAyICYmIHR5cGVvZiBpbml0ID09PSAiZnVu
Y3Rpb24iKSByb3cgPSBpbml0LCBpbml0ID0gdW5kZWZpbmVkOwogICAgcmV0dXJuIHRleHQoaW5w
dXQsIGluaXQpLnRoZW4oZnVuY3Rpb24ocmVzcG9uc2UpIHsKICAgICAgcmV0dXJuIHBhcnNlKHJl
c3BvbnNlLCByb3cpOwogICAgfSk7CiAgfTsKfQoKZnVuY3Rpb24gZHN2KGRlbGltaXRlciwgaW5w
dXQsIGluaXQsIHJvdykgewogIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAzICYmIHR5cGVvZiBp
bml0ID09PSAiZnVuY3Rpb24iKSByb3cgPSBpbml0LCBpbml0ID0gdW5kZWZpbmVkOwogIHZhciBm
b3JtYXQgPSBkc3ZGb3JtYXQoZGVsaW1pdGVyKTsKICByZXR1cm4gdGV4dChpbnB1dCwgaW5pdCku
dGhlbihmdW5jdGlvbihyZXNwb25zZSkgewogICAgcmV0dXJuIGZvcm1hdC5wYXJzZShyZXNwb25z
ZSwgcm93KTsKICB9KTsKfQoKdmFyIGNzdiQxID0gZHN2UGFyc2UoY3N2UGFyc2UpOwp2YXIgdHN2
JDEgPSBkc3ZQYXJzZSh0c3ZQYXJzZSk7CgpmdW5jdGlvbiBpbWFnZShpbnB1dCwgaW5pdCkgewog
IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHsKICAgIHZhciBp
bWFnZSA9IG5ldyBJbWFnZTsKICAgIGZvciAodmFyIGtleSBpbiBpbml0KSBpbWFnZVtrZXldID0g
aW5pdFtrZXldOwogICAgaW1hZ2Uub25lcnJvciA9IHJlamVjdDsKICAgIGltYWdlLm9ubG9hZCA9
IGZ1bmN0aW9uKCkgeyByZXNvbHZlKGltYWdlKTsgfTsKICAgIGltYWdlLnNyYyA9IGlucHV0Owog
IH0pOwp9CgpmdW5jdGlvbiByZXNwb25zZUpzb24ocmVzcG9uc2UpIHsKICBpZiAoIXJlc3BvbnNl
Lm9rKSB0aHJvdyBuZXcgRXJyb3IocmVzcG9uc2Uuc3RhdHVzICsgIiAiICsgcmVzcG9uc2Uuc3Rh
dHVzVGV4dCk7CiAgcmV0dXJuIHJlc3BvbnNlLmpzb24oKTsKfQoKZnVuY3Rpb24ganNvbihpbnB1
dCwgaW5pdCkgewogIHJldHVybiBmZXRjaChpbnB1dCwgaW5pdCkudGhlbihyZXNwb25zZUpzb24p
Owp9CgpmdW5jdGlvbiBwYXJzZXIodHlwZSkgewogIHJldHVybiBmdW5jdGlvbihpbnB1dCwgaW5p
dCkgIHsKICAgIHJldHVybiB0ZXh0KGlucHV0LCBpbml0KS50aGVuKGZ1bmN0aW9uKHRleHQpIHsK
ICAgICAgcmV0dXJuIChuZXcgRE9NUGFyc2VyKS5wYXJzZUZyb21TdHJpbmcodGV4dCwgdHlwZSk7
CiAgICB9KTsKICB9Owp9Cgp2YXIgeG1sID0gcGFyc2VyKCJhcHBsaWNhdGlvbi94bWwiKTsKCnZh
ciBodG1sID0gcGFyc2VyKCJ0ZXh0L2h0bWwiKTsKCnZhciBzdmcgPSBwYXJzZXIoImltYWdlL3N2
Zyt4bWwiKTsKCmZ1bmN0aW9uIGNlbnRlciQxKHgsIHkpIHsKICB2YXIgbm9kZXM7CgogIGlmICh4
ID09IG51bGwpIHggPSAwOwogIGlmICh5ID09IG51bGwpIHkgPSAwOwoKICBmdW5jdGlvbiBmb3Jj
ZSgpIHsKICAgIHZhciBpLAogICAgICAgIG4gPSBub2Rlcy5sZW5ndGgsCiAgICAgICAgbm9kZSwK
ICAgICAgICBzeCA9IDAsCiAgICAgICAgc3kgPSAwOwoKICAgIGZvciAoaSA9IDA7IGkgPCBuOyAr
K2kpIHsKICAgICAgbm9kZSA9IG5vZGVzW2ldLCBzeCArPSBub2RlLngsIHN5ICs9IG5vZGUueTsK
ICAgIH0KCiAgICBmb3IgKHN4ID0gc3ggLyBuIC0geCwgc3kgPSBzeSAvIG4gLSB5LCBpID0gMDsg
aSA8IG47ICsraSkgewogICAgICBub2RlID0gbm9kZXNbaV0sIG5vZGUueCAtPSBzeCwgbm9kZS55
IC09IHN5OwogICAgfQogIH0KCiAgZm9yY2UuaW5pdGlhbGl6ZSA9IGZ1bmN0aW9uKF8pIHsKICAg
IG5vZGVzID0gXzsKICB9OwoKICBmb3JjZS54ID0gZnVuY3Rpb24oXykgewogICAgcmV0dXJuIGFy
Z3VtZW50cy5sZW5ndGggPyAoeCA9ICtfLCBmb3JjZSkgOiB4OwogIH07CgogIGZvcmNlLnkgPSBm
dW5jdGlvbihfKSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh5ID0gK18sIGZvcmNl
KSA6IHk7CiAgfTsKCiAgcmV0dXJuIGZvcmNlOwp9CgpmdW5jdGlvbiBjb25zdGFudCQ3KHgpIHsK
ICByZXR1cm4gZnVuY3Rpb24oKSB7CiAgICByZXR1cm4geDsKICB9Owp9CgpmdW5jdGlvbiBqaWdn
bGUoKSB7CiAgcmV0dXJuIChNYXRoLnJhbmRvbSgpIC0gMC41KSAqIDFlLTY7Cn0KCmZ1bmN0aW9u
IHRyZWVfYWRkKGQpIHsKICB2YXIgeCA9ICt0aGlzLl94LmNhbGwobnVsbCwgZCksCiAgICAgIHkg
PSArdGhpcy5feS5jYWxsKG51bGwsIGQpOwogIHJldHVybiBhZGQodGhpcy5jb3Zlcih4LCB5KSwg
eCwgeSwgZCk7Cn0KCmZ1bmN0aW9uIGFkZCh0cmVlLCB4LCB5LCBkKSB7CiAgaWYgKGlzTmFOKHgp
IHx8IGlzTmFOKHkpKSByZXR1cm4gdHJlZTsgLy8gaWdub3JlIGludmFsaWQgcG9pbnRzCgogIHZh
ciBwYXJlbnQsCiAgICAgIG5vZGUgPSB0cmVlLl9yb290LAogICAgICBsZWFmID0ge2RhdGE6IGR9
LAogICAgICB4MCA9IHRyZWUuX3gwLAogICAgICB5MCA9IHRyZWUuX3kwLAogICAgICB4MSA9IHRy
ZWUuX3gxLAogICAgICB5MSA9IHRyZWUuX3kxLAogICAgICB4bSwKICAgICAgeW0sCiAgICAgIHhw
LAogICAgICB5cCwKICAgICAgcmlnaHQsCiAgICAgIGJvdHRvbSwKICAgICAgaSwKICAgICAgajsK
CiAgLy8gSWYgdGhlIHRyZWUgaXMgZW1wdHksIGluaXRpYWxpemUgdGhlIHJvb3QgYXMgYSBsZWFm
LgogIGlmICghbm9kZSkgcmV0dXJuIHRyZWUuX3Jvb3QgPSBsZWFmLCB0cmVlOwoKICAvLyBGaW5k
IHRoZSBleGlzdGluZyBsZWFmIGZvciB0aGUgbmV3IHBvaW50LCBvciBhZGQgaXQuCiAgd2hpbGUg
KG5vZGUubGVuZ3RoKSB7CiAgICBpZiAocmlnaHQgPSB4ID49ICh4bSA9ICh4MCArIHgxKSAvIDIp
KSB4MCA9IHhtOyBlbHNlIHgxID0geG07CiAgICBpZiAoYm90dG9tID0geSA+PSAoeW0gPSAoeTAg
KyB5MSkgLyAyKSkgeTAgPSB5bTsgZWxzZSB5MSA9IHltOwogICAgaWYgKHBhcmVudCA9IG5vZGUs
ICEobm9kZSA9IG5vZGVbaSA9IGJvdHRvbSA8PCAxIHwgcmlnaHRdKSkgcmV0dXJuIHBhcmVudFtp
XSA9IGxlYWYsIHRyZWU7CiAgfQoKICAvLyBJcyB0aGUgbmV3IHBvaW50IGlzIGV4YWN0bHkgY29p
bmNpZGVudCB3aXRoIHRoZSBleGlzdGluZyBwb2ludD8KICB4cCA9ICt0cmVlLl94LmNhbGwobnVs
bCwgbm9kZS5kYXRhKTsKICB5cCA9ICt0cmVlLl95LmNhbGwobnVsbCwgbm9kZS5kYXRhKTsKICBp
ZiAoeCA9PT0geHAgJiYgeSA9PT0geXApIHJldHVybiBsZWFmLm5leHQgPSBub2RlLCBwYXJlbnQg
PyBwYXJlbnRbaV0gPSBsZWFmIDogdHJlZS5fcm9vdCA9IGxlYWYsIHRyZWU7CgogIC8vIE90aGVy
d2lzZSwgc3BsaXQgdGhlIGxlYWYgbm9kZSB1bnRpbCB0aGUgb2xkIGFuZCBuZXcgcG9pbnQgYXJl
IHNlcGFyYXRlZC4KICBkbyB7CiAgICBwYXJlbnQgPSBwYXJlbnQgPyBwYXJlbnRbaV0gPSBuZXcg
QXJyYXkoNCkgOiB0cmVlLl9yb290ID0gbmV3IEFycmF5KDQpOwogICAgaWYgKHJpZ2h0ID0geCA+
PSAoeG0gPSAoeDAgKyB4MSkgLyAyKSkgeDAgPSB4bTsgZWxzZSB4MSA9IHhtOwogICAgaWYgKGJv
dHRvbSA9IHkgPj0gKHltID0gKHkwICsgeTEpIC8gMikpIHkwID0geW07IGVsc2UgeTEgPSB5bTsK
ICB9IHdoaWxlICgoaSA9IGJvdHRvbSA8PCAxIHwgcmlnaHQpID09PSAoaiA9ICh5cCA+PSB5bSkg
PDwgMSB8ICh4cCA+PSB4bSkpKTsKICByZXR1cm4gcGFyZW50W2pdID0gbm9kZSwgcGFyZW50W2ld
ID0gbGVhZiwgdHJlZTsKfQoKZnVuY3Rpb24gYWRkQWxsKGRhdGEpIHsKICB2YXIgZCwgaSwgbiA9
IGRhdGEubGVuZ3RoLAogICAgICB4LAogICAgICB5LAogICAgICB4eiA9IG5ldyBBcnJheShuKSwK
ICAgICAgeXogPSBuZXcgQXJyYXkobiksCiAgICAgIHgwID0gSW5maW5pdHksCiAgICAgIHkwID0g
SW5maW5pdHksCiAgICAgIHgxID0gLUluZmluaXR5LAogICAgICB5MSA9IC1JbmZpbml0eTsKCiAg
Ly8gQ29tcHV0ZSB0aGUgcG9pbnRzIGFuZCB0aGVpciBleHRlbnQuCiAgZm9yIChpID0gMDsgaSA8
IG47ICsraSkgewogICAgaWYgKGlzTmFOKHggPSArdGhpcy5feC5jYWxsKG51bGwsIGQgPSBkYXRh
W2ldKSkgfHwgaXNOYU4oeSA9ICt0aGlzLl95LmNhbGwobnVsbCwgZCkpKSBjb250aW51ZTsKICAg
IHh6W2ldID0geDsKICAgIHl6W2ldID0geTsKICAgIGlmICh4IDwgeDApIHgwID0geDsKICAgIGlm
ICh4ID4geDEpIHgxID0geDsKICAgIGlmICh5IDwgeTApIHkwID0geTsKICAgIGlmICh5ID4geTEp
IHkxID0geTsKICB9CgogIC8vIElmIHRoZXJlIHdlcmUgbm8gKHZhbGlkKSBwb2ludHMsIGFib3J0
LgogIGlmICh4MCA+IHgxIHx8IHkwID4geTEpIHJldHVybiB0aGlzOwoKICAvLyBFeHBhbmQgdGhl
IHRyZWUgdG8gY292ZXIgdGhlIG5ldyBwb2ludHMuCiAgdGhpcy5jb3Zlcih4MCwgeTApLmNvdmVy
KHgxLCB5MSk7CgogIC8vIEFkZCB0aGUgbmV3IHBvaW50cy4KICBmb3IgKGkgPSAwOyBpIDwgbjsg
KytpKSB7CiAgICBhZGQodGhpcywgeHpbaV0sIHl6W2ldLCBkYXRhW2ldKTsKICB9CgogIHJldHVy
biB0aGlzOwp9CgpmdW5jdGlvbiB0cmVlX2NvdmVyKHgsIHkpIHsKICBpZiAoaXNOYU4oeCA9ICt4
KSB8fCBpc05hTih5ID0gK3kpKSByZXR1cm4gdGhpczsgLy8gaWdub3JlIGludmFsaWQgcG9pbnRz
CgogIHZhciB4MCA9IHRoaXMuX3gwLAogICAgICB5MCA9IHRoaXMuX3kwLAogICAgICB4MSA9IHRo
aXMuX3gxLAogICAgICB5MSA9IHRoaXMuX3kxOwoKICAvLyBJZiB0aGUgcXVhZHRyZWUgaGFzIG5v
IGV4dGVudCwgaW5pdGlhbGl6ZSB0aGVtLgogIC8vIEludGVnZXIgZXh0ZW50IGFyZSBuZWNlc3Nh
cnkgc28gdGhhdCBpZiB3ZSBsYXRlciBkb3VibGUgdGhlIGV4dGVudCwKICAvLyB0aGUgZXhpc3Rp
bmcgcXVhZHJhbnQgYm91bmRhcmllcyBkb27igJl0IGNoYW5nZSBkdWUgdG8gZmxvYXRpbmcgcG9p
bnQgZXJyb3IhCiAgaWYgKGlzTmFOKHgwKSkgewogICAgeDEgPSAoeDAgPSBNYXRoLmZsb29yKHgp
KSArIDE7CiAgICB5MSA9ICh5MCA9IE1hdGguZmxvb3IoeSkpICsgMTsKICB9CgogIC8vIE90aGVy
d2lzZSwgZG91YmxlIHJlcGVhdGVkbHkgdG8gY292ZXIuCiAgZWxzZSB7CiAgICB2YXIgeiA9IHgx
IC0geDAsCiAgICAgICAgbm9kZSA9IHRoaXMuX3Jvb3QsCiAgICAgICAgcGFyZW50LAogICAgICAg
IGk7CgogICAgd2hpbGUgKHgwID4geCB8fCB4ID49IHgxIHx8IHkwID4geSB8fCB5ID49IHkxKSB7
CiAgICAgIGkgPSAoeSA8IHkwKSA8PCAxIHwgKHggPCB4MCk7CiAgICAgIHBhcmVudCA9IG5ldyBB
cnJheSg0KSwgcGFyZW50W2ldID0gbm9kZSwgbm9kZSA9IHBhcmVudCwgeiAqPSAyOwogICAgICBz
d2l0Y2ggKGkpIHsKICAgICAgICBjYXNlIDA6IHgxID0geDAgKyB6LCB5MSA9IHkwICsgejsgYnJl
YWs7CiAgICAgICAgY2FzZSAxOiB4MCA9IHgxIC0geiwgeTEgPSB5MCArIHo7IGJyZWFrOwogICAg
ICAgIGNhc2UgMjogeDEgPSB4MCArIHosIHkwID0geTEgLSB6OyBicmVhazsKICAgICAgICBjYXNl
IDM6IHgwID0geDEgLSB6LCB5MCA9IHkxIC0gejsgYnJlYWs7CiAgICAgIH0KICAgIH0KCiAgICBp
ZiAodGhpcy5fcm9vdCAmJiB0aGlzLl9yb290Lmxlbmd0aCkgdGhpcy5fcm9vdCA9IG5vZGU7CiAg
fQoKICB0aGlzLl94MCA9IHgwOwogIHRoaXMuX3kwID0geTA7CiAgdGhpcy5feDEgPSB4MTsKICB0
aGlzLl95MSA9IHkxOwogIHJldHVybiB0aGlzOwp9CgpmdW5jdGlvbiB0cmVlX2RhdGEoKSB7CiAg
dmFyIGRhdGEgPSBbXTsKICB0aGlzLnZpc2l0KGZ1bmN0aW9uKG5vZGUpIHsKICAgIGlmICghbm9k
ZS5sZW5ndGgpIGRvIGRhdGEucHVzaChub2RlLmRhdGEpOyB3aGlsZSAobm9kZSA9IG5vZGUubmV4
dCkKICB9KTsKICByZXR1cm4gZGF0YTsKfQoKZnVuY3Rpb24gdHJlZV9leHRlbnQoXykgewogIHJl
dHVybiBhcmd1bWVudHMubGVuZ3RoCiAgICAgID8gdGhpcy5jb3ZlcigrX1swXVswXSwgK19bMF1b
MV0pLmNvdmVyKCtfWzFdWzBdLCArX1sxXVsxXSkKICAgICAgOiBpc05hTih0aGlzLl94MCkgPyB1
bmRlZmluZWQgOiBbW3RoaXMuX3gwLCB0aGlzLl95MF0sIFt0aGlzLl94MSwgdGhpcy5feTFdXTsK
fQoKZnVuY3Rpb24gUXVhZChub2RlLCB4MCwgeTAsIHgxLCB5MSkgewogIHRoaXMubm9kZSA9IG5v
ZGU7CiAgdGhpcy54MCA9IHgwOwogIHRoaXMueTAgPSB5MDsKICB0aGlzLngxID0geDE7CiAgdGhp
cy55MSA9IHkxOwp9CgpmdW5jdGlvbiB0cmVlX2ZpbmQoeCwgeSwgcmFkaXVzKSB7CiAgdmFyIGRh
dGEsCiAgICAgIHgwID0gdGhpcy5feDAsCiAgICAgIHkwID0gdGhpcy5feTAsCiAgICAgIHgxLAog
ICAgICB5MSwKICAgICAgeDIsCiAgICAgIHkyLAogICAgICB4MyA9IHRoaXMuX3gxLAogICAgICB5
MyA9IHRoaXMuX3kxLAogICAgICBxdWFkcyA9IFtdLAogICAgICBub2RlID0gdGhpcy5fcm9vdCwK
ICAgICAgcSwKICAgICAgaTsKCiAgaWYgKG5vZGUpIHF1YWRzLnB1c2gobmV3IFF1YWQobm9kZSwg
eDAsIHkwLCB4MywgeTMpKTsKICBpZiAocmFkaXVzID09IG51bGwpIHJhZGl1cyA9IEluZmluaXR5
OwogIGVsc2UgewogICAgeDAgPSB4IC0gcmFkaXVzLCB5MCA9IHkgLSByYWRpdXM7CiAgICB4MyA9
IHggKyByYWRpdXMsIHkzID0geSArIHJhZGl1czsKICAgIHJhZGl1cyAqPSByYWRpdXM7CiAgfQoK
ICB3aGlsZSAocSA9IHF1YWRzLnBvcCgpKSB7CgogICAgLy8gU3RvcCBzZWFyY2hpbmcgaWYgdGhp
cyBxdWFkcmFudCBjYW7igJl0IGNvbnRhaW4gYSBjbG9zZXIgbm9kZS4KICAgIGlmICghKG5vZGUg
PSBxLm5vZGUpCiAgICAgICAgfHwgKHgxID0gcS54MCkgPiB4MwogICAgICAgIHx8ICh5MSA9IHEu
eTApID4geTMKICAgICAgICB8fCAoeDIgPSBxLngxKSA8IHgwCiAgICAgICAgfHwgKHkyID0gcS55
MSkgPCB5MCkgY29udGludWU7CgogICAgLy8gQmlzZWN0IHRoZSBjdXJyZW50IHF1YWRyYW50Lgog
ICAgaWYgKG5vZGUubGVuZ3RoKSB7CiAgICAgIHZhciB4bSA9ICh4MSArIHgyKSAvIDIsCiAgICAg
ICAgICB5bSA9ICh5MSArIHkyKSAvIDI7CgogICAgICBxdWFkcy5wdXNoKAogICAgICAgIG5ldyBR
dWFkKG5vZGVbM10sIHhtLCB5bSwgeDIsIHkyKSwKICAgICAgICBuZXcgUXVhZChub2RlWzJdLCB4
MSwgeW0sIHhtLCB5MiksCiAgICAgICAgbmV3IFF1YWQobm9kZVsxXSwgeG0sIHkxLCB4MiwgeW0p
LAogICAgICAgIG5ldyBRdWFkKG5vZGVbMF0sIHgxLCB5MSwgeG0sIHltKQogICAgICApOwoKICAg
ICAgLy8gVmlzaXQgdGhlIGNsb3Nlc3QgcXVhZHJhbnQgZmlyc3QuCiAgICAgIGlmIChpID0gKHkg
Pj0geW0pIDw8IDEgfCAoeCA+PSB4bSkpIHsKICAgICAgICBxID0gcXVhZHNbcXVhZHMubGVuZ3Ro
IC0gMV07CiAgICAgICAgcXVhZHNbcXVhZHMubGVuZ3RoIC0gMV0gPSBxdWFkc1txdWFkcy5sZW5n
dGggLSAxIC0gaV07CiAgICAgICAgcXVhZHNbcXVhZHMubGVuZ3RoIC0gMSAtIGldID0gcTsKICAg
ICAgfQogICAgfQoKICAgIC8vIFZpc2l0IHRoaXMgcG9pbnQuIChWaXNpdGluZyBjb2luY2lkZW50
IHBvaW50cyBpc27igJl0IG5lY2Vzc2FyeSEpCiAgICBlbHNlIHsKICAgICAgdmFyIGR4ID0geCAt
ICt0aGlzLl94LmNhbGwobnVsbCwgbm9kZS5kYXRhKSwKICAgICAgICAgIGR5ID0geSAtICt0aGlz
Ll95LmNhbGwobnVsbCwgbm9kZS5kYXRhKSwKICAgICAgICAgIGQyID0gZHggKiBkeCArIGR5ICog
ZHk7CiAgICAgIGlmIChkMiA8IHJhZGl1cykgewogICAgICAgIHZhciBkID0gTWF0aC5zcXJ0KHJh
ZGl1cyA9IGQyKTsKICAgICAgICB4MCA9IHggLSBkLCB5MCA9IHkgLSBkOwogICAgICAgIHgzID0g
eCArIGQsIHkzID0geSArIGQ7CiAgICAgICAgZGF0YSA9IG5vZGUuZGF0YTsKICAgICAgfQogICAg
fQogIH0KCiAgcmV0dXJuIGRhdGE7Cn0KCmZ1bmN0aW9uIHRyZWVfcmVtb3ZlKGQpIHsKICBpZiAo
aXNOYU4oeCA9ICt0aGlzLl94LmNhbGwobnVsbCwgZCkpIHx8IGlzTmFOKHkgPSArdGhpcy5feS5j
YWxsKG51bGwsIGQpKSkgcmV0dXJuIHRoaXM7IC8vIGlnbm9yZSBpbnZhbGlkIHBvaW50cwoKICB2
YXIgcGFyZW50LAogICAgICBub2RlID0gdGhpcy5fcm9vdCwKICAgICAgcmV0YWluZXIsCiAgICAg
IHByZXZpb3VzLAogICAgICBuZXh0LAogICAgICB4MCA9IHRoaXMuX3gwLAogICAgICB5MCA9IHRo
aXMuX3kwLAogICAgICB4MSA9IHRoaXMuX3gxLAogICAgICB5MSA9IHRoaXMuX3kxLAogICAgICB4
LAogICAgICB5LAogICAgICB4bSwKICAgICAgeW0sCiAgICAgIHJpZ2h0LAogICAgICBib3R0b20s
CiAgICAgIGksCiAgICAgIGo7CgogIC8vIElmIHRoZSB0cmVlIGlzIGVtcHR5LCBpbml0aWFsaXpl
IHRoZSByb290IGFzIGEgbGVhZi4KICBpZiAoIW5vZGUpIHJldHVybiB0aGlzOwoKICAvLyBGaW5k
IHRoZSBsZWFmIG5vZGUgZm9yIHRoZSBwb2ludC4KICAvLyBXaGlsZSBkZXNjZW5kaW5nLCBhbHNv
IHJldGFpbiB0aGUgZGVlcGVzdCBwYXJlbnQgd2l0aCBhIG5vbi1yZW1vdmVkIHNpYmxpbmcuCiAg
aWYgKG5vZGUubGVuZ3RoKSB3aGlsZSAodHJ1ZSkgewogICAgaWYgKHJpZ2h0ID0geCA+PSAoeG0g
PSAoeDAgKyB4MSkgLyAyKSkgeDAgPSB4bTsgZWxzZSB4MSA9IHhtOwogICAgaWYgKGJvdHRvbSA9
IHkgPj0gKHltID0gKHkwICsgeTEpIC8gMikpIHkwID0geW07IGVsc2UgeTEgPSB5bTsKICAgIGlm
ICghKHBhcmVudCA9IG5vZGUsIG5vZGUgPSBub2RlW2kgPSBib3R0b20gPDwgMSB8IHJpZ2h0XSkp
IHJldHVybiB0aGlzOwogICAgaWYgKCFub2RlLmxlbmd0aCkgYnJlYWs7CiAgICBpZiAocGFyZW50
WyhpICsgMSkgJiAzXSB8fCBwYXJlbnRbKGkgKyAyKSAmIDNdIHx8IHBhcmVudFsoaSArIDMpICYg
M10pIHJldGFpbmVyID0gcGFyZW50LCBqID0gaTsKICB9CgogIC8vIEZpbmQgdGhlIHBvaW50IHRv
IHJlbW92ZS4KICB3aGlsZSAobm9kZS5kYXRhICE9PSBkKSBpZiAoIShwcmV2aW91cyA9IG5vZGUs
IG5vZGUgPSBub2RlLm5leHQpKSByZXR1cm4gdGhpczsKICBpZiAobmV4dCA9IG5vZGUubmV4dCkg
ZGVsZXRlIG5vZGUubmV4dDsKCiAgLy8gSWYgdGhlcmUgYXJlIG11bHRpcGxlIGNvaW5jaWRlbnQg
cG9pbnRzLCByZW1vdmUganVzdCB0aGUgcG9pbnQuCiAgaWYgKHByZXZpb3VzKSByZXR1cm4gKG5l
eHQgPyBwcmV2aW91cy5uZXh0ID0gbmV4dCA6IGRlbGV0ZSBwcmV2aW91cy5uZXh0KSwgdGhpczsK
CiAgLy8gSWYgdGhpcyBpcyB0aGUgcm9vdCBwb2ludCwgcmVtb3ZlIGl0LgogIGlmICghcGFyZW50
KSByZXR1cm4gdGhpcy5fcm9vdCA9IG5leHQsIHRoaXM7CgogIC8vIFJlbW92ZSB0aGlzIGxlYWYu
CiAgbmV4dCA/IHBhcmVudFtpXSA9IG5leHQgOiBkZWxldGUgcGFyZW50W2ldOwoKICAvLyBJZiB0
aGUgcGFyZW50IG5vdyBjb250YWlucyBleGFjdGx5IG9uZSBsZWFmLCBjb2xsYXBzZSBzdXBlcmZs
dW91cyBwYXJlbnRzLgogIGlmICgobm9kZSA9IHBhcmVudFswXSB8fCBwYXJlbnRbMV0gfHwgcGFy
ZW50WzJdIHx8IHBhcmVudFszXSkKICAgICAgJiYgbm9kZSA9PT0gKHBhcmVudFszXSB8fCBwYXJl
bnRbMl0gfHwgcGFyZW50WzFdIHx8IHBhcmVudFswXSkKICAgICAgJiYgIW5vZGUubGVuZ3RoKSB7
CiAgICBpZiAocmV0YWluZXIpIHJldGFpbmVyW2pdID0gbm9kZTsKICAgIGVsc2UgdGhpcy5fcm9v
dCA9IG5vZGU7CiAgfQoKICByZXR1cm4gdGhpczsKfQoKZnVuY3Rpb24gcmVtb3ZlQWxsKGRhdGEp
IHsKICBmb3IgKHZhciBpID0gMCwgbiA9IGRhdGEubGVuZ3RoOyBpIDwgbjsgKytpKSB0aGlzLnJl
bW92ZShkYXRhW2ldKTsKICByZXR1cm4gdGhpczsKfQoKZnVuY3Rpb24gdHJlZV9yb290KCkgewog
IHJldHVybiB0aGlzLl9yb290Owp9CgpmdW5jdGlvbiB0cmVlX3NpemUoKSB7CiAgdmFyIHNpemUg
PSAwOwogIHRoaXMudmlzaXQoZnVuY3Rpb24obm9kZSkgewogICAgaWYgKCFub2RlLmxlbmd0aCkg
ZG8gKytzaXplOyB3aGlsZSAobm9kZSA9IG5vZGUubmV4dCkKICB9KTsKICByZXR1cm4gc2l6ZTsK
fQoKZnVuY3Rpb24gdHJlZV92aXNpdChjYWxsYmFjaykgewogIHZhciBxdWFkcyA9IFtdLCBxLCBu
b2RlID0gdGhpcy5fcm9vdCwgY2hpbGQsIHgwLCB5MCwgeDEsIHkxOwogIGlmIChub2RlKSBxdWFk
cy5wdXNoKG5ldyBRdWFkKG5vZGUsIHRoaXMuX3gwLCB0aGlzLl95MCwgdGhpcy5feDEsIHRoaXMu
X3kxKSk7CiAgd2hpbGUgKHEgPSBxdWFkcy5wb3AoKSkgewogICAgaWYgKCFjYWxsYmFjayhub2Rl
ID0gcS5ub2RlLCB4MCA9IHEueDAsIHkwID0gcS55MCwgeDEgPSBxLngxLCB5MSA9IHEueTEpICYm
IG5vZGUubGVuZ3RoKSB7CiAgICAgIHZhciB4bSA9ICh4MCArIHgxKSAvIDIsIHltID0gKHkwICsg
eTEpIC8gMjsKICAgICAgaWYgKGNoaWxkID0gbm9kZVszXSkgcXVhZHMucHVzaChuZXcgUXVhZChj
aGlsZCwgeG0sIHltLCB4MSwgeTEpKTsKICAgICAgaWYgKGNoaWxkID0gbm9kZVsyXSkgcXVhZHMu
cHVzaChuZXcgUXVhZChjaGlsZCwgeDAsIHltLCB4bSwgeTEpKTsKICAgICAgaWYgKGNoaWxkID0g
bm9kZVsxXSkgcXVhZHMucHVzaChuZXcgUXVhZChjaGlsZCwgeG0sIHkwLCB4MSwgeW0pKTsKICAg
ICAgaWYgKGNoaWxkID0gbm9kZVswXSkgcXVhZHMucHVzaChuZXcgUXVhZChjaGlsZCwgeDAsIHkw
LCB4bSwgeW0pKTsKICAgIH0KICB9CiAgcmV0dXJuIHRoaXM7Cn0KCmZ1bmN0aW9uIHRyZWVfdmlz
aXRBZnRlcihjYWxsYmFjaykgewogIHZhciBxdWFkcyA9IFtdLCBuZXh0ID0gW10sIHE7CiAgaWYg
KHRoaXMuX3Jvb3QpIHF1YWRzLnB1c2gobmV3IFF1YWQodGhpcy5fcm9vdCwgdGhpcy5feDAsIHRo
aXMuX3kwLCB0aGlzLl94MSwgdGhpcy5feTEpKTsKICB3aGlsZSAocSA9IHF1YWRzLnBvcCgpKSB7
CiAgICB2YXIgbm9kZSA9IHEubm9kZTsKICAgIGlmIChub2RlLmxlbmd0aCkgewogICAgICB2YXIg
Y2hpbGQsIHgwID0gcS54MCwgeTAgPSBxLnkwLCB4MSA9IHEueDEsIHkxID0gcS55MSwgeG0gPSAo
eDAgKyB4MSkgLyAyLCB5bSA9ICh5MCArIHkxKSAvIDI7CiAgICAgIGlmIChjaGlsZCA9IG5vZGVb
MF0pIHF1YWRzLnB1c2gobmV3IFF1YWQoY2hpbGQsIHgwLCB5MCwgeG0sIHltKSk7CiAgICAgIGlm
IChjaGlsZCA9IG5vZGVbMV0pIHF1YWRzLnB1c2gobmV3IFF1YWQoY2hpbGQsIHhtLCB5MCwgeDEs
IHltKSk7CiAgICAgIGlmIChjaGlsZCA9IG5vZGVbMl0pIHF1YWRzLnB1c2gobmV3IFF1YWQoY2hp
bGQsIHgwLCB5bSwgeG0sIHkxKSk7CiAgICAgIGlmIChjaGlsZCA9IG5vZGVbM10pIHF1YWRzLnB1
c2gobmV3IFF1YWQoY2hpbGQsIHhtLCB5bSwgeDEsIHkxKSk7CiAgICB9CiAgICBuZXh0LnB1c2go
cSk7CiAgfQogIHdoaWxlIChxID0gbmV4dC5wb3AoKSkgewogICAgY2FsbGJhY2socS5ub2RlLCBx
LngwLCBxLnkwLCBxLngxLCBxLnkxKTsKICB9CiAgcmV0dXJuIHRoaXM7Cn0KCmZ1bmN0aW9uIGRl
ZmF1bHRYJDEoZCkgewogIHJldHVybiBkWzBdOwp9CgpmdW5jdGlvbiB0cmVlX3goXykgewogIHJl
dHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHRoaXMuX3ggPSBfLCB0aGlzKSA6IHRoaXMuX3g7Cn0K
CmZ1bmN0aW9uIGRlZmF1bHRZJDEoZCkgewogIHJldHVybiBkWzFdOwp9CgpmdW5jdGlvbiB0cmVl
X3koXykgewogIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHRoaXMuX3kgPSBfLCB0aGlzKSA6
IHRoaXMuX3k7Cn0KCmZ1bmN0aW9uIHF1YWR0cmVlKG5vZGVzLCB4LCB5KSB7CiAgdmFyIHRyZWUg
PSBuZXcgUXVhZHRyZWUoeCA9PSBudWxsID8gZGVmYXVsdFgkMSA6IHgsIHkgPT0gbnVsbCA/IGRl
ZmF1bHRZJDEgOiB5LCBOYU4sIE5hTiwgTmFOLCBOYU4pOwogIHJldHVybiBub2RlcyA9PSBudWxs
ID8gdHJlZSA6IHRyZWUuYWRkQWxsKG5vZGVzKTsKfQoKZnVuY3Rpb24gUXVhZHRyZWUoeCwgeSwg
eDAsIHkwLCB4MSwgeTEpIHsKICB0aGlzLl94ID0geDsKICB0aGlzLl95ID0geTsKICB0aGlzLl94
MCA9IHgwOwogIHRoaXMuX3kwID0geTA7CiAgdGhpcy5feDEgPSB4MTsKICB0aGlzLl95MSA9IHkx
OwogIHRoaXMuX3Jvb3QgPSB1bmRlZmluZWQ7Cn0KCmZ1bmN0aW9uIGxlYWZfY29weShsZWFmKSB7
CiAgdmFyIGNvcHkgPSB7ZGF0YTogbGVhZi5kYXRhfSwgbmV4dCA9IGNvcHk7CiAgd2hpbGUgKGxl
YWYgPSBsZWFmLm5leHQpIG5leHQgPSBuZXh0Lm5leHQgPSB7ZGF0YTogbGVhZi5kYXRhfTsKICBy
ZXR1cm4gY29weTsKfQoKdmFyIHRyZWVQcm90byA9IHF1YWR0cmVlLnByb3RvdHlwZSA9IFF1YWR0
cmVlLnByb3RvdHlwZTsKCnRyZWVQcm90by5jb3B5ID0gZnVuY3Rpb24oKSB7CiAgdmFyIGNvcHkg
PSBuZXcgUXVhZHRyZWUodGhpcy5feCwgdGhpcy5feSwgdGhpcy5feDAsIHRoaXMuX3kwLCB0aGlz
Ll94MSwgdGhpcy5feTEpLAogICAgICBub2RlID0gdGhpcy5fcm9vdCwKICAgICAgbm9kZXMsCiAg
ICAgIGNoaWxkOwoKICBpZiAoIW5vZGUpIHJldHVybiBjb3B5OwoKICBpZiAoIW5vZGUubGVuZ3Ro
KSByZXR1cm4gY29weS5fcm9vdCA9IGxlYWZfY29weShub2RlKSwgY29weTsKCiAgbm9kZXMgPSBb
e3NvdXJjZTogbm9kZSwgdGFyZ2V0OiBjb3B5Ll9yb290ID0gbmV3IEFycmF5KDQpfV07CiAgd2hp
bGUgKG5vZGUgPSBub2Rlcy5wb3AoKSkgewogICAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyArK2kp
IHsKICAgICAgaWYgKGNoaWxkID0gbm9kZS5zb3VyY2VbaV0pIHsKICAgICAgICBpZiAoY2hpbGQu
bGVuZ3RoKSBub2Rlcy5wdXNoKHtzb3VyY2U6IGNoaWxkLCB0YXJnZXQ6IG5vZGUudGFyZ2V0W2ld
ID0gbmV3IEFycmF5KDQpfSk7CiAgICAgICAgZWxzZSBub2RlLnRhcmdldFtpXSA9IGxlYWZfY29w
eShjaGlsZCk7CiAgICAgIH0KICAgIH0KICB9CgogIHJldHVybiBjb3B5Owp9OwoKdHJlZVByb3Rv
LmFkZCA9IHRyZWVfYWRkOwp0cmVlUHJvdG8uYWRkQWxsID0gYWRkQWxsOwp0cmVlUHJvdG8uY292
ZXIgPSB0cmVlX2NvdmVyOwp0cmVlUHJvdG8uZGF0YSA9IHRyZWVfZGF0YTsKdHJlZVByb3RvLmV4
dGVudCA9IHRyZWVfZXh0ZW50Owp0cmVlUHJvdG8uZmluZCA9IHRyZWVfZmluZDsKdHJlZVByb3Rv
LnJlbW92ZSA9IHRyZWVfcmVtb3ZlOwp0cmVlUHJvdG8ucmVtb3ZlQWxsID0gcmVtb3ZlQWxsOwp0
cmVlUHJvdG8ucm9vdCA9IHRyZWVfcm9vdDsKdHJlZVByb3RvLnNpemUgPSB0cmVlX3NpemU7CnRy
ZWVQcm90by52aXNpdCA9IHRyZWVfdmlzaXQ7CnRyZWVQcm90by52aXNpdEFmdGVyID0gdHJlZV92
aXNpdEFmdGVyOwp0cmVlUHJvdG8ueCA9IHRyZWVfeDsKdHJlZVByb3RvLnkgPSB0cmVlX3k7Cgpm
dW5jdGlvbiB4KGQpIHsKICByZXR1cm4gZC54ICsgZC52eDsKfQoKZnVuY3Rpb24geShkKSB7CiAg
cmV0dXJuIGQueSArIGQudnk7Cn0KCmZ1bmN0aW9uIGNvbGxpZGUocmFkaXVzKSB7CiAgdmFyIG5v
ZGVzLAogICAgICByYWRpaSwKICAgICAgc3RyZW5ndGggPSAxLAogICAgICBpdGVyYXRpb25zID0g
MTsKCiAgaWYgKHR5cGVvZiByYWRpdXMgIT09ICJmdW5jdGlvbiIpIHJhZGl1cyA9IGNvbnN0YW50
JDcocmFkaXVzID09IG51bGwgPyAxIDogK3JhZGl1cyk7CgogIGZ1bmN0aW9uIGZvcmNlKCkgewog
ICAgdmFyIGksIG4gPSBub2Rlcy5sZW5ndGgsCiAgICAgICAgdHJlZSwKICAgICAgICBub2RlLAog
ICAgICAgIHhpLAogICAgICAgIHlpLAogICAgICAgIHJpLAogICAgICAgIHJpMjsKCiAgICBmb3Ig
KHZhciBrID0gMDsgayA8IGl0ZXJhdGlvbnM7ICsraykgewogICAgICB0cmVlID0gcXVhZHRyZWUo
bm9kZXMsIHgsIHkpLnZpc2l0QWZ0ZXIocHJlcGFyZSk7CiAgICAgIGZvciAoaSA9IDA7IGkgPCBu
OyArK2kpIHsKICAgICAgICBub2RlID0gbm9kZXNbaV07CiAgICAgICAgcmkgPSByYWRpaVtub2Rl
LmluZGV4XSwgcmkyID0gcmkgKiByaTsKICAgICAgICB4aSA9IG5vZGUueCArIG5vZGUudng7CiAg
ICAgICAgeWkgPSBub2RlLnkgKyBub2RlLnZ5OwogICAgICAgIHRyZWUudmlzaXQoYXBwbHkpOwog
ICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gYXBwbHkocXVhZCwgeDAsIHkwLCB4MSwgeTEpIHsK
ICAgICAgdmFyIGRhdGEgPSBxdWFkLmRhdGEsIHJqID0gcXVhZC5yLCByID0gcmkgKyByajsKICAg
ICAgaWYgKGRhdGEpIHsKICAgICAgICBpZiAoZGF0YS5pbmRleCA+IG5vZGUuaW5kZXgpIHsKICAg
ICAgICAgIHZhciB4ID0geGkgLSBkYXRhLnggLSBkYXRhLnZ4LAogICAgICAgICAgICAgIHkgPSB5
aSAtIGRhdGEueSAtIGRhdGEudnksCiAgICAgICAgICAgICAgbCA9IHggKiB4ICsgeSAqIHk7CiAg
ICAgICAgICBpZiAobCA8IHIgKiByKSB7CiAgICAgICAgICAgIGlmICh4ID09PSAwKSB4ID0gamln
Z2xlKCksIGwgKz0geCAqIHg7CiAgICAgICAgICAgIGlmICh5ID09PSAwKSB5ID0gamlnZ2xlKCks
IGwgKz0geSAqIHk7CiAgICAgICAgICAgIGwgPSAociAtIChsID0gTWF0aC5zcXJ0KGwpKSkgLyBs
ICogc3RyZW5ndGg7CiAgICAgICAgICAgIG5vZGUudnggKz0gKHggKj0gbCkgKiAociA9IChyaiAq
PSByaikgLyAocmkyICsgcmopKTsKICAgICAgICAgICAgbm9kZS52eSArPSAoeSAqPSBsKSAqIHI7
CiAgICAgICAgICAgIGRhdGEudnggLT0geCAqIChyID0gMSAtIHIpOwogICAgICAgICAgICBkYXRh
LnZ5IC09IHkgKiByOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm47CiAgICAg
IH0KICAgICAgcmV0dXJuIHgwID4geGkgKyByIHx8IHgxIDwgeGkgLSByIHx8IHkwID4geWkgKyBy
IHx8IHkxIDwgeWkgLSByOwogICAgfQogIH0KCiAgZnVuY3Rpb24gcHJlcGFyZShxdWFkKSB7CiAg
ICBpZiAocXVhZC5kYXRhKSByZXR1cm4gcXVhZC5yID0gcmFkaWlbcXVhZC5kYXRhLmluZGV4XTsK
ICAgIGZvciAodmFyIGkgPSBxdWFkLnIgPSAwOyBpIDwgNDsgKytpKSB7CiAgICAgIGlmIChxdWFk
W2ldICYmIHF1YWRbaV0uciA+IHF1YWQucikgewogICAgICAgIHF1YWQuciA9IHF1YWRbaV0ucjsK
ICAgICAgfQogICAgfQogIH0KCiAgZnVuY3Rpb24gaW5pdGlhbGl6ZSgpIHsKICAgIGlmICghbm9k
ZXMpIHJldHVybjsKICAgIHZhciBpLCBuID0gbm9kZXMubGVuZ3RoLCBub2RlOwogICAgcmFkaWkg
PSBuZXcgQXJyYXkobik7CiAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSBub2RlID0gbm9kZXNb
aV0sIHJhZGlpW25vZGUuaW5kZXhdID0gK3JhZGl1cyhub2RlLCBpLCBub2Rlcyk7CiAgfQoKICBm
b3JjZS5pbml0aWFsaXplID0gZnVuY3Rpb24oXykgewogICAgbm9kZXMgPSBfOwogICAgaW5pdGlh
bGl6ZSgpOwogIH07CgogIGZvcmNlLml0ZXJhdGlvbnMgPSBmdW5jdGlvbihfKSB7CiAgICByZXR1
cm4gYXJndW1lbnRzLmxlbmd0aCA/IChpdGVyYXRpb25zID0gK18sIGZvcmNlKSA6IGl0ZXJhdGlv
bnM7CiAgfTsKCiAgZm9yY2Uuc3RyZW5ndGggPSBmdW5jdGlvbihfKSB7CiAgICByZXR1cm4gYXJn
dW1lbnRzLmxlbmd0aCA/IChzdHJlbmd0aCA9ICtfLCBmb3JjZSkgOiBzdHJlbmd0aDsKICB9OwoK
ICBmb3JjZS5yYWRpdXMgPSBmdW5jdGlvbihfKSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0
aCA/IChyYWRpdXMgPSB0eXBlb2YgXyA9PT0gImZ1bmN0aW9uIiA/IF8gOiBjb25zdGFudCQ3KCtf
KSwgaW5pdGlhbGl6ZSgpLCBmb3JjZSkgOiByYWRpdXM7CiAgfTsKCiAgcmV0dXJuIGZvcmNlOwp9
CgpmdW5jdGlvbiBpbmRleChkKSB7CiAgcmV0dXJuIGQuaW5kZXg7Cn0KCmZ1bmN0aW9uIGZpbmQo
bm9kZUJ5SWQsIG5vZGVJZCkgewogIHZhciBub2RlID0gbm9kZUJ5SWQuZ2V0KG5vZGVJZCk7CiAg
aWYgKCFub2RlKSB0aHJvdyBuZXcgRXJyb3IoIm1pc3Npbmc6ICIgKyBub2RlSWQpOwogIHJldHVy
biBub2RlOwp9CgpmdW5jdGlvbiBsaW5rKGxpbmtzKSB7CiAgdmFyIGlkID0gaW5kZXgsCiAgICAg
IHN0cmVuZ3RoID0gZGVmYXVsdFN0cmVuZ3RoLAogICAgICBzdHJlbmd0aHMsCiAgICAgIGRpc3Rh
bmNlID0gY29uc3RhbnQkNygzMCksCiAgICAgIGRpc3RhbmNlcywKICAgICAgbm9kZXMsCiAgICAg
IGNvdW50LAogICAgICBiaWFzLAogICAgICBpdGVyYXRpb25zID0gMTsKCiAgaWYgKGxpbmtzID09
IG51bGwpIGxpbmtzID0gW107CgogIGZ1bmN0aW9uIGRlZmF1bHRTdHJlbmd0aChsaW5rKSB7CiAg
ICByZXR1cm4gMSAvIE1hdGgubWluKGNvdW50W2xpbmsuc291cmNlLmluZGV4XSwgY291bnRbbGlu
ay50YXJnZXQuaW5kZXhdKTsKICB9CgogIGZ1bmN0aW9uIGZvcmNlKGFscGhhKSB7CiAgICBmb3Ig
KHZhciBrID0gMCwgbiA9IGxpbmtzLmxlbmd0aDsgayA8IGl0ZXJhdGlvbnM7ICsraykgewogICAg
ICBmb3IgKHZhciBpID0gMCwgbGluaywgc291cmNlLCB0YXJnZXQsIHgsIHksIGwsIGI7IGkgPCBu
OyArK2kpIHsKICAgICAgICBsaW5rID0gbGlua3NbaV0sIHNvdXJjZSA9IGxpbmsuc291cmNlLCB0
YXJnZXQgPSBsaW5rLnRhcmdldDsKICAgICAgICB4ID0gdGFyZ2V0LnggKyB0YXJnZXQudnggLSBz
b3VyY2UueCAtIHNvdXJjZS52eCB8fCBqaWdnbGUoKTsKICAgICAgICB5ID0gdGFyZ2V0LnkgKyB0
YXJnZXQudnkgLSBzb3VyY2UueSAtIHNvdXJjZS52eSB8fCBqaWdnbGUoKTsKICAgICAgICBsID0g
TWF0aC5zcXJ0KHggKiB4ICsgeSAqIHkpOwogICAgICAgIGwgPSAobCAtIGRpc3RhbmNlc1tpXSkg
LyBsICogYWxwaGEgKiBzdHJlbmd0aHNbaV07CiAgICAgICAgeCAqPSBsLCB5ICo9IGw7CiAgICAg
ICAgdGFyZ2V0LnZ4IC09IHggKiAoYiA9IGJpYXNbaV0pOwogICAgICAgIHRhcmdldC52eSAtPSB5
ICogYjsKICAgICAgICBzb3VyY2UudnggKz0geCAqIChiID0gMSAtIGIpOwogICAgICAgIHNvdXJj
ZS52eSArPSB5ICogYjsKICAgICAgfQogICAgfQogIH0KCiAgZnVuY3Rpb24gaW5pdGlhbGl6ZSgp
IHsKICAgIGlmICghbm9kZXMpIHJldHVybjsKCiAgICB2YXIgaSwKICAgICAgICBuID0gbm9kZXMu
bGVuZ3RoLAogICAgICAgIG0gPSBsaW5rcy5sZW5ndGgsCiAgICAgICAgbm9kZUJ5SWQgPSBtYXAk
MShub2RlcywgaWQpLAogICAgICAgIGxpbms7CgogICAgZm9yIChpID0gMCwgY291bnQgPSBuZXcg
QXJyYXkobik7IGkgPCBtOyArK2kpIHsKICAgICAgbGluayA9IGxpbmtzW2ldLCBsaW5rLmluZGV4
ID0gaTsKICAgICAgaWYgKHR5cGVvZiBsaW5rLnNvdXJjZSAhPT0gIm9iamVjdCIpIGxpbmsuc291
cmNlID0gZmluZChub2RlQnlJZCwgbGluay5zb3VyY2UpOwogICAgICBpZiAodHlwZW9mIGxpbmsu
dGFyZ2V0ICE9PSAib2JqZWN0IikgbGluay50YXJnZXQgPSBmaW5kKG5vZGVCeUlkLCBsaW5rLnRh
cmdldCk7CiAgICAgIGNvdW50W2xpbmsuc291cmNlLmluZGV4XSA9IChjb3VudFtsaW5rLnNvdXJj
ZS5pbmRleF0gfHwgMCkgKyAxOwogICAgICBjb3VudFtsaW5rLnRhcmdldC5pbmRleF0gPSAoY291
bnRbbGluay50YXJnZXQuaW5kZXhdIHx8IDApICsgMTsKICAgIH0KCiAgICBmb3IgKGkgPSAwLCBi
aWFzID0gbmV3IEFycmF5KG0pOyBpIDwgbTsgKytpKSB7CiAgICAgIGxpbmsgPSBsaW5rc1tpXSwg
Ymlhc1tpXSA9IGNvdW50W2xpbmsuc291cmNlLmluZGV4XSAvIChjb3VudFtsaW5rLnNvdXJjZS5p
bmRleF0gKyBjb3VudFtsaW5rLnRhcmdldC5pbmRleF0pOwogICAgfQoKICAgIHN0cmVuZ3RocyA9
IG5ldyBBcnJheShtKSwgaW5pdGlhbGl6ZVN0cmVuZ3RoKCk7CiAgICBkaXN0YW5jZXMgPSBuZXcg
QXJyYXkobSksIGluaXRpYWxpemVEaXN0YW5jZSgpOwogIH0KCiAgZnVuY3Rpb24gaW5pdGlhbGl6
ZVN0cmVuZ3RoKCkgewogICAgaWYgKCFub2RlcykgcmV0dXJuOwoKICAgIGZvciAodmFyIGkgPSAw
LCBuID0gbGlua3MubGVuZ3RoOyBpIDwgbjsgKytpKSB7CiAgICAgIHN0cmVuZ3Roc1tpXSA9ICtz
dHJlbmd0aChsaW5rc1tpXSwgaSwgbGlua3MpOwogICAgfQogIH0KCiAgZnVuY3Rpb24gaW5pdGlh
bGl6ZURpc3RhbmNlKCkgewogICAgaWYgKCFub2RlcykgcmV0dXJuOwoKICAgIGZvciAodmFyIGkg
PSAwLCBuID0gbGlua3MubGVuZ3RoOyBpIDwgbjsgKytpKSB7CiAgICAgIGRpc3RhbmNlc1tpXSA9
ICtkaXN0YW5jZShsaW5rc1tpXSwgaSwgbGlua3MpOwogICAgfQogIH0KCiAgZm9yY2UuaW5pdGlh
bGl6ZSA9IGZ1bmN0aW9uKF8pIHsKICAgIG5vZGVzID0gXzsKICAgIGluaXRpYWxpemUoKTsKICB9
OwoKICBmb3JjZS5saW5rcyA9IGZ1bmN0aW9uKF8pIHsKICAgIHJldHVybiBhcmd1bWVudHMubGVu
Z3RoID8gKGxpbmtzID0gXywgaW5pdGlhbGl6ZSgpLCBmb3JjZSkgOiBsaW5rczsKICB9OwoKICBm
b3JjZS5pZCA9IGZ1bmN0aW9uKF8pIHsKICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGlk
ID0gXywgZm9yY2UpIDogaWQ7CiAgfTsKCiAgZm9yY2UuaXRlcmF0aW9ucyA9IGZ1bmN0aW9uKF8p
IHsKICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGl0ZXJhdGlvbnMgPSArXywgZm9yY2Up
IDogaXRlcmF0aW9uczsKICB9OwoKICBmb3JjZS5zdHJlbmd0aCA9IGZ1bmN0aW9uKF8pIHsKICAg
IHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHN0cmVuZ3RoID0gdHlwZW9mIF8gPT09ICJmdW5j
dGlvbiIgPyBfIDogY29uc3RhbnQkNygrXyksIGluaXRpYWxpemVTdHJlbmd0aCgpLCBmb3JjZSkg
OiBzdHJlbmd0aDsKICB9OwoKICBmb3JjZS5kaXN0YW5jZSA9IGZ1bmN0aW9uKF8pIHsKICAgIHJl
dHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGRpc3RhbmNlID0gdHlwZW9mIF8gPT09ICJmdW5jdGlv
biIgPyBfIDogY29uc3RhbnQkNygrXyksIGluaXRpYWxpemVEaXN0YW5jZSgpLCBmb3JjZSkgOiBk
aXN0YW5jZTsKICB9OwoKICByZXR1cm4gZm9yY2U7Cn0KCmZ1bmN0aW9uIHgkMShkKSB7CiAgcmV0
dXJuIGQueDsKfQoKZnVuY3Rpb24geSQxKGQpIHsKICByZXR1cm4gZC55Owp9Cgp2YXIgaW5pdGlh
bFJhZGl1cyA9IDEwLAogICAgaW5pdGlhbEFuZ2xlID0gTWF0aC5QSSAqICgzIC0gTWF0aC5zcXJ0
KDUpKTsKCmZ1bmN0aW9uIHNpbXVsYXRpb24obm9kZXMpIHsKICB2YXIgc2ltdWxhdGlvbiwKICAg
ICAgYWxwaGEgPSAxLAogICAgICBhbHBoYU1pbiA9IDAuMDAxLAogICAgICBhbHBoYURlY2F5ID0g
MSAtIE1hdGgucG93KGFscGhhTWluLCAxIC8gMzAwKSwKICAgICAgYWxwaGFUYXJnZXQgPSAwLAog
ICAgICB2ZWxvY2l0eURlY2F5ID0gMC42LAogICAgICBmb3JjZXMgPSBtYXAkMSgpLAogICAgICBz
dGVwcGVyID0gdGltZXIoc3RlcCksCiAgICAgIGV2ZW50ID0gZGlzcGF0Y2goInRpY2siLCAiZW5k
Iik7CgogIGlmIChub2RlcyA9PSBudWxsKSBub2RlcyA9IFtdOwoKICBmdW5jdGlvbiBzdGVwKCkg
ewogICAgdGljaygpOwogICAgZXZlbnQuY2FsbCgidGljayIsIHNpbXVsYXRpb24pOwogICAgaWYg
KGFscGhhIDwgYWxwaGFNaW4pIHsKICAgICAgc3RlcHBlci5zdG9wKCk7CiAgICAgIGV2ZW50LmNh
bGwoImVuZCIsIHNpbXVsYXRpb24pOwogICAgfQogIH0KCiAgZnVuY3Rpb24gdGljayhpdGVyYXRp
b25zKSB7CiAgICB2YXIgaSwgbiA9IG5vZGVzLmxlbmd0aCwgbm9kZTsKCiAgICBpZiAoaXRlcmF0
aW9ucyA9PT0gdW5kZWZpbmVkKSBpdGVyYXRpb25zID0gMTsKCiAgICBmb3IgKHZhciBrID0gMDsg
ayA8IGl0ZXJhdGlvbnM7ICsraykgewogICAgICBhbHBoYSArPSAoYWxwaGFUYXJnZXQgLSBhbHBo
YSkgKiBhbHBoYURlY2F5OwoKICAgICAgZm9yY2VzLmVhY2goZnVuY3Rpb24gKGZvcmNlKSB7CiAg
ICAgICAgZm9yY2UoYWxwaGEpOwogICAgICB9KTsKCiAgICAgIGZvciAoaSA9IDA7IGkgPCBuOyAr
K2kpIHsKICAgICAgICBub2RlID0gbm9kZXNbaV07CiAgICAgICAgaWYgKG5vZGUuZnggPT0gbnVs
bCkgbm9kZS54ICs9IG5vZGUudnggKj0gdmVsb2NpdHlEZWNheTsKICAgICAgICBlbHNlIG5vZGUu
eCA9IG5vZGUuZngsIG5vZGUudnggPSAwOwogICAgICAgIGlmIChub2RlLmZ5ID09IG51bGwpIG5v
ZGUueSArPSBub2RlLnZ5ICo9IHZlbG9jaXR5RGVjYXk7CiAgICAgICAgZWxzZSBub2RlLnkgPSBu
b2RlLmZ5LCBub2RlLnZ5ID0gMDsKICAgICAgfQogICAgfQoKICAgIHJldHVybiBzaW11bGF0aW9u
OwogIH0KCiAgZnVuY3Rpb24gaW5pdGlhbGl6ZU5vZGVzKCkgewogICAgZm9yICh2YXIgaSA9IDAs
IG4gPSBub2Rlcy5sZW5ndGgsIG5vZGU7IGkgPCBuOyArK2kpIHsKICAgICAgbm9kZSA9IG5vZGVz
W2ldLCBub2RlLmluZGV4ID0gaTsKICAgICAgaWYgKG5vZGUuZnggIT0gbnVsbCkgbm9kZS54ID0g
bm9kZS5meDsKICAgICAgaWYgKG5vZGUuZnkgIT0gbnVsbCkgbm9kZS55ID0gbm9kZS5meTsKICAg
ICAgaWYgKGlzTmFOKG5vZGUueCkgfHwgaXNOYU4obm9kZS55KSkgewogICAgICAgIHZhciByYWRp
dXMgPSBpbml0aWFsUmFkaXVzICogTWF0aC5zcXJ0KGkpLCBhbmdsZSA9IGkgKiBpbml0aWFsQW5n
bGU7CiAgICAgICAgbm9kZS54ID0gcmFkaXVzICogTWF0aC5jb3MoYW5nbGUpOwogICAgICAgIG5v
ZGUueSA9IHJhZGl1cyAqIE1hdGguc2luKGFuZ2xlKTsKICAgICAgfQogICAgICBpZiAoaXNOYU4o
bm9kZS52eCkgfHwgaXNOYU4obm9kZS52eSkpIHsKICAgICAgICBub2RlLnZ4ID0gbm9kZS52eSA9
IDA7CiAgICAgIH0KICAgIH0KICB9CgogIGZ1bmN0aW9uIGluaXRpYWxpemVGb3JjZShmb3JjZSkg
ewogICAgaWYgKGZvcmNlLmluaXRpYWxpemUpIGZvcmNlLmluaXRpYWxpemUobm9kZXMpOwogICAg
cmV0dXJuIGZvcmNlOwogIH0KCiAgaW5pdGlhbGl6ZU5vZGVzKCk7CgogIHJldHVybiBzaW11bGF0
aW9uID0gewogICAgdGljazogdGljaywKCiAgICByZXN0YXJ0OiBmdW5jdGlvbigpIHsKICAgICAg
cmV0dXJuIHN0ZXBwZXIucmVzdGFydChzdGVwKSwgc2ltdWxhdGlvbjsKICAgIH0sCgogICAgc3Rv
cDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBzdGVwcGVyLnN0b3AoKSwgc2ltdWxhdGlvbjsK
ICAgIH0sCgogICAgbm9kZXM6IGZ1bmN0aW9uKF8pIHsKICAgICAgcmV0dXJuIGFyZ3VtZW50cy5s
ZW5ndGggPyAobm9kZXMgPSBfLCBpbml0aWFsaXplTm9kZXMoKSwgZm9yY2VzLmVhY2goaW5pdGlh
bGl6ZUZvcmNlKSwgc2ltdWxhdGlvbikgOiBub2RlczsKICAgIH0sCgogICAgYWxwaGE6IGZ1bmN0
aW9uKF8pIHsKICAgICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoYWxwaGEgPSArXywgc2lt
dWxhdGlvbikgOiBhbHBoYTsKICAgIH0sCgogICAgYWxwaGFNaW46IGZ1bmN0aW9uKF8pIHsKICAg
ICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoYWxwaGFNaW4gPSArXywgc2ltdWxhdGlvbikg
OiBhbHBoYU1pbjsKICAgIH0sCgogICAgYWxwaGFEZWNheTogZnVuY3Rpb24oXykgewogICAgICBy
ZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChhbHBoYURlY2F5ID0gK18sIHNpbXVsYXRpb24pIDog
K2FscGhhRGVjYXk7CiAgICB9LAoKICAgIGFscGhhVGFyZ2V0OiBmdW5jdGlvbihfKSB7CiAgICAg
IHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGFscGhhVGFyZ2V0ID0gK18sIHNpbXVsYXRpb24p
IDogYWxwaGFUYXJnZXQ7CiAgICB9LAoKICAgIHZlbG9jaXR5RGVjYXk6IGZ1bmN0aW9uKF8pIHsK
ICAgICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAodmVsb2NpdHlEZWNheSA9IDEgLSBfLCBz
aW11bGF0aW9uKSA6IDEgLSB2ZWxvY2l0eURlY2F5OwogICAgfSwKCiAgICBmb3JjZTogZnVuY3Rp
b24obmFtZSwgXykgewogICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA+IDEgPyAoKF8gPT0g
bnVsbCA/IGZvcmNlcy5yZW1vdmUobmFtZSkgOiBmb3JjZXMuc2V0KG5hbWUsIGluaXRpYWxpemVG
b3JjZShfKSkpLCBzaW11bGF0aW9uKSA6IGZvcmNlcy5nZXQobmFtZSk7CiAgICB9LAoKICAgIGZp
bmQ6IGZ1bmN0aW9uKHgsIHksIHJhZGl1cykgewogICAgICB2YXIgaSA9IDAsCiAgICAgICAgICBu
ID0gbm9kZXMubGVuZ3RoLAogICAgICAgICAgZHgsCiAgICAgICAgICBkeSwKICAgICAgICAgIGQy
LAogICAgICAgICAgbm9kZSwKICAgICAgICAgIGNsb3Nlc3Q7CgogICAgICBpZiAocmFkaXVzID09
IG51bGwpIHJhZGl1cyA9IEluZmluaXR5OwogICAgICBlbHNlIHJhZGl1cyAqPSByYWRpdXM7Cgog
ICAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSB7CiAgICAgICAgbm9kZSA9IG5vZGVzW2ldOwog
ICAgICAgIGR4ID0geCAtIG5vZGUueDsKICAgICAgICBkeSA9IHkgLSBub2RlLnk7CiAgICAgICAg
ZDIgPSBkeCAqIGR4ICsgZHkgKiBkeTsKICAgICAgICBpZiAoZDIgPCByYWRpdXMpIGNsb3Nlc3Qg
PSBub2RlLCByYWRpdXMgPSBkMjsKICAgICAgfQoKICAgICAgcmV0dXJuIGNsb3Nlc3Q7CiAgICB9
LAoKICAgIG9uOiBmdW5jdGlvbihuYW1lLCBfKSB7CiAgICAgIHJldHVybiBhcmd1bWVudHMubGVu
Z3RoID4gMSA/IChldmVudC5vbihuYW1lLCBfKSwgc2ltdWxhdGlvbikgOiBldmVudC5vbihuYW1l
KTsKICAgIH0KICB9Owp9CgpmdW5jdGlvbiBtYW55Qm9keSgpIHsKICB2YXIgbm9kZXMsCiAgICAg
IG5vZGUsCiAgICAgIGFscGhhLAogICAgICBzdHJlbmd0aCA9IGNvbnN0YW50JDcoLTMwKSwKICAg
ICAgc3RyZW5ndGhzLAogICAgICBkaXN0YW5jZU1pbjIgPSAxLAogICAgICBkaXN0YW5jZU1heDIg
PSBJbmZpbml0eSwKICAgICAgdGhldGEyID0gMC44MTsKCiAgZnVuY3Rpb24gZm9yY2UoXykgewog
ICAgdmFyIGksIG4gPSBub2Rlcy5sZW5ndGgsIHRyZWUgPSBxdWFkdHJlZShub2RlcywgeCQxLCB5
JDEpLnZpc2l0QWZ0ZXIoYWNjdW11bGF0ZSk7CiAgICBmb3IgKGFscGhhID0gXywgaSA9IDA7IGkg
PCBuOyArK2kpIG5vZGUgPSBub2Rlc1tpXSwgdHJlZS52aXNpdChhcHBseSk7CiAgfQoKICBmdW5j
dGlvbiBpbml0aWFsaXplKCkgewogICAgaWYgKCFub2RlcykgcmV0dXJuOwogICAgdmFyIGksIG4g
PSBub2Rlcy5sZW5ndGgsIG5vZGU7CiAgICBzdHJlbmd0aHMgPSBuZXcgQXJyYXkobik7CiAgICBm
b3IgKGkgPSAwOyBpIDwgbjsgKytpKSBub2RlID0gbm9kZXNbaV0sIHN0cmVuZ3Roc1tub2RlLmlu
ZGV4XSA9ICtzdHJlbmd0aChub2RlLCBpLCBub2Rlcyk7CiAgfQoKICBmdW5jdGlvbiBhY2N1bXVs
YXRlKHF1YWQpIHsKICAgIHZhciBzdHJlbmd0aCA9IDAsIHEsIGMsIHdlaWdodCA9IDAsIHgsIHks
IGk7CgogICAgLy8gRm9yIGludGVybmFsIG5vZGVzLCBhY2N1bXVsYXRlIGZvcmNlcyBmcm9tIGNo
aWxkIHF1YWRyYW50cy4KICAgIGlmIChxdWFkLmxlbmd0aCkgewogICAgICBmb3IgKHggPSB5ID0g
aSA9IDA7IGkgPCA0OyArK2kpIHsKICAgICAgICBpZiAoKHEgPSBxdWFkW2ldKSAmJiAoYyA9IE1h
dGguYWJzKHEudmFsdWUpKSkgewogICAgICAgICAgc3RyZW5ndGggKz0gcS52YWx1ZSwgd2VpZ2h0
ICs9IGMsIHggKz0gYyAqIHEueCwgeSArPSBjICogcS55OwogICAgICAgIH0KICAgICAgfQogICAg
ICBxdWFkLnggPSB4IC8gd2VpZ2h0OwogICAgICBxdWFkLnkgPSB5IC8gd2VpZ2h0OwogICAgfQoK
ICAgIC8vIEZvciBsZWFmIG5vZGVzLCBhY2N1bXVsYXRlIGZvcmNlcyBmcm9tIGNvaW5jaWRlbnQg
cXVhZHJhbnRzLgogICAgZWxzZSB7CiAgICAgIHEgPSBxdWFkOwogICAgICBxLnggPSBxLmRhdGEu
eDsKICAgICAgcS55ID0gcS5kYXRhLnk7CiAgICAgIGRvIHN0cmVuZ3RoICs9IHN0cmVuZ3Roc1tx
LmRhdGEuaW5kZXhdOwogICAgICB3aGlsZSAocSA9IHEubmV4dCk7CiAgICB9CgogICAgcXVhZC52
YWx1ZSA9IHN0cmVuZ3RoOwogIH0KCiAgZnVuY3Rpb24gYXBwbHkocXVhZCwgeDEsIF8sIHgyKSB7
CiAgICBpZiAoIXF1YWQudmFsdWUpIHJldHVybiB0cnVlOwoKICAgIHZhciB4ID0gcXVhZC54IC0g
bm9kZS54LAogICAgICAgIHkgPSBxdWFkLnkgLSBub2RlLnksCiAgICAgICAgdyA9IHgyIC0geDEs
CiAgICAgICAgbCA9IHggKiB4ICsgeSAqIHk7CgogICAgLy8gQXBwbHkgdGhlIEJhcm5lcy1IdXQg
YXBwcm94aW1hdGlvbiBpZiBwb3NzaWJsZS4KICAgIC8vIExpbWl0IGZvcmNlcyBmb3IgdmVyeSBj
bG9zZSBub2RlczsgcmFuZG9taXplIGRpcmVjdGlvbiBpZiBjb2luY2lkZW50LgogICAgaWYgKHcg
KiB3IC8gdGhldGEyIDwgbCkgewogICAgICBpZiAobCA8IGRpc3RhbmNlTWF4MikgewogICAgICAg
IGlmICh4ID09PSAwKSB4ID0gamlnZ2xlKCksIGwgKz0geCAqIHg7CiAgICAgICAgaWYgKHkgPT09
IDApIHkgPSBqaWdnbGUoKSwgbCArPSB5ICogeTsKICAgICAgICBpZiAobCA8IGRpc3RhbmNlTWlu
MikgbCA9IE1hdGguc3FydChkaXN0YW5jZU1pbjIgKiBsKTsKICAgICAgICBub2RlLnZ4ICs9IHgg
KiBxdWFkLnZhbHVlICogYWxwaGEgLyBsOwogICAgICAgIG5vZGUudnkgKz0geSAqIHF1YWQudmFs
dWUgKiBhbHBoYSAvIGw7CiAgICAgIH0KICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLy8g
T3RoZXJ3aXNlLCBwcm9jZXNzIHBvaW50cyBkaXJlY3RseS4KICAgIGVsc2UgaWYgKHF1YWQubGVu
Z3RoIHx8IGwgPj0gZGlzdGFuY2VNYXgyKSByZXR1cm47CgogICAgLy8gTGltaXQgZm9yY2VzIGZv
ciB2ZXJ5IGNsb3NlIG5vZGVzOyByYW5kb21pemUgZGlyZWN0aW9uIGlmIGNvaW5jaWRlbnQuCiAg
ICBpZiAocXVhZC5kYXRhICE9PSBub2RlIHx8IHF1YWQubmV4dCkgewogICAgICBpZiAoeCA9PT0g
MCkgeCA9IGppZ2dsZSgpLCBsICs9IHggKiB4OwogICAgICBpZiAoeSA9PT0gMCkgeSA9IGppZ2ds
ZSgpLCBsICs9IHkgKiB5OwogICAgICBpZiAobCA8IGRpc3RhbmNlTWluMikgbCA9IE1hdGguc3Fy
dChkaXN0YW5jZU1pbjIgKiBsKTsKICAgIH0KCiAgICBkbyBpZiAocXVhZC5kYXRhICE9PSBub2Rl
KSB7CiAgICAgIHcgPSBzdHJlbmd0aHNbcXVhZC5kYXRhLmluZGV4XSAqIGFscGhhIC8gbDsKICAg
ICAgbm9kZS52eCArPSB4ICogdzsKICAgICAgbm9kZS52eSArPSB5ICogdzsKICAgIH0gd2hpbGUg
KHF1YWQgPSBxdWFkLm5leHQpOwogIH0KCiAgZm9yY2UuaW5pdGlhbGl6ZSA9IGZ1bmN0aW9uKF8p
IHsKICAgIG5vZGVzID0gXzsKICAgIGluaXRpYWxpemUoKTsKICB9OwoKICBmb3JjZS5zdHJlbmd0
aCA9IGZ1bmN0aW9uKF8pIHsKICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHN0cmVuZ3Ro
ID0gdHlwZW9mIF8gPT09ICJmdW5jdGlvbiIgPyBfIDogY29uc3RhbnQkNygrXyksIGluaXRpYWxp
emUoKSwgZm9yY2UpIDogc3RyZW5ndGg7CiAgfTsKCiAgZm9yY2UuZGlzdGFuY2VNaW4gPSBmdW5j
dGlvbihfKSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChkaXN0YW5jZU1pbjIgPSBf
ICogXywgZm9yY2UpIDogTWF0aC5zcXJ0KGRpc3RhbmNlTWluMik7CiAgfTsKCiAgZm9yY2UuZGlz
dGFuY2VNYXggPSBmdW5jdGlvbihfKSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChk
aXN0YW5jZU1heDIgPSBfICogXywgZm9yY2UpIDogTWF0aC5zcXJ0KGRpc3RhbmNlTWF4Mik7CiAg
fTsKCiAgZm9yY2UudGhldGEgPSBmdW5jdGlvbihfKSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxl
bmd0aCA/ICh0aGV0YTIgPSBfICogXywgZm9yY2UpIDogTWF0aC5zcXJ0KHRoZXRhMik7CiAgfTsK
CiAgcmV0dXJuIGZvcmNlOwp9CgpmdW5jdGlvbiByYWRpYWwocmFkaXVzLCB4LCB5KSB7CiAgdmFy
IG5vZGVzLAogICAgICBzdHJlbmd0aCA9IGNvbnN0YW50JDcoMC4xKSwKICAgICAgc3RyZW5ndGhz
LAogICAgICByYWRpdXNlczsKCiAgaWYgKHR5cGVvZiByYWRpdXMgIT09ICJmdW5jdGlvbiIpIHJh
ZGl1cyA9IGNvbnN0YW50JDcoK3JhZGl1cyk7CiAgaWYgKHggPT0gbnVsbCkgeCA9IDA7CiAgaWYg
KHkgPT0gbnVsbCkgeSA9IDA7CgogIGZ1bmN0aW9uIGZvcmNlKGFscGhhKSB7CiAgICBmb3IgKHZh
ciBpID0gMCwgbiA9IG5vZGVzLmxlbmd0aDsgaSA8IG47ICsraSkgewogICAgICB2YXIgbm9kZSA9
IG5vZGVzW2ldLAogICAgICAgICAgZHggPSBub2RlLnggLSB4IHx8IDFlLTYsCiAgICAgICAgICBk
eSA9IG5vZGUueSAtIHkgfHwgMWUtNiwKICAgICAgICAgIHIgPSBNYXRoLnNxcnQoZHggKiBkeCAr
IGR5ICogZHkpLAogICAgICAgICAgayA9IChyYWRpdXNlc1tpXSAtIHIpICogc3RyZW5ndGhzW2ld
ICogYWxwaGEgLyByOwogICAgICBub2RlLnZ4ICs9IGR4ICogazsKICAgICAgbm9kZS52eSArPSBk
eSAqIGs7CiAgICB9CiAgfQoKICBmdW5jdGlvbiBpbml0aWFsaXplKCkgewogICAgaWYgKCFub2Rl
cykgcmV0dXJuOwogICAgdmFyIGksIG4gPSBub2Rlcy5sZW5ndGg7CiAgICBzdHJlbmd0aHMgPSBu
ZXcgQXJyYXkobik7CiAgICByYWRpdXNlcyA9IG5ldyBBcnJheShuKTsKICAgIGZvciAoaSA9IDA7
IGkgPCBuOyArK2kpIHsKICAgICAgcmFkaXVzZXNbaV0gPSArcmFkaXVzKG5vZGVzW2ldLCBpLCBu
b2Rlcyk7CiAgICAgIHN0cmVuZ3Roc1tpXSA9IGlzTmFOKHJhZGl1c2VzW2ldKSA/IDAgOiArc3Ry
ZW5ndGgobm9kZXNbaV0sIGksIG5vZGVzKTsKICAgIH0KICB9CgogIGZvcmNlLmluaXRpYWxpemUg
PSBmdW5jdGlvbihfKSB7CiAgICBub2RlcyA9IF8sIGluaXRpYWxpemUoKTsKICB9OwoKICBmb3Jj
ZS5zdHJlbmd0aCA9IGZ1bmN0aW9uKF8pIHsKICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8g
KHN0cmVuZ3RoID0gdHlwZW9mIF8gPT09ICJmdW5jdGlvbiIgPyBfIDogY29uc3RhbnQkNygrXyks
IGluaXRpYWxpemUoKSwgZm9yY2UpIDogc3RyZW5ndGg7CiAgfTsKCiAgZm9yY2UucmFkaXVzID0g
ZnVuY3Rpb24oXykgewogICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAocmFkaXVzID0gdHlw
ZW9mIF8gPT09ICJmdW5jdGlvbiIgPyBfIDogY29uc3RhbnQkNygrXyksIGluaXRpYWxpemUoKSwg
Zm9yY2UpIDogcmFkaXVzOwogIH07CgogIGZvcmNlLnggPSBmdW5jdGlvbihfKSB7CiAgICByZXR1
cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh4ID0gK18sIGZvcmNlKSA6IHg7CiAgfTsKCiAgZm9yY2Uu
eSA9IGZ1bmN0aW9uKF8pIHsKICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHkgPSArXywg
Zm9yY2UpIDogeTsKICB9OwoKICByZXR1cm4gZm9yY2U7Cn0KCmZ1bmN0aW9uIHgkMih4KSB7CiAg
dmFyIHN0cmVuZ3RoID0gY29uc3RhbnQkNygwLjEpLAogICAgICBub2RlcywKICAgICAgc3RyZW5n
dGhzLAogICAgICB4ejsKCiAgaWYgKHR5cGVvZiB4ICE9PSAiZnVuY3Rpb24iKSB4ID0gY29uc3Rh
bnQkNyh4ID09IG51bGwgPyAwIDogK3gpOwoKICBmdW5jdGlvbiBmb3JjZShhbHBoYSkgewogICAg
Zm9yICh2YXIgaSA9IDAsIG4gPSBub2Rlcy5sZW5ndGgsIG5vZGU7IGkgPCBuOyArK2kpIHsKICAg
ICAgbm9kZSA9IG5vZGVzW2ldLCBub2RlLnZ4ICs9ICh4eltpXSAtIG5vZGUueCkgKiBzdHJlbmd0
aHNbaV0gKiBhbHBoYTsKICAgIH0KICB9CgogIGZ1bmN0aW9uIGluaXRpYWxpemUoKSB7CiAgICBp
ZiAoIW5vZGVzKSByZXR1cm47CiAgICB2YXIgaSwgbiA9IG5vZGVzLmxlbmd0aDsKICAgIHN0cmVu
Z3RocyA9IG5ldyBBcnJheShuKTsKICAgIHh6ID0gbmV3IEFycmF5KG4pOwogICAgZm9yIChpID0g
MDsgaSA8IG47ICsraSkgewogICAgICBzdHJlbmd0aHNbaV0gPSBpc05hTih4eltpXSA9ICt4KG5v
ZGVzW2ldLCBpLCBub2RlcykpID8gMCA6ICtzdHJlbmd0aChub2Rlc1tpXSwgaSwgbm9kZXMpOwog
ICAgfQogIH0KCiAgZm9yY2UuaW5pdGlhbGl6ZSA9IGZ1bmN0aW9uKF8pIHsKICAgIG5vZGVzID0g
XzsKICAgIGluaXRpYWxpemUoKTsKICB9OwoKICBmb3JjZS5zdHJlbmd0aCA9IGZ1bmN0aW9uKF8p
IHsKICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHN0cmVuZ3RoID0gdHlwZW9mIF8gPT09
ICJmdW5jdGlvbiIgPyBfIDogY29uc3RhbnQkNygrXyksIGluaXRpYWxpemUoKSwgZm9yY2UpIDog
c3RyZW5ndGg7CiAgfTsKCiAgZm9yY2UueCA9IGZ1bmN0aW9uKF8pIHsKICAgIHJldHVybiBhcmd1
bWVudHMubGVuZ3RoID8gKHggPSB0eXBlb2YgXyA9PT0gImZ1bmN0aW9uIiA/IF8gOiBjb25zdGFu
dCQ3KCtfKSwgaW5pdGlhbGl6ZSgpLCBmb3JjZSkgOiB4OwogIH07CgogIHJldHVybiBmb3JjZTsK
fQoKZnVuY3Rpb24geSQyKHkpIHsKICB2YXIgc3RyZW5ndGggPSBjb25zdGFudCQ3KDAuMSksCiAg
ICAgIG5vZGVzLAogICAgICBzdHJlbmd0aHMsCiAgICAgIHl6OwoKICBpZiAodHlwZW9mIHkgIT09
ICJmdW5jdGlvbiIpIHkgPSBjb25zdGFudCQ3KHkgPT0gbnVsbCA/IDAgOiAreSk7CgogIGZ1bmN0
aW9uIGZvcmNlKGFscGhhKSB7CiAgICBmb3IgKHZhciBpID0gMCwgbiA9IG5vZGVzLmxlbmd0aCwg
bm9kZTsgaSA8IG47ICsraSkgewogICAgICBub2RlID0gbm9kZXNbaV0sIG5vZGUudnkgKz0gKHl6
W2ldIC0gbm9kZS55KSAqIHN0cmVuZ3Roc1tpXSAqIGFscGhhOwogICAgfQogIH0KCiAgZnVuY3Rp
b24gaW5pdGlhbGl6ZSgpIHsKICAgIGlmICghbm9kZXMpIHJldHVybjsKICAgIHZhciBpLCBuID0g
bm9kZXMubGVuZ3RoOwogICAgc3RyZW5ndGhzID0gbmV3IEFycmF5KG4pOwogICAgeXogPSBuZXcg
QXJyYXkobik7CiAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSB7CiAgICAgIHN0cmVuZ3Roc1tp
XSA9IGlzTmFOKHl6W2ldID0gK3kobm9kZXNbaV0sIGksIG5vZGVzKSkgPyAwIDogK3N0cmVuZ3Ro
KG5vZGVzW2ldLCBpLCBub2Rlcyk7CiAgICB9CiAgfQoKICBmb3JjZS5pbml0aWFsaXplID0gZnVu
Y3Rpb24oXykgewogICAgbm9kZXMgPSBfOwogICAgaW5pdGlhbGl6ZSgpOwogIH07CgogIGZvcmNl
LnN0cmVuZ3RoID0gZnVuY3Rpb24oXykgewogICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAo
c3RyZW5ndGggPSB0eXBlb2YgXyA9PT0gImZ1bmN0aW9uIiA/IF8gOiBjb25zdGFudCQ3KCtfKSwg
aW5pdGlhbGl6ZSgpLCBmb3JjZSkgOiBzdHJlbmd0aDsKICB9OwoKICBmb3JjZS55ID0gZnVuY3Rp
b24oXykgewogICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoeSA9IHR5cGVvZiBfID09PSAi
ZnVuY3Rpb24iID8gXyA6IGNvbnN0YW50JDcoK18pLCBpbml0aWFsaXplKCksIGZvcmNlKSA6IHk7
CiAgfTsKCiAgcmV0dXJuIGZvcmNlOwp9CgovLyBDb21wdXRlcyB0aGUgZGVjaW1hbCBjb2VmZmlj
aWVudCBhbmQgZXhwb25lbnQgb2YgdGhlIHNwZWNpZmllZCBudW1iZXIgeCB3aXRoCi8vIHNpZ25p
ZmljYW50IGRpZ2l0cyBwLCB3aGVyZSB4IGlzIHBvc2l0aXZlIGFuZCBwIGlzIGluIFsxLCAyMV0g
b3IgdW5kZWZpbmVkLgovLyBGb3IgZXhhbXBsZSwgZm9ybWF0RGVjaW1hbCgxLjIzKSByZXR1cm5z
IFsiMTIzIiwgMF0uCmZ1bmN0aW9uIGZvcm1hdERlY2ltYWwoeCwgcCkgewogIGlmICgoaSA9ICh4
ID0gcCA/IHgudG9FeHBvbmVudGlhbChwIC0gMSkgOiB4LnRvRXhwb25lbnRpYWwoKSkuaW5kZXhP
ZigiZSIpKSA8IDApIHJldHVybiBudWxsOyAvLyBOYU4sIMKxSW5maW5pdHkKICB2YXIgaSwgY29l
ZmZpY2llbnQgPSB4LnNsaWNlKDAsIGkpOwoKICAvLyBUaGUgc3RyaW5nIHJldHVybmVkIGJ5IHRv
RXhwb25lbnRpYWwgZWl0aGVyIGhhcyB0aGUgZm9ybSBcZFwuXGQrZVstK11cZCsKICAvLyAoZS5n
LiwgMS4yZSszKSBvciB0aGUgZm9ybSBcZGVbLStdXGQrIChlLmcuLCAxZSszKS4KICByZXR1cm4g
WwogICAgY29lZmZpY2llbnQubGVuZ3RoID4gMSA/IGNvZWZmaWNpZW50WzBdICsgY29lZmZpY2ll
bnQuc2xpY2UoMikgOiBjb2VmZmljaWVudCwKICAgICt4LnNsaWNlKGkgKyAxKQogIF07Cn0KCmZ1
bmN0aW9uIGV4cG9uZW50JDEoeCkgewogIHJldHVybiB4ID0gZm9ybWF0RGVjaW1hbChNYXRoLmFi
cyh4KSksIHggPyB4WzFdIDogTmFOOwp9CgpmdW5jdGlvbiBmb3JtYXRHcm91cChncm91cGluZywg
dGhvdXNhbmRzKSB7CiAgcmV0dXJuIGZ1bmN0aW9uKHZhbHVlLCB3aWR0aCkgewogICAgdmFyIGkg
PSB2YWx1ZS5sZW5ndGgsCiAgICAgICAgdCA9IFtdLAogICAgICAgIGogPSAwLAogICAgICAgIGcg
PSBncm91cGluZ1swXSwKICAgICAgICBsZW5ndGggPSAwOwoKICAgIHdoaWxlIChpID4gMCAmJiBn
ID4gMCkgewogICAgICBpZiAobGVuZ3RoICsgZyArIDEgPiB3aWR0aCkgZyA9IE1hdGgubWF4KDEs
IHdpZHRoIC0gbGVuZ3RoKTsKICAgICAgdC5wdXNoKHZhbHVlLnN1YnN0cmluZyhpIC09IGcsIGkg
KyBnKSk7CiAgICAgIGlmICgobGVuZ3RoICs9IGcgKyAxKSA+IHdpZHRoKSBicmVhazsKICAgICAg
ZyA9IGdyb3VwaW5nW2ogPSAoaiArIDEpICUgZ3JvdXBpbmcubGVuZ3RoXTsKICAgIH0KCiAgICBy
ZXR1cm4gdC5yZXZlcnNlKCkuam9pbih0aG91c2FuZHMpOwogIH07Cn0KCmZ1bmN0aW9uIGZvcm1h
dE51bWVyYWxzKG51bWVyYWxzKSB7CiAgcmV0dXJuIGZ1bmN0aW9uKHZhbHVlKSB7CiAgICByZXR1
cm4gdmFsdWUucmVwbGFjZSgvWzAtOV0vZywgZnVuY3Rpb24oaSkgewogICAgICByZXR1cm4gbnVt
ZXJhbHNbK2ldOwogICAgfSk7CiAgfTsKfQoKLy8gW1tmaWxsXWFsaWduXVtzaWduXVtzeW1ib2xd
WzBdW3dpZHRoXVssXVsucHJlY2lzaW9uXVt+XVt0eXBlXQp2YXIgcmUgPSAvXig/OiguKT8oWzw+
PV5dKSk/KFsrXC0oIF0pPyhbJCNdKT8oMCk/KFxkKyk/KCwpPyhcLlxkKyk/KH4pPyhbYS16JV0p
PyQvaTsKCmZ1bmN0aW9uIGZvcm1hdFNwZWNpZmllcihzcGVjaWZpZXIpIHsKICBpZiAoIShtYXRj
aCA9IHJlLmV4ZWMoc3BlY2lmaWVyKSkpIHRocm93IG5ldyBFcnJvcigiaW52YWxpZCBmb3JtYXQ6
ICIgKyBzcGVjaWZpZXIpOwogIHZhciBtYXRjaDsKICByZXR1cm4gbmV3IEZvcm1hdFNwZWNpZmll
cih7CiAgICBmaWxsOiBtYXRjaFsxXSwKICAgIGFsaWduOiBtYXRjaFsyXSwKICAgIHNpZ246IG1h
dGNoWzNdLAogICAgc3ltYm9sOiBtYXRjaFs0XSwKICAgIHplcm86IG1hdGNoWzVdLAogICAgd2lk
dGg6IG1hdGNoWzZdLAogICAgY29tbWE6IG1hdGNoWzddLAogICAgcHJlY2lzaW9uOiBtYXRjaFs4
XSAmJiBtYXRjaFs4XS5zbGljZSgxKSwKICAgIHRyaW06IG1hdGNoWzldLAogICAgdHlwZTogbWF0
Y2hbMTBdCiAgfSk7Cn0KCmZvcm1hdFNwZWNpZmllci5wcm90b3R5cGUgPSBGb3JtYXRTcGVjaWZp
ZXIucHJvdG90eXBlOyAvLyBpbnN0YW5jZW9mCgpmdW5jdGlvbiBGb3JtYXRTcGVjaWZpZXIoc3Bl
Y2lmaWVyKSB7CiAgdGhpcy5maWxsID0gc3BlY2lmaWVyLmZpbGwgPT09IHVuZGVmaW5lZCA/ICIg
IiA6IHNwZWNpZmllci5maWxsICsgIiI7CiAgdGhpcy5hbGlnbiA9IHNwZWNpZmllci5hbGlnbiA9
PT0gdW5kZWZpbmVkID8gIj4iIDogc3BlY2lmaWVyLmFsaWduICsgIiI7CiAgdGhpcy5zaWduID0g
c3BlY2lmaWVyLnNpZ24gPT09IHVuZGVmaW5lZCA/ICItIiA6IHNwZWNpZmllci5zaWduICsgIiI7
CiAgdGhpcy5zeW1ib2wgPSBzcGVjaWZpZXIuc3ltYm9sID09PSB1bmRlZmluZWQgPyAiIiA6IHNw
ZWNpZmllci5zeW1ib2wgKyAiIjsKICB0aGlzLnplcm8gPSAhIXNwZWNpZmllci56ZXJvOwogIHRo
aXMud2lkdGggPSBzcGVjaWZpZXIud2lkdGggPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6ICtz
cGVjaWZpZXIud2lkdGg7CiAgdGhpcy5jb21tYSA9ICEhc3BlY2lmaWVyLmNvbW1hOwogIHRoaXMu
cHJlY2lzaW9uID0gc3BlY2lmaWVyLnByZWNpc2lvbiA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVk
IDogK3NwZWNpZmllci5wcmVjaXNpb247CiAgdGhpcy50cmltID0gISFzcGVjaWZpZXIudHJpbTsK
ICB0aGlzLnR5cGUgPSBzcGVjaWZpZXIudHlwZSA9PT0gdW5kZWZpbmVkID8gIiIgOiBzcGVjaWZp
ZXIudHlwZSArICIiOwp9CgpGb3JtYXRTcGVjaWZpZXIucHJvdG90eXBlLnRvU3RyaW5nID0gZnVu
Y3Rpb24oKSB7CiAgcmV0dXJuIHRoaXMuZmlsbAogICAgICArIHRoaXMuYWxpZ24KICAgICAgKyB0
aGlzLnNpZ24KICAgICAgKyB0aGlzLnN5bWJvbAogICAgICArICh0aGlzLnplcm8gPyAiMCIgOiAi
IikKICAgICAgKyAodGhpcy53aWR0aCA9PT0gdW5kZWZpbmVkID8gIiIgOiBNYXRoLm1heCgxLCB0
aGlzLndpZHRoIHwgMCkpCiAgICAgICsgKHRoaXMuY29tbWEgPyAiLCIgOiAiIikKICAgICAgKyAo
dGhpcy5wcmVjaXNpb24gPT09IHVuZGVmaW5lZCA/ICIiIDogIi4iICsgTWF0aC5tYXgoMCwgdGhp
cy5wcmVjaXNpb24gfCAwKSkKICAgICAgKyAodGhpcy50cmltID8gIn4iIDogIiIpCiAgICAgICsg
dGhpcy50eXBlOwp9OwoKLy8gVHJpbXMgaW5zaWduaWZpY2FudCB6ZXJvcywgZS5nLiwgcmVwbGFj
ZXMgMS4yMDAwayB3aXRoIDEuMmsuCmZ1bmN0aW9uIGZvcm1hdFRyaW0ocykgewogIG91dDogZm9y
ICh2YXIgbiA9IHMubGVuZ3RoLCBpID0gMSwgaTAgPSAtMSwgaTE7IGkgPCBuOyArK2kpIHsKICAg
IHN3aXRjaCAoc1tpXSkgewogICAgICBjYXNlICIuIjogaTAgPSBpMSA9IGk7IGJyZWFrOwogICAg
ICBjYXNlICIwIjogaWYgKGkwID09PSAwKSBpMCA9IGk7IGkxID0gaTsgYnJlYWs7CiAgICAgIGRl
ZmF1bHQ6IGlmICghK3NbaV0pIGJyZWFrIG91dDsgaWYgKGkwID4gMCkgaTAgPSAwOyBicmVhazsK
ICAgIH0KICB9CiAgcmV0dXJuIGkwID4gMCA/IHMuc2xpY2UoMCwgaTApICsgcy5zbGljZShpMSAr
IDEpIDogczsKfQoKdmFyIHByZWZpeEV4cG9uZW50OwoKZnVuY3Rpb24gZm9ybWF0UHJlZml4QXV0
byh4LCBwKSB7CiAgdmFyIGQgPSBmb3JtYXREZWNpbWFsKHgsIHApOwogIGlmICghZCkgcmV0dXJu
IHggKyAiIjsKICB2YXIgY29lZmZpY2llbnQgPSBkWzBdLAogICAgICBleHBvbmVudCA9IGRbMV0s
CiAgICAgIGkgPSBleHBvbmVudCAtIChwcmVmaXhFeHBvbmVudCA9IE1hdGgubWF4KC04LCBNYXRo
Lm1pbig4LCBNYXRoLmZsb29yKGV4cG9uZW50IC8gMykpKSAqIDMpICsgMSwKICAgICAgbiA9IGNv
ZWZmaWNpZW50Lmxlbmd0aDsKICByZXR1cm4gaSA9PT0gbiA/IGNvZWZmaWNpZW50CiAgICAgIDog
aSA+IG4gPyBjb2VmZmljaWVudCArIG5ldyBBcnJheShpIC0gbiArIDEpLmpvaW4oIjAiKQogICAg
ICA6IGkgPiAwID8gY29lZmZpY2llbnQuc2xpY2UoMCwgaSkgKyAiLiIgKyBjb2VmZmljaWVudC5z
bGljZShpKQogICAgICA6ICIwLiIgKyBuZXcgQXJyYXkoMSAtIGkpLmpvaW4oIjAiKSArIGZvcm1h
dERlY2ltYWwoeCwgTWF0aC5tYXgoMCwgcCArIGkgLSAxKSlbMF07IC8vIGxlc3MgdGhhbiAxeSEK
fQoKZnVuY3Rpb24gZm9ybWF0Um91bmRlZCh4LCBwKSB7CiAgdmFyIGQgPSBmb3JtYXREZWNpbWFs
KHgsIHApOwogIGlmICghZCkgcmV0dXJuIHggKyAiIjsKICB2YXIgY29lZmZpY2llbnQgPSBkWzBd
LAogICAgICBleHBvbmVudCA9IGRbMV07CiAgcmV0dXJuIGV4cG9uZW50IDwgMCA/ICIwLiIgKyBu
ZXcgQXJyYXkoLWV4cG9uZW50KS5qb2luKCIwIikgKyBjb2VmZmljaWVudAogICAgICA6IGNvZWZm
aWNpZW50Lmxlbmd0aCA+IGV4cG9uZW50ICsgMSA/IGNvZWZmaWNpZW50LnNsaWNlKDAsIGV4cG9u
ZW50ICsgMSkgKyAiLiIgKyBjb2VmZmljaWVudC5zbGljZShleHBvbmVudCArIDEpCiAgICAgIDog
Y29lZmZpY2llbnQgKyBuZXcgQXJyYXkoZXhwb25lbnQgLSBjb2VmZmljaWVudC5sZW5ndGggKyAy
KS5qb2luKCIwIik7Cn0KCnZhciBmb3JtYXRUeXBlcyA9IHsKICAiJSI6IGZ1bmN0aW9uKHgsIHAp
IHsgcmV0dXJuICh4ICogMTAwKS50b0ZpeGVkKHApOyB9LAogICJiIjogZnVuY3Rpb24oeCkgeyBy
ZXR1cm4gTWF0aC5yb3VuZCh4KS50b1N0cmluZygyKTsgfSwKICAiYyI6IGZ1bmN0aW9uKHgpIHsg
cmV0dXJuIHggKyAiIjsgfSwKICAiZCI6IGZ1bmN0aW9uKHgpIHsgcmV0dXJuIE1hdGgucm91bmQo
eCkudG9TdHJpbmcoMTApOyB9LAogICJlIjogZnVuY3Rpb24oeCwgcCkgeyByZXR1cm4geC50b0V4
cG9uZW50aWFsKHApOyB9LAogICJmIjogZnVuY3Rpb24oeCwgcCkgeyByZXR1cm4geC50b0ZpeGVk
KHApOyB9LAogICJnIjogZnVuY3Rpb24oeCwgcCkgeyByZXR1cm4geC50b1ByZWNpc2lvbihwKTsg
fSwKICAibyI6IGZ1bmN0aW9uKHgpIHsgcmV0dXJuIE1hdGgucm91bmQoeCkudG9TdHJpbmcoOCk7
IH0sCiAgInAiOiBmdW5jdGlvbih4LCBwKSB7IHJldHVybiBmb3JtYXRSb3VuZGVkKHggKiAxMDAs
IHApOyB9LAogICJyIjogZm9ybWF0Um91bmRlZCwKICAicyI6IGZvcm1hdFByZWZpeEF1dG8sCiAg
IlgiOiBmdW5jdGlvbih4KSB7IHJldHVybiBNYXRoLnJvdW5kKHgpLnRvU3RyaW5nKDE2KS50b1Vw
cGVyQ2FzZSgpOyB9LAogICJ4IjogZnVuY3Rpb24oeCkgeyByZXR1cm4gTWF0aC5yb3VuZCh4KS50
b1N0cmluZygxNik7IH0KfTsKCmZ1bmN0aW9uIGlkZW50aXR5JDMoeCkgewogIHJldHVybiB4Owp9
Cgp2YXIgbWFwJDIgPSBBcnJheS5wcm90b3R5cGUubWFwLAogICAgcHJlZml4ZXMgPSBbInkiLCJ6
IiwiYSIsImYiLCJwIiwibiIsIlx4QjUiLCJtIiwiIiwiayIsIk0iLCJHIiwiVCIsIlAiLCJFIiwi
WiIsIlkiXTsKCmZ1bmN0aW9uIGZvcm1hdExvY2FsZShsb2NhbGUpIHsKICB2YXIgZ3JvdXAgPSBs
b2NhbGUuZ3JvdXBpbmcgPT09IHVuZGVmaW5lZCB8fCBsb2NhbGUudGhvdXNhbmRzID09PSB1bmRl
ZmluZWQgPyBpZGVudGl0eSQzIDogZm9ybWF0R3JvdXAobWFwJDIuY2FsbChsb2NhbGUuZ3JvdXBp
bmcsIE51bWJlciksIGxvY2FsZS50aG91c2FuZHMgKyAiIiksCiAgICAgIGN1cnJlbmN5UHJlZml4
ID0gbG9jYWxlLmN1cnJlbmN5ID09PSB1bmRlZmluZWQgPyAiIiA6IGxvY2FsZS5jdXJyZW5jeVsw
XSArICIiLAogICAgICBjdXJyZW5jeVN1ZmZpeCA9IGxvY2FsZS5jdXJyZW5jeSA9PT0gdW5kZWZp
bmVkID8gIiIgOiBsb2NhbGUuY3VycmVuY3lbMV0gKyAiIiwKICAgICAgZGVjaW1hbCA9IGxvY2Fs
ZS5kZWNpbWFsID09PSB1bmRlZmluZWQgPyAiLiIgOiBsb2NhbGUuZGVjaW1hbCArICIiLAogICAg
ICBudW1lcmFscyA9IGxvY2FsZS5udW1lcmFscyA9PT0gdW5kZWZpbmVkID8gaWRlbnRpdHkkMyA6
IGZvcm1hdE51bWVyYWxzKG1hcCQyLmNhbGwobG9jYWxlLm51bWVyYWxzLCBTdHJpbmcpKSwKICAg
ICAgcGVyY2VudCA9IGxvY2FsZS5wZXJjZW50ID09PSB1bmRlZmluZWQgPyAiJSIgOiBsb2NhbGUu
cGVyY2VudCArICIiLAogICAgICBtaW51cyA9IGxvY2FsZS5taW51cyA9PT0gdW5kZWZpbmVkID8g
Ii0iIDogbG9jYWxlLm1pbnVzICsgIiIsCiAgICAgIG5hbiA9IGxvY2FsZS5uYW4gPT09IHVuZGVm
aW5lZCA/ICJOYU4iIDogbG9jYWxlLm5hbiArICIiOwoKICBmdW5jdGlvbiBuZXdGb3JtYXQoc3Bl
Y2lmaWVyKSB7CiAgICBzcGVjaWZpZXIgPSBmb3JtYXRTcGVjaWZpZXIoc3BlY2lmaWVyKTsKCiAg
ICB2YXIgZmlsbCA9IHNwZWNpZmllci5maWxsLAogICAgICAgIGFsaWduID0gc3BlY2lmaWVyLmFs
aWduLAogICAgICAgIHNpZ24gPSBzcGVjaWZpZXIuc2lnbiwKICAgICAgICBzeW1ib2wgPSBzcGVj
aWZpZXIuc3ltYm9sLAogICAgICAgIHplcm8gPSBzcGVjaWZpZXIuemVybywKICAgICAgICB3aWR0
aCA9IHNwZWNpZmllci53aWR0aCwKICAgICAgICBjb21tYSA9IHNwZWNpZmllci5jb21tYSwKICAg
ICAgICBwcmVjaXNpb24gPSBzcGVjaWZpZXIucHJlY2lzaW9uLAogICAgICAgIHRyaW0gPSBzcGVj
aWZpZXIudHJpbSwKICAgICAgICB0eXBlID0gc3BlY2lmaWVyLnR5cGU7CgogICAgLy8gVGhlICJu
IiB0eXBlIGlzIGFuIGFsaWFzIGZvciAiLGciLgogICAgaWYgKHR5cGUgPT09ICJuIikgY29tbWEg
PSB0cnVlLCB0eXBlID0gImciOwoKICAgIC8vIFRoZSAiIiB0eXBlLCBhbmQgYW55IGludmFsaWQg
dHlwZSwgaXMgYW4gYWxpYXMgZm9yICIuMTJ+ZyIuCiAgICBlbHNlIGlmICghZm9ybWF0VHlwZXNb
dHlwZV0pIHByZWNpc2lvbiA9PT0gdW5kZWZpbmVkICYmIChwcmVjaXNpb24gPSAxMiksIHRyaW0g
PSB0cnVlLCB0eXBlID0gImciOwoKICAgIC8vIElmIHplcm8gZmlsbCBpcyBzcGVjaWZpZWQsIHBh
ZGRpbmcgZ29lcyBhZnRlciBzaWduIGFuZCBiZWZvcmUgZGlnaXRzLgogICAgaWYgKHplcm8gfHwg
KGZpbGwgPT09ICIwIiAmJiBhbGlnbiA9PT0gIj0iKSkgemVybyA9IHRydWUsIGZpbGwgPSAiMCIs
IGFsaWduID0gIj0iOwoKICAgIC8vIENvbXB1dGUgdGhlIHByZWZpeCBhbmQgc3VmZml4LgogICAg
Ly8gRm9yIFNJLXByZWZpeCwgdGhlIHN1ZmZpeCBpcyBsYXppbHkgY29tcHV0ZWQuCiAgICB2YXIg
cHJlZml4ID0gc3ltYm9sID09PSAiJCIgPyBjdXJyZW5jeVByZWZpeCA6IHN5bWJvbCA9PT0gIiMi
ICYmIC9bYm94WF0vLnRlc3QodHlwZSkgPyAiMCIgKyB0eXBlLnRvTG93ZXJDYXNlKCkgOiAiIiwK
ICAgICAgICBzdWZmaXggPSBzeW1ib2wgPT09ICIkIiA/IGN1cnJlbmN5U3VmZml4IDogL1slcF0v
LnRlc3QodHlwZSkgPyBwZXJjZW50IDogIiI7CgogICAgLy8gV2hhdCBmb3JtYXQgZnVuY3Rpb24g
c2hvdWxkIHdlIHVzZT8KICAgIC8vIElzIHRoaXMgYW4gaW50ZWdlciB0eXBlPwogICAgLy8gQ2Fu
IHRoaXMgdHlwZSBnZW5lcmF0ZSBleHBvbmVudGlhbCBub3RhdGlvbj8KICAgIHZhciBmb3JtYXRU
eXBlID0gZm9ybWF0VHlwZXNbdHlwZV0sCiAgICAgICAgbWF5YmVTdWZmaXggPSAvW2RlZmdwcnMl
XS8udGVzdCh0eXBlKTsKCiAgICAvLyBTZXQgdGhlIGRlZmF1bHQgcHJlY2lzaW9uIGlmIG5vdCBz
cGVjaWZpZWQsCiAgICAvLyBvciBjbGFtcCB0aGUgc3BlY2lmaWVkIHByZWNpc2lvbiB0byB0aGUg
c3VwcG9ydGVkIHJhbmdlLgogICAgLy8gRm9yIHNpZ25pZmljYW50IHByZWNpc2lvbiwgaXQgbXVz
dCBiZSBpbiBbMSwgMjFdLgogICAgLy8gRm9yIGZpeGVkIHByZWNpc2lvbiwgaXQgbXVzdCBiZSBp
biBbMCwgMjBdLgogICAgcHJlY2lzaW9uID0gcHJlY2lzaW9uID09PSB1bmRlZmluZWQgPyA2CiAg
ICAgICAgOiAvW2dwcnNdLy50ZXN0KHR5cGUpID8gTWF0aC5tYXgoMSwgTWF0aC5taW4oMjEsIHBy
ZWNpc2lvbikpCiAgICAgICAgOiBNYXRoLm1heCgwLCBNYXRoLm1pbigyMCwgcHJlY2lzaW9uKSk7
CgogICAgZnVuY3Rpb24gZm9ybWF0KHZhbHVlKSB7CiAgICAgIHZhciB2YWx1ZVByZWZpeCA9IHBy
ZWZpeCwKICAgICAgICAgIHZhbHVlU3VmZml4ID0gc3VmZml4LAogICAgICAgICAgaSwgbiwgYzsK
CiAgICAgIGlmICh0eXBlID09PSAiYyIpIHsKICAgICAgICB2YWx1ZVN1ZmZpeCA9IGZvcm1hdFR5
cGUodmFsdWUpICsgdmFsdWVTdWZmaXg7CiAgICAgICAgdmFsdWUgPSAiIjsKICAgICAgfSBlbHNl
IHsKICAgICAgICB2YWx1ZSA9ICt2YWx1ZTsKCiAgICAgICAgLy8gRGV0ZXJtaW5lIHRoZSBzaWdu
LiAtMCBpcyBub3QgbGVzcyB0aGFuIDAsIGJ1dCAxIC8gLTAgaXMhCiAgICAgICAgdmFyIHZhbHVl
TmVnYXRpdmUgPSB2YWx1ZSA8IDAgfHwgMSAvIHZhbHVlIDwgMDsKCiAgICAgICAgLy8gUGVyZm9y
bSB0aGUgaW5pdGlhbCBmb3JtYXR0aW5nLgogICAgICAgIHZhbHVlID0gaXNOYU4odmFsdWUpID8g
bmFuIDogZm9ybWF0VHlwZShNYXRoLmFicyh2YWx1ZSksIHByZWNpc2lvbik7CgogICAgICAgIC8v
IFRyaW0gaW5zaWduaWZpY2FudCB6ZXJvcy4KICAgICAgICBpZiAodHJpbSkgdmFsdWUgPSBmb3Jt
YXRUcmltKHZhbHVlKTsKCiAgICAgICAgLy8gSWYgYSBuZWdhdGl2ZSB2YWx1ZSByb3VuZHMgdG8g
emVybyBhZnRlciBmb3JtYXR0aW5nLCBhbmQgbm8gZXhwbGljaXQgcG9zaXRpdmUgc2lnbiBpcyBy
ZXF1ZXN0ZWQsIGhpZGUgdGhlIHNpZ24uCiAgICAgICAgaWYgKHZhbHVlTmVnYXRpdmUgJiYgK3Zh
bHVlID09PSAwICYmIHNpZ24gIT09ICIrIikgdmFsdWVOZWdhdGl2ZSA9IGZhbHNlOwoKICAgICAg
ICAvLyBDb21wdXRlIHRoZSBwcmVmaXggYW5kIHN1ZmZpeC4KICAgICAgICB2YWx1ZVByZWZpeCA9
ICh2YWx1ZU5lZ2F0aXZlID8gKHNpZ24gPT09ICIoIiA/IHNpZ24gOiBtaW51cykgOiBzaWduID09
PSAiLSIgfHwgc2lnbiA9PT0gIigiID8gIiIgOiBzaWduKSArIHZhbHVlUHJlZml4OwogICAgICAg
IHZhbHVlU3VmZml4ID0gKHR5cGUgPT09ICJzIiA/IHByZWZpeGVzWzggKyBwcmVmaXhFeHBvbmVu
dCAvIDNdIDogIiIpICsgdmFsdWVTdWZmaXggKyAodmFsdWVOZWdhdGl2ZSAmJiBzaWduID09PSAi
KCIgPyAiKSIgOiAiIik7CgogICAgICAgIC8vIEJyZWFrIHRoZSBmb3JtYXR0ZWQgdmFsdWUgaW50
byB0aGUgaW50ZWdlciDigJx2YWx1ZeKAnSBwYXJ0IHRoYXQgY2FuIGJlCiAgICAgICAgLy8gZ3Jv
dXBlZCwgYW5kIGZyYWN0aW9uYWwgb3IgZXhwb25lbnRpYWwg4oCcc3VmZml44oCdIHBhcnQgdGhh
dCBpcyBub3QuCiAgICAgICAgaWYgKG1heWJlU3VmZml4KSB7CiAgICAgICAgICBpID0gLTEsIG4g
PSB2YWx1ZS5sZW5ndGg7CiAgICAgICAgICB3aGlsZSAoKytpIDwgbikgewogICAgICAgICAgICBp
ZiAoYyA9IHZhbHVlLmNoYXJDb2RlQXQoaSksIDQ4ID4gYyB8fCBjID4gNTcpIHsKICAgICAgICAg
ICAgICB2YWx1ZVN1ZmZpeCA9IChjID09PSA0NiA/IGRlY2ltYWwgKyB2YWx1ZS5zbGljZShpICsg
MSkgOiB2YWx1ZS5zbGljZShpKSkgKyB2YWx1ZVN1ZmZpeDsKICAgICAgICAgICAgICB2YWx1ZSA9
IHZhbHVlLnNsaWNlKDAsIGkpOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAg
ICAgICAgICB9CiAgICAgICAgfQogICAgICB9CgogICAgICAvLyBJZiB0aGUgZmlsbCBjaGFyYWN0
ZXIgaXMgbm90ICIwIiwgZ3JvdXBpbmcgaXMgYXBwbGllZCBiZWZvcmUgcGFkZGluZy4KICAgICAg
aWYgKGNvbW1hICYmICF6ZXJvKSB2YWx1ZSA9IGdyb3VwKHZhbHVlLCBJbmZpbml0eSk7CgogICAg
ICAvLyBDb21wdXRlIHRoZSBwYWRkaW5nLgogICAgICB2YXIgbGVuZ3RoID0gdmFsdWVQcmVmaXgu
bGVuZ3RoICsgdmFsdWUubGVuZ3RoICsgdmFsdWVTdWZmaXgubGVuZ3RoLAogICAgICAgICAgcGFk
ZGluZyA9IGxlbmd0aCA8IHdpZHRoID8gbmV3IEFycmF5KHdpZHRoIC0gbGVuZ3RoICsgMSkuam9p
bihmaWxsKSA6ICIiOwoKICAgICAgLy8gSWYgdGhlIGZpbGwgY2hhcmFjdGVyIGlzICIwIiwgZ3Jv
dXBpbmcgaXMgYXBwbGllZCBhZnRlciBwYWRkaW5nLgogICAgICBpZiAoY29tbWEgJiYgemVybykg
dmFsdWUgPSBncm91cChwYWRkaW5nICsgdmFsdWUsIHBhZGRpbmcubGVuZ3RoID8gd2lkdGggLSB2
YWx1ZVN1ZmZpeC5sZW5ndGggOiBJbmZpbml0eSksIHBhZGRpbmcgPSAiIjsKCiAgICAgIC8vIFJl
Y29uc3RydWN0IHRoZSBmaW5hbCBvdXRwdXQgYmFzZWQgb24gdGhlIGRlc2lyZWQgYWxpZ25tZW50
LgogICAgICBzd2l0Y2ggKGFsaWduKSB7CiAgICAgICAgY2FzZSAiPCI6IHZhbHVlID0gdmFsdWVQ
cmVmaXggKyB2YWx1ZSArIHZhbHVlU3VmZml4ICsgcGFkZGluZzsgYnJlYWs7CiAgICAgICAgY2Fz
ZSAiPSI6IHZhbHVlID0gdmFsdWVQcmVmaXggKyBwYWRkaW5nICsgdmFsdWUgKyB2YWx1ZVN1ZmZp
eDsgYnJlYWs7CiAgICAgICAgY2FzZSAiXiI6IHZhbHVlID0gcGFkZGluZy5zbGljZSgwLCBsZW5n
dGggPSBwYWRkaW5nLmxlbmd0aCA+PiAxKSArIHZhbHVlUHJlZml4ICsgdmFsdWUgKyB2YWx1ZVN1
ZmZpeCArIHBhZGRpbmcuc2xpY2UobGVuZ3RoKTsgYnJlYWs7CiAgICAgICAgZGVmYXVsdDogdmFs
dWUgPSBwYWRkaW5nICsgdmFsdWVQcmVmaXggKyB2YWx1ZSArIHZhbHVlU3VmZml4OyBicmVhazsK
ICAgICAgfQoKICAgICAgcmV0dXJuIG51bWVyYWxzKHZhbHVlKTsKICAgIH0KCiAgICBmb3JtYXQu
dG9TdHJpbmcgPSBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIHNwZWNpZmllciArICIiOwogICAg
fTsKCiAgICByZXR1cm4gZm9ybWF0OwogIH0KCiAgZnVuY3Rpb24gZm9ybWF0UHJlZml4KHNwZWNp
ZmllciwgdmFsdWUpIHsKICAgIHZhciBmID0gbmV3Rm9ybWF0KChzcGVjaWZpZXIgPSBmb3JtYXRT
cGVjaWZpZXIoc3BlY2lmaWVyKSwgc3BlY2lmaWVyLnR5cGUgPSAiZiIsIHNwZWNpZmllcikpLAog
ICAgICAgIGUgPSBNYXRoLm1heCgtOCwgTWF0aC5taW4oOCwgTWF0aC5mbG9vcihleHBvbmVudCQx
KHZhbHVlKSAvIDMpKSkgKiAzLAogICAgICAgIGsgPSBNYXRoLnBvdygxMCwgLWUpLAogICAgICAg
IHByZWZpeCA9IHByZWZpeGVzWzggKyBlIC8gM107CiAgICByZXR1cm4gZnVuY3Rpb24odmFsdWUp
IHsKICAgICAgcmV0dXJuIGYoayAqIHZhbHVlKSArIHByZWZpeDsKICAgIH07CiAgfQoKICByZXR1
cm4gewogICAgZm9ybWF0OiBuZXdGb3JtYXQsCiAgICBmb3JtYXRQcmVmaXg6IGZvcm1hdFByZWZp
eAogIH07Cn0KCnZhciBsb2NhbGU7CgpkZWZhdWx0TG9jYWxlKHsKICBkZWNpbWFsOiAiLiIsCiAg
dGhvdXNhbmRzOiAiLCIsCiAgZ3JvdXBpbmc6IFszXSwKICBjdXJyZW5jeTogWyIkIiwgIiJdLAog
IG1pbnVzOiAiLSIKfSk7CgpmdW5jdGlvbiBkZWZhdWx0TG9jYWxlKGRlZmluaXRpb24pIHsKICBs
b2NhbGUgPSBmb3JtYXRMb2NhbGUoZGVmaW5pdGlvbik7CiAgZXhwb3J0cy5mb3JtYXQgPSBsb2Nh
bGUuZm9ybWF0OwogIGV4cG9ydHMuZm9ybWF0UHJlZml4ID0gbG9jYWxlLmZvcm1hdFByZWZpeDsK
ICByZXR1cm4gbG9jYWxlOwp9CgpmdW5jdGlvbiBwcmVjaXNpb25GaXhlZChzdGVwKSB7CiAgcmV0
dXJuIE1hdGgubWF4KDAsIC1leHBvbmVudCQxKE1hdGguYWJzKHN0ZXApKSk7Cn0KCmZ1bmN0aW9u
IHByZWNpc2lvblByZWZpeChzdGVwLCB2YWx1ZSkgewogIHJldHVybiBNYXRoLm1heCgwLCBNYXRo
Lm1heCgtOCwgTWF0aC5taW4oOCwgTWF0aC5mbG9vcihleHBvbmVudCQxKHZhbHVlKSAvIDMpKSkg
KiAzIC0gZXhwb25lbnQkMShNYXRoLmFicyhzdGVwKSkpOwp9CgpmdW5jdGlvbiBwcmVjaXNpb25S
b3VuZChzdGVwLCBtYXgpIHsKICBzdGVwID0gTWF0aC5hYnMoc3RlcCksIG1heCA9IE1hdGguYWJz
KG1heCkgLSBzdGVwOwogIHJldHVybiBNYXRoLm1heCgwLCBleHBvbmVudCQxKG1heCkgLSBleHBv
bmVudCQxKHN0ZXApKSArIDE7Cn0KCi8vIEFkZHMgZmxvYXRpbmcgcG9pbnQgbnVtYmVycyB3aXRo
IHR3aWNlIHRoZSBub3JtYWwgcHJlY2lzaW9uLgovLyBSZWZlcmVuY2U6IEouIFIuIFNoZXdjaHVr
LCBBZGFwdGl2ZSBQcmVjaXNpb24gRmxvYXRpbmctUG9pbnQgQXJpdGhtZXRpYyBhbmQKLy8gRmFz
dCBSb2J1c3QgR2VvbWV0cmljIFByZWRpY2F0ZXMsIERpc2NyZXRlICYgQ29tcHV0YXRpb25hbCBH
ZW9tZXRyeSAxOCgzKQovLyAzMDXigJMzNjMgKDE5OTcpLgovLyBDb2RlIGFkYXB0ZWQgZnJvbSBH
ZW9ncmFwaGljTGliIGJ5IENoYXJsZXMgRi4gRi4gS2FybmV5LAovLyBodHRwOi8vZ2VvZ3JhcGhp
Y2xpYi5zb3VyY2Vmb3JnZS5uZXQvCgpmdW5jdGlvbiBhZGRlcigpIHsKICByZXR1cm4gbmV3IEFk
ZGVyOwp9CgpmdW5jdGlvbiBBZGRlcigpIHsKICB0aGlzLnJlc2V0KCk7Cn0KCkFkZGVyLnByb3Rv
dHlwZSA9IHsKICBjb25zdHJ1Y3RvcjogQWRkZXIsCiAgcmVzZXQ6IGZ1bmN0aW9uKCkgewogICAg
dGhpcy5zID0gLy8gcm91bmRlZCB2YWx1ZQogICAgdGhpcy50ID0gMDsgLy8gZXhhY3QgZXJyb3IK
ICB9LAogIGFkZDogZnVuY3Rpb24oeSkgewogICAgYWRkJDEodGVtcCwgeSwgdGhpcy50KTsKICAg
IGFkZCQxKHRoaXMsIHRlbXAucywgdGhpcy5zKTsKICAgIGlmICh0aGlzLnMpIHRoaXMudCArPSB0
ZW1wLnQ7CiAgICBlbHNlIHRoaXMucyA9IHRlbXAudDsKICB9LAogIHZhbHVlT2Y6IGZ1bmN0aW9u
KCkgewogICAgcmV0dXJuIHRoaXMuczsKICB9Cn07Cgp2YXIgdGVtcCA9IG5ldyBBZGRlcjsKCmZ1
bmN0aW9uIGFkZCQxKGFkZGVyLCBhLCBiKSB7CiAgdmFyIHggPSBhZGRlci5zID0gYSArIGIsCiAg
ICAgIGJ2ID0geCAtIGEsCiAgICAgIGF2ID0geCAtIGJ2OwogIGFkZGVyLnQgPSAoYSAtIGF2KSAr
IChiIC0gYnYpOwp9Cgp2YXIgZXBzaWxvbiQyID0gMWUtNjsKdmFyIGVwc2lsb24yJDEgPSAxZS0x
MjsKdmFyIHBpJDMgPSBNYXRoLlBJOwp2YXIgaGFsZlBpJDIgPSBwaSQzIC8gMjsKdmFyIHF1YXJ0
ZXJQaSA9IHBpJDMgLyA0Owp2YXIgdGF1JDMgPSBwaSQzICogMjsKCnZhciBkZWdyZWVzJDEgPSAx
ODAgLyBwaSQzOwp2YXIgcmFkaWFucyA9IHBpJDMgLyAxODA7Cgp2YXIgYWJzID0gTWF0aC5hYnM7
CnZhciBhdGFuID0gTWF0aC5hdGFuOwp2YXIgYXRhbjIgPSBNYXRoLmF0YW4yOwp2YXIgY29zJDEg
PSBNYXRoLmNvczsKdmFyIGNlaWwgPSBNYXRoLmNlaWw7CnZhciBleHAgPSBNYXRoLmV4cDsKdmFy
IGxvZyA9IE1hdGgubG9nOwp2YXIgcG93ID0gTWF0aC5wb3c7CnZhciBzaW4kMSA9IE1hdGguc2lu
Owp2YXIgc2lnbiA9IE1hdGguc2lnbiB8fCBmdW5jdGlvbih4KSB7IHJldHVybiB4ID4gMCA/IDEg
OiB4IDwgMCA/IC0xIDogMDsgfTsKdmFyIHNxcnQgPSBNYXRoLnNxcnQ7CnZhciB0YW4gPSBNYXRo
LnRhbjsKCmZ1bmN0aW9uIGFjb3MoeCkgewogIHJldHVybiB4ID4gMSA/IDAgOiB4IDwgLTEgPyBw
aSQzIDogTWF0aC5hY29zKHgpOwp9CgpmdW5jdGlvbiBhc2luKHgpIHsKICByZXR1cm4geCA+IDEg
PyBoYWxmUGkkMiA6IHggPCAtMSA/IC1oYWxmUGkkMiA6IE1hdGguYXNpbih4KTsKfQoKZnVuY3Rp
b24gaGF2ZXJzaW4oeCkgewogIHJldHVybiAoeCA9IHNpbiQxKHggLyAyKSkgKiB4Owp9CgpmdW5j
dGlvbiBub29wJDIoKSB7fQoKZnVuY3Rpb24gc3RyZWFtR2VvbWV0cnkoZ2VvbWV0cnksIHN0cmVh
bSkgewogIGlmIChnZW9tZXRyeSAmJiBzdHJlYW1HZW9tZXRyeVR5cGUuaGFzT3duUHJvcGVydHko
Z2VvbWV0cnkudHlwZSkpIHsKICAgIHN0cmVhbUdlb21ldHJ5VHlwZVtnZW9tZXRyeS50eXBlXShn
ZW9tZXRyeSwgc3RyZWFtKTsKICB9Cn0KCnZhciBzdHJlYW1PYmplY3RUeXBlID0gewogIEZlYXR1
cmU6IGZ1bmN0aW9uKG9iamVjdCwgc3RyZWFtKSB7CiAgICBzdHJlYW1HZW9tZXRyeShvYmplY3Qu
Z2VvbWV0cnksIHN0cmVhbSk7CiAgfSwKICBGZWF0dXJlQ29sbGVjdGlvbjogZnVuY3Rpb24ob2Jq
ZWN0LCBzdHJlYW0pIHsKICAgIHZhciBmZWF0dXJlcyA9IG9iamVjdC5mZWF0dXJlcywgaSA9IC0x
LCBuID0gZmVhdHVyZXMubGVuZ3RoOwogICAgd2hpbGUgKCsraSA8IG4pIHN0cmVhbUdlb21ldHJ5
KGZlYXR1cmVzW2ldLmdlb21ldHJ5LCBzdHJlYW0pOwogIH0KfTsKCnZhciBzdHJlYW1HZW9tZXRy
eVR5cGUgPSB7CiAgU3BoZXJlOiBmdW5jdGlvbihvYmplY3QsIHN0cmVhbSkgewogICAgc3RyZWFt
LnNwaGVyZSgpOwogIH0sCiAgUG9pbnQ6IGZ1bmN0aW9uKG9iamVjdCwgc3RyZWFtKSB7CiAgICBv
YmplY3QgPSBvYmplY3QuY29vcmRpbmF0ZXM7CiAgICBzdHJlYW0ucG9pbnQob2JqZWN0WzBdLCBv
YmplY3RbMV0sIG9iamVjdFsyXSk7CiAgfSwKICBNdWx0aVBvaW50OiBmdW5jdGlvbihvYmplY3Qs
IHN0cmVhbSkgewogICAgdmFyIGNvb3JkaW5hdGVzID0gb2JqZWN0LmNvb3JkaW5hdGVzLCBpID0g
LTEsIG4gPSBjb29yZGluYXRlcy5sZW5ndGg7CiAgICB3aGlsZSAoKytpIDwgbikgb2JqZWN0ID0g
Y29vcmRpbmF0ZXNbaV0sIHN0cmVhbS5wb2ludChvYmplY3RbMF0sIG9iamVjdFsxXSwgb2JqZWN0
WzJdKTsKICB9LAogIExpbmVTdHJpbmc6IGZ1bmN0aW9uKG9iamVjdCwgc3RyZWFtKSB7CiAgICBz
dHJlYW1MaW5lKG9iamVjdC5jb29yZGluYXRlcywgc3RyZWFtLCAwKTsKICB9LAogIE11bHRpTGlu
ZVN0cmluZzogZnVuY3Rpb24ob2JqZWN0LCBzdHJlYW0pIHsKICAgIHZhciBjb29yZGluYXRlcyA9
IG9iamVjdC5jb29yZGluYXRlcywgaSA9IC0xLCBuID0gY29vcmRpbmF0ZXMubGVuZ3RoOwogICAg
d2hpbGUgKCsraSA8IG4pIHN0cmVhbUxpbmUoY29vcmRpbmF0ZXNbaV0sIHN0cmVhbSwgMCk7CiAg
fSwKICBQb2x5Z29uOiBmdW5jdGlvbihvYmplY3QsIHN0cmVhbSkgewogICAgc3RyZWFtUG9seWdv
bihvYmplY3QuY29vcmRpbmF0ZXMsIHN0cmVhbSk7CiAgfSwKICBNdWx0aVBvbHlnb246IGZ1bmN0
aW9uKG9iamVjdCwgc3RyZWFtKSB7CiAgICB2YXIgY29vcmRpbmF0ZXMgPSBvYmplY3QuY29vcmRp
bmF0ZXMsIGkgPSAtMSwgbiA9IGNvb3JkaW5hdGVzLmxlbmd0aDsKICAgIHdoaWxlICgrK2kgPCBu
KSBzdHJlYW1Qb2x5Z29uKGNvb3JkaW5hdGVzW2ldLCBzdHJlYW0pOwogIH0sCiAgR2VvbWV0cnlD
b2xsZWN0aW9uOiBmdW5jdGlvbihvYmplY3QsIHN0cmVhbSkgewogICAgdmFyIGdlb21ldHJpZXMg
PSBvYmplY3QuZ2VvbWV0cmllcywgaSA9IC0xLCBuID0gZ2VvbWV0cmllcy5sZW5ndGg7CiAgICB3
aGlsZSAoKytpIDwgbikgc3RyZWFtR2VvbWV0cnkoZ2VvbWV0cmllc1tpXSwgc3RyZWFtKTsKICB9
Cn07CgpmdW5jdGlvbiBzdHJlYW1MaW5lKGNvb3JkaW5hdGVzLCBzdHJlYW0sIGNsb3NlZCkgewog
IHZhciBpID0gLTEsIG4gPSBjb29yZGluYXRlcy5sZW5ndGggLSBjbG9zZWQsIGNvb3JkaW5hdGU7
CiAgc3RyZWFtLmxpbmVTdGFydCgpOwogIHdoaWxlICgrK2kgPCBuKSBjb29yZGluYXRlID0gY29v
cmRpbmF0ZXNbaV0sIHN0cmVhbS5wb2ludChjb29yZGluYXRlWzBdLCBjb29yZGluYXRlWzFdLCBj
b29yZGluYXRlWzJdKTsKICBzdHJlYW0ubGluZUVuZCgpOwp9CgpmdW5jdGlvbiBzdHJlYW1Qb2x5
Z29uKGNvb3JkaW5hdGVzLCBzdHJlYW0pIHsKICB2YXIgaSA9IC0xLCBuID0gY29vcmRpbmF0ZXMu
bGVuZ3RoOwogIHN0cmVhbS5wb2x5Z29uU3RhcnQoKTsKICB3aGlsZSAoKytpIDwgbikgc3RyZWFt
TGluZShjb29yZGluYXRlc1tpXSwgc3RyZWFtLCAxKTsKICBzdHJlYW0ucG9seWdvbkVuZCgpOwp9
CgpmdW5jdGlvbiBnZW9TdHJlYW0ob2JqZWN0LCBzdHJlYW0pIHsKICBpZiAob2JqZWN0ICYmIHN0
cmVhbU9iamVjdFR5cGUuaGFzT3duUHJvcGVydHkob2JqZWN0LnR5cGUpKSB7CiAgICBzdHJlYW1P
YmplY3RUeXBlW29iamVjdC50eXBlXShvYmplY3QsIHN0cmVhbSk7CiAgfSBlbHNlIHsKICAgIHN0
cmVhbUdlb21ldHJ5KG9iamVjdCwgc3RyZWFtKTsKICB9Cn0KCnZhciBhcmVhUmluZ1N1bSA9IGFk
ZGVyKCk7Cgp2YXIgYXJlYVN1bSA9IGFkZGVyKCksCiAgICBsYW1iZGEwMCwKICAgIHBoaTAwLAog
ICAgbGFtYmRhMCwKICAgIGNvc1BoaTAsCiAgICBzaW5QaGkwOwoKdmFyIGFyZWFTdHJlYW0gPSB7
CiAgcG9pbnQ6IG5vb3AkMiwKICBsaW5lU3RhcnQ6IG5vb3AkMiwKICBsaW5lRW5kOiBub29wJDIs
CiAgcG9seWdvblN0YXJ0OiBmdW5jdGlvbigpIHsKICAgIGFyZWFSaW5nU3VtLnJlc2V0KCk7CiAg
ICBhcmVhU3RyZWFtLmxpbmVTdGFydCA9IGFyZWFSaW5nU3RhcnQ7CiAgICBhcmVhU3RyZWFtLmxp
bmVFbmQgPSBhcmVhUmluZ0VuZDsKICB9LAogIHBvbHlnb25FbmQ6IGZ1bmN0aW9uKCkgewogICAg
dmFyIGFyZWFSaW5nID0gK2FyZWFSaW5nU3VtOwogICAgYXJlYVN1bS5hZGQoYXJlYVJpbmcgPCAw
ID8gdGF1JDMgKyBhcmVhUmluZyA6IGFyZWFSaW5nKTsKICAgIHRoaXMubGluZVN0YXJ0ID0gdGhp
cy5saW5lRW5kID0gdGhpcy5wb2ludCA9IG5vb3AkMjsKICB9LAogIHNwaGVyZTogZnVuY3Rpb24o
KSB7CiAgICBhcmVhU3VtLmFkZCh0YXUkMyk7CiAgfQp9OwoKZnVuY3Rpb24gYXJlYVJpbmdTdGFy
dCgpIHsKICBhcmVhU3RyZWFtLnBvaW50ID0gYXJlYVBvaW50Rmlyc3Q7Cn0KCmZ1bmN0aW9uIGFy
ZWFSaW5nRW5kKCkgewogIGFyZWFQb2ludChsYW1iZGEwMCwgcGhpMDApOwp9CgpmdW5jdGlvbiBh
cmVhUG9pbnRGaXJzdChsYW1iZGEsIHBoaSkgewogIGFyZWFTdHJlYW0ucG9pbnQgPSBhcmVhUG9p
bnQ7CiAgbGFtYmRhMDAgPSBsYW1iZGEsIHBoaTAwID0gcGhpOwogIGxhbWJkYSAqPSByYWRpYW5z
LCBwaGkgKj0gcmFkaWFuczsKICBsYW1iZGEwID0gbGFtYmRhLCBjb3NQaGkwID0gY29zJDEocGhp
ID0gcGhpIC8gMiArIHF1YXJ0ZXJQaSksIHNpblBoaTAgPSBzaW4kMShwaGkpOwp9CgpmdW5jdGlv
biBhcmVhUG9pbnQobGFtYmRhLCBwaGkpIHsKICBsYW1iZGEgKj0gcmFkaWFucywgcGhpICo9IHJh
ZGlhbnM7CiAgcGhpID0gcGhpIC8gMiArIHF1YXJ0ZXJQaTsgLy8gaGFsZiB0aGUgYW5ndWxhciBk
aXN0YW5jZSBmcm9tIHNvdXRoIHBvbGUKCiAgLy8gU3BoZXJpY2FsIGV4Y2VzcyBFIGZvciBhIHNw
aGVyaWNhbCB0cmlhbmdsZSB3aXRoIHZlcnRpY2VzOiBzb3V0aCBwb2xlLAogIC8vIHByZXZpb3Vz
IHBvaW50LCBjdXJyZW50IHBvaW50LiAgVXNlcyBhIGZvcm11bGEgZGVyaXZlZCBmcm9tIENhZ25v
bGnigJlzCiAgLy8gdGhlb3JlbS4gIFNlZSBUb2RodW50ZXIsIFNwaGVyaWNhbCBUcmlnLiAoMTg3
MSksIFNlYy4gMTAzLCBFcS4gKDIpLgogIHZhciBkTGFtYmRhID0gbGFtYmRhIC0gbGFtYmRhMCwK
ICAgICAgc2RMYW1iZGEgPSBkTGFtYmRhID49IDAgPyAxIDogLTEsCiAgICAgIGFkTGFtYmRhID0g
c2RMYW1iZGEgKiBkTGFtYmRhLAogICAgICBjb3NQaGkgPSBjb3MkMShwaGkpLAogICAgICBzaW5Q
aGkgPSBzaW4kMShwaGkpLAogICAgICBrID0gc2luUGhpMCAqIHNpblBoaSwKICAgICAgdSA9IGNv
c1BoaTAgKiBjb3NQaGkgKyBrICogY29zJDEoYWRMYW1iZGEpLAogICAgICB2ID0gayAqIHNkTGFt
YmRhICogc2luJDEoYWRMYW1iZGEpOwogIGFyZWFSaW5nU3VtLmFkZChhdGFuMih2LCB1KSk7Cgog
IC8vIEFkdmFuY2UgdGhlIHByZXZpb3VzIHBvaW50cy4KICBsYW1iZGEwID0gbGFtYmRhLCBjb3NQ
aGkwID0gY29zUGhpLCBzaW5QaGkwID0gc2luUGhpOwp9CgpmdW5jdGlvbiBhcmVhJDEob2JqZWN0
KSB7CiAgYXJlYVN1bS5yZXNldCgpOwogIGdlb1N0cmVhbShvYmplY3QsIGFyZWFTdHJlYW0pOwog
IHJldHVybiBhcmVhU3VtICogMjsKfQoKZnVuY3Rpb24gc3BoZXJpY2FsKGNhcnRlc2lhbikgewog
IHJldHVybiBbYXRhbjIoY2FydGVzaWFuWzFdLCBjYXJ0ZXNpYW5bMF0pLCBhc2luKGNhcnRlc2lh
blsyXSldOwp9CgpmdW5jdGlvbiBjYXJ0ZXNpYW4oc3BoZXJpY2FsKSB7CiAgdmFyIGxhbWJkYSA9
IHNwaGVyaWNhbFswXSwgcGhpID0gc3BoZXJpY2FsWzFdLCBjb3NQaGkgPSBjb3MkMShwaGkpOwog
IHJldHVybiBbY29zUGhpICogY29zJDEobGFtYmRhKSwgY29zUGhpICogc2luJDEobGFtYmRhKSwg
c2luJDEocGhpKV07Cn0KCmZ1bmN0aW9uIGNhcnRlc2lhbkRvdChhLCBiKSB7CiAgcmV0dXJuIGFb
MF0gKiBiWzBdICsgYVsxXSAqIGJbMV0gKyBhWzJdICogYlsyXTsKfQoKZnVuY3Rpb24gY2FydGVz
aWFuQ3Jvc3MoYSwgYikgewogIHJldHVybiBbYVsxXSAqIGJbMl0gLSBhWzJdICogYlsxXSwgYVsy
XSAqIGJbMF0gLSBhWzBdICogYlsyXSwgYVswXSAqIGJbMV0gLSBhWzFdICogYlswXV07Cn0KCi8v
IFRPRE8gcmV0dXJuIGEKZnVuY3Rpb24gY2FydGVzaWFuQWRkSW5QbGFjZShhLCBiKSB7CiAgYVsw
XSArPSBiWzBdLCBhWzFdICs9IGJbMV0sIGFbMl0gKz0gYlsyXTsKfQoKZnVuY3Rpb24gY2FydGVz
aWFuU2NhbGUodmVjdG9yLCBrKSB7CiAgcmV0dXJuIFt2ZWN0b3JbMF0gKiBrLCB2ZWN0b3JbMV0g
KiBrLCB2ZWN0b3JbMl0gKiBrXTsKfQoKLy8gVE9ETyByZXR1cm4gZApmdW5jdGlvbiBjYXJ0ZXNp
YW5Ob3JtYWxpemVJblBsYWNlKGQpIHsKICB2YXIgbCA9IHNxcnQoZFswXSAqIGRbMF0gKyBkWzFd
ICogZFsxXSArIGRbMl0gKiBkWzJdKTsKICBkWzBdIC89IGwsIGRbMV0gLz0gbCwgZFsyXSAvPSBs
Owp9Cgp2YXIgbGFtYmRhMCQxLCBwaGkwLCBsYW1iZGExLCBwaGkxLCAvLyBib3VuZHMKICAgIGxh
bWJkYTIsIC8vIHByZXZpb3VzIGxhbWJkYS1jb29yZGluYXRlCiAgICBsYW1iZGEwMCQxLCBwaGkw
MCQxLCAvLyBmaXJzdCBwb2ludAogICAgcDAsIC8vIHByZXZpb3VzIDNEIHBvaW50CiAgICBkZWx0
YVN1bSA9IGFkZGVyKCksCiAgICByYW5nZXMsCiAgICByYW5nZTsKCnZhciBib3VuZHNTdHJlYW0g
PSB7CiAgcG9pbnQ6IGJvdW5kc1BvaW50LAogIGxpbmVTdGFydDogYm91bmRzTGluZVN0YXJ0LAog
IGxpbmVFbmQ6IGJvdW5kc0xpbmVFbmQsCiAgcG9seWdvblN0YXJ0OiBmdW5jdGlvbigpIHsKICAg
IGJvdW5kc1N0cmVhbS5wb2ludCA9IGJvdW5kc1JpbmdQb2ludDsKICAgIGJvdW5kc1N0cmVhbS5s
aW5lU3RhcnQgPSBib3VuZHNSaW5nU3RhcnQ7CiAgICBib3VuZHNTdHJlYW0ubGluZUVuZCA9IGJv
dW5kc1JpbmdFbmQ7CiAgICBkZWx0YVN1bS5yZXNldCgpOwogICAgYXJlYVN0cmVhbS5wb2x5Z29u
U3RhcnQoKTsKICB9LAogIHBvbHlnb25FbmQ6IGZ1bmN0aW9uKCkgewogICAgYXJlYVN0cmVhbS5w
b2x5Z29uRW5kKCk7CiAgICBib3VuZHNTdHJlYW0ucG9pbnQgPSBib3VuZHNQb2ludDsKICAgIGJv
dW5kc1N0cmVhbS5saW5lU3RhcnQgPSBib3VuZHNMaW5lU3RhcnQ7CiAgICBib3VuZHNTdHJlYW0u
bGluZUVuZCA9IGJvdW5kc0xpbmVFbmQ7CiAgICBpZiAoYXJlYVJpbmdTdW0gPCAwKSBsYW1iZGEw
JDEgPSAtKGxhbWJkYTEgPSAxODApLCBwaGkwID0gLShwaGkxID0gOTApOwogICAgZWxzZSBpZiAo
ZGVsdGFTdW0gPiBlcHNpbG9uJDIpIHBoaTEgPSA5MDsKICAgIGVsc2UgaWYgKGRlbHRhU3VtIDwg
LWVwc2lsb24kMikgcGhpMCA9IC05MDsKICAgIHJhbmdlWzBdID0gbGFtYmRhMCQxLCByYW5nZVsx
XSA9IGxhbWJkYTE7CiAgfSwKICBzcGhlcmU6IGZ1bmN0aW9uKCkgewogICAgbGFtYmRhMCQxID0g
LShsYW1iZGExID0gMTgwKSwgcGhpMCA9IC0ocGhpMSA9IDkwKTsKICB9Cn07CgpmdW5jdGlvbiBi
b3VuZHNQb2ludChsYW1iZGEsIHBoaSkgewogIHJhbmdlcy5wdXNoKHJhbmdlID0gW2xhbWJkYTAk
MSA9IGxhbWJkYSwgbGFtYmRhMSA9IGxhbWJkYV0pOwogIGlmIChwaGkgPCBwaGkwKSBwaGkwID0g
cGhpOwogIGlmIChwaGkgPiBwaGkxKSBwaGkxID0gcGhpOwp9CgpmdW5jdGlvbiBsaW5lUG9pbnQo
bGFtYmRhLCBwaGkpIHsKICB2YXIgcCA9IGNhcnRlc2lhbihbbGFtYmRhICogcmFkaWFucywgcGhp
ICogcmFkaWFuc10pOwogIGlmIChwMCkgewogICAgdmFyIG5vcm1hbCA9IGNhcnRlc2lhbkNyb3Nz
KHAwLCBwKSwKICAgICAgICBlcXVhdG9yaWFsID0gW25vcm1hbFsxXSwgLW5vcm1hbFswXSwgMF0s
CiAgICAgICAgaW5mbGVjdGlvbiA9IGNhcnRlc2lhbkNyb3NzKGVxdWF0b3JpYWwsIG5vcm1hbCk7
CiAgICBjYXJ0ZXNpYW5Ob3JtYWxpemVJblBsYWNlKGluZmxlY3Rpb24pOwogICAgaW5mbGVjdGlv
biA9IHNwaGVyaWNhbChpbmZsZWN0aW9uKTsKICAgIHZhciBkZWx0YSA9IGxhbWJkYSAtIGxhbWJk
YTIsCiAgICAgICAgc2lnbiA9IGRlbHRhID4gMCA/IDEgOiAtMSwKICAgICAgICBsYW1iZGFpID0g
aW5mbGVjdGlvblswXSAqIGRlZ3JlZXMkMSAqIHNpZ24sCiAgICAgICAgcGhpaSwKICAgICAgICBh
bnRpbWVyaWRpYW4gPSBhYnMoZGVsdGEpID4gMTgwOwogICAgaWYgKGFudGltZXJpZGlhbiBeIChz
aWduICogbGFtYmRhMiA8IGxhbWJkYWkgJiYgbGFtYmRhaSA8IHNpZ24gKiBsYW1iZGEpKSB7CiAg
ICAgIHBoaWkgPSBpbmZsZWN0aW9uWzFdICogZGVncmVlcyQxOwogICAgICBpZiAocGhpaSA+IHBo
aTEpIHBoaTEgPSBwaGlpOwogICAgfSBlbHNlIGlmIChsYW1iZGFpID0gKGxhbWJkYWkgKyAzNjAp
ICUgMzYwIC0gMTgwLCBhbnRpbWVyaWRpYW4gXiAoc2lnbiAqIGxhbWJkYTIgPCBsYW1iZGFpICYm
IGxhbWJkYWkgPCBzaWduICogbGFtYmRhKSkgewogICAgICBwaGlpID0gLWluZmxlY3Rpb25bMV0g
KiBkZWdyZWVzJDE7CiAgICAgIGlmIChwaGlpIDwgcGhpMCkgcGhpMCA9IHBoaWk7CiAgICB9IGVs
c2UgewogICAgICBpZiAocGhpIDwgcGhpMCkgcGhpMCA9IHBoaTsKICAgICAgaWYgKHBoaSA+IHBo
aTEpIHBoaTEgPSBwaGk7CiAgICB9CiAgICBpZiAoYW50aW1lcmlkaWFuKSB7CiAgICAgIGlmIChs
YW1iZGEgPCBsYW1iZGEyKSB7CiAgICAgICAgaWYgKGFuZ2xlKGxhbWJkYTAkMSwgbGFtYmRhKSA+
IGFuZ2xlKGxhbWJkYTAkMSwgbGFtYmRhMSkpIGxhbWJkYTEgPSBsYW1iZGE7CiAgICAgIH0gZWxz
ZSB7CiAgICAgICAgaWYgKGFuZ2xlKGxhbWJkYSwgbGFtYmRhMSkgPiBhbmdsZShsYW1iZGEwJDEs
IGxhbWJkYTEpKSBsYW1iZGEwJDEgPSBsYW1iZGE7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAg
IGlmIChsYW1iZGExID49IGxhbWJkYTAkMSkgewogICAgICAgIGlmIChsYW1iZGEgPCBsYW1iZGEw
JDEpIGxhbWJkYTAkMSA9IGxhbWJkYTsKICAgICAgICBpZiAobGFtYmRhID4gbGFtYmRhMSkgbGFt
YmRhMSA9IGxhbWJkYTsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAobGFtYmRhID4gbGFtYmRh
MikgewogICAgICAgICAgaWYgKGFuZ2xlKGxhbWJkYTAkMSwgbGFtYmRhKSA+IGFuZ2xlKGxhbWJk
YTAkMSwgbGFtYmRhMSkpIGxhbWJkYTEgPSBsYW1iZGE7CiAgICAgICAgfSBlbHNlIHsKICAgICAg
ICAgIGlmIChhbmdsZShsYW1iZGEsIGxhbWJkYTEpID4gYW5nbGUobGFtYmRhMCQxLCBsYW1iZGEx
KSkgbGFtYmRhMCQxID0gbGFtYmRhOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0gZWxzZSB7
CiAgICByYW5nZXMucHVzaChyYW5nZSA9IFtsYW1iZGEwJDEgPSBsYW1iZGEsIGxhbWJkYTEgPSBs
YW1iZGFdKTsKICB9CiAgaWYgKHBoaSA8IHBoaTApIHBoaTAgPSBwaGk7CiAgaWYgKHBoaSA+IHBo
aTEpIHBoaTEgPSBwaGk7CiAgcDAgPSBwLCBsYW1iZGEyID0gbGFtYmRhOwp9CgpmdW5jdGlvbiBi
b3VuZHNMaW5lU3RhcnQoKSB7CiAgYm91bmRzU3RyZWFtLnBvaW50ID0gbGluZVBvaW50Owp9Cgpm
dW5jdGlvbiBib3VuZHNMaW5lRW5kKCkgewogIHJhbmdlWzBdID0gbGFtYmRhMCQxLCByYW5nZVsx
XSA9IGxhbWJkYTE7CiAgYm91bmRzU3RyZWFtLnBvaW50ID0gYm91bmRzUG9pbnQ7CiAgcDAgPSBu
dWxsOwp9CgpmdW5jdGlvbiBib3VuZHNSaW5nUG9pbnQobGFtYmRhLCBwaGkpIHsKICBpZiAocDAp
IHsKICAgIHZhciBkZWx0YSA9IGxhbWJkYSAtIGxhbWJkYTI7CiAgICBkZWx0YVN1bS5hZGQoYWJz
KGRlbHRhKSA+IDE4MCA/IGRlbHRhICsgKGRlbHRhID4gMCA/IDM2MCA6IC0zNjApIDogZGVsdGEp
OwogIH0gZWxzZSB7CiAgICBsYW1iZGEwMCQxID0gbGFtYmRhLCBwaGkwMCQxID0gcGhpOwogIH0K
ICBhcmVhU3RyZWFtLnBvaW50KGxhbWJkYSwgcGhpKTsKICBsaW5lUG9pbnQobGFtYmRhLCBwaGkp
Owp9CgpmdW5jdGlvbiBib3VuZHNSaW5nU3RhcnQoKSB7CiAgYXJlYVN0cmVhbS5saW5lU3RhcnQo
KTsKfQoKZnVuY3Rpb24gYm91bmRzUmluZ0VuZCgpIHsKICBib3VuZHNSaW5nUG9pbnQobGFtYmRh
MDAkMSwgcGhpMDAkMSk7CiAgYXJlYVN0cmVhbS5saW5lRW5kKCk7CiAgaWYgKGFicyhkZWx0YVN1
bSkgPiBlcHNpbG9uJDIpIGxhbWJkYTAkMSA9IC0obGFtYmRhMSA9IDE4MCk7CiAgcmFuZ2VbMF0g
PSBsYW1iZGEwJDEsIHJhbmdlWzFdID0gbGFtYmRhMTsKICBwMCA9IG51bGw7Cn0KCi8vIEZpbmRz
IHRoZSBsZWZ0LXJpZ2h0IGRpc3RhbmNlIGJldHdlZW4gdHdvIGxvbmdpdHVkZXMuCi8vIFRoaXMg
aXMgYWxtb3N0IHRoZSBzYW1lIGFzIChsYW1iZGExIC0gbGFtYmRhMCArIDM2MMKwKSAlIDM2MMKw
LCBleGNlcHQgdGhhdCB3ZSB3YW50Ci8vIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIMKxMTgwwrAgdG8g
YmUgMzYwwrAuCmZ1bmN0aW9uIGFuZ2xlKGxhbWJkYTAsIGxhbWJkYTEpIHsKICByZXR1cm4gKGxh
bWJkYTEgLT0gbGFtYmRhMCkgPCAwID8gbGFtYmRhMSArIDM2MCA6IGxhbWJkYTE7Cn0KCmZ1bmN0
aW9uIHJhbmdlQ29tcGFyZShhLCBiKSB7CiAgcmV0dXJuIGFbMF0gLSBiWzBdOwp9CgpmdW5jdGlv
biByYW5nZUNvbnRhaW5zKHJhbmdlLCB4KSB7CiAgcmV0dXJuIHJhbmdlWzBdIDw9IHJhbmdlWzFd
ID8gcmFuZ2VbMF0gPD0geCAmJiB4IDw9IHJhbmdlWzFdIDogeCA8IHJhbmdlWzBdIHx8IHJhbmdl
WzFdIDwgeDsKfQoKZnVuY3Rpb24gYm91bmRzKGZlYXR1cmUpIHsKICB2YXIgaSwgbiwgYSwgYiwg
bWVyZ2VkLCBkZWx0YU1heCwgZGVsdGE7CgogIHBoaTEgPSBsYW1iZGExID0gLShsYW1iZGEwJDEg
PSBwaGkwID0gSW5maW5pdHkpOwogIHJhbmdlcyA9IFtdOwogIGdlb1N0cmVhbShmZWF0dXJlLCBi
b3VuZHNTdHJlYW0pOwoKICAvLyBGaXJzdCwgc29ydCByYW5nZXMgYnkgdGhlaXIgbWluaW11bSBs
b25naXR1ZGVzLgogIGlmIChuID0gcmFuZ2VzLmxlbmd0aCkgewogICAgcmFuZ2VzLnNvcnQocmFu
Z2VDb21wYXJlKTsKCiAgICAvLyBUaGVuLCBtZXJnZSBhbnkgcmFuZ2VzIHRoYXQgb3ZlcmxhcC4K
ICAgIGZvciAoaSA9IDEsIGEgPSByYW5nZXNbMF0sIG1lcmdlZCA9IFthXTsgaSA8IG47ICsraSkg
ewogICAgICBiID0gcmFuZ2VzW2ldOwogICAgICBpZiAocmFuZ2VDb250YWlucyhhLCBiWzBdKSB8
fCByYW5nZUNvbnRhaW5zKGEsIGJbMV0pKSB7CiAgICAgICAgaWYgKGFuZ2xlKGFbMF0sIGJbMV0p
ID4gYW5nbGUoYVswXSwgYVsxXSkpIGFbMV0gPSBiWzFdOwogICAgICAgIGlmIChhbmdsZShiWzBd
LCBhWzFdKSA+IGFuZ2xlKGFbMF0sIGFbMV0pKSBhWzBdID0gYlswXTsKICAgICAgfSBlbHNlIHsK
ICAgICAgICBtZXJnZWQucHVzaChhID0gYik7CiAgICAgIH0KICAgIH0KCiAgICAvLyBGaW5hbGx5
LCBmaW5kIHRoZSBsYXJnZXN0IGdhcCBiZXR3ZWVuIHRoZSBtZXJnZWQgcmFuZ2VzLgogICAgLy8g
VGhlIGZpbmFsIGJvdW5kaW5nIGJveCB3aWxsIGJlIHRoZSBpbnZlcnNlIG9mIHRoaXMgZ2FwLgog
ICAgZm9yIChkZWx0YU1heCA9IC1JbmZpbml0eSwgbiA9IG1lcmdlZC5sZW5ndGggLSAxLCBpID0g
MCwgYSA9IG1lcmdlZFtuXTsgaSA8PSBuOyBhID0gYiwgKytpKSB7CiAgICAgIGIgPSBtZXJnZWRb
aV07CiAgICAgIGlmICgoZGVsdGEgPSBhbmdsZShhWzFdLCBiWzBdKSkgPiBkZWx0YU1heCkgZGVs
dGFNYXggPSBkZWx0YSwgbGFtYmRhMCQxID0gYlswXSwgbGFtYmRhMSA9IGFbMV07CiAgICB9CiAg
fQoKICByYW5nZXMgPSByYW5nZSA9IG51bGw7CgogIHJldHVybiBsYW1iZGEwJDEgPT09IEluZmlu
aXR5IHx8IHBoaTAgPT09IEluZmluaXR5CiAgICAgID8gW1tOYU4sIE5hTl0sIFtOYU4sIE5hTl1d
CiAgICAgIDogW1tsYW1iZGEwJDEsIHBoaTBdLCBbbGFtYmRhMSwgcGhpMV1dOwp9Cgp2YXIgVzAs
IFcxLAogICAgWDAsIFkwLCBaMCwKICAgIFgxLCBZMSwgWjEsCiAgICBYMiwgWTIsIFoyLAogICAg
bGFtYmRhMDAkMiwgcGhpMDAkMiwgLy8gZmlyc3QgcG9pbnQKICAgIHgwLCB5MCwgejA7IC8vIHBy
ZXZpb3VzIHBvaW50Cgp2YXIgY2VudHJvaWRTdHJlYW0gPSB7CiAgc3BoZXJlOiBub29wJDIsCiAg
cG9pbnQ6IGNlbnRyb2lkUG9pbnQsCiAgbGluZVN0YXJ0OiBjZW50cm9pZExpbmVTdGFydCwKICBs
aW5lRW5kOiBjZW50cm9pZExpbmVFbmQsCiAgcG9seWdvblN0YXJ0OiBmdW5jdGlvbigpIHsKICAg
IGNlbnRyb2lkU3RyZWFtLmxpbmVTdGFydCA9IGNlbnRyb2lkUmluZ1N0YXJ0OwogICAgY2VudHJv
aWRTdHJlYW0ubGluZUVuZCA9IGNlbnRyb2lkUmluZ0VuZDsKICB9LAogIHBvbHlnb25FbmQ6IGZ1
bmN0aW9uKCkgewogICAgY2VudHJvaWRTdHJlYW0ubGluZVN0YXJ0ID0gY2VudHJvaWRMaW5lU3Rh
cnQ7CiAgICBjZW50cm9pZFN0cmVhbS5saW5lRW5kID0gY2VudHJvaWRMaW5lRW5kOwogIH0KfTsK
Ci8vIEFyaXRobWV0aWMgbWVhbiBvZiBDYXJ0ZXNpYW4gdmVjdG9ycy4KZnVuY3Rpb24gY2VudHJv
aWRQb2ludChsYW1iZGEsIHBoaSkgewogIGxhbWJkYSAqPSByYWRpYW5zLCBwaGkgKj0gcmFkaWFu
czsKICB2YXIgY29zUGhpID0gY29zJDEocGhpKTsKICBjZW50cm9pZFBvaW50Q2FydGVzaWFuKGNv
c1BoaSAqIGNvcyQxKGxhbWJkYSksIGNvc1BoaSAqIHNpbiQxKGxhbWJkYSksIHNpbiQxKHBoaSkp
Owp9CgpmdW5jdGlvbiBjZW50cm9pZFBvaW50Q2FydGVzaWFuKHgsIHksIHopIHsKICArK1cwOwog
IFgwICs9ICh4IC0gWDApIC8gVzA7CiAgWTAgKz0gKHkgLSBZMCkgLyBXMDsKICBaMCArPSAoeiAt
IFowKSAvIFcwOwp9CgpmdW5jdGlvbiBjZW50cm9pZExpbmVTdGFydCgpIHsKICBjZW50cm9pZFN0
cmVhbS5wb2ludCA9IGNlbnRyb2lkTGluZVBvaW50Rmlyc3Q7Cn0KCmZ1bmN0aW9uIGNlbnRyb2lk
TGluZVBvaW50Rmlyc3QobGFtYmRhLCBwaGkpIHsKICBsYW1iZGEgKj0gcmFkaWFucywgcGhpICo9
IHJhZGlhbnM7CiAgdmFyIGNvc1BoaSA9IGNvcyQxKHBoaSk7CiAgeDAgPSBjb3NQaGkgKiBjb3Mk
MShsYW1iZGEpOwogIHkwID0gY29zUGhpICogc2luJDEobGFtYmRhKTsKICB6MCA9IHNpbiQxKHBo
aSk7CiAgY2VudHJvaWRTdHJlYW0ucG9pbnQgPSBjZW50cm9pZExpbmVQb2ludDsKICBjZW50cm9p
ZFBvaW50Q2FydGVzaWFuKHgwLCB5MCwgejApOwp9CgpmdW5jdGlvbiBjZW50cm9pZExpbmVQb2lu
dChsYW1iZGEsIHBoaSkgewogIGxhbWJkYSAqPSByYWRpYW5zLCBwaGkgKj0gcmFkaWFuczsKICB2
YXIgY29zUGhpID0gY29zJDEocGhpKSwKICAgICAgeCA9IGNvc1BoaSAqIGNvcyQxKGxhbWJkYSks
CiAgICAgIHkgPSBjb3NQaGkgKiBzaW4kMShsYW1iZGEpLAogICAgICB6ID0gc2luJDEocGhpKSwK
ICAgICAgdyA9IGF0YW4yKHNxcnQoKHcgPSB5MCAqIHogLSB6MCAqIHkpICogdyArICh3ID0gejAg
KiB4IC0geDAgKiB6KSAqIHcgKyAodyA9IHgwICogeSAtIHkwICogeCkgKiB3KSwgeDAgKiB4ICsg
eTAgKiB5ICsgejAgKiB6KTsKICBXMSArPSB3OwogIFgxICs9IHcgKiAoeDAgKyAoeDAgPSB4KSk7
CiAgWTEgKz0gdyAqICh5MCArICh5MCA9IHkpKTsKICBaMSArPSB3ICogKHowICsgKHowID0geikp
OwogIGNlbnRyb2lkUG9pbnRDYXJ0ZXNpYW4oeDAsIHkwLCB6MCk7Cn0KCmZ1bmN0aW9uIGNlbnRy
b2lkTGluZUVuZCgpIHsKICBjZW50cm9pZFN0cmVhbS5wb2ludCA9IGNlbnRyb2lkUG9pbnQ7Cn0K
Ci8vIFNlZSBKLiBFLiBCcm9jaywgVGhlIEluZXJ0aWEgVGVuc29yIGZvciBhIFNwaGVyaWNhbCBU
cmlhbmdsZSwKLy8gSi4gQXBwbGllZCBNZWNoYW5pY3MgNDIsIDIzOSAoMTk3NSkuCmZ1bmN0aW9u
IGNlbnRyb2lkUmluZ1N0YXJ0KCkgewogIGNlbnRyb2lkU3RyZWFtLnBvaW50ID0gY2VudHJvaWRS
aW5nUG9pbnRGaXJzdDsKfQoKZnVuY3Rpb24gY2VudHJvaWRSaW5nRW5kKCkgewogIGNlbnRyb2lk
UmluZ1BvaW50KGxhbWJkYTAwJDIsIHBoaTAwJDIpOwogIGNlbnRyb2lkU3RyZWFtLnBvaW50ID0g
Y2VudHJvaWRQb2ludDsKfQoKZnVuY3Rpb24gY2VudHJvaWRSaW5nUG9pbnRGaXJzdChsYW1iZGEs
IHBoaSkgewogIGxhbWJkYTAwJDIgPSBsYW1iZGEsIHBoaTAwJDIgPSBwaGk7CiAgbGFtYmRhICo9
IHJhZGlhbnMsIHBoaSAqPSByYWRpYW5zOwogIGNlbnRyb2lkU3RyZWFtLnBvaW50ID0gY2VudHJv
aWRSaW5nUG9pbnQ7CiAgdmFyIGNvc1BoaSA9IGNvcyQxKHBoaSk7CiAgeDAgPSBjb3NQaGkgKiBj
b3MkMShsYW1iZGEpOwogIHkwID0gY29zUGhpICogc2luJDEobGFtYmRhKTsKICB6MCA9IHNpbiQx
KHBoaSk7CiAgY2VudHJvaWRQb2ludENhcnRlc2lhbih4MCwgeTAsIHowKTsKfQoKZnVuY3Rpb24g
Y2VudHJvaWRSaW5nUG9pbnQobGFtYmRhLCBwaGkpIHsKICBsYW1iZGEgKj0gcmFkaWFucywgcGhp
ICo9IHJhZGlhbnM7CiAgdmFyIGNvc1BoaSA9IGNvcyQxKHBoaSksCiAgICAgIHggPSBjb3NQaGkg
KiBjb3MkMShsYW1iZGEpLAogICAgICB5ID0gY29zUGhpICogc2luJDEobGFtYmRhKSwKICAgICAg
eiA9IHNpbiQxKHBoaSksCiAgICAgIGN4ID0geTAgKiB6IC0gejAgKiB5LAogICAgICBjeSA9IHow
ICogeCAtIHgwICogeiwKICAgICAgY3ogPSB4MCAqIHkgLSB5MCAqIHgsCiAgICAgIG0gPSBzcXJ0
KGN4ICogY3ggKyBjeSAqIGN5ICsgY3ogKiBjeiksCiAgICAgIHcgPSBhc2luKG0pLCAvLyBsaW5l
IHdlaWdodCA9IGFuZ2xlCiAgICAgIHYgPSBtICYmIC13IC8gbTsgLy8gYXJlYSB3ZWlnaHQgbXVs
dGlwbGllcgogIFgyICs9IHYgKiBjeDsKICBZMiArPSB2ICogY3k7CiAgWjIgKz0gdiAqIGN6Owog
IFcxICs9IHc7CiAgWDEgKz0gdyAqICh4MCArICh4MCA9IHgpKTsKICBZMSArPSB3ICogKHkwICsg
KHkwID0geSkpOwogIFoxICs9IHcgKiAoejAgKyAoejAgPSB6KSk7CiAgY2VudHJvaWRQb2ludENh
cnRlc2lhbih4MCwgeTAsIHowKTsKfQoKZnVuY3Rpb24gY2VudHJvaWQob2JqZWN0KSB7CiAgVzAg
PSBXMSA9CiAgWDAgPSBZMCA9IFowID0KICBYMSA9IFkxID0gWjEgPQogIFgyID0gWTIgPSBaMiA9
IDA7CiAgZ2VvU3RyZWFtKG9iamVjdCwgY2VudHJvaWRTdHJlYW0pOwoKICB2YXIgeCA9IFgyLAog
ICAgICB5ID0gWTIsCiAgICAgIHogPSBaMiwKICAgICAgbSA9IHggKiB4ICsgeSAqIHkgKyB6ICog
ejsKCiAgLy8gSWYgdGhlIGFyZWEtd2VpZ2h0ZWQgY2NlbnRyb2lkIGlzIHVuZGVmaW5lZCwgZmFs
bCBiYWNrIHRvIGxlbmd0aC13ZWlnaHRlZCBjY2VudHJvaWQuCiAgaWYgKG0gPCBlcHNpbG9uMiQx
KSB7CiAgICB4ID0gWDEsIHkgPSBZMSwgeiA9IFoxOwogICAgLy8gSWYgdGhlIGZlYXR1cmUgaGFz
IHplcm8gbGVuZ3RoLCBmYWxsIGJhY2sgdG8gYXJpdGhtZXRpYyBtZWFuIG9mIHBvaW50IHZlY3Rv
cnMuCiAgICBpZiAoVzEgPCBlcHNpbG9uJDIpIHggPSBYMCwgeSA9IFkwLCB6ID0gWjA7CiAgICBt
ID0geCAqIHggKyB5ICogeSArIHogKiB6OwogICAgLy8gSWYgdGhlIGZlYXR1cmUgc3RpbGwgaGFz
IGFuIHVuZGVmaW5lZCBjY2VudHJvaWQsIHRoZW4gcmV0dXJuLgogICAgaWYgKG0gPCBlcHNpbG9u
MiQxKSByZXR1cm4gW05hTiwgTmFOXTsKICB9CgogIHJldHVybiBbYXRhbjIoeSwgeCkgKiBkZWdy
ZWVzJDEsIGFzaW4oeiAvIHNxcnQobSkpICogZGVncmVlcyQxXTsKfQoKZnVuY3Rpb24gY29uc3Rh
bnQkOCh4KSB7CiAgcmV0dXJuIGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIHg7CiAgfTsKfQoKZnVu
Y3Rpb24gY29tcG9zZShhLCBiKSB7CgogIGZ1bmN0aW9uIGNvbXBvc2UoeCwgeSkgewogICAgcmV0
dXJuIHggPSBhKHgsIHkpLCBiKHhbMF0sIHhbMV0pOwogIH0KCiAgaWYgKGEuaW52ZXJ0ICYmIGIu
aW52ZXJ0KSBjb21wb3NlLmludmVydCA9IGZ1bmN0aW9uKHgsIHkpIHsKICAgIHJldHVybiB4ID0g
Yi5pbnZlcnQoeCwgeSksIHggJiYgYS5pbnZlcnQoeFswXSwgeFsxXSk7CiAgfTsKCiAgcmV0dXJu
IGNvbXBvc2U7Cn0KCmZ1bmN0aW9uIHJvdGF0aW9uSWRlbnRpdHkobGFtYmRhLCBwaGkpIHsKICBy
ZXR1cm4gW2FicyhsYW1iZGEpID4gcGkkMyA/IGxhbWJkYSArIE1hdGgucm91bmQoLWxhbWJkYSAv
IHRhdSQzKSAqIHRhdSQzIDogbGFtYmRhLCBwaGldOwp9Cgpyb3RhdGlvbklkZW50aXR5LmludmVy
dCA9IHJvdGF0aW9uSWRlbnRpdHk7CgpmdW5jdGlvbiByb3RhdGVSYWRpYW5zKGRlbHRhTGFtYmRh
LCBkZWx0YVBoaSwgZGVsdGFHYW1tYSkgewogIHJldHVybiAoZGVsdGFMYW1iZGEgJT0gdGF1JDMp
ID8gKGRlbHRhUGhpIHx8IGRlbHRhR2FtbWEgPyBjb21wb3NlKHJvdGF0aW9uTGFtYmRhKGRlbHRh
TGFtYmRhKSwgcm90YXRpb25QaGlHYW1tYShkZWx0YVBoaSwgZGVsdGFHYW1tYSkpCiAgICA6IHJv
dGF0aW9uTGFtYmRhKGRlbHRhTGFtYmRhKSkKICAgIDogKGRlbHRhUGhpIHx8IGRlbHRhR2FtbWEg
PyByb3RhdGlvblBoaUdhbW1hKGRlbHRhUGhpLCBkZWx0YUdhbW1hKQogICAgOiByb3RhdGlvbklk
ZW50aXR5KTsKfQoKZnVuY3Rpb24gZm9yd2FyZFJvdGF0aW9uTGFtYmRhKGRlbHRhTGFtYmRhKSB7
CiAgcmV0dXJuIGZ1bmN0aW9uKGxhbWJkYSwgcGhpKSB7CiAgICByZXR1cm4gbGFtYmRhICs9IGRl
bHRhTGFtYmRhLCBbbGFtYmRhID4gcGkkMyA/IGxhbWJkYSAtIHRhdSQzIDogbGFtYmRhIDwgLXBp
JDMgPyBsYW1iZGEgKyB0YXUkMyA6IGxhbWJkYSwgcGhpXTsKICB9Owp9CgpmdW5jdGlvbiByb3Rh
dGlvbkxhbWJkYShkZWx0YUxhbWJkYSkgewogIHZhciByb3RhdGlvbiA9IGZvcndhcmRSb3RhdGlv
bkxhbWJkYShkZWx0YUxhbWJkYSk7CiAgcm90YXRpb24uaW52ZXJ0ID0gZm9yd2FyZFJvdGF0aW9u
TGFtYmRhKC1kZWx0YUxhbWJkYSk7CiAgcmV0dXJuIHJvdGF0aW9uOwp9CgpmdW5jdGlvbiByb3Rh
dGlvblBoaUdhbW1hKGRlbHRhUGhpLCBkZWx0YUdhbW1hKSB7CiAgdmFyIGNvc0RlbHRhUGhpID0g
Y29zJDEoZGVsdGFQaGkpLAogICAgICBzaW5EZWx0YVBoaSA9IHNpbiQxKGRlbHRhUGhpKSwKICAg
ICAgY29zRGVsdGFHYW1tYSA9IGNvcyQxKGRlbHRhR2FtbWEpLAogICAgICBzaW5EZWx0YUdhbW1h
ID0gc2luJDEoZGVsdGFHYW1tYSk7CgogIGZ1bmN0aW9uIHJvdGF0aW9uKGxhbWJkYSwgcGhpKSB7
CiAgICB2YXIgY29zUGhpID0gY29zJDEocGhpKSwKICAgICAgICB4ID0gY29zJDEobGFtYmRhKSAq
IGNvc1BoaSwKICAgICAgICB5ID0gc2luJDEobGFtYmRhKSAqIGNvc1BoaSwKICAgICAgICB6ID0g
c2luJDEocGhpKSwKICAgICAgICBrID0geiAqIGNvc0RlbHRhUGhpICsgeCAqIHNpbkRlbHRhUGhp
OwogICAgcmV0dXJuIFsKICAgICAgYXRhbjIoeSAqIGNvc0RlbHRhR2FtbWEgLSBrICogc2luRGVs
dGFHYW1tYSwgeCAqIGNvc0RlbHRhUGhpIC0geiAqIHNpbkRlbHRhUGhpKSwKICAgICAgYXNpbihr
ICogY29zRGVsdGFHYW1tYSArIHkgKiBzaW5EZWx0YUdhbW1hKQogICAgXTsKICB9CgogIHJvdGF0
aW9uLmludmVydCA9IGZ1bmN0aW9uKGxhbWJkYSwgcGhpKSB7CiAgICB2YXIgY29zUGhpID0gY29z
JDEocGhpKSwKICAgICAgICB4ID0gY29zJDEobGFtYmRhKSAqIGNvc1BoaSwKICAgICAgICB5ID0g
c2luJDEobGFtYmRhKSAqIGNvc1BoaSwKICAgICAgICB6ID0gc2luJDEocGhpKSwKICAgICAgICBr
ID0geiAqIGNvc0RlbHRhR2FtbWEgLSB5ICogc2luRGVsdGFHYW1tYTsKICAgIHJldHVybiBbCiAg
ICAgIGF0YW4yKHkgKiBjb3NEZWx0YUdhbW1hICsgeiAqIHNpbkRlbHRhR2FtbWEsIHggKiBjb3NE
ZWx0YVBoaSArIGsgKiBzaW5EZWx0YVBoaSksCiAgICAgIGFzaW4oayAqIGNvc0RlbHRhUGhpIC0g
eCAqIHNpbkRlbHRhUGhpKQogICAgXTsKICB9OwoKICByZXR1cm4gcm90YXRpb247Cn0KCmZ1bmN0
aW9uIHJvdGF0aW9uKHJvdGF0ZSkgewogIHJvdGF0ZSA9IHJvdGF0ZVJhZGlhbnMocm90YXRlWzBd
ICogcmFkaWFucywgcm90YXRlWzFdICogcmFkaWFucywgcm90YXRlLmxlbmd0aCA+IDIgPyByb3Rh
dGVbMl0gKiByYWRpYW5zIDogMCk7CgogIGZ1bmN0aW9uIGZvcndhcmQoY29vcmRpbmF0ZXMpIHsK
ICAgIGNvb3JkaW5hdGVzID0gcm90YXRlKGNvb3JkaW5hdGVzWzBdICogcmFkaWFucywgY29vcmRp
bmF0ZXNbMV0gKiByYWRpYW5zKTsKICAgIHJldHVybiBjb29yZGluYXRlc1swXSAqPSBkZWdyZWVz
JDEsIGNvb3JkaW5hdGVzWzFdICo9IGRlZ3JlZXMkMSwgY29vcmRpbmF0ZXM7CiAgfQoKICBmb3J3
YXJkLmludmVydCA9IGZ1bmN0aW9uKGNvb3JkaW5hdGVzKSB7CiAgICBjb29yZGluYXRlcyA9IHJv
dGF0ZS5pbnZlcnQoY29vcmRpbmF0ZXNbMF0gKiByYWRpYW5zLCBjb29yZGluYXRlc1sxXSAqIHJh
ZGlhbnMpOwogICAgcmV0dXJuIGNvb3JkaW5hdGVzWzBdICo9IGRlZ3JlZXMkMSwgY29vcmRpbmF0
ZXNbMV0gKj0gZGVncmVlcyQxLCBjb29yZGluYXRlczsKICB9OwoKICByZXR1cm4gZm9yd2FyZDsK
fQoKLy8gR2VuZXJhdGVzIGEgY2lyY2xlIGNlbnRlcmVkIGF0IFswwrAsIDDCsF0sIHdpdGggYSBn
aXZlbiByYWRpdXMgYW5kIHByZWNpc2lvbi4KZnVuY3Rpb24gY2lyY2xlU3RyZWFtKHN0cmVhbSwg
cmFkaXVzLCBkZWx0YSwgZGlyZWN0aW9uLCB0MCwgdDEpIHsKICBpZiAoIWRlbHRhKSByZXR1cm47
CiAgdmFyIGNvc1JhZGl1cyA9IGNvcyQxKHJhZGl1cyksCiAgICAgIHNpblJhZGl1cyA9IHNpbiQx
KHJhZGl1cyksCiAgICAgIHN0ZXAgPSBkaXJlY3Rpb24gKiBkZWx0YTsKICBpZiAodDAgPT0gbnVs
bCkgewogICAgdDAgPSByYWRpdXMgKyBkaXJlY3Rpb24gKiB0YXUkMzsKICAgIHQxID0gcmFkaXVz
IC0gc3RlcCAvIDI7CiAgfSBlbHNlIHsKICAgIHQwID0gY2lyY2xlUmFkaXVzKGNvc1JhZGl1cywg
dDApOwogICAgdDEgPSBjaXJjbGVSYWRpdXMoY29zUmFkaXVzLCB0MSk7CiAgICBpZiAoZGlyZWN0
aW9uID4gMCA/IHQwIDwgdDEgOiB0MCA+IHQxKSB0MCArPSBkaXJlY3Rpb24gKiB0YXUkMzsKICB9
CiAgZm9yICh2YXIgcG9pbnQsIHQgPSB0MDsgZGlyZWN0aW9uID4gMCA/IHQgPiB0MSA6IHQgPCB0
MTsgdCAtPSBzdGVwKSB7CiAgICBwb2ludCA9IHNwaGVyaWNhbChbY29zUmFkaXVzLCAtc2luUmFk
aXVzICogY29zJDEodCksIC1zaW5SYWRpdXMgKiBzaW4kMSh0KV0pOwogICAgc3RyZWFtLnBvaW50
KHBvaW50WzBdLCBwb2ludFsxXSk7CiAgfQp9CgovLyBSZXR1cm5zIHRoZSBzaWduZWQgYW5nbGUg
b2YgYSBjYXJ0ZXNpYW4gcG9pbnQgcmVsYXRpdmUgdG8gW2Nvc1JhZGl1cywgMCwgMF0uCmZ1bmN0
aW9uIGNpcmNsZVJhZGl1cyhjb3NSYWRpdXMsIHBvaW50KSB7CiAgcG9pbnQgPSBjYXJ0ZXNpYW4o
cG9pbnQpLCBwb2ludFswXSAtPSBjb3NSYWRpdXM7CiAgY2FydGVzaWFuTm9ybWFsaXplSW5QbGFj
ZShwb2ludCk7CiAgdmFyIHJhZGl1cyA9IGFjb3MoLXBvaW50WzFdKTsKICByZXR1cm4gKCgtcG9p
bnRbMl0gPCAwID8gLXJhZGl1cyA6IHJhZGl1cykgKyB0YXUkMyAtIGVwc2lsb24kMikgJSB0YXUk
MzsKfQoKZnVuY3Rpb24gY2lyY2xlKCkgewogIHZhciBjZW50ZXIgPSBjb25zdGFudCQ4KFswLCAw
XSksCiAgICAgIHJhZGl1cyA9IGNvbnN0YW50JDgoOTApLAogICAgICBwcmVjaXNpb24gPSBjb25z
dGFudCQ4KDYpLAogICAgICByaW5nLAogICAgICByb3RhdGUsCiAgICAgIHN0cmVhbSA9IHtwb2lu
dDogcG9pbnR9OwoKICBmdW5jdGlvbiBwb2ludCh4LCB5KSB7CiAgICByaW5nLnB1c2goeCA9IHJv
dGF0ZSh4LCB5KSk7CiAgICB4WzBdICo9IGRlZ3JlZXMkMSwgeFsxXSAqPSBkZWdyZWVzJDE7CiAg
fQoKICBmdW5jdGlvbiBjaXJjbGUoKSB7CiAgICB2YXIgYyA9IGNlbnRlci5hcHBseSh0aGlzLCBh
cmd1bWVudHMpLAogICAgICAgIHIgPSByYWRpdXMuYXBwbHkodGhpcywgYXJndW1lbnRzKSAqIHJh
ZGlhbnMsCiAgICAgICAgcCA9IHByZWNpc2lvbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpICogcmFk
aWFuczsKICAgIHJpbmcgPSBbXTsKICAgIHJvdGF0ZSA9IHJvdGF0ZVJhZGlhbnMoLWNbMF0gKiBy
YWRpYW5zLCAtY1sxXSAqIHJhZGlhbnMsIDApLmludmVydDsKICAgIGNpcmNsZVN0cmVhbShzdHJl
YW0sIHIsIHAsIDEpOwogICAgYyA9IHt0eXBlOiAiUG9seWdvbiIsIGNvb3JkaW5hdGVzOiBbcmlu
Z119OwogICAgcmluZyA9IHJvdGF0ZSA9IG51bGw7CiAgICByZXR1cm4gYzsKICB9CgogIGNpcmNs
ZS5jZW50ZXIgPSBmdW5jdGlvbihfKSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChj
ZW50ZXIgPSB0eXBlb2YgXyA9PT0gImZ1bmN0aW9uIiA/IF8gOiBjb25zdGFudCQ4KFsrX1swXSwg
K19bMV1dKSwgY2lyY2xlKSA6IGNlbnRlcjsKICB9OwoKICBjaXJjbGUucmFkaXVzID0gZnVuY3Rp
b24oXykgewogICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAocmFkaXVzID0gdHlwZW9mIF8g
PT09ICJmdW5jdGlvbiIgPyBfIDogY29uc3RhbnQkOCgrXyksIGNpcmNsZSkgOiByYWRpdXM7CiAg
fTsKCiAgY2lyY2xlLnByZWNpc2lvbiA9IGZ1bmN0aW9uKF8pIHsKICAgIHJldHVybiBhcmd1bWVu
dHMubGVuZ3RoID8gKHByZWNpc2lvbiA9IHR5cGVvZiBfID09PSAiZnVuY3Rpb24iID8gXyA6IGNv
bnN0YW50JDgoK18pLCBjaXJjbGUpIDogcHJlY2lzaW9uOwogIH07CgogIHJldHVybiBjaXJjbGU7
Cn0KCmZ1bmN0aW9uIGNsaXBCdWZmZXIoKSB7CiAgdmFyIGxpbmVzID0gW10sCiAgICAgIGxpbmU7
CiAgcmV0dXJuIHsKICAgIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7CiAgICAgIGxpbmUucHVzaChb
eCwgeV0pOwogICAgfSwKICAgIGxpbmVTdGFydDogZnVuY3Rpb24oKSB7CiAgICAgIGxpbmVzLnB1
c2gobGluZSA9IFtdKTsKICAgIH0sCiAgICBsaW5lRW5kOiBub29wJDIsCiAgICByZWpvaW46IGZ1
bmN0aW9uKCkgewogICAgICBpZiAobGluZXMubGVuZ3RoID4gMSkgbGluZXMucHVzaChsaW5lcy5w
b3AoKS5jb25jYXQobGluZXMuc2hpZnQoKSkpOwogICAgfSwKICAgIHJlc3VsdDogZnVuY3Rpb24o
KSB7CiAgICAgIHZhciByZXN1bHQgPSBsaW5lczsKICAgICAgbGluZXMgPSBbXTsKICAgICAgbGlu
ZSA9IG51bGw7CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CiAgfTsKfQoKZnVuY3Rpb24gcG9p
bnRFcXVhbChhLCBiKSB7CiAgcmV0dXJuIGFicyhhWzBdIC0gYlswXSkgPCBlcHNpbG9uJDIgJiYg
YWJzKGFbMV0gLSBiWzFdKSA8IGVwc2lsb24kMjsKfQoKZnVuY3Rpb24gSW50ZXJzZWN0aW9uKHBv
aW50LCBwb2ludHMsIG90aGVyLCBlbnRyeSkgewogIHRoaXMueCA9IHBvaW50OwogIHRoaXMueiA9
IHBvaW50czsKICB0aGlzLm8gPSBvdGhlcjsgLy8gYW5vdGhlciBpbnRlcnNlY3Rpb24KICB0aGlz
LmUgPSBlbnRyeTsgLy8gaXMgYW4gZW50cnk/CiAgdGhpcy52ID0gZmFsc2U7IC8vIHZpc2l0ZWQK
ICB0aGlzLm4gPSB0aGlzLnAgPSBudWxsOyAvLyBuZXh0ICYgcHJldmlvdXMKfQoKLy8gQSBnZW5l
cmFsaXplZCBwb2x5Z29uIGNsaXBwaW5nIGFsZ29yaXRobTogZ2l2ZW4gYSBwb2x5Z29uIHRoYXQg
aGFzIGJlZW4gY3V0Ci8vIGludG8gaXRzIHZpc2libGUgbGluZSBzZWdtZW50cywgYW5kIHJlam9p
bnMgdGhlIHNlZ21lbnRzIGJ5IGludGVycG9sYXRpbmcKLy8gYWxvbmcgdGhlIGNsaXAgZWRnZS4K
ZnVuY3Rpb24gY2xpcFJlam9pbihzZWdtZW50cywgY29tcGFyZUludGVyc2VjdGlvbiwgc3RhcnRJ
bnNpZGUsIGludGVycG9sYXRlLCBzdHJlYW0pIHsKICB2YXIgc3ViamVjdCA9IFtdLAogICAgICBj
bGlwID0gW10sCiAgICAgIGksCiAgICAgIG47CgogIHNlZ21lbnRzLmZvckVhY2goZnVuY3Rpb24o
c2VnbWVudCkgewogICAgaWYgKChuID0gc2VnbWVudC5sZW5ndGggLSAxKSA8PSAwKSByZXR1cm47
CiAgICB2YXIgbiwgcDAgPSBzZWdtZW50WzBdLCBwMSA9IHNlZ21lbnRbbl0sIHg7CgogICAgLy8g
SWYgdGhlIGZpcnN0IGFuZCBsYXN0IHBvaW50cyBvZiBhIHNlZ21lbnQgYXJlIGNvaW5jaWRlbnQs
IHRoZW4gdHJlYXQgYXMgYQogICAgLy8gY2xvc2VkIHJpbmcuIFRPRE8gaWYgYWxsIHJpbmdzIGFy
ZSBjbG9zZWQsIHRoZW4gdGhlIHdpbmRpbmcgb3JkZXIgb2YgdGhlCiAgICAvLyBleHRlcmlvciBy
aW5nIHNob3VsZCBiZSBjaGVja2VkLgogICAgaWYgKHBvaW50RXF1YWwocDAsIHAxKSkgewogICAg
ICBzdHJlYW0ubGluZVN0YXJ0KCk7CiAgICAgIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIHN0cmVh
bS5wb2ludCgocDAgPSBzZWdtZW50W2ldKVswXSwgcDBbMV0pOwogICAgICBzdHJlYW0ubGluZUVu
ZCgpOwogICAgICByZXR1cm47CiAgICB9CgogICAgc3ViamVjdC5wdXNoKHggPSBuZXcgSW50ZXJz
ZWN0aW9uKHAwLCBzZWdtZW50LCBudWxsLCB0cnVlKSk7CiAgICBjbGlwLnB1c2goeC5vID0gbmV3
IEludGVyc2VjdGlvbihwMCwgbnVsbCwgeCwgZmFsc2UpKTsKICAgIHN1YmplY3QucHVzaCh4ID0g
bmV3IEludGVyc2VjdGlvbihwMSwgc2VnbWVudCwgbnVsbCwgZmFsc2UpKTsKICAgIGNsaXAucHVz
aCh4Lm8gPSBuZXcgSW50ZXJzZWN0aW9uKHAxLCBudWxsLCB4LCB0cnVlKSk7CiAgfSk7CgogIGlm
ICghc3ViamVjdC5sZW5ndGgpIHJldHVybjsKCiAgY2xpcC5zb3J0KGNvbXBhcmVJbnRlcnNlY3Rp
b24pOwogIGxpbmskMShzdWJqZWN0KTsKICBsaW5rJDEoY2xpcCk7CgogIGZvciAoaSA9IDAsIG4g
PSBjbGlwLmxlbmd0aDsgaSA8IG47ICsraSkgewogICAgY2xpcFtpXS5lID0gc3RhcnRJbnNpZGUg
PSAhc3RhcnRJbnNpZGU7CiAgfQoKICB2YXIgc3RhcnQgPSBzdWJqZWN0WzBdLAogICAgICBwb2lu
dHMsCiAgICAgIHBvaW50OwoKICB3aGlsZSAoMSkgewogICAgLy8gRmluZCBmaXJzdCB1bnZpc2l0
ZWQgaW50ZXJzZWN0aW9uLgogICAgdmFyIGN1cnJlbnQgPSBzdGFydCwKICAgICAgICBpc1N1Ympl
Y3QgPSB0cnVlOwogICAgd2hpbGUgKGN1cnJlbnQudikgaWYgKChjdXJyZW50ID0gY3VycmVudC5u
KSA9PT0gc3RhcnQpIHJldHVybjsKICAgIHBvaW50cyA9IGN1cnJlbnQuejsKICAgIHN0cmVhbS5s
aW5lU3RhcnQoKTsKICAgIGRvIHsKICAgICAgY3VycmVudC52ID0gY3VycmVudC5vLnYgPSB0cnVl
OwogICAgICBpZiAoY3VycmVudC5lKSB7CiAgICAgICAgaWYgKGlzU3ViamVjdCkgewogICAgICAg
ICAgZm9yIChpID0gMCwgbiA9IHBvaW50cy5sZW5ndGg7IGkgPCBuOyArK2kpIHN0cmVhbS5wb2lu
dCgocG9pbnQgPSBwb2ludHNbaV0pWzBdLCBwb2ludFsxXSk7CiAgICAgICAgfSBlbHNlIHsKICAg
ICAgICAgIGludGVycG9sYXRlKGN1cnJlbnQueCwgY3VycmVudC5uLngsIDEsIHN0cmVhbSk7CiAg
ICAgICAgfQogICAgICAgIGN1cnJlbnQgPSBjdXJyZW50Lm47CiAgICAgIH0gZWxzZSB7CiAgICAg
ICAgaWYgKGlzU3ViamVjdCkgewogICAgICAgICAgcG9pbnRzID0gY3VycmVudC5wLno7CiAgICAg
ICAgICBmb3IgKGkgPSBwb2ludHMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHN0cmVhbS5wb2lu
dCgocG9pbnQgPSBwb2ludHNbaV0pWzBdLCBwb2ludFsxXSk7CiAgICAgICAgfSBlbHNlIHsKICAg
ICAgICAgIGludGVycG9sYXRlKGN1cnJlbnQueCwgY3VycmVudC5wLngsIC0xLCBzdHJlYW0pOwog
ICAgICAgIH0KICAgICAgICBjdXJyZW50ID0gY3VycmVudC5wOwogICAgICB9CiAgICAgIGN1cnJl
bnQgPSBjdXJyZW50Lm87CiAgICAgIHBvaW50cyA9IGN1cnJlbnQuejsKICAgICAgaXNTdWJqZWN0
ID0gIWlzU3ViamVjdDsKICAgIH0gd2hpbGUgKCFjdXJyZW50LnYpOwogICAgc3RyZWFtLmxpbmVF
bmQoKTsKICB9Cn0KCmZ1bmN0aW9uIGxpbmskMShhcnJheSkgewogIGlmICghKG4gPSBhcnJheS5s
ZW5ndGgpKSByZXR1cm47CiAgdmFyIG4sCiAgICAgIGkgPSAwLAogICAgICBhID0gYXJyYXlbMF0s
CiAgICAgIGI7CiAgd2hpbGUgKCsraSA8IG4pIHsKICAgIGEubiA9IGIgPSBhcnJheVtpXTsKICAg
IGIucCA9IGE7CiAgICBhID0gYjsKICB9CiAgYS5uID0gYiA9IGFycmF5WzBdOwogIGIucCA9IGE7
Cn0KCnZhciBzdW0kMSA9IGFkZGVyKCk7CgpmdW5jdGlvbiBsb25naXR1ZGUocG9pbnQpIHsKICBp
ZiAoYWJzKHBvaW50WzBdKSA8PSBwaSQzKQogICAgcmV0dXJuIHBvaW50WzBdOwogIGVsc2UKICAg
IHJldHVybiBzaWduKHBvaW50WzBdKSAqICgoYWJzKHBvaW50WzBdKSArIHBpJDMpICUgdGF1JDMg
LSBwaSQzKTsKfQoKZnVuY3Rpb24gcG9seWdvbkNvbnRhaW5zKHBvbHlnb24sIHBvaW50KSB7CiAg
dmFyIGxhbWJkYSA9IGxvbmdpdHVkZShwb2ludCksCiAgICAgIHBoaSA9IHBvaW50WzFdLAogICAg
ICBzaW5QaGkgPSBzaW4kMShwaGkpLAogICAgICBub3JtYWwgPSBbc2luJDEobGFtYmRhKSwgLWNv
cyQxKGxhbWJkYSksIDBdLAogICAgICBhbmdsZSA9IDAsCiAgICAgIHdpbmRpbmcgPSAwOwoKICBz
dW0kMS5yZXNldCgpOwoKICBpZiAoc2luUGhpID09PSAxKSBwaGkgPSBoYWxmUGkkMiArIGVwc2ls
b24kMjsKICBlbHNlIGlmIChzaW5QaGkgPT09IC0xKSBwaGkgPSAtaGFsZlBpJDIgLSBlcHNpbG9u
JDI7CgogIGZvciAodmFyIGkgPSAwLCBuID0gcG9seWdvbi5sZW5ndGg7IGkgPCBuOyArK2kpIHsK
ICAgIGlmICghKG0gPSAocmluZyA9IHBvbHlnb25baV0pLmxlbmd0aCkpIGNvbnRpbnVlOwogICAg
dmFyIHJpbmcsCiAgICAgICAgbSwKICAgICAgICBwb2ludDAgPSByaW5nW20gLSAxXSwKICAgICAg
ICBsYW1iZGEwID0gbG9uZ2l0dWRlKHBvaW50MCksCiAgICAgICAgcGhpMCA9IHBvaW50MFsxXSAv
IDIgKyBxdWFydGVyUGksCiAgICAgICAgc2luUGhpMCA9IHNpbiQxKHBoaTApLAogICAgICAgIGNv
c1BoaTAgPSBjb3MkMShwaGkwKTsKCiAgICBmb3IgKHZhciBqID0gMDsgaiA8IG07ICsraiwgbGFt
YmRhMCA9IGxhbWJkYTEsIHNpblBoaTAgPSBzaW5QaGkxLCBjb3NQaGkwID0gY29zUGhpMSwgcG9p
bnQwID0gcG9pbnQxKSB7CiAgICAgIHZhciBwb2ludDEgPSByaW5nW2pdLAogICAgICAgICAgbGFt
YmRhMSA9IGxvbmdpdHVkZShwb2ludDEpLAogICAgICAgICAgcGhpMSA9IHBvaW50MVsxXSAvIDIg
KyBxdWFydGVyUGksCiAgICAgICAgICBzaW5QaGkxID0gc2luJDEocGhpMSksCiAgICAgICAgICBj
b3NQaGkxID0gY29zJDEocGhpMSksCiAgICAgICAgICBkZWx0YSA9IGxhbWJkYTEgLSBsYW1iZGEw
LAogICAgICAgICAgc2lnbiA9IGRlbHRhID49IDAgPyAxIDogLTEsCiAgICAgICAgICBhYnNEZWx0
YSA9IHNpZ24gKiBkZWx0YSwKICAgICAgICAgIGFudGltZXJpZGlhbiA9IGFic0RlbHRhID4gcGkk
MywKICAgICAgICAgIGsgPSBzaW5QaGkwICogc2luUGhpMTsKCiAgICAgIHN1bSQxLmFkZChhdGFu
MihrICogc2lnbiAqIHNpbiQxKGFic0RlbHRhKSwgY29zUGhpMCAqIGNvc1BoaTEgKyBrICogY29z
JDEoYWJzRGVsdGEpKSk7CiAgICAgIGFuZ2xlICs9IGFudGltZXJpZGlhbiA/IGRlbHRhICsgc2ln
biAqIHRhdSQzIDogZGVsdGE7CgogICAgICAvLyBBcmUgdGhlIGxvbmdpdHVkZXMgZWl0aGVyIHNp
ZGUgb2YgdGhlIHBvaW504oCZcyBtZXJpZGlhbiAobGFtYmRhKSwKICAgICAgLy8gYW5kIGFyZSB0
aGUgbGF0aXR1ZGVzIHNtYWxsZXIgdGhhbiB0aGUgcGFyYWxsZWwgKHBoaSk/CiAgICAgIGlmIChh
bnRpbWVyaWRpYW4gXiBsYW1iZGEwID49IGxhbWJkYSBeIGxhbWJkYTEgPj0gbGFtYmRhKSB7CiAg
ICAgICAgdmFyIGFyYyA9IGNhcnRlc2lhbkNyb3NzKGNhcnRlc2lhbihwb2ludDApLCBjYXJ0ZXNp
YW4ocG9pbnQxKSk7CiAgICAgICAgY2FydGVzaWFuTm9ybWFsaXplSW5QbGFjZShhcmMpOwogICAg
ICAgIHZhciBpbnRlcnNlY3Rpb24gPSBjYXJ0ZXNpYW5Dcm9zcyhub3JtYWwsIGFyYyk7CiAgICAg
ICAgY2FydGVzaWFuTm9ybWFsaXplSW5QbGFjZShpbnRlcnNlY3Rpb24pOwogICAgICAgIHZhciBw
aGlBcmMgPSAoYW50aW1lcmlkaWFuIF4gZGVsdGEgPj0gMCA/IC0xIDogMSkgKiBhc2luKGludGVy
c2VjdGlvblsyXSk7CiAgICAgICAgaWYgKHBoaSA+IHBoaUFyYyB8fCBwaGkgPT09IHBoaUFyYyAm
JiAoYXJjWzBdIHx8IGFyY1sxXSkpIHsKICAgICAgICAgIHdpbmRpbmcgKz0gYW50aW1lcmlkaWFu
IF4gZGVsdGEgPj0gMCA/IDEgOiAtMTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9CgogIC8v
IEZpcnN0LCBkZXRlcm1pbmUgd2hldGhlciB0aGUgU291dGggcG9sZSBpcyBpbnNpZGUgb3Igb3V0
c2lkZToKICAvLwogIC8vIEl0IGlzIGluc2lkZSBpZjoKICAvLyAqIHRoZSBwb2x5Z29uIHdpbmRz
IGFyb3VuZCBpdCBpbiBhIGNsb2Nrd2lzZSBkaXJlY3Rpb24uCiAgLy8gKiB0aGUgcG9seWdvbiBk
b2VzIG5vdCAoY3VtdWxhdGl2ZWx5KSB3aW5kIGFyb3VuZCBpdCwgYnV0IGhhcyBhIG5lZ2F0aXZl
CiAgLy8gICAoY291bnRlci1jbG9ja3dpc2UpIGFyZWEuCiAgLy8KICAvLyBTZWNvbmQsIGNvdW50
IHRoZSAoc2lnbmVkKSBudW1iZXIgb2YgdGltZXMgYSBzZWdtZW50IGNyb3NzZXMgYSBsYW1iZGEK
ICAvLyBmcm9tIHRoZSBwb2ludCB0byB0aGUgU291dGggcG9sZS4gIElmIGl0IGlzIHplcm8sIHRo
ZW4gdGhlIHBvaW50IGlzIHRoZQogIC8vIHNhbWUgc2lkZSBhcyB0aGUgU291dGggcG9sZS4KCiAg
cmV0dXJuIChhbmdsZSA8IC1lcHNpbG9uJDIgfHwgYW5nbGUgPCBlcHNpbG9uJDIgJiYgc3VtJDEg
PCAtZXBzaWxvbiQyKSBeICh3aW5kaW5nICYgMSk7Cn0KCmZ1bmN0aW9uIGNsaXAocG9pbnRWaXNp
YmxlLCBjbGlwTGluZSwgaW50ZXJwb2xhdGUsIHN0YXJ0KSB7CiAgcmV0dXJuIGZ1bmN0aW9uKHNp
bmspIHsKICAgIHZhciBsaW5lID0gY2xpcExpbmUoc2luayksCiAgICAgICAgcmluZ0J1ZmZlciA9
IGNsaXBCdWZmZXIoKSwKICAgICAgICByaW5nU2luayA9IGNsaXBMaW5lKHJpbmdCdWZmZXIpLAog
ICAgICAgIHBvbHlnb25TdGFydGVkID0gZmFsc2UsCiAgICAgICAgcG9seWdvbiwKICAgICAgICBz
ZWdtZW50cywKICAgICAgICByaW5nOwoKICAgIHZhciBjbGlwID0gewogICAgICBwb2ludDogcG9p
bnQsCiAgICAgIGxpbmVTdGFydDogbGluZVN0YXJ0LAogICAgICBsaW5lRW5kOiBsaW5lRW5kLAog
ICAgICBwb2x5Z29uU3RhcnQ6IGZ1bmN0aW9uKCkgewogICAgICAgIGNsaXAucG9pbnQgPSBwb2lu
dFJpbmc7CiAgICAgICAgY2xpcC5saW5lU3RhcnQgPSByaW5nU3RhcnQ7CiAgICAgICAgY2xpcC5s
aW5lRW5kID0gcmluZ0VuZDsKICAgICAgICBzZWdtZW50cyA9IFtdOwogICAgICAgIHBvbHlnb24g
PSBbXTsKICAgICAgfSwKICAgICAgcG9seWdvbkVuZDogZnVuY3Rpb24oKSB7CiAgICAgICAgY2xp
cC5wb2ludCA9IHBvaW50OwogICAgICAgIGNsaXAubGluZVN0YXJ0ID0gbGluZVN0YXJ0OwogICAg
ICAgIGNsaXAubGluZUVuZCA9IGxpbmVFbmQ7CiAgICAgICAgc2VnbWVudHMgPSBtZXJnZShzZWdt
ZW50cyk7CiAgICAgICAgdmFyIHN0YXJ0SW5zaWRlID0gcG9seWdvbkNvbnRhaW5zKHBvbHlnb24s
IHN0YXJ0KTsKICAgICAgICBpZiAoc2VnbWVudHMubGVuZ3RoKSB7CiAgICAgICAgICBpZiAoIXBv
bHlnb25TdGFydGVkKSBzaW5rLnBvbHlnb25TdGFydCgpLCBwb2x5Z29uU3RhcnRlZCA9IHRydWU7
CiAgICAgICAgICBjbGlwUmVqb2luKHNlZ21lbnRzLCBjb21wYXJlSW50ZXJzZWN0aW9uLCBzdGFy
dEluc2lkZSwgaW50ZXJwb2xhdGUsIHNpbmspOwogICAgICAgIH0gZWxzZSBpZiAoc3RhcnRJbnNp
ZGUpIHsKICAgICAgICAgIGlmICghcG9seWdvblN0YXJ0ZWQpIHNpbmsucG9seWdvblN0YXJ0KCks
IHBvbHlnb25TdGFydGVkID0gdHJ1ZTsKICAgICAgICAgIHNpbmsubGluZVN0YXJ0KCk7CiAgICAg
ICAgICBpbnRlcnBvbGF0ZShudWxsLCBudWxsLCAxLCBzaW5rKTsKICAgICAgICAgIHNpbmsubGlu
ZUVuZCgpOwogICAgICAgIH0KICAgICAgICBpZiAocG9seWdvblN0YXJ0ZWQpIHNpbmsucG9seWdv
bkVuZCgpLCBwb2x5Z29uU3RhcnRlZCA9IGZhbHNlOwogICAgICAgIHNlZ21lbnRzID0gcG9seWdv
biA9IG51bGw7CiAgICAgIH0sCiAgICAgIHNwaGVyZTogZnVuY3Rpb24oKSB7CiAgICAgICAgc2lu
ay5wb2x5Z29uU3RhcnQoKTsKICAgICAgICBzaW5rLmxpbmVTdGFydCgpOwogICAgICAgIGludGVy
cG9sYXRlKG51bGwsIG51bGwsIDEsIHNpbmspOwogICAgICAgIHNpbmsubGluZUVuZCgpOwogICAg
ICAgIHNpbmsucG9seWdvbkVuZCgpOwogICAgICB9CiAgICB9OwoKICAgIGZ1bmN0aW9uIHBvaW50
KGxhbWJkYSwgcGhpKSB7CiAgICAgIGlmIChwb2ludFZpc2libGUobGFtYmRhLCBwaGkpKSBzaW5r
LnBvaW50KGxhbWJkYSwgcGhpKTsKICAgIH0KCiAgICBmdW5jdGlvbiBwb2ludExpbmUobGFtYmRh
LCBwaGkpIHsKICAgICAgbGluZS5wb2ludChsYW1iZGEsIHBoaSk7CiAgICB9CgogICAgZnVuY3Rp
b24gbGluZVN0YXJ0KCkgewogICAgICBjbGlwLnBvaW50ID0gcG9pbnRMaW5lOwogICAgICBsaW5l
LmxpbmVTdGFydCgpOwogICAgfQoKICAgIGZ1bmN0aW9uIGxpbmVFbmQoKSB7CiAgICAgIGNsaXAu
cG9pbnQgPSBwb2ludDsKICAgICAgbGluZS5saW5lRW5kKCk7CiAgICB9CgogICAgZnVuY3Rpb24g
cG9pbnRSaW5nKGxhbWJkYSwgcGhpKSB7CiAgICAgIHJpbmcucHVzaChbbGFtYmRhLCBwaGldKTsK
ICAgICAgcmluZ1NpbmsucG9pbnQobGFtYmRhLCBwaGkpOwogICAgfQoKICAgIGZ1bmN0aW9uIHJp
bmdTdGFydCgpIHsKICAgICAgcmluZ1NpbmsubGluZVN0YXJ0KCk7CiAgICAgIHJpbmcgPSBbXTsK
ICAgIH0KCiAgICBmdW5jdGlvbiByaW5nRW5kKCkgewogICAgICBwb2ludFJpbmcocmluZ1swXVsw
XSwgcmluZ1swXVsxXSk7CiAgICAgIHJpbmdTaW5rLmxpbmVFbmQoKTsKCiAgICAgIHZhciBjbGVh
biA9IHJpbmdTaW5rLmNsZWFuKCksCiAgICAgICAgICByaW5nU2VnbWVudHMgPSByaW5nQnVmZmVy
LnJlc3VsdCgpLAogICAgICAgICAgaSwgbiA9IHJpbmdTZWdtZW50cy5sZW5ndGgsIG0sCiAgICAg
ICAgICBzZWdtZW50LAogICAgICAgICAgcG9pbnQ7CgogICAgICByaW5nLnBvcCgpOwogICAgICBw
b2x5Z29uLnB1c2gocmluZyk7CiAgICAgIHJpbmcgPSBudWxsOwoKICAgICAgaWYgKCFuKSByZXR1
cm47CgogICAgICAvLyBObyBpbnRlcnNlY3Rpb25zLgogICAgICBpZiAoY2xlYW4gJiAxKSB7CiAg
ICAgICAgc2VnbWVudCA9IHJpbmdTZWdtZW50c1swXTsKICAgICAgICBpZiAoKG0gPSBzZWdtZW50
Lmxlbmd0aCAtIDEpID4gMCkgewogICAgICAgICAgaWYgKCFwb2x5Z29uU3RhcnRlZCkgc2luay5w
b2x5Z29uU3RhcnQoKSwgcG9seWdvblN0YXJ0ZWQgPSB0cnVlOwogICAgICAgICAgc2luay5saW5l
U3RhcnQoKTsKICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBtOyArK2kpIHNpbmsucG9pbnQoKHBv
aW50ID0gc2VnbWVudFtpXSlbMF0sIHBvaW50WzFdKTsKICAgICAgICAgIHNpbmsubGluZUVuZCgp
OwogICAgICAgIH0KICAgICAgICByZXR1cm47CiAgICAgIH0KCiAgICAgIC8vIFJlam9pbiBjb25u
ZWN0ZWQgc2VnbWVudHMuCiAgICAgIC8vIFRPRE8gcmV1c2UgcmluZ0J1ZmZlci5yZWpvaW4oKT8K
ICAgICAgaWYgKG4gPiAxICYmIGNsZWFuICYgMikgcmluZ1NlZ21lbnRzLnB1c2gocmluZ1NlZ21l
bnRzLnBvcCgpLmNvbmNhdChyaW5nU2VnbWVudHMuc2hpZnQoKSkpOwoKICAgICAgc2VnbWVudHMu
cHVzaChyaW5nU2VnbWVudHMuZmlsdGVyKHZhbGlkU2VnbWVudCkpOwogICAgfQoKICAgIHJldHVy
biBjbGlwOwogIH07Cn0KCmZ1bmN0aW9uIHZhbGlkU2VnbWVudChzZWdtZW50KSB7CiAgcmV0dXJu
IHNlZ21lbnQubGVuZ3RoID4gMTsKfQoKLy8gSW50ZXJzZWN0aW9ucyBhcmUgc29ydGVkIGFsb25n
IHRoZSBjbGlwIGVkZ2UuIEZvciBib3RoIGFudGltZXJpZGlhbiBjdXR0aW5nCi8vIGFuZCBjaXJj
bGUgY2xpcHBpbmcsIHRoZSBzYW1lIGNvbXBhcmlzb24gaXMgdXNlZC4KZnVuY3Rpb24gY29tcGFy
ZUludGVyc2VjdGlvbihhLCBiKSB7CiAgcmV0dXJuICgoYSA9IGEueClbMF0gPCAwID8gYVsxXSAt
IGhhbGZQaSQyIC0gZXBzaWxvbiQyIDogaGFsZlBpJDIgLSBhWzFdKQogICAgICAgLSAoKGIgPSBi
LngpWzBdIDwgMCA/IGJbMV0gLSBoYWxmUGkkMiAtIGVwc2lsb24kMiA6IGhhbGZQaSQyIC0gYlsx
XSk7Cn0KCnZhciBjbGlwQW50aW1lcmlkaWFuID0gY2xpcCgKICBmdW5jdGlvbigpIHsgcmV0dXJu
IHRydWU7IH0sCiAgY2xpcEFudGltZXJpZGlhbkxpbmUsCiAgY2xpcEFudGltZXJpZGlhbkludGVy
cG9sYXRlLAogIFstcGkkMywgLWhhbGZQaSQyXQopOwoKLy8gVGFrZXMgYSBsaW5lIGFuZCBjdXRz
IGludG8gdmlzaWJsZSBzZWdtZW50cy4gUmV0dXJuIHZhbHVlczogMCAtIHRoZXJlIHdlcmUKLy8g
aW50ZXJzZWN0aW9ucyBvciB0aGUgbGluZSB3YXMgZW1wdHk7IDEgLSBubyBpbnRlcnNlY3Rpb25z
OyAyIC0gdGhlcmUgd2VyZQovLyBpbnRlcnNlY3Rpb25zLCBhbmQgdGhlIGZpcnN0IGFuZCBsYXN0
IHNlZ21lbnRzIHNob3VsZCBiZSByZWpvaW5lZC4KZnVuY3Rpb24gY2xpcEFudGltZXJpZGlhbkxp
bmUoc3RyZWFtKSB7CiAgdmFyIGxhbWJkYTAgPSBOYU4sCiAgICAgIHBoaTAgPSBOYU4sCiAgICAg
IHNpZ24wID0gTmFOLAogICAgICBjbGVhbjsgLy8gbm8gaW50ZXJzZWN0aW9ucwoKICByZXR1cm4g
ewogICAgbGluZVN0YXJ0OiBmdW5jdGlvbigpIHsKICAgICAgc3RyZWFtLmxpbmVTdGFydCgpOwog
ICAgICBjbGVhbiA9IDE7CiAgICB9LAogICAgcG9pbnQ6IGZ1bmN0aW9uKGxhbWJkYTEsIHBoaTEp
IHsKICAgICAgdmFyIHNpZ24xID0gbGFtYmRhMSA+IDAgPyBwaSQzIDogLXBpJDMsCiAgICAgICAg
ICBkZWx0YSA9IGFicyhsYW1iZGExIC0gbGFtYmRhMCk7CiAgICAgIGlmIChhYnMoZGVsdGEgLSBw
aSQzKSA8IGVwc2lsb24kMikgeyAvLyBsaW5lIGNyb3NzZXMgYSBwb2xlCiAgICAgICAgc3RyZWFt
LnBvaW50KGxhbWJkYTAsIHBoaTAgPSAocGhpMCArIHBoaTEpIC8gMiA+IDAgPyBoYWxmUGkkMiA6
IC1oYWxmUGkkMik7CiAgICAgICAgc3RyZWFtLnBvaW50KHNpZ24wLCBwaGkwKTsKICAgICAgICBz
dHJlYW0ubGluZUVuZCgpOwogICAgICAgIHN0cmVhbS5saW5lU3RhcnQoKTsKICAgICAgICBzdHJl
YW0ucG9pbnQoc2lnbjEsIHBoaTApOwogICAgICAgIHN0cmVhbS5wb2ludChsYW1iZGExLCBwaGkw
KTsKICAgICAgICBjbGVhbiA9IDA7CiAgICAgIH0gZWxzZSBpZiAoc2lnbjAgIT09IHNpZ24xICYm
IGRlbHRhID49IHBpJDMpIHsgLy8gbGluZSBjcm9zc2VzIGFudGltZXJpZGlhbgogICAgICAgIGlm
IChhYnMobGFtYmRhMCAtIHNpZ24wKSA8IGVwc2lsb24kMikgbGFtYmRhMCAtPSBzaWduMCAqIGVw
c2lsb24kMjsgLy8gaGFuZGxlIGRlZ2VuZXJhY2llcwogICAgICAgIGlmIChhYnMobGFtYmRhMSAt
IHNpZ24xKSA8IGVwc2lsb24kMikgbGFtYmRhMSAtPSBzaWduMSAqIGVwc2lsb24kMjsKICAgICAg
ICBwaGkwID0gY2xpcEFudGltZXJpZGlhbkludGVyc2VjdChsYW1iZGEwLCBwaGkwLCBsYW1iZGEx
LCBwaGkxKTsKICAgICAgICBzdHJlYW0ucG9pbnQoc2lnbjAsIHBoaTApOwogICAgICAgIHN0cmVh
bS5saW5lRW5kKCk7CiAgICAgICAgc3RyZWFtLmxpbmVTdGFydCgpOwogICAgICAgIHN0cmVhbS5w
b2ludChzaWduMSwgcGhpMCk7CiAgICAgICAgY2xlYW4gPSAwOwogICAgICB9CiAgICAgIHN0cmVh
bS5wb2ludChsYW1iZGEwID0gbGFtYmRhMSwgcGhpMCA9IHBoaTEpOwogICAgICBzaWduMCA9IHNp
Z24xOwogICAgfSwKICAgIGxpbmVFbmQ6IGZ1bmN0aW9uKCkgewogICAgICBzdHJlYW0ubGluZUVu
ZCgpOwogICAgICBsYW1iZGEwID0gcGhpMCA9IE5hTjsKICAgIH0sCiAgICBjbGVhbjogZnVuY3Rp
b24oKSB7CiAgICAgIHJldHVybiAyIC0gY2xlYW47IC8vIGlmIGludGVyc2VjdGlvbnMsIHJlam9p
biBmaXJzdCBhbmQgbGFzdCBzZWdtZW50cwogICAgfQogIH07Cn0KCmZ1bmN0aW9uIGNsaXBBbnRp
bWVyaWRpYW5JbnRlcnNlY3QobGFtYmRhMCwgcGhpMCwgbGFtYmRhMSwgcGhpMSkgewogIHZhciBj
b3NQaGkwLAogICAgICBjb3NQaGkxLAogICAgICBzaW5MYW1iZGEwTGFtYmRhMSA9IHNpbiQxKGxh
bWJkYTAgLSBsYW1iZGExKTsKICByZXR1cm4gYWJzKHNpbkxhbWJkYTBMYW1iZGExKSA+IGVwc2ls
b24kMgogICAgICA/IGF0YW4oKHNpbiQxKHBoaTApICogKGNvc1BoaTEgPSBjb3MkMShwaGkxKSkg
KiBzaW4kMShsYW1iZGExKQogICAgICAgICAgLSBzaW4kMShwaGkxKSAqIChjb3NQaGkwID0gY29z
JDEocGhpMCkpICogc2luJDEobGFtYmRhMCkpCiAgICAgICAgICAvIChjb3NQaGkwICogY29zUGhp
MSAqIHNpbkxhbWJkYTBMYW1iZGExKSkKICAgICAgOiAocGhpMCArIHBoaTEpIC8gMjsKfQoKZnVu
Y3Rpb24gY2xpcEFudGltZXJpZGlhbkludGVycG9sYXRlKGZyb20sIHRvLCBkaXJlY3Rpb24sIHN0
cmVhbSkgewogIHZhciBwaGk7CiAgaWYgKGZyb20gPT0gbnVsbCkgewogICAgcGhpID0gZGlyZWN0
aW9uICogaGFsZlBpJDI7CiAgICBzdHJlYW0ucG9pbnQoLXBpJDMsIHBoaSk7CiAgICBzdHJlYW0u
cG9pbnQoMCwgcGhpKTsKICAgIHN0cmVhbS5wb2ludChwaSQzLCBwaGkpOwogICAgc3RyZWFtLnBv
aW50KHBpJDMsIDApOwogICAgc3RyZWFtLnBvaW50KHBpJDMsIC1waGkpOwogICAgc3RyZWFtLnBv
aW50KDAsIC1waGkpOwogICAgc3RyZWFtLnBvaW50KC1waSQzLCAtcGhpKTsKICAgIHN0cmVhbS5w
b2ludCgtcGkkMywgMCk7CiAgICBzdHJlYW0ucG9pbnQoLXBpJDMsIHBoaSk7CiAgfSBlbHNlIGlm
IChhYnMoZnJvbVswXSAtIHRvWzBdKSA+IGVwc2lsb24kMikgewogICAgdmFyIGxhbWJkYSA9IGZy
b21bMF0gPCB0b1swXSA/IHBpJDMgOiAtcGkkMzsKICAgIHBoaSA9IGRpcmVjdGlvbiAqIGxhbWJk
YSAvIDI7CiAgICBzdHJlYW0ucG9pbnQoLWxhbWJkYSwgcGhpKTsKICAgIHN0cmVhbS5wb2ludCgw
LCBwaGkpOwogICAgc3RyZWFtLnBvaW50KGxhbWJkYSwgcGhpKTsKICB9IGVsc2UgewogICAgc3Ry
ZWFtLnBvaW50KHRvWzBdLCB0b1sxXSk7CiAgfQp9CgpmdW5jdGlvbiBjbGlwQ2lyY2xlKHJhZGl1
cykgewogIHZhciBjciA9IGNvcyQxKHJhZGl1cyksCiAgICAgIGRlbHRhID0gNiAqIHJhZGlhbnMs
CiAgICAgIHNtYWxsUmFkaXVzID0gY3IgPiAwLAogICAgICBub3RIZW1pc3BoZXJlID0gYWJzKGNy
KSA+IGVwc2lsb24kMjsgLy8gVE9ETyBvcHRpbWlzZSBmb3IgdGhpcyBjb21tb24gY2FzZQoKICBm
dW5jdGlvbiBpbnRlcnBvbGF0ZShmcm9tLCB0bywgZGlyZWN0aW9uLCBzdHJlYW0pIHsKICAgIGNp
cmNsZVN0cmVhbShzdHJlYW0sIHJhZGl1cywgZGVsdGEsIGRpcmVjdGlvbiwgZnJvbSwgdG8pOwog
IH0KCiAgZnVuY3Rpb24gdmlzaWJsZShsYW1iZGEsIHBoaSkgewogICAgcmV0dXJuIGNvcyQxKGxh
bWJkYSkgKiBjb3MkMShwaGkpID4gY3I7CiAgfQoKICAvLyBUYWtlcyBhIGxpbmUgYW5kIGN1dHMg
aW50byB2aXNpYmxlIHNlZ21lbnRzLiBSZXR1cm4gdmFsdWVzIHVzZWQgZm9yIHBvbHlnb24KICAv
LyBjbGlwcGluZzogMCAtIHRoZXJlIHdlcmUgaW50ZXJzZWN0aW9ucyBvciB0aGUgbGluZSB3YXMg
ZW1wdHk7IDEgLSBubwogIC8vIGludGVyc2VjdGlvbnMgMiAtIHRoZXJlIHdlcmUgaW50ZXJzZWN0
aW9ucywgYW5kIHRoZSBmaXJzdCBhbmQgbGFzdCBzZWdtZW50cwogIC8vIHNob3VsZCBiZSByZWpv
aW5lZC4KICBmdW5jdGlvbiBjbGlwTGluZShzdHJlYW0pIHsKICAgIHZhciBwb2ludDAsIC8vIHBy
ZXZpb3VzIHBvaW50CiAgICAgICAgYzAsIC8vIGNvZGUgZm9yIHByZXZpb3VzIHBvaW50CiAgICAg
ICAgdjAsIC8vIHZpc2liaWxpdHkgb2YgcHJldmlvdXMgcG9pbnQKICAgICAgICB2MDAsIC8vIHZp
c2liaWxpdHkgb2YgZmlyc3QgcG9pbnQKICAgICAgICBjbGVhbjsgLy8gbm8gaW50ZXJzZWN0aW9u
cwogICAgcmV0dXJuIHsKICAgICAgbGluZVN0YXJ0OiBmdW5jdGlvbigpIHsKICAgICAgICB2MDAg
PSB2MCA9IGZhbHNlOwogICAgICAgIGNsZWFuID0gMTsKICAgICAgfSwKICAgICAgcG9pbnQ6IGZ1
bmN0aW9uKGxhbWJkYSwgcGhpKSB7CiAgICAgICAgdmFyIHBvaW50MSA9IFtsYW1iZGEsIHBoaV0s
CiAgICAgICAgICAgIHBvaW50MiwKICAgICAgICAgICAgdiA9IHZpc2libGUobGFtYmRhLCBwaGkp
LAogICAgICAgICAgICBjID0gc21hbGxSYWRpdXMKICAgICAgICAgICAgICA/IHYgPyAwIDogY29k
ZShsYW1iZGEsIHBoaSkKICAgICAgICAgICAgICA6IHYgPyBjb2RlKGxhbWJkYSArIChsYW1iZGEg
PCAwID8gcGkkMyA6IC1waSQzKSwgcGhpKSA6IDA7CiAgICAgICAgaWYgKCFwb2ludDAgJiYgKHYw
MCA9IHYwID0gdikpIHN0cmVhbS5saW5lU3RhcnQoKTsKICAgICAgICAvLyBIYW5kbGUgZGVnZW5l
cmFjaWVzLgogICAgICAgIC8vIFRPRE8gaWdub3JlIGlmIG5vdCBjbGlwcGluZyBwb2x5Z29ucy4K
ICAgICAgICBpZiAodiAhPT0gdjApIHsKICAgICAgICAgIHBvaW50MiA9IGludGVyc2VjdChwb2lu
dDAsIHBvaW50MSk7CiAgICAgICAgICBpZiAoIXBvaW50MiB8fCBwb2ludEVxdWFsKHBvaW50MCwg
cG9pbnQyKSB8fCBwb2ludEVxdWFsKHBvaW50MSwgcG9pbnQyKSkgewogICAgICAgICAgICBwb2lu
dDFbMF0gKz0gZXBzaWxvbiQyOwogICAgICAgICAgICBwb2ludDFbMV0gKz0gZXBzaWxvbiQyOwog
ICAgICAgICAgICB2ID0gdmlzaWJsZShwb2ludDFbMF0sIHBvaW50MVsxXSk7CiAgICAgICAgICB9
CiAgICAgICAgfQogICAgICAgIGlmICh2ICE9PSB2MCkgewogICAgICAgICAgY2xlYW4gPSAwOwog
ICAgICAgICAgaWYgKHYpIHsKICAgICAgICAgICAgLy8gb3V0c2lkZSBnb2luZyBpbgogICAgICAg
ICAgICBzdHJlYW0ubGluZVN0YXJ0KCk7CiAgICAgICAgICAgIHBvaW50MiA9IGludGVyc2VjdChw
b2ludDEsIHBvaW50MCk7CiAgICAgICAgICAgIHN0cmVhbS5wb2ludChwb2ludDJbMF0sIHBvaW50
MlsxXSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBpbnNpZGUgZ29pbmcgb3V0
CiAgICAgICAgICAgIHBvaW50MiA9IGludGVyc2VjdChwb2ludDAsIHBvaW50MSk7CiAgICAgICAg
ICAgIHN0cmVhbS5wb2ludChwb2ludDJbMF0sIHBvaW50MlsxXSk7CiAgICAgICAgICAgIHN0cmVh
bS5saW5lRW5kKCk7CiAgICAgICAgICB9CiAgICAgICAgICBwb2ludDAgPSBwb2ludDI7CiAgICAg
ICAgfSBlbHNlIGlmIChub3RIZW1pc3BoZXJlICYmIHBvaW50MCAmJiBzbWFsbFJhZGl1cyBeIHYp
IHsKICAgICAgICAgIHZhciB0OwogICAgICAgICAgLy8gSWYgdGhlIGNvZGVzIGZvciB0d28gcG9p
bnRzIGFyZSBkaWZmZXJlbnQsIG9yIGFyZSBib3RoIHplcm8sCiAgICAgICAgICAvLyBhbmQgdGhl
cmUgdGhpcyBzZWdtZW50IGludGVyc2VjdHMgd2l0aCB0aGUgc21hbGwgY2lyY2xlLgogICAgICAg
ICAgaWYgKCEoYyAmIGMwKSAmJiAodCA9IGludGVyc2VjdChwb2ludDEsIHBvaW50MCwgdHJ1ZSkp
KSB7CiAgICAgICAgICAgIGNsZWFuID0gMDsKICAgICAgICAgICAgaWYgKHNtYWxsUmFkaXVzKSB7
CiAgICAgICAgICAgICAgc3RyZWFtLmxpbmVTdGFydCgpOwogICAgICAgICAgICAgIHN0cmVhbS5w
b2ludCh0WzBdWzBdLCB0WzBdWzFdKTsKICAgICAgICAgICAgICBzdHJlYW0ucG9pbnQodFsxXVsw
XSwgdFsxXVsxXSk7CiAgICAgICAgICAgICAgc3RyZWFtLmxpbmVFbmQoKTsKICAgICAgICAgICAg
fSBlbHNlIHsKICAgICAgICAgICAgICBzdHJlYW0ucG9pbnQodFsxXVswXSwgdFsxXVsxXSk7CiAg
ICAgICAgICAgICAgc3RyZWFtLmxpbmVFbmQoKTsKICAgICAgICAgICAgICBzdHJlYW0ubGluZVN0
YXJ0KCk7CiAgICAgICAgICAgICAgc3RyZWFtLnBvaW50KHRbMF1bMF0sIHRbMF1bMV0pOwogICAg
ICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmICh2ICYmICghcG9pbnQw
IHx8ICFwb2ludEVxdWFsKHBvaW50MCwgcG9pbnQxKSkpIHsKICAgICAgICAgIHN0cmVhbS5wb2lu
dChwb2ludDFbMF0sIHBvaW50MVsxXSk7CiAgICAgICAgfQogICAgICAgIHBvaW50MCA9IHBvaW50
MSwgdjAgPSB2LCBjMCA9IGM7CiAgICAgIH0sCiAgICAgIGxpbmVFbmQ6IGZ1bmN0aW9uKCkgewog
ICAgICAgIGlmICh2MCkgc3RyZWFtLmxpbmVFbmQoKTsKICAgICAgICBwb2ludDAgPSBudWxsOwog
ICAgICB9LAogICAgICAvLyBSZWpvaW4gZmlyc3QgYW5kIGxhc3Qgc2VnbWVudHMgaWYgdGhlcmUg
d2VyZSBpbnRlcnNlY3Rpb25zIGFuZCB0aGUgZmlyc3QKICAgICAgLy8gYW5kIGxhc3QgcG9pbnRz
IHdlcmUgdmlzaWJsZS4KICAgICAgY2xlYW46IGZ1bmN0aW9uKCkgewogICAgICAgIHJldHVybiBj
bGVhbiB8ICgodjAwICYmIHYwKSA8PCAxKTsKICAgICAgfQogICAgfTsKICB9CgogIC8vIEludGVy
c2VjdHMgdGhlIGdyZWF0IGNpcmNsZSBiZXR3ZWVuIGEgYW5kIGIgd2l0aCB0aGUgY2xpcCBjaXJj
bGUuCiAgZnVuY3Rpb24gaW50ZXJzZWN0KGEsIGIsIHR3bykgewogICAgdmFyIHBhID0gY2FydGVz
aWFuKGEpLAogICAgICAgIHBiID0gY2FydGVzaWFuKGIpOwoKICAgIC8vIFdlIGhhdmUgdHdvIHBs
YW5lcywgbjEucCA9IGQxIGFuZCBuMi5wID0gZDIuCiAgICAvLyBGaW5kIGludGVyc2VjdGlvbiBs
aW5lIHAodCkgPSBjMSBuMSArIGMyIG4yICsgdCAobjEg4qivIG4yKS4KICAgIHZhciBuMSA9IFsx
LCAwLCAwXSwgLy8gbm9ybWFsCiAgICAgICAgbjIgPSBjYXJ0ZXNpYW5Dcm9zcyhwYSwgcGIpLAog
ICAgICAgIG4ybjIgPSBjYXJ0ZXNpYW5Eb3QobjIsIG4yKSwKICAgICAgICBuMW4yID0gbjJbMF0s
IC8vIGNhcnRlc2lhbkRvdChuMSwgbjIpLAogICAgICAgIGRldGVybWluYW50ID0gbjJuMiAtIG4x
bjIgKiBuMW4yOwoKICAgIC8vIFR3byBwb2xhciBwb2ludHMuCiAgICBpZiAoIWRldGVybWluYW50
KSByZXR1cm4gIXR3byAmJiBhOwoKICAgIHZhciBjMSA9ICBjciAqIG4ybjIgLyBkZXRlcm1pbmFu
dCwKICAgICAgICBjMiA9IC1jciAqIG4xbjIgLyBkZXRlcm1pbmFudCwKICAgICAgICBuMXhuMiA9
IGNhcnRlc2lhbkNyb3NzKG4xLCBuMiksCiAgICAgICAgQSA9IGNhcnRlc2lhblNjYWxlKG4xLCBj
MSksCiAgICAgICAgQiA9IGNhcnRlc2lhblNjYWxlKG4yLCBjMik7CiAgICBjYXJ0ZXNpYW5BZGRJ
blBsYWNlKEEsIEIpOwoKICAgIC8vIFNvbHZlIHxwKHQpfF4yID0gMS4KICAgIHZhciB1ID0gbjF4
bjIsCiAgICAgICAgdyA9IGNhcnRlc2lhbkRvdChBLCB1KSwKICAgICAgICB1dSA9IGNhcnRlc2lh
bkRvdCh1LCB1KSwKICAgICAgICB0MiA9IHcgKiB3IC0gdXUgKiAoY2FydGVzaWFuRG90KEEsIEEp
IC0gMSk7CgogICAgaWYgKHQyIDwgMCkgcmV0dXJuOwoKICAgIHZhciB0ID0gc3FydCh0MiksCiAg
ICAgICAgcSA9IGNhcnRlc2lhblNjYWxlKHUsICgtdyAtIHQpIC8gdXUpOwogICAgY2FydGVzaWFu
QWRkSW5QbGFjZShxLCBBKTsKICAgIHEgPSBzcGhlcmljYWwocSk7CgogICAgaWYgKCF0d28pIHJl
dHVybiBxOwoKICAgIC8vIFR3byBpbnRlcnNlY3Rpb24gcG9pbnRzLgogICAgdmFyIGxhbWJkYTAg
PSBhWzBdLAogICAgICAgIGxhbWJkYTEgPSBiWzBdLAogICAgICAgIHBoaTAgPSBhWzFdLAogICAg
ICAgIHBoaTEgPSBiWzFdLAogICAgICAgIHo7CgogICAgaWYgKGxhbWJkYTEgPCBsYW1iZGEwKSB6
ID0gbGFtYmRhMCwgbGFtYmRhMCA9IGxhbWJkYTEsIGxhbWJkYTEgPSB6OwoKICAgIHZhciBkZWx0
YSA9IGxhbWJkYTEgLSBsYW1iZGEwLAogICAgICAgIHBvbGFyID0gYWJzKGRlbHRhIC0gcGkkMykg
PCBlcHNpbG9uJDIsCiAgICAgICAgbWVyaWRpYW4gPSBwb2xhciB8fCBkZWx0YSA8IGVwc2lsb24k
MjsKCiAgICBpZiAoIXBvbGFyICYmIHBoaTEgPCBwaGkwKSB6ID0gcGhpMCwgcGhpMCA9IHBoaTEs
IHBoaTEgPSB6OwoKICAgIC8vIENoZWNrIHRoYXQgdGhlIGZpcnN0IHBvaW50IGlzIGJldHdlZW4g
YSBhbmQgYi4KICAgIGlmIChtZXJpZGlhbgogICAgICAgID8gcG9sYXIKICAgICAgICAgID8gcGhp
MCArIHBoaTEgPiAwIF4gcVsxXSA8IChhYnMocVswXSAtIGxhbWJkYTApIDwgZXBzaWxvbiQyID8g
cGhpMCA6IHBoaTEpCiAgICAgICAgICA6IHBoaTAgPD0gcVsxXSAmJiBxWzFdIDw9IHBoaTEKICAg
ICAgICA6IGRlbHRhID4gcGkkMyBeIChsYW1iZGEwIDw9IHFbMF0gJiYgcVswXSA8PSBsYW1iZGEx
KSkgewogICAgICB2YXIgcTEgPSBjYXJ0ZXNpYW5TY2FsZSh1LCAoLXcgKyB0KSAvIHV1KTsKICAg
ICAgY2FydGVzaWFuQWRkSW5QbGFjZShxMSwgQSk7CiAgICAgIHJldHVybiBbcSwgc3BoZXJpY2Fs
KHExKV07CiAgICB9CiAgfQoKICAvLyBHZW5lcmF0ZXMgYSA0LWJpdCB2ZWN0b3IgcmVwcmVzZW50
aW5nIHRoZSBsb2NhdGlvbiBvZiBhIHBvaW50IHJlbGF0aXZlIHRvCiAgLy8gdGhlIHNtYWxsIGNp
cmNsZSdzIGJvdW5kaW5nIGJveC4KICBmdW5jdGlvbiBjb2RlKGxhbWJkYSwgcGhpKSB7CiAgICB2
YXIgciA9IHNtYWxsUmFkaXVzID8gcmFkaXVzIDogcGkkMyAtIHJhZGl1cywKICAgICAgICBjb2Rl
ID0gMDsKICAgIGlmIChsYW1iZGEgPCAtcikgY29kZSB8PSAxOyAvLyBsZWZ0CiAgICBlbHNlIGlm
IChsYW1iZGEgPiByKSBjb2RlIHw9IDI7IC8vIHJpZ2h0CiAgICBpZiAocGhpIDwgLXIpIGNvZGUg
fD0gNDsgLy8gYmVsb3cKICAgIGVsc2UgaWYgKHBoaSA+IHIpIGNvZGUgfD0gODsgLy8gYWJvdmUK
ICAgIHJldHVybiBjb2RlOwogIH0KCiAgcmV0dXJuIGNsaXAodmlzaWJsZSwgY2xpcExpbmUsIGlu
dGVycG9sYXRlLCBzbWFsbFJhZGl1cyA/IFswLCAtcmFkaXVzXSA6IFstcGkkMywgcmFkaXVzIC0g
cGkkM10pOwp9CgpmdW5jdGlvbiBjbGlwTGluZShhLCBiLCB4MCwgeTAsIHgxLCB5MSkgewogIHZh
ciBheCA9IGFbMF0sCiAgICAgIGF5ID0gYVsxXSwKICAgICAgYnggPSBiWzBdLAogICAgICBieSA9
IGJbMV0sCiAgICAgIHQwID0gMCwKICAgICAgdDEgPSAxLAogICAgICBkeCA9IGJ4IC0gYXgsCiAg
ICAgIGR5ID0gYnkgLSBheSwKICAgICAgcjsKCiAgciA9IHgwIC0gYXg7CiAgaWYgKCFkeCAmJiBy
ID4gMCkgcmV0dXJuOwogIHIgLz0gZHg7CiAgaWYgKGR4IDwgMCkgewogICAgaWYgKHIgPCB0MCkg
cmV0dXJuOwogICAgaWYgKHIgPCB0MSkgdDEgPSByOwogIH0gZWxzZSBpZiAoZHggPiAwKSB7CiAg
ICBpZiAociA+IHQxKSByZXR1cm47CiAgICBpZiAociA+IHQwKSB0MCA9IHI7CiAgfQoKICByID0g
eDEgLSBheDsKICBpZiAoIWR4ICYmIHIgPCAwKSByZXR1cm47CiAgciAvPSBkeDsKICBpZiAoZHgg
PCAwKSB7CiAgICBpZiAociA+IHQxKSByZXR1cm47CiAgICBpZiAociA+IHQwKSB0MCA9IHI7CiAg
fSBlbHNlIGlmIChkeCA+IDApIHsKICAgIGlmIChyIDwgdDApIHJldHVybjsKICAgIGlmIChyIDwg
dDEpIHQxID0gcjsKICB9CgogIHIgPSB5MCAtIGF5OwogIGlmICghZHkgJiYgciA+IDApIHJldHVy
bjsKICByIC89IGR5OwogIGlmIChkeSA8IDApIHsKICAgIGlmIChyIDwgdDApIHJldHVybjsKICAg
IGlmIChyIDwgdDEpIHQxID0gcjsKICB9IGVsc2UgaWYgKGR5ID4gMCkgewogICAgaWYgKHIgPiB0
MSkgcmV0dXJuOwogICAgaWYgKHIgPiB0MCkgdDAgPSByOwogIH0KCiAgciA9IHkxIC0gYXk7CiAg
aWYgKCFkeSAmJiByIDwgMCkgcmV0dXJuOwogIHIgLz0gZHk7CiAgaWYgKGR5IDwgMCkgewogICAg
aWYgKHIgPiB0MSkgcmV0dXJuOwogICAgaWYgKHIgPiB0MCkgdDAgPSByOwogIH0gZWxzZSBpZiAo
ZHkgPiAwKSB7CiAgICBpZiAociA8IHQwKSByZXR1cm47CiAgICBpZiAociA8IHQxKSB0MSA9IHI7
CiAgfQoKICBpZiAodDAgPiAwKSBhWzBdID0gYXggKyB0MCAqIGR4LCBhWzFdID0gYXkgKyB0MCAq
IGR5OwogIGlmICh0MSA8IDEpIGJbMF0gPSBheCArIHQxICogZHgsIGJbMV0gPSBheSArIHQxICog
ZHk7CiAgcmV0dXJuIHRydWU7Cn0KCnZhciBjbGlwTWF4ID0gMWU5LCBjbGlwTWluID0gLWNsaXBN
YXg7CgovLyBUT0RPIFVzZSBkMy1wb2x5Z29u4oCZcyBwb2x5Z29uQ29udGFpbnMgaGVyZSBmb3Ig
dGhlIHJpbmcgY2hlY2s/Ci8vIFRPRE8gRWxpbWluYXRlIGR1cGxpY2F0ZSBidWZmZXJpbmcgaW4g
Y2xpcEJ1ZmZlciBhbmQgcG9seWdvbi5wdXNoPwoKZnVuY3Rpb24gY2xpcFJlY3RhbmdsZSh4MCwg
eTAsIHgxLCB5MSkgewoKICBmdW5jdGlvbiB2aXNpYmxlKHgsIHkpIHsKICAgIHJldHVybiB4MCA8
PSB4ICYmIHggPD0geDEgJiYgeTAgPD0geSAmJiB5IDw9IHkxOwogIH0KCiAgZnVuY3Rpb24gaW50
ZXJwb2xhdGUoZnJvbSwgdG8sIGRpcmVjdGlvbiwgc3RyZWFtKSB7CiAgICB2YXIgYSA9IDAsIGEx
ID0gMDsKICAgIGlmIChmcm9tID09IG51bGwKICAgICAgICB8fCAoYSA9IGNvcm5lcihmcm9tLCBk
aXJlY3Rpb24pKSAhPT0gKGExID0gY29ybmVyKHRvLCBkaXJlY3Rpb24pKQogICAgICAgIHx8IGNv
bXBhcmVQb2ludChmcm9tLCB0bykgPCAwIF4gZGlyZWN0aW9uID4gMCkgewogICAgICBkbyBzdHJl
YW0ucG9pbnQoYSA9PT0gMCB8fCBhID09PSAzID8geDAgOiB4MSwgYSA+IDEgPyB5MSA6IHkwKTsK
ICAgICAgd2hpbGUgKChhID0gKGEgKyBkaXJlY3Rpb24gKyA0KSAlIDQpICE9PSBhMSk7CiAgICB9
IGVsc2UgewogICAgICBzdHJlYW0ucG9pbnQodG9bMF0sIHRvWzFdKTsKICAgIH0KICB9CgogIGZ1
bmN0aW9uIGNvcm5lcihwLCBkaXJlY3Rpb24pIHsKICAgIHJldHVybiBhYnMocFswXSAtIHgwKSA8
IGVwc2lsb24kMiA/IGRpcmVjdGlvbiA+IDAgPyAwIDogMwogICAgICAgIDogYWJzKHBbMF0gLSB4
MSkgPCBlcHNpbG9uJDIgPyBkaXJlY3Rpb24gPiAwID8gMiA6IDEKICAgICAgICA6IGFicyhwWzFd
IC0geTApIDwgZXBzaWxvbiQyID8gZGlyZWN0aW9uID4gMCA/IDEgOiAwCiAgICAgICAgOiBkaXJl
Y3Rpb24gPiAwID8gMyA6IDI7IC8vIGFicyhwWzFdIC0geTEpIDwgZXBzaWxvbgogIH0KCiAgZnVu
Y3Rpb24gY29tcGFyZUludGVyc2VjdGlvbihhLCBiKSB7CiAgICByZXR1cm4gY29tcGFyZVBvaW50
KGEueCwgYi54KTsKICB9CgogIGZ1bmN0aW9uIGNvbXBhcmVQb2ludChhLCBiKSB7CiAgICB2YXIg
Y2EgPSBjb3JuZXIoYSwgMSksCiAgICAgICAgY2IgPSBjb3JuZXIoYiwgMSk7CiAgICByZXR1cm4g
Y2EgIT09IGNiID8gY2EgLSBjYgogICAgICAgIDogY2EgPT09IDAgPyBiWzFdIC0gYVsxXQogICAg
ICAgIDogY2EgPT09IDEgPyBhWzBdIC0gYlswXQogICAgICAgIDogY2EgPT09IDIgPyBhWzFdIC0g
YlsxXQogICAgICAgIDogYlswXSAtIGFbMF07CiAgfQoKICByZXR1cm4gZnVuY3Rpb24oc3RyZWFt
KSB7CiAgICB2YXIgYWN0aXZlU3RyZWFtID0gc3RyZWFtLAogICAgICAgIGJ1ZmZlclN0cmVhbSA9
IGNsaXBCdWZmZXIoKSwKICAgICAgICBzZWdtZW50cywKICAgICAgICBwb2x5Z29uLAogICAgICAg
IHJpbmcsCiAgICAgICAgeF9fLCB5X18sIHZfXywgLy8gZmlyc3QgcG9pbnQKICAgICAgICB4Xywg
eV8sIHZfLCAvLyBwcmV2aW91cyBwb2ludAogICAgICAgIGZpcnN0LAogICAgICAgIGNsZWFuOwoK
ICAgIHZhciBjbGlwU3RyZWFtID0gewogICAgICBwb2ludDogcG9pbnQsCiAgICAgIGxpbmVTdGFy
dDogbGluZVN0YXJ0LAogICAgICBsaW5lRW5kOiBsaW5lRW5kLAogICAgICBwb2x5Z29uU3RhcnQ6
IHBvbHlnb25TdGFydCwKICAgICAgcG9seWdvbkVuZDogcG9seWdvbkVuZAogICAgfTsKCiAgICBm
dW5jdGlvbiBwb2ludCh4LCB5KSB7CiAgICAgIGlmICh2aXNpYmxlKHgsIHkpKSBhY3RpdmVTdHJl
YW0ucG9pbnQoeCwgeSk7CiAgICB9CgogICAgZnVuY3Rpb24gcG9seWdvbkluc2lkZSgpIHsKICAg
ICAgdmFyIHdpbmRpbmcgPSAwOwoKICAgICAgZm9yICh2YXIgaSA9IDAsIG4gPSBwb2x5Z29uLmxl
bmd0aDsgaSA8IG47ICsraSkgewogICAgICAgIGZvciAodmFyIHJpbmcgPSBwb2x5Z29uW2ldLCBq
ID0gMSwgbSA9IHJpbmcubGVuZ3RoLCBwb2ludCA9IHJpbmdbMF0sIGEwLCBhMSwgYjAgPSBwb2lu
dFswXSwgYjEgPSBwb2ludFsxXTsgaiA8IG07ICsraikgewogICAgICAgICAgYTAgPSBiMCwgYTEg
PSBiMSwgcG9pbnQgPSByaW5nW2pdLCBiMCA9IHBvaW50WzBdLCBiMSA9IHBvaW50WzFdOwogICAg
ICAgICAgaWYgKGExIDw9IHkxKSB7IGlmIChiMSA+IHkxICYmIChiMCAtIGEwKSAqICh5MSAtIGEx
KSA+IChiMSAtIGExKSAqICh4MCAtIGEwKSkgKyt3aW5kaW5nOyB9CiAgICAgICAgICBlbHNlIHsg
aWYgKGIxIDw9IHkxICYmIChiMCAtIGEwKSAqICh5MSAtIGExKSA8IChiMSAtIGExKSAqICh4MCAt
IGEwKSkgLS13aW5kaW5nOyB9CiAgICAgICAgfQogICAgICB9CgogICAgICByZXR1cm4gd2luZGlu
ZzsKICAgIH0KCiAgICAvLyBCdWZmZXIgZ2VvbWV0cnkgd2l0aGluIGEgcG9seWdvbiBhbmQgdGhl
biBjbGlwIGl0IGVuIG1hc3NlLgogICAgZnVuY3Rpb24gcG9seWdvblN0YXJ0KCkgewogICAgICBh
Y3RpdmVTdHJlYW0gPSBidWZmZXJTdHJlYW0sIHNlZ21lbnRzID0gW10sIHBvbHlnb24gPSBbXSwg
Y2xlYW4gPSB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIHBvbHlnb25FbmQoKSB7CiAgICAgIHZh
ciBzdGFydEluc2lkZSA9IHBvbHlnb25JbnNpZGUoKSwKICAgICAgICAgIGNsZWFuSW5zaWRlID0g
Y2xlYW4gJiYgc3RhcnRJbnNpZGUsCiAgICAgICAgICB2aXNpYmxlID0gKHNlZ21lbnRzID0gbWVy
Z2Uoc2VnbWVudHMpKS5sZW5ndGg7CiAgICAgIGlmIChjbGVhbkluc2lkZSB8fCB2aXNpYmxlKSB7
CiAgICAgICAgc3RyZWFtLnBvbHlnb25TdGFydCgpOwogICAgICAgIGlmIChjbGVhbkluc2lkZSkg
ewogICAgICAgICAgc3RyZWFtLmxpbmVTdGFydCgpOwogICAgICAgICAgaW50ZXJwb2xhdGUobnVs
bCwgbnVsbCwgMSwgc3RyZWFtKTsKICAgICAgICAgIHN0cmVhbS5saW5lRW5kKCk7CiAgICAgICAg
fQogICAgICAgIGlmICh2aXNpYmxlKSB7CiAgICAgICAgICBjbGlwUmVqb2luKHNlZ21lbnRzLCBj
b21wYXJlSW50ZXJzZWN0aW9uLCBzdGFydEluc2lkZSwgaW50ZXJwb2xhdGUsIHN0cmVhbSk7CiAg
ICAgICAgfQogICAgICAgIHN0cmVhbS5wb2x5Z29uRW5kKCk7CiAgICAgIH0KICAgICAgYWN0aXZl
U3RyZWFtID0gc3RyZWFtLCBzZWdtZW50cyA9IHBvbHlnb24gPSByaW5nID0gbnVsbDsKICAgIH0K
CiAgICBmdW5jdGlvbiBsaW5lU3RhcnQoKSB7CiAgICAgIGNsaXBTdHJlYW0ucG9pbnQgPSBsaW5l
UG9pbnQ7CiAgICAgIGlmIChwb2x5Z29uKSBwb2x5Z29uLnB1c2gocmluZyA9IFtdKTsKICAgICAg
Zmlyc3QgPSB0cnVlOwogICAgICB2XyA9IGZhbHNlOwogICAgICB4XyA9IHlfID0gTmFOOwogICAg
fQoKICAgIC8vIFRPRE8gcmF0aGVyIHRoYW4gc3BlY2lhbC1jYXNlIHBvbHlnb25zLCBzaW1wbHkg
aGFuZGxlIHRoZW0gc2VwYXJhdGVseS4KICAgIC8vIElkZWFsbHksIGNvaW5jaWRlbnQgaW50ZXJz
ZWN0aW9uIHBvaW50cyBzaG91bGQgYmUgaml0dGVyZWQgdG8gYXZvaWQKICAgIC8vIGNsaXBwaW5n
IGlzc3Vlcy4KICAgIGZ1bmN0aW9uIGxpbmVFbmQoKSB7CiAgICAgIGlmIChzZWdtZW50cykgewog
ICAgICAgIGxpbmVQb2ludCh4X18sIHlfXyk7CiAgICAgICAgaWYgKHZfXyAmJiB2XykgYnVmZmVy
U3RyZWFtLnJlam9pbigpOwogICAgICAgIHNlZ21lbnRzLnB1c2goYnVmZmVyU3RyZWFtLnJlc3Vs
dCgpKTsKICAgICAgfQogICAgICBjbGlwU3RyZWFtLnBvaW50ID0gcG9pbnQ7CiAgICAgIGlmICh2
XykgYWN0aXZlU3RyZWFtLmxpbmVFbmQoKTsKICAgIH0KCiAgICBmdW5jdGlvbiBsaW5lUG9pbnQo
eCwgeSkgewogICAgICB2YXIgdiA9IHZpc2libGUoeCwgeSk7CiAgICAgIGlmIChwb2x5Z29uKSBy
aW5nLnB1c2goW3gsIHldKTsKICAgICAgaWYgKGZpcnN0KSB7CiAgICAgICAgeF9fID0geCwgeV9f
ID0geSwgdl9fID0gdjsKICAgICAgICBmaXJzdCA9IGZhbHNlOwogICAgICAgIGlmICh2KSB7CiAg
ICAgICAgICBhY3RpdmVTdHJlYW0ubGluZVN0YXJ0KCk7CiAgICAgICAgICBhY3RpdmVTdHJlYW0u
cG9pbnQoeCwgeSk7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIGlmICh2ICYmIHZf
KSBhY3RpdmVTdHJlYW0ucG9pbnQoeCwgeSk7CiAgICAgICAgZWxzZSB7CiAgICAgICAgICB2YXIg
YSA9IFt4XyA9IE1hdGgubWF4KGNsaXBNaW4sIE1hdGgubWluKGNsaXBNYXgsIHhfKSksIHlfID0g
TWF0aC5tYXgoY2xpcE1pbiwgTWF0aC5taW4oY2xpcE1heCwgeV8pKV0sCiAgICAgICAgICAgICAg
YiA9IFt4ID0gTWF0aC5tYXgoY2xpcE1pbiwgTWF0aC5taW4oY2xpcE1heCwgeCkpLCB5ID0gTWF0
aC5tYXgoY2xpcE1pbiwgTWF0aC5taW4oY2xpcE1heCwgeSkpXTsKICAgICAgICAgIGlmIChjbGlw
TGluZShhLCBiLCB4MCwgeTAsIHgxLCB5MSkpIHsKICAgICAgICAgICAgaWYgKCF2XykgewogICAg
ICAgICAgICAgIGFjdGl2ZVN0cmVhbS5saW5lU3RhcnQoKTsKICAgICAgICAgICAgICBhY3RpdmVT
dHJlYW0ucG9pbnQoYVswXSwgYVsxXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYWN0aXZl
U3RyZWFtLnBvaW50KGJbMF0sIGJbMV0pOwogICAgICAgICAgICBpZiAoIXYpIGFjdGl2ZVN0cmVh
bS5saW5lRW5kKCk7CiAgICAgICAgICAgIGNsZWFuID0gZmFsc2U7CiAgICAgICAgICB9IGVsc2Ug
aWYgKHYpIHsKICAgICAgICAgICAgYWN0aXZlU3RyZWFtLmxpbmVTdGFydCgpOwogICAgICAgICAg
ICBhY3RpdmVTdHJlYW0ucG9pbnQoeCwgeSk7CiAgICAgICAgICAgIGNsZWFuID0gZmFsc2U7CiAg
ICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICAgIHhfID0geCwgeV8gPSB5LCB2XyA9IHY7
CiAgICB9CgogICAgcmV0dXJuIGNsaXBTdHJlYW07CiAgfTsKfQoKZnVuY3Rpb24gZXh0ZW50JDEo
KSB7CiAgdmFyIHgwID0gMCwKICAgICAgeTAgPSAwLAogICAgICB4MSA9IDk2MCwKICAgICAgeTEg
PSA1MDAsCiAgICAgIGNhY2hlLAogICAgICBjYWNoZVN0cmVhbSwKICAgICAgY2xpcDsKCiAgcmV0
dXJuIGNsaXAgPSB7CiAgICBzdHJlYW06IGZ1bmN0aW9uKHN0cmVhbSkgewogICAgICByZXR1cm4g
Y2FjaGUgJiYgY2FjaGVTdHJlYW0gPT09IHN0cmVhbSA/IGNhY2hlIDogY2FjaGUgPSBjbGlwUmVj
dGFuZ2xlKHgwLCB5MCwgeDEsIHkxKShjYWNoZVN0cmVhbSA9IHN0cmVhbSk7CiAgICB9LAogICAg
ZXh0ZW50OiBmdW5jdGlvbihfKSB7CiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHgw
ID0gK19bMF1bMF0sIHkwID0gK19bMF1bMV0sIHgxID0gK19bMV1bMF0sIHkxID0gK19bMV1bMV0s
IGNhY2hlID0gY2FjaGVTdHJlYW0gPSBudWxsLCBjbGlwKSA6IFtbeDAsIHkwXSwgW3gxLCB5MV1d
OwogICAgfQogIH07Cn0KCnZhciBsZW5ndGhTdW0gPSBhZGRlcigpLAogICAgbGFtYmRhMCQyLAog
ICAgc2luUGhpMCQxLAogICAgY29zUGhpMCQxOwoKdmFyIGxlbmd0aFN0cmVhbSA9IHsKICBzcGhl
cmU6IG5vb3AkMiwKICBwb2ludDogbm9vcCQyLAogIGxpbmVTdGFydDogbGVuZ3RoTGluZVN0YXJ0
LAogIGxpbmVFbmQ6IG5vb3AkMiwKICBwb2x5Z29uU3RhcnQ6IG5vb3AkMiwKICBwb2x5Z29uRW5k
OiBub29wJDIKfTsKCmZ1bmN0aW9uIGxlbmd0aExpbmVTdGFydCgpIHsKICBsZW5ndGhTdHJlYW0u
cG9pbnQgPSBsZW5ndGhQb2ludEZpcnN0OwogIGxlbmd0aFN0cmVhbS5saW5lRW5kID0gbGVuZ3Ro
TGluZUVuZDsKfQoKZnVuY3Rpb24gbGVuZ3RoTGluZUVuZCgpIHsKICBsZW5ndGhTdHJlYW0ucG9p
bnQgPSBsZW5ndGhTdHJlYW0ubGluZUVuZCA9IG5vb3AkMjsKfQoKZnVuY3Rpb24gbGVuZ3RoUG9p
bnRGaXJzdChsYW1iZGEsIHBoaSkgewogIGxhbWJkYSAqPSByYWRpYW5zLCBwaGkgKj0gcmFkaWFu
czsKICBsYW1iZGEwJDIgPSBsYW1iZGEsIHNpblBoaTAkMSA9IHNpbiQxKHBoaSksIGNvc1BoaTAk
MSA9IGNvcyQxKHBoaSk7CiAgbGVuZ3RoU3RyZWFtLnBvaW50ID0gbGVuZ3RoUG9pbnQ7Cn0KCmZ1
bmN0aW9uIGxlbmd0aFBvaW50KGxhbWJkYSwgcGhpKSB7CiAgbGFtYmRhICo9IHJhZGlhbnMsIHBo
aSAqPSByYWRpYW5zOwogIHZhciBzaW5QaGkgPSBzaW4kMShwaGkpLAogICAgICBjb3NQaGkgPSBj
b3MkMShwaGkpLAogICAgICBkZWx0YSA9IGFicyhsYW1iZGEgLSBsYW1iZGEwJDIpLAogICAgICBj
b3NEZWx0YSA9IGNvcyQxKGRlbHRhKSwKICAgICAgc2luRGVsdGEgPSBzaW4kMShkZWx0YSksCiAg
ICAgIHggPSBjb3NQaGkgKiBzaW5EZWx0YSwKICAgICAgeSA9IGNvc1BoaTAkMSAqIHNpblBoaSAt
IHNpblBoaTAkMSAqIGNvc1BoaSAqIGNvc0RlbHRhLAogICAgICB6ID0gc2luUGhpMCQxICogc2lu
UGhpICsgY29zUGhpMCQxICogY29zUGhpICogY29zRGVsdGE7CiAgbGVuZ3RoU3VtLmFkZChhdGFu
MihzcXJ0KHggKiB4ICsgeSAqIHkpLCB6KSk7CiAgbGFtYmRhMCQyID0gbGFtYmRhLCBzaW5QaGkw
JDEgPSBzaW5QaGksIGNvc1BoaTAkMSA9IGNvc1BoaTsKfQoKZnVuY3Rpb24gbGVuZ3RoJDEob2Jq
ZWN0KSB7CiAgbGVuZ3RoU3VtLnJlc2V0KCk7CiAgZ2VvU3RyZWFtKG9iamVjdCwgbGVuZ3RoU3Ry
ZWFtKTsKICByZXR1cm4gK2xlbmd0aFN1bTsKfQoKdmFyIGNvb3JkaW5hdGVzID0gW251bGwsIG51
bGxdLAogICAgb2JqZWN0JDEgPSB7dHlwZTogIkxpbmVTdHJpbmciLCBjb29yZGluYXRlczogY29v
cmRpbmF0ZXN9OwoKZnVuY3Rpb24gZGlzdGFuY2UoYSwgYikgewogIGNvb3JkaW5hdGVzWzBdID0g
YTsKICBjb29yZGluYXRlc1sxXSA9IGI7CiAgcmV0dXJuIGxlbmd0aCQxKG9iamVjdCQxKTsKfQoK
dmFyIGNvbnRhaW5zT2JqZWN0VHlwZSA9IHsKICBGZWF0dXJlOiBmdW5jdGlvbihvYmplY3QsIHBv
aW50KSB7CiAgICByZXR1cm4gY29udGFpbnNHZW9tZXRyeShvYmplY3QuZ2VvbWV0cnksIHBvaW50
KTsKICB9LAogIEZlYXR1cmVDb2xsZWN0aW9uOiBmdW5jdGlvbihvYmplY3QsIHBvaW50KSB7CiAg
ICB2YXIgZmVhdHVyZXMgPSBvYmplY3QuZmVhdHVyZXMsIGkgPSAtMSwgbiA9IGZlYXR1cmVzLmxl
bmd0aDsKICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoY29udGFpbnNHZW9tZXRyeShmZWF0dXJlc1tp
XS5nZW9tZXRyeSwgcG9pbnQpKSByZXR1cm4gdHJ1ZTsKICAgIHJldHVybiBmYWxzZTsKICB9Cn07
Cgp2YXIgY29udGFpbnNHZW9tZXRyeVR5cGUgPSB7CiAgU3BoZXJlOiBmdW5jdGlvbigpIHsKICAg
IHJldHVybiB0cnVlOwogIH0sCiAgUG9pbnQ6IGZ1bmN0aW9uKG9iamVjdCwgcG9pbnQpIHsKICAg
IHJldHVybiBjb250YWluc1BvaW50KG9iamVjdC5jb29yZGluYXRlcywgcG9pbnQpOwogIH0sCiAg
TXVsdGlQb2ludDogZnVuY3Rpb24ob2JqZWN0LCBwb2ludCkgewogICAgdmFyIGNvb3JkaW5hdGVz
ID0gb2JqZWN0LmNvb3JkaW5hdGVzLCBpID0gLTEsIG4gPSBjb29yZGluYXRlcy5sZW5ndGg7CiAg
ICB3aGlsZSAoKytpIDwgbikgaWYgKGNvbnRhaW5zUG9pbnQoY29vcmRpbmF0ZXNbaV0sIHBvaW50
KSkgcmV0dXJuIHRydWU7CiAgICByZXR1cm4gZmFsc2U7CiAgfSwKICBMaW5lU3RyaW5nOiBmdW5j
dGlvbihvYmplY3QsIHBvaW50KSB7CiAgICByZXR1cm4gY29udGFpbnNMaW5lKG9iamVjdC5jb29y
ZGluYXRlcywgcG9pbnQpOwogIH0sCiAgTXVsdGlMaW5lU3RyaW5nOiBmdW5jdGlvbihvYmplY3Qs
IHBvaW50KSB7CiAgICB2YXIgY29vcmRpbmF0ZXMgPSBvYmplY3QuY29vcmRpbmF0ZXMsIGkgPSAt
MSwgbiA9IGNvb3JkaW5hdGVzLmxlbmd0aDsKICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoY29udGFp
bnNMaW5lKGNvb3JkaW5hdGVzW2ldLCBwb2ludCkpIHJldHVybiB0cnVlOwogICAgcmV0dXJuIGZh
bHNlOwogIH0sCiAgUG9seWdvbjogZnVuY3Rpb24ob2JqZWN0LCBwb2ludCkgewogICAgcmV0dXJu
IGNvbnRhaW5zUG9seWdvbihvYmplY3QuY29vcmRpbmF0ZXMsIHBvaW50KTsKICB9LAogIE11bHRp
UG9seWdvbjogZnVuY3Rpb24ob2JqZWN0LCBwb2ludCkgewogICAgdmFyIGNvb3JkaW5hdGVzID0g
b2JqZWN0LmNvb3JkaW5hdGVzLCBpID0gLTEsIG4gPSBjb29yZGluYXRlcy5sZW5ndGg7CiAgICB3
aGlsZSAoKytpIDwgbikgaWYgKGNvbnRhaW5zUG9seWdvbihjb29yZGluYXRlc1tpXSwgcG9pbnQp
KSByZXR1cm4gdHJ1ZTsKICAgIHJldHVybiBmYWxzZTsKICB9LAogIEdlb21ldHJ5Q29sbGVjdGlv
bjogZnVuY3Rpb24ob2JqZWN0LCBwb2ludCkgewogICAgdmFyIGdlb21ldHJpZXMgPSBvYmplY3Qu
Z2VvbWV0cmllcywgaSA9IC0xLCBuID0gZ2VvbWV0cmllcy5sZW5ndGg7CiAgICB3aGlsZSAoKytp
IDwgbikgaWYgKGNvbnRhaW5zR2VvbWV0cnkoZ2VvbWV0cmllc1tpXSwgcG9pbnQpKSByZXR1cm4g
dHJ1ZTsKICAgIHJldHVybiBmYWxzZTsKICB9Cn07CgpmdW5jdGlvbiBjb250YWluc0dlb21ldHJ5
KGdlb21ldHJ5LCBwb2ludCkgewogIHJldHVybiBnZW9tZXRyeSAmJiBjb250YWluc0dlb21ldHJ5
VHlwZS5oYXNPd25Qcm9wZXJ0eShnZW9tZXRyeS50eXBlKQogICAgICA/IGNvbnRhaW5zR2VvbWV0
cnlUeXBlW2dlb21ldHJ5LnR5cGVdKGdlb21ldHJ5LCBwb2ludCkKICAgICAgOiBmYWxzZTsKfQoK
ZnVuY3Rpb24gY29udGFpbnNQb2ludChjb29yZGluYXRlcywgcG9pbnQpIHsKICByZXR1cm4gZGlz
dGFuY2UoY29vcmRpbmF0ZXMsIHBvaW50KSA9PT0gMDsKfQoKZnVuY3Rpb24gY29udGFpbnNMaW5l
KGNvb3JkaW5hdGVzLCBwb2ludCkgewogIHZhciBhbywgYm8sIGFiOwogIGZvciAodmFyIGkgPSAw
LCBuID0gY29vcmRpbmF0ZXMubGVuZ3RoOyBpIDwgbjsgaSsrKSB7CiAgICBibyA9IGRpc3RhbmNl
KGNvb3JkaW5hdGVzW2ldLCBwb2ludCk7CiAgICBpZiAoYm8gPT09IDApIHJldHVybiB0cnVlOwog
ICAgaWYgKGkgPiAwKSB7CiAgICAgIGFiID0gZGlzdGFuY2UoY29vcmRpbmF0ZXNbaV0sIGNvb3Jk
aW5hdGVzW2kgLSAxXSk7CiAgICAgIGlmICgKICAgICAgICBhYiA+IDAgJiYKICAgICAgICBhbyA8
PSBhYiAmJgogICAgICAgIGJvIDw9IGFiICYmCiAgICAgICAgKGFvICsgYm8gLSBhYikgKiAoMSAt
IE1hdGgucG93KChhbyAtIGJvKSAvIGFiLCAyKSkgPCBlcHNpbG9uMiQxICogYWIKICAgICAgKQog
ICAgICAgIHJldHVybiB0cnVlOwogICAgfQogICAgYW8gPSBibzsKICB9CiAgcmV0dXJuIGZhbHNl
Owp9CgpmdW5jdGlvbiBjb250YWluc1BvbHlnb24oY29vcmRpbmF0ZXMsIHBvaW50KSB7CiAgcmV0
dXJuICEhcG9seWdvbkNvbnRhaW5zKGNvb3JkaW5hdGVzLm1hcChyaW5nUmFkaWFucyksIHBvaW50
UmFkaWFucyhwb2ludCkpOwp9CgpmdW5jdGlvbiByaW5nUmFkaWFucyhyaW5nKSB7CiAgcmV0dXJu
IHJpbmcgPSByaW5nLm1hcChwb2ludFJhZGlhbnMpLCByaW5nLnBvcCgpLCByaW5nOwp9CgpmdW5j
dGlvbiBwb2ludFJhZGlhbnMocG9pbnQpIHsKICByZXR1cm4gW3BvaW50WzBdICogcmFkaWFucywg
cG9pbnRbMV0gKiByYWRpYW5zXTsKfQoKZnVuY3Rpb24gY29udGFpbnMkMShvYmplY3QsIHBvaW50
KSB7CiAgcmV0dXJuIChvYmplY3QgJiYgY29udGFpbnNPYmplY3RUeXBlLmhhc093blByb3BlcnR5
KG9iamVjdC50eXBlKQogICAgICA/IGNvbnRhaW5zT2JqZWN0VHlwZVtvYmplY3QudHlwZV0KICAg
ICAgOiBjb250YWluc0dlb21ldHJ5KShvYmplY3QsIHBvaW50KTsKfQoKZnVuY3Rpb24gZ3JhdGlj
dWxlWCh5MCwgeTEsIGR5KSB7CiAgdmFyIHkgPSBzZXF1ZW5jZSh5MCwgeTEgLSBlcHNpbG9uJDIs
IGR5KS5jb25jYXQoeTEpOwogIHJldHVybiBmdW5jdGlvbih4KSB7IHJldHVybiB5Lm1hcChmdW5j
dGlvbih5KSB7IHJldHVybiBbeCwgeV07IH0pOyB9Owp9CgpmdW5jdGlvbiBncmF0aWN1bGVZKHgw
LCB4MSwgZHgpIHsKICB2YXIgeCA9IHNlcXVlbmNlKHgwLCB4MSAtIGVwc2lsb24kMiwgZHgpLmNv
bmNhdCh4MSk7CiAgcmV0dXJuIGZ1bmN0aW9uKHkpIHsgcmV0dXJuIHgubWFwKGZ1bmN0aW9uKHgp
IHsgcmV0dXJuIFt4LCB5XTsgfSk7IH07Cn0KCmZ1bmN0aW9uIGdyYXRpY3VsZSgpIHsKICB2YXIg
eDEsIHgwLCBYMSwgWDAsCiAgICAgIHkxLCB5MCwgWTEsIFkwLAogICAgICBkeCA9IDEwLCBkeSA9
IGR4LCBEWCA9IDkwLCBEWSA9IDM2MCwKICAgICAgeCwgeSwgWCwgWSwKICAgICAgcHJlY2lzaW9u
ID0gMi41OwoKICBmdW5jdGlvbiBncmF0aWN1bGUoKSB7CiAgICByZXR1cm4ge3R5cGU6ICJNdWx0
aUxpbmVTdHJpbmciLCBjb29yZGluYXRlczogbGluZXMoKX07CiAgfQoKICBmdW5jdGlvbiBsaW5l
cygpIHsKICAgIHJldHVybiBzZXF1ZW5jZShjZWlsKFgwIC8gRFgpICogRFgsIFgxLCBEWCkubWFw
KFgpCiAgICAgICAgLmNvbmNhdChzZXF1ZW5jZShjZWlsKFkwIC8gRFkpICogRFksIFkxLCBEWSku
bWFwKFkpKQogICAgICAgIC5jb25jYXQoc2VxdWVuY2UoY2VpbCh4MCAvIGR4KSAqIGR4LCB4MSwg
ZHgpLmZpbHRlcihmdW5jdGlvbih4KSB7IHJldHVybiBhYnMoeCAlIERYKSA+IGVwc2lsb24kMjsg
fSkubWFwKHgpKQogICAgICAgIC5jb25jYXQoc2VxdWVuY2UoY2VpbCh5MCAvIGR5KSAqIGR5LCB5
MSwgZHkpLmZpbHRlcihmdW5jdGlvbih5KSB7IHJldHVybiBhYnMoeSAlIERZKSA+IGVwc2lsb24k
MjsgfSkubWFwKHkpKTsKICB9CgogIGdyYXRpY3VsZS5saW5lcyA9IGZ1bmN0aW9uKCkgewogICAg
cmV0dXJuIGxpbmVzKCkubWFwKGZ1bmN0aW9uKGNvb3JkaW5hdGVzKSB7IHJldHVybiB7dHlwZTog
IkxpbmVTdHJpbmciLCBjb29yZGluYXRlczogY29vcmRpbmF0ZXN9OyB9KTsKICB9OwoKICBncmF0
aWN1bGUub3V0bGluZSA9IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIHsKICAgICAgdHlwZTogIlBv
bHlnb24iLAogICAgICBjb29yZGluYXRlczogWwogICAgICAgIFgoWDApLmNvbmNhdCgKICAgICAg
ICBZKFkxKS5zbGljZSgxKSwKICAgICAgICBYKFgxKS5yZXZlcnNlKCkuc2xpY2UoMSksCiAgICAg
ICAgWShZMCkucmV2ZXJzZSgpLnNsaWNlKDEpKQogICAgICBdCiAgICB9OwogIH07CgogIGdyYXRp
Y3VsZS5leHRlbnQgPSBmdW5jdGlvbihfKSB7CiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJl
dHVybiBncmF0aWN1bGUuZXh0ZW50TWlub3IoKTsKICAgIHJldHVybiBncmF0aWN1bGUuZXh0ZW50
TWFqb3IoXykuZXh0ZW50TWlub3IoXyk7CiAgfTsKCiAgZ3JhdGljdWxlLmV4dGVudE1ham9yID0g
ZnVuY3Rpb24oXykgewogICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gW1tYMCwgWTBd
LCBbWDEsIFkxXV07CiAgICBYMCA9ICtfWzBdWzBdLCBYMSA9ICtfWzFdWzBdOwogICAgWTAgPSAr
X1swXVsxXSwgWTEgPSArX1sxXVsxXTsKICAgIGlmIChYMCA+IFgxKSBfID0gWDAsIFgwID0gWDEs
IFgxID0gXzsKICAgIGlmIChZMCA+IFkxKSBfID0gWTAsIFkwID0gWTEsIFkxID0gXzsKICAgIHJl
dHVybiBncmF0aWN1bGUucHJlY2lzaW9uKHByZWNpc2lvbik7CiAgfTsKCiAgZ3JhdGljdWxlLmV4
dGVudE1pbm9yID0gZnVuY3Rpb24oXykgewogICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1
cm4gW1t4MCwgeTBdLCBbeDEsIHkxXV07CiAgICB4MCA9ICtfWzBdWzBdLCB4MSA9ICtfWzFdWzBd
OwogICAgeTAgPSArX1swXVsxXSwgeTEgPSArX1sxXVsxXTsKICAgIGlmICh4MCA+IHgxKSBfID0g
eDAsIHgwID0geDEsIHgxID0gXzsKICAgIGlmICh5MCA+IHkxKSBfID0geTAsIHkwID0geTEsIHkx
ID0gXzsKICAgIHJldHVybiBncmF0aWN1bGUucHJlY2lzaW9uKHByZWNpc2lvbik7CiAgfTsKCiAg
Z3JhdGljdWxlLnN0ZXAgPSBmdW5jdGlvbihfKSB7CiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgp
IHJldHVybiBncmF0aWN1bGUuc3RlcE1pbm9yKCk7CiAgICByZXR1cm4gZ3JhdGljdWxlLnN0ZXBN
YWpvcihfKS5zdGVwTWlub3IoXyk7CiAgfTsKCiAgZ3JhdGljdWxlLnN0ZXBNYWpvciA9IGZ1bmN0
aW9uKF8pIHsKICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIFtEWCwgRFldOwogICAg
RFggPSArX1swXSwgRFkgPSArX1sxXTsKICAgIHJldHVybiBncmF0aWN1bGU7CiAgfTsKCiAgZ3Jh
dGljdWxlLnN0ZXBNaW5vciA9IGZ1bmN0aW9uKF8pIHsKICAgIGlmICghYXJndW1lbnRzLmxlbmd0
aCkgcmV0dXJuIFtkeCwgZHldOwogICAgZHggPSArX1swXSwgZHkgPSArX1sxXTsKICAgIHJldHVy
biBncmF0aWN1bGU7CiAgfTsKCiAgZ3JhdGljdWxlLnByZWNpc2lvbiA9IGZ1bmN0aW9uKF8pIHsK
ICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHByZWNpc2lvbjsKICAgIHByZWNpc2lv
biA9ICtfOwogICAgeCA9IGdyYXRpY3VsZVgoeTAsIHkxLCA5MCk7CiAgICB5ID0gZ3JhdGljdWxl
WSh4MCwgeDEsIHByZWNpc2lvbik7CiAgICBYID0gZ3JhdGljdWxlWChZMCwgWTEsIDkwKTsKICAg
IFkgPSBncmF0aWN1bGVZKFgwLCBYMSwgcHJlY2lzaW9uKTsKICAgIHJldHVybiBncmF0aWN1bGU7
CiAgfTsKCiAgcmV0dXJuIGdyYXRpY3VsZQogICAgICAuZXh0ZW50TWFqb3IoW1stMTgwLCAtOTAg
KyBlcHNpbG9uJDJdLCBbMTgwLCA5MCAtIGVwc2lsb24kMl1dKQogICAgICAuZXh0ZW50TWlub3Io
W1stMTgwLCAtODAgLSBlcHNpbG9uJDJdLCBbMTgwLCA4MCArIGVwc2lsb24kMl1dKTsKfQoKZnVu
Y3Rpb24gZ3JhdGljdWxlMTAoKSB7CiAgcmV0dXJuIGdyYXRpY3VsZSgpKCk7Cn0KCmZ1bmN0aW9u
IGludGVycG9sYXRlJDEoYSwgYikgewogIHZhciB4MCA9IGFbMF0gKiByYWRpYW5zLAogICAgICB5
MCA9IGFbMV0gKiByYWRpYW5zLAogICAgICB4MSA9IGJbMF0gKiByYWRpYW5zLAogICAgICB5MSA9
IGJbMV0gKiByYWRpYW5zLAogICAgICBjeTAgPSBjb3MkMSh5MCksCiAgICAgIHN5MCA9IHNpbiQx
KHkwKSwKICAgICAgY3kxID0gY29zJDEoeTEpLAogICAgICBzeTEgPSBzaW4kMSh5MSksCiAgICAg
IGt4MCA9IGN5MCAqIGNvcyQxKHgwKSwKICAgICAga3kwID0gY3kwICogc2luJDEoeDApLAogICAg
ICBreDEgPSBjeTEgKiBjb3MkMSh4MSksCiAgICAgIGt5MSA9IGN5MSAqIHNpbiQxKHgxKSwKICAg
ICAgZCA9IDIgKiBhc2luKHNxcnQoaGF2ZXJzaW4oeTEgLSB5MCkgKyBjeTAgKiBjeTEgKiBoYXZl
cnNpbih4MSAtIHgwKSkpLAogICAgICBrID0gc2luJDEoZCk7CgogIHZhciBpbnRlcnBvbGF0ZSA9
IGQgPyBmdW5jdGlvbih0KSB7CiAgICB2YXIgQiA9IHNpbiQxKHQgKj0gZCkgLyBrLAogICAgICAg
IEEgPSBzaW4kMShkIC0gdCkgLyBrLAogICAgICAgIHggPSBBICoga3gwICsgQiAqIGt4MSwKICAg
ICAgICB5ID0gQSAqIGt5MCArIEIgKiBreTEsCiAgICAgICAgeiA9IEEgKiBzeTAgKyBCICogc3kx
OwogICAgcmV0dXJuIFsKICAgICAgYXRhbjIoeSwgeCkgKiBkZWdyZWVzJDEsCiAgICAgIGF0YW4y
KHosIHNxcnQoeCAqIHggKyB5ICogeSkpICogZGVncmVlcyQxCiAgICBdOwogIH0gOiBmdW5jdGlv
bigpIHsKICAgIHJldHVybiBbeDAgKiBkZWdyZWVzJDEsIHkwICogZGVncmVlcyQxXTsKICB9OwoK
ICBpbnRlcnBvbGF0ZS5kaXN0YW5jZSA9IGQ7CgogIHJldHVybiBpbnRlcnBvbGF0ZTsKfQoKZnVu
Y3Rpb24gaWRlbnRpdHkkNCh4KSB7CiAgcmV0dXJuIHg7Cn0KCnZhciBhcmVhU3VtJDEgPSBhZGRl
cigpLAogICAgYXJlYVJpbmdTdW0kMSA9IGFkZGVyKCksCiAgICB4MDAsCiAgICB5MDAsCiAgICB4
MCQxLAogICAgeTAkMTsKCnZhciBhcmVhU3RyZWFtJDEgPSB7CiAgcG9pbnQ6IG5vb3AkMiwKICBs
aW5lU3RhcnQ6IG5vb3AkMiwKICBsaW5lRW5kOiBub29wJDIsCiAgcG9seWdvblN0YXJ0OiBmdW5j
dGlvbigpIHsKICAgIGFyZWFTdHJlYW0kMS5saW5lU3RhcnQgPSBhcmVhUmluZ1N0YXJ0JDE7CiAg
ICBhcmVhU3RyZWFtJDEubGluZUVuZCA9IGFyZWFSaW5nRW5kJDE7CiAgfSwKICBwb2x5Z29uRW5k
OiBmdW5jdGlvbigpIHsKICAgIGFyZWFTdHJlYW0kMS5saW5lU3RhcnQgPSBhcmVhU3RyZWFtJDEu
bGluZUVuZCA9IGFyZWFTdHJlYW0kMS5wb2ludCA9IG5vb3AkMjsKICAgIGFyZWFTdW0kMS5hZGQo
YWJzKGFyZWFSaW5nU3VtJDEpKTsKICAgIGFyZWFSaW5nU3VtJDEucmVzZXQoKTsKICB9LAogIHJl
c3VsdDogZnVuY3Rpb24oKSB7CiAgICB2YXIgYXJlYSA9IGFyZWFTdW0kMSAvIDI7CiAgICBhcmVh
U3VtJDEucmVzZXQoKTsKICAgIHJldHVybiBhcmVhOwogIH0KfTsKCmZ1bmN0aW9uIGFyZWFSaW5n
U3RhcnQkMSgpIHsKICBhcmVhU3RyZWFtJDEucG9pbnQgPSBhcmVhUG9pbnRGaXJzdCQxOwp9Cgpm
dW5jdGlvbiBhcmVhUG9pbnRGaXJzdCQxKHgsIHkpIHsKICBhcmVhU3RyZWFtJDEucG9pbnQgPSBh
cmVhUG9pbnQkMTsKICB4MDAgPSB4MCQxID0geCwgeTAwID0geTAkMSA9IHk7Cn0KCmZ1bmN0aW9u
IGFyZWFQb2ludCQxKHgsIHkpIHsKICBhcmVhUmluZ1N1bSQxLmFkZCh5MCQxICogeCAtIHgwJDEg
KiB5KTsKICB4MCQxID0geCwgeTAkMSA9IHk7Cn0KCmZ1bmN0aW9uIGFyZWFSaW5nRW5kJDEoKSB7
CiAgYXJlYVBvaW50JDEoeDAwLCB5MDApOwp9Cgp2YXIgeDAkMiA9IEluZmluaXR5LAogICAgeTAk
MiA9IHgwJDIsCiAgICB4MSA9IC14MCQyLAogICAgeTEgPSB4MTsKCnZhciBib3VuZHNTdHJlYW0k
MSA9IHsKICBwb2ludDogYm91bmRzUG9pbnQkMSwKICBsaW5lU3RhcnQ6IG5vb3AkMiwKICBsaW5l
RW5kOiBub29wJDIsCiAgcG9seWdvblN0YXJ0OiBub29wJDIsCiAgcG9seWdvbkVuZDogbm9vcCQy
LAogIHJlc3VsdDogZnVuY3Rpb24oKSB7CiAgICB2YXIgYm91bmRzID0gW1t4MCQyLCB5MCQyXSwg
W3gxLCB5MV1dOwogICAgeDEgPSB5MSA9IC0oeTAkMiA9IHgwJDIgPSBJbmZpbml0eSk7CiAgICBy
ZXR1cm4gYm91bmRzOwogIH0KfTsKCmZ1bmN0aW9uIGJvdW5kc1BvaW50JDEoeCwgeSkgewogIGlm
ICh4IDwgeDAkMikgeDAkMiA9IHg7CiAgaWYgKHggPiB4MSkgeDEgPSB4OwogIGlmICh5IDwgeTAk
MikgeTAkMiA9IHk7CiAgaWYgKHkgPiB5MSkgeTEgPSB5Owp9CgovLyBUT0RPIEVuZm9yY2UgcG9z
aXRpdmUgYXJlYSBmb3IgZXh0ZXJpb3IsIG5lZ2F0aXZlIGFyZWEgZm9yIGludGVyaW9yPwoKdmFy
IFgwJDEgPSAwLAogICAgWTAkMSA9IDAsCiAgICBaMCQxID0gMCwKICAgIFgxJDEgPSAwLAogICAg
WTEkMSA9IDAsCiAgICBaMSQxID0gMCwKICAgIFgyJDEgPSAwLAogICAgWTIkMSA9IDAsCiAgICBa
MiQxID0gMCwKICAgIHgwMCQxLAogICAgeTAwJDEsCiAgICB4MCQzLAogICAgeTAkMzsKCnZhciBj
ZW50cm9pZFN0cmVhbSQxID0gewogIHBvaW50OiBjZW50cm9pZFBvaW50JDEsCiAgbGluZVN0YXJ0
OiBjZW50cm9pZExpbmVTdGFydCQxLAogIGxpbmVFbmQ6IGNlbnRyb2lkTGluZUVuZCQxLAogIHBv
bHlnb25TdGFydDogZnVuY3Rpb24oKSB7CiAgICBjZW50cm9pZFN0cmVhbSQxLmxpbmVTdGFydCA9
IGNlbnRyb2lkUmluZ1N0YXJ0JDE7CiAgICBjZW50cm9pZFN0cmVhbSQxLmxpbmVFbmQgPSBjZW50
cm9pZFJpbmdFbmQkMTsKICB9LAogIHBvbHlnb25FbmQ6IGZ1bmN0aW9uKCkgewogICAgY2VudHJv
aWRTdHJlYW0kMS5wb2ludCA9IGNlbnRyb2lkUG9pbnQkMTsKICAgIGNlbnRyb2lkU3RyZWFtJDEu
bGluZVN0YXJ0ID0gY2VudHJvaWRMaW5lU3RhcnQkMTsKICAgIGNlbnRyb2lkU3RyZWFtJDEubGlu
ZUVuZCA9IGNlbnRyb2lkTGluZUVuZCQxOwogIH0sCiAgcmVzdWx0OiBmdW5jdGlvbigpIHsKICAg
IHZhciBjZW50cm9pZCA9IFoyJDEgPyBbWDIkMSAvIFoyJDEsIFkyJDEgLyBaMiQxXQogICAgICAg
IDogWjEkMSA/IFtYMSQxIC8gWjEkMSwgWTEkMSAvIFoxJDFdCiAgICAgICAgOiBaMCQxID8gW1gw
JDEgLyBaMCQxLCBZMCQxIC8gWjAkMV0KICAgICAgICA6IFtOYU4sIE5hTl07CiAgICBYMCQxID0g
WTAkMSA9IFowJDEgPQogICAgWDEkMSA9IFkxJDEgPSBaMSQxID0KICAgIFgyJDEgPSBZMiQxID0g
WjIkMSA9IDA7CiAgICByZXR1cm4gY2VudHJvaWQ7CiAgfQp9OwoKZnVuY3Rpb24gY2VudHJvaWRQ
b2ludCQxKHgsIHkpIHsKICBYMCQxICs9IHg7CiAgWTAkMSArPSB5OwogICsrWjAkMTsKfQoKZnVu
Y3Rpb24gY2VudHJvaWRMaW5lU3RhcnQkMSgpIHsKICBjZW50cm9pZFN0cmVhbSQxLnBvaW50ID0g
Y2VudHJvaWRQb2ludEZpcnN0TGluZTsKfQoKZnVuY3Rpb24gY2VudHJvaWRQb2ludEZpcnN0TGlu
ZSh4LCB5KSB7CiAgY2VudHJvaWRTdHJlYW0kMS5wb2ludCA9IGNlbnRyb2lkUG9pbnRMaW5lOwog
IGNlbnRyb2lkUG9pbnQkMSh4MCQzID0geCwgeTAkMyA9IHkpOwp9CgpmdW5jdGlvbiBjZW50cm9p
ZFBvaW50TGluZSh4LCB5KSB7CiAgdmFyIGR4ID0geCAtIHgwJDMsIGR5ID0geSAtIHkwJDMsIHog
PSBzcXJ0KGR4ICogZHggKyBkeSAqIGR5KTsKICBYMSQxICs9IHogKiAoeDAkMyArIHgpIC8gMjsK
ICBZMSQxICs9IHogKiAoeTAkMyArIHkpIC8gMjsKICBaMSQxICs9IHo7CiAgY2VudHJvaWRQb2lu
dCQxKHgwJDMgPSB4LCB5MCQzID0geSk7Cn0KCmZ1bmN0aW9uIGNlbnRyb2lkTGluZUVuZCQxKCkg
ewogIGNlbnRyb2lkU3RyZWFtJDEucG9pbnQgPSBjZW50cm9pZFBvaW50JDE7Cn0KCmZ1bmN0aW9u
IGNlbnRyb2lkUmluZ1N0YXJ0JDEoKSB7CiAgY2VudHJvaWRTdHJlYW0kMS5wb2ludCA9IGNlbnRy
b2lkUG9pbnRGaXJzdFJpbmc7Cn0KCmZ1bmN0aW9uIGNlbnRyb2lkUmluZ0VuZCQxKCkgewogIGNl
bnRyb2lkUG9pbnRSaW5nKHgwMCQxLCB5MDAkMSk7Cn0KCmZ1bmN0aW9uIGNlbnRyb2lkUG9pbnRG
aXJzdFJpbmcoeCwgeSkgewogIGNlbnRyb2lkU3RyZWFtJDEucG9pbnQgPSBjZW50cm9pZFBvaW50
UmluZzsKICBjZW50cm9pZFBvaW50JDEoeDAwJDEgPSB4MCQzID0geCwgeTAwJDEgPSB5MCQzID0g
eSk7Cn0KCmZ1bmN0aW9uIGNlbnRyb2lkUG9pbnRSaW5nKHgsIHkpIHsKICB2YXIgZHggPSB4IC0g
eDAkMywKICAgICAgZHkgPSB5IC0geTAkMywKICAgICAgeiA9IHNxcnQoZHggKiBkeCArIGR5ICog
ZHkpOwoKICBYMSQxICs9IHogKiAoeDAkMyArIHgpIC8gMjsKICBZMSQxICs9IHogKiAoeTAkMyAr
IHkpIC8gMjsKICBaMSQxICs9IHo7CgogIHogPSB5MCQzICogeCAtIHgwJDMgKiB5OwogIFgyJDEg
Kz0geiAqICh4MCQzICsgeCk7CiAgWTIkMSArPSB6ICogKHkwJDMgKyB5KTsKICBaMiQxICs9IHog
KiAzOwogIGNlbnRyb2lkUG9pbnQkMSh4MCQzID0geCwgeTAkMyA9IHkpOwp9CgpmdW5jdGlvbiBQ
YXRoQ29udGV4dChjb250ZXh0KSB7CiAgdGhpcy5fY29udGV4dCA9IGNvbnRleHQ7Cn0KClBhdGhD
b250ZXh0LnByb3RvdHlwZSA9IHsKICBfcmFkaXVzOiA0LjUsCiAgcG9pbnRSYWRpdXM6IGZ1bmN0
aW9uKF8pIHsKICAgIHJldHVybiB0aGlzLl9yYWRpdXMgPSBfLCB0aGlzOwogIH0sCiAgcG9seWdv
blN0YXJ0OiBmdW5jdGlvbigpIHsKICAgIHRoaXMuX2xpbmUgPSAwOwogIH0sCiAgcG9seWdvbkVu
ZDogZnVuY3Rpb24oKSB7CiAgICB0aGlzLl9saW5lID0gTmFOOwogIH0sCiAgbGluZVN0YXJ0OiBm
dW5jdGlvbigpIHsKICAgIHRoaXMuX3BvaW50ID0gMDsKICB9LAogIGxpbmVFbmQ6IGZ1bmN0aW9u
KCkgewogICAgaWYgKHRoaXMuX2xpbmUgPT09IDApIHRoaXMuX2NvbnRleHQuY2xvc2VQYXRoKCk7
CiAgICB0aGlzLl9wb2ludCA9IE5hTjsKICB9LAogIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7CiAg
ICBzd2l0Y2ggKHRoaXMuX3BvaW50KSB7CiAgICAgIGNhc2UgMDogewogICAgICAgIHRoaXMuX2Nv
bnRleHQubW92ZVRvKHgsIHkpOwogICAgICAgIHRoaXMuX3BvaW50ID0gMTsKICAgICAgICBicmVh
azsKICAgICAgfQogICAgICBjYXNlIDE6IHsKICAgICAgICB0aGlzLl9jb250ZXh0LmxpbmVUbyh4
LCB5KTsKICAgICAgICBicmVhazsKICAgICAgfQogICAgICBkZWZhdWx0OiB7CiAgICAgICAgdGhp
cy5fY29udGV4dC5tb3ZlVG8oeCArIHRoaXMuX3JhZGl1cywgeSk7CiAgICAgICAgdGhpcy5fY29u
dGV4dC5hcmMoeCwgeSwgdGhpcy5fcmFkaXVzLCAwLCB0YXUkMyk7CiAgICAgICAgYnJlYWs7CiAg
ICAgIH0KICAgIH0KICB9LAogIHJlc3VsdDogbm9vcCQyCn07Cgp2YXIgbGVuZ3RoU3VtJDEgPSBh
ZGRlcigpLAogICAgbGVuZ3RoUmluZywKICAgIHgwMCQyLAogICAgeTAwJDIsCiAgICB4MCQ0LAog
ICAgeTAkNDsKCnZhciBsZW5ndGhTdHJlYW0kMSA9IHsKICBwb2ludDogbm9vcCQyLAogIGxpbmVT
dGFydDogZnVuY3Rpb24oKSB7CiAgICBsZW5ndGhTdHJlYW0kMS5wb2ludCA9IGxlbmd0aFBvaW50
Rmlyc3QkMTsKICB9LAogIGxpbmVFbmQ6IGZ1bmN0aW9uKCkgewogICAgaWYgKGxlbmd0aFJpbmcp
IGxlbmd0aFBvaW50JDEoeDAwJDIsIHkwMCQyKTsKICAgIGxlbmd0aFN0cmVhbSQxLnBvaW50ID0g
bm9vcCQyOwogIH0sCiAgcG9seWdvblN0YXJ0OiBmdW5jdGlvbigpIHsKICAgIGxlbmd0aFJpbmcg
PSB0cnVlOwogIH0sCiAgcG9seWdvbkVuZDogZnVuY3Rpb24oKSB7CiAgICBsZW5ndGhSaW5nID0g
bnVsbDsKICB9LAogIHJlc3VsdDogZnVuY3Rpb24oKSB7CiAgICB2YXIgbGVuZ3RoID0gK2xlbmd0
aFN1bSQxOwogICAgbGVuZ3RoU3VtJDEucmVzZXQoKTsKICAgIHJldHVybiBsZW5ndGg7CiAgfQp9
OwoKZnVuY3Rpb24gbGVuZ3RoUG9pbnRGaXJzdCQxKHgsIHkpIHsKICBsZW5ndGhTdHJlYW0kMS5w
b2ludCA9IGxlbmd0aFBvaW50JDE7CiAgeDAwJDIgPSB4MCQ0ID0geCwgeTAwJDIgPSB5MCQ0ID0g
eTsKfQoKZnVuY3Rpb24gbGVuZ3RoUG9pbnQkMSh4LCB5KSB7CiAgeDAkNCAtPSB4LCB5MCQ0IC09
IHk7CiAgbGVuZ3RoU3VtJDEuYWRkKHNxcnQoeDAkNCAqIHgwJDQgKyB5MCQ0ICogeTAkNCkpOwog
IHgwJDQgPSB4LCB5MCQ0ID0geTsKfQoKZnVuY3Rpb24gUGF0aFN0cmluZygpIHsKICB0aGlzLl9z
dHJpbmcgPSBbXTsKfQoKUGF0aFN0cmluZy5wcm90b3R5cGUgPSB7CiAgX3JhZGl1czogNC41LAog
IF9jaXJjbGU6IGNpcmNsZSQxKDQuNSksCiAgcG9pbnRSYWRpdXM6IGZ1bmN0aW9uKF8pIHsKICAg
IGlmICgoXyA9ICtfKSAhPT0gdGhpcy5fcmFkaXVzKSB0aGlzLl9yYWRpdXMgPSBfLCB0aGlzLl9j
aXJjbGUgPSBudWxsOwogICAgcmV0dXJuIHRoaXM7CiAgfSwKICBwb2x5Z29uU3RhcnQ6IGZ1bmN0
aW9uKCkgewogICAgdGhpcy5fbGluZSA9IDA7CiAgfSwKICBwb2x5Z29uRW5kOiBmdW5jdGlvbigp
IHsKICAgIHRoaXMuX2xpbmUgPSBOYU47CiAgfSwKICBsaW5lU3RhcnQ6IGZ1bmN0aW9uKCkgewog
ICAgdGhpcy5fcG9pbnQgPSAwOwogIH0sCiAgbGluZUVuZDogZnVuY3Rpb24oKSB7CiAgICBpZiAo
dGhpcy5fbGluZSA9PT0gMCkgdGhpcy5fc3RyaW5nLnB1c2goIloiKTsKICAgIHRoaXMuX3BvaW50
ID0gTmFOOwogIH0sCiAgcG9pbnQ6IGZ1bmN0aW9uKHgsIHkpIHsKICAgIHN3aXRjaCAodGhpcy5f
cG9pbnQpIHsKICAgICAgY2FzZSAwOiB7CiAgICAgICAgdGhpcy5fc3RyaW5nLnB1c2goIk0iLCB4
LCAiLCIsIHkpOwogICAgICAgIHRoaXMuX3BvaW50ID0gMTsKICAgICAgICBicmVhazsKICAgICAg
fQogICAgICBjYXNlIDE6IHsKICAgICAgICB0aGlzLl9zdHJpbmcucHVzaCgiTCIsIHgsICIsIiwg
eSk7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgZGVmYXVsdDogewogICAgICAgIGlmICh0
aGlzLl9jaXJjbGUgPT0gbnVsbCkgdGhpcy5fY2lyY2xlID0gY2lyY2xlJDEodGhpcy5fcmFkaXVz
KTsKICAgICAgICB0aGlzLl9zdHJpbmcucHVzaCgiTSIsIHgsICIsIiwgeSwgdGhpcy5fY2lyY2xl
KTsKICAgICAgICBicmVhazsKICAgICAgfQogICAgfQogIH0sCiAgcmVzdWx0OiBmdW5jdGlvbigp
IHsKICAgIGlmICh0aGlzLl9zdHJpbmcubGVuZ3RoKSB7CiAgICAgIHZhciByZXN1bHQgPSB0aGlz
Ll9zdHJpbmcuam9pbigiIik7CiAgICAgIHRoaXMuX3N0cmluZyA9IFtdOwogICAgICByZXR1cm4g
cmVzdWx0OwogICAgfSBlbHNlIHsKICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgfQp9OwoKZnVu
Y3Rpb24gY2lyY2xlJDEocmFkaXVzKSB7CiAgcmV0dXJuICJtMCwiICsgcmFkaXVzCiAgICAgICsg
ImEiICsgcmFkaXVzICsgIiwiICsgcmFkaXVzICsgIiAwIDEsMSAwLCIgKyAtMiAqIHJhZGl1cwog
ICAgICArICJhIiArIHJhZGl1cyArICIsIiArIHJhZGl1cyArICIgMCAxLDEgMCwiICsgMiAqIHJh
ZGl1cwogICAgICArICJ6IjsKfQoKZnVuY3Rpb24gaW5kZXgkMShwcm9qZWN0aW9uLCBjb250ZXh0
KSB7CiAgdmFyIHBvaW50UmFkaXVzID0gNC41LAogICAgICBwcm9qZWN0aW9uU3RyZWFtLAogICAg
ICBjb250ZXh0U3RyZWFtOwoKICBmdW5jdGlvbiBwYXRoKG9iamVjdCkgewogICAgaWYgKG9iamVj
dCkgewogICAgICBpZiAodHlwZW9mIHBvaW50UmFkaXVzID09PSAiZnVuY3Rpb24iKSBjb250ZXh0
U3RyZWFtLnBvaW50UmFkaXVzKCtwb2ludFJhZGl1cy5hcHBseSh0aGlzLCBhcmd1bWVudHMpKTsK
ICAgICAgZ2VvU3RyZWFtKG9iamVjdCwgcHJvamVjdGlvblN0cmVhbShjb250ZXh0U3RyZWFtKSk7
CiAgICB9CiAgICByZXR1cm4gY29udGV4dFN0cmVhbS5yZXN1bHQoKTsKICB9CgogIHBhdGguYXJl
YSA9IGZ1bmN0aW9uKG9iamVjdCkgewogICAgZ2VvU3RyZWFtKG9iamVjdCwgcHJvamVjdGlvblN0
cmVhbShhcmVhU3RyZWFtJDEpKTsKICAgIHJldHVybiBhcmVhU3RyZWFtJDEucmVzdWx0KCk7CiAg
fTsKCiAgcGF0aC5tZWFzdXJlID0gZnVuY3Rpb24ob2JqZWN0KSB7CiAgICBnZW9TdHJlYW0ob2Jq
ZWN0LCBwcm9qZWN0aW9uU3RyZWFtKGxlbmd0aFN0cmVhbSQxKSk7CiAgICByZXR1cm4gbGVuZ3Ro
U3RyZWFtJDEucmVzdWx0KCk7CiAgfTsKCiAgcGF0aC5ib3VuZHMgPSBmdW5jdGlvbihvYmplY3Qp
IHsKICAgIGdlb1N0cmVhbShvYmplY3QsIHByb2plY3Rpb25TdHJlYW0oYm91bmRzU3RyZWFtJDEp
KTsKICAgIHJldHVybiBib3VuZHNTdHJlYW0kMS5yZXN1bHQoKTsKICB9OwoKICBwYXRoLmNlbnRy
b2lkID0gZnVuY3Rpb24ob2JqZWN0KSB7CiAgICBnZW9TdHJlYW0ob2JqZWN0LCBwcm9qZWN0aW9u
U3RyZWFtKGNlbnRyb2lkU3RyZWFtJDEpKTsKICAgIHJldHVybiBjZW50cm9pZFN0cmVhbSQxLnJl
c3VsdCgpOwogIH07CgogIHBhdGgucHJvamVjdGlvbiA9IGZ1bmN0aW9uKF8pIHsKICAgIHJldHVy
biBhcmd1bWVudHMubGVuZ3RoID8gKHByb2plY3Rpb25TdHJlYW0gPSBfID09IG51bGwgPyAocHJv
amVjdGlvbiA9IG51bGwsIGlkZW50aXR5JDQpIDogKHByb2plY3Rpb24gPSBfKS5zdHJlYW0sIHBh
dGgpIDogcHJvamVjdGlvbjsKICB9OwoKICBwYXRoLmNvbnRleHQgPSBmdW5jdGlvbihfKSB7CiAg
ICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBjb250ZXh0OwogICAgY29udGV4dFN0cmVh
bSA9IF8gPT0gbnVsbCA/IChjb250ZXh0ID0gbnVsbCwgbmV3IFBhdGhTdHJpbmcpIDogbmV3IFBh
dGhDb250ZXh0KGNvbnRleHQgPSBfKTsKICAgIGlmICh0eXBlb2YgcG9pbnRSYWRpdXMgIT09ICJm
dW5jdGlvbiIpIGNvbnRleHRTdHJlYW0ucG9pbnRSYWRpdXMocG9pbnRSYWRpdXMpOwogICAgcmV0
dXJuIHBhdGg7CiAgfTsKCiAgcGF0aC5wb2ludFJhZGl1cyA9IGZ1bmN0aW9uKF8pIHsKICAgIGlm
ICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHBvaW50UmFkaXVzOwogICAgcG9pbnRSYWRpdXMg
PSB0eXBlb2YgXyA9PT0gImZ1bmN0aW9uIiA/IF8gOiAoY29udGV4dFN0cmVhbS5wb2ludFJhZGl1
cygrXyksICtfKTsKICAgIHJldHVybiBwYXRoOwogIH07CgogIHJldHVybiBwYXRoLnByb2plY3Rp
b24ocHJvamVjdGlvbikuY29udGV4dChjb250ZXh0KTsKfQoKZnVuY3Rpb24gdHJhbnNmb3JtKG1l
dGhvZHMpIHsKICByZXR1cm4gewogICAgc3RyZWFtOiB0cmFuc2Zvcm1lcihtZXRob2RzKQogIH07
Cn0KCmZ1bmN0aW9uIHRyYW5zZm9ybWVyKG1ldGhvZHMpIHsKICByZXR1cm4gZnVuY3Rpb24oc3Ry
ZWFtKSB7CiAgICB2YXIgcyA9IG5ldyBUcmFuc2Zvcm1TdHJlYW07CiAgICBmb3IgKHZhciBrZXkg
aW4gbWV0aG9kcykgc1trZXldID0gbWV0aG9kc1trZXldOwogICAgcy5zdHJlYW0gPSBzdHJlYW07
CiAgICByZXR1cm4gczsKICB9Owp9CgpmdW5jdGlvbiBUcmFuc2Zvcm1TdHJlYW0oKSB7fQoKVHJh
bnNmb3JtU3RyZWFtLnByb3RvdHlwZSA9IHsKICBjb25zdHJ1Y3RvcjogVHJhbnNmb3JtU3RyZWFt
LAogIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7IHRoaXMuc3RyZWFtLnBvaW50KHgsIHkpOyB9LAog
IHNwaGVyZTogZnVuY3Rpb24oKSB7IHRoaXMuc3RyZWFtLnNwaGVyZSgpOyB9LAogIGxpbmVTdGFy
dDogZnVuY3Rpb24oKSB7IHRoaXMuc3RyZWFtLmxpbmVTdGFydCgpOyB9LAogIGxpbmVFbmQ6IGZ1
bmN0aW9uKCkgeyB0aGlzLnN0cmVhbS5saW5lRW5kKCk7IH0sCiAgcG9seWdvblN0YXJ0OiBmdW5j
dGlvbigpIHsgdGhpcy5zdHJlYW0ucG9seWdvblN0YXJ0KCk7IH0sCiAgcG9seWdvbkVuZDogZnVu
Y3Rpb24oKSB7IHRoaXMuc3RyZWFtLnBvbHlnb25FbmQoKTsgfQp9OwoKZnVuY3Rpb24gZml0KHBy
b2plY3Rpb24sIGZpdEJvdW5kcywgb2JqZWN0KSB7CiAgdmFyIGNsaXAgPSBwcm9qZWN0aW9uLmNs
aXBFeHRlbnQgJiYgcHJvamVjdGlvbi5jbGlwRXh0ZW50KCk7CiAgcHJvamVjdGlvbi5zY2FsZSgx
NTApLnRyYW5zbGF0ZShbMCwgMF0pOwogIGlmIChjbGlwICE9IG51bGwpIHByb2plY3Rpb24uY2xp
cEV4dGVudChudWxsKTsKICBnZW9TdHJlYW0ob2JqZWN0LCBwcm9qZWN0aW9uLnN0cmVhbShib3Vu
ZHNTdHJlYW0kMSkpOwogIGZpdEJvdW5kcyhib3VuZHNTdHJlYW0kMS5yZXN1bHQoKSk7CiAgaWYg
KGNsaXAgIT0gbnVsbCkgcHJvamVjdGlvbi5jbGlwRXh0ZW50KGNsaXApOwogIHJldHVybiBwcm9q
ZWN0aW9uOwp9CgpmdW5jdGlvbiBmaXRFeHRlbnQocHJvamVjdGlvbiwgZXh0ZW50LCBvYmplY3Qp
IHsKICByZXR1cm4gZml0KHByb2plY3Rpb24sIGZ1bmN0aW9uKGIpIHsKICAgIHZhciB3ID0gZXh0
ZW50WzFdWzBdIC0gZXh0ZW50WzBdWzBdLAogICAgICAgIGggPSBleHRlbnRbMV1bMV0gLSBleHRl
bnRbMF1bMV0sCiAgICAgICAgayA9IE1hdGgubWluKHcgLyAoYlsxXVswXSAtIGJbMF1bMF0pLCBo
IC8gKGJbMV1bMV0gLSBiWzBdWzFdKSksCiAgICAgICAgeCA9ICtleHRlbnRbMF1bMF0gKyAodyAt
IGsgKiAoYlsxXVswXSArIGJbMF1bMF0pKSAvIDIsCiAgICAgICAgeSA9ICtleHRlbnRbMF1bMV0g
KyAoaCAtIGsgKiAoYlsxXVsxXSArIGJbMF1bMV0pKSAvIDI7CiAgICBwcm9qZWN0aW9uLnNjYWxl
KDE1MCAqIGspLnRyYW5zbGF0ZShbeCwgeV0pOwogIH0sIG9iamVjdCk7Cn0KCmZ1bmN0aW9uIGZp
dFNpemUocHJvamVjdGlvbiwgc2l6ZSwgb2JqZWN0KSB7CiAgcmV0dXJuIGZpdEV4dGVudChwcm9q
ZWN0aW9uLCBbWzAsIDBdLCBzaXplXSwgb2JqZWN0KTsKfQoKZnVuY3Rpb24gZml0V2lkdGgocHJv
amVjdGlvbiwgd2lkdGgsIG9iamVjdCkgewogIHJldHVybiBmaXQocHJvamVjdGlvbiwgZnVuY3Rp
b24oYikgewogICAgdmFyIHcgPSArd2lkdGgsCiAgICAgICAgayA9IHcgLyAoYlsxXVswXSAtIGJb
MF1bMF0pLAogICAgICAgIHggPSAodyAtIGsgKiAoYlsxXVswXSArIGJbMF1bMF0pKSAvIDIsCiAg
ICAgICAgeSA9IC1rICogYlswXVsxXTsKICAgIHByb2plY3Rpb24uc2NhbGUoMTUwICogaykudHJh
bnNsYXRlKFt4LCB5XSk7CiAgfSwgb2JqZWN0KTsKfQoKZnVuY3Rpb24gZml0SGVpZ2h0KHByb2pl
Y3Rpb24sIGhlaWdodCwgb2JqZWN0KSB7CiAgcmV0dXJuIGZpdChwcm9qZWN0aW9uLCBmdW5jdGlv
bihiKSB7CiAgICB2YXIgaCA9ICtoZWlnaHQsCiAgICAgICAgayA9IGggLyAoYlsxXVsxXSAtIGJb
MF1bMV0pLAogICAgICAgIHggPSAtayAqIGJbMF1bMF0sCiAgICAgICAgeSA9IChoIC0gayAqIChi
WzFdWzFdICsgYlswXVsxXSkpIC8gMjsKICAgIHByb2plY3Rpb24uc2NhbGUoMTUwICogaykudHJh
bnNsYXRlKFt4LCB5XSk7CiAgfSwgb2JqZWN0KTsKfQoKdmFyIG1heERlcHRoID0gMTYsIC8vIG1h
eGltdW0gZGVwdGggb2Ygc3ViZGl2aXNpb24KICAgIGNvc01pbkRpc3RhbmNlID0gY29zJDEoMzAg
KiByYWRpYW5zKTsgLy8gY29zKG1pbmltdW0gYW5ndWxhciBkaXN0YW5jZSkKCmZ1bmN0aW9uIHJl
c2FtcGxlKHByb2plY3QsIGRlbHRhMikgewogIHJldHVybiArZGVsdGEyID8gcmVzYW1wbGUkMShw
cm9qZWN0LCBkZWx0YTIpIDogcmVzYW1wbGVOb25lKHByb2plY3QpOwp9CgpmdW5jdGlvbiByZXNh
bXBsZU5vbmUocHJvamVjdCkgewogIHJldHVybiB0cmFuc2Zvcm1lcih7CiAgICBwb2ludDogZnVu
Y3Rpb24oeCwgeSkgewogICAgICB4ID0gcHJvamVjdCh4LCB5KTsKICAgICAgdGhpcy5zdHJlYW0u
cG9pbnQoeFswXSwgeFsxXSk7CiAgICB9CiAgfSk7Cn0KCmZ1bmN0aW9uIHJlc2FtcGxlJDEocHJv
amVjdCwgZGVsdGEyKSB7CgogIGZ1bmN0aW9uIHJlc2FtcGxlTGluZVRvKHgwLCB5MCwgbGFtYmRh
MCwgYTAsIGIwLCBjMCwgeDEsIHkxLCBsYW1iZGExLCBhMSwgYjEsIGMxLCBkZXB0aCwgc3RyZWFt
KSB7CiAgICB2YXIgZHggPSB4MSAtIHgwLAogICAgICAgIGR5ID0geTEgLSB5MCwKICAgICAgICBk
MiA9IGR4ICogZHggKyBkeSAqIGR5OwogICAgaWYgKGQyID4gNCAqIGRlbHRhMiAmJiBkZXB0aC0t
KSB7CiAgICAgIHZhciBhID0gYTAgKyBhMSwKICAgICAgICAgIGIgPSBiMCArIGIxLAogICAgICAg
ICAgYyA9IGMwICsgYzEsCiAgICAgICAgICBtID0gc3FydChhICogYSArIGIgKiBiICsgYyAqIGMp
LAogICAgICAgICAgcGhpMiA9IGFzaW4oYyAvPSBtKSwKICAgICAgICAgIGxhbWJkYTIgPSBhYnMo
YWJzKGMpIC0gMSkgPCBlcHNpbG9uJDIgfHwgYWJzKGxhbWJkYTAgLSBsYW1iZGExKSA8IGVwc2ls
b24kMiA/IChsYW1iZGEwICsgbGFtYmRhMSkgLyAyIDogYXRhbjIoYiwgYSksCiAgICAgICAgICBw
ID0gcHJvamVjdChsYW1iZGEyLCBwaGkyKSwKICAgICAgICAgIHgyID0gcFswXSwKICAgICAgICAg
IHkyID0gcFsxXSwKICAgICAgICAgIGR4MiA9IHgyIC0geDAsCiAgICAgICAgICBkeTIgPSB5MiAt
IHkwLAogICAgICAgICAgZHogPSBkeSAqIGR4MiAtIGR4ICogZHkyOwogICAgICBpZiAoZHogKiBk
eiAvIGQyID4gZGVsdGEyIC8vIHBlcnBlbmRpY3VsYXIgcHJvamVjdGVkIGRpc3RhbmNlCiAgICAg
ICAgICB8fCBhYnMoKGR4ICogZHgyICsgZHkgKiBkeTIpIC8gZDIgLSAwLjUpID4gMC4zIC8vIG1p
ZHBvaW50IGNsb3NlIHRvIGFuIGVuZAogICAgICAgICAgfHwgYTAgKiBhMSArIGIwICogYjEgKyBj
MCAqIGMxIDwgY29zTWluRGlzdGFuY2UpIHsgLy8gYW5ndWxhciBkaXN0YW5jZQogICAgICAgIHJl
c2FtcGxlTGluZVRvKHgwLCB5MCwgbGFtYmRhMCwgYTAsIGIwLCBjMCwgeDIsIHkyLCBsYW1iZGEy
LCBhIC89IG0sIGIgLz0gbSwgYywgZGVwdGgsIHN0cmVhbSk7CiAgICAgICAgc3RyZWFtLnBvaW50
KHgyLCB5Mik7CiAgICAgICAgcmVzYW1wbGVMaW5lVG8oeDIsIHkyLCBsYW1iZGEyLCBhLCBiLCBj
LCB4MSwgeTEsIGxhbWJkYTEsIGExLCBiMSwgYzEsIGRlcHRoLCBzdHJlYW0pOwogICAgICB9CiAg
ICB9CiAgfQogIHJldHVybiBmdW5jdGlvbihzdHJlYW0pIHsKICAgIHZhciBsYW1iZGEwMCwgeDAw
LCB5MDAsIGEwMCwgYjAwLCBjMDAsIC8vIGZpcnN0IHBvaW50CiAgICAgICAgbGFtYmRhMCwgeDAs
IHkwLCBhMCwgYjAsIGMwOyAvLyBwcmV2aW91cyBwb2ludAoKICAgIHZhciByZXNhbXBsZVN0cmVh
bSA9IHsKICAgICAgcG9pbnQ6IHBvaW50LAogICAgICBsaW5lU3RhcnQ6IGxpbmVTdGFydCwKICAg
ICAgbGluZUVuZDogbGluZUVuZCwKICAgICAgcG9seWdvblN0YXJ0OiBmdW5jdGlvbigpIHsgc3Ry
ZWFtLnBvbHlnb25TdGFydCgpOyByZXNhbXBsZVN0cmVhbS5saW5lU3RhcnQgPSByaW5nU3RhcnQ7
IH0sCiAgICAgIHBvbHlnb25FbmQ6IGZ1bmN0aW9uKCkgeyBzdHJlYW0ucG9seWdvbkVuZCgpOyBy
ZXNhbXBsZVN0cmVhbS5saW5lU3RhcnQgPSBsaW5lU3RhcnQ7IH0KICAgIH07CgogICAgZnVuY3Rp
b24gcG9pbnQoeCwgeSkgewogICAgICB4ID0gcHJvamVjdCh4LCB5KTsKICAgICAgc3RyZWFtLnBv
aW50KHhbMF0sIHhbMV0pOwogICAgfQoKICAgIGZ1bmN0aW9uIGxpbmVTdGFydCgpIHsKICAgICAg
eDAgPSBOYU47CiAgICAgIHJlc2FtcGxlU3RyZWFtLnBvaW50ID0gbGluZVBvaW50OwogICAgICBz
dHJlYW0ubGluZVN0YXJ0KCk7CiAgICB9CgogICAgZnVuY3Rpb24gbGluZVBvaW50KGxhbWJkYSwg
cGhpKSB7CiAgICAgIHZhciBjID0gY2FydGVzaWFuKFtsYW1iZGEsIHBoaV0pLCBwID0gcHJvamVj
dChsYW1iZGEsIHBoaSk7CiAgICAgIHJlc2FtcGxlTGluZVRvKHgwLCB5MCwgbGFtYmRhMCwgYTAs
IGIwLCBjMCwgeDAgPSBwWzBdLCB5MCA9IHBbMV0sIGxhbWJkYTAgPSBsYW1iZGEsIGEwID0gY1sw
XSwgYjAgPSBjWzFdLCBjMCA9IGNbMl0sIG1heERlcHRoLCBzdHJlYW0pOwogICAgICBzdHJlYW0u
cG9pbnQoeDAsIHkwKTsKICAgIH0KCiAgICBmdW5jdGlvbiBsaW5lRW5kKCkgewogICAgICByZXNh
bXBsZVN0cmVhbS5wb2ludCA9IHBvaW50OwogICAgICBzdHJlYW0ubGluZUVuZCgpOwogICAgfQoK
ICAgIGZ1bmN0aW9uIHJpbmdTdGFydCgpIHsKICAgICAgbGluZVN0YXJ0KCk7CiAgICAgIHJlc2Ft
cGxlU3RyZWFtLnBvaW50ID0gcmluZ1BvaW50OwogICAgICByZXNhbXBsZVN0cmVhbS5saW5lRW5k
ID0gcmluZ0VuZDsKICAgIH0KCiAgICBmdW5jdGlvbiByaW5nUG9pbnQobGFtYmRhLCBwaGkpIHsK
ICAgICAgbGluZVBvaW50KGxhbWJkYTAwID0gbGFtYmRhLCBwaGkpLCB4MDAgPSB4MCwgeTAwID0g
eTAsIGEwMCA9IGEwLCBiMDAgPSBiMCwgYzAwID0gYzA7CiAgICAgIHJlc2FtcGxlU3RyZWFtLnBv
aW50ID0gbGluZVBvaW50OwogICAgfQoKICAgIGZ1bmN0aW9uIHJpbmdFbmQoKSB7CiAgICAgIHJl
c2FtcGxlTGluZVRvKHgwLCB5MCwgbGFtYmRhMCwgYTAsIGIwLCBjMCwgeDAwLCB5MDAsIGxhbWJk
YTAwLCBhMDAsIGIwMCwgYzAwLCBtYXhEZXB0aCwgc3RyZWFtKTsKICAgICAgcmVzYW1wbGVTdHJl
YW0ubGluZUVuZCA9IGxpbmVFbmQ7CiAgICAgIGxpbmVFbmQoKTsKICAgIH0KCiAgICByZXR1cm4g
cmVzYW1wbGVTdHJlYW07CiAgfTsKfQoKdmFyIHRyYW5zZm9ybVJhZGlhbnMgPSB0cmFuc2Zvcm1l
cih7CiAgcG9pbnQ6IGZ1bmN0aW9uKHgsIHkpIHsKICAgIHRoaXMuc3RyZWFtLnBvaW50KHggKiBy
YWRpYW5zLCB5ICogcmFkaWFucyk7CiAgfQp9KTsKCmZ1bmN0aW9uIHRyYW5zZm9ybVJvdGF0ZShy
b3RhdGUpIHsKICByZXR1cm4gdHJhbnNmb3JtZXIoewogICAgcG9pbnQ6IGZ1bmN0aW9uKHgsIHkp
IHsKICAgICAgdmFyIHIgPSByb3RhdGUoeCwgeSk7CiAgICAgIHJldHVybiB0aGlzLnN0cmVhbS5w
b2ludChyWzBdLCByWzFdKTsKICAgIH0KICB9KTsKfQoKZnVuY3Rpb24gc2NhbGVUcmFuc2xhdGUo
aywgZHgsIGR5LCBzeCwgc3kpIHsKICBmdW5jdGlvbiB0cmFuc2Zvcm0oeCwgeSkgewogICAgeCAq
PSBzeDsgeSAqPSBzeTsKICAgIHJldHVybiBbZHggKyBrICogeCwgZHkgLSBrICogeV07CiAgfQog
IHRyYW5zZm9ybS5pbnZlcnQgPSBmdW5jdGlvbih4LCB5KSB7CiAgICByZXR1cm4gWyh4IC0gZHgp
IC8gayAqIHN4LCAoZHkgLSB5KSAvIGsgKiBzeV07CiAgfTsKICByZXR1cm4gdHJhbnNmb3JtOwp9
CgpmdW5jdGlvbiBzY2FsZVRyYW5zbGF0ZVJvdGF0ZShrLCBkeCwgZHksIHN4LCBzeSwgYWxwaGEp
IHsKICB2YXIgY29zQWxwaGEgPSBjb3MkMShhbHBoYSksCiAgICAgIHNpbkFscGhhID0gc2luJDEo
YWxwaGEpLAogICAgICBhID0gY29zQWxwaGEgKiBrLAogICAgICBiID0gc2luQWxwaGEgKiBrLAog
ICAgICBhaSA9IGNvc0FscGhhIC8gaywKICAgICAgYmkgPSBzaW5BbHBoYSAvIGssCiAgICAgIGNp
ID0gKHNpbkFscGhhICogZHkgLSBjb3NBbHBoYSAqIGR4KSAvIGssCiAgICAgIGZpID0gKHNpbkFs
cGhhICogZHggKyBjb3NBbHBoYSAqIGR5KSAvIGs7CiAgZnVuY3Rpb24gdHJhbnNmb3JtKHgsIHkp
IHsKICAgIHggKj0gc3g7IHkgKj0gc3k7CiAgICByZXR1cm4gW2EgKiB4IC0gYiAqIHkgKyBkeCwg
ZHkgLSBiICogeCAtIGEgKiB5XTsKICB9CiAgdHJhbnNmb3JtLmludmVydCA9IGZ1bmN0aW9uKHgs
IHkpIHsKICAgIHJldHVybiBbc3ggKiAoYWkgKiB4IC0gYmkgKiB5ICsgY2kpLCBzeSAqIChmaSAt
IGJpICogeCAtIGFpICogeSldOwogIH07CiAgcmV0dXJuIHRyYW5zZm9ybTsKfQoKZnVuY3Rpb24g
cHJvamVjdGlvbihwcm9qZWN0KSB7CiAgcmV0dXJuIHByb2plY3Rpb25NdXRhdG9yKGZ1bmN0aW9u
KCkgeyByZXR1cm4gcHJvamVjdDsgfSkoKTsKfQoKZnVuY3Rpb24gcHJvamVjdGlvbk11dGF0b3Io
cHJvamVjdEF0KSB7CiAgdmFyIHByb2plY3QsCiAgICAgIGsgPSAxNTAsIC8vIHNjYWxlCiAgICAg
IHggPSA0ODAsIHkgPSAyNTAsIC8vIHRyYW5zbGF0ZQogICAgICBsYW1iZGEgPSAwLCBwaGkgPSAw
LCAvLyBjZW50ZXIKICAgICAgZGVsdGFMYW1iZGEgPSAwLCBkZWx0YVBoaSA9IDAsIGRlbHRhR2Ft
bWEgPSAwLCByb3RhdGUsIC8vIHByZS1yb3RhdGUKICAgICAgYWxwaGEgPSAwLCAvLyBwb3N0LXJv
dGF0ZSBhbmdsZQogICAgICBzeCA9IDEsIC8vIHJlZmxlY3RYCiAgICAgIHN5ID0gMSwgLy8gcmVm
bGVjdFgKICAgICAgdGhldGEgPSBudWxsLCBwcmVjbGlwID0gY2xpcEFudGltZXJpZGlhbiwgLy8g
cHJlLWNsaXAgYW5nbGUKICAgICAgeDAgPSBudWxsLCB5MCwgeDEsIHkxLCBwb3N0Y2xpcCA9IGlk
ZW50aXR5JDQsIC8vIHBvc3QtY2xpcCBleHRlbnQKICAgICAgZGVsdGEyID0gMC41LCAvLyBwcmVj
aXNpb24KICAgICAgcHJvamVjdFJlc2FtcGxlLAogICAgICBwcm9qZWN0VHJhbnNmb3JtLAogICAg
ICBwcm9qZWN0Um90YXRlVHJhbnNmb3JtLAogICAgICBjYWNoZSwKICAgICAgY2FjaGVTdHJlYW07
CgogIGZ1bmN0aW9uIHByb2plY3Rpb24ocG9pbnQpIHsKICAgIHJldHVybiBwcm9qZWN0Um90YXRl
VHJhbnNmb3JtKHBvaW50WzBdICogcmFkaWFucywgcG9pbnRbMV0gKiByYWRpYW5zKTsKICB9Cgog
IGZ1bmN0aW9uIGludmVydChwb2ludCkgewogICAgcG9pbnQgPSBwcm9qZWN0Um90YXRlVHJhbnNm
b3JtLmludmVydChwb2ludFswXSwgcG9pbnRbMV0pOwogICAgcmV0dXJuIHBvaW50ICYmIFtwb2lu
dFswXSAqIGRlZ3JlZXMkMSwgcG9pbnRbMV0gKiBkZWdyZWVzJDFdOwogIH0KCiAgcHJvamVjdGlv
bi5zdHJlYW0gPSBmdW5jdGlvbihzdHJlYW0pIHsKICAgIHJldHVybiBjYWNoZSAmJiBjYWNoZVN0
cmVhbSA9PT0gc3RyZWFtID8gY2FjaGUgOiBjYWNoZSA9IHRyYW5zZm9ybVJhZGlhbnModHJhbnNm
b3JtUm90YXRlKHJvdGF0ZSkocHJlY2xpcChwcm9qZWN0UmVzYW1wbGUocG9zdGNsaXAoY2FjaGVT
dHJlYW0gPSBzdHJlYW0pKSkpKTsKICB9OwoKICBwcm9qZWN0aW9uLnByZWNsaXAgPSBmdW5jdGlv
bihfKSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChwcmVjbGlwID0gXywgdGhldGEg
PSB1bmRlZmluZWQsIHJlc2V0KCkpIDogcHJlY2xpcDsKICB9OwoKICBwcm9qZWN0aW9uLnBvc3Rj
bGlwID0gZnVuY3Rpb24oXykgewogICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAocG9zdGNs
aXAgPSBfLCB4MCA9IHkwID0geDEgPSB5MSA9IG51bGwsIHJlc2V0KCkpIDogcG9zdGNsaXA7CiAg
fTsKCiAgcHJvamVjdGlvbi5jbGlwQW5nbGUgPSBmdW5jdGlvbihfKSB7CiAgICByZXR1cm4gYXJn
dW1lbnRzLmxlbmd0aCA/IChwcmVjbGlwID0gK18gPyBjbGlwQ2lyY2xlKHRoZXRhID0gXyAqIHJh
ZGlhbnMpIDogKHRoZXRhID0gbnVsbCwgY2xpcEFudGltZXJpZGlhbiksIHJlc2V0KCkpIDogdGhl
dGEgKiBkZWdyZWVzJDE7CiAgfTsKCiAgcHJvamVjdGlvbi5jbGlwRXh0ZW50ID0gZnVuY3Rpb24o
XykgewogICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAocG9zdGNsaXAgPSBfID09IG51bGwg
PyAoeDAgPSB5MCA9IHgxID0geTEgPSBudWxsLCBpZGVudGl0eSQ0KSA6IGNsaXBSZWN0YW5nbGUo
eDAgPSArX1swXVswXSwgeTAgPSArX1swXVsxXSwgeDEgPSArX1sxXVswXSwgeTEgPSArX1sxXVsx
XSksIHJlc2V0KCkpIDogeDAgPT0gbnVsbCA/IG51bGwgOiBbW3gwLCB5MF0sIFt4MSwgeTFdXTsK
ICB9OwoKICBwcm9qZWN0aW9uLnNjYWxlID0gZnVuY3Rpb24oXykgewogICAgcmV0dXJuIGFyZ3Vt
ZW50cy5sZW5ndGggPyAoayA9ICtfLCByZWNlbnRlcigpKSA6IGs7CiAgfTsKCiAgcHJvamVjdGlv
bi50cmFuc2xhdGUgPSBmdW5jdGlvbihfKSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/
ICh4ID0gK19bMF0sIHkgPSArX1sxXSwgcmVjZW50ZXIoKSkgOiBbeCwgeV07CiAgfTsKCiAgcHJv
amVjdGlvbi5jZW50ZXIgPSBmdW5jdGlvbihfKSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0
aCA/IChsYW1iZGEgPSBfWzBdICUgMzYwICogcmFkaWFucywgcGhpID0gX1sxXSAlIDM2MCAqIHJh
ZGlhbnMsIHJlY2VudGVyKCkpIDogW2xhbWJkYSAqIGRlZ3JlZXMkMSwgcGhpICogZGVncmVlcyQx
XTsKICB9OwoKICBwcm9qZWN0aW9uLnJvdGF0ZSA9IGZ1bmN0aW9uKF8pIHsKICAgIHJldHVybiBh
cmd1bWVudHMubGVuZ3RoID8gKGRlbHRhTGFtYmRhID0gX1swXSAlIDM2MCAqIHJhZGlhbnMsIGRl
bHRhUGhpID0gX1sxXSAlIDM2MCAqIHJhZGlhbnMsIGRlbHRhR2FtbWEgPSBfLmxlbmd0aCA+IDIg
PyBfWzJdICUgMzYwICogcmFkaWFucyA6IDAsIHJlY2VudGVyKCkpIDogW2RlbHRhTGFtYmRhICog
ZGVncmVlcyQxLCBkZWx0YVBoaSAqIGRlZ3JlZXMkMSwgZGVsdGFHYW1tYSAqIGRlZ3JlZXMkMV07
CiAgfTsKCiAgcHJvamVjdGlvbi5hbmdsZSA9IGZ1bmN0aW9uKF8pIHsKICAgIHJldHVybiBhcmd1
bWVudHMubGVuZ3RoID8gKGFscGhhID0gXyAlIDM2MCAqIHJhZGlhbnMsIHJlY2VudGVyKCkpIDog
YWxwaGEgKiBkZWdyZWVzJDE7CiAgfTsKCiAgcHJvamVjdGlvbi5yZWZsZWN0WCA9IGZ1bmN0aW9u
KF8pIHsKICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHN4ID0gXyA/IC0xIDogMSwgcmVj
ZW50ZXIoKSkgOiBzeCA8IDA7CiAgfTsKCiAgcHJvamVjdGlvbi5yZWZsZWN0WSA9IGZ1bmN0aW9u
KF8pIHsKICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHN5ID0gXyA/IC0xIDogMSwgcmVj
ZW50ZXIoKSkgOiBzeSA8IDA7CiAgfTsKCiAgcHJvamVjdGlvbi5wcmVjaXNpb24gPSBmdW5jdGlv
bihfKSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChwcm9qZWN0UmVzYW1wbGUgPSBy
ZXNhbXBsZShwcm9qZWN0VHJhbnNmb3JtLCBkZWx0YTIgPSBfICogXyksIHJlc2V0KCkpIDogc3Fy
dChkZWx0YTIpOwogIH07CgogIHByb2plY3Rpb24uZml0RXh0ZW50ID0gZnVuY3Rpb24oZXh0ZW50
LCBvYmplY3QpIHsKICAgIHJldHVybiBmaXRFeHRlbnQocHJvamVjdGlvbiwgZXh0ZW50LCBvYmpl
Y3QpOwogIH07CgogIHByb2plY3Rpb24uZml0U2l6ZSA9IGZ1bmN0aW9uKHNpemUsIG9iamVjdCkg
ewogICAgcmV0dXJuIGZpdFNpemUocHJvamVjdGlvbiwgc2l6ZSwgb2JqZWN0KTsKICB9OwoKICBw
cm9qZWN0aW9uLmZpdFdpZHRoID0gZnVuY3Rpb24od2lkdGgsIG9iamVjdCkgewogICAgcmV0dXJu
IGZpdFdpZHRoKHByb2plY3Rpb24sIHdpZHRoLCBvYmplY3QpOwogIH07CgogIHByb2plY3Rpb24u
Zml0SGVpZ2h0ID0gZnVuY3Rpb24oaGVpZ2h0LCBvYmplY3QpIHsKICAgIHJldHVybiBmaXRIZWln
aHQocHJvamVjdGlvbiwgaGVpZ2h0LCBvYmplY3QpOwogIH07CgogIGZ1bmN0aW9uIHJlY2VudGVy
KCkgewogICAgdmFyIGNlbnRlciA9IHNjYWxlVHJhbnNsYXRlUm90YXRlKGssIDAsIDAsIHN4LCBz
eSwgYWxwaGEpLmFwcGx5KG51bGwsIHByb2plY3QobGFtYmRhLCBwaGkpKSwKICAgICAgICB0cmFu
c2Zvcm0gPSAoYWxwaGEgPyBzY2FsZVRyYW5zbGF0ZVJvdGF0ZSA6IHNjYWxlVHJhbnNsYXRlKShr
LCB4IC0gY2VudGVyWzBdLCB5IC0gY2VudGVyWzFdLCBzeCwgc3ksIGFscGhhKTsKICAgIHJvdGF0
ZSA9IHJvdGF0ZVJhZGlhbnMoZGVsdGFMYW1iZGEsIGRlbHRhUGhpLCBkZWx0YUdhbW1hKTsKICAg
IHByb2plY3RUcmFuc2Zvcm0gPSBjb21wb3NlKHByb2plY3QsIHRyYW5zZm9ybSk7CiAgICBwcm9q
ZWN0Um90YXRlVHJhbnNmb3JtID0gY29tcG9zZShyb3RhdGUsIHByb2plY3RUcmFuc2Zvcm0pOwog
ICAgcHJvamVjdFJlc2FtcGxlID0gcmVzYW1wbGUocHJvamVjdFRyYW5zZm9ybSwgZGVsdGEyKTsK
ICAgIHJldHVybiByZXNldCgpOwogIH0KCiAgZnVuY3Rpb24gcmVzZXQoKSB7CiAgICBjYWNoZSA9
IGNhY2hlU3RyZWFtID0gbnVsbDsKICAgIHJldHVybiBwcm9qZWN0aW9uOwogIH0KCiAgcmV0dXJu
IGZ1bmN0aW9uKCkgewogICAgcHJvamVjdCA9IHByb2plY3RBdC5hcHBseSh0aGlzLCBhcmd1bWVu
dHMpOwogICAgcHJvamVjdGlvbi5pbnZlcnQgPSBwcm9qZWN0LmludmVydCAmJiBpbnZlcnQ7CiAg
ICByZXR1cm4gcmVjZW50ZXIoKTsKICB9Owp9CgpmdW5jdGlvbiBjb25pY1Byb2plY3Rpb24ocHJv
amVjdEF0KSB7CiAgdmFyIHBoaTAgPSAwLAogICAgICBwaGkxID0gcGkkMyAvIDMsCiAgICAgIG0g
PSBwcm9qZWN0aW9uTXV0YXRvcihwcm9qZWN0QXQpLAogICAgICBwID0gbShwaGkwLCBwaGkxKTsK
CiAgcC5wYXJhbGxlbHMgPSBmdW5jdGlvbihfKSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0
aCA/IG0ocGhpMCA9IF9bMF0gKiByYWRpYW5zLCBwaGkxID0gX1sxXSAqIHJhZGlhbnMpIDogW3Bo
aTAgKiBkZWdyZWVzJDEsIHBoaTEgKiBkZWdyZWVzJDFdOwogIH07CgogIHJldHVybiBwOwp9Cgpm
dW5jdGlvbiBjeWxpbmRyaWNhbEVxdWFsQXJlYVJhdyhwaGkwKSB7CiAgdmFyIGNvc1BoaTAgPSBj
b3MkMShwaGkwKTsKCiAgZnVuY3Rpb24gZm9yd2FyZChsYW1iZGEsIHBoaSkgewogICAgcmV0dXJu
IFtsYW1iZGEgKiBjb3NQaGkwLCBzaW4kMShwaGkpIC8gY29zUGhpMF07CiAgfQoKICBmb3J3YXJk
LmludmVydCA9IGZ1bmN0aW9uKHgsIHkpIHsKICAgIHJldHVybiBbeCAvIGNvc1BoaTAsIGFzaW4o
eSAqIGNvc1BoaTApXTsKICB9OwoKICByZXR1cm4gZm9yd2FyZDsKfQoKZnVuY3Rpb24gY29uaWNF
cXVhbEFyZWFSYXcoeTAsIHkxKSB7CiAgdmFyIHN5MCA9IHNpbiQxKHkwKSwgbiA9IChzeTAgKyBz
aW4kMSh5MSkpIC8gMjsKCiAgLy8gQXJlIHRoZSBwYXJhbGxlbHMgc3ltbWV0cmljYWwgYXJvdW5k
IHRoZSBFcXVhdG9yPwogIGlmIChhYnMobikgPCBlcHNpbG9uJDIpIHJldHVybiBjeWxpbmRyaWNh
bEVxdWFsQXJlYVJhdyh5MCk7CgogIHZhciBjID0gMSArIHN5MCAqICgyICogbiAtIHN5MCksIHIw
ID0gc3FydChjKSAvIG47CgogIGZ1bmN0aW9uIHByb2plY3QoeCwgeSkgewogICAgdmFyIHIgPSBz
cXJ0KGMgLSAyICogbiAqIHNpbiQxKHkpKSAvIG47CiAgICByZXR1cm4gW3IgKiBzaW4kMSh4ICo9
IG4pLCByMCAtIHIgKiBjb3MkMSh4KV07CiAgfQoKICBwcm9qZWN0LmludmVydCA9IGZ1bmN0aW9u
KHgsIHkpIHsKICAgIHZhciByMHkgPSByMCAtIHksCiAgICAgICAgbCA9IGF0YW4yKHgsIGFicyhy
MHkpKSAqIHNpZ24ocjB5KTsKICAgIGlmIChyMHkgKiBuIDwgMCkKICAgICAgbCAtPSBwaSQzICog
c2lnbih4KSAqIHNpZ24ocjB5KTsKICAgIHJldHVybiBbbCAvIG4sIGFzaW4oKGMgLSAoeCAqIHgg
KyByMHkgKiByMHkpICogbiAqIG4pIC8gKDIgKiBuKSldOwogIH07CgogIHJldHVybiBwcm9qZWN0
Owp9CgpmdW5jdGlvbiBjb25pY0VxdWFsQXJlYSgpIHsKICByZXR1cm4gY29uaWNQcm9qZWN0aW9u
KGNvbmljRXF1YWxBcmVhUmF3KQogICAgICAuc2NhbGUoMTU1LjQyNCkKICAgICAgLmNlbnRlcihb
MCwgMzMuNjQ0Ml0pOwp9CgpmdW5jdGlvbiBhbGJlcnMoKSB7CiAgcmV0dXJuIGNvbmljRXF1YWxB
cmVhKCkKICAgICAgLnBhcmFsbGVscyhbMjkuNSwgNDUuNV0pCiAgICAgIC5zY2FsZSgxMDcwKQog
ICAgICAudHJhbnNsYXRlKFs0ODAsIDI1MF0pCiAgICAgIC5yb3RhdGUoWzk2LCAwXSkKICAgICAg
LmNlbnRlcihbLTAuNiwgMzguN10pOwp9CgovLyBUaGUgcHJvamVjdGlvbnMgbXVzdCBoYXZlIG11
dHVhbGx5IGV4Y2x1c2l2ZSBjbGlwIHJlZ2lvbnMgb24gdGhlIHNwaGVyZSwKLy8gYXMgdGhpcyB3
aWxsIGF2b2lkIGVtaXR0aW5nIGludGVybGVhdmluZyBsaW5lcyBhbmQgcG9seWdvbnMuCmZ1bmN0
aW9uIG11bHRpcGxleChzdHJlYW1zKSB7CiAgdmFyIG4gPSBzdHJlYW1zLmxlbmd0aDsKICByZXR1
cm4gewogICAgcG9pbnQ6IGZ1bmN0aW9uKHgsIHkpIHsgdmFyIGkgPSAtMTsgd2hpbGUgKCsraSA8
IG4pIHN0cmVhbXNbaV0ucG9pbnQoeCwgeSk7IH0sCiAgICBzcGhlcmU6IGZ1bmN0aW9uKCkgeyB2
YXIgaSA9IC0xOyB3aGlsZSAoKytpIDwgbikgc3RyZWFtc1tpXS5zcGhlcmUoKTsgfSwKICAgIGxp
bmVTdGFydDogZnVuY3Rpb24oKSB7IHZhciBpID0gLTE7IHdoaWxlICgrK2kgPCBuKSBzdHJlYW1z
W2ldLmxpbmVTdGFydCgpOyB9LAogICAgbGluZUVuZDogZnVuY3Rpb24oKSB7IHZhciBpID0gLTE7
IHdoaWxlICgrK2kgPCBuKSBzdHJlYW1zW2ldLmxpbmVFbmQoKTsgfSwKICAgIHBvbHlnb25TdGFy
dDogZnVuY3Rpb24oKSB7IHZhciBpID0gLTE7IHdoaWxlICgrK2kgPCBuKSBzdHJlYW1zW2ldLnBv
bHlnb25TdGFydCgpOyB9LAogICAgcG9seWdvbkVuZDogZnVuY3Rpb24oKSB7IHZhciBpID0gLTE7
IHdoaWxlICgrK2kgPCBuKSBzdHJlYW1zW2ldLnBvbHlnb25FbmQoKTsgfQogIH07Cn0KCi8vIEEg
Y29tcG9zaXRlIHByb2plY3Rpb24gZm9yIHRoZSBVbml0ZWQgU3RhdGVzLCBjb25maWd1cmVkIGJ5
IGRlZmF1bHQgZm9yCi8vIDk2MMOXNTAwLiBUaGUgcHJvamVjdGlvbiBhbHNvIHdvcmtzIHF1aXRl
IHdlbGwgYXQgOTYww5c2MDAgaWYgeW91IGNoYW5nZSB0aGUKLy8gc2NhbGUgdG8gMTI4NSBhbmQg
YWRqdXN0IHRoZSB0cmFuc2xhdGUgYWNjb3JkaW5nbHkuIFRoZSBzZXQgb2Ygc3RhbmRhcmQKLy8g
cGFyYWxsZWxzIGZvciBlYWNoIHJlZ2lvbiBjb21lcyBmcm9tIFVTR1MsIHdoaWNoIGlzIHB1Ymxp
c2hlZCBoZXJlOgovLyBodHRwOi8vZWdzYy51c2dzLmdvdi9pc2IvcHVicy9NYXBQcm9qZWN0aW9u
cy9wcm9qZWN0aW9ucy5odG1sI2FsYmVycwpmdW5jdGlvbiBhbGJlcnNVc2EoKSB7CiAgdmFyIGNh
Y2hlLAogICAgICBjYWNoZVN0cmVhbSwKICAgICAgbG93ZXI0OCA9IGFsYmVycygpLCBsb3dlcjQ4
UG9pbnQsCiAgICAgIGFsYXNrYSA9IGNvbmljRXF1YWxBcmVhKCkucm90YXRlKFsxNTQsIDBdKS5j
ZW50ZXIoWy0yLCA1OC41XSkucGFyYWxsZWxzKFs1NSwgNjVdKSwgYWxhc2thUG9pbnQsIC8vIEVQ
U0c6MzMzOAogICAgICBoYXdhaWkgPSBjb25pY0VxdWFsQXJlYSgpLnJvdGF0ZShbMTU3LCAwXSku
Y2VudGVyKFstMywgMTkuOV0pLnBhcmFsbGVscyhbOCwgMThdKSwgaGF3YWlpUG9pbnQsIC8vIEVT
Ukk6MTAyMDA3CiAgICAgIHBvaW50LCBwb2ludFN0cmVhbSA9IHtwb2ludDogZnVuY3Rpb24oeCwg
eSkgeyBwb2ludCA9IFt4LCB5XTsgfX07CgogIGZ1bmN0aW9uIGFsYmVyc1VzYShjb29yZGluYXRl
cykgewogICAgdmFyIHggPSBjb29yZGluYXRlc1swXSwgeSA9IGNvb3JkaW5hdGVzWzFdOwogICAg
cmV0dXJuIHBvaW50ID0gbnVsbCwKICAgICAgICAobG93ZXI0OFBvaW50LnBvaW50KHgsIHkpLCBw
b2ludCkKICAgICAgICB8fCAoYWxhc2thUG9pbnQucG9pbnQoeCwgeSksIHBvaW50KQogICAgICAg
IHx8IChoYXdhaWlQb2ludC5wb2ludCh4LCB5KSwgcG9pbnQpOwogIH0KCiAgYWxiZXJzVXNhLmlu
dmVydCA9IGZ1bmN0aW9uKGNvb3JkaW5hdGVzKSB7CiAgICB2YXIgayA9IGxvd2VyNDguc2NhbGUo
KSwKICAgICAgICB0ID0gbG93ZXI0OC50cmFuc2xhdGUoKSwKICAgICAgICB4ID0gKGNvb3JkaW5h
dGVzWzBdIC0gdFswXSkgLyBrLAogICAgICAgIHkgPSAoY29vcmRpbmF0ZXNbMV0gLSB0WzFdKSAv
IGs7CiAgICByZXR1cm4gKHkgPj0gMC4xMjAgJiYgeSA8IDAuMjM0ICYmIHggPj0gLTAuNDI1ICYm
IHggPCAtMC4yMTQgPyBhbGFza2EKICAgICAgICA6IHkgPj0gMC4xNjYgJiYgeSA8IDAuMjM0ICYm
IHggPj0gLTAuMjE0ICYmIHggPCAtMC4xMTUgPyBoYXdhaWkKICAgICAgICA6IGxvd2VyNDgpLmlu
dmVydChjb29yZGluYXRlcyk7CiAgfTsKCiAgYWxiZXJzVXNhLnN0cmVhbSA9IGZ1bmN0aW9uKHN0
cmVhbSkgewogICAgcmV0dXJuIGNhY2hlICYmIGNhY2hlU3RyZWFtID09PSBzdHJlYW0gPyBjYWNo
ZSA6IGNhY2hlID0gbXVsdGlwbGV4KFtsb3dlcjQ4LnN0cmVhbShjYWNoZVN0cmVhbSA9IHN0cmVh
bSksIGFsYXNrYS5zdHJlYW0oc3RyZWFtKSwgaGF3YWlpLnN0cmVhbShzdHJlYW0pXSk7CiAgfTsK
CiAgYWxiZXJzVXNhLnByZWNpc2lvbiA9IGZ1bmN0aW9uKF8pIHsKICAgIGlmICghYXJndW1lbnRz
Lmxlbmd0aCkgcmV0dXJuIGxvd2VyNDgucHJlY2lzaW9uKCk7CiAgICBsb3dlcjQ4LnByZWNpc2lv
bihfKSwgYWxhc2thLnByZWNpc2lvbihfKSwgaGF3YWlpLnByZWNpc2lvbihfKTsKICAgIHJldHVy
biByZXNldCgpOwogIH07CgogIGFsYmVyc1VzYS5zY2FsZSA9IGZ1bmN0aW9uKF8pIHsKICAgIGlm
ICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGxvd2VyNDguc2NhbGUoKTsKICAgIGxvd2VyNDgu
c2NhbGUoXyksIGFsYXNrYS5zY2FsZShfICogMC4zNSksIGhhd2FpaS5zY2FsZShfKTsKICAgIHJl
dHVybiBhbGJlcnNVc2EudHJhbnNsYXRlKGxvd2VyNDgudHJhbnNsYXRlKCkpOwogIH07CgogIGFs
YmVyc1VzYS50cmFuc2xhdGUgPSBmdW5jdGlvbihfKSB7CiAgICBpZiAoIWFyZ3VtZW50cy5sZW5n
dGgpIHJldHVybiBsb3dlcjQ4LnRyYW5zbGF0ZSgpOwogICAgdmFyIGsgPSBsb3dlcjQ4LnNjYWxl
KCksIHggPSArX1swXSwgeSA9ICtfWzFdOwoKICAgIGxvd2VyNDhQb2ludCA9IGxvd2VyNDgKICAg
ICAgICAudHJhbnNsYXRlKF8pCiAgICAgICAgLmNsaXBFeHRlbnQoW1t4IC0gMC40NTUgKiBrLCB5
IC0gMC4yMzggKiBrXSwgW3ggKyAwLjQ1NSAqIGssIHkgKyAwLjIzOCAqIGtdXSkKICAgICAgICAu
c3RyZWFtKHBvaW50U3RyZWFtKTsKCiAgICBhbGFza2FQb2ludCA9IGFsYXNrYQogICAgICAgIC50
cmFuc2xhdGUoW3ggLSAwLjMwNyAqIGssIHkgKyAwLjIwMSAqIGtdKQogICAgICAgIC5jbGlwRXh0
ZW50KFtbeCAtIDAuNDI1ICogayArIGVwc2lsb24kMiwgeSArIDAuMTIwICogayArIGVwc2lsb24k
Ml0sIFt4IC0gMC4yMTQgKiBrIC0gZXBzaWxvbiQyLCB5ICsgMC4yMzQgKiBrIC0gZXBzaWxvbiQy
XV0pCiAgICAgICAgLnN0cmVhbShwb2ludFN0cmVhbSk7CgogICAgaGF3YWlpUG9pbnQgPSBoYXdh
aWkKICAgICAgICAudHJhbnNsYXRlKFt4IC0gMC4yMDUgKiBrLCB5ICsgMC4yMTIgKiBrXSkKICAg
ICAgICAuY2xpcEV4dGVudChbW3ggLSAwLjIxNCAqIGsgKyBlcHNpbG9uJDIsIHkgKyAwLjE2NiAq
IGsgKyBlcHNpbG9uJDJdLCBbeCAtIDAuMTE1ICogayAtIGVwc2lsb24kMiwgeSArIDAuMjM0ICog
ayAtIGVwc2lsb24kMl1dKQogICAgICAgIC5zdHJlYW0ocG9pbnRTdHJlYW0pOwoKICAgIHJldHVy
biByZXNldCgpOwogIH07CgogIGFsYmVyc1VzYS5maXRFeHRlbnQgPSBmdW5jdGlvbihleHRlbnQs
IG9iamVjdCkgewogICAgcmV0dXJuIGZpdEV4dGVudChhbGJlcnNVc2EsIGV4dGVudCwgb2JqZWN0
KTsKICB9OwoKICBhbGJlcnNVc2EuZml0U2l6ZSA9IGZ1bmN0aW9uKHNpemUsIG9iamVjdCkgewog
ICAgcmV0dXJuIGZpdFNpemUoYWxiZXJzVXNhLCBzaXplLCBvYmplY3QpOwogIH07CgogIGFsYmVy
c1VzYS5maXRXaWR0aCA9IGZ1bmN0aW9uKHdpZHRoLCBvYmplY3QpIHsKICAgIHJldHVybiBmaXRX
aWR0aChhbGJlcnNVc2EsIHdpZHRoLCBvYmplY3QpOwogIH07CgogIGFsYmVyc1VzYS5maXRIZWln
aHQgPSBmdW5jdGlvbihoZWlnaHQsIG9iamVjdCkgewogICAgcmV0dXJuIGZpdEhlaWdodChhbGJl
cnNVc2EsIGhlaWdodCwgb2JqZWN0KTsKICB9OwoKICBmdW5jdGlvbiByZXNldCgpIHsKICAgIGNh
Y2hlID0gY2FjaGVTdHJlYW0gPSBudWxsOwogICAgcmV0dXJuIGFsYmVyc1VzYTsKICB9CgogIHJl
dHVybiBhbGJlcnNVc2Euc2NhbGUoMTA3MCk7Cn0KCmZ1bmN0aW9uIGF6aW11dGhhbFJhdyhzY2Fs
ZSkgewogIHJldHVybiBmdW5jdGlvbih4LCB5KSB7CiAgICB2YXIgY3ggPSBjb3MkMSh4KSwKICAg
ICAgICBjeSA9IGNvcyQxKHkpLAogICAgICAgIGsgPSBzY2FsZShjeCAqIGN5KTsKICAgIHJldHVy
biBbCiAgICAgIGsgKiBjeSAqIHNpbiQxKHgpLAogICAgICBrICogc2luJDEoeSkKICAgIF07CiAg
fQp9CgpmdW5jdGlvbiBhemltdXRoYWxJbnZlcnQoYW5nbGUpIHsKICByZXR1cm4gZnVuY3Rpb24o
eCwgeSkgewogICAgdmFyIHogPSBzcXJ0KHggKiB4ICsgeSAqIHkpLAogICAgICAgIGMgPSBhbmds
ZSh6KSwKICAgICAgICBzYyA9IHNpbiQxKGMpLAogICAgICAgIGNjID0gY29zJDEoYyk7CiAgICBy
ZXR1cm4gWwogICAgICBhdGFuMih4ICogc2MsIHogKiBjYyksCiAgICAgIGFzaW4oeiAmJiB5ICog
c2MgLyB6KQogICAgXTsKICB9Cn0KCnZhciBhemltdXRoYWxFcXVhbEFyZWFSYXcgPSBhemltdXRo
YWxSYXcoZnVuY3Rpb24oY3hjeSkgewogIHJldHVybiBzcXJ0KDIgLyAoMSArIGN4Y3kpKTsKfSk7
CgphemltdXRoYWxFcXVhbEFyZWFSYXcuaW52ZXJ0ID0gYXppbXV0aGFsSW52ZXJ0KGZ1bmN0aW9u
KHopIHsKICByZXR1cm4gMiAqIGFzaW4oeiAvIDIpOwp9KTsKCmZ1bmN0aW9uIGF6aW11dGhhbEVx
dWFsQXJlYSgpIHsKICByZXR1cm4gcHJvamVjdGlvbihhemltdXRoYWxFcXVhbEFyZWFSYXcpCiAg
ICAgIC5zY2FsZSgxMjQuNzUpCiAgICAgIC5jbGlwQW5nbGUoMTgwIC0gMWUtMyk7Cn0KCnZhciBh
emltdXRoYWxFcXVpZGlzdGFudFJhdyA9IGF6aW11dGhhbFJhdyhmdW5jdGlvbihjKSB7CiAgcmV0
dXJuIChjID0gYWNvcyhjKSkgJiYgYyAvIHNpbiQxKGMpOwp9KTsKCmF6aW11dGhhbEVxdWlkaXN0
YW50UmF3LmludmVydCA9IGF6aW11dGhhbEludmVydChmdW5jdGlvbih6KSB7CiAgcmV0dXJuIHo7
Cn0pOwoKZnVuY3Rpb24gYXppbXV0aGFsRXF1aWRpc3RhbnQoKSB7CiAgcmV0dXJuIHByb2plY3Rp
b24oYXppbXV0aGFsRXF1aWRpc3RhbnRSYXcpCiAgICAgIC5zY2FsZSg3OS40MTg4KQogICAgICAu
Y2xpcEFuZ2xlKDE4MCAtIDFlLTMpOwp9CgpmdW5jdGlvbiBtZXJjYXRvclJhdyhsYW1iZGEsIHBo
aSkgewogIHJldHVybiBbbGFtYmRhLCBsb2codGFuKChoYWxmUGkkMiArIHBoaSkgLyAyKSldOwp9
CgptZXJjYXRvclJhdy5pbnZlcnQgPSBmdW5jdGlvbih4LCB5KSB7CiAgcmV0dXJuIFt4LCAyICog
YXRhbihleHAoeSkpIC0gaGFsZlBpJDJdOwp9OwoKZnVuY3Rpb24gbWVyY2F0b3IoKSB7CiAgcmV0
dXJuIG1lcmNhdG9yUHJvamVjdGlvbihtZXJjYXRvclJhdykKICAgICAgLnNjYWxlKDk2MSAvIHRh
dSQzKTsKfQoKZnVuY3Rpb24gbWVyY2F0b3JQcm9qZWN0aW9uKHByb2plY3QpIHsKICB2YXIgbSA9
IHByb2plY3Rpb24ocHJvamVjdCksCiAgICAgIGNlbnRlciA9IG0uY2VudGVyLAogICAgICBzY2Fs
ZSA9IG0uc2NhbGUsCiAgICAgIHRyYW5zbGF0ZSA9IG0udHJhbnNsYXRlLAogICAgICBjbGlwRXh0
ZW50ID0gbS5jbGlwRXh0ZW50LAogICAgICB4MCA9IG51bGwsIHkwLCB4MSwgeTE7IC8vIGNsaXAg
ZXh0ZW50CgogIG0uc2NhbGUgPSBmdW5jdGlvbihfKSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxl
bmd0aCA/IChzY2FsZShfKSwgcmVjbGlwKCkpIDogc2NhbGUoKTsKICB9OwoKICBtLnRyYW5zbGF0
ZSA9IGZ1bmN0aW9uKF8pIHsKICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHRyYW5zbGF0
ZShfKSwgcmVjbGlwKCkpIDogdHJhbnNsYXRlKCk7CiAgfTsKCiAgbS5jZW50ZXIgPSBmdW5jdGlv
bihfKSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChjZW50ZXIoXyksIHJlY2xpcCgp
KSA6IGNlbnRlcigpOwogIH07CgogIG0uY2xpcEV4dGVudCA9IGZ1bmN0aW9uKF8pIHsKICAgIHJl
dHVybiBhcmd1bWVudHMubGVuZ3RoID8gKChfID09IG51bGwgPyB4MCA9IHkwID0geDEgPSB5MSA9
IG51bGwgOiAoeDAgPSArX1swXVswXSwgeTAgPSArX1swXVsxXSwgeDEgPSArX1sxXVswXSwgeTEg
PSArX1sxXVsxXSkpLCByZWNsaXAoKSkgOiB4MCA9PSBudWxsID8gbnVsbCA6IFtbeDAsIHkwXSwg
W3gxLCB5MV1dOwogIH07CgogIGZ1bmN0aW9uIHJlY2xpcCgpIHsKICAgIHZhciBrID0gcGkkMyAq
IHNjYWxlKCksCiAgICAgICAgdCA9IG0ocm90YXRpb24obS5yb3RhdGUoKSkuaW52ZXJ0KFswLCAw
XSkpOwogICAgcmV0dXJuIGNsaXBFeHRlbnQoeDAgPT0gbnVsbAogICAgICAgID8gW1t0WzBdIC0g
aywgdFsxXSAtIGtdLCBbdFswXSArIGssIHRbMV0gKyBrXV0gOiBwcm9qZWN0ID09PSBtZXJjYXRv
clJhdwogICAgICAgID8gW1tNYXRoLm1heCh0WzBdIC0gaywgeDApLCB5MF0sIFtNYXRoLm1pbih0
WzBdICsgaywgeDEpLCB5MV1dCiAgICAgICAgOiBbW3gwLCBNYXRoLm1heCh0WzFdIC0gaywgeTAp
XSwgW3gxLCBNYXRoLm1pbih0WzFdICsgaywgeTEpXV0pOwogIH0KCiAgcmV0dXJuIHJlY2xpcCgp
Owp9CgpmdW5jdGlvbiB0YW55KHkpIHsKICByZXR1cm4gdGFuKChoYWxmUGkkMiArIHkpIC8gMik7
Cn0KCmZ1bmN0aW9uIGNvbmljQ29uZm9ybWFsUmF3KHkwLCB5MSkgewogIHZhciBjeTAgPSBjb3Mk
MSh5MCksCiAgICAgIG4gPSB5MCA9PT0geTEgPyBzaW4kMSh5MCkgOiBsb2coY3kwIC8gY29zJDEo
eTEpKSAvIGxvZyh0YW55KHkxKSAvIHRhbnkoeTApKSwKICAgICAgZiA9IGN5MCAqIHBvdyh0YW55
KHkwKSwgbikgLyBuOwoKICBpZiAoIW4pIHJldHVybiBtZXJjYXRvclJhdzsKCiAgZnVuY3Rpb24g
cHJvamVjdCh4LCB5KSB7CiAgICBpZiAoZiA+IDApIHsgaWYgKHkgPCAtaGFsZlBpJDIgKyBlcHNp
bG9uJDIpIHkgPSAtaGFsZlBpJDIgKyBlcHNpbG9uJDI7IH0KICAgIGVsc2UgeyBpZiAoeSA+IGhh
bGZQaSQyIC0gZXBzaWxvbiQyKSB5ID0gaGFsZlBpJDIgLSBlcHNpbG9uJDI7IH0KICAgIHZhciBy
ID0gZiAvIHBvdyh0YW55KHkpLCBuKTsKICAgIHJldHVybiBbciAqIHNpbiQxKG4gKiB4KSwgZiAt
IHIgKiBjb3MkMShuICogeCldOwogIH0KCiAgcHJvamVjdC5pbnZlcnQgPSBmdW5jdGlvbih4LCB5
KSB7CiAgICB2YXIgZnkgPSBmIC0geSwgciA9IHNpZ24obikgKiBzcXJ0KHggKiB4ICsgZnkgKiBm
eSksCiAgICAgIGwgPSBhdGFuMih4LCBhYnMoZnkpKSAqIHNpZ24oZnkpOwogICAgaWYgKGZ5ICog
biA8IDApCiAgICAgIGwgLT0gcGkkMyAqIHNpZ24oeCkgKiBzaWduKGZ5KTsKICAgIHJldHVybiBb
bCAvIG4sIDIgKiBhdGFuKHBvdyhmIC8gciwgMSAvIG4pKSAtIGhhbGZQaSQyXTsKICB9OwoKICBy
ZXR1cm4gcHJvamVjdDsKfQoKZnVuY3Rpb24gY29uaWNDb25mb3JtYWwoKSB7CiAgcmV0dXJuIGNv
bmljUHJvamVjdGlvbihjb25pY0NvbmZvcm1hbFJhdykKICAgICAgLnNjYWxlKDEwOS41KQogICAg
ICAucGFyYWxsZWxzKFszMCwgMzBdKTsKfQoKZnVuY3Rpb24gZXF1aXJlY3Rhbmd1bGFyUmF3KGxh
bWJkYSwgcGhpKSB7CiAgcmV0dXJuIFtsYW1iZGEsIHBoaV07Cn0KCmVxdWlyZWN0YW5ndWxhclJh
dy5pbnZlcnQgPSBlcXVpcmVjdGFuZ3VsYXJSYXc7CgpmdW5jdGlvbiBlcXVpcmVjdGFuZ3VsYXIo
KSB7CiAgcmV0dXJuIHByb2plY3Rpb24oZXF1aXJlY3Rhbmd1bGFyUmF3KQogICAgICAuc2NhbGUo
MTUyLjYzKTsKfQoKZnVuY3Rpb24gY29uaWNFcXVpZGlzdGFudFJhdyh5MCwgeTEpIHsKICB2YXIg
Y3kwID0gY29zJDEoeTApLAogICAgICBuID0geTAgPT09IHkxID8gc2luJDEoeTApIDogKGN5MCAt
IGNvcyQxKHkxKSkgLyAoeTEgLSB5MCksCiAgICAgIGcgPSBjeTAgLyBuICsgeTA7CgogIGlmIChh
YnMobikgPCBlcHNpbG9uJDIpIHJldHVybiBlcXVpcmVjdGFuZ3VsYXJSYXc7CgogIGZ1bmN0aW9u
IHByb2plY3QoeCwgeSkgewogICAgdmFyIGd5ID0gZyAtIHksIG54ID0gbiAqIHg7CiAgICByZXR1
cm4gW2d5ICogc2luJDEobngpLCBnIC0gZ3kgKiBjb3MkMShueCldOwogIH0KCiAgcHJvamVjdC5p
bnZlcnQgPSBmdW5jdGlvbih4LCB5KSB7CiAgICB2YXIgZ3kgPSBnIC0geSwKICAgICAgICBsID0g
YXRhbjIoeCwgYWJzKGd5KSkgKiBzaWduKGd5KTsKICAgIGlmIChneSAqIG4gPCAwKQogICAgICBs
IC09IHBpJDMgKiBzaWduKHgpICogc2lnbihneSk7CiAgICByZXR1cm4gW2wgLyBuLCBnIC0gc2ln
bihuKSAqIHNxcnQoeCAqIHggKyBneSAqIGd5KV07CiAgfTsKCiAgcmV0dXJuIHByb2plY3Q7Cn0K
CmZ1bmN0aW9uIGNvbmljRXF1aWRpc3RhbnQoKSB7CiAgcmV0dXJuIGNvbmljUHJvamVjdGlvbihj
b25pY0VxdWlkaXN0YW50UmF3KQogICAgICAuc2NhbGUoMTMxLjE1NCkKICAgICAgLmNlbnRlcihb
MCwgMTMuOTM4OV0pOwp9Cgp2YXIgQTEgPSAxLjM0MDI2NCwKICAgIEEyID0gLTAuMDgxMTA2LAog
ICAgQTMgPSAwLjAwMDg5MywKICAgIEE0ID0gMC4wMDM3OTYsCiAgICBNID0gc3FydCgzKSAvIDIs
CiAgICBpdGVyYXRpb25zID0gMTI7CgpmdW5jdGlvbiBlcXVhbEVhcnRoUmF3KGxhbWJkYSwgcGhp
KSB7CiAgdmFyIGwgPSBhc2luKE0gKiBzaW4kMShwaGkpKSwgbDIgPSBsICogbCwgbDYgPSBsMiAq
IGwyICogbDI7CiAgcmV0dXJuIFsKICAgIGxhbWJkYSAqIGNvcyQxKGwpIC8gKE0gKiAoQTEgKyAz
ICogQTIgKiBsMiArIGw2ICogKDcgKiBBMyArIDkgKiBBNCAqIGwyKSkpLAogICAgbCAqIChBMSAr
IEEyICogbDIgKyBsNiAqIChBMyArIEE0ICogbDIpKQogIF07Cn0KCmVxdWFsRWFydGhSYXcuaW52
ZXJ0ID0gZnVuY3Rpb24oeCwgeSkgewogIHZhciBsID0geSwgbDIgPSBsICogbCwgbDYgPSBsMiAq
IGwyICogbDI7CiAgZm9yICh2YXIgaSA9IDAsIGRlbHRhLCBmeSwgZnB5OyBpIDwgaXRlcmF0aW9u
czsgKytpKSB7CiAgICBmeSA9IGwgKiAoQTEgKyBBMiAqIGwyICsgbDYgKiAoQTMgKyBBNCAqIGwy
KSkgLSB5OwogICAgZnB5ID0gQTEgKyAzICogQTIgKiBsMiArIGw2ICogKDcgKiBBMyArIDkgKiBB
NCAqIGwyKTsKICAgIGwgLT0gZGVsdGEgPSBmeSAvIGZweSwgbDIgPSBsICogbCwgbDYgPSBsMiAq
IGwyICogbDI7CiAgICBpZiAoYWJzKGRlbHRhKSA8IGVwc2lsb24yJDEpIGJyZWFrOwogIH0KICBy
ZXR1cm4gWwogICAgTSAqIHggKiAoQTEgKyAzICogQTIgKiBsMiArIGw2ICogKDcgKiBBMyArIDkg
KiBBNCAqIGwyKSkgLyBjb3MkMShsKSwKICAgIGFzaW4oc2luJDEobCkgLyBNKQogIF07Cn07Cgpm
dW5jdGlvbiBlcXVhbEVhcnRoKCkgewogIHJldHVybiBwcm9qZWN0aW9uKGVxdWFsRWFydGhSYXcp
CiAgICAgIC5zY2FsZSgxNzcuMTU4KTsKfQoKZnVuY3Rpb24gZ25vbW9uaWNSYXcoeCwgeSkgewog
IHZhciBjeSA9IGNvcyQxKHkpLCBrID0gY29zJDEoeCkgKiBjeTsKICByZXR1cm4gW2N5ICogc2lu
JDEoeCkgLyBrLCBzaW4kMSh5KSAvIGtdOwp9Cgpnbm9tb25pY1Jhdy5pbnZlcnQgPSBhemltdXRo
YWxJbnZlcnQoYXRhbik7CgpmdW5jdGlvbiBnbm9tb25pYygpIHsKICByZXR1cm4gcHJvamVjdGlv
bihnbm9tb25pY1JhdykKICAgICAgLnNjYWxlKDE0NC4wNDkpCiAgICAgIC5jbGlwQW5nbGUoNjAp
Owp9CgpmdW5jdGlvbiBpZGVudGl0eSQ1KCkgewogIHZhciBrID0gMSwgdHggPSAwLCB0eSA9IDAs
IHN4ID0gMSwgc3kgPSAxLCAvLyBzY2FsZSwgdHJhbnNsYXRlIGFuZCByZWZsZWN0CiAgICAgIGFs
cGhhID0gMCwgY2EsIHNhLCAvLyBhbmdsZQogICAgICB4MCA9IG51bGwsIHkwLCB4MSwgeTEsIC8v
IGNsaXAgZXh0ZW50CiAgICAgIGt4ID0gMSwga3kgPSAxLAogICAgICB0cmFuc2Zvcm0gPSB0cmFu
c2Zvcm1lcih7CiAgICAgICAgcG9pbnQ6IGZ1bmN0aW9uKHgsIHkpIHsKICAgICAgICAgIHZhciBw
ID0gcHJvamVjdGlvbihbeCwgeV0pOwogICAgICAgICAgdGhpcy5zdHJlYW0ucG9pbnQocFswXSwg
cFsxXSk7CiAgICAgICAgfQogICAgICB9KSwKICAgICAgcG9zdGNsaXAgPSBpZGVudGl0eSQ0LAog
ICAgICBjYWNoZSwKICAgICAgY2FjaGVTdHJlYW07CgogIGZ1bmN0aW9uIHJlc2V0KCkgewogICAg
a3ggPSBrICogc3g7CiAgICBreSA9IGsgKiBzeTsKICAgIGNhY2hlID0gY2FjaGVTdHJlYW0gPSBu
dWxsOwogICAgcmV0dXJuIHByb2plY3Rpb247CiAgfQoKICBmdW5jdGlvbiBwcm9qZWN0aW9uIChw
KSB7CiAgICB2YXIgeCA9IHBbMF0gKiBreCwgeSA9IHBbMV0gKiBreTsKICAgIGlmIChhbHBoYSkg
ewogICAgICB2YXIgdCA9IHkgKiBjYSAtIHggKiBzYTsKICAgICAgeCA9IHggKiBjYSArIHkgKiBz
YTsKICAgICAgeSA9IHQ7CiAgICB9ICAgIAogICAgcmV0dXJuIFt4ICsgdHgsIHkgKyB0eV07CiAg
fQogIHByb2plY3Rpb24uaW52ZXJ0ID0gZnVuY3Rpb24ocCkgewogICAgdmFyIHggPSBwWzBdIC0g
dHgsIHkgPSBwWzFdIC0gdHk7CiAgICBpZiAoYWxwaGEpIHsKICAgICAgdmFyIHQgPSB5ICogY2Eg
KyB4ICogc2E7CiAgICAgIHggPSB4ICogY2EgLSB5ICogc2E7CiAgICAgIHkgPSB0OwogICAgfQog
ICAgcmV0dXJuIFt4IC8ga3gsIHkgLyBreV07CiAgfTsKICBwcm9qZWN0aW9uLnN0cmVhbSA9IGZ1
bmN0aW9uKHN0cmVhbSkgewogICAgcmV0dXJuIGNhY2hlICYmIGNhY2hlU3RyZWFtID09PSBzdHJl
YW0gPyBjYWNoZSA6IGNhY2hlID0gdHJhbnNmb3JtKHBvc3RjbGlwKGNhY2hlU3RyZWFtID0gc3Ry
ZWFtKSk7CiAgfTsKICBwcm9qZWN0aW9uLnBvc3RjbGlwID0gZnVuY3Rpb24oXykgewogICAgcmV0
dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAocG9zdGNsaXAgPSBfLCB4MCA9IHkwID0geDEgPSB5MSA9
IG51bGwsIHJlc2V0KCkpIDogcG9zdGNsaXA7CiAgfTsKICBwcm9qZWN0aW9uLmNsaXBFeHRlbnQg
PSBmdW5jdGlvbihfKSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChwb3N0Y2xpcCA9
IF8gPT0gbnVsbCA/ICh4MCA9IHkwID0geDEgPSB5MSA9IG51bGwsIGlkZW50aXR5JDQpIDogY2xp
cFJlY3RhbmdsZSh4MCA9ICtfWzBdWzBdLCB5MCA9ICtfWzBdWzFdLCB4MSA9ICtfWzFdWzBdLCB5
MSA9ICtfWzFdWzFdKSwgcmVzZXQoKSkgOiB4MCA9PSBudWxsID8gbnVsbCA6IFtbeDAsIHkwXSwg
W3gxLCB5MV1dOwogIH07CiAgcHJvamVjdGlvbi5zY2FsZSA9IGZ1bmN0aW9uKF8pIHsKICAgIHJl
dHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGsgPSArXywgcmVzZXQoKSkgOiBrOwogIH07CiAgcHJv
amVjdGlvbi50cmFuc2xhdGUgPSBmdW5jdGlvbihfKSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxl
bmd0aCA/ICh0eCA9ICtfWzBdLCB0eSA9ICtfWzFdLCByZXNldCgpKSA6IFt0eCwgdHldOwogIH07
CiAgcHJvamVjdGlvbi5hbmdsZSA9IGZ1bmN0aW9uKF8pIHsKICAgIHJldHVybiBhcmd1bWVudHMu
bGVuZ3RoID8gKGFscGhhID0gXyAlIDM2MCAqIHJhZGlhbnMsIHNhID0gc2luJDEoYWxwaGEpLCBj
YSA9IGNvcyQxKGFscGhhKSwgcmVzZXQoKSkgOiBhbHBoYSAqIGRlZ3JlZXMkMTsKICB9OwogIHBy
b2plY3Rpb24ucmVmbGVjdFggPSBmdW5jdGlvbihfKSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxl
bmd0aCA/IChzeCA9IF8gPyAtMSA6IDEsIHJlc2V0KCkpIDogc3ggPCAwOwogIH07CiAgcHJvamVj
dGlvbi5yZWZsZWN0WSA9IGZ1bmN0aW9uKF8pIHsKICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3Ro
ID8gKHN5ID0gXyA/IC0xIDogMSwgcmVzZXQoKSkgOiBzeSA8IDA7CiAgfTsKICBwcm9qZWN0aW9u
LmZpdEV4dGVudCA9IGZ1bmN0aW9uKGV4dGVudCwgb2JqZWN0KSB7CiAgICByZXR1cm4gZml0RXh0
ZW50KHByb2plY3Rpb24sIGV4dGVudCwgb2JqZWN0KTsKICB9OwogIHByb2plY3Rpb24uZml0U2l6
ZSA9IGZ1bmN0aW9uKHNpemUsIG9iamVjdCkgewogICAgcmV0dXJuIGZpdFNpemUocHJvamVjdGlv
biwgc2l6ZSwgb2JqZWN0KTsKICB9OwogIHByb2plY3Rpb24uZml0V2lkdGggPSBmdW5jdGlvbih3
aWR0aCwgb2JqZWN0KSB7CiAgICByZXR1cm4gZml0V2lkdGgocHJvamVjdGlvbiwgd2lkdGgsIG9i
amVjdCk7CiAgfTsKICBwcm9qZWN0aW9uLmZpdEhlaWdodCA9IGZ1bmN0aW9uKGhlaWdodCwgb2Jq
ZWN0KSB7CiAgICByZXR1cm4gZml0SGVpZ2h0KHByb2plY3Rpb24sIGhlaWdodCwgb2JqZWN0KTsK
ICB9OwoKICByZXR1cm4gcHJvamVjdGlvbjsKfQoKZnVuY3Rpb24gbmF0dXJhbEVhcnRoMVJhdyhs
YW1iZGEsIHBoaSkgewogIHZhciBwaGkyID0gcGhpICogcGhpLCBwaGk0ID0gcGhpMiAqIHBoaTI7
CiAgcmV0dXJuIFsKICAgIGxhbWJkYSAqICgwLjg3MDcgLSAwLjEzMTk3OSAqIHBoaTIgKyBwaGk0
ICogKC0wLjAxMzc5MSArIHBoaTQgKiAoMC4wMDM5NzEgKiBwaGkyIC0gMC4wMDE1MjkgKiBwaGk0
KSkpLAogICAgcGhpICogKDEuMDA3MjI2ICsgcGhpMiAqICgwLjAxNTA4NSArIHBoaTQgKiAoLTAu
MDQ0NDc1ICsgMC4wMjg4NzQgKiBwaGkyIC0gMC4wMDU5MTYgKiBwaGk0KSkpCiAgXTsKfQoKbmF0
dXJhbEVhcnRoMVJhdy5pbnZlcnQgPSBmdW5jdGlvbih4LCB5KSB7CiAgdmFyIHBoaSA9IHksIGkg
PSAyNSwgZGVsdGE7CiAgZG8gewogICAgdmFyIHBoaTIgPSBwaGkgKiBwaGksIHBoaTQgPSBwaGky
ICogcGhpMjsKICAgIHBoaSAtPSBkZWx0YSA9IChwaGkgKiAoMS4wMDcyMjYgKyBwaGkyICogKDAu
MDE1MDg1ICsgcGhpNCAqICgtMC4wNDQ0NzUgKyAwLjAyODg3NCAqIHBoaTIgLSAwLjAwNTkxNiAq
IHBoaTQpKSkgLSB5KSAvCiAgICAgICAgKDEuMDA3MjI2ICsgcGhpMiAqICgwLjAxNTA4NSAqIDMg
KyBwaGk0ICogKC0wLjA0NDQ3NSAqIDcgKyAwLjAyODg3NCAqIDkgKiBwaGkyIC0gMC4wMDU5MTYg
KiAxMSAqIHBoaTQpKSk7CiAgfSB3aGlsZSAoYWJzKGRlbHRhKSA+IGVwc2lsb24kMiAmJiAtLWkg
PiAwKTsKICByZXR1cm4gWwogICAgeCAvICgwLjg3MDcgKyAocGhpMiA9IHBoaSAqIHBoaSkgKiAo
LTAuMTMxOTc5ICsgcGhpMiAqICgtMC4wMTM3OTEgKyBwaGkyICogcGhpMiAqIHBoaTIgKiAoMC4w
MDM5NzEgLSAwLjAwMTUyOSAqIHBoaTIpKSkpLAogICAgcGhpCiAgXTsKfTsKCmZ1bmN0aW9uIG5h
dHVyYWxFYXJ0aDEoKSB7CiAgcmV0dXJuIHByb2plY3Rpb24obmF0dXJhbEVhcnRoMVJhdykKICAg
ICAgLnNjYWxlKDE3NS4yOTUpOwp9CgpmdW5jdGlvbiBvcnRob2dyYXBoaWNSYXcoeCwgeSkgewog
IHJldHVybiBbY29zJDEoeSkgKiBzaW4kMSh4KSwgc2luJDEoeSldOwp9CgpvcnRob2dyYXBoaWNS
YXcuaW52ZXJ0ID0gYXppbXV0aGFsSW52ZXJ0KGFzaW4pOwoKZnVuY3Rpb24gb3J0aG9ncmFwaGlj
KCkgewogIHJldHVybiBwcm9qZWN0aW9uKG9ydGhvZ3JhcGhpY1JhdykKICAgICAgLnNjYWxlKDI0
OS41KQogICAgICAuY2xpcEFuZ2xlKDkwICsgZXBzaWxvbiQyKTsKfQoKZnVuY3Rpb24gc3RlcmVv
Z3JhcGhpY1Jhdyh4LCB5KSB7CiAgdmFyIGN5ID0gY29zJDEoeSksIGsgPSAxICsgY29zJDEoeCkg
KiBjeTsKICByZXR1cm4gW2N5ICogc2luJDEoeCkgLyBrLCBzaW4kMSh5KSAvIGtdOwp9CgpzdGVy
ZW9ncmFwaGljUmF3LmludmVydCA9IGF6aW11dGhhbEludmVydChmdW5jdGlvbih6KSB7CiAgcmV0
dXJuIDIgKiBhdGFuKHopOwp9KTsKCmZ1bmN0aW9uIHN0ZXJlb2dyYXBoaWMoKSB7CiAgcmV0dXJu
IHByb2plY3Rpb24oc3RlcmVvZ3JhcGhpY1JhdykKICAgICAgLnNjYWxlKDI1MCkKICAgICAgLmNs
aXBBbmdsZSgxNDIpOwp9CgpmdW5jdGlvbiB0cmFuc3ZlcnNlTWVyY2F0b3JSYXcobGFtYmRhLCBw
aGkpIHsKICByZXR1cm4gW2xvZyh0YW4oKGhhbGZQaSQyICsgcGhpKSAvIDIpKSwgLWxhbWJkYV07
Cn0KCnRyYW5zdmVyc2VNZXJjYXRvclJhdy5pbnZlcnQgPSBmdW5jdGlvbih4LCB5KSB7CiAgcmV0
dXJuIFsteSwgMiAqIGF0YW4oZXhwKHgpKSAtIGhhbGZQaSQyXTsKfTsKCmZ1bmN0aW9uIHRyYW5z
dmVyc2VNZXJjYXRvcigpIHsKICB2YXIgbSA9IG1lcmNhdG9yUHJvamVjdGlvbih0cmFuc3ZlcnNl
TWVyY2F0b3JSYXcpLAogICAgICBjZW50ZXIgPSBtLmNlbnRlciwKICAgICAgcm90YXRlID0gbS5y
b3RhdGU7CgogIG0uY2VudGVyID0gZnVuY3Rpb24oXykgewogICAgcmV0dXJuIGFyZ3VtZW50cy5s
ZW5ndGggPyBjZW50ZXIoWy1fWzFdLCBfWzBdXSkgOiAoXyA9IGNlbnRlcigpLCBbX1sxXSwgLV9b
MF1dKTsKICB9OwoKICBtLnJvdGF0ZSA9IGZ1bmN0aW9uKF8pIHsKICAgIHJldHVybiBhcmd1bWVu
dHMubGVuZ3RoID8gcm90YXRlKFtfWzBdLCBfWzFdLCBfLmxlbmd0aCA+IDIgPyBfWzJdICsgOTAg
OiA5MF0pIDogKF8gPSByb3RhdGUoKSwgW19bMF0sIF9bMV0sIF9bMl0gLSA5MF0pOwogIH07Cgog
IHJldHVybiByb3RhdGUoWzAsIDAsIDkwXSkKICAgICAgLnNjYWxlKDE1OS4xNTUpOwp9CgpmdW5j
dGlvbiBkZWZhdWx0U2VwYXJhdGlvbihhLCBiKSB7CiAgcmV0dXJuIGEucGFyZW50ID09PSBiLnBh
cmVudCA/IDEgOiAyOwp9CgpmdW5jdGlvbiBtZWFuWChjaGlsZHJlbikgewogIHJldHVybiBjaGls
ZHJlbi5yZWR1Y2UobWVhblhSZWR1Y2UsIDApIC8gY2hpbGRyZW4ubGVuZ3RoOwp9CgpmdW5jdGlv
biBtZWFuWFJlZHVjZSh4LCBjKSB7CiAgcmV0dXJuIHggKyBjLng7Cn0KCmZ1bmN0aW9uIG1heFko
Y2hpbGRyZW4pIHsKICByZXR1cm4gMSArIGNoaWxkcmVuLnJlZHVjZShtYXhZUmVkdWNlLCAwKTsK
fQoKZnVuY3Rpb24gbWF4WVJlZHVjZSh5LCBjKSB7CiAgcmV0dXJuIE1hdGgubWF4KHksIGMueSk7
Cn0KCmZ1bmN0aW9uIGxlYWZMZWZ0KG5vZGUpIHsKICB2YXIgY2hpbGRyZW47CiAgd2hpbGUgKGNo
aWxkcmVuID0gbm9kZS5jaGlsZHJlbikgbm9kZSA9IGNoaWxkcmVuWzBdOwogIHJldHVybiBub2Rl
Owp9CgpmdW5jdGlvbiBsZWFmUmlnaHQobm9kZSkgewogIHZhciBjaGlsZHJlbjsKICB3aGlsZSAo
Y2hpbGRyZW4gPSBub2RlLmNoaWxkcmVuKSBub2RlID0gY2hpbGRyZW5bY2hpbGRyZW4ubGVuZ3Ro
IC0gMV07CiAgcmV0dXJuIG5vZGU7Cn0KCmZ1bmN0aW9uIGNsdXN0ZXIoKSB7CiAgdmFyIHNlcGFy
YXRpb24gPSBkZWZhdWx0U2VwYXJhdGlvbiwKICAgICAgZHggPSAxLAogICAgICBkeSA9IDEsCiAg
ICAgIG5vZGVTaXplID0gZmFsc2U7CgogIGZ1bmN0aW9uIGNsdXN0ZXIocm9vdCkgewogICAgdmFy
IHByZXZpb3VzTm9kZSwKICAgICAgICB4ID0gMDsKCiAgICAvLyBGaXJzdCB3YWxrLCBjb21wdXRp
bmcgdGhlIGluaXRpYWwgeCAmIHkgdmFsdWVzLgogICAgcm9vdC5lYWNoQWZ0ZXIoZnVuY3Rpb24o
bm9kZSkgewogICAgICB2YXIgY2hpbGRyZW4gPSBub2RlLmNoaWxkcmVuOwogICAgICBpZiAoY2hp
bGRyZW4pIHsKICAgICAgICBub2RlLnggPSBtZWFuWChjaGlsZHJlbik7CiAgICAgICAgbm9kZS55
ID0gbWF4WShjaGlsZHJlbik7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgbm9kZS54ID0gcHJldmlv
dXNOb2RlID8geCArPSBzZXBhcmF0aW9uKG5vZGUsIHByZXZpb3VzTm9kZSkgOiAwOwogICAgICAg
IG5vZGUueSA9IDA7CiAgICAgICAgcHJldmlvdXNOb2RlID0gbm9kZTsKICAgICAgfQogICAgfSk7
CgogICAgdmFyIGxlZnQgPSBsZWFmTGVmdChyb290KSwKICAgICAgICByaWdodCA9IGxlYWZSaWdo
dChyb290KSwKICAgICAgICB4MCA9IGxlZnQueCAtIHNlcGFyYXRpb24obGVmdCwgcmlnaHQpIC8g
MiwKICAgICAgICB4MSA9IHJpZ2h0LnggKyBzZXBhcmF0aW9uKHJpZ2h0LCBsZWZ0KSAvIDI7Cgog
ICAgLy8gU2Vjb25kIHdhbGssIG5vcm1hbGl6aW5nIHggJiB5IHRvIHRoZSBkZXNpcmVkIHNpemUu
CiAgICByZXR1cm4gcm9vdC5lYWNoQWZ0ZXIobm9kZVNpemUgPyBmdW5jdGlvbihub2RlKSB7CiAg
ICAgIG5vZGUueCA9IChub2RlLnggLSByb290LngpICogZHg7CiAgICAgIG5vZGUueSA9IChyb290
LnkgLSBub2RlLnkpICogZHk7CiAgICB9IDogZnVuY3Rpb24obm9kZSkgewogICAgICBub2RlLngg
PSAobm9kZS54IC0geDApIC8gKHgxIC0geDApICogZHg7CiAgICAgIG5vZGUueSA9ICgxIC0gKHJv
b3QueSA/IG5vZGUueSAvIHJvb3QueSA6IDEpKSAqIGR5OwogICAgfSk7CiAgfQoKICBjbHVzdGVy
LnNlcGFyYXRpb24gPSBmdW5jdGlvbih4KSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/
IChzZXBhcmF0aW9uID0geCwgY2x1c3RlcikgOiBzZXBhcmF0aW9uOwogIH07CgogIGNsdXN0ZXIu
c2l6ZSA9IGZ1bmN0aW9uKHgpIHsKICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKG5vZGVT
aXplID0gZmFsc2UsIGR4ID0gK3hbMF0sIGR5ID0gK3hbMV0sIGNsdXN0ZXIpIDogKG5vZGVTaXpl
ID8gbnVsbCA6IFtkeCwgZHldKTsKICB9OwoKICBjbHVzdGVyLm5vZGVTaXplID0gZnVuY3Rpb24o
eCkgewogICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAobm9kZVNpemUgPSB0cnVlLCBkeCA9
ICt4WzBdLCBkeSA9ICt4WzFdLCBjbHVzdGVyKSA6IChub2RlU2l6ZSA/IFtkeCwgZHldIDogbnVs
bCk7CiAgfTsKCiAgcmV0dXJuIGNsdXN0ZXI7Cn0KCmZ1bmN0aW9uIGNvdW50KG5vZGUpIHsKICB2
YXIgc3VtID0gMCwKICAgICAgY2hpbGRyZW4gPSBub2RlLmNoaWxkcmVuLAogICAgICBpID0gY2hp
bGRyZW4gJiYgY2hpbGRyZW4ubGVuZ3RoOwogIGlmICghaSkgc3VtID0gMTsKICBlbHNlIHdoaWxl
ICgtLWkgPj0gMCkgc3VtICs9IGNoaWxkcmVuW2ldLnZhbHVlOwogIG5vZGUudmFsdWUgPSBzdW07
Cn0KCmZ1bmN0aW9uIG5vZGVfY291bnQoKSB7CiAgcmV0dXJuIHRoaXMuZWFjaEFmdGVyKGNvdW50
KTsKfQoKZnVuY3Rpb24gbm9kZV9lYWNoKGNhbGxiYWNrKSB7CiAgdmFyIG5vZGUgPSB0aGlzLCBj
dXJyZW50LCBuZXh0ID0gW25vZGVdLCBjaGlsZHJlbiwgaSwgbjsKICBkbyB7CiAgICBjdXJyZW50
ID0gbmV4dC5yZXZlcnNlKCksIG5leHQgPSBbXTsKICAgIHdoaWxlIChub2RlID0gY3VycmVudC5w
b3AoKSkgewogICAgICBjYWxsYmFjayhub2RlKSwgY2hpbGRyZW4gPSBub2RlLmNoaWxkcmVuOwog
ICAgICBpZiAoY2hpbGRyZW4pIGZvciAoaSA9IDAsIG4gPSBjaGlsZHJlbi5sZW5ndGg7IGkgPCBu
OyArK2kpIHsKICAgICAgICBuZXh0LnB1c2goY2hpbGRyZW5baV0pOwogICAgICB9CiAgICB9CiAg
fSB3aGlsZSAobmV4dC5sZW5ndGgpOwogIHJldHVybiB0aGlzOwp9CgpmdW5jdGlvbiBub2RlX2Vh
Y2hCZWZvcmUoY2FsbGJhY2spIHsKICB2YXIgbm9kZSA9IHRoaXMsIG5vZGVzID0gW25vZGVdLCBj
aGlsZHJlbiwgaTsKICB3aGlsZSAobm9kZSA9IG5vZGVzLnBvcCgpKSB7CiAgICBjYWxsYmFjayhu
b2RlKSwgY2hpbGRyZW4gPSBub2RlLmNoaWxkcmVuOwogICAgaWYgKGNoaWxkcmVuKSBmb3IgKGkg
PSBjaGlsZHJlbi5sZW5ndGggLSAxOyBpID49IDA7IC0taSkgewogICAgICBub2Rlcy5wdXNoKGNo
aWxkcmVuW2ldKTsKICAgIH0KICB9CiAgcmV0dXJuIHRoaXM7Cn0KCmZ1bmN0aW9uIG5vZGVfZWFj
aEFmdGVyKGNhbGxiYWNrKSB7CiAgdmFyIG5vZGUgPSB0aGlzLCBub2RlcyA9IFtub2RlXSwgbmV4
dCA9IFtdLCBjaGlsZHJlbiwgaSwgbjsKICB3aGlsZSAobm9kZSA9IG5vZGVzLnBvcCgpKSB7CiAg
ICBuZXh0LnB1c2gobm9kZSksIGNoaWxkcmVuID0gbm9kZS5jaGlsZHJlbjsKICAgIGlmIChjaGls
ZHJlbikgZm9yIChpID0gMCwgbiA9IGNoaWxkcmVuLmxlbmd0aDsgaSA8IG47ICsraSkgewogICAg
ICBub2Rlcy5wdXNoKGNoaWxkcmVuW2ldKTsKICAgIH0KICB9CiAgd2hpbGUgKG5vZGUgPSBuZXh0
LnBvcCgpKSB7CiAgICBjYWxsYmFjayhub2RlKTsKICB9CiAgcmV0dXJuIHRoaXM7Cn0KCmZ1bmN0
aW9uIG5vZGVfc3VtKHZhbHVlKSB7CiAgcmV0dXJuIHRoaXMuZWFjaEFmdGVyKGZ1bmN0aW9uKG5v
ZGUpIHsKICAgIHZhciBzdW0gPSArdmFsdWUobm9kZS5kYXRhKSB8fCAwLAogICAgICAgIGNoaWxk
cmVuID0gbm9kZS5jaGlsZHJlbiwKICAgICAgICBpID0gY2hpbGRyZW4gJiYgY2hpbGRyZW4ubGVu
Z3RoOwogICAgd2hpbGUgKC0taSA+PSAwKSBzdW0gKz0gY2hpbGRyZW5baV0udmFsdWU7CiAgICBu
b2RlLnZhbHVlID0gc3VtOwogIH0pOwp9CgpmdW5jdGlvbiBub2RlX3NvcnQoY29tcGFyZSkgewog
IHJldHVybiB0aGlzLmVhY2hCZWZvcmUoZnVuY3Rpb24obm9kZSkgewogICAgaWYgKG5vZGUuY2hp
bGRyZW4pIHsKICAgICAgbm9kZS5jaGlsZHJlbi5zb3J0KGNvbXBhcmUpOwogICAgfQogIH0pOwp9
CgpmdW5jdGlvbiBub2RlX3BhdGgoZW5kKSB7CiAgdmFyIHN0YXJ0ID0gdGhpcywKICAgICAgYW5j
ZXN0b3IgPSBsZWFzdENvbW1vbkFuY2VzdG9yKHN0YXJ0LCBlbmQpLAogICAgICBub2RlcyA9IFtz
dGFydF07CiAgd2hpbGUgKHN0YXJ0ICE9PSBhbmNlc3RvcikgewogICAgc3RhcnQgPSBzdGFydC5w
YXJlbnQ7CiAgICBub2Rlcy5wdXNoKHN0YXJ0KTsKICB9CiAgdmFyIGsgPSBub2Rlcy5sZW5ndGg7
CiAgd2hpbGUgKGVuZCAhPT0gYW5jZXN0b3IpIHsKICAgIG5vZGVzLnNwbGljZShrLCAwLCBlbmQp
OwogICAgZW5kID0gZW5kLnBhcmVudDsKICB9CiAgcmV0dXJuIG5vZGVzOwp9CgpmdW5jdGlvbiBs
ZWFzdENvbW1vbkFuY2VzdG9yKGEsIGIpIHsKICBpZiAoYSA9PT0gYikgcmV0dXJuIGE7CiAgdmFy
IGFOb2RlcyA9IGEuYW5jZXN0b3JzKCksCiAgICAgIGJOb2RlcyA9IGIuYW5jZXN0b3JzKCksCiAg
ICAgIGMgPSBudWxsOwogIGEgPSBhTm9kZXMucG9wKCk7CiAgYiA9IGJOb2Rlcy5wb3AoKTsKICB3
aGlsZSAoYSA9PT0gYikgewogICAgYyA9IGE7CiAgICBhID0gYU5vZGVzLnBvcCgpOwogICAgYiA9
IGJOb2Rlcy5wb3AoKTsKICB9CiAgcmV0dXJuIGM7Cn0KCmZ1bmN0aW9uIG5vZGVfYW5jZXN0b3Jz
KCkgewogIHZhciBub2RlID0gdGhpcywgbm9kZXMgPSBbbm9kZV07CiAgd2hpbGUgKG5vZGUgPSBu
b2RlLnBhcmVudCkgewogICAgbm9kZXMucHVzaChub2RlKTsKICB9CiAgcmV0dXJuIG5vZGVzOwp9
CgpmdW5jdGlvbiBub2RlX2Rlc2NlbmRhbnRzKCkgewogIHZhciBub2RlcyA9IFtdOwogIHRoaXMu
ZWFjaChmdW5jdGlvbihub2RlKSB7CiAgICBub2Rlcy5wdXNoKG5vZGUpOwogIH0pOwogIHJldHVy
biBub2RlczsKfQoKZnVuY3Rpb24gbm9kZV9sZWF2ZXMoKSB7CiAgdmFyIGxlYXZlcyA9IFtdOwog
IHRoaXMuZWFjaEJlZm9yZShmdW5jdGlvbihub2RlKSB7CiAgICBpZiAoIW5vZGUuY2hpbGRyZW4p
IHsKICAgICAgbGVhdmVzLnB1c2gobm9kZSk7CiAgICB9CiAgfSk7CiAgcmV0dXJuIGxlYXZlczsK
fQoKZnVuY3Rpb24gbm9kZV9saW5rcygpIHsKICB2YXIgcm9vdCA9IHRoaXMsIGxpbmtzID0gW107
CiAgcm9vdC5lYWNoKGZ1bmN0aW9uKG5vZGUpIHsKICAgIGlmIChub2RlICE9PSByb290KSB7IC8v
IERvbuKAmXQgaW5jbHVkZSB0aGUgcm9vdOKAmXMgcGFyZW50LCBpZiBhbnkuCiAgICAgIGxpbmtz
LnB1c2goe3NvdXJjZTogbm9kZS5wYXJlbnQsIHRhcmdldDogbm9kZX0pOwogICAgfQogIH0pOwog
IHJldHVybiBsaW5rczsKfQoKZnVuY3Rpb24gaGllcmFyY2h5KGRhdGEsIGNoaWxkcmVuKSB7CiAg
dmFyIHJvb3QgPSBuZXcgTm9kZShkYXRhKSwKICAgICAgdmFsdWVkID0gK2RhdGEudmFsdWUgJiYg
KHJvb3QudmFsdWUgPSBkYXRhLnZhbHVlKSwKICAgICAgbm9kZSwKICAgICAgbm9kZXMgPSBbcm9v
dF0sCiAgICAgIGNoaWxkLAogICAgICBjaGlsZHMsCiAgICAgIGksCiAgICAgIG47CgogIGlmIChj
aGlsZHJlbiA9PSBudWxsKSBjaGlsZHJlbiA9IGRlZmF1bHRDaGlsZHJlbjsKCiAgd2hpbGUgKG5v
ZGUgPSBub2Rlcy5wb3AoKSkgewogICAgaWYgKHZhbHVlZCkgbm9kZS52YWx1ZSA9ICtub2RlLmRh
dGEudmFsdWU7CiAgICBpZiAoKGNoaWxkcyA9IGNoaWxkcmVuKG5vZGUuZGF0YSkpICYmIChuID0g
Y2hpbGRzLmxlbmd0aCkpIHsKICAgICAgbm9kZS5jaGlsZHJlbiA9IG5ldyBBcnJheShuKTsKICAg
ICAgZm9yIChpID0gbiAtIDE7IGkgPj0gMDsgLS1pKSB7CiAgICAgICAgbm9kZXMucHVzaChjaGls
ZCA9IG5vZGUuY2hpbGRyZW5baV0gPSBuZXcgTm9kZShjaGlsZHNbaV0pKTsKICAgICAgICBjaGls
ZC5wYXJlbnQgPSBub2RlOwogICAgICAgIGNoaWxkLmRlcHRoID0gbm9kZS5kZXB0aCArIDE7CiAg
ICAgIH0KICAgIH0KICB9CgogIHJldHVybiByb290LmVhY2hCZWZvcmUoY29tcHV0ZUhlaWdodCk7
Cn0KCmZ1bmN0aW9uIG5vZGVfY29weSgpIHsKICByZXR1cm4gaGllcmFyY2h5KHRoaXMpLmVhY2hC
ZWZvcmUoY29weURhdGEpOwp9CgpmdW5jdGlvbiBkZWZhdWx0Q2hpbGRyZW4oZCkgewogIHJldHVy
biBkLmNoaWxkcmVuOwp9CgpmdW5jdGlvbiBjb3B5RGF0YShub2RlKSB7CiAgbm9kZS5kYXRhID0g
bm9kZS5kYXRhLmRhdGE7Cn0KCmZ1bmN0aW9uIGNvbXB1dGVIZWlnaHQobm9kZSkgewogIHZhciBo
ZWlnaHQgPSAwOwogIGRvIG5vZGUuaGVpZ2h0ID0gaGVpZ2h0OwogIHdoaWxlICgobm9kZSA9IG5v
ZGUucGFyZW50KSAmJiAobm9kZS5oZWlnaHQgPCArK2hlaWdodCkpOwp9CgpmdW5jdGlvbiBOb2Rl
KGRhdGEpIHsKICB0aGlzLmRhdGEgPSBkYXRhOwogIHRoaXMuZGVwdGggPQogIHRoaXMuaGVpZ2h0
ID0gMDsKICB0aGlzLnBhcmVudCA9IG51bGw7Cn0KCk5vZGUucHJvdG90eXBlID0gaGllcmFyY2h5
LnByb3RvdHlwZSA9IHsKICBjb25zdHJ1Y3RvcjogTm9kZSwKICBjb3VudDogbm9kZV9jb3VudCwK
ICBlYWNoOiBub2RlX2VhY2gsCiAgZWFjaEFmdGVyOiBub2RlX2VhY2hBZnRlciwKICBlYWNoQmVm
b3JlOiBub2RlX2VhY2hCZWZvcmUsCiAgc3VtOiBub2RlX3N1bSwKICBzb3J0OiBub2RlX3NvcnQs
CiAgcGF0aDogbm9kZV9wYXRoLAogIGFuY2VzdG9yczogbm9kZV9hbmNlc3RvcnMsCiAgZGVzY2Vu
ZGFudHM6IG5vZGVfZGVzY2VuZGFudHMsCiAgbGVhdmVzOiBub2RlX2xlYXZlcywKICBsaW5rczog
bm9kZV9saW5rcywKICBjb3B5OiBub2RlX2NvcHkKfTsKCnZhciBzbGljZSQ0ID0gQXJyYXkucHJv
dG90eXBlLnNsaWNlOwoKZnVuY3Rpb24gc2h1ZmZsZSQxKGFycmF5KSB7CiAgdmFyIG0gPSBhcnJh
eS5sZW5ndGgsCiAgICAgIHQsCiAgICAgIGk7CgogIHdoaWxlIChtKSB7CiAgICBpID0gTWF0aC5y
YW5kb20oKSAqIG0tLSB8IDA7CiAgICB0ID0gYXJyYXlbbV07CiAgICBhcnJheVttXSA9IGFycmF5
W2ldOwogICAgYXJyYXlbaV0gPSB0OwogIH0KCiAgcmV0dXJuIGFycmF5Owp9CgpmdW5jdGlvbiBl
bmNsb3NlKGNpcmNsZXMpIHsKICB2YXIgaSA9IDAsIG4gPSAoY2lyY2xlcyA9IHNodWZmbGUkMShz
bGljZSQ0LmNhbGwoY2lyY2xlcykpKS5sZW5ndGgsIEIgPSBbXSwgcCwgZTsKCiAgd2hpbGUgKGkg
PCBuKSB7CiAgICBwID0gY2lyY2xlc1tpXTsKICAgIGlmIChlICYmIGVuY2xvc2VzV2VhayhlLCBw
KSkgKytpOwogICAgZWxzZSBlID0gZW5jbG9zZUJhc2lzKEIgPSBleHRlbmRCYXNpcyhCLCBwKSks
IGkgPSAwOwogIH0KCiAgcmV0dXJuIGU7Cn0KCmZ1bmN0aW9uIGV4dGVuZEJhc2lzKEIsIHApIHsK
ICB2YXIgaSwgajsKCiAgaWYgKGVuY2xvc2VzV2Vha0FsbChwLCBCKSkgcmV0dXJuIFtwXTsKCiAg
Ly8gSWYgd2UgZ2V0IGhlcmUgdGhlbiBCIG11c3QgaGF2ZSBhdCBsZWFzdCBvbmUgZWxlbWVudC4K
ICBmb3IgKGkgPSAwOyBpIDwgQi5sZW5ndGg7ICsraSkgewogICAgaWYgKGVuY2xvc2VzTm90KHAs
IEJbaV0pCiAgICAgICAgJiYgZW5jbG9zZXNXZWFrQWxsKGVuY2xvc2VCYXNpczIoQltpXSwgcCks
IEIpKSB7CiAgICAgIHJldHVybiBbQltpXSwgcF07CiAgICB9CiAgfQoKICAvLyBJZiB3ZSBnZXQg
aGVyZSB0aGVuIEIgbXVzdCBoYXZlIGF0IGxlYXN0IHR3byBlbGVtZW50cy4KICBmb3IgKGkgPSAw
OyBpIDwgQi5sZW5ndGggLSAxOyArK2kpIHsKICAgIGZvciAoaiA9IGkgKyAxOyBqIDwgQi5sZW5n
dGg7ICsraikgewogICAgICBpZiAoZW5jbG9zZXNOb3QoZW5jbG9zZUJhc2lzMihCW2ldLCBCW2pd
KSwgcCkKICAgICAgICAgICYmIGVuY2xvc2VzTm90KGVuY2xvc2VCYXNpczIoQltpXSwgcCksIEJb
al0pCiAgICAgICAgICAmJiBlbmNsb3Nlc05vdChlbmNsb3NlQmFzaXMyKEJbal0sIHApLCBCW2ld
KQogICAgICAgICAgJiYgZW5jbG9zZXNXZWFrQWxsKGVuY2xvc2VCYXNpczMoQltpXSwgQltqXSwg
cCksIEIpKSB7CiAgICAgICAgcmV0dXJuIFtCW2ldLCBCW2pdLCBwXTsKICAgICAgfQogICAgfQog
IH0KCiAgLy8gSWYgd2UgZ2V0IGhlcmUgdGhlbiBzb21ldGhpbmcgaXMgdmVyeSB3cm9uZy4KICB0
aHJvdyBuZXcgRXJyb3I7Cn0KCmZ1bmN0aW9uIGVuY2xvc2VzTm90KGEsIGIpIHsKICB2YXIgZHIg
PSBhLnIgLSBiLnIsIGR4ID0gYi54IC0gYS54LCBkeSA9IGIueSAtIGEueTsKICByZXR1cm4gZHIg
PCAwIHx8IGRyICogZHIgPCBkeCAqIGR4ICsgZHkgKiBkeTsKfQoKZnVuY3Rpb24gZW5jbG9zZXNX
ZWFrKGEsIGIpIHsKICB2YXIgZHIgPSBhLnIgLSBiLnIgKyAxZS02LCBkeCA9IGIueCAtIGEueCwg
ZHkgPSBiLnkgLSBhLnk7CiAgcmV0dXJuIGRyID4gMCAmJiBkciAqIGRyID4gZHggKiBkeCArIGR5
ICogZHk7Cn0KCmZ1bmN0aW9uIGVuY2xvc2VzV2Vha0FsbChhLCBCKSB7CiAgZm9yICh2YXIgaSA9
IDA7IGkgPCBCLmxlbmd0aDsgKytpKSB7CiAgICBpZiAoIWVuY2xvc2VzV2VhayhhLCBCW2ldKSkg
ewogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgfQogIHJldHVybiB0cnVlOwp9CgpmdW5jdGlv
biBlbmNsb3NlQmFzaXMoQikgewogIHN3aXRjaCAoQi5sZW5ndGgpIHsKICAgIGNhc2UgMTogcmV0
dXJuIGVuY2xvc2VCYXNpczEoQlswXSk7CiAgICBjYXNlIDI6IHJldHVybiBlbmNsb3NlQmFzaXMy
KEJbMF0sIEJbMV0pOwogICAgY2FzZSAzOiByZXR1cm4gZW5jbG9zZUJhc2lzMyhCWzBdLCBCWzFd
LCBCWzJdKTsKICB9Cn0KCmZ1bmN0aW9uIGVuY2xvc2VCYXNpczEoYSkgewogIHJldHVybiB7CiAg
ICB4OiBhLngsCiAgICB5OiBhLnksCiAgICByOiBhLnIKICB9Owp9CgpmdW5jdGlvbiBlbmNsb3Nl
QmFzaXMyKGEsIGIpIHsKICB2YXIgeDEgPSBhLngsIHkxID0gYS55LCByMSA9IGEuciwKICAgICAg
eDIgPSBiLngsIHkyID0gYi55LCByMiA9IGIuciwKICAgICAgeDIxID0geDIgLSB4MSwgeTIxID0g
eTIgLSB5MSwgcjIxID0gcjIgLSByMSwKICAgICAgbCA9IE1hdGguc3FydCh4MjEgKiB4MjEgKyB5
MjEgKiB5MjEpOwogIHJldHVybiB7CiAgICB4OiAoeDEgKyB4MiArIHgyMSAvIGwgKiByMjEpIC8g
MiwKICAgIHk6ICh5MSArIHkyICsgeTIxIC8gbCAqIHIyMSkgLyAyLAogICAgcjogKGwgKyByMSAr
IHIyKSAvIDIKICB9Owp9CgpmdW5jdGlvbiBlbmNsb3NlQmFzaXMzKGEsIGIsIGMpIHsKICB2YXIg
eDEgPSBhLngsIHkxID0gYS55LCByMSA9IGEuciwKICAgICAgeDIgPSBiLngsIHkyID0gYi55LCBy
MiA9IGIuciwKICAgICAgeDMgPSBjLngsIHkzID0gYy55LCByMyA9IGMuciwKICAgICAgYTIgPSB4
MSAtIHgyLAogICAgICBhMyA9IHgxIC0geDMsCiAgICAgIGIyID0geTEgLSB5MiwKICAgICAgYjMg
PSB5MSAtIHkzLAogICAgICBjMiA9IHIyIC0gcjEsCiAgICAgIGMzID0gcjMgLSByMSwKICAgICAg
ZDEgPSB4MSAqIHgxICsgeTEgKiB5MSAtIHIxICogcjEsCiAgICAgIGQyID0gZDEgLSB4MiAqIHgy
IC0geTIgKiB5MiArIHIyICogcjIsCiAgICAgIGQzID0gZDEgLSB4MyAqIHgzIC0geTMgKiB5MyAr
IHIzICogcjMsCiAgICAgIGFiID0gYTMgKiBiMiAtIGEyICogYjMsCiAgICAgIHhhID0gKGIyICog
ZDMgLSBiMyAqIGQyKSAvIChhYiAqIDIpIC0geDEsCiAgICAgIHhiID0gKGIzICogYzIgLSBiMiAq
IGMzKSAvIGFiLAogICAgICB5YSA9IChhMyAqIGQyIC0gYTIgKiBkMykgLyAoYWIgKiAyKSAtIHkx
LAogICAgICB5YiA9IChhMiAqIGMzIC0gYTMgKiBjMikgLyBhYiwKICAgICAgQSA9IHhiICogeGIg
KyB5YiAqIHliIC0gMSwKICAgICAgQiA9IDIgKiAocjEgKyB4YSAqIHhiICsgeWEgKiB5YiksCiAg
ICAgIEMgPSB4YSAqIHhhICsgeWEgKiB5YSAtIHIxICogcjEsCiAgICAgIHIgPSAtKEEgPyAoQiAr
IE1hdGguc3FydChCICogQiAtIDQgKiBBICogQykpIC8gKDIgKiBBKSA6IEMgLyBCKTsKICByZXR1
cm4gewogICAgeDogeDEgKyB4YSArIHhiICogciwKICAgIHk6IHkxICsgeWEgKyB5YiAqIHIsCiAg
ICByOiByCiAgfTsKfQoKZnVuY3Rpb24gcGxhY2UoYiwgYSwgYykgewogIHZhciBkeCA9IGIueCAt
IGEueCwgeCwgYTIsCiAgICAgIGR5ID0gYi55IC0gYS55LCB5LCBiMiwKICAgICAgZDIgPSBkeCAq
IGR4ICsgZHkgKiBkeTsKICBpZiAoZDIpIHsKICAgIGEyID0gYS5yICsgYy5yLCBhMiAqPSBhMjsK
ICAgIGIyID0gYi5yICsgYy5yLCBiMiAqPSBiMjsKICAgIGlmIChhMiA+IGIyKSB7CiAgICAgIHgg
PSAoZDIgKyBiMiAtIGEyKSAvICgyICogZDIpOwogICAgICB5ID0gTWF0aC5zcXJ0KE1hdGgubWF4
KDAsIGIyIC8gZDIgLSB4ICogeCkpOwogICAgICBjLnggPSBiLnggLSB4ICogZHggLSB5ICogZHk7
CiAgICAgIGMueSA9IGIueSAtIHggKiBkeSArIHkgKiBkeDsKICAgIH0gZWxzZSB7CiAgICAgIHgg
PSAoZDIgKyBhMiAtIGIyKSAvICgyICogZDIpOwogICAgICB5ID0gTWF0aC5zcXJ0KE1hdGgubWF4
KDAsIGEyIC8gZDIgLSB4ICogeCkpOwogICAgICBjLnggPSBhLnggKyB4ICogZHggLSB5ICogZHk7
CiAgICAgIGMueSA9IGEueSArIHggKiBkeSArIHkgKiBkeDsKICAgIH0KICB9IGVsc2UgewogICAg
Yy54ID0gYS54ICsgYy5yOwogICAgYy55ID0gYS55OwogIH0KfQoKZnVuY3Rpb24gaW50ZXJzZWN0
cyhhLCBiKSB7CiAgdmFyIGRyID0gYS5yICsgYi5yIC0gMWUtNiwgZHggPSBiLnggLSBhLngsIGR5
ID0gYi55IC0gYS55OwogIHJldHVybiBkciA+IDAgJiYgZHIgKiBkciA+IGR4ICogZHggKyBkeSAq
IGR5Owp9CgpmdW5jdGlvbiBzY29yZShub2RlKSB7CiAgdmFyIGEgPSBub2RlLl8sCiAgICAgIGIg
PSBub2RlLm5leHQuXywKICAgICAgYWIgPSBhLnIgKyBiLnIsCiAgICAgIGR4ID0gKGEueCAqIGIu
ciArIGIueCAqIGEucikgLyBhYiwKICAgICAgZHkgPSAoYS55ICogYi5yICsgYi55ICogYS5yKSAv
IGFiOwogIHJldHVybiBkeCAqIGR4ICsgZHkgKiBkeTsKfQoKZnVuY3Rpb24gTm9kZSQxKGNpcmNs
ZSkgewogIHRoaXMuXyA9IGNpcmNsZTsKICB0aGlzLm5leHQgPSBudWxsOwogIHRoaXMucHJldmlv
dXMgPSBudWxsOwp9CgpmdW5jdGlvbiBwYWNrRW5jbG9zZShjaXJjbGVzKSB7CiAgaWYgKCEobiA9
IGNpcmNsZXMubGVuZ3RoKSkgcmV0dXJuIDA7CgogIHZhciBhLCBiLCBjLCBuLCBhYSwgY2EsIGks
IGosIGssIHNqLCBzazsKCiAgLy8gUGxhY2UgdGhlIGZpcnN0IGNpcmNsZS4KICBhID0gY2lyY2xl
c1swXSwgYS54ID0gMCwgYS55ID0gMDsKICBpZiAoIShuID4gMSkpIHJldHVybiBhLnI7CgogIC8v
IFBsYWNlIHRoZSBzZWNvbmQgY2lyY2xlLgogIGIgPSBjaXJjbGVzWzFdLCBhLnggPSAtYi5yLCBi
LnggPSBhLnIsIGIueSA9IDA7CiAgaWYgKCEobiA+IDIpKSByZXR1cm4gYS5yICsgYi5yOwoKICAv
LyBQbGFjZSB0aGUgdGhpcmQgY2lyY2xlLgogIHBsYWNlKGIsIGEsIGMgPSBjaXJjbGVzWzJdKTsK
CiAgLy8gSW5pdGlhbGl6ZSB0aGUgZnJvbnQtY2hhaW4gdXNpbmcgdGhlIGZpcnN0IHRocmVlIGNp
cmNsZXMgYSwgYiBhbmQgYy4KICBhID0gbmV3IE5vZGUkMShhKSwgYiA9IG5ldyBOb2RlJDEoYiks
IGMgPSBuZXcgTm9kZSQxKGMpOwogIGEubmV4dCA9IGMucHJldmlvdXMgPSBiOwogIGIubmV4dCA9
IGEucHJldmlvdXMgPSBjOwogIGMubmV4dCA9IGIucHJldmlvdXMgPSBhOwoKICAvLyBBdHRlbXB0
IHRvIHBsYWNlIGVhY2ggcmVtYWluaW5nIGNpcmNsZeKApgogIHBhY2s6IGZvciAoaSA9IDM7IGkg
PCBuOyArK2kpIHsKICAgIHBsYWNlKGEuXywgYi5fLCBjID0gY2lyY2xlc1tpXSksIGMgPSBuZXcg
Tm9kZSQxKGMpOwoKICAgIC8vIEZpbmQgdGhlIGNsb3Nlc3QgaW50ZXJzZWN0aW5nIGNpcmNsZSBv
biB0aGUgZnJvbnQtY2hhaW4sIGlmIGFueS4KICAgIC8vIOKAnENsb3NlbmVzc+KAnSBpcyBkZXRl
cm1pbmVkIGJ5IGxpbmVhciBkaXN0YW5jZSBhbG9uZyB0aGUgZnJvbnQtY2hhaW4uCiAgICAvLyDi
gJxBaGVhZOKAnSBvciDigJxiZWhpbmTigJ0gaXMgbGlrZXdpc2UgZGV0ZXJtaW5lZCBieSBsaW5l
YXIgZGlzdGFuY2UuCiAgICBqID0gYi5uZXh0LCBrID0gYS5wcmV2aW91cywgc2ogPSBiLl8uciwg
c2sgPSBhLl8ucjsKICAgIGRvIHsKICAgICAgaWYgKHNqIDw9IHNrKSB7CiAgICAgICAgaWYgKGlu
dGVyc2VjdHMoai5fLCBjLl8pKSB7CiAgICAgICAgICBiID0gaiwgYS5uZXh0ID0gYiwgYi5wcmV2
aW91cyA9IGEsIC0taTsKICAgICAgICAgIGNvbnRpbnVlIHBhY2s7CiAgICAgICAgfQogICAgICAg
IHNqICs9IGouXy5yLCBqID0gai5uZXh0OwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChpbnRl
cnNlY3RzKGsuXywgYy5fKSkgewogICAgICAgICAgYSA9IGssIGEubmV4dCA9IGIsIGIucHJldmlv
dXMgPSBhLCAtLWk7CiAgICAgICAgICBjb250aW51ZSBwYWNrOwogICAgICAgIH0KICAgICAgICBz
ayArPSBrLl8uciwgayA9IGsucHJldmlvdXM7CiAgICAgIH0KICAgIH0gd2hpbGUgKGogIT09IGsu
bmV4dCk7CgogICAgLy8gU3VjY2VzcyEgSW5zZXJ0IHRoZSBuZXcgY2lyY2xlIGMgYmV0d2VlbiBh
IGFuZCBiLgogICAgYy5wcmV2aW91cyA9IGEsIGMubmV4dCA9IGIsIGEubmV4dCA9IGIucHJldmlv
dXMgPSBiID0gYzsKCiAgICAvLyBDb21wdXRlIHRoZSBuZXcgY2xvc2VzdCBjaXJjbGUgcGFpciB0
byB0aGUgY2VudHJvaWQuCiAgICBhYSA9IHNjb3JlKGEpOwogICAgd2hpbGUgKChjID0gYy5uZXh0
KSAhPT0gYikgewogICAgICBpZiAoKGNhID0gc2NvcmUoYykpIDwgYWEpIHsKICAgICAgICBhID0g
YywgYWEgPSBjYTsKICAgICAgfQogICAgfQogICAgYiA9IGEubmV4dDsKICB9CgogIC8vIENvbXB1
dGUgdGhlIGVuY2xvc2luZyBjaXJjbGUgb2YgdGhlIGZyb250IGNoYWluLgogIGEgPSBbYi5fXSwg
YyA9IGI7IHdoaWxlICgoYyA9IGMubmV4dCkgIT09IGIpIGEucHVzaChjLl8pOyBjID0gZW5jbG9z
ZShhKTsKCiAgLy8gVHJhbnNsYXRlIHRoZSBjaXJjbGVzIHRvIHB1dCB0aGUgZW5jbG9zaW5nIGNp
cmNsZSBhcm91bmQgdGhlIG9yaWdpbi4KICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSBhID0gY2ly
Y2xlc1tpXSwgYS54IC09IGMueCwgYS55IC09IGMueTsKCiAgcmV0dXJuIGMucjsKfQoKZnVuY3Rp
b24gc2libGluZ3MoY2lyY2xlcykgewogIHBhY2tFbmNsb3NlKGNpcmNsZXMpOwogIHJldHVybiBj
aXJjbGVzOwp9CgpmdW5jdGlvbiBvcHRpb25hbChmKSB7CiAgcmV0dXJuIGYgPT0gbnVsbCA/IG51
bGwgOiByZXF1aXJlZChmKTsKfQoKZnVuY3Rpb24gcmVxdWlyZWQoZikgewogIGlmICh0eXBlb2Yg
ZiAhPT0gImZ1bmN0aW9uIikgdGhyb3cgbmV3IEVycm9yOwogIHJldHVybiBmOwp9CgpmdW5jdGlv
biBjb25zdGFudFplcm8oKSB7CiAgcmV0dXJuIDA7Cn0KCmZ1bmN0aW9uIGNvbnN0YW50JDkoeCkg
ewogIHJldHVybiBmdW5jdGlvbigpIHsKICAgIHJldHVybiB4OwogIH07Cn0KCmZ1bmN0aW9uIGRl
ZmF1bHRSYWRpdXMkMShkKSB7CiAgcmV0dXJuIE1hdGguc3FydChkLnZhbHVlKTsKfQoKZnVuY3Rp
b24gaW5kZXgkMigpIHsKICB2YXIgcmFkaXVzID0gbnVsbCwKICAgICAgZHggPSAxLAogICAgICBk
eSA9IDEsCiAgICAgIHBhZGRpbmcgPSBjb25zdGFudFplcm87CgogIGZ1bmN0aW9uIHBhY2socm9v
dCkgewogICAgcm9vdC54ID0gZHggLyAyLCByb290LnkgPSBkeSAvIDI7CiAgICBpZiAocmFkaXVz
KSB7CiAgICAgIHJvb3QuZWFjaEJlZm9yZShyYWRpdXNMZWFmKHJhZGl1cykpCiAgICAgICAgICAu
ZWFjaEFmdGVyKHBhY2tDaGlsZHJlbihwYWRkaW5nLCAwLjUpKQogICAgICAgICAgLmVhY2hCZWZv
cmUodHJhbnNsYXRlQ2hpbGQoMSkpOwogICAgfSBlbHNlIHsKICAgICAgcm9vdC5lYWNoQmVmb3Jl
KHJhZGl1c0xlYWYoZGVmYXVsdFJhZGl1cyQxKSkKICAgICAgICAgIC5lYWNoQWZ0ZXIocGFja0No
aWxkcmVuKGNvbnN0YW50WmVybywgMSkpCiAgICAgICAgICAuZWFjaEFmdGVyKHBhY2tDaGlsZHJl
bihwYWRkaW5nLCByb290LnIgLyBNYXRoLm1pbihkeCwgZHkpKSkKICAgICAgICAgIC5lYWNoQmVm
b3JlKHRyYW5zbGF0ZUNoaWxkKE1hdGgubWluKGR4LCBkeSkgLyAoMiAqIHJvb3QucikpKTsKICAg
IH0KICAgIHJldHVybiByb290OwogIH0KCiAgcGFjay5yYWRpdXMgPSBmdW5jdGlvbih4KSB7CiAg
ICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChyYWRpdXMgPSBvcHRpb25hbCh4KSwgcGFjaykg
OiByYWRpdXM7CiAgfTsKCiAgcGFjay5zaXplID0gZnVuY3Rpb24oeCkgewogICAgcmV0dXJuIGFy
Z3VtZW50cy5sZW5ndGggPyAoZHggPSAreFswXSwgZHkgPSAreFsxXSwgcGFjaykgOiBbZHgsIGR5
XTsKICB9OwoKICBwYWNrLnBhZGRpbmcgPSBmdW5jdGlvbih4KSB7CiAgICByZXR1cm4gYXJndW1l
bnRzLmxlbmd0aCA/IChwYWRkaW5nID0gdHlwZW9mIHggPT09ICJmdW5jdGlvbiIgPyB4IDogY29u
c3RhbnQkOSgreCksIHBhY2spIDogcGFkZGluZzsKICB9OwoKICByZXR1cm4gcGFjazsKfQoKZnVu
Y3Rpb24gcmFkaXVzTGVhZihyYWRpdXMpIHsKICByZXR1cm4gZnVuY3Rpb24obm9kZSkgewogICAg
aWYgKCFub2RlLmNoaWxkcmVuKSB7CiAgICAgIG5vZGUuciA9IE1hdGgubWF4KDAsICtyYWRpdXMo
bm9kZSkgfHwgMCk7CiAgICB9CiAgfTsKfQoKZnVuY3Rpb24gcGFja0NoaWxkcmVuKHBhZGRpbmcs
IGspIHsKICByZXR1cm4gZnVuY3Rpb24obm9kZSkgewogICAgaWYgKGNoaWxkcmVuID0gbm9kZS5j
aGlsZHJlbikgewogICAgICB2YXIgY2hpbGRyZW4sCiAgICAgICAgICBpLAogICAgICAgICAgbiA9
IGNoaWxkcmVuLmxlbmd0aCwKICAgICAgICAgIHIgPSBwYWRkaW5nKG5vZGUpICogayB8fCAwLAog
ICAgICAgICAgZTsKCiAgICAgIGlmIChyKSBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSBjaGlsZHJl
bltpXS5yICs9IHI7CiAgICAgIGUgPSBwYWNrRW5jbG9zZShjaGlsZHJlbik7CiAgICAgIGlmIChy
KSBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSBjaGlsZHJlbltpXS5yIC09IHI7CiAgICAgIG5vZGUu
ciA9IGUgKyByOwogICAgfQogIH07Cn0KCmZ1bmN0aW9uIHRyYW5zbGF0ZUNoaWxkKGspIHsKICBy
ZXR1cm4gZnVuY3Rpb24obm9kZSkgewogICAgdmFyIHBhcmVudCA9IG5vZGUucGFyZW50OwogICAg
bm9kZS5yICo9IGs7CiAgICBpZiAocGFyZW50KSB7CiAgICAgIG5vZGUueCA9IHBhcmVudC54ICsg
ayAqIG5vZGUueDsKICAgICAgbm9kZS55ID0gcGFyZW50LnkgKyBrICogbm9kZS55OwogICAgfQog
IH07Cn0KCmZ1bmN0aW9uIHJvdW5kTm9kZShub2RlKSB7CiAgbm9kZS54MCA9IE1hdGgucm91bmQo
bm9kZS54MCk7CiAgbm9kZS55MCA9IE1hdGgucm91bmQobm9kZS55MCk7CiAgbm9kZS54MSA9IE1h
dGgucm91bmQobm9kZS54MSk7CiAgbm9kZS55MSA9IE1hdGgucm91bmQobm9kZS55MSk7Cn0KCmZ1
bmN0aW9uIHRyZWVtYXBEaWNlKHBhcmVudCwgeDAsIHkwLCB4MSwgeTEpIHsKICB2YXIgbm9kZXMg
PSBwYXJlbnQuY2hpbGRyZW4sCiAgICAgIG5vZGUsCiAgICAgIGkgPSAtMSwKICAgICAgbiA9IG5v
ZGVzLmxlbmd0aCwKICAgICAgayA9IHBhcmVudC52YWx1ZSAmJiAoeDEgLSB4MCkgLyBwYXJlbnQu
dmFsdWU7CgogIHdoaWxlICgrK2kgPCBuKSB7CiAgICBub2RlID0gbm9kZXNbaV0sIG5vZGUueTAg
PSB5MCwgbm9kZS55MSA9IHkxOwogICAgbm9kZS54MCA9IHgwLCBub2RlLngxID0geDAgKz0gbm9k
ZS52YWx1ZSAqIGs7CiAgfQp9CgpmdW5jdGlvbiBwYXJ0aXRpb24oKSB7CiAgdmFyIGR4ID0gMSwK
ICAgICAgZHkgPSAxLAogICAgICBwYWRkaW5nID0gMCwKICAgICAgcm91bmQgPSBmYWxzZTsKCiAg
ZnVuY3Rpb24gcGFydGl0aW9uKHJvb3QpIHsKICAgIHZhciBuID0gcm9vdC5oZWlnaHQgKyAxOwog
ICAgcm9vdC54MCA9CiAgICByb290LnkwID0gcGFkZGluZzsKICAgIHJvb3QueDEgPSBkeDsKICAg
IHJvb3QueTEgPSBkeSAvIG47CiAgICByb290LmVhY2hCZWZvcmUocG9zaXRpb25Ob2RlKGR5LCBu
KSk7CiAgICBpZiAocm91bmQpIHJvb3QuZWFjaEJlZm9yZShyb3VuZE5vZGUpOwogICAgcmV0dXJu
IHJvb3Q7CiAgfQoKICBmdW5jdGlvbiBwb3NpdGlvbk5vZGUoZHksIG4pIHsKICAgIHJldHVybiBm
dW5jdGlvbihub2RlKSB7CiAgICAgIGlmIChub2RlLmNoaWxkcmVuKSB7CiAgICAgICAgdHJlZW1h
cERpY2Uobm9kZSwgbm9kZS54MCwgZHkgKiAobm9kZS5kZXB0aCArIDEpIC8gbiwgbm9kZS54MSwg
ZHkgKiAobm9kZS5kZXB0aCArIDIpIC8gbik7CiAgICAgIH0KICAgICAgdmFyIHgwID0gbm9kZS54
MCwKICAgICAgICAgIHkwID0gbm9kZS55MCwKICAgICAgICAgIHgxID0gbm9kZS54MSAtIHBhZGRp
bmcsCiAgICAgICAgICB5MSA9IG5vZGUueTEgLSBwYWRkaW5nOwogICAgICBpZiAoeDEgPCB4MCkg
eDAgPSB4MSA9ICh4MCArIHgxKSAvIDI7CiAgICAgIGlmICh5MSA8IHkwKSB5MCA9IHkxID0gKHkw
ICsgeTEpIC8gMjsKICAgICAgbm9kZS54MCA9IHgwOwogICAgICBub2RlLnkwID0geTA7CiAgICAg
IG5vZGUueDEgPSB4MTsKICAgICAgbm9kZS55MSA9IHkxOwogICAgfTsKICB9CgogIHBhcnRpdGlv
bi5yb3VuZCA9IGZ1bmN0aW9uKHgpIHsKICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHJv
dW5kID0gISF4LCBwYXJ0aXRpb24pIDogcm91bmQ7CiAgfTsKCiAgcGFydGl0aW9uLnNpemUgPSBm
dW5jdGlvbih4KSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChkeCA9ICt4WzBdLCBk
eSA9ICt4WzFdLCBwYXJ0aXRpb24pIDogW2R4LCBkeV07CiAgfTsKCiAgcGFydGl0aW9uLnBhZGRp
bmcgPSBmdW5jdGlvbih4KSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChwYWRkaW5n
ID0gK3gsIHBhcnRpdGlvbikgOiBwYWRkaW5nOwogIH07CgogIHJldHVybiBwYXJ0aXRpb247Cn0K
CnZhciBrZXlQcmVmaXgkMSA9ICIkIiwgLy8gUHJvdGVjdCBhZ2FpbnN0IGtleXMgbGlrZSDigJxf
X3Byb3RvX1/igJ0uCiAgICBwcmVyb290ID0ge2RlcHRoOiAtMX0sCiAgICBhbWJpZ3VvdXMgPSB7
fTsKCmZ1bmN0aW9uIGRlZmF1bHRJZChkKSB7CiAgcmV0dXJuIGQuaWQ7Cn0KCmZ1bmN0aW9uIGRl
ZmF1bHRQYXJlbnRJZChkKSB7CiAgcmV0dXJuIGQucGFyZW50SWQ7Cn0KCmZ1bmN0aW9uIHN0cmF0
aWZ5KCkgewogIHZhciBpZCA9IGRlZmF1bHRJZCwKICAgICAgcGFyZW50SWQgPSBkZWZhdWx0UGFy
ZW50SWQ7CgogIGZ1bmN0aW9uIHN0cmF0aWZ5KGRhdGEpIHsKICAgIHZhciBkLAogICAgICAgIGks
CiAgICAgICAgbiA9IGRhdGEubGVuZ3RoLAogICAgICAgIHJvb3QsCiAgICAgICAgcGFyZW50LAog
ICAgICAgIG5vZGUsCiAgICAgICAgbm9kZXMgPSBuZXcgQXJyYXkobiksCiAgICAgICAgbm9kZUlk
LAogICAgICAgIG5vZGVLZXksCiAgICAgICAgbm9kZUJ5S2V5ID0ge307CgogICAgZm9yIChpID0g
MDsgaSA8IG47ICsraSkgewogICAgICBkID0gZGF0YVtpXSwgbm9kZSA9IG5vZGVzW2ldID0gbmV3
IE5vZGUoZCk7CiAgICAgIGlmICgobm9kZUlkID0gaWQoZCwgaSwgZGF0YSkpICE9IG51bGwgJiYg
KG5vZGVJZCArPSAiIikpIHsKICAgICAgICBub2RlS2V5ID0ga2V5UHJlZml4JDEgKyAobm9kZS5p
ZCA9IG5vZGVJZCk7CiAgICAgICAgbm9kZUJ5S2V5W25vZGVLZXldID0gbm9kZUtleSBpbiBub2Rl
QnlLZXkgPyBhbWJpZ3VvdXMgOiBub2RlOwogICAgICB9CiAgICB9CgogICAgZm9yIChpID0gMDsg
aSA8IG47ICsraSkgewogICAgICBub2RlID0gbm9kZXNbaV0sIG5vZGVJZCA9IHBhcmVudElkKGRh
dGFbaV0sIGksIGRhdGEpOwogICAgICBpZiAobm9kZUlkID09IG51bGwgfHwgIShub2RlSWQgKz0g
IiIpKSB7CiAgICAgICAgaWYgKHJvb3QpIHRocm93IG5ldyBFcnJvcigibXVsdGlwbGUgcm9vdHMi
KTsKICAgICAgICByb290ID0gbm9kZTsKICAgICAgfSBlbHNlIHsKICAgICAgICBwYXJlbnQgPSBu
b2RlQnlLZXlba2V5UHJlZml4JDEgKyBub2RlSWRdOwogICAgICAgIGlmICghcGFyZW50KSB0aHJv
dyBuZXcgRXJyb3IoIm1pc3Npbmc6ICIgKyBub2RlSWQpOwogICAgICAgIGlmIChwYXJlbnQgPT09
IGFtYmlndW91cykgdGhyb3cgbmV3IEVycm9yKCJhbWJpZ3VvdXM6ICIgKyBub2RlSWQpOwogICAg
ICAgIGlmIChwYXJlbnQuY2hpbGRyZW4pIHBhcmVudC5jaGlsZHJlbi5wdXNoKG5vZGUpOwogICAg
ICAgIGVsc2UgcGFyZW50LmNoaWxkcmVuID0gW25vZGVdOwogICAgICAgIG5vZGUucGFyZW50ID0g
cGFyZW50OwogICAgICB9CiAgICB9CgogICAgaWYgKCFyb290KSB0aHJvdyBuZXcgRXJyb3IoIm5v
IHJvb3QiKTsKICAgIHJvb3QucGFyZW50ID0gcHJlcm9vdDsKICAgIHJvb3QuZWFjaEJlZm9yZShm
dW5jdGlvbihub2RlKSB7IG5vZGUuZGVwdGggPSBub2RlLnBhcmVudC5kZXB0aCArIDE7IC0tbjsg
fSkuZWFjaEJlZm9yZShjb21wdXRlSGVpZ2h0KTsKICAgIHJvb3QucGFyZW50ID0gbnVsbDsKICAg
IGlmIChuID4gMCkgdGhyb3cgbmV3IEVycm9yKCJjeWNsZSIpOwoKICAgIHJldHVybiByb290Owog
IH0KCiAgc3RyYXRpZnkuaWQgPSBmdW5jdGlvbih4KSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxl
bmd0aCA/IChpZCA9IHJlcXVpcmVkKHgpLCBzdHJhdGlmeSkgOiBpZDsKICB9OwoKICBzdHJhdGlm
eS5wYXJlbnRJZCA9IGZ1bmN0aW9uKHgpIHsKICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8g
KHBhcmVudElkID0gcmVxdWlyZWQoeCksIHN0cmF0aWZ5KSA6IHBhcmVudElkOwogIH07CgogIHJl
dHVybiBzdHJhdGlmeTsKfQoKZnVuY3Rpb24gZGVmYXVsdFNlcGFyYXRpb24kMShhLCBiKSB7CiAg
cmV0dXJuIGEucGFyZW50ID09PSBiLnBhcmVudCA/IDEgOiAyOwp9CgovLyBmdW5jdGlvbiByYWRp
YWxTZXBhcmF0aW9uKGEsIGIpIHsKLy8gICByZXR1cm4gKGEucGFyZW50ID09PSBiLnBhcmVudCA/
IDEgOiAyKSAvIGEuZGVwdGg7Ci8vIH0KCi8vIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCB0byB0cmF2
ZXJzZSB0aGUgbGVmdCBjb250b3VyIG9mIGEgc3VidHJlZSAob3IKLy8gc3ViZm9yZXN0KS4gSXQg
cmV0dXJucyB0aGUgc3VjY2Vzc29yIG9mIHYgb24gdGhpcyBjb250b3VyLiBUaGlzIHN1Y2Nlc3Nv
ciBpcwovLyBlaXRoZXIgZ2l2ZW4gYnkgdGhlIGxlZnRtb3N0IGNoaWxkIG9mIHYgb3IgYnkgdGhl
IHRocmVhZCBvZiB2LiBUaGUgZnVuY3Rpb24KLy8gcmV0dXJucyBudWxsIGlmIGFuZCBvbmx5IGlm
IHYgaXMgb24gdGhlIGhpZ2hlc3QgbGV2ZWwgb2YgaXRzIHN1YnRyZWUuCmZ1bmN0aW9uIG5leHRM
ZWZ0KHYpIHsKICB2YXIgY2hpbGRyZW4gPSB2LmNoaWxkcmVuOwogIHJldHVybiBjaGlsZHJlbiA/
IGNoaWxkcmVuWzBdIDogdi50Owp9CgovLyBUaGlzIGZ1bmN0aW9uIHdvcmtzIGFuYWxvZ291c2x5
IHRvIG5leHRMZWZ0LgpmdW5jdGlvbiBuZXh0UmlnaHQodikgewogIHZhciBjaGlsZHJlbiA9IHYu
Y2hpbGRyZW47CiAgcmV0dXJuIGNoaWxkcmVuID8gY2hpbGRyZW5bY2hpbGRyZW4ubGVuZ3RoIC0g
MV0gOiB2LnQ7Cn0KCi8vIFNoaWZ0cyB0aGUgY3VycmVudCBzdWJ0cmVlIHJvb3RlZCBhdCB3Ky4g
VGhpcyBpcyBkb25lIGJ5IGluY3JlYXNpbmcKLy8gcHJlbGltKHcrKSBhbmQgbW9kKHcrKSBieSBz
aGlmdC4KZnVuY3Rpb24gbW92ZVN1YnRyZWUod20sIHdwLCBzaGlmdCkgewogIHZhciBjaGFuZ2Ug
PSBzaGlmdCAvICh3cC5pIC0gd20uaSk7CiAgd3AuYyAtPSBjaGFuZ2U7CiAgd3AucyArPSBzaGlm
dDsKICB3bS5jICs9IGNoYW5nZTsKICB3cC56ICs9IHNoaWZ0OwogIHdwLm0gKz0gc2hpZnQ7Cn0K
Ci8vIEFsbCBvdGhlciBzaGlmdHMsIGFwcGxpZWQgdG8gdGhlIHNtYWxsZXIgc3VidHJlZXMgYmV0
d2VlbiB3LSBhbmQgdyssIGFyZQovLyBwZXJmb3JtZWQgYnkgdGhpcyBmdW5jdGlvbi4gVG8gcHJl
cGFyZSB0aGUgc2hpZnRzLCB3ZSBoYXZlIHRvIGFkanVzdAovLyBjaGFuZ2UodyspLCBzaGlmdCh3
KyksIGFuZCBjaGFuZ2Uody0pLgpmdW5jdGlvbiBleGVjdXRlU2hpZnRzKHYpIHsKICB2YXIgc2hp
ZnQgPSAwLAogICAgICBjaGFuZ2UgPSAwLAogICAgICBjaGlsZHJlbiA9IHYuY2hpbGRyZW4sCiAg
ICAgIGkgPSBjaGlsZHJlbi5sZW5ndGgsCiAgICAgIHc7CiAgd2hpbGUgKC0taSA+PSAwKSB7CiAg
ICB3ID0gY2hpbGRyZW5baV07CiAgICB3LnogKz0gc2hpZnQ7CiAgICB3Lm0gKz0gc2hpZnQ7CiAg
ICBzaGlmdCArPSB3LnMgKyAoY2hhbmdlICs9IHcuYyk7CiAgfQp9CgovLyBJZiB2aS3igJlzIGFu
Y2VzdG9yIGlzIGEgc2libGluZyBvZiB2LCByZXR1cm5zIHZpLeKAmXMgYW5jZXN0b3IuIE90aGVy
d2lzZSwKLy8gcmV0dXJucyB0aGUgc3BlY2lmaWVkIChkZWZhdWx0KSBhbmNlc3Rvci4KZnVuY3Rp
b24gbmV4dEFuY2VzdG9yKHZpbSwgdiwgYW5jZXN0b3IpIHsKICByZXR1cm4gdmltLmEucGFyZW50
ID09PSB2LnBhcmVudCA/IHZpbS5hIDogYW5jZXN0b3I7Cn0KCmZ1bmN0aW9uIFRyZWVOb2RlKG5v
ZGUsIGkpIHsKICB0aGlzLl8gPSBub2RlOwogIHRoaXMucGFyZW50ID0gbnVsbDsKICB0aGlzLmNo
aWxkcmVuID0gbnVsbDsKICB0aGlzLkEgPSBudWxsOyAvLyBkZWZhdWx0IGFuY2VzdG9yCiAgdGhp
cy5hID0gdGhpczsgLy8gYW5jZXN0b3IKICB0aGlzLnogPSAwOyAvLyBwcmVsaW0KICB0aGlzLm0g
PSAwOyAvLyBtb2QKICB0aGlzLmMgPSAwOyAvLyBjaGFuZ2UKICB0aGlzLnMgPSAwOyAvLyBzaGlm
dAogIHRoaXMudCA9IG51bGw7IC8vIHRocmVhZAogIHRoaXMuaSA9IGk7IC8vIG51bWJlcgp9CgpU
cmVlTm9kZS5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKE5vZGUucHJvdG90eXBlKTsKCmZ1bmN0
aW9uIHRyZWVSb290KHJvb3QpIHsKICB2YXIgdHJlZSA9IG5ldyBUcmVlTm9kZShyb290LCAwKSwK
ICAgICAgbm9kZSwKICAgICAgbm9kZXMgPSBbdHJlZV0sCiAgICAgIGNoaWxkLAogICAgICBjaGls
ZHJlbiwKICAgICAgaSwKICAgICAgbjsKCiAgd2hpbGUgKG5vZGUgPSBub2Rlcy5wb3AoKSkgewog
ICAgaWYgKGNoaWxkcmVuID0gbm9kZS5fLmNoaWxkcmVuKSB7CiAgICAgIG5vZGUuY2hpbGRyZW4g
PSBuZXcgQXJyYXkobiA9IGNoaWxkcmVuLmxlbmd0aCk7CiAgICAgIGZvciAoaSA9IG4gLSAxOyBp
ID49IDA7IC0taSkgewogICAgICAgIG5vZGVzLnB1c2goY2hpbGQgPSBub2RlLmNoaWxkcmVuW2ld
ID0gbmV3IFRyZWVOb2RlKGNoaWxkcmVuW2ldLCBpKSk7CiAgICAgICAgY2hpbGQucGFyZW50ID0g
bm9kZTsKICAgICAgfQogICAgfQogIH0KCiAgKHRyZWUucGFyZW50ID0gbmV3IFRyZWVOb2RlKG51
bGwsIDApKS5jaGlsZHJlbiA9IFt0cmVlXTsKICByZXR1cm4gdHJlZTsKfQoKLy8gTm9kZS1saW5r
IHRyZWUgZGlhZ3JhbSB1c2luZyB0aGUgUmVpbmdvbGQtVGlsZm9yZCAidGlkeSIgYWxnb3JpdGht
CmZ1bmN0aW9uIHRyZWUoKSB7CiAgdmFyIHNlcGFyYXRpb24gPSBkZWZhdWx0U2VwYXJhdGlvbiQx
LAogICAgICBkeCA9IDEsCiAgICAgIGR5ID0gMSwKICAgICAgbm9kZVNpemUgPSBudWxsOwoKICBm
dW5jdGlvbiB0cmVlKHJvb3QpIHsKICAgIHZhciB0ID0gdHJlZVJvb3Qocm9vdCk7CgogICAgLy8g
Q29tcHV0ZSB0aGUgbGF5b3V0IHVzaW5nIEJ1Y2hoZWltIGV0IGFsLuKAmXMgYWxnb3JpdGhtLgog
ICAgdC5lYWNoQWZ0ZXIoZmlyc3RXYWxrKSwgdC5wYXJlbnQubSA9IC10Lno7CiAgICB0LmVhY2hC
ZWZvcmUoc2Vjb25kV2Fsayk7CgogICAgLy8gSWYgYSBmaXhlZCBub2RlIHNpemUgaXMgc3BlY2lm
aWVkLCBzY2FsZSB4IGFuZCB5LgogICAgaWYgKG5vZGVTaXplKSByb290LmVhY2hCZWZvcmUoc2l6
ZU5vZGUpOwoKICAgIC8vIElmIGEgZml4ZWQgdHJlZSBzaXplIGlzIHNwZWNpZmllZCwgc2NhbGUg
eCBhbmQgeSBiYXNlZCBvbiB0aGUgZXh0ZW50LgogICAgLy8gQ29tcHV0ZSB0aGUgbGVmdC1tb3N0
LCByaWdodC1tb3N0LCBhbmQgZGVwdGgtbW9zdCBub2RlcyBmb3IgZXh0ZW50cy4KICAgIGVsc2Ug
ewogICAgICB2YXIgbGVmdCA9IHJvb3QsCiAgICAgICAgICByaWdodCA9IHJvb3QsCiAgICAgICAg
ICBib3R0b20gPSByb290OwogICAgICByb290LmVhY2hCZWZvcmUoZnVuY3Rpb24obm9kZSkgewog
ICAgICAgIGlmIChub2RlLnggPCBsZWZ0LngpIGxlZnQgPSBub2RlOwogICAgICAgIGlmIChub2Rl
LnggPiByaWdodC54KSByaWdodCA9IG5vZGU7CiAgICAgICAgaWYgKG5vZGUuZGVwdGggPiBib3R0
b20uZGVwdGgpIGJvdHRvbSA9IG5vZGU7CiAgICAgIH0pOwogICAgICB2YXIgcyA9IGxlZnQgPT09
IHJpZ2h0ID8gMSA6IHNlcGFyYXRpb24obGVmdCwgcmlnaHQpIC8gMiwKICAgICAgICAgIHR4ID0g
cyAtIGxlZnQueCwKICAgICAgICAgIGt4ID0gZHggLyAocmlnaHQueCArIHMgKyB0eCksCiAgICAg
ICAgICBreSA9IGR5IC8gKGJvdHRvbS5kZXB0aCB8fCAxKTsKICAgICAgcm9vdC5lYWNoQmVmb3Jl
KGZ1bmN0aW9uKG5vZGUpIHsKICAgICAgICBub2RlLnggPSAobm9kZS54ICsgdHgpICoga3g7CiAg
ICAgICAgbm9kZS55ID0gbm9kZS5kZXB0aCAqIGt5OwogICAgICB9KTsKICAgIH0KCiAgICByZXR1
cm4gcm9vdDsKICB9CgogIC8vIENvbXB1dGVzIGEgcHJlbGltaW5hcnkgeC1jb29yZGluYXRlIGZv
ciB2LiBCZWZvcmUgdGhhdCwgRklSU1QgV0FMSyBpcwogIC8vIGFwcGxpZWQgcmVjdXJzaXZlbHkg
dG8gdGhlIGNoaWxkcmVuIG9mIHYsIGFzIHdlbGwgYXMgdGhlIGZ1bmN0aW9uCiAgLy8gQVBQT1JU
SU9OLiBBZnRlciBzcGFjaW5nIG91dCB0aGUgY2hpbGRyZW4gYnkgY2FsbGluZyBFWEVDVVRFIFNI
SUZUUywgdGhlCiAgLy8gbm9kZSB2IGlzIHBsYWNlZCB0byB0aGUgbWlkcG9pbnQgb2YgaXRzIG91
dGVybW9zdCBjaGlsZHJlbi4KICBmdW5jdGlvbiBmaXJzdFdhbGsodikgewogICAgdmFyIGNoaWxk
cmVuID0gdi5jaGlsZHJlbiwKICAgICAgICBzaWJsaW5ncyA9IHYucGFyZW50LmNoaWxkcmVuLAog
ICAgICAgIHcgPSB2LmkgPyBzaWJsaW5nc1t2LmkgLSAxXSA6IG51bGw7CiAgICBpZiAoY2hpbGRy
ZW4pIHsKICAgICAgZXhlY3V0ZVNoaWZ0cyh2KTsKICAgICAgdmFyIG1pZHBvaW50ID0gKGNoaWxk
cmVuWzBdLnogKyBjaGlsZHJlbltjaGlsZHJlbi5sZW5ndGggLSAxXS56KSAvIDI7CiAgICAgIGlm
ICh3KSB7CiAgICAgICAgdi56ID0gdy56ICsgc2VwYXJhdGlvbih2Ll8sIHcuXyk7CiAgICAgICAg
di5tID0gdi56IC0gbWlkcG9pbnQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdi56ID0gbWlkcG9p
bnQ7CiAgICAgIH0KICAgIH0gZWxzZSBpZiAodykgewogICAgICB2LnogPSB3LnogKyBzZXBhcmF0
aW9uKHYuXywgdy5fKTsKICAgIH0KICAgIHYucGFyZW50LkEgPSBhcHBvcnRpb24odiwgdywgdi5w
YXJlbnQuQSB8fCBzaWJsaW5nc1swXSk7CiAgfQoKICAvLyBDb21wdXRlcyBhbGwgcmVhbCB4LWNv
b3JkaW5hdGVzIGJ5IHN1bW1pbmcgdXAgdGhlIG1vZGlmaWVycyByZWN1cnNpdmVseS4KICBmdW5j
dGlvbiBzZWNvbmRXYWxrKHYpIHsKICAgIHYuXy54ID0gdi56ICsgdi5wYXJlbnQubTsKICAgIHYu
bSArPSB2LnBhcmVudC5tOwogIH0KCiAgLy8gVGhlIGNvcmUgb2YgdGhlIGFsZ29yaXRobS4gSGVy
ZSwgYSBuZXcgc3VidHJlZSBpcyBjb21iaW5lZCB3aXRoIHRoZQogIC8vIHByZXZpb3VzIHN1YnRy
ZWVzLiBUaHJlYWRzIGFyZSB1c2VkIHRvIHRyYXZlcnNlIHRoZSBpbnNpZGUgYW5kIG91dHNpZGUK
ICAvLyBjb250b3VycyBvZiB0aGUgbGVmdCBhbmQgcmlnaHQgc3VidHJlZSB1cCB0byB0aGUgaGln
aGVzdCBjb21tb24gbGV2ZWwuIFRoZQogIC8vIHZlcnRpY2VzIHVzZWQgZm9yIHRoZSB0cmF2ZXJz
YWxzIGFyZSB2aSssIHZpLSwgdm8tLCBhbmQgdm8rLCB3aGVyZSB0aGUKICAvLyBzdXBlcnNjcmlw
dCBvIG1lYW5zIG91dHNpZGUgYW5kIGkgbWVhbnMgaW5zaWRlLCB0aGUgc3Vic2NyaXB0IC0gbWVh
bnMgbGVmdAogIC8vIHN1YnRyZWUgYW5kICsgbWVhbnMgcmlnaHQgc3VidHJlZS4gRm9yIHN1bW1p
bmcgdXAgdGhlIG1vZGlmaWVycyBhbG9uZyB0aGUKICAvLyBjb250b3VyLCB3ZSB1c2UgcmVzcGVj
dGl2ZSB2YXJpYWJsZXMgc2krLCBzaS0sIHNvLSwgYW5kIHNvKy4gV2hlbmV2ZXIgdHdvCiAgLy8g
bm9kZXMgb2YgdGhlIGluc2lkZSBjb250b3VycyBjb25mbGljdCwgd2UgY29tcHV0ZSB0aGUgbGVm
dCBvbmUgb2YgdGhlCiAgLy8gZ3JlYXRlc3QgdW5jb21tb24gYW5jZXN0b3JzIHVzaW5nIHRoZSBm
dW5jdGlvbiBBTkNFU1RPUiBhbmQgY2FsbCBNT1ZFCiAgLy8gU1VCVFJFRSB0byBzaGlmdCB0aGUg
c3VidHJlZSBhbmQgcHJlcGFyZSB0aGUgc2hpZnRzIG9mIHNtYWxsZXIgc3VidHJlZXMuCiAgLy8g
RmluYWxseSwgd2UgYWRkIGEgbmV3IHRocmVhZCAoaWYgbmVjZXNzYXJ5KS4KICBmdW5jdGlvbiBh
cHBvcnRpb24odiwgdywgYW5jZXN0b3IpIHsKICAgIGlmICh3KSB7CiAgICAgIHZhciB2aXAgPSB2
LAogICAgICAgICAgdm9wID0gdiwKICAgICAgICAgIHZpbSA9IHcsCiAgICAgICAgICB2b20gPSB2
aXAucGFyZW50LmNoaWxkcmVuWzBdLAogICAgICAgICAgc2lwID0gdmlwLm0sCiAgICAgICAgICBz
b3AgPSB2b3AubSwKICAgICAgICAgIHNpbSA9IHZpbS5tLAogICAgICAgICAgc29tID0gdm9tLm0s
CiAgICAgICAgICBzaGlmdDsKICAgICAgd2hpbGUgKHZpbSA9IG5leHRSaWdodCh2aW0pLCB2aXAg
PSBuZXh0TGVmdCh2aXApLCB2aW0gJiYgdmlwKSB7CiAgICAgICAgdm9tID0gbmV4dExlZnQodm9t
KTsKICAgICAgICB2b3AgPSBuZXh0UmlnaHQodm9wKTsKICAgICAgICB2b3AuYSA9IHY7CiAgICAg
ICAgc2hpZnQgPSB2aW0ueiArIHNpbSAtIHZpcC56IC0gc2lwICsgc2VwYXJhdGlvbih2aW0uXywg
dmlwLl8pOwogICAgICAgIGlmIChzaGlmdCA+IDApIHsKICAgICAgICAgIG1vdmVTdWJ0cmVlKG5l
eHRBbmNlc3Rvcih2aW0sIHYsIGFuY2VzdG9yKSwgdiwgc2hpZnQpOwogICAgICAgICAgc2lwICs9
IHNoaWZ0OwogICAgICAgICAgc29wICs9IHNoaWZ0OwogICAgICAgIH0KICAgICAgICBzaW0gKz0g
dmltLm07CiAgICAgICAgc2lwICs9IHZpcC5tOwogICAgICAgIHNvbSArPSB2b20ubTsKICAgICAg
ICBzb3AgKz0gdm9wLm07CiAgICAgIH0KICAgICAgaWYgKHZpbSAmJiAhbmV4dFJpZ2h0KHZvcCkp
IHsKICAgICAgICB2b3AudCA9IHZpbTsKICAgICAgICB2b3AubSArPSBzaW0gLSBzb3A7CiAgICAg
IH0KICAgICAgaWYgKHZpcCAmJiAhbmV4dExlZnQodm9tKSkgewogICAgICAgIHZvbS50ID0gdmlw
OwogICAgICAgIHZvbS5tICs9IHNpcCAtIHNvbTsKICAgICAgICBhbmNlc3RvciA9IHY7CiAgICAg
IH0KICAgIH0KICAgIHJldHVybiBhbmNlc3RvcjsKICB9CgogIGZ1bmN0aW9uIHNpemVOb2RlKG5v
ZGUpIHsKICAgIG5vZGUueCAqPSBkeDsKICAgIG5vZGUueSA9IG5vZGUuZGVwdGggKiBkeTsKICB9
CgogIHRyZWUuc2VwYXJhdGlvbiA9IGZ1bmN0aW9uKHgpIHsKICAgIHJldHVybiBhcmd1bWVudHMu
bGVuZ3RoID8gKHNlcGFyYXRpb24gPSB4LCB0cmVlKSA6IHNlcGFyYXRpb247CiAgfTsKCiAgdHJl
ZS5zaXplID0gZnVuY3Rpb24oeCkgewogICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAobm9k
ZVNpemUgPSBmYWxzZSwgZHggPSAreFswXSwgZHkgPSAreFsxXSwgdHJlZSkgOiAobm9kZVNpemUg
PyBudWxsIDogW2R4LCBkeV0pOwogIH07CgogIHRyZWUubm9kZVNpemUgPSBmdW5jdGlvbih4KSB7
CiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChub2RlU2l6ZSA9IHRydWUsIGR4ID0gK3hb
MF0sIGR5ID0gK3hbMV0sIHRyZWUpIDogKG5vZGVTaXplID8gW2R4LCBkeV0gOiBudWxsKTsKICB9
OwoKICByZXR1cm4gdHJlZTsKfQoKZnVuY3Rpb24gdHJlZW1hcFNsaWNlKHBhcmVudCwgeDAsIHkw
LCB4MSwgeTEpIHsKICB2YXIgbm9kZXMgPSBwYXJlbnQuY2hpbGRyZW4sCiAgICAgIG5vZGUsCiAg
ICAgIGkgPSAtMSwKICAgICAgbiA9IG5vZGVzLmxlbmd0aCwKICAgICAgayA9IHBhcmVudC52YWx1
ZSAmJiAoeTEgLSB5MCkgLyBwYXJlbnQudmFsdWU7CgogIHdoaWxlICgrK2kgPCBuKSB7CiAgICBu
b2RlID0gbm9kZXNbaV0sIG5vZGUueDAgPSB4MCwgbm9kZS54MSA9IHgxOwogICAgbm9kZS55MCA9
IHkwLCBub2RlLnkxID0geTAgKz0gbm9kZS52YWx1ZSAqIGs7CiAgfQp9Cgp2YXIgcGhpID0gKDEg
KyBNYXRoLnNxcnQoNSkpIC8gMjsKCmZ1bmN0aW9uIHNxdWFyaWZ5UmF0aW8ocmF0aW8sIHBhcmVu
dCwgeDAsIHkwLCB4MSwgeTEpIHsKICB2YXIgcm93cyA9IFtdLAogICAgICBub2RlcyA9IHBhcmVu
dC5jaGlsZHJlbiwKICAgICAgcm93LAogICAgICBub2RlVmFsdWUsCiAgICAgIGkwID0gMCwKICAg
ICAgaTEgPSAwLAogICAgICBuID0gbm9kZXMubGVuZ3RoLAogICAgICBkeCwgZHksCiAgICAgIHZh
bHVlID0gcGFyZW50LnZhbHVlLAogICAgICBzdW1WYWx1ZSwKICAgICAgbWluVmFsdWUsCiAgICAg
IG1heFZhbHVlLAogICAgICBuZXdSYXRpbywKICAgICAgbWluUmF0aW8sCiAgICAgIGFscGhhLAog
ICAgICBiZXRhOwoKICB3aGlsZSAoaTAgPCBuKSB7CiAgICBkeCA9IHgxIC0geDAsIGR5ID0geTEg
LSB5MDsKCiAgICAvLyBGaW5kIHRoZSBuZXh0IG5vbi1lbXB0eSBub2RlLgogICAgZG8gc3VtVmFs
dWUgPSBub2Rlc1tpMSsrXS52YWx1ZTsgd2hpbGUgKCFzdW1WYWx1ZSAmJiBpMSA8IG4pOwogICAg
bWluVmFsdWUgPSBtYXhWYWx1ZSA9IHN1bVZhbHVlOwogICAgYWxwaGEgPSBNYXRoLm1heChkeSAv
IGR4LCBkeCAvIGR5KSAvICh2YWx1ZSAqIHJhdGlvKTsKICAgIGJldGEgPSBzdW1WYWx1ZSAqIHN1
bVZhbHVlICogYWxwaGE7CiAgICBtaW5SYXRpbyA9IE1hdGgubWF4KG1heFZhbHVlIC8gYmV0YSwg
YmV0YSAvIG1pblZhbHVlKTsKCiAgICAvLyBLZWVwIGFkZGluZyBub2RlcyB3aGlsZSB0aGUgYXNw
ZWN0IHJhdGlvIG1haW50YWlucyBvciBpbXByb3Zlcy4KICAgIGZvciAoOyBpMSA8IG47ICsraTEp
IHsKICAgICAgc3VtVmFsdWUgKz0gbm9kZVZhbHVlID0gbm9kZXNbaTFdLnZhbHVlOwogICAgICBp
ZiAobm9kZVZhbHVlIDwgbWluVmFsdWUpIG1pblZhbHVlID0gbm9kZVZhbHVlOwogICAgICBpZiAo
bm9kZVZhbHVlID4gbWF4VmFsdWUpIG1heFZhbHVlID0gbm9kZVZhbHVlOwogICAgICBiZXRhID0g
c3VtVmFsdWUgKiBzdW1WYWx1ZSAqIGFscGhhOwogICAgICBuZXdSYXRpbyA9IE1hdGgubWF4KG1h
eFZhbHVlIC8gYmV0YSwgYmV0YSAvIG1pblZhbHVlKTsKICAgICAgaWYgKG5ld1JhdGlvID4gbWlu
UmF0aW8pIHsgc3VtVmFsdWUgLT0gbm9kZVZhbHVlOyBicmVhazsgfQogICAgICBtaW5SYXRpbyA9
IG5ld1JhdGlvOwogICAgfQoKICAgIC8vIFBvc2l0aW9uIGFuZCByZWNvcmQgdGhlIHJvdyBvcmll
bnRhdGlvbi4KICAgIHJvd3MucHVzaChyb3cgPSB7dmFsdWU6IHN1bVZhbHVlLCBkaWNlOiBkeCA8
IGR5LCBjaGlsZHJlbjogbm9kZXMuc2xpY2UoaTAsIGkxKX0pOwogICAgaWYgKHJvdy5kaWNlKSB0
cmVlbWFwRGljZShyb3csIHgwLCB5MCwgeDEsIHZhbHVlID8geTAgKz0gZHkgKiBzdW1WYWx1ZSAv
IHZhbHVlIDogeTEpOwogICAgZWxzZSB0cmVlbWFwU2xpY2Uocm93LCB4MCwgeTAsIHZhbHVlID8g
eDAgKz0gZHggKiBzdW1WYWx1ZSAvIHZhbHVlIDogeDEsIHkxKTsKICAgIHZhbHVlIC09IHN1bVZh
bHVlLCBpMCA9IGkxOwogIH0KCiAgcmV0dXJuIHJvd3M7Cn0KCnZhciBzcXVhcmlmeSA9IChmdW5j
dGlvbiBjdXN0b20ocmF0aW8pIHsKCiAgZnVuY3Rpb24gc3F1YXJpZnkocGFyZW50LCB4MCwgeTAs
IHgxLCB5MSkgewogICAgc3F1YXJpZnlSYXRpbyhyYXRpbywgcGFyZW50LCB4MCwgeTAsIHgxLCB5
MSk7CiAgfQoKICBzcXVhcmlmeS5yYXRpbyA9IGZ1bmN0aW9uKHgpIHsKICAgIHJldHVybiBjdXN0
b20oKHggPSAreCkgPiAxID8geCA6IDEpOwogIH07CgogIHJldHVybiBzcXVhcmlmeTsKfSkocGhp
KTsKCmZ1bmN0aW9uIGluZGV4JDMoKSB7CiAgdmFyIHRpbGUgPSBzcXVhcmlmeSwKICAgICAgcm91
bmQgPSBmYWxzZSwKICAgICAgZHggPSAxLAogICAgICBkeSA9IDEsCiAgICAgIHBhZGRpbmdTdGFj
ayA9IFswXSwKICAgICAgcGFkZGluZ0lubmVyID0gY29uc3RhbnRaZXJvLAogICAgICBwYWRkaW5n
VG9wID0gY29uc3RhbnRaZXJvLAogICAgICBwYWRkaW5nUmlnaHQgPSBjb25zdGFudFplcm8sCiAg
ICAgIHBhZGRpbmdCb3R0b20gPSBjb25zdGFudFplcm8sCiAgICAgIHBhZGRpbmdMZWZ0ID0gY29u
c3RhbnRaZXJvOwoKICBmdW5jdGlvbiB0cmVlbWFwKHJvb3QpIHsKICAgIHJvb3QueDAgPQogICAg
cm9vdC55MCA9IDA7CiAgICByb290LngxID0gZHg7CiAgICByb290LnkxID0gZHk7CiAgICByb290
LmVhY2hCZWZvcmUocG9zaXRpb25Ob2RlKTsKICAgIHBhZGRpbmdTdGFjayA9IFswXTsKICAgIGlm
IChyb3VuZCkgcm9vdC5lYWNoQmVmb3JlKHJvdW5kTm9kZSk7CiAgICByZXR1cm4gcm9vdDsKICB9
CgogIGZ1bmN0aW9uIHBvc2l0aW9uTm9kZShub2RlKSB7CiAgICB2YXIgcCA9IHBhZGRpbmdTdGFj
a1tub2RlLmRlcHRoXSwKICAgICAgICB4MCA9IG5vZGUueDAgKyBwLAogICAgICAgIHkwID0gbm9k
ZS55MCArIHAsCiAgICAgICAgeDEgPSBub2RlLngxIC0gcCwKICAgICAgICB5MSA9IG5vZGUueTEg
LSBwOwogICAgaWYgKHgxIDwgeDApIHgwID0geDEgPSAoeDAgKyB4MSkgLyAyOwogICAgaWYgKHkx
IDwgeTApIHkwID0geTEgPSAoeTAgKyB5MSkgLyAyOwogICAgbm9kZS54MCA9IHgwOwogICAgbm9k
ZS55MCA9IHkwOwogICAgbm9kZS54MSA9IHgxOwogICAgbm9kZS55MSA9IHkxOwogICAgaWYgKG5v
ZGUuY2hpbGRyZW4pIHsKICAgICAgcCA9IHBhZGRpbmdTdGFja1tub2RlLmRlcHRoICsgMV0gPSBw
YWRkaW5nSW5uZXIobm9kZSkgLyAyOwogICAgICB4MCArPSBwYWRkaW5nTGVmdChub2RlKSAtIHA7
CiAgICAgIHkwICs9IHBhZGRpbmdUb3Aobm9kZSkgLSBwOwogICAgICB4MSAtPSBwYWRkaW5nUmln
aHQobm9kZSkgLSBwOwogICAgICB5MSAtPSBwYWRkaW5nQm90dG9tKG5vZGUpIC0gcDsKICAgICAg
aWYgKHgxIDwgeDApIHgwID0geDEgPSAoeDAgKyB4MSkgLyAyOwogICAgICBpZiAoeTEgPCB5MCkg
eTAgPSB5MSA9ICh5MCArIHkxKSAvIDI7CiAgICAgIHRpbGUobm9kZSwgeDAsIHkwLCB4MSwgeTEp
OwogICAgfQogIH0KCiAgdHJlZW1hcC5yb3VuZCA9IGZ1bmN0aW9uKHgpIHsKICAgIHJldHVybiBh
cmd1bWVudHMubGVuZ3RoID8gKHJvdW5kID0gISF4LCB0cmVlbWFwKSA6IHJvdW5kOwogIH07Cgog
IHRyZWVtYXAuc2l6ZSA9IGZ1bmN0aW9uKHgpIHsKICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3Ro
ID8gKGR4ID0gK3hbMF0sIGR5ID0gK3hbMV0sIHRyZWVtYXApIDogW2R4LCBkeV07CiAgfTsKCiAg
dHJlZW1hcC50aWxlID0gZnVuY3Rpb24oeCkgewogICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGgg
PyAodGlsZSA9IHJlcXVpcmVkKHgpLCB0cmVlbWFwKSA6IHRpbGU7CiAgfTsKCiAgdHJlZW1hcC5w
YWRkaW5nID0gZnVuY3Rpb24oeCkgewogICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyB0cmVl
bWFwLnBhZGRpbmdJbm5lcih4KS5wYWRkaW5nT3V0ZXIoeCkgOiB0cmVlbWFwLnBhZGRpbmdJbm5l
cigpOwogIH07CgogIHRyZWVtYXAucGFkZGluZ0lubmVyID0gZnVuY3Rpb24oeCkgewogICAgcmV0
dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAocGFkZGluZ0lubmVyID0gdHlwZW9mIHggPT09ICJmdW5j
dGlvbiIgPyB4IDogY29uc3RhbnQkOSgreCksIHRyZWVtYXApIDogcGFkZGluZ0lubmVyOwogIH07
CgogIHRyZWVtYXAucGFkZGluZ091dGVyID0gZnVuY3Rpb24oeCkgewogICAgcmV0dXJuIGFyZ3Vt
ZW50cy5sZW5ndGggPyB0cmVlbWFwLnBhZGRpbmdUb3AoeCkucGFkZGluZ1JpZ2h0KHgpLnBhZGRp
bmdCb3R0b20oeCkucGFkZGluZ0xlZnQoeCkgOiB0cmVlbWFwLnBhZGRpbmdUb3AoKTsKICB9OwoK
ICB0cmVlbWFwLnBhZGRpbmdUb3AgPSBmdW5jdGlvbih4KSB7CiAgICByZXR1cm4gYXJndW1lbnRz
Lmxlbmd0aCA/IChwYWRkaW5nVG9wID0gdHlwZW9mIHggPT09ICJmdW5jdGlvbiIgPyB4IDogY29u
c3RhbnQkOSgreCksIHRyZWVtYXApIDogcGFkZGluZ1RvcDsKICB9OwoKICB0cmVlbWFwLnBhZGRp
bmdSaWdodCA9IGZ1bmN0aW9uKHgpIHsKICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHBh
ZGRpbmdSaWdodCA9IHR5cGVvZiB4ID09PSAiZnVuY3Rpb24iID8geCA6IGNvbnN0YW50JDkoK3gp
LCB0cmVlbWFwKSA6IHBhZGRpbmdSaWdodDsKICB9OwoKICB0cmVlbWFwLnBhZGRpbmdCb3R0b20g
PSBmdW5jdGlvbih4KSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChwYWRkaW5nQm90
dG9tID0gdHlwZW9mIHggPT09ICJmdW5jdGlvbiIgPyB4IDogY29uc3RhbnQkOSgreCksIHRyZWVt
YXApIDogcGFkZGluZ0JvdHRvbTsKICB9OwoKICB0cmVlbWFwLnBhZGRpbmdMZWZ0ID0gZnVuY3Rp
b24oeCkgewogICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAocGFkZGluZ0xlZnQgPSB0eXBl
b2YgeCA9PT0gImZ1bmN0aW9uIiA/IHggOiBjb25zdGFudCQ5KCt4KSwgdHJlZW1hcCkgOiBwYWRk
aW5nTGVmdDsKICB9OwoKICByZXR1cm4gdHJlZW1hcDsKfQoKZnVuY3Rpb24gYmluYXJ5KHBhcmVu
dCwgeDAsIHkwLCB4MSwgeTEpIHsKICB2YXIgbm9kZXMgPSBwYXJlbnQuY2hpbGRyZW4sCiAgICAg
IGksIG4gPSBub2Rlcy5sZW5ndGgsCiAgICAgIHN1bSwgc3VtcyA9IG5ldyBBcnJheShuICsgMSk7
CgogIGZvciAoc3Vtc1swXSA9IHN1bSA9IGkgPSAwOyBpIDwgbjsgKytpKSB7CiAgICBzdW1zW2kg
KyAxXSA9IHN1bSArPSBub2Rlc1tpXS52YWx1ZTsKICB9CgogIHBhcnRpdGlvbigwLCBuLCBwYXJl
bnQudmFsdWUsIHgwLCB5MCwgeDEsIHkxKTsKCiAgZnVuY3Rpb24gcGFydGl0aW9uKGksIGosIHZh
bHVlLCB4MCwgeTAsIHgxLCB5MSkgewogICAgaWYgKGkgPj0gaiAtIDEpIHsKICAgICAgdmFyIG5v
ZGUgPSBub2Rlc1tpXTsKICAgICAgbm9kZS54MCA9IHgwLCBub2RlLnkwID0geTA7CiAgICAgIG5v
ZGUueDEgPSB4MSwgbm9kZS55MSA9IHkxOwogICAgICByZXR1cm47CiAgICB9CgogICAgdmFyIHZh
bHVlT2Zmc2V0ID0gc3Vtc1tpXSwKICAgICAgICB2YWx1ZVRhcmdldCA9ICh2YWx1ZSAvIDIpICsg
dmFsdWVPZmZzZXQsCiAgICAgICAgayA9IGkgKyAxLAogICAgICAgIGhpID0gaiAtIDE7CgogICAg
d2hpbGUgKGsgPCBoaSkgewogICAgICB2YXIgbWlkID0gayArIGhpID4+PiAxOwogICAgICBpZiAo
c3Vtc1ttaWRdIDwgdmFsdWVUYXJnZXQpIGsgPSBtaWQgKyAxOwogICAgICBlbHNlIGhpID0gbWlk
OwogICAgfQoKICAgIGlmICgodmFsdWVUYXJnZXQgLSBzdW1zW2sgLSAxXSkgPCAoc3Vtc1trXSAt
IHZhbHVlVGFyZ2V0KSAmJiBpICsgMSA8IGspIC0tazsKCiAgICB2YXIgdmFsdWVMZWZ0ID0gc3Vt
c1trXSAtIHZhbHVlT2Zmc2V0LAogICAgICAgIHZhbHVlUmlnaHQgPSB2YWx1ZSAtIHZhbHVlTGVm
dDsKCiAgICBpZiAoKHgxIC0geDApID4gKHkxIC0geTApKSB7CiAgICAgIHZhciB4ayA9ICh4MCAq
IHZhbHVlUmlnaHQgKyB4MSAqIHZhbHVlTGVmdCkgLyB2YWx1ZTsKICAgICAgcGFydGl0aW9uKGks
IGssIHZhbHVlTGVmdCwgeDAsIHkwLCB4aywgeTEpOwogICAgICBwYXJ0aXRpb24oaywgaiwgdmFs
dWVSaWdodCwgeGssIHkwLCB4MSwgeTEpOwogICAgfSBlbHNlIHsKICAgICAgdmFyIHlrID0gKHkw
ICogdmFsdWVSaWdodCArIHkxICogdmFsdWVMZWZ0KSAvIHZhbHVlOwogICAgICBwYXJ0aXRpb24o
aSwgaywgdmFsdWVMZWZ0LCB4MCwgeTAsIHgxLCB5ayk7CiAgICAgIHBhcnRpdGlvbihrLCBqLCB2
YWx1ZVJpZ2h0LCB4MCwgeWssIHgxLCB5MSk7CiAgICB9CiAgfQp9CgpmdW5jdGlvbiBzbGljZURp
Y2UocGFyZW50LCB4MCwgeTAsIHgxLCB5MSkgewogIChwYXJlbnQuZGVwdGggJiAxID8gdHJlZW1h
cFNsaWNlIDogdHJlZW1hcERpY2UpKHBhcmVudCwgeDAsIHkwLCB4MSwgeTEpOwp9Cgp2YXIgcmVz
cXVhcmlmeSA9IChmdW5jdGlvbiBjdXN0b20ocmF0aW8pIHsKCiAgZnVuY3Rpb24gcmVzcXVhcmlm
eShwYXJlbnQsIHgwLCB5MCwgeDEsIHkxKSB7CiAgICBpZiAoKHJvd3MgPSBwYXJlbnQuX3NxdWFy
aWZ5KSAmJiAocm93cy5yYXRpbyA9PT0gcmF0aW8pKSB7CiAgICAgIHZhciByb3dzLAogICAgICAg
ICAgcm93LAogICAgICAgICAgbm9kZXMsCiAgICAgICAgICBpLAogICAgICAgICAgaiA9IC0xLAog
ICAgICAgICAgbiwKICAgICAgICAgIG0gPSByb3dzLmxlbmd0aCwKICAgICAgICAgIHZhbHVlID0g
cGFyZW50LnZhbHVlOwoKICAgICAgd2hpbGUgKCsraiA8IG0pIHsKICAgICAgICByb3cgPSByb3dz
W2pdLCBub2RlcyA9IHJvdy5jaGlsZHJlbjsKICAgICAgICBmb3IgKGkgPSByb3cudmFsdWUgPSAw
LCBuID0gbm9kZXMubGVuZ3RoOyBpIDwgbjsgKytpKSByb3cudmFsdWUgKz0gbm9kZXNbaV0udmFs
dWU7CiAgICAgICAgaWYgKHJvdy5kaWNlKSB0cmVlbWFwRGljZShyb3csIHgwLCB5MCwgeDEsIHkw
ICs9ICh5MSAtIHkwKSAqIHJvdy52YWx1ZSAvIHZhbHVlKTsKICAgICAgICBlbHNlIHRyZWVtYXBT
bGljZShyb3csIHgwLCB5MCwgeDAgKz0gKHgxIC0geDApICogcm93LnZhbHVlIC8gdmFsdWUsIHkx
KTsKICAgICAgICB2YWx1ZSAtPSByb3cudmFsdWU7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAg
IHBhcmVudC5fc3F1YXJpZnkgPSByb3dzID0gc3F1YXJpZnlSYXRpbyhyYXRpbywgcGFyZW50LCB4
MCwgeTAsIHgxLCB5MSk7CiAgICAgIHJvd3MucmF0aW8gPSByYXRpbzsKICAgIH0KICB9CgogIHJl
c3F1YXJpZnkucmF0aW8gPSBmdW5jdGlvbih4KSB7CiAgICByZXR1cm4gY3VzdG9tKCh4ID0gK3gp
ID4gMSA/IHggOiAxKTsKICB9OwoKICByZXR1cm4gcmVzcXVhcmlmeTsKfSkocGhpKTsKCmZ1bmN0
aW9uIGFyZWEkMihwb2x5Z29uKSB7CiAgdmFyIGkgPSAtMSwKICAgICAgbiA9IHBvbHlnb24ubGVu
Z3RoLAogICAgICBhLAogICAgICBiID0gcG9seWdvbltuIC0gMV0sCiAgICAgIGFyZWEgPSAwOwoK
ICB3aGlsZSAoKytpIDwgbikgewogICAgYSA9IGI7CiAgICBiID0gcG9seWdvbltpXTsKICAgIGFy
ZWEgKz0gYVsxXSAqIGJbMF0gLSBhWzBdICogYlsxXTsKICB9CgogIHJldHVybiBhcmVhIC8gMjsK
fQoKZnVuY3Rpb24gY2VudHJvaWQkMShwb2x5Z29uKSB7CiAgdmFyIGkgPSAtMSwKICAgICAgbiA9
IHBvbHlnb24ubGVuZ3RoLAogICAgICB4ID0gMCwKICAgICAgeSA9IDAsCiAgICAgIGEsCiAgICAg
IGIgPSBwb2x5Z29uW24gLSAxXSwKICAgICAgYywKICAgICAgayA9IDA7CgogIHdoaWxlICgrK2kg
PCBuKSB7CiAgICBhID0gYjsKICAgIGIgPSBwb2x5Z29uW2ldOwogICAgayArPSBjID0gYVswXSAq
IGJbMV0gLSBiWzBdICogYVsxXTsKICAgIHggKz0gKGFbMF0gKyBiWzBdKSAqIGM7CiAgICB5ICs9
IChhWzFdICsgYlsxXSkgKiBjOwogIH0KCiAgcmV0dXJuIGsgKj0gMywgW3ggLyBrLCB5IC8ga107
Cn0KCi8vIFJldHVybnMgdGhlIDJEIGNyb3NzIHByb2R1Y3Qgb2YgQUIgYW5kIEFDIHZlY3RvcnMs
IGkuZS4sIHRoZSB6LWNvbXBvbmVudCBvZgovLyB0aGUgM0QgY3Jvc3MgcHJvZHVjdCBpbiBhIHF1
YWRyYW50IEkgQ2FydGVzaWFuIGNvb3JkaW5hdGUgc3lzdGVtICgreCBpcwovLyByaWdodCwgK3kg
aXMgdXApLiBSZXR1cm5zIGEgcG9zaXRpdmUgdmFsdWUgaWYgQUJDIGlzIGNvdW50ZXItY2xvY2t3
aXNlLAovLyBuZWdhdGl2ZSBpZiBjbG9ja3dpc2UsIGFuZCB6ZXJvIGlmIHRoZSBwb2ludHMgYXJl
IGNvbGxpbmVhci4KZnVuY3Rpb24gY3Jvc3MkMShhLCBiLCBjKSB7CiAgcmV0dXJuIChiWzBdIC0g
YVswXSkgKiAoY1sxXSAtIGFbMV0pIC0gKGJbMV0gLSBhWzFdKSAqIChjWzBdIC0gYVswXSk7Cn0K
CmZ1bmN0aW9uIGxleGljb2dyYXBoaWNPcmRlcihhLCBiKSB7CiAgcmV0dXJuIGFbMF0gLSBiWzBd
IHx8IGFbMV0gLSBiWzFdOwp9CgovLyBDb21wdXRlcyB0aGUgdXBwZXIgY29udmV4IGh1bGwgcGVy
IHRoZSBtb25vdG9uZSBjaGFpbiBhbGdvcml0aG0uCi8vIEFzc3VtZXMgcG9pbnRzLmxlbmd0aCA+
PSAzLCBpcyBzb3J0ZWQgYnkgeCwgdW5pcXVlIGluIHkuCi8vIFJldHVybnMgYW4gYXJyYXkgb2Yg
aW5kaWNlcyBpbnRvIHBvaW50cyBpbiBsZWZ0LXRvLXJpZ2h0IG9yZGVyLgpmdW5jdGlvbiBjb21w
dXRlVXBwZXJIdWxsSW5kZXhlcyhwb2ludHMpIHsKICB2YXIgbiA9IHBvaW50cy5sZW5ndGgsCiAg
ICAgIGluZGV4ZXMgPSBbMCwgMV0sCiAgICAgIHNpemUgPSAyOwoKICBmb3IgKHZhciBpID0gMjsg
aSA8IG47ICsraSkgewogICAgd2hpbGUgKHNpemUgPiAxICYmIGNyb3NzJDEocG9pbnRzW2luZGV4
ZXNbc2l6ZSAtIDJdXSwgcG9pbnRzW2luZGV4ZXNbc2l6ZSAtIDFdXSwgcG9pbnRzW2ldKSA8PSAw
KSAtLXNpemU7CiAgICBpbmRleGVzW3NpemUrK10gPSBpOwogIH0KCiAgcmV0dXJuIGluZGV4ZXMu
c2xpY2UoMCwgc2l6ZSk7IC8vIHJlbW92ZSBwb3BwZWQgcG9pbnRzCn0KCmZ1bmN0aW9uIGh1bGwo
cG9pbnRzKSB7CiAgaWYgKChuID0gcG9pbnRzLmxlbmd0aCkgPCAzKSByZXR1cm4gbnVsbDsKCiAg
dmFyIGksCiAgICAgIG4sCiAgICAgIHNvcnRlZFBvaW50cyA9IG5ldyBBcnJheShuKSwKICAgICAg
ZmxpcHBlZFBvaW50cyA9IG5ldyBBcnJheShuKTsKCiAgZm9yIChpID0gMDsgaSA8IG47ICsraSkg
c29ydGVkUG9pbnRzW2ldID0gWytwb2ludHNbaV1bMF0sICtwb2ludHNbaV1bMV0sIGldOwogIHNv
cnRlZFBvaW50cy5zb3J0KGxleGljb2dyYXBoaWNPcmRlcik7CiAgZm9yIChpID0gMDsgaSA8IG47
ICsraSkgZmxpcHBlZFBvaW50c1tpXSA9IFtzb3J0ZWRQb2ludHNbaV1bMF0sIC1zb3J0ZWRQb2lu
dHNbaV1bMV1dOwoKICB2YXIgdXBwZXJJbmRleGVzID0gY29tcHV0ZVVwcGVySHVsbEluZGV4ZXMo
c29ydGVkUG9pbnRzKSwKICAgICAgbG93ZXJJbmRleGVzID0gY29tcHV0ZVVwcGVySHVsbEluZGV4
ZXMoZmxpcHBlZFBvaW50cyk7CgogIC8vIENvbnN0cnVjdCB0aGUgaHVsbCBwb2x5Z29uLCByZW1v
dmluZyBwb3NzaWJsZSBkdXBsaWNhdGUgZW5kcG9pbnRzLgogIHZhciBza2lwTGVmdCA9IGxvd2Vy
SW5kZXhlc1swXSA9PT0gdXBwZXJJbmRleGVzWzBdLAogICAgICBza2lwUmlnaHQgPSBsb3dlcklu
ZGV4ZXNbbG93ZXJJbmRleGVzLmxlbmd0aCAtIDFdID09PSB1cHBlckluZGV4ZXNbdXBwZXJJbmRl
eGVzLmxlbmd0aCAtIDFdLAogICAgICBodWxsID0gW107CgogIC8vIEFkZCB1cHBlciBodWxsIGlu
IHJpZ2h0LXRvLWwgb3JkZXIuCiAgLy8gVGhlbiBhZGQgbG93ZXIgaHVsbCBpbiBsZWZ0LXRvLXJp
Z2h0IG9yZGVyLgogIGZvciAoaSA9IHVwcGVySW5kZXhlcy5sZW5ndGggLSAxOyBpID49IDA7IC0t
aSkgaHVsbC5wdXNoKHBvaW50c1tzb3J0ZWRQb2ludHNbdXBwZXJJbmRleGVzW2ldXVsyXV0pOwog
IGZvciAoaSA9ICtza2lwTGVmdDsgaSA8IGxvd2VySW5kZXhlcy5sZW5ndGggLSBza2lwUmlnaHQ7
ICsraSkgaHVsbC5wdXNoKHBvaW50c1tzb3J0ZWRQb2ludHNbbG93ZXJJbmRleGVzW2ldXVsyXV0p
OwoKICByZXR1cm4gaHVsbDsKfQoKZnVuY3Rpb24gY29udGFpbnMkMihwb2x5Z29uLCBwb2ludCkg
ewogIHZhciBuID0gcG9seWdvbi5sZW5ndGgsCiAgICAgIHAgPSBwb2x5Z29uW24gLSAxXSwKICAg
ICAgeCA9IHBvaW50WzBdLCB5ID0gcG9pbnRbMV0sCiAgICAgIHgwID0gcFswXSwgeTAgPSBwWzFd
LAogICAgICB4MSwgeTEsCiAgICAgIGluc2lkZSA9IGZhbHNlOwoKICBmb3IgKHZhciBpID0gMDsg
aSA8IG47ICsraSkgewogICAgcCA9IHBvbHlnb25baV0sIHgxID0gcFswXSwgeTEgPSBwWzFdOwog
ICAgaWYgKCgoeTEgPiB5KSAhPT0gKHkwID4geSkpICYmICh4IDwgKHgwIC0geDEpICogKHkgLSB5
MSkgLyAoeTAgLSB5MSkgKyB4MSkpIGluc2lkZSA9ICFpbnNpZGU7CiAgICB4MCA9IHgxLCB5MCA9
IHkxOwogIH0KCiAgcmV0dXJuIGluc2lkZTsKfQoKZnVuY3Rpb24gbGVuZ3RoJDIocG9seWdvbikg
ewogIHZhciBpID0gLTEsCiAgICAgIG4gPSBwb2x5Z29uLmxlbmd0aCwKICAgICAgYiA9IHBvbHln
b25bbiAtIDFdLAogICAgICB4YSwKICAgICAgeWEsCiAgICAgIHhiID0gYlswXSwKICAgICAgeWIg
PSBiWzFdLAogICAgICBwZXJpbWV0ZXIgPSAwOwoKICB3aGlsZSAoKytpIDwgbikgewogICAgeGEg
PSB4YjsKICAgIHlhID0geWI7CiAgICBiID0gcG9seWdvbltpXTsKICAgIHhiID0gYlswXTsKICAg
IHliID0gYlsxXTsKICAgIHhhIC09IHhiOwogICAgeWEgLT0geWI7CiAgICBwZXJpbWV0ZXIgKz0g
TWF0aC5zcXJ0KHhhICogeGEgKyB5YSAqIHlhKTsKICB9CgogIHJldHVybiBwZXJpbWV0ZXI7Cn0K
CmZ1bmN0aW9uIGRlZmF1bHRTb3VyY2UkMSgpIHsKICByZXR1cm4gTWF0aC5yYW5kb20oKTsKfQoK
dmFyIHVuaWZvcm0gPSAoZnVuY3Rpb24gc291cmNlUmFuZG9tVW5pZm9ybShzb3VyY2UpIHsKICBm
dW5jdGlvbiByYW5kb21Vbmlmb3JtKG1pbiwgbWF4KSB7CiAgICBtaW4gPSBtaW4gPT0gbnVsbCA/
IDAgOiArbWluOwogICAgbWF4ID0gbWF4ID09IG51bGwgPyAxIDogK21heDsKICAgIGlmIChhcmd1
bWVudHMubGVuZ3RoID09PSAxKSBtYXggPSBtaW4sIG1pbiA9IDA7CiAgICBlbHNlIG1heCAtPSBt
aW47CiAgICByZXR1cm4gZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBzb3VyY2UoKSAqIG1heCAr
IG1pbjsKICAgIH07CiAgfQoKICByYW5kb21Vbmlmb3JtLnNvdXJjZSA9IHNvdXJjZVJhbmRvbVVu
aWZvcm07CgogIHJldHVybiByYW5kb21Vbmlmb3JtOwp9KShkZWZhdWx0U291cmNlJDEpOwoKdmFy
IG5vcm1hbCA9IChmdW5jdGlvbiBzb3VyY2VSYW5kb21Ob3JtYWwoc291cmNlKSB7CiAgZnVuY3Rp
b24gcmFuZG9tTm9ybWFsKG11LCBzaWdtYSkgewogICAgdmFyIHgsIHI7CiAgICBtdSA9IG11ID09
IG51bGwgPyAwIDogK211OwogICAgc2lnbWEgPSBzaWdtYSA9PSBudWxsID8gMSA6ICtzaWdtYTsK
ICAgIHJldHVybiBmdW5jdGlvbigpIHsKICAgICAgdmFyIHk7CgogICAgICAvLyBJZiBhdmFpbGFi
bGUsIHVzZSB0aGUgc2Vjb25kIHByZXZpb3VzbHktZ2VuZXJhdGVkIHVuaWZvcm0gcmFuZG9tLgog
ICAgICBpZiAoeCAhPSBudWxsKSB5ID0geCwgeCA9IG51bGw7CgogICAgICAvLyBPdGhlcndpc2Us
IGdlbmVyYXRlIGEgbmV3IHggYW5kIHkuCiAgICAgIGVsc2UgZG8gewogICAgICAgIHggPSBzb3Vy
Y2UoKSAqIDIgLSAxOwogICAgICAgIHkgPSBzb3VyY2UoKSAqIDIgLSAxOwogICAgICAgIHIgPSB4
ICogeCArIHkgKiB5OwogICAgICB9IHdoaWxlICghciB8fCByID4gMSk7CgogICAgICByZXR1cm4g
bXUgKyBzaWdtYSAqIHkgKiBNYXRoLnNxcnQoLTIgKiBNYXRoLmxvZyhyKSAvIHIpOwogICAgfTsK
ICB9CgogIHJhbmRvbU5vcm1hbC5zb3VyY2UgPSBzb3VyY2VSYW5kb21Ob3JtYWw7CgogIHJldHVy
biByYW5kb21Ob3JtYWw7Cn0pKGRlZmF1bHRTb3VyY2UkMSk7Cgp2YXIgbG9nTm9ybWFsID0gKGZ1
bmN0aW9uIHNvdXJjZVJhbmRvbUxvZ05vcm1hbChzb3VyY2UpIHsKICBmdW5jdGlvbiByYW5kb21M
b2dOb3JtYWwoKSB7CiAgICB2YXIgcmFuZG9tTm9ybWFsID0gbm9ybWFsLnNvdXJjZShzb3VyY2Up
LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICByZXR1cm4gZnVuY3Rpb24oKSB7CiAgICAgIHJl
dHVybiBNYXRoLmV4cChyYW5kb21Ob3JtYWwoKSk7CiAgICB9OwogIH0KCiAgcmFuZG9tTG9nTm9y
bWFsLnNvdXJjZSA9IHNvdXJjZVJhbmRvbUxvZ05vcm1hbDsKCiAgcmV0dXJuIHJhbmRvbUxvZ05v
cm1hbDsKfSkoZGVmYXVsdFNvdXJjZSQxKTsKCnZhciBpcndpbkhhbGwgPSAoZnVuY3Rpb24gc291
cmNlUmFuZG9tSXJ3aW5IYWxsKHNvdXJjZSkgewogIGZ1bmN0aW9uIHJhbmRvbUlyd2luSGFsbChu
KSB7CiAgICByZXR1cm4gZnVuY3Rpb24oKSB7CiAgICAgIGZvciAodmFyIHN1bSA9IDAsIGkgPSAw
OyBpIDwgbjsgKytpKSBzdW0gKz0gc291cmNlKCk7CiAgICAgIHJldHVybiBzdW07CiAgICB9Owog
IH0KCiAgcmFuZG9tSXJ3aW5IYWxsLnNvdXJjZSA9IHNvdXJjZVJhbmRvbUlyd2luSGFsbDsKCiAg
cmV0dXJuIHJhbmRvbUlyd2luSGFsbDsKfSkoZGVmYXVsdFNvdXJjZSQxKTsKCnZhciBiYXRlcyA9
IChmdW5jdGlvbiBzb3VyY2VSYW5kb21CYXRlcyhzb3VyY2UpIHsKICBmdW5jdGlvbiByYW5kb21C
YXRlcyhuKSB7CiAgICB2YXIgcmFuZG9tSXJ3aW5IYWxsID0gaXJ3aW5IYWxsLnNvdXJjZShzb3Vy
Y2UpKG4pOwogICAgcmV0dXJuIGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gcmFuZG9tSXJ3aW5I
YWxsKCkgLyBuOwogICAgfTsKICB9CgogIHJhbmRvbUJhdGVzLnNvdXJjZSA9IHNvdXJjZVJhbmRv
bUJhdGVzOwoKICByZXR1cm4gcmFuZG9tQmF0ZXM7Cn0pKGRlZmF1bHRTb3VyY2UkMSk7Cgp2YXIg
ZXhwb25lbnRpYWwkMSA9IChmdW5jdGlvbiBzb3VyY2VSYW5kb21FeHBvbmVudGlhbChzb3VyY2Up
IHsKICBmdW5jdGlvbiByYW5kb21FeHBvbmVudGlhbChsYW1iZGEpIHsKICAgIHJldHVybiBmdW5j
dGlvbigpIHsKICAgICAgcmV0dXJuIC1NYXRoLmxvZygxIC0gc291cmNlKCkpIC8gbGFtYmRhOwog
ICAgfTsKICB9CgogIHJhbmRvbUV4cG9uZW50aWFsLnNvdXJjZSA9IHNvdXJjZVJhbmRvbUV4cG9u
ZW50aWFsOwoKICByZXR1cm4gcmFuZG9tRXhwb25lbnRpYWw7Cn0pKGRlZmF1bHRTb3VyY2UkMSk7
CgpmdW5jdGlvbiBpbml0UmFuZ2UoZG9tYWluLCByYW5nZSkgewogIHN3aXRjaCAoYXJndW1lbnRz
Lmxlbmd0aCkgewogICAgY2FzZSAwOiBicmVhazsKICAgIGNhc2UgMTogdGhpcy5yYW5nZShkb21h
aW4pOyBicmVhazsKICAgIGRlZmF1bHQ6IHRoaXMucmFuZ2UocmFuZ2UpLmRvbWFpbihkb21haW4p
OyBicmVhazsKICB9CiAgcmV0dXJuIHRoaXM7Cn0KCmZ1bmN0aW9uIGluaXRJbnRlcnBvbGF0b3Io
ZG9tYWluLCBpbnRlcnBvbGF0b3IpIHsKICBzd2l0Y2ggKGFyZ3VtZW50cy5sZW5ndGgpIHsKICAg
IGNhc2UgMDogYnJlYWs7CiAgICBjYXNlIDE6IHRoaXMuaW50ZXJwb2xhdG9yKGRvbWFpbik7IGJy
ZWFrOwogICAgZGVmYXVsdDogdGhpcy5pbnRlcnBvbGF0b3IoaW50ZXJwb2xhdG9yKS5kb21haW4o
ZG9tYWluKTsgYnJlYWs7CiAgfQogIHJldHVybiB0aGlzOwp9Cgp2YXIgYXJyYXkkMyA9IEFycmF5
LnByb3RvdHlwZTsKCnZhciBtYXAkMyA9IGFycmF5JDMubWFwOwp2YXIgc2xpY2UkNSA9IGFycmF5
JDMuc2xpY2U7Cgp2YXIgaW1wbGljaXQgPSB7bmFtZTogImltcGxpY2l0In07CgpmdW5jdGlvbiBv
cmRpbmFsKCkgewogIHZhciBpbmRleCA9IG1hcCQxKCksCiAgICAgIGRvbWFpbiA9IFtdLAogICAg
ICByYW5nZSA9IFtdLAogICAgICB1bmtub3duID0gaW1wbGljaXQ7CgogIGZ1bmN0aW9uIHNjYWxl
KGQpIHsKICAgIHZhciBrZXkgPSBkICsgIiIsIGkgPSBpbmRleC5nZXQoa2V5KTsKICAgIGlmICgh
aSkgewogICAgICBpZiAodW5rbm93biAhPT0gaW1wbGljaXQpIHJldHVybiB1bmtub3duOwogICAg
ICBpbmRleC5zZXQoa2V5LCBpID0gZG9tYWluLnB1c2goZCkpOwogICAgfQogICAgcmV0dXJuIHJh
bmdlWyhpIC0gMSkgJSByYW5nZS5sZW5ndGhdOwogIH0KCiAgc2NhbGUuZG9tYWluID0gZnVuY3Rp
b24oXykgewogICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gZG9tYWluLnNsaWNlKCk7
CiAgICBkb21haW4gPSBbXSwgaW5kZXggPSBtYXAkMSgpOwogICAgdmFyIGkgPSAtMSwgbiA9IF8u
bGVuZ3RoLCBkLCBrZXk7CiAgICB3aGlsZSAoKytpIDwgbikgaWYgKCFpbmRleC5oYXMoa2V5ID0g
KGQgPSBfW2ldKSArICIiKSkgaW5kZXguc2V0KGtleSwgZG9tYWluLnB1c2goZCkpOwogICAgcmV0
dXJuIHNjYWxlOwogIH07CgogIHNjYWxlLnJhbmdlID0gZnVuY3Rpb24oXykgewogICAgcmV0dXJu
IGFyZ3VtZW50cy5sZW5ndGggPyAocmFuZ2UgPSBzbGljZSQ1LmNhbGwoXyksIHNjYWxlKSA6IHJh
bmdlLnNsaWNlKCk7CiAgfTsKCiAgc2NhbGUudW5rbm93biA9IGZ1bmN0aW9uKF8pIHsKICAgIHJl
dHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHVua25vd24gPSBfLCBzY2FsZSkgOiB1bmtub3duOwog
IH07CgogIHNjYWxlLmNvcHkgPSBmdW5jdGlvbigpIHsKICAgIHJldHVybiBvcmRpbmFsKGRvbWFp
biwgcmFuZ2UpLnVua25vd24odW5rbm93bik7CiAgfTsKCiAgaW5pdFJhbmdlLmFwcGx5KHNjYWxl
LCBhcmd1bWVudHMpOwoKICByZXR1cm4gc2NhbGU7Cn0KCmZ1bmN0aW9uIGJhbmQoKSB7CiAgdmFy
IHNjYWxlID0gb3JkaW5hbCgpLnVua25vd24odW5kZWZpbmVkKSwKICAgICAgZG9tYWluID0gc2Nh
bGUuZG9tYWluLAogICAgICBvcmRpbmFsUmFuZ2UgPSBzY2FsZS5yYW5nZSwKICAgICAgcmFuZ2Ug
PSBbMCwgMV0sCiAgICAgIHN0ZXAsCiAgICAgIGJhbmR3aWR0aCwKICAgICAgcm91bmQgPSBmYWxz
ZSwKICAgICAgcGFkZGluZ0lubmVyID0gMCwKICAgICAgcGFkZGluZ091dGVyID0gMCwKICAgICAg
YWxpZ24gPSAwLjU7CgogIGRlbGV0ZSBzY2FsZS51bmtub3duOwoKICBmdW5jdGlvbiByZXNjYWxl
KCkgewogICAgdmFyIG4gPSBkb21haW4oKS5sZW5ndGgsCiAgICAgICAgcmV2ZXJzZSA9IHJhbmdl
WzFdIDwgcmFuZ2VbMF0sCiAgICAgICAgc3RhcnQgPSByYW5nZVtyZXZlcnNlIC0gMF0sCiAgICAg
ICAgc3RvcCA9IHJhbmdlWzEgLSByZXZlcnNlXTsKICAgIHN0ZXAgPSAoc3RvcCAtIHN0YXJ0KSAv
IE1hdGgubWF4KDEsIG4gLSBwYWRkaW5nSW5uZXIgKyBwYWRkaW5nT3V0ZXIgKiAyKTsKICAgIGlm
IChyb3VuZCkgc3RlcCA9IE1hdGguZmxvb3Ioc3RlcCk7CiAgICBzdGFydCArPSAoc3RvcCAtIHN0
YXJ0IC0gc3RlcCAqIChuIC0gcGFkZGluZ0lubmVyKSkgKiBhbGlnbjsKICAgIGJhbmR3aWR0aCA9
IHN0ZXAgKiAoMSAtIHBhZGRpbmdJbm5lcik7CiAgICBpZiAocm91bmQpIHN0YXJ0ID0gTWF0aC5y
b3VuZChzdGFydCksIGJhbmR3aWR0aCA9IE1hdGgucm91bmQoYmFuZHdpZHRoKTsKICAgIHZhciB2
YWx1ZXMgPSBzZXF1ZW5jZShuKS5tYXAoZnVuY3Rpb24oaSkgeyByZXR1cm4gc3RhcnQgKyBzdGVw
ICogaTsgfSk7CiAgICByZXR1cm4gb3JkaW5hbFJhbmdlKHJldmVyc2UgPyB2YWx1ZXMucmV2ZXJz
ZSgpIDogdmFsdWVzKTsKICB9CgogIHNjYWxlLmRvbWFpbiA9IGZ1bmN0aW9uKF8pIHsKICAgIHJl
dHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGRvbWFpbihfKSwgcmVzY2FsZSgpKSA6IGRvbWFpbigp
OwogIH07CgogIHNjYWxlLnJhbmdlID0gZnVuY3Rpb24oXykgewogICAgcmV0dXJuIGFyZ3VtZW50
cy5sZW5ndGggPyAocmFuZ2UgPSBbK19bMF0sICtfWzFdXSwgcmVzY2FsZSgpKSA6IHJhbmdlLnNs
aWNlKCk7CiAgfTsKCiAgc2NhbGUucmFuZ2VSb3VuZCA9IGZ1bmN0aW9uKF8pIHsKICAgIHJldHVy
biByYW5nZSA9IFsrX1swXSwgK19bMV1dLCByb3VuZCA9IHRydWUsIHJlc2NhbGUoKTsKICB9OwoK
ICBzY2FsZS5iYW5kd2lkdGggPSBmdW5jdGlvbigpIHsKICAgIHJldHVybiBiYW5kd2lkdGg7CiAg
fTsKCiAgc2NhbGUuc3RlcCA9IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIHN0ZXA7CiAgfTsKCiAg
c2NhbGUucm91bmQgPSBmdW5jdGlvbihfKSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/
IChyb3VuZCA9ICEhXywgcmVzY2FsZSgpKSA6IHJvdW5kOwogIH07CgogIHNjYWxlLnBhZGRpbmcg
PSBmdW5jdGlvbihfKSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChwYWRkaW5nSW5u
ZXIgPSBNYXRoLm1pbigxLCBwYWRkaW5nT3V0ZXIgPSArXyksIHJlc2NhbGUoKSkgOiBwYWRkaW5n
SW5uZXI7CiAgfTsKCiAgc2NhbGUucGFkZGluZ0lubmVyID0gZnVuY3Rpb24oXykgewogICAgcmV0
dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAocGFkZGluZ0lubmVyID0gTWF0aC5taW4oMSwgXyksIHJl
c2NhbGUoKSkgOiBwYWRkaW5nSW5uZXI7CiAgfTsKCiAgc2NhbGUucGFkZGluZ091dGVyID0gZnVu
Y3Rpb24oXykgewogICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAocGFkZGluZ091dGVyID0g
K18sIHJlc2NhbGUoKSkgOiBwYWRkaW5nT3V0ZXI7CiAgfTsKCiAgc2NhbGUuYWxpZ24gPSBmdW5j
dGlvbihfKSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChhbGlnbiA9IE1hdGgubWF4
KDAsIE1hdGgubWluKDEsIF8pKSwgcmVzY2FsZSgpKSA6IGFsaWduOwogIH07CgogIHNjYWxlLmNv
cHkgPSBmdW5jdGlvbigpIHsKICAgIHJldHVybiBiYW5kKGRvbWFpbigpLCByYW5nZSkKICAgICAg
ICAucm91bmQocm91bmQpCiAgICAgICAgLnBhZGRpbmdJbm5lcihwYWRkaW5nSW5uZXIpCiAgICAg
ICAgLnBhZGRpbmdPdXRlcihwYWRkaW5nT3V0ZXIpCiAgICAgICAgLmFsaWduKGFsaWduKTsKICB9
OwoKICByZXR1cm4gaW5pdFJhbmdlLmFwcGx5KHJlc2NhbGUoKSwgYXJndW1lbnRzKTsKfQoKZnVu
Y3Rpb24gcG9pbnRpc2goc2NhbGUpIHsKICB2YXIgY29weSA9IHNjYWxlLmNvcHk7CgogIHNjYWxl
LnBhZGRpbmcgPSBzY2FsZS5wYWRkaW5nT3V0ZXI7CiAgZGVsZXRlIHNjYWxlLnBhZGRpbmdJbm5l
cjsKICBkZWxldGUgc2NhbGUucGFkZGluZ091dGVyOwoKICBzY2FsZS5jb3B5ID0gZnVuY3Rpb24o
KSB7CiAgICByZXR1cm4gcG9pbnRpc2goY29weSgpKTsKICB9OwoKICByZXR1cm4gc2NhbGU7Cn0K
CmZ1bmN0aW9uIHBvaW50JDEoKSB7CiAgcmV0dXJuIHBvaW50aXNoKGJhbmQuYXBwbHkobnVsbCwg
YXJndW1lbnRzKS5wYWRkaW5nSW5uZXIoMSkpOwp9CgpmdW5jdGlvbiBjb25zdGFudCRhKHgpIHsK
ICByZXR1cm4gZnVuY3Rpb24oKSB7CiAgICByZXR1cm4geDsKICB9Owp9CgpmdW5jdGlvbiBudW1i
ZXIkMih4KSB7CiAgcmV0dXJuICt4Owp9Cgp2YXIgdW5pdCA9IFswLCAxXTsKCmZ1bmN0aW9uIGlk
ZW50aXR5JDYoeCkgewogIHJldHVybiB4Owp9CgpmdW5jdGlvbiBub3JtYWxpemUoYSwgYikgewog
IHJldHVybiAoYiAtPSAoYSA9ICthKSkKICAgICAgPyBmdW5jdGlvbih4KSB7IHJldHVybiAoeCAt
IGEpIC8gYjsgfQogICAgICA6IGNvbnN0YW50JGEoaXNOYU4oYikgPyBOYU4gOiAwLjUpOwp9Cgpm
dW5jdGlvbiBjbGFtcGVyKGRvbWFpbikgewogIHZhciBhID0gZG9tYWluWzBdLCBiID0gZG9tYWlu
W2RvbWFpbi5sZW5ndGggLSAxXSwgdDsKICBpZiAoYSA+IGIpIHQgPSBhLCBhID0gYiwgYiA9IHQ7
CiAgcmV0dXJuIGZ1bmN0aW9uKHgpIHsgcmV0dXJuIE1hdGgubWF4KGEsIE1hdGgubWluKGIsIHgp
KTsgfTsKfQoKLy8gbm9ybWFsaXplKGEsIGIpKHgpIHRha2VzIGEgZG9tYWluIHZhbHVlIHggaW4g
W2EsYl0gYW5kIHJldHVybnMgdGhlIGNvcnJlc3BvbmRpbmcgcGFyYW1ldGVyIHQgaW4gWzAsMV0u
Ci8vIGludGVycG9sYXRlKGEsIGIpKHQpIHRha2VzIGEgcGFyYW1ldGVyIHQgaW4gWzAsMV0gYW5k
IHJldHVybnMgdGhlIGNvcnJlc3BvbmRpbmcgcmFuZ2UgdmFsdWUgeCBpbiBbYSxiXS4KZnVuY3Rp
b24gYmltYXAoZG9tYWluLCByYW5nZSwgaW50ZXJwb2xhdGUpIHsKICB2YXIgZDAgPSBkb21haW5b
MF0sIGQxID0gZG9tYWluWzFdLCByMCA9IHJhbmdlWzBdLCByMSA9IHJhbmdlWzFdOwogIGlmIChk
MSA8IGQwKSBkMCA9IG5vcm1hbGl6ZShkMSwgZDApLCByMCA9IGludGVycG9sYXRlKHIxLCByMCk7
CiAgZWxzZSBkMCA9IG5vcm1hbGl6ZShkMCwgZDEpLCByMCA9IGludGVycG9sYXRlKHIwLCByMSk7
CiAgcmV0dXJuIGZ1bmN0aW9uKHgpIHsgcmV0dXJuIHIwKGQwKHgpKTsgfTsKfQoKZnVuY3Rpb24g
cG9seW1hcChkb21haW4sIHJhbmdlLCBpbnRlcnBvbGF0ZSkgewogIHZhciBqID0gTWF0aC5taW4o
ZG9tYWluLmxlbmd0aCwgcmFuZ2UubGVuZ3RoKSAtIDEsCiAgICAgIGQgPSBuZXcgQXJyYXkoaiks
CiAgICAgIHIgPSBuZXcgQXJyYXkoaiksCiAgICAgIGkgPSAtMTsKCiAgLy8gUmV2ZXJzZSBkZXNj
ZW5kaW5nIGRvbWFpbnMuCiAgaWYgKGRvbWFpbltqXSA8IGRvbWFpblswXSkgewogICAgZG9tYWlu
ID0gZG9tYWluLnNsaWNlKCkucmV2ZXJzZSgpOwogICAgcmFuZ2UgPSByYW5nZS5zbGljZSgpLnJl
dmVyc2UoKTsKICB9CgogIHdoaWxlICgrK2kgPCBqKSB7CiAgICBkW2ldID0gbm9ybWFsaXplKGRv
bWFpbltpXSwgZG9tYWluW2kgKyAxXSk7CiAgICByW2ldID0gaW50ZXJwb2xhdGUocmFuZ2VbaV0s
IHJhbmdlW2kgKyAxXSk7CiAgfQoKICByZXR1cm4gZnVuY3Rpb24oeCkgewogICAgdmFyIGkgPSBi
aXNlY3RSaWdodChkb21haW4sIHgsIDEsIGopIC0gMTsKICAgIHJldHVybiByW2ldKGRbaV0oeCkp
OwogIH07Cn0KCmZ1bmN0aW9uIGNvcHkoc291cmNlLCB0YXJnZXQpIHsKICByZXR1cm4gdGFyZ2V0
CiAgICAgIC5kb21haW4oc291cmNlLmRvbWFpbigpKQogICAgICAucmFuZ2Uoc291cmNlLnJhbmdl
KCkpCiAgICAgIC5pbnRlcnBvbGF0ZShzb3VyY2UuaW50ZXJwb2xhdGUoKSkKICAgICAgLmNsYW1w
KHNvdXJjZS5jbGFtcCgpKQogICAgICAudW5rbm93bihzb3VyY2UudW5rbm93bigpKTsKfQoKZnVu
Y3Rpb24gdHJhbnNmb3JtZXIkMSgpIHsKICB2YXIgZG9tYWluID0gdW5pdCwKICAgICAgcmFuZ2Ug
PSB1bml0LAogICAgICBpbnRlcnBvbGF0ZSA9IGludGVycG9sYXRlVmFsdWUsCiAgICAgIHRyYW5z
Zm9ybSwKICAgICAgdW50cmFuc2Zvcm0sCiAgICAgIHVua25vd24sCiAgICAgIGNsYW1wID0gaWRl
bnRpdHkkNiwKICAgICAgcGllY2V3aXNlLAogICAgICBvdXRwdXQsCiAgICAgIGlucHV0OwoKICBm
dW5jdGlvbiByZXNjYWxlKCkgewogICAgcGllY2V3aXNlID0gTWF0aC5taW4oZG9tYWluLmxlbmd0
aCwgcmFuZ2UubGVuZ3RoKSA+IDIgPyBwb2x5bWFwIDogYmltYXA7CiAgICBvdXRwdXQgPSBpbnB1
dCA9IG51bGw7CiAgICByZXR1cm4gc2NhbGU7CiAgfQoKICBmdW5jdGlvbiBzY2FsZSh4KSB7CiAg
ICByZXR1cm4gaXNOYU4oeCA9ICt4KSA/IHVua25vd24gOiAob3V0cHV0IHx8IChvdXRwdXQgPSBw
aWVjZXdpc2UoZG9tYWluLm1hcCh0cmFuc2Zvcm0pLCByYW5nZSwgaW50ZXJwb2xhdGUpKSkodHJh
bnNmb3JtKGNsYW1wKHgpKSk7CiAgfQoKICBzY2FsZS5pbnZlcnQgPSBmdW5jdGlvbih5KSB7CiAg
ICByZXR1cm4gY2xhbXAodW50cmFuc2Zvcm0oKGlucHV0IHx8IChpbnB1dCA9IHBpZWNld2lzZShy
YW5nZSwgZG9tYWluLm1hcCh0cmFuc2Zvcm0pLCBpbnRlcnBvbGF0ZU51bWJlcikpKSh5KSkpOwog
IH07CgogIHNjYWxlLmRvbWFpbiA9IGZ1bmN0aW9uKF8pIHsKICAgIHJldHVybiBhcmd1bWVudHMu
bGVuZ3RoID8gKGRvbWFpbiA9IG1hcCQzLmNhbGwoXywgbnVtYmVyJDIpLCBjbGFtcCA9PT0gaWRl
bnRpdHkkNiB8fCAoY2xhbXAgPSBjbGFtcGVyKGRvbWFpbikpLCByZXNjYWxlKCkpIDogZG9tYWlu
LnNsaWNlKCk7CiAgfTsKCiAgc2NhbGUucmFuZ2UgPSBmdW5jdGlvbihfKSB7CiAgICByZXR1cm4g
YXJndW1lbnRzLmxlbmd0aCA/IChyYW5nZSA9IHNsaWNlJDUuY2FsbChfKSwgcmVzY2FsZSgpKSA6
IHJhbmdlLnNsaWNlKCk7CiAgfTsKCiAgc2NhbGUucmFuZ2VSb3VuZCA9IGZ1bmN0aW9uKF8pIHsK
ICAgIHJldHVybiByYW5nZSA9IHNsaWNlJDUuY2FsbChfKSwgaW50ZXJwb2xhdGUgPSBpbnRlcnBv
bGF0ZVJvdW5kLCByZXNjYWxlKCk7CiAgfTsKCiAgc2NhbGUuY2xhbXAgPSBmdW5jdGlvbihfKSB7
CiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChjbGFtcCA9IF8gPyBjbGFtcGVyKGRvbWFp
bikgOiBpZGVudGl0eSQ2LCBzY2FsZSkgOiBjbGFtcCAhPT0gaWRlbnRpdHkkNjsKICB9OwoKICBz
Y2FsZS5pbnRlcnBvbGF0ZSA9IGZ1bmN0aW9uKF8pIHsKICAgIHJldHVybiBhcmd1bWVudHMubGVu
Z3RoID8gKGludGVycG9sYXRlID0gXywgcmVzY2FsZSgpKSA6IGludGVycG9sYXRlOwogIH07Cgog
IHNjYWxlLnVua25vd24gPSBmdW5jdGlvbihfKSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0
aCA/ICh1bmtub3duID0gXywgc2NhbGUpIDogdW5rbm93bjsKICB9OwoKICByZXR1cm4gZnVuY3Rp
b24odCwgdSkgewogICAgdHJhbnNmb3JtID0gdCwgdW50cmFuc2Zvcm0gPSB1OwogICAgcmV0dXJu
IHJlc2NhbGUoKTsKICB9Owp9CgpmdW5jdGlvbiBjb250aW51b3VzKHRyYW5zZm9ybSwgdW50cmFu
c2Zvcm0pIHsKICByZXR1cm4gdHJhbnNmb3JtZXIkMSgpKHRyYW5zZm9ybSwgdW50cmFuc2Zvcm0p
Owp9CgpmdW5jdGlvbiB0aWNrRm9ybWF0KHN0YXJ0LCBzdG9wLCBjb3VudCwgc3BlY2lmaWVyKSB7
CiAgdmFyIHN0ZXAgPSB0aWNrU3RlcChzdGFydCwgc3RvcCwgY291bnQpLAogICAgICBwcmVjaXNp
b247CiAgc3BlY2lmaWVyID0gZm9ybWF0U3BlY2lmaWVyKHNwZWNpZmllciA9PSBudWxsID8gIixm
IiA6IHNwZWNpZmllcik7CiAgc3dpdGNoIChzcGVjaWZpZXIudHlwZSkgewogICAgY2FzZSAicyI6
IHsKICAgICAgdmFyIHZhbHVlID0gTWF0aC5tYXgoTWF0aC5hYnMoc3RhcnQpLCBNYXRoLmFicyhz
dG9wKSk7CiAgICAgIGlmIChzcGVjaWZpZXIucHJlY2lzaW9uID09IG51bGwgJiYgIWlzTmFOKHBy
ZWNpc2lvbiA9IHByZWNpc2lvblByZWZpeChzdGVwLCB2YWx1ZSkpKSBzcGVjaWZpZXIucHJlY2lz
aW9uID0gcHJlY2lzaW9uOwogICAgICByZXR1cm4gZXhwb3J0cy5mb3JtYXRQcmVmaXgoc3BlY2lm
aWVyLCB2YWx1ZSk7CiAgICB9CiAgICBjYXNlICIiOgogICAgY2FzZSAiZSI6CiAgICBjYXNlICJn
IjoKICAgIGNhc2UgInAiOgogICAgY2FzZSAiciI6IHsKICAgICAgaWYgKHNwZWNpZmllci5wcmVj
aXNpb24gPT0gbnVsbCAmJiAhaXNOYU4ocHJlY2lzaW9uID0gcHJlY2lzaW9uUm91bmQoc3RlcCwg
TWF0aC5tYXgoTWF0aC5hYnMoc3RhcnQpLCBNYXRoLmFicyhzdG9wKSkpKSkgc3BlY2lmaWVyLnBy
ZWNpc2lvbiA9IHByZWNpc2lvbiAtIChzcGVjaWZpZXIudHlwZSA9PT0gImUiKTsKICAgICAgYnJl
YWs7CiAgICB9CiAgICBjYXNlICJmIjoKICAgIGNhc2UgIiUiOiB7CiAgICAgIGlmIChzcGVjaWZp
ZXIucHJlY2lzaW9uID09IG51bGwgJiYgIWlzTmFOKHByZWNpc2lvbiA9IHByZWNpc2lvbkZpeGVk
KHN0ZXApKSkgc3BlY2lmaWVyLnByZWNpc2lvbiA9IHByZWNpc2lvbiAtIChzcGVjaWZpZXIudHlw
ZSA9PT0gIiUiKSAqIDI7CiAgICAgIGJyZWFrOwogICAgfQogIH0KICByZXR1cm4gZXhwb3J0cy5m
b3JtYXQoc3BlY2lmaWVyKTsKfQoKZnVuY3Rpb24gbGluZWFyaXNoKHNjYWxlKSB7CiAgdmFyIGRv
bWFpbiA9IHNjYWxlLmRvbWFpbjsKCiAgc2NhbGUudGlja3MgPSBmdW5jdGlvbihjb3VudCkgewog
ICAgdmFyIGQgPSBkb21haW4oKTsKICAgIHJldHVybiB0aWNrcyhkWzBdLCBkW2QubGVuZ3RoIC0g
MV0sIGNvdW50ID09IG51bGwgPyAxMCA6IGNvdW50KTsKICB9OwoKICBzY2FsZS50aWNrRm9ybWF0
ID0gZnVuY3Rpb24oY291bnQsIHNwZWNpZmllcikgewogICAgdmFyIGQgPSBkb21haW4oKTsKICAg
IHJldHVybiB0aWNrRm9ybWF0KGRbMF0sIGRbZC5sZW5ndGggLSAxXSwgY291bnQgPT0gbnVsbCA/
IDEwIDogY291bnQsIHNwZWNpZmllcik7CiAgfTsKCiAgc2NhbGUubmljZSA9IGZ1bmN0aW9uKGNv
dW50KSB7CiAgICBpZiAoY291bnQgPT0gbnVsbCkgY291bnQgPSAxMDsKCiAgICB2YXIgZCA9IGRv
bWFpbigpLAogICAgICAgIGkwID0gMCwKICAgICAgICBpMSA9IGQubGVuZ3RoIC0gMSwKICAgICAg
ICBzdGFydCA9IGRbaTBdLAogICAgICAgIHN0b3AgPSBkW2kxXSwKICAgICAgICBzdGVwOwoKICAg
IGlmIChzdG9wIDwgc3RhcnQpIHsKICAgICAgc3RlcCA9IHN0YXJ0LCBzdGFydCA9IHN0b3AsIHN0
b3AgPSBzdGVwOwogICAgICBzdGVwID0gaTAsIGkwID0gaTEsIGkxID0gc3RlcDsKICAgIH0KCiAg
ICBzdGVwID0gdGlja0luY3JlbWVudChzdGFydCwgc3RvcCwgY291bnQpOwoKICAgIGlmIChzdGVw
ID4gMCkgewogICAgICBzdGFydCA9IE1hdGguZmxvb3Ioc3RhcnQgLyBzdGVwKSAqIHN0ZXA7CiAg
ICAgIHN0b3AgPSBNYXRoLmNlaWwoc3RvcCAvIHN0ZXApICogc3RlcDsKICAgICAgc3RlcCA9IHRp
Y2tJbmNyZW1lbnQoc3RhcnQsIHN0b3AsIGNvdW50KTsKICAgIH0gZWxzZSBpZiAoc3RlcCA8IDAp
IHsKICAgICAgc3RhcnQgPSBNYXRoLmNlaWwoc3RhcnQgKiBzdGVwKSAvIHN0ZXA7CiAgICAgIHN0
b3AgPSBNYXRoLmZsb29yKHN0b3AgKiBzdGVwKSAvIHN0ZXA7CiAgICAgIHN0ZXAgPSB0aWNrSW5j
cmVtZW50KHN0YXJ0LCBzdG9wLCBjb3VudCk7CiAgICB9CgogICAgaWYgKHN0ZXAgPiAwKSB7CiAg
ICAgIGRbaTBdID0gTWF0aC5mbG9vcihzdGFydCAvIHN0ZXApICogc3RlcDsKICAgICAgZFtpMV0g
PSBNYXRoLmNlaWwoc3RvcCAvIHN0ZXApICogc3RlcDsKICAgICAgZG9tYWluKGQpOwogICAgfSBl
bHNlIGlmIChzdGVwIDwgMCkgewogICAgICBkW2kwXSA9IE1hdGguY2VpbChzdGFydCAqIHN0ZXAp
IC8gc3RlcDsKICAgICAgZFtpMV0gPSBNYXRoLmZsb29yKHN0b3AgKiBzdGVwKSAvIHN0ZXA7CiAg
ICAgIGRvbWFpbihkKTsKICAgIH0KCiAgICByZXR1cm4gc2NhbGU7CiAgfTsKCiAgcmV0dXJuIHNj
YWxlOwp9CgpmdW5jdGlvbiBsaW5lYXIkMigpIHsKICB2YXIgc2NhbGUgPSBjb250aW51b3VzKGlk
ZW50aXR5JDYsIGlkZW50aXR5JDYpOwoKICBzY2FsZS5jb3B5ID0gZnVuY3Rpb24oKSB7CiAgICBy
ZXR1cm4gY29weShzY2FsZSwgbGluZWFyJDIoKSk7CiAgfTsKCiAgaW5pdFJhbmdlLmFwcGx5KHNj
YWxlLCBhcmd1bWVudHMpOwoKICByZXR1cm4gbGluZWFyaXNoKHNjYWxlKTsKfQoKZnVuY3Rpb24g
aWRlbnRpdHkkNyhkb21haW4pIHsKICB2YXIgdW5rbm93bjsKCiAgZnVuY3Rpb24gc2NhbGUoeCkg
ewogICAgcmV0dXJuIGlzTmFOKHggPSAreCkgPyB1bmtub3duIDogeDsKICB9CgogIHNjYWxlLmlu
dmVydCA9IHNjYWxlOwoKICBzY2FsZS5kb21haW4gPSBzY2FsZS5yYW5nZSA9IGZ1bmN0aW9uKF8p
IHsKICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGRvbWFpbiA9IG1hcCQzLmNhbGwoXywg
bnVtYmVyJDIpLCBzY2FsZSkgOiBkb21haW4uc2xpY2UoKTsKICB9OwoKICBzY2FsZS51bmtub3du
ID0gZnVuY3Rpb24oXykgewogICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAodW5rbm93biA9
IF8sIHNjYWxlKSA6IHVua25vd247CiAgfTsKCiAgc2NhbGUuY29weSA9IGZ1bmN0aW9uKCkgewog
ICAgcmV0dXJuIGlkZW50aXR5JDcoZG9tYWluKS51bmtub3duKHVua25vd24pOwogIH07CgogIGRv
bWFpbiA9IGFyZ3VtZW50cy5sZW5ndGggPyBtYXAkMy5jYWxsKGRvbWFpbiwgbnVtYmVyJDIpIDog
WzAsIDFdOwoKICByZXR1cm4gbGluZWFyaXNoKHNjYWxlKTsKfQoKZnVuY3Rpb24gbmljZShkb21h
aW4sIGludGVydmFsKSB7CiAgZG9tYWluID0gZG9tYWluLnNsaWNlKCk7CgogIHZhciBpMCA9IDAs
CiAgICAgIGkxID0gZG9tYWluLmxlbmd0aCAtIDEsCiAgICAgIHgwID0gZG9tYWluW2kwXSwKICAg
ICAgeDEgPSBkb21haW5baTFdLAogICAgICB0OwoKICBpZiAoeDEgPCB4MCkgewogICAgdCA9IGkw
LCBpMCA9IGkxLCBpMSA9IHQ7CiAgICB0ID0geDAsIHgwID0geDEsIHgxID0gdDsKICB9CgogIGRv
bWFpbltpMF0gPSBpbnRlcnZhbC5mbG9vcih4MCk7CiAgZG9tYWluW2kxXSA9IGludGVydmFsLmNl
aWwoeDEpOwogIHJldHVybiBkb21haW47Cn0KCmZ1bmN0aW9uIHRyYW5zZm9ybUxvZyh4KSB7CiAg
cmV0dXJuIE1hdGgubG9nKHgpOwp9CgpmdW5jdGlvbiB0cmFuc2Zvcm1FeHAoeCkgewogIHJldHVy
biBNYXRoLmV4cCh4KTsKfQoKZnVuY3Rpb24gdHJhbnNmb3JtTG9nbih4KSB7CiAgcmV0dXJuIC1N
YXRoLmxvZygteCk7Cn0KCmZ1bmN0aW9uIHRyYW5zZm9ybUV4cG4oeCkgewogIHJldHVybiAtTWF0
aC5leHAoLXgpOwp9CgpmdW5jdGlvbiBwb3cxMCh4KSB7CiAgcmV0dXJuIGlzRmluaXRlKHgpID8g
KygiMWUiICsgeCkgOiB4IDwgMCA/IDAgOiB4Owp9CgpmdW5jdGlvbiBwb3dwKGJhc2UpIHsKICBy
ZXR1cm4gYmFzZSA9PT0gMTAgPyBwb3cxMAogICAgICA6IGJhc2UgPT09IE1hdGguRSA/IE1hdGgu
ZXhwCiAgICAgIDogZnVuY3Rpb24oeCkgeyByZXR1cm4gTWF0aC5wb3coYmFzZSwgeCk7IH07Cn0K
CmZ1bmN0aW9uIGxvZ3AoYmFzZSkgewogIHJldHVybiBiYXNlID09PSBNYXRoLkUgPyBNYXRoLmxv
ZwogICAgICA6IGJhc2UgPT09IDEwICYmIE1hdGgubG9nMTAKICAgICAgfHwgYmFzZSA9PT0gMiAm
JiBNYXRoLmxvZzIKICAgICAgfHwgKGJhc2UgPSBNYXRoLmxvZyhiYXNlKSwgZnVuY3Rpb24oeCkg
eyByZXR1cm4gTWF0aC5sb2coeCkgLyBiYXNlOyB9KTsKfQoKZnVuY3Rpb24gcmVmbGVjdChmKSB7
CiAgcmV0dXJuIGZ1bmN0aW9uKHgpIHsKICAgIHJldHVybiAtZigteCk7CiAgfTsKfQoKZnVuY3Rp
b24gbG9nZ2lzaCh0cmFuc2Zvcm0pIHsKICB2YXIgc2NhbGUgPSB0cmFuc2Zvcm0odHJhbnNmb3Jt
TG9nLCB0cmFuc2Zvcm1FeHApLAogICAgICBkb21haW4gPSBzY2FsZS5kb21haW4sCiAgICAgIGJh
c2UgPSAxMCwKICAgICAgbG9ncywKICAgICAgcG93czsKCiAgZnVuY3Rpb24gcmVzY2FsZSgpIHsK
ICAgIGxvZ3MgPSBsb2dwKGJhc2UpLCBwb3dzID0gcG93cChiYXNlKTsKICAgIGlmIChkb21haW4o
KVswXSA8IDApIHsKICAgICAgbG9ncyA9IHJlZmxlY3QobG9ncyksIHBvd3MgPSByZWZsZWN0KHBv
d3MpOwogICAgICB0cmFuc2Zvcm0odHJhbnNmb3JtTG9nbiwgdHJhbnNmb3JtRXhwbik7CiAgICB9
IGVsc2UgewogICAgICB0cmFuc2Zvcm0odHJhbnNmb3JtTG9nLCB0cmFuc2Zvcm1FeHApOwogICAg
fQogICAgcmV0dXJuIHNjYWxlOwogIH0KCiAgc2NhbGUuYmFzZSA9IGZ1bmN0aW9uKF8pIHsKICAg
IHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGJhc2UgPSArXywgcmVzY2FsZSgpKSA6IGJhc2U7
CiAgfTsKCiAgc2NhbGUuZG9tYWluID0gZnVuY3Rpb24oXykgewogICAgcmV0dXJuIGFyZ3VtZW50
cy5sZW5ndGggPyAoZG9tYWluKF8pLCByZXNjYWxlKCkpIDogZG9tYWluKCk7CiAgfTsKCiAgc2Nh
bGUudGlja3MgPSBmdW5jdGlvbihjb3VudCkgewogICAgdmFyIGQgPSBkb21haW4oKSwKICAgICAg
ICB1ID0gZFswXSwKICAgICAgICB2ID0gZFtkLmxlbmd0aCAtIDFdLAogICAgICAgIHI7CgogICAg
aWYgKHIgPSB2IDwgdSkgaSA9IHUsIHUgPSB2LCB2ID0gaTsKCiAgICB2YXIgaSA9IGxvZ3ModSks
CiAgICAgICAgaiA9IGxvZ3ModiksCiAgICAgICAgcCwKICAgICAgICBrLAogICAgICAgIHQsCiAg
ICAgICAgbiA9IGNvdW50ID09IG51bGwgPyAxMCA6ICtjb3VudCwKICAgICAgICB6ID0gW107Cgog
ICAgaWYgKCEoYmFzZSAlIDEpICYmIGogLSBpIDwgbikgewogICAgICBpID0gTWF0aC5yb3VuZChp
KSAtIDEsIGogPSBNYXRoLnJvdW5kKGopICsgMTsKICAgICAgaWYgKHUgPiAwKSBmb3IgKDsgaSA8
IGo7ICsraSkgewogICAgICAgIGZvciAoayA9IDEsIHAgPSBwb3dzKGkpOyBrIDwgYmFzZTsgKytr
KSB7CiAgICAgICAgICB0ID0gcCAqIGs7CiAgICAgICAgICBpZiAodCA8IHUpIGNvbnRpbnVlOwog
ICAgICAgICAgaWYgKHQgPiB2KSBicmVhazsKICAgICAgICAgIHoucHVzaCh0KTsKICAgICAgICB9
CiAgICAgIH0gZWxzZSBmb3IgKDsgaSA8IGo7ICsraSkgewogICAgICAgIGZvciAoayA9IGJhc2Ug
LSAxLCBwID0gcG93cyhpKTsgayA+PSAxOyAtLWspIHsKICAgICAgICAgIHQgPSBwICogazsKICAg
ICAgICAgIGlmICh0IDwgdSkgY29udGludWU7CiAgICAgICAgICBpZiAodCA+IHYpIGJyZWFrOwog
ICAgICAgICAgei5wdXNoKHQpOwogICAgICAgIH0KICAgICAgfQogICAgfSBlbHNlIHsKICAgICAg
eiA9IHRpY2tzKGksIGosIE1hdGgubWluKGogLSBpLCBuKSkubWFwKHBvd3MpOwogICAgfQoKICAg
IHJldHVybiByID8gei5yZXZlcnNlKCkgOiB6OwogIH07CgogIHNjYWxlLnRpY2tGb3JtYXQgPSBm
dW5jdGlvbihjb3VudCwgc3BlY2lmaWVyKSB7CiAgICBpZiAoc3BlY2lmaWVyID09IG51bGwpIHNw
ZWNpZmllciA9IGJhc2UgPT09IDEwID8gIi4wZSIgOiAiLCI7CiAgICBpZiAodHlwZW9mIHNwZWNp
ZmllciAhPT0gImZ1bmN0aW9uIikgc3BlY2lmaWVyID0gZXhwb3J0cy5mb3JtYXQoc3BlY2lmaWVy
KTsKICAgIGlmIChjb3VudCA9PT0gSW5maW5pdHkpIHJldHVybiBzcGVjaWZpZXI7CiAgICBpZiAo
Y291bnQgPT0gbnVsbCkgY291bnQgPSAxMDsKICAgIHZhciBrID0gTWF0aC5tYXgoMSwgYmFzZSAq
IGNvdW50IC8gc2NhbGUudGlja3MoKS5sZW5ndGgpOyAvLyBUT0RPIGZhc3QgZXN0aW1hdGU/CiAg
ICByZXR1cm4gZnVuY3Rpb24oZCkgewogICAgICB2YXIgaSA9IGQgLyBwb3dzKE1hdGgucm91bmQo
bG9ncyhkKSkpOwogICAgICBpZiAoaSAqIGJhc2UgPCBiYXNlIC0gMC41KSBpICo9IGJhc2U7CiAg
ICAgIHJldHVybiBpIDw9IGsgPyBzcGVjaWZpZXIoZCkgOiAiIjsKICAgIH07CiAgfTsKCiAgc2Nh
bGUubmljZSA9IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIGRvbWFpbihuaWNlKGRvbWFpbigpLCB7
CiAgICAgIGZsb29yOiBmdW5jdGlvbih4KSB7IHJldHVybiBwb3dzKE1hdGguZmxvb3IobG9ncyh4
KSkpOyB9LAogICAgICBjZWlsOiBmdW5jdGlvbih4KSB7IHJldHVybiBwb3dzKE1hdGguY2VpbChs
b2dzKHgpKSk7IH0KICAgIH0pKTsKICB9OwoKICByZXR1cm4gc2NhbGU7Cn0KCmZ1bmN0aW9uIGxv
ZyQxKCkgewogIHZhciBzY2FsZSA9IGxvZ2dpc2godHJhbnNmb3JtZXIkMSgpKS5kb21haW4oWzEs
IDEwXSk7CgogIHNjYWxlLmNvcHkgPSBmdW5jdGlvbigpIHsKICAgIHJldHVybiBjb3B5KHNjYWxl
LCBsb2ckMSgpKS5iYXNlKHNjYWxlLmJhc2UoKSk7CiAgfTsKCiAgaW5pdFJhbmdlLmFwcGx5KHNj
YWxlLCBhcmd1bWVudHMpOwoKICByZXR1cm4gc2NhbGU7Cn0KCmZ1bmN0aW9uIHRyYW5zZm9ybVN5
bWxvZyhjKSB7CiAgcmV0dXJuIGZ1bmN0aW9uKHgpIHsKICAgIHJldHVybiBNYXRoLnNpZ24oeCkg
KiBNYXRoLmxvZzFwKE1hdGguYWJzKHggLyBjKSk7CiAgfTsKfQoKZnVuY3Rpb24gdHJhbnNmb3Jt
U3ltZXhwKGMpIHsKICByZXR1cm4gZnVuY3Rpb24oeCkgewogICAgcmV0dXJuIE1hdGguc2lnbih4
KSAqIE1hdGguZXhwbTEoTWF0aC5hYnMoeCkpICogYzsKICB9Owp9CgpmdW5jdGlvbiBzeW1sb2dp
c2godHJhbnNmb3JtKSB7CiAgdmFyIGMgPSAxLCBzY2FsZSA9IHRyYW5zZm9ybSh0cmFuc2Zvcm1T
eW1sb2coYyksIHRyYW5zZm9ybVN5bWV4cChjKSk7CgogIHNjYWxlLmNvbnN0YW50ID0gZnVuY3Rp
b24oXykgewogICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyB0cmFuc2Zvcm0odHJhbnNmb3Jt
U3ltbG9nKGMgPSArXyksIHRyYW5zZm9ybVN5bWV4cChjKSkgOiBjOwogIH07CgogIHJldHVybiBs
aW5lYXJpc2goc2NhbGUpOwp9CgpmdW5jdGlvbiBzeW1sb2coKSB7CiAgdmFyIHNjYWxlID0gc3lt
bG9naXNoKHRyYW5zZm9ybWVyJDEoKSk7CgogIHNjYWxlLmNvcHkgPSBmdW5jdGlvbigpIHsKICAg
IHJldHVybiBjb3B5KHNjYWxlLCBzeW1sb2coKSkuY29uc3RhbnQoc2NhbGUuY29uc3RhbnQoKSk7
CiAgfTsKCiAgcmV0dXJuIGluaXRSYW5nZS5hcHBseShzY2FsZSwgYXJndW1lbnRzKTsKfQoKZnVu
Y3Rpb24gdHJhbnNmb3JtUG93KGV4cG9uZW50KSB7CiAgcmV0dXJuIGZ1bmN0aW9uKHgpIHsKICAg
IHJldHVybiB4IDwgMCA/IC1NYXRoLnBvdygteCwgZXhwb25lbnQpIDogTWF0aC5wb3coeCwgZXhw
b25lbnQpOwogIH07Cn0KCmZ1bmN0aW9uIHRyYW5zZm9ybVNxcnQoeCkgewogIHJldHVybiB4IDwg
MCA/IC1NYXRoLnNxcnQoLXgpIDogTWF0aC5zcXJ0KHgpOwp9CgpmdW5jdGlvbiB0cmFuc2Zvcm1T
cXVhcmUoeCkgewogIHJldHVybiB4IDwgMCA/IC14ICogeCA6IHggKiB4Owp9CgpmdW5jdGlvbiBw
b3dpc2godHJhbnNmb3JtKSB7CiAgdmFyIHNjYWxlID0gdHJhbnNmb3JtKGlkZW50aXR5JDYsIGlk
ZW50aXR5JDYpLAogICAgICBleHBvbmVudCA9IDE7CgogIGZ1bmN0aW9uIHJlc2NhbGUoKSB7CiAg
ICByZXR1cm4gZXhwb25lbnQgPT09IDEgPyB0cmFuc2Zvcm0oaWRlbnRpdHkkNiwgaWRlbnRpdHkk
NikKICAgICAgICA6IGV4cG9uZW50ID09PSAwLjUgPyB0cmFuc2Zvcm0odHJhbnNmb3JtU3FydCwg
dHJhbnNmb3JtU3F1YXJlKQogICAgICAgIDogdHJhbnNmb3JtKHRyYW5zZm9ybVBvdyhleHBvbmVu
dCksIHRyYW5zZm9ybVBvdygxIC8gZXhwb25lbnQpKTsKICB9CgogIHNjYWxlLmV4cG9uZW50ID0g
ZnVuY3Rpb24oXykgewogICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoZXhwb25lbnQgPSAr
XywgcmVzY2FsZSgpKSA6IGV4cG9uZW50OwogIH07CgogIHJldHVybiBsaW5lYXJpc2goc2NhbGUp
Owp9CgpmdW5jdGlvbiBwb3ckMSgpIHsKICB2YXIgc2NhbGUgPSBwb3dpc2godHJhbnNmb3JtZXIk
MSgpKTsKCiAgc2NhbGUuY29weSA9IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIGNvcHkoc2NhbGUs
IHBvdyQxKCkpLmV4cG9uZW50KHNjYWxlLmV4cG9uZW50KCkpOwogIH07CgogIGluaXRSYW5nZS5h
cHBseShzY2FsZSwgYXJndW1lbnRzKTsKCiAgcmV0dXJuIHNjYWxlOwp9CgpmdW5jdGlvbiBzcXJ0
JDEoKSB7CiAgcmV0dXJuIHBvdyQxLmFwcGx5KG51bGwsIGFyZ3VtZW50cykuZXhwb25lbnQoMC41
KTsKfQoKZnVuY3Rpb24gcXVhbnRpbGUoKSB7CiAgdmFyIGRvbWFpbiA9IFtdLAogICAgICByYW5n
ZSA9IFtdLAogICAgICB0aHJlc2hvbGRzID0gW10sCiAgICAgIHVua25vd247CgogIGZ1bmN0aW9u
IHJlc2NhbGUoKSB7CiAgICB2YXIgaSA9IDAsIG4gPSBNYXRoLm1heCgxLCByYW5nZS5sZW5ndGgp
OwogICAgdGhyZXNob2xkcyA9IG5ldyBBcnJheShuIC0gMSk7CiAgICB3aGlsZSAoKytpIDwgbikg
dGhyZXNob2xkc1tpIC0gMV0gPSB0aHJlc2hvbGQoZG9tYWluLCBpIC8gbik7CiAgICByZXR1cm4g
c2NhbGU7CiAgfQoKICBmdW5jdGlvbiBzY2FsZSh4KSB7CiAgICByZXR1cm4gaXNOYU4oeCA9ICt4
KSA/IHVua25vd24gOiByYW5nZVtiaXNlY3RSaWdodCh0aHJlc2hvbGRzLCB4KV07CiAgfQoKICBz
Y2FsZS5pbnZlcnRFeHRlbnQgPSBmdW5jdGlvbih5KSB7CiAgICB2YXIgaSA9IHJhbmdlLmluZGV4
T2YoeSk7CiAgICByZXR1cm4gaSA8IDAgPyBbTmFOLCBOYU5dIDogWwogICAgICBpID4gMCA/IHRo
cmVzaG9sZHNbaSAtIDFdIDogZG9tYWluWzBdLAogICAgICBpIDwgdGhyZXNob2xkcy5sZW5ndGgg
PyB0aHJlc2hvbGRzW2ldIDogZG9tYWluW2RvbWFpbi5sZW5ndGggLSAxXQogICAgXTsKICB9OwoK
ICBzY2FsZS5kb21haW4gPSBmdW5jdGlvbihfKSB7CiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgp
IHJldHVybiBkb21haW4uc2xpY2UoKTsKICAgIGRvbWFpbiA9IFtdOwogICAgZm9yICh2YXIgaSA9
IDAsIG4gPSBfLmxlbmd0aCwgZDsgaSA8IG47ICsraSkgaWYgKGQgPSBfW2ldLCBkICE9IG51bGwg
JiYgIWlzTmFOKGQgPSArZCkpIGRvbWFpbi5wdXNoKGQpOwogICAgZG9tYWluLnNvcnQoYXNjZW5k
aW5nKTsKICAgIHJldHVybiByZXNjYWxlKCk7CiAgfTsKCiAgc2NhbGUucmFuZ2UgPSBmdW5jdGlv
bihfKSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChyYW5nZSA9IHNsaWNlJDUuY2Fs
bChfKSwgcmVzY2FsZSgpKSA6IHJhbmdlLnNsaWNlKCk7CiAgfTsKCiAgc2NhbGUudW5rbm93biA9
IGZ1bmN0aW9uKF8pIHsKICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHVua25vd24gPSBf
LCBzY2FsZSkgOiB1bmtub3duOwogIH07CgogIHNjYWxlLnF1YW50aWxlcyA9IGZ1bmN0aW9uKCkg
ewogICAgcmV0dXJuIHRocmVzaG9sZHMuc2xpY2UoKTsKICB9OwoKICBzY2FsZS5jb3B5ID0gZnVu
Y3Rpb24oKSB7CiAgICByZXR1cm4gcXVhbnRpbGUoKQogICAgICAgIC5kb21haW4oZG9tYWluKQog
ICAgICAgIC5yYW5nZShyYW5nZSkKICAgICAgICAudW5rbm93bih1bmtub3duKTsKICB9OwoKICBy
ZXR1cm4gaW5pdFJhbmdlLmFwcGx5KHNjYWxlLCBhcmd1bWVudHMpOwp9CgpmdW5jdGlvbiBxdWFu
dGl6ZSQxKCkgewogIHZhciB4MCA9IDAsCiAgICAgIHgxID0gMSwKICAgICAgbiA9IDEsCiAgICAg
IGRvbWFpbiA9IFswLjVdLAogICAgICByYW5nZSA9IFswLCAxXSwKICAgICAgdW5rbm93bjsKCiAg
ZnVuY3Rpb24gc2NhbGUoeCkgewogICAgcmV0dXJuIHggPD0geCA/IHJhbmdlW2Jpc2VjdFJpZ2h0
KGRvbWFpbiwgeCwgMCwgbildIDogdW5rbm93bjsKICB9CgogIGZ1bmN0aW9uIHJlc2NhbGUoKSB7
CiAgICB2YXIgaSA9IC0xOwogICAgZG9tYWluID0gbmV3IEFycmF5KG4pOwogICAgd2hpbGUgKCsr
aSA8IG4pIGRvbWFpbltpXSA9ICgoaSArIDEpICogeDEgLSAoaSAtIG4pICogeDApIC8gKG4gKyAx
KTsKICAgIHJldHVybiBzY2FsZTsKICB9CgogIHNjYWxlLmRvbWFpbiA9IGZ1bmN0aW9uKF8pIHsK
ICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHgwID0gK19bMF0sIHgxID0gK19bMV0sIHJl
c2NhbGUoKSkgOiBbeDAsIHgxXTsKICB9OwoKICBzY2FsZS5yYW5nZSA9IGZ1bmN0aW9uKF8pIHsK
ICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKG4gPSAocmFuZ2UgPSBzbGljZSQ1LmNhbGwo
XykpLmxlbmd0aCAtIDEsIHJlc2NhbGUoKSkgOiByYW5nZS5zbGljZSgpOwogIH07CgogIHNjYWxl
LmludmVydEV4dGVudCA9IGZ1bmN0aW9uKHkpIHsKICAgIHZhciBpID0gcmFuZ2UuaW5kZXhPZih5
KTsKICAgIHJldHVybiBpIDwgMCA/IFtOYU4sIE5hTl0KICAgICAgICA6IGkgPCAxID8gW3gwLCBk
b21haW5bMF1dCiAgICAgICAgOiBpID49IG4gPyBbZG9tYWluW24gLSAxXSwgeDFdCiAgICAgICAg
OiBbZG9tYWluW2kgLSAxXSwgZG9tYWluW2ldXTsKICB9OwoKICBzY2FsZS51bmtub3duID0gZnVu
Y3Rpb24oXykgewogICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAodW5rbm93biA9IF8sIHNj
YWxlKSA6IHNjYWxlOwogIH07CgogIHNjYWxlLnRocmVzaG9sZHMgPSBmdW5jdGlvbigpIHsKICAg
IHJldHVybiBkb21haW4uc2xpY2UoKTsKICB9OwoKICBzY2FsZS5jb3B5ID0gZnVuY3Rpb24oKSB7
CiAgICByZXR1cm4gcXVhbnRpemUkMSgpCiAgICAgICAgLmRvbWFpbihbeDAsIHgxXSkKICAgICAg
ICAucmFuZ2UocmFuZ2UpCiAgICAgICAgLnVua25vd24odW5rbm93bik7CiAgfTsKCiAgcmV0dXJu
IGluaXRSYW5nZS5hcHBseShsaW5lYXJpc2goc2NhbGUpLCBhcmd1bWVudHMpOwp9CgpmdW5jdGlv
biB0aHJlc2hvbGQkMSgpIHsKICB2YXIgZG9tYWluID0gWzAuNV0sCiAgICAgIHJhbmdlID0gWzAs
IDFdLAogICAgICB1bmtub3duLAogICAgICBuID0gMTsKCiAgZnVuY3Rpb24gc2NhbGUoeCkgewog
ICAgcmV0dXJuIHggPD0geCA/IHJhbmdlW2Jpc2VjdFJpZ2h0KGRvbWFpbiwgeCwgMCwgbildIDog
dW5rbm93bjsKICB9CgogIHNjYWxlLmRvbWFpbiA9IGZ1bmN0aW9uKF8pIHsKICAgIHJldHVybiBh
cmd1bWVudHMubGVuZ3RoID8gKGRvbWFpbiA9IHNsaWNlJDUuY2FsbChfKSwgbiA9IE1hdGgubWlu
KGRvbWFpbi5sZW5ndGgsIHJhbmdlLmxlbmd0aCAtIDEpLCBzY2FsZSkgOiBkb21haW4uc2xpY2Uo
KTsKICB9OwoKICBzY2FsZS5yYW5nZSA9IGZ1bmN0aW9uKF8pIHsKICAgIHJldHVybiBhcmd1bWVu
dHMubGVuZ3RoID8gKHJhbmdlID0gc2xpY2UkNS5jYWxsKF8pLCBuID0gTWF0aC5taW4oZG9tYWlu
Lmxlbmd0aCwgcmFuZ2UubGVuZ3RoIC0gMSksIHNjYWxlKSA6IHJhbmdlLnNsaWNlKCk7CiAgfTsK
CiAgc2NhbGUuaW52ZXJ0RXh0ZW50ID0gZnVuY3Rpb24oeSkgewogICAgdmFyIGkgPSByYW5nZS5p
bmRleE9mKHkpOwogICAgcmV0dXJuIFtkb21haW5baSAtIDFdLCBkb21haW5baV1dOwogIH07Cgog
IHNjYWxlLnVua25vd24gPSBmdW5jdGlvbihfKSB7CiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0
aCA/ICh1bmtub3duID0gXywgc2NhbGUpIDogdW5rbm93bjsKICB9OwoKICBzY2FsZS5jb3B5ID0g
ZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gdGhyZXNob2xkJDEoKQogICAgICAgIC5kb21haW4oZG9t
YWluKQogICAgICAgIC5yYW5nZShyYW5nZSkKICAgICAgICAudW5rbm93bih1bmtub3duKTsKICB9
OwoKICByZXR1cm4gaW5pdFJhbmdlLmFwcGx5KHNjYWxlLCBhcmd1bWVudHMpOwp9Cgp2YXIgdDAk
MSA9IG5ldyBEYXRlLAogICAgdDEkMSA9IG5ldyBEYXRlOwoKZnVuY3Rpb24gbmV3SW50ZXJ2YWwo
Zmxvb3JpLCBvZmZzZXRpLCBjb3VudCwgZmllbGQpIHsKCiAgZnVuY3Rpb24gaW50ZXJ2YWwoZGF0
ZSkgewogICAgcmV0dXJuIGZsb29yaShkYXRlID0gYXJndW1lbnRzLmxlbmd0aCA9PT0gMCA/IG5l
dyBEYXRlIDogbmV3IERhdGUoK2RhdGUpKSwgZGF0ZTsKICB9CgogIGludGVydmFsLmZsb29yID0g
ZnVuY3Rpb24oZGF0ZSkgewogICAgcmV0dXJuIGZsb29yaShkYXRlID0gbmV3IERhdGUoK2RhdGUp
KSwgZGF0ZTsKICB9OwoKICBpbnRlcnZhbC5jZWlsID0gZnVuY3Rpb24oZGF0ZSkgewogICAgcmV0
dXJuIGZsb29yaShkYXRlID0gbmV3IERhdGUoZGF0ZSAtIDEpKSwgb2Zmc2V0aShkYXRlLCAxKSwg
Zmxvb3JpKGRhdGUpLCBkYXRlOwogIH07CgogIGludGVydmFsLnJvdW5kID0gZnVuY3Rpb24oZGF0
ZSkgewogICAgdmFyIGQwID0gaW50ZXJ2YWwoZGF0ZSksCiAgICAgICAgZDEgPSBpbnRlcnZhbC5j
ZWlsKGRhdGUpOwogICAgcmV0dXJuIGRhdGUgLSBkMCA8IGQxIC0gZGF0ZSA/IGQwIDogZDE7CiAg
fTsKCiAgaW50ZXJ2YWwub2Zmc2V0ID0gZnVuY3Rpb24oZGF0ZSwgc3RlcCkgewogICAgcmV0dXJu
IG9mZnNldGkoZGF0ZSA9IG5ldyBEYXRlKCtkYXRlKSwgc3RlcCA9PSBudWxsID8gMSA6IE1hdGgu
Zmxvb3Ioc3RlcCkpLCBkYXRlOwogIH07CgogIGludGVydmFsLnJhbmdlID0gZnVuY3Rpb24oc3Rh
cnQsIHN0b3AsIHN0ZXApIHsKICAgIHZhciByYW5nZSA9IFtdLCBwcmV2aW91czsKICAgIHN0YXJ0
ID0gaW50ZXJ2YWwuY2VpbChzdGFydCk7CiAgICBzdGVwID0gc3RlcCA9PSBudWxsID8gMSA6IE1h
dGguZmxvb3Ioc3RlcCk7CiAgICBpZiAoIShzdGFydCA8IHN0b3ApIHx8ICEoc3RlcCA+IDApKSBy
ZXR1cm4gcmFuZ2U7IC8vIGFsc28gaGFuZGxlcyBJbnZhbGlkIERhdGUKICAgIGRvIHJhbmdlLnB1
c2gocHJldmlvdXMgPSBuZXcgRGF0ZSgrc3RhcnQpKSwgb2Zmc2V0aShzdGFydCwgc3RlcCksIGZs
b29yaShzdGFydCk7CiAgICB3aGlsZSAocHJldmlvdXMgPCBzdGFydCAmJiBzdGFydCA8IHN0b3Ap
OwogICAgcmV0dXJuIHJhbmdlOwogIH07CgogIGludGVydmFsLmZpbHRlciA9IGZ1bmN0aW9uKHRl
c3QpIHsKICAgIHJldHVybiBuZXdJbnRlcnZhbChmdW5jdGlvbihkYXRlKSB7CiAgICAgIGlmIChk
YXRlID49IGRhdGUpIHdoaWxlIChmbG9vcmkoZGF0ZSksICF0ZXN0KGRhdGUpKSBkYXRlLnNldFRp
bWUoZGF0ZSAtIDEpOwogICAgfSwgZnVuY3Rpb24oZGF0ZSwgc3RlcCkgewogICAgICBpZiAoZGF0
ZSA+PSBkYXRlKSB7CiAgICAgICAgaWYgKHN0ZXAgPCAwKSB3aGlsZSAoKytzdGVwIDw9IDApIHsK
ICAgICAgICAgIHdoaWxlIChvZmZzZXRpKGRhdGUsIC0xKSwgIXRlc3QoZGF0ZSkpIHt9IC8vIGVz
bGludC1kaXNhYmxlLWxpbmUgbm8tZW1wdHkKICAgICAgICB9IGVsc2Ugd2hpbGUgKC0tc3RlcCA+
PSAwKSB7CiAgICAgICAgICB3aGlsZSAob2Zmc2V0aShkYXRlLCArMSksICF0ZXN0KGRhdGUpKSB7
fSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLWVtcHR5CiAgICAgICAgfQogICAgICB9CiAgICB9
KTsKICB9OwoKICBpZiAoY291bnQpIHsKICAgIGludGVydmFsLmNvdW50ID0gZnVuY3Rpb24oc3Rh
cnQsIGVuZCkgewogICAgICB0MCQxLnNldFRpbWUoK3N0YXJ0KSwgdDEkMS5zZXRUaW1lKCtlbmQp
OwogICAgICBmbG9vcmkodDAkMSksIGZsb29yaSh0MSQxKTsKICAgICAgcmV0dXJuIE1hdGguZmxv
b3IoY291bnQodDAkMSwgdDEkMSkpOwogICAgfTsKCiAgICBpbnRlcnZhbC5ldmVyeSA9IGZ1bmN0
aW9uKHN0ZXApIHsKICAgICAgc3RlcCA9IE1hdGguZmxvb3Ioc3RlcCk7CiAgICAgIHJldHVybiAh
aXNGaW5pdGUoc3RlcCkgfHwgIShzdGVwID4gMCkgPyBudWxsCiAgICAgICAgICA6ICEoc3RlcCA+
IDEpID8gaW50ZXJ2YWwKICAgICAgICAgIDogaW50ZXJ2YWwuZmlsdGVyKGZpZWxkCiAgICAg