From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp1.migadu.com ([2001:41d0:303:e16b::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms8.migadu.com with LMTPS id qCXGNJl30mVFjQAA62LTzQ:P1 (envelope-from ) for ; Sun, 18 Feb 2024 22:33:14 +0100 Received: from aspmx1.migadu.com ([2001:41d0:303:e16b::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp1.migadu.com with LMTPS id qCXGNJl30mVFjQAA62LTzQ (envelope-from ) for ; Sun, 18 Feb 2024 22:33:13 +0100 X-Envelope-To: larch@yhetil.org Authentication-Results: aspmx1.migadu.com; dkim=pass header.d=excalamus.com header.s=zmail header.b=WUUlw4NL; arc=pass ("zohomail.com:s=zohoarc:i=1"); dmarc=none; spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org" ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1708291993; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:in-reply-to:in-reply-to: references:references:list-id:list-help:list-unsubscribe: list-subscribe:list-post:dkim-signature; bh=73tgLpsKYTpKtv4VH5V+dsf4dguH4sp5Gyci9q/hA40=; b=RcrqeUv9Yxif671169nt6D44Uy3ivIky+kNEs4nkiN0WyUVPv3i2ntzhynOImDLadO/prr QImyB9tTpab0S3F6YBxoQZr2ahGdnkaOYDMag+sriKwj+fNPDJM4CdsdvZVJneLRVoMva6 QTDX18xM4HX9Varero2db19SD2cuVLxahOxt/e1hCbzmwIycaKxv9s/8WqjJj/HRaYKFJS h2/hR5+L23790gNt2WVVV3GbHYbYhn+4OrP3/ihcxV/gjama/nSNXelKzOnFsdGeY1DkZA h0WD3bnFuyP5JOmNiInff73/yK8cXqDGL+zs8pO33Pgd+qyQR/oFWtH/JqBKuw== ARC-Authentication-Results: i=2; aspmx1.migadu.com; dkim=pass header.d=excalamus.com header.s=zmail header.b=WUUlw4NL; arc=pass ("zohomail.com:s=zohoarc:i=1"); dmarc=none; spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org" ARC-Seal: i=2; s=key1; d=yhetil.org; t=1708291993; a=rsa-sha256; cv=pass; b=czypHTHayXU+qNxmbGSkeIXZXKSDhaOaCP91ZwdXrrtF14lisqQ2rU443O3KjLjsIKEW8L jkuEsAKOhANLVLnX4pSHrOAxZicYvuQv0SzGO/Ytd7Gid52pnObdybGtJOxTvKgqgD1Hc6 rEAjFk/2coEbM7heyP6auhuqF9lcT7BxYWVoT8tmh/MQHz/9EreuCm4cjh8AvFqTVmyyyw ao1BFmLb+nMtH3/2aexdisAnVvvLWPAJACZ68xnq/7I1PY+XG/r6Rs5dXtN/q9zpMJ1dhf K0TwI34VZR4nESdDtuJR/4iajS4PgC/CCkMaW3adY8CRFgyaytrv163FpwNz2Q== Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 5AAB440618 for ; Sun, 18 Feb 2024 22:33:13 +0100 (CET) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rboUD-00088l-VD; Sun, 18 Feb 2024 16:14:09 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rboUB-00086D-MS for emacs-orgmode@gnu.org; Sun, 18 Feb 2024 16:14:08 -0500 Received: from sender4-pp-f112.zoho.com ([136.143.188.112]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rboU9-0007eB-EY for emacs-orgmode@gnu.org; Sun, 18 Feb 2024 16:14:07 -0500 ARC-Seal: i=1; a=rsa-sha256; t=1708290842; cv=none; d=zohomail.com; s=zohoarc; b=XGOneZsyD2HVQgGx08LzIljC/lVROfgT0weNXJ/gMRv4BrvkIMXyx9FljTak1/zJt89/RvVNRwMQzk/JbZMqeND8t2N4uCsrVbes9CIiJ6DBMiUwkM7uxTirHlxMtUcE4Db8FwgRIUcEZvYo3HNy/NPdc6Ya0WcSkOtNjYFFaaY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1708290842; h=Content-Type:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=73tgLpsKYTpKtv4VH5V+dsf4dguH4sp5Gyci9q/hA40=; b=jFI46fn8+TIRZSt80v/4RXGw5aaKW/2knfVVlVGhFh4uPEpz3wL5N2Hrjq4WBbF7gwXy0mViTSFgIxD1st84ZVuotdYHjjE7g03pRf1xDSKgEVOfLgcvMgoXkfEPkjVMnFXTFVpBYHHFBGdJSxjInMI0faPlYFVys5sjfSkpnVE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=excalamus.com; spf=pass smtp.mailfrom=matt@excalamus.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1708290842; s=zmail; d=excalamus.com; i=matt@excalamus.com; h=Date:Date:From:From:To:To:Cc:Cc:Message-Id:Message-Id:In-Reply-To:References:Subject:Subject:MIME-Version:Content-Type:Reply-To; bh=73tgLpsKYTpKtv4VH5V+dsf4dguH4sp5Gyci9q/hA40=; b=WUUlw4NLOYMy4jGdsx+UmBO/b+Bhj798nEv1xKThTx9dIC3vAhqP2BKN+Hb7t6Bn /eLESaSRnjyLJp1u1jVomAEGsZoHV1y0J5Zlvn/J/MFINpuzVrxWErfH1kd9BpetOWM fzBuP5uPSpyZxR2BUwuQESex1Yq7vtOPMTJVj1Ck= Received: from mail.zoho.com by mx.zohomail.com with SMTP id 1708290840243569.907745043626; Sun, 18 Feb 2024 13:14:00 -0800 (PST) Date: Sun, 18 Feb 2024 22:14:00 +0100 From: Matt To: "Bruno Barbier" Cc: "Ihor Radchenko" , "Jack Kamm" , "emacs-orgmode" Message-Id: <18dbe11968a.12c0800a31425096.5114791462107560324@excalamus.com> In-Reply-To: <65cfa0d8.050a0220.cb569.ce34@mx.google.com> References: <87o7d0mm54.fsf@localhost> <65bbb108.050a0220.b60fd.6790@mx.google.com> <87jznm8hcu.fsf@gmail.com> <875xz42rp9.fsf@localhost> <874jen8zec.fsf@gmail.com> <87o7cv9e80.fsf@localhost> <65c2875f.050a0220.caf6d.8291@mx.google.com> <18dae5cab1d.bf1c7563863897.4896289306902277373@excalamus.com> <65cfa0d8.050a0220.cb569.ce34@mx.google.com> Subject: Re: Asynchronous blocks for everything (was Re: [BUG] Unexpected result when evaluating python src block asynchronously [9.7-pre (release_9.6.17-1131-gc9ed03.dirty @ /home/yantar92/.emacs.d/straight/build/org/)]) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_Part_4640427_612908003.1708290840203" Importance: Medium User-Agent: Zoho Mail X-Mailer: Zoho Mail X-Zoho-Virus-Status: 1 X-Zoho-AV-Stamp: zmail-av-1.1.0/208.267.99 Received-SPF: pass client-ip=136.143.188.112; envelope-from=matt@excalamus.com; helo=sender4-pp-f112.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_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-orgmode@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+larch=yhetil.org@gnu.org Sender: emacs-orgmode-bounces+larch=yhetil.org@gnu.org X-Migadu-Flow: FLOW_IN X-Migadu-Country: US X-Migadu-Spam-Score: -7.14 X-Spam-Score: -7.14 X-Migadu-Queue-Id: 5AAB440618 X-Migadu-Scanner: mx13.migadu.com X-TUID: lUalGfn1jf19 ------=_Part_4640427_612908003.1708290840203 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable ---- On Fri, 16 Feb 2024 18:52:22 +0100 Bruno Barbier=20 > Sorry for the late reply. Cleaning the code took me longer than expecte= d. No need to apologize, we're all volunteers here :) > Feedbacks, corrections, critiques, etc are most welcome! Thank you for sharing! If I understand correctly, there are several independent topics the code ad= dresses: | topic | manner addressed | |------------------+------------------------------------------------| | execution status | using overlays to communicate execution status | | locating results | using overlays to locate results | | blocking | making all execution asynchronous | |------------------+------------------------------------------------| I suggest these be discussed in separate threads. > > The use of the overlay is a really cool idea! > > > > I hesitate to say that's a good way to convey success or failure. If = a process failed, I want to see the output which tells me why so that I can= correct it. Or, I might actually want the failure output. Maybe I want t= o literally demonstrate what a code failure looks like. Maybe I want to us= e that output in another block. For example, shell blocks have multiple ou= tput types. A shell process may return standard output/error or a failure = code. The result of the failure may trigger something else. >=20 > I'm not sure I fully understand what you mean. The API just assumes the = backend returns the outcome: either success or failure, where failure means= "no result" (the previous result, if it exists, is even preserved in the d= ocument). The backend is free to transform a failure into a success to mak= e that result available though. You can disregard my hesitation on this point. I had not run your code yet= and had misunderstood how it worked. Since this thread is dedicated to blocking, let me share my thoughts on tha= t subject. > To execute Python blocks, using the proposed async API: >=20 > - I've (re)implemented the "asynchronous with session" case (copying/= pasting the relevant part from ob-python). > =20 > - The "synchronous case" is just artificially blocking the user until= the asynchronous result is known (which looks incredibly tricky to impleme= nt if even possible...). > =20 > - The "no session" case is just about creating a new unique session a= nd throwing it away immediately. This is an interesting idea, feeding all processes through the same mechani= sm. Executing a shell block requires starting a [[https://www.gnu.org/software/= emacs/manual/html_node/elisp/Processes.html][process]]. Processes are synchronous or asynchronous. Three primitives exist in Emacs for making processes: 1. make-process (asynchronous) 2. call-process (synchronous) 3. call-process-region (synchronous) There exist several convenience wrappers for these. AFAIK, everything redu= ces to these three primitives. For example, =3Dasync-shell-command=3D runs= =3Dcall-process=3D and prevents blocking by appending a "&" to the command= which tells the shell to run the command in the background and return cont= rol to the terminal. This background-foreground distinction is called "job= control". Output from a process typically goes to a buffer. This may be changed and = instead handle output with a filter function. =3Dcall-process=3D has an op= tion to directly send output to a file. Subprocesses inherent the =3Ddefault-directory=3D and the environment from = Emacs. The environment may be changed using =3Dprocess-environment=3D. There are two types of asynchronous connections: "pty" ("pseudoterminal") a= nd "pipe". The main difference is that "pty" provides a terminal-like conn= ection which allows for things like job control (=3DC-c=3D, =3DC-z=3D, etc.= ). In my previous message, I divided evaluation into 4 types: - non-persistent vs. persistent=20 - synchronous vs. asynchronous I find the approach of feeding everything through, fundamentally, =3Dmake-p= rocess=3D interesting because if we make a chart of the 4 types, we see som= e ambiguities: | | non-persistent | persistent | |--------------+----------------+--------------| | synchronous | call-process | ??? | |--------------+----------------+--------------| | asynchronous | ??? | make-process | |--------------+----------------+--------------| To make a non-persistent asynchronous process, the first thing that comes t= o mind is =3Dasync-shell-command=3D. However, as the code shows, another o= ption is to use =3Dmake-process=3D and throw away the state (the process bu= ffer). I'm not sure how we could make a persistent, synchronous process. Persiste= nce is achieved, currently, by a process buffer. Is there another way pers= istence may be achieved? Of course, this ignores whether a persistent, syn= chronous process is even desirable. Given reliable asynchronous execution = with persistence, I can't think of reason why someone would prefer a blocki= ng operation. All that is mainly academic. The idea I think most interesting is using a = single primitive to handle all evaluation. It idea reminded me of exploration code I wrote a while back which uses =3D= make-process=3D to run all code blocks asynchronously (attached). It works as follows. I defined a new Babel "language" called "blub". Blu= b could be a shell, python, ruby, whatever. I wanted to test that the impl= ementation could work with different interpreters or compilers. Note that = "blub" doesn't have any relationship to Paul Graham's blub; I just needed a= name for a generic language that could be swapped out. Attached are two files, ob-blub.el and ob-blub-test.org. Download both to = the same directory. Run the first block in ob-blub-test.org. This imports= ob-blub, loads it into Babel, and sets up blub to be whatever =3Dshell-fil= e-name=3D is (for example, bash). If you want to try Python or Ruby, comme= nt out the shell configuration, uncomment the Python or Ruby implementation= s, and evaluate the block again. Hopefully ob-blub.el is documented suffic= iently for you to experiment. The blub implementation has the same shortcomings, at least for shells, as = the current shell implementation. It has a few ideas, such as everything b= eing asynchronous and completely removing the prompt, that may prove useful= for improving Babel generally. The blub implementation is also simpler th= an related parts of Babel and may be useful for figuring out ways to solve = the currently known shortcomings. If you run into an error during executio= n, you will need to call (setq my-org-babel-comint--async-uuid nil). The challenge I've found with Babel is figuring out how to make the changes= . My current approach is to address bugs and to make changes that move us = toward something like the ob-blub implementation. I wonder if it might hel= p to discuss the core ideas and use a minimal reference implementation that= serves as a guide for the actual changes we make. Curious to hear other people's thoughts! -- Matt Trzcinski Emacs Org contributor (ob-shell) Learn more about Org mode at https://orgmode.org Support Org development at=C2=A0https://liberapay.com/org-mode ------=_Part_4640427_612908003.1708290840203 Content-Type: application/octet-stream; name=ob-blub-test.org Content-Transfer-Encoding: 7bit X-ZM_AttachId: 139275836402030110 Content-Disposition: attachment; filename=ob-blub-test.org #+begin_src emacs-lisp :results silent :var HERE=(buffer-file-name) ;; load blub (add-to-list 'load-path (file-name-directory HERE)) (require 'ob-blub) (org-babel-do-load-languages 'org-babel-load-languages '((blub . t))) ;; reset uuid on failed block (setq my-org-babel-comint--async-uuid nil) ;; configure shell (setq org-babel-blub-interpreter shell-file-name) (setq org-babel-blub-remove-prompt-command "PROMPT_COMMAND=;PS1=;PS2=;") (setq org-babel-blub-output-start-delimiter "echo \"start_%s\"") (setq org-babel-blub-output-end-delimiter "echo \"end_%s\"") (setq org-babel-blub-interpreter-args '()) ;; configure python ;; (setq org-babel-blub-interpreter "python3") ;; (setq org-babel-blub-remove-prompt-command "import sys;sys.ps1='';sys.ps2='';") ;; (setq org-babel-blub-output-start-delimiter "print(\"start_%s\")") ;; (setq org-babel-blub-output-end-delimiter "print(\"end_%s\")") ;; (setq org-babel-blub-interpreter-args '()) ;; configure ruby ;; (setq org-babel-blub-interpreter "ruby") ; for non-sessions ;; (setq org-babel-blub-interpreter "irb") ; for sessions ;; (setq org-babel-blub-remove-prompt-command nil) ;; (setq org-babel-blub-output-start-delimiter "puts \"start_%s\"") ;; (setq org-babel-blub-output-end-delimiter "puts \"end_%s\"") ;; (setq org-babel-blub-interpreter-args '("--noprompt" "--noreadline" "--nomultiline")) #+end_src * Non-persistent ** shell #+begin_src blub echo "hello" sleep 3 echo "world!" #+end_src #+RESULTS: : hello : world! #+begin_src blub ==echo "hello" sleep 3 echo "world!" #+end_src ** python #+begin_src blub import time print("hello without session") time.sleep(3) print("world") #+end_src ** ruby #+begin_src blub puts "cruel world" sleep(3) puts "good-bye" #+end_src * Persistent ** shell #+begin_src blub :session *shell-blubber* echo "hello" sleep 3 echo "world!" #+end_src #+begin_src blub :session *shell-blubber* ==echo "hello" sleep 3 echo "world!" #+end_src ** python #+begin_src blub :session *python-blubber* import time print("hello") time.sleep(5) print("world") #+end_src #+RESULTS: #+begin_src blub :session *python-blubber* import time print("good-bye") time.sleep(5) print("cruel world") #+end_src ** ruby #+begin_src blub :session *ruby-blubber* puts "good-bye" sleep(3) puts "cruel world" #+end_src * Failures #+begin_src blub :session *bash-blubber* ssh localhost "echo foo>foo_file" echo "bar" | tee /tmp/bar.txt #+end_src #+begin_src blub :session *shell-blubber* :epilogue echo "bye" ssh $USER@localhost echo "hi" #+end_src ------=_Part_4640427_612908003.1708290840203 Content-Type: application/octet-stream; name=ob-blub.el Content-Transfer-Encoding: base64 X-ZM_AttachId: 139275836402100070 Content-Disposition: attachment; filename=ob-blub.el OzsgLSotIGxleGljYWwtYmluZGluZzogdCAtKi0KCjs7OyBvYi1ibHViLmVsIC0tLSBvcmctYmFi ZWwgZnVuY3Rpb25zIGZvciBibHViIGV2YWx1YXRpb24KCjs7IENvcHlyaWdodCAoQykgTWF0dCBU cnpjaW5za2kKCjs7IEF1dGhvcjogTWF0dCBUcnpjaW5za2kKOzsgS2V5d29yZHM6IGxpdGVyYXRl IHByb2dyYW1taW5nLCByZXByb2R1Y2libGUgcmVzZWFyY2gKOzsgSG9tZXBhZ2U6IGh0dHBzOi8v b3JnbW9kZS5vcmcKOzsgVmVyc2lvbjogMC4wMQoKOzs7IExpY2Vuc2U6Cgo7OyBUaGlzIHByb2dy YW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlm eQo7OyBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNl IGFzIHB1Ymxpc2hlZCBieQo7OyB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIg dmVyc2lvbiAzLCBvciAoYXQgeW91ciBvcHRpb24pCjs7IGFueSBsYXRlciB2ZXJzaW9uLgo7Owo7 OyBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJl IHVzZWZ1bCwKOzsgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGlt cGxpZWQgd2FycmFudHkgb2YKOzsgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFS VElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQo7OyBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBm b3IgbW9yZSBkZXRhaWxzLgo7Owo7OyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9m IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQo7OyBhbG9uZyB3aXRoIEdOVSBFbWFjczsg c2VlIHRoZSBmaWxlIENPUFlJTkcuICBJZiBub3QsIHdyaXRlIHRvIHRoZQo7OyBGcmVlIFNvZnR3 YXJlIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsCjs7 IEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBLgoKOzs7IENvbW1lbnRhcnk6Cjs7Cjs7IEEgbmV3 IGxhbmd1YWdlLCBibHViLCBpcyBkZWZpbmVkIHVzaW5nIHRoZSBPcmcgQmFiZWwgQVBJCjs7IChg b3JnLWJhYmVsLWV4ZWN1dGU6Ymx1YicpLiAgIkJsdWIiIGlzIGEgZHVtbXkgbGFuZ3VhZ2UuICBJ ZiBibHViCjs7IGlzIGludGVycHJldGVkLCBzZXQgdGhlIGludGVycHJldGVyIHVzaW5nCjs7IGBv cmctYmFiZWwtYmx1Yi1pbnRlcnByZXRlcicuICBDb21waWxlZCBsYW5ndWFnZXMgYXJlIG5vdAo7 OyBkZW1vbnN0cmF0ZWQgaGVyZSBhbHRob3VnaCB0aGUgaW1wbGVtZW50YXRpb24gbWF5IGJlIGV4 dGVuZGVkIHRvCjs7IHN1cHBvcnQgY29tcGlsZWQgbGFuZ3VhZ2VzLgo7Owo7OyBUaGUgY29kZSBp cyBzcGxpdCBpbnRvIHRocmVlIHNlY3Rpb25zOgo7Owo7OyAgIDEuIEV2YWwKOzsgICAyLiBDb21p bnQKOzsgICAzLiBCbHViCjs7Cjs7IFNlY3Rpb25zIGFyZSBiYXNlZCBvbiB0aGVpciBjdXJyZW50 IGltcGxlbWVudHMgaW4gT3JnIEJhYmVsLiAgSXQncwo7OyBub3QgY2xlYXIgaWYgdGhlc2UgYXJl IHRoZSAicmlnaHQiIGNhdGVnb3JpemF0aW9ucy4gIEZvciBleGFtcGxlLAo7OyBzaG91bGQgY29t aW50IGV2YWx1YXRpb24gYmUgaW4gb2ItY29taW50IG9yIG9iLWV2YWw/Cjs7Cjs7IFNldCB0aGUg Zm9sbG93aW5nOgo7Owo7OyAgIGBvcmctYmFiZWwtYmx1Yi1pbnRlcnByZXRlcicKOzsgICBgb3Jn LWJhYmVsLWJsdWItaW50ZXJwcmV0ZXItYXJncycKOzsgICBgb3JnLWJhYmVsLWJsdWItcmVtb3Zl LXByb21wdC1jb21tYW5kJwo7OyAgIGBvcmctYmFiZWwtYmx1Yi1vdXRwdXQtc3RhcnQtZGVsaW1p dGVyJwo7OyAgIGBvcmctYmFiZWwtYmx1Yi1vdXRwdXQtZW5kLWRlbGltaXRlcicKOzsKOzsgU2Vz c2lvbnMgcnVuIGluIGEgZGVkaWNhdGVkIHByb2Nlc3MgYnVmZmVyLiAgT3V0cHV0IGlzIGNhcHR1 cmVkCjs7IGZyb20gYmV0d2VlbiBkZWxpbWl0ZXJzLiAgVGhpcyBpcyBzaW1pbGFyIHRvIHRoZSBj dXJyZW50IEJhYmVsCjs7IGltcGxlbWVudGF0aW9uLiAgSG93ZXZlciwgdW5saWtlIHRoZSBjdXJy ZW50IEJhYmVsIGltcGxlbWVudGF0aW9uLAo7OyBib3RoIGRlbGltaXRlcnMgaW4gdGhpcyBwcm9v ZiBvZiBjb25jZXB0IGFyZSBjdXN0b20uICBUaGUgY3VycmVudAo7OyBCYWJlbCBpbXBsZW1lbnRh dGlvbiB1c2VzIHRoZSBwcm9tcHQgZm9yIHRoZSBzdGFydCBkZWxpbWl0ZXIgd2hpY2gKOzsgY2F1 c2VzIHByb2JsZW1zIHdoZW4gaXQgY2hhbmdlcy4KOzsKOzsgRm9yIHNlc3Npb25zLCBvbmx5IGEg c2luZ2xlIHByb2Nlc3MgbWF5IHJ1biBhdCBhIHRpbWUuICBUaGUgVVVJRCBpcwo7OyBzdG9yZWQg aW4gYG15LW9yZy1iYWJlbC1jb21pbnQtLWFzeW5jLXV1aWQnIGFuZCB0aGUgYXNzb2NpYXRlZCBP cmcKOzsgYnVmZmVyIGlzIHN0b3JlZCBpbiBgbXktb3JnLWJhYmVsLWNvbWludC0tYXN5bmMtb3Jn LWJ1ZmZlcicuICBJZiBhbgo7OyBlcnJvciBvY2N1cnMgdGhhdCBwcmV2ZW50cyB0aGUgZW5kIGRl bGltaXRlciBmcm9tIHByaW50aW5nLAo7OyBtYW51YWxseSB0aGUgY2xlYXIgYG15LW9yZy1iYWJl bC1jb21pbnQtLWFzeW5jLXV1aWQnIHRvIHJ1biBibG9ja3MuCjs7Cjs7ICAgKHNldHEgbXktb3Jn LWJhYmVsLWNvbWludC0tYXN5bmMtdXVpZCBuaWwpCjs7Cjs7IFJlc3VsdHMgYXJlIGV4dHJhY3Rl ZCBmcm9tIHN0YW5kYXJkIG91dHB1dCB1c2luZyBhIHJlZ2V4cC4KOzsKOzsgTm90ZWQgcHJvYmxl bXM6Cjs7ICAgLSBydW5uaW5nIHN1ZG8KCjs7OyBSZXF1aXJlbWVudHM6CihyZXF1aXJlICdvYikK CgwKOzs7IEV2YWw6CihkZWZ1biBteS1vcmctYmFiZWwtZXZhbC1hc3luYyAoY29tbWFuZCBib2R5 KQogICJTdGFydCBwcm9jZXNzIHdpdGggQ09NTUFORCwgc2VuZCBCT0RZIHRvIHByb2Nlc3MsIGdl dApyZXN1bHRzLgoKU2luY2UgcmVzdWx0cyBleGVjdXRlIGFzeW5jaHJvbm91c2x5LCBhIFVVSUQg aXMgcmV0dXJuZWQuICBUaGUKVVVJRCBpcyBsYXRlciByZXBsYWNlZCB3aGVuIHRoZSBhc3luYyBw cm9jZXNzIGZpbmlzaGVzLiIKICAoc2V0cSBteS1vcmctYmFiZWwtY29taW50LS1hc3luYy11dWlk IChvcmctaWQtdXVpZCkpCiAgKHNldHEgbXktb3JnLWJhYmVsLWNvbWludC0tYXN5bmMtb3JnLWJ1 ZmZlciAoY3VycmVudC1idWZmZXIpKQogIChsZXQqICgobXktcHJvY2VzcwogICAgICAgICAgKG1h a2UtcHJvY2VzcwogICAgICAgICAgIDpuYW1lICJteS1vcmctYmFiZWwtZXZhbC1hc3luYyIKICAg ICAgICAgICA6YnVmZmVyICIqbXktb3JnLWJhYmVsLWV2YWwtYXN5bmMqIgogICAgICAgICAgIDpj b21tYW5kIGAoLGNvbW1hbmQpCiAgICAgICAgICAgOmNvbm5lY3Rpb24tdHlwZSAncGlwZQogICAg ICAgICAgIDpzZW50aW5lbCAnKGxhbWJkYSAocHJvY2VzcyBtc2cpCiAgICAgICAgICAgICAgICAg ICAgICAgIChjb25kICgoc3RyaW5nPSBtc2cgImZpbmlzaGVkXG4iKQogICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgKG15LW9yZy1iYWJlbC1jb21pbnQtcmVwbGFjZS11dWlkLXdpdGgtcmVz dWx0cwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG15LW9yZy1iYWJlbC1jb21pbnQt LWFzeW5jLW9yZy1idWZmZXIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBteS1vcmct YmFiZWwtY29taW50LS1hc3luYy11dWlkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg KHdpdGgtY3VycmVudC1idWZmZXIgKHByb2Nlc3MtYnVmZmVyIHByb2Nlc3MpCiAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAoYnVmZmVyLXN1YnN0cmluZy1uby1wcm9wZXJ0aWVzIChw b2ludC1taW4pIChwb2ludC1tYXgpKSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAo c2V0cSBteS1vcmctYmFiZWwtY29taW50LS1hc3luYy11dWlkIG5pbCkKICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgIChsZXQgKChraWxsLWJ1ZmZlci1xdWVyeS1mdW5jdGlvbnMgbmlsKSkK ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGlmIChraWxsLWJ1ZmZlciAiKm15LW9y Zy1iYWJlbC1ldmFsLWFzeW5jKiIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAoc2V0cSBteS1vcmctYmFiZWwtY29taW50LS1hc3luYy1vcmctYnVmZmVyIG5pbCkpKQogICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgKSkpKSkpCiAgICAocHJvY2Vzcy1zZW5kLXN0cmlu ZyBteS1wcm9jZXNzIGJvZHkpCiAgICAocHJvY2Vzcy1zZW5kLWVvZiBteS1wcm9jZXNzKSkKICBt eS1vcmctYmFiZWwtY29taW50LS1hc3luYy11dWlkKQoKDAo7OzsgQ29taW50OgooZGVmdmFyIG15 LW9yZy1iYWJlbC1jb21pbnQtLWFzeW5jLXV1aWQgbmlsCiAgIlBsYWNlaG9sZGVyIGZvciByZXN1 bHRzLiIpCihkZWZ2YXIgbXktb3JnLWJhYmVsLWNvbWludC0tYXN5bmMtb3JnLWJ1ZmZlciBuaWwK ICAiQnVmZmVyIGNvbnRhaW5pbmcgVVVJRC4iKQoKKGRlZnVuIG15LW9yZy1iYWJlbC1jb21pbnQt c2VuZC1zdHJpbmcgKHNlc3Npb24gc3RyaW5nKQogICJTZW5kIFNUUklORyB0byBjb21pbnQgU0VT U0lPTi4iCiAgKHdpdGgtY3VycmVudC1idWZmZXIgc2Vzc2lvbgogICAgKGdvdG8tY2hhciAocHJv Y2Vzcy1tYXJrIChnZXQtYnVmZmVyLXByb2Nlc3Mgc2Vzc2lvbikpKQogICAgKGluc2VydCBzdHJp bmcpCiAgICAoY29taW50LXNlbmQtaW5wdXQpKSkKCihkZWZ1biBteS1vcmctYmFiZWwtY29taW50 LXJlcGxhY2UtdXVpZC13aXRoLXJlc3VsdHMgKGJ1ZmZlciB1dWlkIHJlc3VsdHMpCiAgIlJlcGxh Y2UgVVVJRCBzdHJpbmcgaW4gQlVGRkVSIHdpdGggUkVTVUxUUyBzdHJpbmcuIgogICh3aXRoLWN1 cnJlbnQtYnVmZmVyIGJ1ZmZlcgogICAgKHNhdmUtZXhjdXJzaW9uCiAgICAgIChnb3RvLWNoYXIg KHBvaW50LW1pbikpCiAgICAgICh3aGVuIChzZWFyY2gtZm9yd2FyZCB1dWlkIG5pbCB0KQogICAg ICAgIChvcmctYmFiZWwtcHJldmlvdXMtc3JjLWJsb2NrKQogICAgICAgIChsZXQqICgoaW5mbyAo b3JnLWJhYmVsLWdldC1zcmMtYmxvY2staW5mbykpCiAgICAgICAgICAgICAgIChwYXJhbXMgKG50 aCAyIGluZm8pKQogICAgICAgICAgICAgICAocmVzdWx0LXBhcmFtcwogICAgICAgICAgICAgICAg KGNkciAoYXNzcSA6cmVzdWx0LXBhcmFtcyBwYXJhbXMpKSkpCiAgICAgICAgICAob3JnLWJhYmVs LWluc2VydC1yZXN1bHQKICAgICAgICAgICByZXN1bHRzIHJlc3VsdC1wYXJhbXMgaW5mbykpKSkp KQoKKGRlZnVuIG15LW9yZy1iYWJlbC1jb21pbnQtc2VuZC10by1zZXNzaW9uLWFzeW5jIChwcm9j ZXNzLWJ1ZmZlciAmcmVzdCBib2R5KQogICJTZW5kIEJPRFkgdG8gUFJPQ0VTUy1CVUZGRVIgYXN5 bmNocm9ub3VzbHkuIgogIChzZXRxIG15LW9yZy1iYWJlbC1jb21pbnQtLWFzeW5jLXV1aWQgKG9y Zy1pZC11dWlkKSkKICAoc2V0cSBteS1vcmctYmFiZWwtY29taW50LS1hc3luYy1vcmctYnVmZmVy IChjdXJyZW50LWJ1ZmZlcikpCgogIChkZWZ1biBteS1vcmctYmFiZWwtY29taW50LS1hc3luYy1m aWx0ZXIgKHRleHQpCiAgICAiQ2hlY2sgVEVYVCBmb3IgZW5kaW5nIGRlbGltaXRlciBhbmQgcmVw bGFjZSByZXN1bHRzIGhlbGQgYnkKYG15LW9yZy1iYWJlbC1jb21pbnQtLWFzeW5jLXV1aWQnIHBs YWNlaG9sZGVyLiIKICAgIChjb25kICgoc3RyaW5nLW1hdGNoLXAgKGZvcm1hdCAiZW5kXyVzIiBt eS1vcmctYmFiZWwtY29taW50LS1hc3luYy11dWlkKSB0ZXh0KQogICAgICAgICAgIChyZW1vdmUt aG9vayAnY29taW50LW91dHB1dC1maWx0ZXItZnVuY3Rpb25zICdteS1vcmctYmFiZWwtY29taW50 LS1hc3luYy1maWx0ZXIpCgogICAgICAgICAgIDs7IHJlcGxhY2UgbXktb3JnLWJhYmVsLWNvbWlu dC0tYXN5bmMtdXVpZCBpbiBPcmcgYnVmZmVyCiAgICAgICAgICAgKGxldCAoKHJlc3VsdHMKICAg ICAgICAgICAgICAgICAgKHdpdGgtY3VycmVudC1idWZmZXIgcHJvY2Vzcy1idWZmZXIgOyBlLmcu ICIqYmx1YmJlcioiCiAgICAgICAgICAgICAgICAgICAgKGdvdG8tY2hhciAocG9pbnQtbWluKSkK ICAgICAgICAgICAgICAgICAgICAocmUtc2VhcmNoLWZvcndhcmQKICAgICAgICAgICAgICAgICAg ICAgOzsgT2YgY291cnNlLCBhbGwgdGhlIHByb2JsZW1zIHdpdGggcmVnZXhwIGhhcHBlbiBoZXJl LiAgVGhlIGdvYWwgaXMgZ2V0dGluZwogICAgICAgICAgICAgICAgICAgICA7OyB0aGUgdGV4dCBi ZXR3ZWVuIHRoZSBkZWxpbWl0ZXJzLgogICAgICAgICAgICAgICAgICAgICA7OwogICAgICAgICAg ICAgICAgICAgICA7OyBTb21lIHByb2dyYW1zIChndWl4IHNoZWxsPykgbWF5IHJlc2V0IFBTMS4g IFNvLCB3ZSBjYW4ndCBhbHdheXMgbWF0Y2ggb24KICAgICAgICAgICAgICAgICAgICAgOzsgc3Rh cnRfdXVpZCBiZWluZyBhdCB0aGUgdmVyeSBzdGFydCBvZiB0aGUgbGluZS4gIE1hdGNoIG9uIHRo ZSBvbmUgdGhhdAogICAgICAgICAgICAgICAgICAgICA7OyBkb2Vzbid0IGhhdmUgdGhlIHF1b3Rl ICh0aGF0IGlzLCB0aGUgcmVzdWx0IG9mIHRoZSBlY2hvKS4KICAgICAgICAgICAgICAgICAgICAg KGZvcm1hdCAiW15cIl1zdGFydF8lc1tcclxuXSpcXChcXCguKltcclxuXStcXCkqLipcXCllbmRf JXMkIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG15LW9yZy1iYWJlbC1jb21pbnQtLWFz eW5jLXV1aWQgICA7IHN0YXJ0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXktb3JnLWJh YmVsLWNvbWludC0tYXN5bmMtdXVpZCkgIDsgZW5kCiAgICAgICAgICAgICAgICAgICAgIG5pbCBu aWwgMSkKICAgICAgICAgICAgICAgICAgICAobGV0ICgobWF0Y2ggKG1hdGNoLXN0cmluZyAxKSkp CiAgICAgICAgICAgICAgICAgICAgICAoc3Vic3RyaW5nLW5vLXByb3BlcnRpZXMKICAgICAgICAg ICAgICAgICAgICAgICBtYXRjaCkpKSkpCgogICAgICAgICAgICAgKG15LW9yZy1iYWJlbC1jb21p bnQtcmVwbGFjZS11dWlkLXdpdGgtcmVzdWx0cwogICAgICAgICAgICAgIG15LW9yZy1iYWJlbC1j b21pbnQtLWFzeW5jLW9yZy1idWZmZXIKICAgICAgICAgICAgICBteS1vcmctYmFiZWwtY29taW50 LS1hc3luYy11dWlkCiAgICAgICAgICAgICAgcmVzdWx0cykKCiAgICAgICAgICAgICAoc2V0cSBt eS1vcmctYmFiZWwtY29taW50LS1hc3luYy11dWlkIG5pbCkKICAgICAgICAgICAgIChzZXRxIG15 LW9yZy1iYWJlbC1jb21pbnQtLWFzeW5jLW9yZy1idWZmZXIgbmlsKSkpKSkKCiAgKGxldCogKChw cm9jIChnZXQtYnVmZmVyLXByb2Nlc3MgcHJvY2Vzcy1idWZmZXIpKSkKICAgICh3aXRoLWN1cnJl bnQtYnVmZmVyIHByb2Nlc3MtYnVmZmVyCiAgICAgIChhZGQtaG9vayAnY29taW50LW91dHB1dC1m aWx0ZXItZnVuY3Rpb25zICdteS1vcmctYmFiZWwtY29taW50LS1hc3luYy1maWx0ZXIpCgogICAg ICAoZ290by1jaGFyIChwcm9jZXNzLW1hcmsgcHJvYykpCiAgICAgIDs7IFRPRE8gbmVlZCBiZXR0 ZXIgYWJzdHJhY3Rpb24KICAgICAgKGluc2VydCAoZm9ybWF0IG9yZy1iYWJlbC1ibHViLW91dHB1 dC1zdGFydC1kZWxpbWl0ZXIgbXktb3JnLWJhYmVsLWNvbWludC0tYXN5bmMtdXVpZCkpCiAgICAg IChjb21pbnQtc2VuZC1pbnB1dCBuaWwgdCkKCiAgICAgIChnb3RvLWNoYXIgKHByb2Nlc3MtbWFy ayBwcm9jKSkKICAgICAgKGluc2VydCAoY2FyIGJvZHkpKQogICAgICAoY29taW50LXNlbmQtaW5w dXQgbmlsIHQpCgogICAgICAoZ290by1jaGFyIChwcm9jZXNzLW1hcmsgcHJvYykpCiAgICAgIDs7 IFRPRE8gbmVlZCBiZXR0ZXIgYWJzdHJhY3Rpb24KICAgICAgKGluc2VydCAoZm9ybWF0IG9yZy1i YWJlbC1ibHViLW91dHB1dC1lbmQtZGVsaW1pdGVyIG15LW9yZy1iYWJlbC1jb21pbnQtLWFzeW5j LXV1aWQpKQogICAgICAoY29taW50LXNlbmQtaW5wdXQgbmlsIHQpKSkKCiAgbXktb3JnLWJhYmVs LWNvbWludC0tYXN5bmMtdXVpZCkKCgwKOzs7IEJsdWI6CihkZWZ2YXIgb3JnLWJhYmVsLWJsdWIt aW50ZXJwcmV0ZXIKICBzaGVsbC1maWxlLW5hbWUgIDsgYmFzaC9zaAogIDs7ICJpcmIiICAgICAg ICAgOyBydWJ5CiAgOzsgInB5dGhvbjMiICAgICA7IHB5dGhvbgogICJCbHViIGludGVycHJldGVy IGNvbW1hbmQgb3IgZXhlY3V0YWJsZS4iKQoKKGRlZnZhciBvcmctYmFiZWwtYmx1Yi1pbnRlcnBy ZXRlci1hcmdzCiAgJygpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgOyBiYXNoCiAgOzsgJygiLS1ub3Byb21wdCIgIi0tbm9yZWFkbGluZSIgIi0tbm9tdWx0 aWxpbmUiKSAgOyBydWJ5CiAgIkJsdWIgaW50ZXJwcmV0ZXIgY29tbWFuZCBvciBleGVjdXRhYmxl IGFyZ3VtZW50cy4iKQoKKGRlZnZhciBvcmctYmFiZWwtYmx1Yi1yZW1vdmUtcHJvbXB0LWNvbW1h bmQKICAiUFJPTVBUX0NPTU1BTkQ9O1BTMT07UFMyPTsiICA7IGJhc2gKICA7OyAiaW1wb3J0IHN5 cztzeXMucHMxPScnO3N5cy5wczI9Jyc7IiAgOyBweXRob24KICAiQ29tbWFuZChzKSB0byByZW1v dmUgaW50ZXJwcmV0ZXIgcHJvbXB0LiIpCgooZGVmdmFyIG9yZy1iYWJlbC1ibHViLW91dHB1dC1z dGFydC1kZWxpbWl0ZXIKICAiZWNobyBcInN0YXJ0XyVzXCIiICAgICAgIDsgYmFzaAogIDs7ICJw dXRzIFwic3RhcnRfJXNcIiIgICAgOyBydWJ5CiAgOzsgInByaW50KFwic3RhcnRfJXNcIikiICA7 IHB5dGhvbgogICJGb3JtYXQgZXhwcmVzc2lvbiBmb3Igd3JpdGluZyB0aGUgc3RhcnQgZGVsaW1p dGVyIHRvIHN0YW5kYXJkCm91dHB1dCBpbiBibHViLiIpCgooZGVmdmFyIG9yZy1iYWJlbC1ibHVi LW91dHB1dC1lbmQtZGVsaW1pdGVyCiAgImVjaG8gXCJlbmRfJXNcIiIgICAgICAgOyBiYXNoCiAg OzsgInB1dHMgXCJlbmRfJXNcIiIgICAgOyBydWJ5CiAgOzsgInByaW50KFwiZW5kXyVzXCIpIiAg OyBweXRob24KICAiRm9ybWF0IGV4cHJlc3Npb24gZm9yIHdyaXRpbmcgdGhlIGVuZCBkZWxpbWl0 ZXIgdG8gc3RhbmRhcmQKb3V0cHV0IGluIGJsdWIuIikKCjs7IHRoaXMgcmVtb3ZlcyB0aGUgbmVl ZCBmb3IgYG9yZy1iYWJlbC1jb21pbnQtYnVmZmVyLWxpdmVwJwooZGVmdW4gb3JnLWJhYmVsLWJs dWItZ2V0LXNlc3Npb24gKHNlc3Npb24pCiAgIlJldHVybiBTRVNTSU9OIGJ1ZmZlciwgbWFraW5n IHByb2Nlc3MgYnVmZmVyIGlmIG5vbmUgZXhpc3RzLiIKICAoY29uZCAoKG5vdCAoZ2V0LWJ1ZmZl ci1wcm9jZXNzIHNlc3Npb24pKQogICAgICAgICAoYXBwbHkKICAgICAgICAgICMnbWFrZS1jb21p bnQtaW4tYnVmZmVyCiAgICAgICAgICBgKCxzZXNzaW9uICAgICAgICAgICAgICAgICAgICAgOyBw cm9jZXNzIG5hbWUKICAgICAgICAgICAgLHNlc3Npb24gICAgICAgICAgICAgICAgICAgICA7IGJ1 ZmZlciBuYW1lCiAgICAgICAgICAgICxvcmctYmFiZWwtYmx1Yi1pbnRlcnByZXRlciAgOyBwcm9n cmFtCiAgICAgICAgICAgIG5pbCAgICAgICAgICAgICAgICAgICAgICAgICAgOyBzdGFydCBmaWxl CiAgICAgICAgICAgICxAb3JnLWJhYmVsLWJsdWItaW50ZXJwcmV0ZXItYXJncykpCiAgICAgICAg IChvcmctYmFiZWwtY29taW50LXdhaXQtZm9yLW91dHB1dCBzZXNzaW9uKQogICAgICAgICAoaWYg b3JnLWJhYmVsLWJsdWItcmVtb3ZlLXByb21wdC1jb21tYW5kCiAgICAgICAgICAgICAobXktb3Jn LWJhYmVsLWNvbWludC1zZW5kLXN0cmluZwogICAgICAgICAgICAgIHNlc3Npb24KICAgICAgICAg ICAgICBvcmctYmFiZWwtYmx1Yi1yZW1vdmUtcHJvbXB0LWNvbW1hbmQpKQoKICAgICAgICAgOzsg TmVlZGVkIGZvciBFbWFjcyAyMyBzaW5jZSB0aGUgbWFya2VyIGlzIGluaXRpYWxseQogICAgICAg ICA7OyB1bmRlZmluZWQgYW5kIHRoZSBmaWx0ZXIgZnVuY3Rpb25zIHRyeSB0byB1c2UgaXQgd2l0 aG91dAogICAgICAgICA7OyBjaGVja2luZy4KICAgICAgICAgKHdpdGgtY3VycmVudC1idWZmZXIg c2Vzc2lvbgogICAgICAgICAgIChzZXQtbWFya2VyIGNvbWludC1sYXN0LW91dHB1dC1zdGFydCAo cG9pbnQpKSkKCiAgICAgICAgIDs7IHJldHVybiBzaGVsbCBidWZmZXIKICAgICAgICAgKGdldC1i dWZmZXIgc2Vzc2lvbikpCiAgICAgICAgKHQgc2Vzc2lvbikpKQoKKGRlZnVuIG9yZy1iYWJlbC1l eGVjdXRlOmJsdWIgKGJvZHkgcGFyYW1zKQogICJFeGVjdXRlIEJPRFkgb2YgQmx1YiBjb2RlIHdp dGggb3JnLWJhYmVsLiIKICAobGV0KiAoKHNlc3Npb24gKGNkciAoYXNzcSA6c2Vzc2lvbiBwYXJh bXMpKSkpCiAgICAoY29uZCAoKGFuZCBzZXNzaW9uCiAgICAgICAgICAgICAgICAobm90IChzdHJp bmc9IHNlc3Npb24gIm5vbmUiKSkKICAgICAgICAgICAgICAgIChvcmctYmFiZWwtYmx1Yi1nZXQt c2Vzc2lvbiBzZXNzaW9uKSkKICAgICAgICAgICAoaWYgKG5vdCBteS1vcmctYmFiZWwtY29taW50 LS1hc3luYy11dWlkKQogICAgICAgICAgICAgICAobXktb3JnLWJhYmVsLWNvbWludC1zZW5kLXRv LXNlc3Npb24tYXN5bmMgc2Vzc2lvbiBib2R5KQogICAgICAgICAgICAgOzsgVE9ETyBwcm9tcHQg dXNlciB0byBqdXN0IGdvIGFoZWFkIHdpdGggaXQgKGNsb2JiZXJpbmcKICAgICAgICAgICAgIDs7 IHRoZSAiZXhpc3RpbmciIHByb2Nlc3MpCiAgICAgICAgICAgICAoZXJyb3IgIkJsb2NrIGFscmVh ZHkgcnVubmluZy4gIENhbGwgYChzZXRxIG15LW9yZy1iYWJlbC1jb21pbnQtLWFzeW5jLXV1aWQg bmlsKScgdG8gcnVuIGEgbmV3IHByb2Nlc3MiKSkpCiAgICAgICAgICAodCAobXktb3JnLWJhYmVs LWV2YWwtYXN5bmMgb3JnLWJhYmVsLWJsdWItaW50ZXJwcmV0ZXIgKG9yZy10cmltIGJvZHkpKSkp KSkKCihwcm92aWRlICdvYi1ibHViKQo7Ozsgb2ItYmx1Yi5lbCBlbmRzIGhlcmUK ------=_Part_4640427_612908003.1708290840203--