Re: xml-parse: file position of elements
Joseph Donaldson <[email protected]> Mon, 14 Feb 2022 17:04:08 +0000 (UTC)
| Newsgroups | gmane.lisp.scheme.bigloo |
|---|---|
| Message-ID | <[email protected]> |
------=_Part_2025032_514358573.1644858248258
Content-Type: multipart/alternative;
boundary="----=_Part_2025031_411431067.1644858248249"
------=_Part_2025031_411431067.1644858248249
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Hello, Sven,
What do you think of changing content-pos to make-content with it being a p=
rocedure for constructing a content object. It will take 2 arguments, the c=
ontent string and the position of the string. The default implementation ju=
st returns the content string, but one can provide his or her own implement=
ation. I also think changing the procedure argument to make-element indicat=
es its purpose better. I have attached a version of xml.scm with these chan=
ges. If providing make-element and make-content is a good idea perhaps we s=
hould also parameterize xml-parse with make-cdata, make-comment, make-decla=
ration, and so on.
Best Regards,Joe Donaldson=20
On Thursday, February 10, 2022, 09:42:43 AM PST, Sven Hartrumpf <hartru=
[email protected]> wrote: =20
=20
Hello Joe.
donaldsonjw, 2022-02-06 01:00:
> Here is another version of xml.scm that I believe addresses the problem y=
ou pointed out. Let me know how it works for you.
Thanks again.
I had to fix two calls of 'make' by moving the position to the end, see att=
ached file,
then everyting worked like a charm.
To finish my problem solution and test it (successfully) on some thousand n=
ontrivial
xml files, I had to add a new option content-pos. If true, content strings =
are turned into
(content-string offset). The changes are backward-compatible because the de=
fault is content-pos #f.
The representation (and the name of the option) might not fit the rest, so =
feel free to change it.
You can open a pull request on bigloo's github soon, I guess.
Greetings
Sven
;*=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D*/
;*=C2=A0 =C2=A0 serrano/prgm/project/bigloo/bigloo/api/web/src/Llib/xml.scm=
=C2=A0 =C2=A0 =C2=A0 */
;*=C2=A0 =C2=A0 -----------------------------------------------------------=
--=C2=A0 =C2=A0 */
;*=C2=A0 =C2=A0 Author=C2=A0 =C2=A0 =C2=A0 :=C2=A0 Manuel Serrano=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 */
;*=C2=A0 =C2=A0 Creation=C2=A0 =C2=A0 :=C2=A0 Fri Mar 11 16:23:53 2005=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 */
;*=C2=A0 =C2=A0 Last change :=C2=A0 Sun Oct=C2=A0 7 08:46:03 2018 (serrano)=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 */
;*=C2=A0 =C2=A0 Copyright=C2=A0 :=C2=A0 2005-18 Manuel Serrano=C2=A0 =C2=A0=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 */
;*=C2=A0 =C2=A0 -----------------------------------------------------------=
--=C2=A0 =C2=A0 */
;*=C2=A0 =C2=A0 XML parsing=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 */
;*=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D*/
;*---------------------------------------------------------------------*/
;*=C2=A0 =C2=A0 The module=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 */
;*---------------------------------------------------------------------*/
(module __web_xml
=C2=A0 (option (set! *dlopen-init-gc* #t))
=C2=A0 (export (xml-parse::pair-nil port::input-port
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=
#!key
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=
(content-length 0)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=
(procedure (lambda (tag attribs body start-pos)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 (list tag attribs body)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=
(specials '())
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=
(strict #t)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (content-pos #f)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=
(encoding 'UTF-8)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=
(eoi #f))
=C2=A0=C2=A0=C2=A0 =C2=A0 (xml-string-decode::bstring ::bstring)
=C2=A0=C2=A0=C2=A0 =C2=A0 (xml-string-decode!::bstring ::bstring)
=C2=A0=C2=A0=C2=A0 =C2=A0 (xml-string-encode::bstring ::bstring)
=C2=A0=C2=A0=C2=A0 =C2=A0 (read-xml #!optional (port::input-port (current-i=
nput-port)))
=C2=A0=C2=A0=C2=A0 =C2=A0 (xml-metadata xml-tree::pair-nil)))
;*---------------------------------------------------------------------*/
;*=C2=A0 =C2=A0 xml-parse ...=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 */
;*---------------------------------------------------------------------*/
(define (xml-parse::pair-nil port::input-port
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 #!ke=
y
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (con=
tent-length 0)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (pro=
cedure (lambda (tag attribs body start-pos)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (=
list tag attribs body)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 (specials '())
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (str=
ict #t)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 (content-pos #f)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (enc=
oding 'UTF-8)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (eoi=
#f))
=C2=A0 (when (elong? content-length)
=C2=A0 =C2=A0 =C2=A0 (set! content-length (elong->fixnum content-length)))
=C2=A0 (when (and (fixnum? content-length) (>fx content-length 0))
=C2=A0 =C2=A0 =C2=A0 (input-port-fill-barrier-set! port content-length))
=C2=A0 (when (>fx content-length 0)
=C2=A0 =C2=A0 =C2=A0 (set! content-length (+fx content-length (input-port-p=
osition port))))
=C2=A0 (let loop ((decoder (lambda (x) x)))
=C2=A0 =C2=A0 =C2=A0 (let ((obj (read/rp xml-grammar port procedure procedu=
re specials strict content-pos decoder encoding (input-port-position port))=
))
=C2=A0=C2=A0=C2=A0 (when (and (fixnum? content-length) (>fx content-length =
0))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (input-port-fill-barrier-set! port -1))
=C2=A0=C2=A0=C2=A0 (cond
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 ((eof-object? obj)
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 '())
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 ((or (and (procedure? eoi) (eoi obj))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 (and (>fx content-length 0)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (>=3Dfx (input-p=
ort-position port) content-length)))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (list obj))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 ((and (pair? obj) (eq? 'xml-decl (car obj)=
))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (let ((enc (assq 'encoding (cdr obj))))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 (if enc
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (cons obj (loop (get-de=
coder (cdr enc) encoding)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (cons obj (loop decoder=
)))))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (else
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (cons obj (loop decoder)))))))
;*---------------------------------------------------------------------*/
;*=C2=A0 =C2=A0 xml-parse-error ...=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 */
;*---------------------------------------------------------------------*/
(define (xml-parse-error msg obj name pos)
=C2=A0 (raise
=C2=A0 =C2=A0 (instantiate::&io-parse-error
=C2=A0 =C2=A0 =C2=A0 (proc 'xml-parse)
=C2=A0 =C2=A0 =C2=A0 (msg msg)
=C2=A0 =C2=A0 =C2=A0 (obj obj)
=C2=A0 =C2=A0 =C2=A0 (fname name)
=C2=A0 =C2=A0 =C2=A0 (location pos))))
;*---------------------------------------------------------------------*/
;*=C2=A0 =C2=A0 error-line ...=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 */
;*---------------------------------------------------------------------*/
(define (error-line c port)
=C2=A0 (let ((line (read-line port)))
=C2=A0 =C2=A0 =C2=A0 (string-append "{" (string c) "}" (if (string? line) l=
ine ""))))
;*---------------------------------------------------------------------*/
;*=C2=A0 =C2=A0 special ...=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 */
;*---------------------------------------------------------------------*/
(define-struct special tag attributes body owner)
;*---------------------------------------------------------------------*/
;*=C2=A0 =C2=A0 collect-up-to ...=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 */
;*---------------------------------------------------------------------*/
(define (collect-up-to start-pos ignore tag attributes port make specials s=
trict content-pos decoder encoding)
=C2=A0 (define (collect ignore tags)
=C2=A0 =C2=A0 =C2=A0 (let ((name (input-port-name port))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (po (input-port-position port)))
=C2=A0=C2=A0=C2=A0 (let loop ((acc '())
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (item (ignore)))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (cond
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 ((symbol? item)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 (cond
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 ((eq? item tag)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (make tag attributes (r=
everse! acc) start-pos))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (strict
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (xml-parse-error "Illeg=
al closing tag"
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (format "`~a' ex=
pected, `~a' provided"
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 tag item)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 name po))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (else
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (make tag attributes (r=
everse! acc) start-pos))))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 ((special? item)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 (let ((nitem (make (special-tag item)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=
(special-attributes item)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=
(special-body item)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 start-pos)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (if (memq (special-tag item) t=
ags)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (loop acc nitem)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (list (make tag =
attributes (reverse! acc) start-pos) nitem))))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 ((eof-object? item)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 (if strict
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (xml-parse-error
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (format "Prematu=
re end of line, expecting tag `~a'"
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 tag)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 item name po)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (make tag attributes (r=
everse! acc) start-pos)))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (else
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 (let ((po (input-port-last-token-posi=
tion port)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (loop (econs item acc (list 'a=
t name po)) (ignore))))))))
=C2=A0 (let ((spec (assq tag specials)))
=C2=A0 =C2=A0 =C2=A0 (cond
=C2=A0=C2=A0=C2=A0 ((not spec)
=C2=A0=C2=A0=C2=A0 =C2=A0 (collect ignore '()))
=C2=A0=C2=A0=C2=A0 ((null? (cdr spec))
=C2=A0=C2=A0=C2=A0 =C2=A0 (make tag attributes '() start-pos))
=C2=A0=C2=A0=C2=A0 ((procedure? (cdr spec))
=C2=A0=C2=A0=C2=A0 =C2=A0 (make tag attributes ((cdr spec) port) start-pos)=
)
=C2=A0=C2=A0=C2=A0 ((pair? (cdr spec))
=C2=A0=C2=A0=C2=A0 =C2=A0 (let ((ignore (lambda ()
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (read/rp xm=
l-grammar port
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=
=C2=A0 =C2=A0 (lambda (t a b) (special t a b tag))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=
=C2=A0 =C2=A0 make
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=
=C2=A0 =C2=A0 specials strict content-pos decoder encoding (input-port-pos=
ition port)))))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (collect ignore (cdr spec))))
=C2=A0=C2=A0=C2=A0 (else
=C2=A0=C2=A0=C2=A0 =C2=A0 (error "xml-parse" "Illegal special handler" spec=
)))))
;*---------------------------------------------------------------------*/
;*=C2=A0 =C2=A0 attribute-value-grammar ...=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 */
;*---------------------------------------------------------------------*/
(define attribute-value-grammar
=C2=A0 (regular-grammar (strict tag)
=C2=A0 =C2=A0 =C2=A0 ((+ (in " \t\n\r"))
=C2=A0 =C2=A0 =C2=A0 (ignore))
=C2=A0 =C2=A0 =C2=A0 ((: #\" (* (or (out #\\ #\") (: #\\ all))) #\")
=C2=A0 =C2=A0 =C2=A0 (the-substring 1 (-fx (the-length) 1)))
=C2=A0 =C2=A0 =C2=A0 ((: #\' (* (or (out #\\ #\') (: #\\ all))) #\')
=C2=A0 =C2=A0 =C2=A0 (the-substring 1 (-fx (the-length) 1)))
=C2=A0 =C2=A0 =C2=A0 ((: (+ digit) (? (or "%" "px" "cm" "em" "mm" "inch")))
=C2=A0 =C2=A0 =C2=A0 (if strict
=C2=A0=C2=A0=C2=A0 =C2=A0 (xml-parse-error (format "Illegal `~a' attribute =
value" tag)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (the=
-string)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (inp=
ut-port-name (the-port))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (inp=
ut-port-position (the-port)))
=C2=A0=C2=A0=C2=A0 =C2=A0 (the-string)))
=C2=A0 =C2=A0 =C2=A0 ((+ (out " \t\n\r<>(){}[]@!\"'/"))
=C2=A0 =C2=A0 =C2=A0 (if strict
=C2=A0=C2=A0=C2=A0 =C2=A0 (xml-parse-error (format "Illegal `~a' attribute =
character" tag)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (the=
-string)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (inp=
ut-port-name (the-port))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (inp=
ut-port-position (the-port)))
=C2=A0=C2=A0=C2=A0 =C2=A0 (the-string)))
=C2=A0 =C2=A0 =C2=A0 (else
=C2=A0 =C2=A0 =C2=A0 (let ((c (the-failure)))
=C2=A0=C2=A0=C2=A0 =C2=A0 (if (not (eof-object? c))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (if (or strict
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (not (or (char=
=3D? c #\space)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 (char=3D? c #\Newline)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 (char=3D? c #\>))))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (xml-parse-error
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (format "Illegal `~a' attribut=
e character" tag)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (error-line c (the-port))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (input-port-name (the-port))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (input-port-position (the-port=
)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 " ")
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (xml-parse-error
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (format "Premature end of line for =
tag `~a' attribute" tag)
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 c
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (input-port-name (the-port))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (-fx (input-port-position (the-port=
)) 1)))))))
;*---------------------------------------------------------------------*/
;*=C2=A0 =C2=A0 attribute-grammar ...=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 */
;*---------------------------------------------------------------------*/
(define attribute-grammar
=C2=A0 (regular-grammar ((id (: (in ("azAZ") "_") (* (in ("azAZ09") ":_-"))=
))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 tag
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 strict
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 decoder)
=C2=A0 =C2=A0 =C2=A0 ((+ (in " \t\n\r"))
=C2=A0 =C2=A0 =C2=A0 (ignore))
=C2=A0 =C2=A0 =C2=A0 ((: id "=3D")
=C2=A0 =C2=A0 =C2=A0 (let* ((key (the-substring 0 (-fx (the-length) 1)))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (val (read/rp attribute-value-gramm=
ar (the-port) strict tag)))
=C2=A0=C2=A0=C2=A0 =C2=A0 (cons (string->symbol (decoder key)) (decoder val=
))))
=C2=A0 =C2=A0 =C2=A0 ((: id (+ blank) "=3D")
=C2=A0 =C2=A0 =C2=A0 (let* ((key (the-substring 0 (-fx (the-length) 2)))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (val (read/rp attribute-value-gramm=
ar (the-port) strict tag)))
=C2=A0=C2=A0=C2=A0 =C2=A0 (let loop ((i (-fx (string-length key) 1)))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (case (string-ref key i)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 ((#\space #\tab #\Newline)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 (loop (-fx i 1)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 (else
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 (set! key (substring key 0 (+ i 1))))=
))
=C2=A0=C2=A0=C2=A0 =C2=A0 (cons (string->symbol (decoder key)) (decoder val=
))))
=C2=A0 =C2=A0 =C2=A0 ((: id)
=C2=A0 =C2=A0 =C2=A0 (let* ((key (decoder (the-string))))
=C2=A0=C2=A0=C2=A0 =C2=A0 (cons (string->symbol key) key)))
=C2=A0 =C2=A0 =C2=A0 ((or "/>" ">")
=C2=A0 =C2=A0 =C2=A0 (the-symbol))
=C2=A0 =C2=A0 =C2=A0 (else
=C2=A0 =C2=A0 =C2=A0 (let ((c (the-failure)))
=C2=A0=C2=A0=C2=A0 =C2=A0 (if (not (eof-object? c))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (xml-parse-error "Illegal attribute=
character"
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 (error-line c (the-port))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 (input-port-name (the-port))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 (input-port-position (the-port)))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (xml-parse-error
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (format "Premature end of line, exp=
ecting tag `~a'" tag)
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 c
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (input-port-name (the-port))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (-fx (input-port-position (the-port=
)) 1)))))))
;*---------------------------------------------------------------------*/
;*=C2=A0 =C2=A0 cdata-grammar ...=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 */
;*---------------------------------------------------------------------*/
(define cdata-grammar
=C2=A0 (regular-grammar (decoder)
=C2=A0 =C2=A0 =C2=A0 ((* (out "]"))
=C2=A0 =C2=A0 =C2=A0 (let* ((res (decoder (the-string)))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (rest (ignore)))
=C2=A0=C2=A0=C2=A0 =C2=A0 (string-append res rest)))
=C2=A0 =C2=A0 =C2=A0 ("]"
=C2=A0 =C2=A0 =C2=A0 (string-append "]" (ignore)))
=C2=A0 =C2=A0 =C2=A0 ((: "]]>" (? "\n"))
=C2=A0 =C2=A0 =C2=A0 "")
=C2=A0 =C2=A0 =C2=A0 (else
=C2=A0 =C2=A0 =C2=A0 (let* ((c (the-failure))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (msg (if (not (eof-object? c))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 "Illegal <![CDAT=
A[ character"
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 "Premature end o=
f line, expecting tag `]]>'")))
=C2=A0=C2=A0=C2=A0 =C2=A0 (xml-parse-error msg
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 c
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (input-port=
-name (the-port))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (input-port=
-position (the-port)))))))
;*---------------------------------------------------------------------*/
;*=C2=A0 =C2=A0 get-decoder ...=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 */
;*---------------------------------------------------------------------*/
(define (get-decoder::procedure enc::bstring dst-enc)
=C2=A0 (let ((src-enc (string->symbol (string-upcase enc))))
=C2=A0 =C2=A0 =C2=A0 (cond
=C2=A0=C2=A0=C2=A0 ((or (not src-enc) (eq? src-enc dst-enc))
=C2=A0=C2=A0=C2=A0 =C2=A0 (lambda (x) x))
=C2=A0=C2=A0=C2=A0 ((eq? src-enc 'UTF-8)
=C2=A0=C2=A0=C2=A0 =C2=A0 (cond
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 ((memq dst-enc '(ISO-8859-1 ISO-8859-2 ISO=
-8859-15))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 utf8->iso-latin)
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 ((eq? dst-enc 'UCS-2)
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 utf8-string->ucs2-string)
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (else
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (lambda (x) x))))
=C2=A0=C2=A0=C2=A0 ((memq src-enc '(ISO-8859-1 ISO-8859-2 ISO-8859-15))
=C2=A0=C2=A0=C2=A0 =C2=A0 (cond
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 ((eq? dst-enc 'UTF-8)
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 iso-latin->utf8)
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 ((eq? dst-enc 'UCS-2)
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (lambda (x)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 (utf8-string->ucs2-string (iso-latin-=
>utf8 x))))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (else
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (lambda (x) x))))
=C2=A0=C2=A0=C2=A0 (else
=C2=A0=C2=A0=C2=A0 =C2=A0 (lambda (x) x)))))
;*---------------------------------------------------------------------*/
;*=C2=A0 =C2=A0 xml-grammar ...=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 */
;*---------------------------------------------------------------------*/
(define xml-grammar
=C2=A0 (regular-grammar ((id (: (in ("azAZ") "!?") (* (in ("azAZ09") ":_-")=
)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 next
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 make
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 specials
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 strict
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 conte=
nt-pos
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 decoder
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 encoding
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 pos)
=C2=A0 =C2=A0 =C2=A0 (define (update-start-position!)
=C2=A0 =C2=A0 =C2=A0 (set! pos (input-port-position (the-port))))
=C2=A0 =C2=A0 =C2=A0 (define (ignore-w/-pos-update!)
=C2=A0 =C2=A0 =C2=A0 (update-start-position!)
=C2=A0 =C2=A0 =C2=A0 (ignore))
=C2=A0 =C2=A0 =C2=A0 ((+ (in " \t\n\r"))
=C2=A0 =C2=A0 =C2=A0 (update-start-position!)
=C2=A0 =C2=A0 =C2=A0 (if content-pos
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (list (the-string) (- pos (the-length)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (the-string)))
=C2=A0 =C2=A0 =C2=A0 ((: "<!--"
=C2=A0=C2=A0=C2=A0 =C2=A0 (* (or (out "-") (: "-" (out "-")) (: "--" (out "=
>"))))
=C2=A0=C2=A0=C2=A0 =C2=A0 "-->")
=C2=A0 =C2=A0 =C2=A0 (update-start-position!)
=C2=A0 =C2=A0 =C2=A0 (cons 'comment (the-string)))
=C2=A0 =C2=A0 =C2=A0 ((: "<!" (: (or (out "[-") (: "-" (out "-")))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (* (out ">]"))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (? (: "[" (* (out "]")) "]"))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (* (out ">"))) ">")
=C2=A0 =C2=A0 =C2=A0 (update-start-position!)
=C2=A0 =C2=A0 =C2=A0 (cons 'declaration (the-string)))
=C2=A0 =C2=A0 =C2=A0 ("<![CDATA["
=C2=A0 =C2=A0 =C2=A0 (let ((cdata (read/rp cdata-grammar (the-port) decoder=
)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (update-start-position!)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (cons 'cdata cdata)))
=C2=A0 =C2=A0 =C2=A0 ((: "<?xml " (* (out "?>")) "?>")
=C2=A0 =C2=A0 =C2=A0 (let ((s (the-substring 6 (the-length))))
=C2=A0=C2=A0=C2=A0 =C2=A0 (string-set! s (-fx (string-length s) 2) #\space)
=C2=A0=C2=A0=C2=A0 =C2=A0 (let ((p (open-input-string s)))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (let loop ((attr '()))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 (let ((obj (read/rp attribute-grammar=
p 'xml #t decoder)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (cond
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 ((pair? obj)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (loop (cons obj =
attr)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 ((eq? obj '>)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 (update-start-position!)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (cons 'xml-decl =
attr))))))))
=C2=A0 =C2=A0 =C2=A0 ((: "<?" (* (out ">")) ">")
=C2=A0 =C2=A0 =C2=A0 (update-start-position!)
=C2=A0 =C2=A0 =C2=A0 (cons 'instruction (the-string)))
=C2=A0 =C2=A0 =C2=A0 ((: "<" id ">")
=C2=A0 =C2=A0 =C2=A0 (let* ((t (the-substring 1 (-fx (the-length) 1)))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (ts (string->symbol t))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (p (the-port)))
=C2=A0=C2=A0=C2=A0 =C2=A0 (let ((element (collect-up-to pos ignore-w/-pos-u=
pdate! ts '() p make specials strict content-pos decoder encoding)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (update-start-position!)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 element)))
=C2=A0 =C2=A0 =C2=A0 ((: "<" id "/>")
=C2=A0 =C2=A0 =C2=A0 (let ((t (the-substring 1 (-fx (the-length) 2))))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (let ((p pos))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (update-start-position!)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (make (string->symbol t) '() '() =
p))))
=C2=A0 =C2=A0 =C2=A0 ((: "<" id (in " \n\t\r"))
=C2=A0 =C2=A0 =C2=A0 (let* ((t (the-substring 1 (-fx (the-length) 1)))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (ts (string->symbol t))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (p (the-port)))
=C2=A0=C2=A0=C2=A0 =C2=A0 (let loop ((attr '()))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (let ((obj (read/rp attribute-grammar p t =
strict decoder)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 (cond
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 ((pair? obj)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (loop (cons obj attr)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 ((eq? obj '>)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (let ((element (collect=
-up-to pos ignore-w/-pos-update! ts (reverse! attr) p make specials strict =
content-pos decoder encoding)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 (update-start-position!)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 element))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 ((eq? obj '/>)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (let =
((p pos))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 (update-start-position!)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 (make ts (reverse! attr) '() p))))))))
=C2=A0 =C2=A0 =C2=A0 ((: "</" id ">")
=C2=A0 =C2=A0 =C2=A0 (update-start-position!)
=C2=A0 =C2=A0 =C2=A0 (string->symbol (the-substring 2 (-fx (the-length) 1))=
))
=C2=A0 =C2=A0 =C2=A0 ((+ (out "<"))
=C2=A0 =C2=A0 =C2=A0 (update-start-position!)
=C2=A0 =C2=A0 =C2=A0 (if content-pos
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (let ((pos2 (- pos (the-length))))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (list (decoder (the-string)) pos2=
))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (decoder (the-string))))
=C2=A0 =C2=A0 =C2=A0 (else
=C2=A0 =C2=A0 =C2=A0 (let ((c (the-failure)))
=C2=A0=C2=A0=C2=A0 =C2=A0 (cond
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 ((not (eof-object? c))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (xml-parse-error "Illegal character=
"
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 (error-line c (the-port))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 (input-port-name (the-port))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 (input-port-position (the-port))))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (else
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 c))))))
;*---------------------------------------------------------------------*/
;*=C2=A0 =C2=A0 char-hexnumeric? ...=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 */
;*---------------------------------------------------------------------*/
(define (char-hexnumeric? c)
=C2=A0 (or (char-numeric? c)
=C2=A0 =C2=A0 =C2=A0 (and (char>=3D? c #\A) (char<=3D? c #\F))
=C2=A0 =C2=A0 =C2=A0 (and (char>=3D? c #\a) (char<=3D? c #\f))))
;*---------------------------------------------------------------------*/
;*=C2=A0 =C2=A0 xml-string-decode-inner! ...=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 */
;*---------------------------------------------------------------------*/
(define (xml-string-decode-inner! str ol nl res)
=C2=A0 (define (char-value c)
=C2=A0 =C2=A0 =C2=A0 (cond
=C2=A0=C2=A0=C2=A0 ((char-numeric? c)
=C2=A0=C2=A0=C2=A0 =C2=A0 (-fx (char->integer c) (char->integer #\0)))
=C2=A0=C2=A0=C2=A0 ((char<=3D? c #\F)
=C2=A0=C2=A0=C2=A0 =C2=A0 (+fx 10 (-fx (char->integer c) (char->integer #\A=
))))
=C2=A0=C2=A0=C2=A0 (else
=C2=A0=C2=A0=C2=A0 =C2=A0 (+fx 10 (-fx (char->integer c) (char->integer #\a=
))))))
=C2=A0 (let ((ol-2 (-fx ol 2)))
=C2=A0 =C2=A0 =C2=A0 (let loop ((i 0)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 (j 0))
=C2=A0=C2=A0=C2=A0 (if (=3Dfx j nl)
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 res
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (let ((c (string-ref str i)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 (if (and (char=3D? c #\%) (<fx i ol-2=
))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (let ((c1 (string-ref s=
tr (+fx i 1)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (c2 (string=
-ref str (+fx i 2))))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (if (and (char-h=
exnumeric? c1) (char-hexnumeric? c2))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (let* ((v1 =
(char-value c1))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=
=C2=A0 (v2 (char-value c2))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=
=C2=A0 (d (integer->char (+fx (*fx v1 16) v2))))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 (string-set! res j d)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 (loop (+fx i 3) (+fx j 1)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (begin
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 (string-set! res j c)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 (loop (+fx i 1) (+fx j 1)))))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (begin
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (string-set! res=
j c)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (loop (+fx i 1) =
(+fx j 1)))))))))
;*---------------------------------------------------------------------*/
;*=C2=A0 =C2=A0 xml-count ...=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 */
;*---------------------------------------------------------------------*/
(define (xml-count str ol)
=C2=A0 (let loop ((i 0)
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (c 0))
=C2=A0 =C2=A0 =C2=A0 (cond
=C2=A0=C2=A0=C2=A0 ((=3Dfx i ol)
=C2=A0=C2=A0=C2=A0 =C2=A0 c)
=C2=A0=C2=A0=C2=A0 ((char=3D? (string-ref str i) #\&)
=C2=A0=C2=A0=C2=A0 =C2=A0 (cond
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 ((substring-at? str "<" i)
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (loop (+fx i 4) (+fx c 1)))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 ((substring-at? str ">" i)
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (loop (+fx i 4) (+fx c 1)))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 ((substring-at? str "&" i)
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (loop (+fx i 5) (+fx c 1)))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 ((substring-at? str """ i)
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (loop (+fx i 6) (+fx c 1)))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 ((substring-at? str " " i)
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (loop (+fx i 6) (+fx c 1)))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 ((substring-at? str "&#" i)
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (let liip ((i (+fx i 2)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 (cond
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 ((=3Dfx i ol)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 c)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 ((char-numeric? (string=
-ref str i))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (liip (+fx i 1)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (else
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (loop (+fx i 1) (+fx c =
1))))))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (else
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (loop (+fx i 1) (+fx c 1)))))
=C2=A0=C2=A0=C2=A0 (else
=C2=A0=C2=A0=C2=A0 =C2=A0 (loop (+fx i 1) (+fx c 1))))))
;*---------------------------------------------------------------------*/
;*=C2=A0 =C2=A0 xml-decode ...=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 */
;*---------------------------------------------------------------------*/
(define (xml-decode! str res ol nl)
=C2=A0 (let loop ((i 0)
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (j 0))
=C2=A0 =C2=A0 =C2=A0 (cond
=C2=A0=C2=A0=C2=A0 ((=3Dfx i ol)
=C2=A0=C2=A0=C2=A0 =C2=A0 res)
=C2=A0=C2=A0=C2=A0 ((char=3D? (string-ref str i) #\&)
=C2=A0=C2=A0=C2=A0 =C2=A0 (cond
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 ((substring-at? str "<" i)
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (string-set! res j #\<)
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (loop (+fx i 4) (+fx j 1)))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 ((substring-at? str ">" i)
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (string-set! res j #\>)
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (loop (+fx i 4) (+fx j 1)))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 ((substring-at? str "&" i)
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (string-set! res j #\&)
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (loop (+fx i 5) (+fx j 1)))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 ((substring-at? str """ i)
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (string-set! res j #\")
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (loop (+fx i 6) (+fx j 1)))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 ((substring-at? str " " i)
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (string-set! res j #\space)
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (loop (+fx i 6) (+fx j 1)))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 ((substring-at? str "&#" i)
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (let liip ((i (+fx i 2))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 (n 0))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 (if (=3Dfx i ol)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 res
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (let ((c (string-ref st=
r i)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 (if (char-numeric?=
c)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (lii=
p (+fx i 1)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 (+fx (*fx n 10)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=
=C2=A0 (-fx (char->integer c)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=
=C2=A0 =C2=A0 (char->integer #\0))))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (beg=
in
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 (string-set! res j (integer->char n))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 (loop (+fx i 1) (+fx j 1))))))))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (else
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (string-set! res j (string-ref str =
i))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (loop (+fx i 1) (+fx j 1)))))
=C2=A0=C2=A0=C2=A0 (else
=C2=A0=C2=A0=C2=A0 =C2=A0 (string-set! res j (string-ref str i))
=C2=A0=C2=A0=C2=A0 =C2=A0 (loop (+fx i 1) (+fx j 1))))))
;*---------------------------------------------------------------------*/
;*=C2=A0 =C2=A0 xml-string-decode ...=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 */
;*---------------------------------------------------------------------*/
(define (xml-string-decode str)
=C2=A0 (let ((ol (string-length str)))
=C2=A0 =C2=A0 =C2=A0 (if (>=3Dfx ol 3)
=C2=A0=C2=A0=C2=A0 =C2=A0 (let ((nl (xml-count str ol)))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (if (=3Dfx nl ol)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 (string-copy str)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 (let ((res (make-string nl)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (xml-decode! str res ol=
nl)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 res)))
=C2=A0=C2=A0=C2=A0 =C2=A0 (string-copy str))))
;*---------------------------------------------------------------------*/
;*=C2=A0 =C2=A0 xml-string-decode! ...=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 */
;*---------------------------------------------------------------------*/
(define (xml-string-decode! str)
=C2=A0 (let ((ol (string-length str)))
=C2=A0 =C2=A0 =C2=A0 (if (>=3Dfx ol 3)
=C2=A0=C2=A0=C2=A0 =C2=A0 (let ((nl (xml-count str ol)))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (if (=3Dfx nl ol)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 str
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 (begin
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (xml-decode! str str ol=
nl)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (string-shrink! str nl)=
)))
=C2=A0=C2=A0=C2=A0 =C2=A0 str)))
;*---------------------------------------------------------------------*/
;*=C2=A0 =C2=A0 xml-string-encode ...=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 */
;*---------------------------------------------------------------------*/
(define (xml-string-encode str)
=C2=A0 (define (count str ol)
=C2=A0 =C2=A0 =C2=A0 (let loop ((i 0)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 (n 0))
=C2=A0=C2=A0=C2=A0 (if (=3Dfx i ol)
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 n
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (let ((c (string-ref str i)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 (case c
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 ((#\")
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (loop (+fx i 1) (+fx n =
6)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 ((#\&)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (loop (+fx i 1) (+fx n =
5)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 ((#\< #\>)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (loop (+fx i 1) (+fx n =
4)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (else
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (loop (+fx i 1) (+fx n =
1))))))))
=C2=A0 (define (encode str ol nl)
=C2=A0 =C2=A0 =C2=A0 (if (=3Dfx nl ol)
=C2=A0=C2=A0=C2=A0 =C2=A0 str
=C2=A0=C2=A0=C2=A0 =C2=A0 (let ((res (make-string nl)))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (let loop ((i 0)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 (j 0))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 (if (=3Dfx j nl)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 res
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (let ((c (string-ref st=
r i)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (case c
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 ((#\<)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (blit-strin=
g! "<" 0 res j 4)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (loop (+fx =
i 1) (+fx j 4)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 ((#\>)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (blit-strin=
g! ">" 0 res j 4)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (loop (+fx =
i 1) (+fx j 4)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 ((#\&)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (blit-strin=
g! "&" 0 res j 5)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (loop (+fx =
i 1) (+fx j 5)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 ((#\")
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (blit-strin=
g! """ 0 res j 6)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (loop (+fx =
i 1) (+fx j 6)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (else
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (string-set=
! res j c)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (loop (+fx =
i 1) (+fx j 1))))))))))
=C2=A0 (let ((ol (string-length str)))
=C2=A0 =C2=A0 =C2=A0 (encode str ol (count str ol))))
;*---------------------------------------------------------------------*/
;*=C2=A0 =C2=A0 read-xml ...=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 */
;*---------------------------------------------------------------------*/
(define (read-xml #!optional (port::input-port (current-input-port)))
=C2=A0 (xml-parse port))
;*---------------------------------------------------------------------*/
;*=C2=A0 =C2=A0 xml-metadata ...=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 */
;*---------------------------------------------------------------------*/
(define (xml-metadata xml)
=C2=A0 (let ((xml-ver #f)
=C2=A0=C2=A0=C2=A0 (xml-enc #f)
=C2=A0=C2=A0=C2=A0 (xml-lang #f)
=C2=A0=C2=A0=C2=A0 (root-ver 0.0)
=C2=A0=C2=A0=C2=A0 (xml-root #f)
=C2=A0=C2=A0=C2=A0 (xml-ns '()))
=C2=A0 =C2=A0 =C2=A0 (let loop1 ((l xml))
=C2=A0=C2=A0=C2=A0 (when (pair? l)
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (match-case (car l)
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 ((xml-decl . (and ?attr (?- . ?-)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 (for-each (lambda (at)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (cas=
e (car at)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=
((version) (set! xml-ver (cdr attr)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=
((encoding) (set! xml-enc (cdr attr)))))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 attr))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 ((?mark ?lattr . ?-)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 (let loop3 ((lattr lattr))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (unless xml-root (set! xml-roo=
t mark))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 (when (pair? lattr)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 (let ((attr (car=
lattr)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 (case (car attr)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 ((xm=
l:lang)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (set=
! xml-lang (cdr attr)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 ((xm=
lns)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (set=
! xml-root (cons (cdr attr) xml-root)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 ((ve=
rsion)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (set=
! root-ver (string->number (cdr attr))))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (els=
e
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (let=
((str (symbol->string (car attr))))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=
(when (substring=3D? str "xmlns:" 6)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=
=C2=A0 (let* ((l (string-length str))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 =C2=A0 (s (substring str 6 l))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 =C2=A0 (si (string->symbol s)))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=
=C2=A0 =C2=A0 =C2=A0 (set! xml-ns
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (cons (cons (cdr attr) si)
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 xml-ns)))))))
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 (loop3 (cdr lattr)=
))))))
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 (loop1 (cdr l))))
=C2=A0 =C2=A0 =C2=A0 (unless xml-root
=C2=A0=C2=A0=C2=A0 (error "xml-metadata" "Empty XML document !" xml))
=C2=A0 =C2=A0 =C2=A0 ;; Values are :
=C2=A0 =C2=A0 =C2=A0 ;; - XML Version (1.0 or 1.1) or #f
=C2=A0 =C2=A0 =C2=A0 ;; - XML Encoding (#f if unknown)
=C2=A0 =C2=A0 =C2=A0 ;; - xml:lang value
=C2=A0 =C2=A0 =C2=A0 ;; - Pair, which car is the first data markup, and
=C2=A0 =C2=A0 =C2=A0 ;;=C2=A0 cdr the default namespace
=C2=A0 =C2=A0 =C2=A0 ;; - xml first data markup version attribute (0 if uns=
pecified)
=C2=A0 =C2=A0 =C2=A0 ;; - list of prefixed namespaces (prefix . path)
=C2=A0 =C2=A0 =C2=A0 (values xml-ver xml-enc xml-lang xml-root root-ver xml=
-ns)))
=20
------=_Part_2025031_411431067.1644858248249
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html><head></head><body><div class=3D"ydp7410d2d2yahoo-style-wrap" style=
=3D"font-family:Helvetica Neue, Helvetica, Arial, sans-serif;font-size:13px=
;"><div></div>
<div dir=3D"ltr" data-setdir=3D"false">Hello, Sven,</div><div dir=
=3D"ltr" data-setdir=3D"false"><br></div><div dir=3D"ltr" data-setdir=3D"fa=
lse">What do you think of changing content-pos to make-content with it bein=
g a procedure for constructing a content object. It will take 2 arguments, =
the content string and the position of the string. The default implementati=
on just returns the content string, but one can provide his or her own impl=
ementation. I also think changing the procedure argument to make-element in=
dicates its purpose better. I have attached a version of xml.scm with these=
changes. If providing make-element and make-content is a good idea perhaps=
we should also parameterize xml-parse with make-cdata, make-comment, make-=
declaration, and so on.</div><div dir=3D"ltr" data-setdir=3D"false"><br></d=
iv><div dir=3D"ltr" data-setdir=3D"false">Best Regards,</div><div dir=3D"lt=
r" data-setdir=3D"false">Joe Donaldson <br></div><div><br></div>
=20
</div><div id=3D"ydpfc4bbcfayahoo_quoted_5777540182" class=3D"ydpfc=
4bbcfayahoo_quoted">
<div style=3D"font-family:'Helvetica Neue', Helvetica, Arial, s=
ans-serif;font-size:13px;color:#26282a;">
=20
<div>
On Thursday, February 10, 2022, 09:42:43 AM PST, Sven H=
artrumpf <[email protected]> wrote:
</div>
<div><br></div>
<div><br></div>
<div><div dir=3D"ltr">Hello Joe.<br clear=3D"none"><br clea=
r=3D"none">donaldsonjw, 2022-02-06 01:00:<br clear=3D"none">> Here is an=
other version of xml.scm that I believe addresses the problem you pointed o=
ut. Let me know how it works for you.<br clear=3D"none"><br clear=3D"none">=
Thanks again.<br clear=3D"none">I had to fix two calls of 'make' by moving =
the position to the end, see attached file,<br clear=3D"none">then everytin=
g worked like a charm.<br clear=3D"none"><br clear=3D"none">To finish my pr=
oblem solution and test it (successfully) on some thousand nontrivial<br cl=
ear=3D"none">xml files, I had to add a new option content-pos. If true, con=
tent strings are turned into<br clear=3D"none">(content-string offset). The=
changes are backward-compatible because the default is content-pos #f.<br =
clear=3D"none">The representation (and the name of the option) might not fi=
t the rest, so feel free to change it.<br clear=3D"none"><br clear=3D"none"=
>You can open a pull request on bigloo's github soon, I guess.<br clear=3D"=
none"><br clear=3D"none">Greetings<div class=3D"ydpfc4bbcfayqt2717482403" i=
d=3D"ydpfc4bbcfayqtfd06520"><br clear=3D"none">Sven<br clear=3D"none"></div=
></div>;*=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D*/<br>;*&=
nbsp; serrano/prgm/project/bigloo/bigloo/api/web/src/Llib/xml.scm&nb=
sp; */<br>;* -----------------------------------=
-------------------------- */<br>;* Author =
: Manuel Serrano &nbs=
p; &n=
bsp; */<br>;* Creation : Fri Mar 11 =
16:23:53 2005 =
*/<br>;* Last change : Sun =
Oct 7 08:46:03 2018 (serrano)  =
; */<br>;* Copyright : 2005-18 Manu=
el Serrano &n=
bsp; */<br>;* --------------------=
----------------------------------------- */<br>;*  =
; XML parsing =
&nbs=
p; */<br>;*=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D*/<br><br>;*---------------------=
------------------------------------------------*/<br>;* The m=
odule =
 =
; */<br>;*----------------------=
-----------------------------------------------*/<br>(module __web_xml<br><=
br> (option (set! *dlopen-init-gc* #t))<br><br> (export (xml-=
parse::pair-nil port::input-port<br> &=
nbsp; #!key<br> &nbs=
p; (content-length 0)<br> =
(proc=
edure (lambda (tag attribs body start-pos)<br> &=
nbsp; =
(list tag attribs =
body)))<br> &=
nbsp; (specials '())<br> &=
nbsp; (strict #t)<br> &=
nbsp; =
(content-pos #f)<br> &nb=
sp; (encoding 'UTF-8)<br> =
(eoi #f))<br>  =
; (xml-string-decode::bstring ::bstring)<br>  =
; (xml-string-decode!::bstring ::bstring)<br> &nb=
sp; (xml-string-encode::bstring ::bstring)<br> (=
read-xml #!optional (port::input-port (current-input-port)))<br>  =
; (xml-metadata xml-tree::pair-nil)))<br><br>;*--------------=
-------------------------------------------------------*/<br>;*  =
; xml-parse ... &nbs=
p; &n=
bsp; */<br>;*--------------------=
-------------------------------------------------*/<br>(define (xml-parse::=
pair-nil port::input-port<br> &n=
bsp; #!key<br> &n=
bsp; (content-length 0)<br> &n=
bsp; (procedure (lambda (tag =
attribs body start-pos)<br> =
&nbs=
p; (list tag attribs body)))<br> &=
nbsp; =
(specials '())<br>  =
; (strict #t)<br> &=
nbsp; (content-pos #f)<br=
> (e=
ncoding 'UTF-8)<br> =
(eoi #f))<br> (when (elong? content-length)<br> =
; (set! content-length (elong->fixnum content-length)))<br=
> (when (and (fixnum? content-length) (>fx content-length 0))<br>=
(input-port-fill-barrier-set! port content-length))<br=
> (when (>fx content-length 0)<br> (set! cont=
ent-length (+fx content-length (input-port-position port))))<br> (le=
t loop ((decoder (lambda (x) x)))<br> (let ((obj (read/=
rp xml-grammar port procedure procedure specials strict content-pos decoder=
encoding (input-port-position port))))<br> (when (and (=
fixnum? content-length) (>fx content-length 0))<br> &n=
bsp; (input-port-fill-barrier-set! port -1))<br> =
(cond<br> ((eof-object? obj)<br>  =
; '())<br> ((or (and (=
procedure? eoi) (eoi obj))<br> (and (=
>fx content-length 0)<br> &n=
bsp; (>=3Dfx (input-port-position port) content-length)))<br>&nbs=
p; (list obj))<br> &nbs=
p; ((and (pair? obj) (eq? 'xml-decl (car obj)))<br>  =
; (let ((enc (assq 'encoding (cdr obj))))<br> &nb=
sp; (if enc<br> &nb=
sp; (cons obj (loop (get-decoder (cdr enc) encoding)))<br>  =
; (cons obj (loop decoder)))))<br> &n=
bsp; (else<br> (cons o=
bj (loop decoder)))))))<br><br>;*------------------------------------------=
---------------------------*/<br>;* xml-parse-error ... =
 =
; &nb=
sp; */<br>;*---------------------------------------------------------------=
------*/<br>(define (xml-parse-error msg obj name pos)<br> (raise<br=
> (instantiate::&io-parse-error<br> (=
proc 'xml-parse)<br> (msg msg)<br> =
(obj obj)<br> (fname name)<br> =
(location pos))))<br><br>;*------------------------------------------------=
---------------------*/<br>;* error-line ... &nbs=
p; &n=
bsp; =
*/<br>;*-----------------------------------------------------------=
----------*/<br>(define (error-line c port)<br> (let ((line (read-li=
ne port)))<br> (string-append "{" (string c) "}" (if (s=
tring? line) line ""))))<br><br>;*-----------------------------------------=
----------------------------*/<br>;* special ... =
 =
; &nb=
sp; */<br>;*------------------------------------------=
---------------------------*/<br>(define-struct special tag attributes body=
owner)<br><br><br>;*------------------------------------------------------=
---------------*/<br>;* collect-up-to ... =
 =
; */<=
br>;*---------------------------------------------------------------------*=
/<br>(define (collect-up-to start-pos ignore tag attributes port make speci=
als strict content-pos decoder encoding)<br><br> (define (collect ig=
nore tags)<br> (let ((name (input-port-name port))<br>&=
nbsp; (po (input-port-position port)))<br> &=
nbsp; (let loop ((acc '())<br> =
(item (ignore)))<br> (cond<br=
> ((symbol? item)<br> &n=
bsp; (cond<br> &nbs=
p; ((eq? item tag)<br> =
(make tag attributes (reverse! acc) start-pos))<br>  =
; (strict<br> &nbs=
p; (xml-parse-error "Illegal closing tag"<br> &nbs=
p; (format "`~a' expected, `~a' provided"=
<br> tag ite=
m)<br> name po))=
<br> (else<br> &nbs=
p; (make tag attributes (reverse! acc) sta=
rt-pos))))<br> ((special? item)<br>=
(let ((nitem (make (special-tag item)=
<br> &n=
bsp; (special-attributes item)<br> &nb=
sp; (special-body item)<br> &nb=
sp; &=
nbsp; start-pos)))<br> &=
nbsp; (if (memq (special-tag item) tags)<br>  =
; (loop acc nitem)<br> =
(list (make tag attributes (reverse! acc=
) start-pos) nitem))))<br> ((eof-ob=
ject? item)<br> (if strict<br> &n=
bsp; (xml-parse-error<br>  =
; (format "Premature end of =
line, expecting tag `~a'"<br> &n=
bsp; tag)<br> &nbs=
p; item name po)<br> &n=
bsp; (make tag attributes (reverse! acc) start-pos)))<br> =
(else<br> (let =
((po (input-port-last-token-position port)))<br> &n=
bsp; (loop (econs item acc (list 'at name po)) (ignore)))))))=
)<br><br> (let ((spec (assq tag specials)))<br> =
(cond<br> ((not spec)<br> (coll=
ect ignore '()))<br> ((null? (cdr spec))<br> =
(make tag attributes '() start-pos))<br> (=
(procedure? (cdr spec))<br> (make tag attributes (=
(cdr spec) port) start-pos))<br> ((pair? (cdr spec))<br>=
(let ((ignore (lambda ()<br> &n=
bsp; (read/rp xml-grammar port<br>&n=
bsp; &=
nbsp; (lambda (t a b) (special t a b tag))<br> &nb=
sp; make<br=
>  =
; specials strict content-pos decoder encoding (input-port-po=
sition port)))))<br> (collect ignore (cdr =
spec))))<br> (else<br> (error "=
xml-parse" "Illegal special handler" spec)))))<br><br>;*-------------------=
--------------------------------------------------*/<br>;* att=
ribute-value-grammar ... &n=
bsp; =
*/<br>;*------------------------------------------------------------=
---------*/<br>(define attribute-value-grammar<br> (regular-grammar =
(strict tag)<br> ((+ (in " \t\n\r"))<br> &=
nbsp; (ignore))<br> ((: #\" (* (or (out #\\ #\") (: #\=
\ all))) #\")<br> (the-substring 1 (-fx (the-length) 1=
)))<br> ((: #\' (* (or (out #\\ #\') (: #\\ all))) #\')=
<br> (the-substring 1 (-fx (the-length) 1)))<br> =
((: (+ digit) (? (or "%" "px" "cm" "em" "mm" "inch")))<br>&n=
bsp; (if strict<br> (xml-parse-err=
or (format "Illegal `~a' attribute value" tag)<br> =
(the-string)<br> &=
nbsp; (input-port-name =
(the-port))<br> &nb=
sp; (input-port-position (the-port)))<br> =
(the-string)))<br> ((+ (out " \t\n\r<>(){}[]@!\"'=
/"))<br> (if strict<br> (xml=
-parse-error (format "Illegal `~a' attribute character" tag)<br>  =
; (the-string)<br=
> (in=
put-port-name (the-port))<br> &n=
bsp; (input-port-position (the-port)))<br> &=
nbsp; (the-string)))<br> (else<br> =
(let ((c (the-failure)))<br> (if (not (eo=
f-object? c))<br> (if (or strict<br>=
(not (or (char=
=3D? c #\space)<br> =
(char=3D? c #\Newline)<br> &=
nbsp; (char=3D? c #\>))))=
<br> (xml-parse-error<br> =
(format "Illegal `~a' attribute cha=
racter" tag)<br> (error-line c=
(the-port))<br> (input-port-n=
ame (the-port))<br> (input-por=
t-position (the-port)))<br> " "=
)<br> (xml-parse-error<br> &nbs=
p; (format "Premature end of line for tag `~a' =
attribute" tag)<br> c<br> &nbs=
p; (input-port-name (the-port))<br> =
(-fx (input-port-position (the-port)) 1)))))))=
<br><br>;*-----------------------------------------------------------------=
----*/<br>;* attribute-grammar ... =
 =
; */<br>;*----------------=
-----------------------------------------------------*/<br>(define attribut=
e-grammar<br> (regular-grammar ((id (: (in ("azAZ") "_") (* (in ("az=
AZ09") ":_-"))))<br> ta=
g<br> strict<br> &=
nbsp; decoder)<br> &nb=
sp; ((+ (in " \t\n\r"))<br> (ignore))<br> =
((: id "=3D")<br> (let* ((key (the-substring 0=
(-fx (the-length) 1)))<br> (val (re=
ad/rp attribute-value-grammar (the-port) strict tag)))<br>  =
; (cons (string->symbol (decoder key)) (decoder val))))<br> =
((: id (+ blank) "=3D")<br> (let* ((key=
(the-substring 0 (-fx (the-length) 2)))<br>  =
; (val (read/rp attribute-value-grammar (the-port) strict tag)))<br>=
(let loop ((i (-fx (string-length key) 1)))<br>&n=
bsp; (case (string-ref key i)<br> &nb=
sp; ((#\space #\tab #\Newline)<br> &nb=
sp; (loop (-fx i 1)))<br> =
(else<br> (set! key (substring key 0=
(+ i 1))))))<br> (cons (string->symbol (decode=
r key)) (decoder val))))<br> ((: id)<br> &=
nbsp; (let* ((key (decoder (the-string))))<br> (c=
ons (string->symbol key) key)))<br> ((or "/>" "&g=
t;")<br> (the-symbol))<br> (else<b=
r> (let ((c (the-failure)))<br> &nbs=
p; (if (not (eof-object? c))<br> (xm=
l-parse-error "Illegal attribute character"<br> &nb=
sp; (error-line c (the-port)=
)<br> =
(input-port-name (the-port))<br> &nb=
sp; (input-port-position (the-port=
)))<br> (xml-parse-error<br> &n=
bsp; (format "Premature end of line, expecting =
tag `~a'" tag)<br> c<br>  =
; (input-port-name (the-port))<br> &=
nbsp; (-fx (input-port-position (the-port)) 1)))))))<=
br><br>;*------------------------------------------------------------------=
---*/<br>;* cdata-grammar ...  =
; &nb=
sp; */<br>;*-------=
--------------------------------------------------------------*/<br>(define=
cdata-grammar<br> (regular-grammar (decoder)<br>  =
; ((* (out "]"))<br> (let* ((res (decoder (the-string)=
))<br> (rest (ignore)))<br> &nb=
sp; (string-append res rest)))<br> ("]"<br=
> (string-append "]" (ignore)))<br>  =
; ((: "]]>" (? "\n"))<br> "")<br> &nbs=
p; (else<br> (let* ((c (the-failure))<br> &=
nbsp; (msg (if (not (eof-object? c))<br> &n=
bsp; "Illegal <![CDATA[ charact=
er"<br> "Prematu=
re end of line, expecting tag `]]>'")))<br> (xm=
l-parse-error msg<br> &nbs=
p; c<br> &n=
bsp; (input-port-name (the-port))<br> =
(input-port-position (the-port)))))))<br><br>;*=
---------------------------------------------------------------------*/<br>=
;* get-decoder ... &n=
bsp; =
*/<br>;*-----------=
----------------------------------------------------------*/<br>(define (ge=
t-decoder::procedure enc::bstring dst-enc)<br> (let ((src-enc (strin=
g->symbol (string-upcase enc))))<br> (cond<br> =
((or (not src-enc) (eq? src-enc dst-enc))<br> &nbs=
p; (lambda (x) x))<br> ((eq? src-enc 'UTF-8)<br>&=
nbsp; (cond<br> ((memq =
dst-enc '(ISO-8859-1 ISO-8859-2 ISO-8859-15))<br> =
utf8->iso-latin)<br> ((eq=
? dst-enc 'UCS-2)<br> utf8-string-&g=
t;ucs2-string)<br> (else<br> &n=
bsp; (lambda (x) x))))<br> ((memq s=
rc-enc '(ISO-8859-1 ISO-8859-2 ISO-8859-15))<br> (=
cond<br> ((eq? dst-enc 'UTF-8)<br> &n=
bsp; iso-latin->utf8)<br> &=
nbsp; ((eq? dst-enc 'UCS-2)<br> &nb=
sp; (lambda (x)<br> (utf8-string->=
ucs2-string (iso-latin->utf8 x))))<br> =
(else<br> (lambda (x) x))))<br> =
; (else<br> (lambda (x) x)))))<br><br=
>;*---------------------------------------------------------------------*/<=
br>;* xml-grammar ... =
&nbs=
p; */<br>;*--------=
-------------------------------------------------------------*/<br>(define =
xml-grammar<br> (regular-grammar ((id (: (in ("azAZ") "!?") (* (in (=
"azAZ09") ":_-"))))<br> =
next<br> make<br> =
; specials<br> &nb=
sp; strict<br> =
content-pos<br> &nbs=
p; decoder<br> &n=
bsp; encoding<br> &n=
bsp; pos)<br><br> (define =
(update-start-position!)<br> (set! pos (input-port-pos=
ition (the-port))))<br><br> (define (ignore-w/-pos-upda=
te!)<br> (update-start-position!)<br> &nb=
sp; (ignore))<br><br> ((+ (in " \t\n\r"))<br> &n=
bsp; (update-start-position!)<br> (if content-=
pos<br> (list (the-string) (- pos (the-l=
ength)))<br> (the-string)))<br> &n=
bsp; ((: "<!--"<br> (* (or (out "-") (: =
"-" (out "-")) (: "--" (out ">"))))<br> "-->=
")<br> (update-start-position!)<br>  =
; (cons 'comment (the-string)))<br> ((: "<!" (: (or=
(out "[-") (: "-" (out "-")))<br> &nb=
sp; (* (out ">]"))<br> (? (:=
"[" (* (out "]")) "]"))<br> (*=
(out ">"))) ">")<br> (update-start-position!)<b=
r> (cons 'declaration (the-string)))<br> =
("<![CDATA["<br> (let ((cdata (read/rp cdata=
-grammar (the-port) decoder)))<br> (updat=
e-start-position!)<br> (cons 'cdata cdata=
)))<br> ((: "<?xml " (* (out "?>")) "?>")<br>&=
nbsp; (let ((s (the-substring 6 (the-length))))<br> &nb=
sp; (string-set! s (-fx (string-length s) 2) #\space)<br> =
; (let ((p (open-input-string s)))<br> =
(let loop ((attr '()))<br> &n=
bsp; (let ((obj (read/rp attribute-grammar p 'xml #t decoder)))<br> &n=
bsp; (cond<br> &nb=
sp; ((pair? obj)<br> &nb=
sp; (loop (cons obj attr)))<br> &nbs=
p; ((eq? obj '>)<br>  =
; (update-s=
tart-position!)<br> &nbs=
p; (cons 'xml-decl attr))))))))<br> ((: "<?" (* (ou=
t ">")) ">")<br> (update-start-position!)<br>&nb=
sp; (cons 'instruction (the-string)))<br>  =
; ((: "<" id ">")<br> (let* ((t (the-substring 1=
(-fx (the-length) 1)))<br> (ts (str=
ing->symbol t))<br> (p (the-port)=
))<br> (let ((element (collect-up-to pos ignore-w/=
-pos-update! ts '() p make specials strict content-pos decoder encoding)))<=
br> (update-start-position!)<br>&=
nbsp; element)))<br>  =
; ((: "<" id "/>")<br> (let ((t (the-substring 1=
(-fx (the-length) 2))))<br> (let ((p pos=
))<br> (update-start-position!)<b=
r> (make (string->symbol t) '(=
) '() p))))<br> ((: "<" id (in " \n\t\r"))<br> =
(let* ((t (the-substring 1 (-fx (the-length) 1)))<br> =
(ts (string->symbol t))<br>  =
; (p (the-port)))<br> (=
let loop ((attr '()))<br> (let ((obj (read=
/rp attribute-grammar p t strict decoder)))<br> &nb=
sp; (cond<br> ((pair? ob=
j)<br> (loop (cons obj a=
ttr)))<br> ((eq? obj '>)<br=
> (let ((element (collec=
t-up-to pos ignore-w/-pos-update! ts (reverse! attr) p make specials strict=
content-pos decoder encoding)))<br> &nbs=
p; (update-start-position!)<br> &=
nbsp; eleme=
nt))<br> ((eq? obj '/>)<br>=
(let =
((p pos))<br> =
(update-start-position!)<br> &nb=
sp; (make ts (reverse! attr) '()=
p))))))))<br> ((: "</" id ">")<br> =
(update-start-position!)<br> (string->symbo=
l (the-substring 2 (-fx (the-length) 1))))<br> ((+ (out=
"<"))<br> (update-start-position!)<br>  =
; (if content-pos<br> (let ((pos=
2 (- pos (the-length))))<br> (lis=
t (decoder (the-string)) pos2))<br> (dec=
oder (the-string))))<br> (else<br> =
(let ((c (the-failure)))<br> (cond<br>  =
; ((not (eof-object? c))<br> =
(xml-parse-error "Illegal character"<br> &n=
bsp; (error-line c (th=
e-port))<br> =
(input-port-name (the-port))<br> &n=
bsp; (input-port-position (t=
he-port))))<br> (else<br>  =
; c))))))<br><br>;*-----------------------------------=
----------------------------------*/<br>;* char-hexnumeric? ..=
. &nbs=
p; &n=
bsp; */<br>;*-------------------------------------------------------------=
--------*/<br>(define (char-hexnumeric? c)<br> (or (char-numeric? c)=
<br> (and (char>=3D? c #\A) (char<=3D? c #\F))<b=
r> (and (char>=3D? c #\a) (char<=3D? c #\f))))<b=
r><br>;*-------------------------------------------------------------------=
--*/<br>;* xml-string-decode-inner! ... &n=
bsp; =
*/<br>;*--------------------------------------=
-------------------------------*/<br>(define (xml-string-decode-inner! str =
ol nl res)<br> (define (char-value c)<br> (cond<=
br> ((char-numeric? c)<br> (-fx=
(char->integer c) (char->integer #\0)))<br> ((cha=
r<=3D? c #\F)<br> (+fx 10 (-fx (char->intege=
r c) (char->integer #\A))))<br> (else<br> =
(+fx 10 (-fx (char->integer c) (char->integer #\a))))))=
<br> (let ((ol-2 (-fx ol 2)))<br> (let loop ((i =
0)<br> (j 0))<br> =
(if (=3Dfx j nl)<br> res<br> &n=
bsp; (let ((c (string-ref str i)))<br> &nb=
sp; (if (and (char=3D? c #\%) (<fx i ol-2))<br> &=
nbsp; (let ((c1 (string-ref str (+fx i 1))=
)<br> (c2 (s=
tring-ref str (+fx i 2))))<br> =
(if (and (char-hexnumeric? c1) (char-hexnumeric? c2))<br>&nb=
sp; (let* ((v1 (c=
har-value c1))<br> =
(v2 (char-value c2))<br> =
(d (integer->c=
har (+fx (*fx v1 16) v2))))<br> =
(string-set! res j d)<br> &nbs=
p; (loop (+fx i =
3) (+fx j 1)))<br> =
(begin<br> =
(string-set! res j c)<br> &nbs=
p; (loop (+fx i 1) (+fx j 1))=
)))<br> (begin<br> =
(string-set! res j c)=
<br> (loop (+fx =
i 1) (+fx j 1)))))))))<br><br>;*-------------------------------------------=
--------------------------*/<br>;* xml-count ... =
 =
; &nb=
sp; */<br>;*-------------------------------------------------=
--------------------*/<br>(define (xml-count str ol)<br> (let loop (=
(i 0)<br> (c 0))<br> &n=
bsp; (cond<br> ((=3Dfx i ol)<br>  =
; c)<br> ((char=3D? (string-ref str i) #\&)<br> =
; (cond<br> ((substring=
-at? str "&lt;" i)<br> (loop (+f=
x i 4) (+fx c 1)))<br> ((substring-at? str=
"&gt;" i)<br> (loop (+fx i 4) (=
+fx c 1)))<br> ((substring-at? str "&a=
mp;" i)<br> (loop (+fx i 5) (+fx c 1=
)))<br> ((substring-at? str "&quot;" i=
)<br> (loop (+fx i 6) (+fx c 1)))<br=
> ((substring-at? str "&nbsp;" i)<br>&=
nbsp; (loop (+fx i 6) (+fx c 1)))<br> =
; ((substring-at? str "&#" i)<br>  =
; (let liip ((i (+fx i 2)))<br>  =
; (cond<br> =
((=3Dfx i ol)<br>  =
; c)<br> ((char-numeric=
? (string-ref str i))<br>  =
; (liip (+fx i 1)))<br> =
(else<br> (loop (+fx i=
1) (+fx c 1))))))<br> (else<br> &nbs=
p; (loop (+fx i 1) (+fx c 1)))))<br> =
(else<br> (loop (+fx i 1) (+fx c 1))))))<b=
r><br>;*-------------------------------------------------------------------=
--*/<br>;* xml-decode ... &n=
bsp; =
*/<br>;*---=
------------------------------------------------------------------*/<br>(de=
fine (xml-decode! str res ol nl)<br> (let loop ((i 0)<br>  =
; (j 0))<br> (cond<br> =
((=3Dfx i ol)<br> res)<br> &nbs=
p; ((char=3D? (string-ref str i) #\&)<br> &nbs=
p; (cond<br> ((substring-at? str "&lt;=
" i)<br> (string-set! res j #\<)<=
br> (loop (+fx i 4) (+fx j 1)))<br>&=
nbsp; ((substring-at? str "&gt;" i)<br> =
; (string-set! res j #\>)<br> &nbs=
p; (loop (+fx i 4) (+fx j 1)))<br> &n=
bsp; ((substring-at? str "&amp;" i)<br>  =
; (string-set! res j #\&)<br> &n=
bsp; (loop (+fx i 5) (+fx j 1)))<br> =
((substring-at? str "&quot;" i)<br> &=
nbsp; (string-set! res j #\")<br> &n=
bsp; (loop (+fx i 6) (+fx j 1)))<br> ((sub=
string-at? str "&nbsp;" i)<br> (=
string-set! res j #\space)<br> (loop=
(+fx i 6) (+fx j 1)))<br> ((substring-at?=
str "&#" i)<br> (let liip ((i (=
+fx i 2))<br> (n 0=
))<br> (if (=3Dfx i ol)<br> &nbs=
p; res<br> =
(let ((c (string-ref str i)))<br> &n=
bsp; (if (char-numeric? c)<br> &=
nbsp; (liip (+fx =
i 1)<br> &nb=
sp; (+fx (*fx n 10)<br> =
(-fx (char->integer c)<br> &=
nbsp; =
(char->integer #\0))))<br> =
(begin<br> =
(string-set! res j (integer=
->char n))<br> &=
nbsp; (loop (+fx i 1) (+fx j 1))))))))<br> =
(else<br> (string-se=
t! res j (string-ref str i))<br> (lo=
op (+fx i 1) (+fx j 1)))))<br> (else<br> &nbs=
p; (string-set! res j (string-ref str i))<br> &nbs=
p; (loop (+fx i 1) (+fx j 1))))))<br><br>;*--------------------------------=
-------------------------------------*/<br>;* xml-string-decod=
e ... =
 =
; */<br>;*----------------------------------------------------------=
-----------*/<br>(define (xml-string-decode str)<br> (let ((ol (stri=
ng-length str)))<br> (if (>=3Dfx ol 3)<br> &nbs=
p; (let ((nl (xml-count str ol)))<br> =
(if (=3Dfx nl ol)<br> (strin=
g-copy str)<br> (let ((res (make-stri=
ng nl)))<br> (xml-decode=
! str res ol nl)<br> res=
)))<br> (string-copy str))))<br><br>;*------------=
---------------------------------------------------------*/<br>;* &nb=
sp; xml-string-decode! ... =
 =
; */<br>;*-------------------------------------------=
--------------------------*/<br>(define (xml-string-decode! str)<br> =
(let ((ol (string-length str)))<br> (if (>=3Dfx ol =
3)<br> (let ((nl (xml-count str ol)))<br> &nb=
sp; (if (=3Dfx nl ol)<br> &nbs=
p; str<br> (begin<br> &nb=
sp; (xml-decode! str str ol nl)<br>&=
nbsp; (string-shrink! str nl))=
))<br> str)))<br><br>;*---------------------------=
------------------------------------------*/<br>;* xml-string-=
encode ... &n=
bsp; =
*/<br>;*-----------------------------------------------------=
----------------*/<br>(define (xml-string-encode str)<br> (define (c=
ount str ol)<br> (let loop ((i 0)<br> =
(n 0))<br> (if (=3Dfx i ol)<br>&nbs=
p; n<br> (let (=
(c (string-ref str i)))<br> (case c<br=
> ((#\")<br> =
(loop (+fx i 1) (+fx n 6)))<br> &nbs=
p; ((#\&)<br> =
(loop (+fx i 1) (+fx n 5)))<br>  =
; ((#\< #\>)<br> &=
nbsp; (loop (+fx i 1) (+fx n 4)))<br> =
(else<br> =
(loop (+fx i 1) (+fx n 1))))))))<br> (define (encode s=
tr ol nl)<br> (if (=3Dfx nl ol)<br> &=
nbsp; str<br> (let ((res (make-string nl)))<br>&nb=
sp; (let loop ((i 0)<br>  =
; (j 0))<br> &=
nbsp; (if (=3Dfx j nl)<br> &nbs=
p; res<br> (let ((c (str=
ing-ref str i)))<br> &nb=
sp; (case c<br> &n=
bsp; ((#\<)<br> =
(blit-string! "&lt;" 0 res j 4)<br> &nb=
sp; (loop (+fx i 1) (+fx j 4)))<br> &=
nbsp; ((#\>)<br> =
; (blit-string! "=
&gt;" 0 res j 4)<br> &=
nbsp; (loop (+fx i 1) (+fx j 4)))<br>  =
; ((#\&)<br> &n=
bsp; (blit-string! "&amp;" 0 res j 5)<=
br> (loop (=
+fx i 1) (+fx j 5)))<br> &=
nbsp; ((#\")<br> &n=
bsp; (blit-string! "&quot;" 0 res j 6)<br> &n=
bsp; (loop (+fx i 1) (+fx j 6)))<br>=
(else<br>&n=
bsp; (string-set!=
res j c)<br>  =
; (loop (+fx i 1) (+fx j 1))))))))))<br> (let ((ol (string-length s=
tr)))<br> (encode str ol (count str ol))))<br><br>;*---=
------------------------------------------------------------------*/<br>;*&=
nbsp; read-xml ... &=
nbsp; =
*/<br>;*---------=
------------------------------------------------------------*/<br>(define (=
read-xml #!optional (port::input-port (current-input-port)))<br> (xm=
l-parse port))<br><br>;*---------------------------------------------------=
------------------*/<br>;* xml-metadata ...  =
; &nb=
sp; =
*/<br>;*-------------------------------------------------------------------=
--*/<br>(define (xml-metadata xml)<br> (let ((xml-ver #f)<br> &=
nbsp; (xml-enc #f)<br> (xml-lang #f)<br> &nb=
sp; (root-ver 0.0)<br> (xml-root #f)<br> &nb=
sp; (xml-ns '()))<br> (let loop1 ((l xml))<br>&n=
bsp; (when (pair? l)<br> (matc=
h-case (car l)<br> ((xml-decl . (an=
d ?attr (?- . ?-)))<br> (for-each (lam=
bda (at)<br> =
(case (car at)<br> &nbs=
p; ((version) (set! xml-ver (cdr attr)))<br> =
((enc=
oding) (set! xml-enc (cdr attr)))))<br>  =
; attr))<br> &nbs=
p; ((?mark ?lattr . ?-)<br> (let loop=
3 ((lattr lattr))<br> (unless =
xml-root (set! xml-root mark))<br> &nb=
sp; (when (pair? lattr)<br> &n=
bsp; (let ((attr (car lattr)))<br> &nb=
sp; (case (car attr)<br> =
((xml:lang)<br> &=
nbsp; (set! xml-lang (cdr att=
r)))<br> &nb=
sp; ((xmlns)<br> &n=
bsp; (set! xml-root (cons (cdr attr) xml-root)))<br> &nb=
sp; ((version)<br> =
; (set! ro=
ot-ver (string->number (cdr attr))))<br> &=
nbsp; (else<br> &n=
bsp; (let ((str (symbol->string =
(car attr))))<br> &=
nbsp; (when (substring=3D? str "xmlns:" 6)<br>  =
; (let* ((=
l (string-length str))<br>  =
; (s (substring str 6 l)=
)<br> &=
nbsp; (si (string->symbol s)))<br> =
&nbs=
p; (set! xml-ns<br>  =
; (cons (cons (cd=
r attr) si)<br> &nb=
sp; xml-ns)))))))<=
br> (loop3 (cdr la=
ttr)))))))<br> (loop1 (cdr l))))<br> =
(unless xml-root<br> (error "xml-metadata"=
"Empty XML document !" xml))<br> ;; Values are :<br>&n=
bsp; ;; - XML Version (1.0 or 1.1) or #f<br> &nb=
sp; ;; - XML Encoding (#f if unknown)<br> ;; - xml:lang=
value<br> ;; - Pair, which car is the first data marku=
p, and<br> ;; cdr the default namespace<br> =
; ;; - xml first data markup version attribute (0 if unspecif=
ied)<br> ;; - list of prefixed namespaces (prefix . pat=
h)<br> (values xml-ver xml-enc xml-lang xml-root root-v=
er xml-ns)))<br></div>
</div>
</div></body></html>
------=_Part_2025031_411431067.1644858248249--
------=_Part_2025032_514358573.1644858248258
Content-Type: text/x-scheme
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="=?UTF-8?b?eG1sLnNjbQ==?="
Content-ID: <[email protected]>
Oyo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT0qLwo7KiAgICBzZXJyYW5vL3ByZ20vcHJvamVjdC9iaWdsb28vYmlnbG9v
L2FwaS93ZWIvc3JjL0xsaWIveG1sLnNjbSAgICAgICovCjsqICAgIC0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gICAgKi8KOyogICAg
QXV0aG9yICAgICAgOiAgTWFudWVsIFNlcnJhbm8gICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAqLwo7KiAgICBDcmVhdGlvbiAgICA6ICBGcmkgTWFyIDExIDE2OjIzOjUzIDIwMDUg
ICAgICAgICAgICAgICAgICAgICAgICAgICovCjsqICAgIExhc3QgY2hhbmdlIDogIFN1biBPY3Qg
IDcgMDg6NDY6MDMgMjAxOCAoc2VycmFubykgICAgICAgICAgICAgICAgKi8KOyogICAgQ29weXJp
Z2h0ICA6ICAyMDA1LTE4IE1hbnVlbCBTZXJyYW5vICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICovCjsqICAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0gICAgKi8KOyogICAgWE1MIHBhcnNpbmcgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwo7Kj09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovCgo7
Ki0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLSovCjsqICAgIFRoZSBtb2R1bGUgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwo7Ki0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCihtb2R1bGUg
X193ZWJfeG1sCgogIChvcHRpb24gKHNldCEgKmRsb3Blbi1pbml0LWdjKiAjdCkpCgogIChleHBv
cnQgKHhtbC1wYXJzZTo6cGFpci1uaWwgcG9ydDo6aW5wdXQtcG9ydAogICAgICAgICAgICAgICAg
IyFrZXkKICAgICAgICAgICAgICAgIChjb250ZW50LWxlbmd0aCAwKQogICAgICAgICAgICAgICAg
KG1ha2UtZWxlbWVudCAobGFtYmRhICh0YWcgYXR0cmlicyBib2R5IHN0YXJ0LXBvcykKICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChsaXN0IHRhZyBhdHRyaWJz
IGJvZHkpKSkKICAgICAgICAgICAgICAgIChzcGVjaWFscyAnKCkpCiAgICAgICAgICAgICAgICAo
c3RyaWN0ICN0KQogICAgICAgICAgICAgICAgKG1ha2UtY29udGVudCAobGFtYmRhIChzdHIgcG9z
KSBzdHIpKQogICAgICAgICAgICAgICAgKGVuY29kaW5nICdVVEYtOCkKICAgICAgICAgICAgICAg
IChlb2kgI2YpKQogICAgICAoeG1sLXN0cmluZy1kZWNvZGU6OmJzdHJpbmcgOjpic3RyaW5nKQog
ICAgICAoeG1sLXN0cmluZy1kZWNvZGUhOjpic3RyaW5nIDo6YnN0cmluZykKICAgICAgKHhtbC1z
dHJpbmctZW5jb2RlOjpic3RyaW5nIDo6YnN0cmluZykKICAgICAgKHJlYWQteG1sICMhb3B0aW9u
YWwgKHBvcnQ6OmlucHV0LXBvcnQgKGN1cnJlbnQtaW5wdXQtcG9ydCkpKQogICAgICAoeG1sLW1l
dGFkYXRhIHhtbC10cmVlOjpwYWlyLW5pbCkpKQoKOyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwo7KiAgICB4bWwt
cGFyc2UgLi4uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICovCjsqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKGRlZmluZSAoeG1sLXBhcnNlOjpwYWlyLW5pbCBwb3J0
OjppbnB1dC1wb3J0CiAgICAgICAgICAgICAgICAjIWtleQogICAgICAgICAgICAgICAgKGNvbnRl
bnQtbGVuZ3RoIDApCiAgICAgICAgICAgICAgICAobWFrZS1lbGVtZW50IChsYW1iZGEgKHRhZyBh
dHRyaWJzIGJvZHkgc3RhcnQtcG9zKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAobGlzdCB0YWcgYXR0cmlicyBib2R5KSkpCiAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAoc3BlY2lhbHMgJygpKQogICAgICAgICAgICAgICAgKHN0cmljdCAjdCkKICAgICAgICAg
ICAgICAgIChtYWtlLWNvbnRlbnQgKGxhbWJkYSAoc3RyIHBvcykgc3RyKSkKICAgICAgICAgICAg
ICAgIChlbmNvZGluZyAnVVRGLTgpCiAgICAgICAgICAgICAgICAoZW9pICNmKSkKICAod2hlbiAo
ZWxvbmc/IGNvbnRlbnQtbGVuZ3RoKQogICAgICAoc2V0ISBjb250ZW50LWxlbmd0aCAoZWxvbmct
PmZpeG51bSBjb250ZW50LWxlbmd0aCkpKQogICh3aGVuIChhbmQgKGZpeG51bT8gY29udGVudC1s
ZW5ndGgpICg+ZnggY29udGVudC1sZW5ndGggMCkpCiAgICAgIChpbnB1dC1wb3J0LWZpbGwtYmFy
cmllci1zZXQhIHBvcnQgY29udGVudC1sZW5ndGgpKQogICh3aGVuICg+ZnggY29udGVudC1sZW5n
dGggMCkKICAgICAgKHNldCEgY29udGVudC1sZW5ndGggKCtmeCBjb250ZW50LWxlbmd0aCAoaW5w
dXQtcG9ydC1wb3NpdGlvbiBwb3J0KSkpKQogIChsZXQgbG9vcCAoKGRlY29kZXIgKGxhbWJkYSAo
eCkgeCkpKQogICAgICAobGV0ICgob2JqIChyZWFkL3JwIHhtbC1ncmFtbWFyIHBvcnQgbWFrZS1l
bGVtZW50IG1ha2UtZWxlbWVudCBzcGVjaWFscyBzdHJpY3QgbWFrZS1jb250ZW50IGRlY29kZXIg
ZW5jb2RpbmcgKGlucHV0LXBvcnQtcG9zaXRpb24gcG9ydCkpKSkKICAgICh3aGVuIChhbmQgKGZp
eG51bT8gY29udGVudC1sZW5ndGgpICg+ZnggY29udGVudC1sZW5ndGggMCkpCiAgICAgICAgKGlu
cHV0LXBvcnQtZmlsbC1iYXJyaWVyLXNldCEgcG9ydCAtMSkpCiAgICAoY29uZAogICAgICAgICgo
ZW9mLW9iamVjdD8gb2JqKQogICAgICAgICcoKSkKICAgICAgICAoKG9yIChhbmQgKHByb2NlZHVy
ZT8gZW9pKSAoZW9pIG9iaikpCiAgICAgICAgKGFuZCAoPmZ4IGNvbnRlbnQtbGVuZ3RoIDApCiAg
ICAgICAgICAgICAgKD49ZnggKGlucHV0LXBvcnQtcG9zaXRpb24gcG9ydCkgY29udGVudC1sZW5n
dGgpKSkKICAgICAgICAobGlzdCBvYmopKQogICAgICAgICgoYW5kIChwYWlyPyBvYmopIChlcT8g
J3htbC1kZWNsIChjYXIgb2JqKSkpCiAgICAgICAgKGxldCAoKGVuYyAoYXNzcSAnZW5jb2Rpbmcg
KGNkciBvYmopKSkpCiAgICAgICAgKGlmIGVuYwogICAgICAgICAgICAoY29ucyBvYmogKGxvb3Ag
KGdldC1kZWNvZGVyIChjZHIgZW5jKSBlbmNvZGluZykpKQogICAgICAgICAgICAoY29ucyBvYmog
KGxvb3AgZGVjb2RlcikpKSkpCiAgICAgICAgKGVsc2UKICAgICAgICAoY29ucyBvYmogKGxvb3Ag
ZGVjb2RlcikpKSkpKSkKCjsqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KOyogICAgeG1sLXBhcnNlLWVycm9yIC4u
LiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwo7Ki0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLSovCihkZWZpbmUgKHhtbC1wYXJzZS1lcnJvciBtc2cgb2JqIG5hbWUgcG9zKQogIChy
YWlzZQogICAgKGluc3RhbnRpYXRlOjomaW8tcGFyc2UtZXJyb3IKICAgICAgKHByb2MgJ3htbC1w
YXJzZSkKICAgICAgKG1zZyBtc2cpCiAgICAgIChvYmogb2JqKQogICAgICAoZm5hbWUgbmFtZSkK
ICAgICAgKGxvY2F0aW9uIHBvcykpKSkKCjsqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KOyogICAgZXJyb3ItbGlu
ZSAuLi4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICov
CjsqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tKi8KKGRlZmluZSAoZXJyb3ItbGluZSBjIHBvcnQpCiAgKGxldCAoKGxp
bmUgKHJlYWQtbGluZSBwb3J0KSkpCiAgICAgIChzdHJpbmctYXBwZW5kICJ7IiAoc3RyaW5nIGMp
ICJ9IiAoaWYgKHN0cmluZz8gbGluZSkgbGluZSAiIikpKSkKCjsqLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KOyog
ICAgc3BlY2lhbCAuLi4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAqLwo7Ki0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCihkZWZpbmUtc3RydWN0IHNwZWNpYWwgdGFn
IGF0dHJpYnV0ZXMgYm9keSBvd25lcikKCgo7Ki0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCjsqICAgIGNvbGxlY3Qt
dXAtdG8gLi4uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
Ki8KOyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0qLwooZGVmaW5lIChjb2xsZWN0LXVwLXRvIHN0YXJ0LXBvcyBpZ25v
cmUgdGFnIGF0dHJpYnV0ZXMgcG9ydCBtYWtlLWVsZW1lbnQgc3BlY2lhbHMgc3RyaWN0IG1ha2Ut
Y29udGVudCBkZWNvZGVyIGVuY29kaW5nKQoKICAoZGVmaW5lIChjb2xsZWN0IGlnbm9yZSB0YWdz
KQogICAgICAobGV0ICgobmFtZSAoaW5wdXQtcG9ydC1uYW1lIHBvcnQpKQogICAgICAgIChwbyAo
aW5wdXQtcG9ydC1wb3NpdGlvbiBwb3J0KSkpCiAgICAobGV0IGxvb3AgKChhY2MgJygpKQogICAg
ICAgICAgICAoaXRlbSAoaWdub3JlKSkpCiAgICAgICAgKGNvbmQKICAgICAgICAgICgoc3ltYm9s
PyBpdGVtKQogICAgICAgIChjb25kCiAgICAgICAgICAoKGVxPyBpdGVtIHRhZykKICAgICAgICAg
ICAgKG1ha2UtZWxlbWVudCB0YWcgYXR0cmlidXRlcyAocmV2ZXJzZSEgYWNjKSBzdGFydC1wb3Mp
KQogICAgICAgICAgKHN0cmljdAogICAgICAgICAgICAoeG1sLXBhcnNlLWVycm9yICJJbGxlZ2Fs
IGNsb3NpbmcgdGFnIgogICAgICAgICAgICAgIChmb3JtYXQgImB+YScgZXhwZWN0ZWQsIGB+YScg
cHJvdmlkZWQiCiAgICAgICAgICAgICAgdGFnIGl0ZW0pCiAgICAgICAgICAgICAgbmFtZSBwbykp
CiAgICAgICAgICAoZWxzZQogICAgICAgICAgICAobWFrZS1lbGVtZW50IHRhZyBhdHRyaWJ1dGVz
IChyZXZlcnNlISBhY2MpIHN0YXJ0LXBvcykpKSkKICAgICAgICAgICgoc3BlY2lhbD8gaXRlbSkK
ICAgICAgICAobGV0ICgobml0ZW0gKG1ha2UtZWxlbWVudCAoc3BlY2lhbC10YWcgaXRlbSkKICAg
ICAgICAgICAgICAgIChzcGVjaWFsLWF0dHJpYnV0ZXMgaXRlbSkKICAgICAgICAgICAgICAgIChz
cGVjaWFsLWJvZHkgaXRlbSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydC1w
b3MpKSkKICAgICAgICAgIChpZiAobWVtcSAoc3BlY2lhbC10YWcgaXRlbSkgdGFncykKICAgICAg
ICAgICAgICAobG9vcCBhY2Mgbml0ZW0pCiAgICAgICAgICAgICAgKGxpc3QgKG1ha2UtZWxlbWVu
dCB0YWcgYXR0cmlidXRlcyAocmV2ZXJzZSEgYWNjKSBzdGFydC1wb3MpIG5pdGVtKSkpKQogICAg
ICAgICAgKChlb2Ytb2JqZWN0PyBpdGVtKQogICAgICAgIChpZiBzdHJpY3QKICAgICAgICAgICAg
KHhtbC1wYXJzZS1lcnJvcgogICAgICAgICAgICAgIChmb3JtYXQgIlByZW1hdHVyZSBlbmQgb2Yg
bGluZSwgZXhwZWN0aW5nIHRhZyBgfmEnIgogICAgICAgICAgICAgIHRhZykKICAgICAgICAgICAg
ICBpdGVtIG5hbWUgcG8pCiAgICAgICAgICAgIChtYWtlLWVsZW1lbnQgdGFnIGF0dHJpYnV0ZXMg
KHJldmVyc2UhIGFjYykgc3RhcnQtcG9zKSkpCiAgICAgICAgICAoZWxzZQogICAgICAgIChsZXQg
KChwbyAoaW5wdXQtcG9ydC1sYXN0LXRva2VuLXBvc2l0aW9uIHBvcnQpKSkKICAgICAgICAgIChs
b29wIChlY29ucyBpdGVtIGFjYyAobGlzdCAnYXQgbmFtZSBwbykpIChpZ25vcmUpKSkpKSkpKQoK
ICAobGV0ICgoc3BlYyAoYXNzcSB0YWcgc3BlY2lhbHMpKSkKICAgICAgKGNvbmQKICAgICgobm90
IHNwZWMpCiAgICAgIChjb2xsZWN0IGlnbm9yZSAnKCkpKQogICAgKChudWxsPyAoY2RyIHNwZWMp
KQogICAgICAobWFrZS1lbGVtZW50IHRhZyBhdHRyaWJ1dGVzICcoKSBzdGFydC1wb3MpKQogICAg
KChwcm9jZWR1cmU/IChjZHIgc3BlYykpCiAgICAgIChtYWtlLWVsZW1lbnQgdGFnIGF0dHJpYnV0
ZXMgKChjZHIgc3BlYykgcG9ydCkgc3RhcnQtcG9zKSkKICAgICgocGFpcj8gKGNkciBzcGVjKSkK
ICAgICAgKGxldCAoKGlnbm9yZSAobGFtYmRhICgpCiAgICAgICAgICAgICAgKHJlYWQvcnAgeG1s
LWdyYW1tYXIgcG9ydAogICAgICAgICAgICAgICAgICAgIChsYW1iZGEgKHQgYSBiKSAoc3BlY2lh
bCB0IGEgYiB0YWcpKQogICAgICAgICAgICAgICAgICAgIG1ha2UtZWxlbWVudAogICAgICAgICAg
ICAgICAgICAgIHNwZWNpYWxzIHN0cmljdCBtYWtlLWNvbnRlbnQgZGVjb2RlciBlbmNvZGluZyAo
aW5wdXQtcG9ydC1wb3NpdGlvbiBwb3J0KSkpKSkKICAgICAgICAoY29sbGVjdCBpZ25vcmUgKGNk
ciBzcGVjKSkpKQogICAgKGVsc2UKICAgICAgKGVycm9yICJ4bWwtcGFyc2UiICJJbGxlZ2FsIHNw
ZWNpYWwgaGFuZGxlciIgc3BlYykpKSkpCgo7Ki0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCjsqICAgIGF0dHJpYnV0
ZS12YWx1ZS1ncmFtbWFyIC4uLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
Ki8KOyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0qLwooZGVmaW5lIGF0dHJpYnV0ZS12YWx1ZS1ncmFtbWFyCiAgKHJl
Z3VsYXItZ3JhbW1hciAoc3RyaWN0IHRhZykKICAgICAgKCgrIChpbiAiIFx0XG5cciIpKQogICAg
ICAoaWdub3JlKSkKICAgICAgKCg6ICNcIiAoKiAob3IgKG91dCAjXFwgI1wiKSAoOiAjXFwgYWxs
KSkpICNcIikKICAgICAgKHRoZS1zdWJzdHJpbmcgMSAoLWZ4ICh0aGUtbGVuZ3RoKSAxKSkpCiAg
ICAgICgoOiAjXCcgKCogKG9yIChvdXQgI1xcICNcJykgKDogI1xcIGFsbCkpKSAjXCcpCiAgICAg
ICh0aGUtc3Vic3RyaW5nIDEgKC1meCAodGhlLWxlbmd0aCkgMSkpKQogICAgICAoKDogKCsgZGln
aXQpICg/IChvciAiJSIgInB4IiAiY20iICJlbSIgIm1tIiAiaW5jaCIpKSkKICAgICAgKGlmIHN0
cmljdAogICAgICAoeG1sLXBhcnNlLWVycm9yIChmb3JtYXQgIklsbGVnYWwgYH5hJyBhdHRyaWJ1
dGUgdmFsdWUiIHRhZykKICAgICAgICAgICAgICAgICh0aGUtc3RyaW5nKQogICAgICAgICAgICAg
ICAgKGlucHV0LXBvcnQtbmFtZSAodGhlLXBvcnQpKQogICAgICAgICAgICAgICAgKGlucHV0LXBv
cnQtcG9zaXRpb24gKHRoZS1wb3J0KSkpCiAgICAgICh0aGUtc3RyaW5nKSkpCiAgICAgICgoKyAo
b3V0ICIgXHRcblxyPD4oKXt9W11AIVwiJy8iKSkKICAgICAgKGlmIHN0cmljdAogICAgICAoeG1s
LXBhcnNlLWVycm9yIChmb3JtYXQgIklsbGVnYWwgYH5hJyBhdHRyaWJ1dGUgY2hhcmFjdGVyIiB0
YWcpCiAgICAgICAgICAgICAgICAodGhlLXN0cmluZykKICAgICAgICAgICAgICAgIChpbnB1dC1w
b3J0LW5hbWUgKHRoZS1wb3J0KSkKICAgICAgICAgICAgICAgIChpbnB1dC1wb3J0LXBvc2l0aW9u
ICh0aGUtcG9ydCkpKQogICAgICAodGhlLXN0cmluZykpKQogICAgICAoZWxzZQogICAgICAobGV0
ICgoYyAodGhlLWZhaWx1cmUpKSkKICAgICAgKGlmIChub3QgKGVvZi1vYmplY3Q/IGMpKQogICAg
ICAgICAgKGlmIChvciBzdHJpY3QKICAgICAgICAgICAgICAobm90IChvciAoY2hhcj0/IGMgI1xz
cGFjZSkKICAgICAgICAgICAgICAgICAgKGNoYXI9PyBjICNcTmV3bGluZSkKICAgICAgICAgICAg
ICAgICAgKGNoYXI9PyBjICNcPikpKSkKICAgICAgICAgICh4bWwtcGFyc2UtZXJyb3IKICAgICAg
ICAgIChmb3JtYXQgIklsbGVnYWwgYH5hJyBhdHRyaWJ1dGUgY2hhcmFjdGVyIiB0YWcpCiAgICAg
ICAgICAoZXJyb3ItbGluZSBjICh0aGUtcG9ydCkpCiAgICAgICAgICAoaW5wdXQtcG9ydC1uYW1l
ICh0aGUtcG9ydCkpCiAgICAgICAgICAoaW5wdXQtcG9ydC1wb3NpdGlvbiAodGhlLXBvcnQpKSkK
ICAgICAgICAgICIgIikKICAgICAgICAgICh4bWwtcGFyc2UtZXJyb3IKICAgICAgICAgIChmb3Jt
YXQgIlByZW1hdHVyZSBlbmQgb2YgbGluZSBmb3IgdGFnIGB+YScgYXR0cmlidXRlIiB0YWcpCiAg
ICAgICAgICBjCiAgICAgICAgICAoaW5wdXQtcG9ydC1uYW1lICh0aGUtcG9ydCkpCiAgICAgICAg
ICAoLWZ4IChpbnB1dC1wb3J0LXBvc2l0aW9uICh0aGUtcG9ydCkpIDEpKSkpKSkpCgo7Ki0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLSovCjsqICAgIGF0dHJpYnV0ZS1ncmFtbWFyIC4uLiAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgKi8KOyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwooZGVmaW5lIGF0dHJp
YnV0ZS1ncmFtbWFyCiAgKHJlZ3VsYXItZ3JhbW1hciAoKGlkICg6IChpbiAoImF6QVoiKSAiXyIp
ICgqIChpbiAoImF6QVowOSIpICI6Xy0iKSkpKQogICAgICAgICAgICB0YWcKICAgICAgICAgICAg
c3RyaWN0CiAgICAgICAgICAgIGRlY29kZXIpCiAgICAgICgoKyAoaW4gIiBcdFxuXHIiKSkKICAg
ICAgKGlnbm9yZSkpCiAgICAgICgoOiBpZCAiPSIpCiAgICAgIChsZXQqICgoa2V5ICh0aGUtc3Vi
c3RyaW5nIDAgKC1meCAodGhlLWxlbmd0aCkgMSkpKQogICAgICAgICAgKHZhbCAocmVhZC9ycCBh
dHRyaWJ1dGUtdmFsdWUtZ3JhbW1hciAodGhlLXBvcnQpIHN0cmljdCB0YWcpKSkKICAgICAgKGNv
bnMgKHN0cmluZy0+c3ltYm9sIChkZWNvZGVyIGtleSkpIChkZWNvZGVyIHZhbCkpKSkKICAgICAg
KCg6IGlkICgrIGJsYW5rKSAiPSIpCiAgICAgIChsZXQqICgoa2V5ICh0aGUtc3Vic3RyaW5nIDAg
KC1meCAodGhlLWxlbmd0aCkgMikpKQogICAgICAgICAgKHZhbCAocmVhZC9ycCBhdHRyaWJ1dGUt
dmFsdWUtZ3JhbW1hciAodGhlLXBvcnQpIHN0cmljdCB0YWcpKSkKICAgICAgKGxldCBsb29wICgo
aSAoLWZ4IChzdHJpbmctbGVuZ3RoIGtleSkgMSkpKQogICAgICAgIChjYXNlIChzdHJpbmctcmVm
IGtleSBpKQogICAgICAgICgoI1xzcGFjZSAjXHRhYiAjXE5ld2xpbmUpCiAgICAgICAgKGxvb3Ag
KC1meCBpIDEpKSkKICAgICAgICAoZWxzZQogICAgICAgIChzZXQhIGtleSAoc3Vic3RyaW5nIGtl
eSAwICgrIGkgMSkpKSkpKQogICAgICAoY29ucyAoc3RyaW5nLT5zeW1ib2wgKGRlY29kZXIga2V5
KSkgKGRlY29kZXIgdmFsKSkpKQogICAgICAoKDogaWQpCiAgICAgIChsZXQqICgoa2V5IChkZWNv
ZGVyICh0aGUtc3RyaW5nKSkpKQogICAgICAoY29ucyAoc3RyaW5nLT5zeW1ib2wga2V5KSBrZXkp
KSkKICAgICAgKChvciAiLz4iICI+IikKICAgICAgKHRoZS1zeW1ib2wpKQogICAgICAoZWxzZQog
ICAgICAobGV0ICgoYyAodGhlLWZhaWx1cmUpKSkKICAgICAgKGlmIChub3QgKGVvZi1vYmplY3Q/
IGMpKQogICAgICAgICAgKHhtbC1wYXJzZS1lcnJvciAiSWxsZWdhbCBhdHRyaWJ1dGUgY2hhcmFj
dGVyIgogICAgICAgICAgICAgICAgICAoZXJyb3ItbGluZSBjICh0aGUtcG9ydCkpCiAgICAgICAg
ICAgICAgICAgIChpbnB1dC1wb3J0LW5hbWUgKHRoZS1wb3J0KSkKICAgICAgICAgICAgICAgICAg
KGlucHV0LXBvcnQtcG9zaXRpb24gKHRoZS1wb3J0KSkpCiAgICAgICAgICAoeG1sLXBhcnNlLWVy
cm9yCiAgICAgICAgICAoZm9ybWF0ICJQcmVtYXR1cmUgZW5kIG9mIGxpbmUsIGV4cGVjdGluZyB0
YWcgYH5hJyIgdGFnKQogICAgICAgICAgYwogICAgICAgICAgKGlucHV0LXBvcnQtbmFtZSAodGhl
LXBvcnQpKQogICAgICAgICAgKC1meCAoaW5wdXQtcG9ydC1wb3NpdGlvbiAodGhlLXBvcnQpKSAx
KSkpKSkpKQoKOyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwo7KiAgICBjZGF0YS1ncmFtbWFyIC4uLiAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCjsqLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
Ki8KKGRlZmluZSBjZGF0YS1ncmFtbWFyCiAgKHJlZ3VsYXItZ3JhbW1hciAoZGVjb2RlcikKICAg
ICAgKCgqIChvdXQgIl0iKSkKICAgICAgKGxldCogKChyZXMgKGRlY29kZXIgKHRoZS1zdHJpbmcp
KSkKICAgICAgICAgIChyZXN0IChpZ25vcmUpKSkKICAgICAgKHN0cmluZy1hcHBlbmQgcmVzIHJl
c3QpKSkKICAgICAgKCJdIgogICAgICAoc3RyaW5nLWFwcGVuZCAiXSIgKGlnbm9yZSkpKQogICAg
ICAoKDogIl1dPiIgKD8gIlxuIikpCiAgICAgICIiKQogICAgICAoZWxzZQogICAgICAobGV0KiAo
KGMgKHRoZS1mYWlsdXJlKSkKICAgICAgICAgIChtc2cgKGlmIChub3QgKGVvZi1vYmplY3Q/IGMp
KQogICAgICAgICAgICAgICJJbGxlZ2FsIDwhW0NEQVRBWyBjaGFyYWN0ZXIiCiAgICAgICAgICAg
ICAgIlByZW1hdHVyZSBlbmQgb2YgbGluZSwgZXhwZWN0aW5nIHRhZyBgXV0+JyIpKSkKICAgICAg
KHhtbC1wYXJzZS1lcnJvciBtc2cKICAgICAgICAgICAgICBjCiAgICAgICAgICAgICAgKGlucHV0
LXBvcnQtbmFtZSAodGhlLXBvcnQpKQogICAgICAgICAgICAgIChpbnB1dC1wb3J0LXBvc2l0aW9u
ICh0aGUtcG9ydCkpKSkpKSkKCjsqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KOyogICAgZ2V0LWRlY29kZXIgLi4u
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwo7Ki0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLSovCihkZWZpbmUgKGdldC1kZWNvZGVyOjpwcm9jZWR1cmUgZW5jOjpic3RyaW5n
IGRzdC1lbmMpCiAgKGxldCAoKHNyYy1lbmMgKHN0cmluZy0+c3ltYm9sIChzdHJpbmctdXBjYXNl
IGVuYykpKSkKICAgICAgKGNvbmQKICAgICgob3IgKG5vdCBzcmMtZW5jKSAoZXE/IHNyYy1lbmMg
ZHN0LWVuYykpCiAgICAgIChsYW1iZGEgKHgpIHgpKQogICAgKChlcT8gc3JjLWVuYyAnVVRGLTgp
CiAgICAgIChjb25kCiAgICAgICAgKChtZW1xIGRzdC1lbmMgJyhJU08tODg1OS0xIElTTy04ODU5
LTIgSVNPLTg4NTktMTUpKQogICAgICAgICAgdXRmOC0+aXNvLWxhdGluKQogICAgICAgICgoZXE/
IGRzdC1lbmMgJ1VDUy0yKQogICAgICAgICAgdXRmOC1zdHJpbmctPnVjczItc3RyaW5nKQogICAg
ICAgIChlbHNlCiAgICAgICAgICAobGFtYmRhICh4KSB4KSkpKQogICAgKChtZW1xIHNyYy1lbmMg
JyhJU08tODg1OS0xIElTTy04ODU5LTIgSVNPLTg4NTktMTUpKQogICAgICAoY29uZAogICAgICAg
ICgoZXE/IGRzdC1lbmMgJ1VURi04KQogICAgICAgICAgaXNvLWxhdGluLT51dGY4KQogICAgICAg
ICgoZXE/IGRzdC1lbmMgJ1VDUy0yKQogICAgICAgICAgKGxhbWJkYSAoeCkKICAgICAgICAodXRm
OC1zdHJpbmctPnVjczItc3RyaW5nIChpc28tbGF0aW4tPnV0ZjggeCkpKSkKICAgICAgICAoZWxz
ZQogICAgICAgICAgKGxhbWJkYSAoeCkgeCkpKSkKICAgIChlbHNlCiAgICAgIChsYW1iZGEgKHgp
IHgpKSkpKQoKOyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwo7KiAgICB4bWwtZ3JhbW1hciAuLi4gICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCjsqLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
Ki8KKGRlZmluZSB4bWwtZ3JhbW1hcgogIChyZWd1bGFyLWdyYW1tYXIgKChpZCAoOiAoaW4gKCJh
ekFaIikgIiE/IikgKCogKGluICgiYXpBWjA5IikgIjpfLSIpKSkpCiAgICAgICAgICAgIG5leHQK
ICAgICAgICAgICAgbWFrZS1lbGVtZW50CiAgICAgICAgICAgIHNwZWNpYWxzCiAgICAgICAgICAg
IHN0cmljdAogICAgICAgICAgICBtYWtlLWNvbnRlbnQKICAgICAgICAgICAgZGVjb2RlcgogICAg
ICAgICAgICBlbmNvZGluZwogICAgICAgICAgICBwb3MpCgogICAgICAoZGVmaW5lICh1cGRhdGUt
c3RhcnQtcG9zaXRpb24hKQogICAgICAgKHNldCEgcG9zIChpbnB1dC1wb3J0LXBvc2l0aW9uICh0
aGUtcG9ydCkpKSkKCiAgICAgIChkZWZpbmUgKGlnbm9yZS13Ly1wb3MtdXBkYXRlISkKICAgICAg
ICh1cGRhdGUtc3RhcnQtcG9zaXRpb24hKQogICAgICAgKGlnbm9yZSkpCgogICAgICAoKCsgKGlu
ICIgXHRcblxyIikpCiAgICAgICAodXBkYXRlLXN0YXJ0LXBvc2l0aW9uISkKICAgICAgIChtYWtl
LWNvbnRlbnQgKHRoZS1zdHJpbmcpICgtIHBvcyAodGhlLWxlbmd0aCkpKSkKICAgICAgKCg6ICI8
IS0tIgogICAgICAoKiAob3IgKG91dCAiLSIpICg6ICItIiAob3V0ICItIikpICg6ICItLSIgKG91
dCAiPiIpKSkpCiAgICAgICItLT4iKQogICAgICAodXBkYXRlLXN0YXJ0LXBvc2l0aW9uISkKICAg
ICAgKGNvbnMgJ2NvbW1lbnQgKHRoZS1zdHJpbmcpKSkKICAgICAgKCg6ICI8ISIgKDogKG9yIChv
dXQgIlstIikgKDogIi0iIChvdXQgIi0iKSkpCiAgICAgICAgICAoKiAob3V0ICI+XSIpKQogICAg
ICAgICAgKD8gKDogIlsiICgqIChvdXQgIl0iKSkgIl0iKSkKICAgICAgICAgICgqIChvdXQgIj4i
KSkpICI+IikKICAgICAgKHVwZGF0ZS1zdGFydC1wb3NpdGlvbiEpCiAgICAgIChjb25zICdkZWNs
YXJhdGlvbiAodGhlLXN0cmluZykpKQogICAgICAoIjwhW0NEQVRBWyIKICAgICAgKGxldCAoKGNk
YXRhIChyZWFkL3JwIGNkYXRhLWdyYW1tYXIgKHRoZS1wb3J0KSBkZWNvZGVyKSkpCiAgICAgICAg
ICAodXBkYXRlLXN0YXJ0LXBvc2l0aW9uISkKICAgICAgICAgIChjb25zICdjZGF0YSBjZGF0YSkp
KQogICAgICAoKDogIjw/eG1sICIgKCogKG91dCAiPz4iKSkgIj8+IikKICAgICAgKGxldCAoKHMg
KHRoZS1zdWJzdHJpbmcgNiAodGhlLWxlbmd0aCkpKSkKICAgICAgKHN0cmluZy1zZXQhIHMgKC1m
eCAoc3RyaW5nLWxlbmd0aCBzKSAyKSAjXHNwYWNlKQogICAgICAobGV0ICgocCAob3Blbi1pbnB1
dC1zdHJpbmcgcykpKQogICAgICAgIChsZXQgbG9vcCAoKGF0dHIgJygpKSkKICAgICAgICAobGV0
ICgob2JqIChyZWFkL3JwIGF0dHJpYnV0ZS1ncmFtbWFyIHAgJ3htbCAjdCBkZWNvZGVyKSkpCiAg
ICAgICAgICAoY29uZAogICAgICAgICAgICAgICgocGFpcj8gb2JqKQogICAgICAgICAgICAgIChs
b29wIChjb25zIG9iaiBhdHRyKSkpCiAgICAgICAgICAgICAgKChlcT8gb2JqICc+KQogICAgICAg
ICAgICAgICAgICAgICAgKHVwZGF0ZS1zdGFydC1wb3NpdGlvbiEpCiAgICAgICAgICAgICAgKGNv
bnMgJ3htbC1kZWNsIGF0dHIpKSkpKSkpKQogICAgICAoKDogIjw/IiAoKiAob3V0ICI+IikpICI+
IikKICAgICAgKHVwZGF0ZS1zdGFydC1wb3NpdGlvbiEpCiAgICAgIChjb25zICdpbnN0cnVjdGlv
biAodGhlLXN0cmluZykpKQogICAgICAoKDogIjwiIGlkICI+IikKICAgICAgKGxldCogKCh0ICh0
aGUtc3Vic3RyaW5nIDEgKC1meCAodGhlLWxlbmd0aCkgMSkpKQogICAgICAgICAgKHRzIChzdHJp
bmctPnN5bWJvbCB0KSkKICAgICAgICAgIChwICh0aGUtcG9ydCkpKQogICAgICAobGV0ICgoZWxl
bWVudCAoY29sbGVjdC11cC10byBwb3MgaWdub3JlLXcvLXBvcy11cGRhdGUhIHRzICcoKSBwIG1h
a2UtZWxlbWVudCBzcGVjaWFscyBzdHJpY3QgbWFrZS1jb250ZW50IGRlY29kZXIgZW5jb2Rpbmcp
KSkKICAgICAgICAgICAgKHVwZGF0ZS1zdGFydC1wb3NpdGlvbiEpCiAgICAgICAgICAgIGVsZW1l
bnQpKSkKICAgICAgKCg6ICI8IiBpZCAiLz4iKQogICAgICAobGV0ICgodCAodGhlLXN1YnN0cmlu
ZyAxICgtZnggKHRoZS1sZW5ndGgpIDIpKSkpCiAgICAgICAgICAobGV0ICgocCBwb3MpKQogICAg
ICAgICAgICAodXBkYXRlLXN0YXJ0LXBvc2l0aW9uISkKICAgICAgICAgICAgKG1ha2UtZWxlbWVu
dCAoc3RyaW5nLT5zeW1ib2wgdCkgJygpICcoKSBwKSkpKQogICAgICAoKDogIjwiIGlkIChpbiAi
IFxuXHRcciIpKQogICAgICAobGV0KiAoKHQgKHRoZS1zdWJzdHJpbmcgMSAoLWZ4ICh0aGUtbGVu
Z3RoKSAxKSkpCiAgICAgICAgICAodHMgKHN0cmluZy0+c3ltYm9sIHQpKQogICAgICAgICAgKHAg
KHRoZS1wb3J0KSkpCiAgICAgIChsZXQgbG9vcCAoKGF0dHIgJygpKSkKICAgICAgICAobGV0ICgo
b2JqIChyZWFkL3JwIGF0dHJpYnV0ZS1ncmFtbWFyIHAgdCBzdHJpY3QgZGVjb2RlcikpKQogICAg
ICAgIChjb25kCiAgICAgICAgICAoKHBhaXI/IG9iaikKICAgICAgICAgICAgKGxvb3AgKGNvbnMg
b2JqIGF0dHIpKSkKICAgICAgICAgICgoZXE/IG9iaiAnPikKICAgICAgICAgICAgKGxldCAoKGVs
ZW1lbnQgKGNvbGxlY3QtdXAtdG8gcG9zIGlnbm9yZS13Ly1wb3MtdXBkYXRlISB0cyAocmV2ZXJz
ZSEgYXR0cikgcCBtYWtlLWVsZW1lbnQgc3BlY2lhbHMgc3RyaWN0IG1ha2UtY29udGVudCBkZWNv
ZGVyIGVuY29kaW5nKSkpCiAgICAgICAgICAgICAgICAgICAgICAodXBkYXRlLXN0YXJ0LXBvc2l0
aW9uISkKICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQpKQogICAgICAgICAgKChlcT8gb2Jq
ICcvPikKICAgICAgICAgICAgICAgICAgICAobGV0ICgocCBwb3MpKQogICAgICAgICAgICAgICAg
ICAgICAgKHVwZGF0ZS1zdGFydC1wb3NpdGlvbiEpCiAgICAgICAgICAgICAgICAgICAgICAobWFr
ZS1lbGVtZW50IHRzIChyZXZlcnNlISBhdHRyKSAnKCkgcCkpKSkpKSkpCiAgICAgICgoOiAiPC8i
IGlkICI+IikKICAgICAgKHVwZGF0ZS1zdGFydC1wb3NpdGlvbiEpCiAgICAgIChzdHJpbmctPnN5
bWJvbCAodGhlLXN1YnN0cmluZyAyICgtZnggKHRoZS1sZW5ndGgpIDEpKSkpCiAgICAgICgoKyAo
b3V0ICI8IikpCiAgICAgICAodXBkYXRlLXN0YXJ0LXBvc2l0aW9uISkKICAgICAgIChtYWtlLWNv
bnRlbnQgKGRlY29kZXIgKHRoZS1zdHJpbmcpKSAoLSBwb3MgKHRoZS1sZW5ndGgpKSkpCiAgICAg
IChlbHNlCiAgICAgIChsZXQgKChjICh0aGUtZmFpbHVyZSkpKQogICAgICAoY29uZAogICAgICAg
ICgobm90IChlb2Ytb2JqZWN0PyBjKSkKICAgICAgICAgICh4bWwtcGFyc2UtZXJyb3IgIklsbGVn
YWwgY2hhcmFjdGVyIgogICAgICAgICAgICAgICAgICAoZXJyb3ItbGluZSBjICh0aGUtcG9ydCkp
CiAgICAgICAgICAgICAgICAgIChpbnB1dC1wb3J0LW5hbWUgKHRoZS1wb3J0KSkKICAgICAgICAg
ICAgICAgICAgKGlucHV0LXBvcnQtcG9zaXRpb24gKHRoZS1wb3J0KSkpKQogICAgICAgIChlbHNl
CiAgICAgICAgICBjKSkpKSkpCgo7Ki0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCjsqICAgIGNoYXItaGV4bnVtZXJp
Yz8gLi4uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwo7Ki0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLSovCihkZWZpbmUgKGNoYXItaGV4bnVtZXJpYz8gYykKICAob3IgKGNoYXItbnVt
ZXJpYz8gYykKICAgICAgKGFuZCAoY2hhcj49PyBjICNcQSkgKGNoYXI8PT8gYyAjXEYpKQogICAg
ICAoYW5kIChjaGFyPj0/IGMgI1xhKSAoY2hhcjw9PyBjICNcZikpKSkKCjsqLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
Ki8KOyogICAgeG1sLXN0cmluZy1kZWNvZGUtaW5uZXIhIC4uLiAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICovCjsqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKGRlZmluZSAoeG1sLXN0cmluZy1k
ZWNvZGUtaW5uZXIhIHN0ciBvbCBubCByZXMpCiAgKGRlZmluZSAoY2hhci12YWx1ZSBjKQogICAg
ICAoY29uZAogICAgKChjaGFyLW51bWVyaWM/IGMpCiAgICAgICgtZnggKGNoYXItPmludGVnZXIg
YykgKGNoYXItPmludGVnZXIgI1wwKSkpCiAgICAoKGNoYXI8PT8gYyAjXEYpCiAgICAgICgrZngg
MTAgKC1meCAoY2hhci0+aW50ZWdlciBjKSAoY2hhci0+aW50ZWdlciAjXEEpKSkpCiAgICAoZWxz
ZQogICAgICAoK2Z4IDEwICgtZnggKGNoYXItPmludGVnZXIgYykgKGNoYXItPmludGVnZXIgI1xh
KSkpKSkpCiAgKGxldCAoKG9sLTIgKC1meCBvbCAyKSkpCiAgICAgIChsZXQgbG9vcCAoKGkgMCkK
ICAgICAgICAoaiAwKSkKICAgIChpZiAoPWZ4IGogbmwpCiAgICAgICAgcmVzCiAgICAgICAgKGxl
dCAoKGMgKHN0cmluZy1yZWYgc3RyIGkpKSkKICAgICAgICAoaWYgKGFuZCAoY2hhcj0/IGMgI1wl
KSAoPGZ4IGkgb2wtMikpCiAgICAgICAgICAgIChsZXQgKChjMSAoc3RyaW5nLXJlZiBzdHIgKCtm
eCBpIDEpKSkKICAgICAgICAgICAgICAoYzIgKHN0cmluZy1yZWYgc3RyICgrZnggaSAyKSkpKQog
ICAgICAgICAgICAgIChpZiAoYW5kIChjaGFyLWhleG51bWVyaWM/IGMxKSAoY2hhci1oZXhudW1l
cmljPyBjMikpCiAgICAgICAgICAgICAgKGxldCogKCh2MSAoY2hhci12YWx1ZSBjMSkpCiAgICAg
ICAgICAgICAgICAgICh2MiAoY2hhci12YWx1ZSBjMikpCiAgICAgICAgICAgICAgICAgIChkIChp
bnRlZ2VyLT5jaGFyICgrZnggKCpmeCB2MSAxNikgdjIpKSkpCiAgICAgICAgICAgICAgICAgIChz
dHJpbmctc2V0ISByZXMgaiBkKQogICAgICAgICAgICAgICAgICAobG9vcCAoK2Z4IGkgMykgKCtm
eCBqIDEpKSkKICAgICAgICAgICAgICAoYmVnaW4KICAgICAgICAgICAgICAgICAgKHN0cmluZy1z
ZXQhIHJlcyBqIGMpCiAgICAgICAgICAgICAgICAgIChsb29wICgrZnggaSAxKSAoK2Z4IGogMSkp
KSkpCiAgICAgICAgICAgIChiZWdpbgogICAgICAgICAgICAgIChzdHJpbmctc2V0ISByZXMgaiBj
KQogICAgICAgICAgICAgIChsb29wICgrZnggaSAxKSAoK2Z4IGogMSkpKSkpKSkpKQoKOyotLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0qLwo7KiAgICB4bWwtY291bnQgLi4uICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICovCjsqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKGRlZmluZSAoeG1s
LWNvdW50IHN0ciBvbCkKICAobGV0IGxvb3AgKChpIDApCiAgICAgICAgICAoYyAwKSkKICAgICAg
KGNvbmQKICAgICgoPWZ4IGkgb2wpCiAgICAgIGMpCiAgICAoKGNoYXI9PyAoc3RyaW5nLXJlZiBz
dHIgaSkgI1wmKQogICAgICAoY29uZAogICAgICAgICgoc3Vic3RyaW5nLWF0PyBzdHIgIiZsdDsi
IGkpCiAgICAgICAgICAobG9vcCAoK2Z4IGkgNCkgKCtmeCBjIDEpKSkKICAgICAgICAoKHN1YnN0
cmluZy1hdD8gc3RyICImZ3Q7IiBpKQogICAgICAgICAgKGxvb3AgKCtmeCBpIDQpICgrZnggYyAx
KSkpCiAgICAgICAgKChzdWJzdHJpbmctYXQ/IHN0ciAiJmFtcDsiIGkpCiAgICAgICAgICAobG9v
cCAoK2Z4IGkgNSkgKCtmeCBjIDEpKSkKICAgICAgICAoKHN1YnN0cmluZy1hdD8gc3RyICImcXVv
dDsiIGkpCiAgICAgICAgICAobG9vcCAoK2Z4IGkgNikgKCtmeCBjIDEpKSkKICAgICAgICAoKHN1
YnN0cmluZy1hdD8gc3RyICImbmJzcDsiIGkpCiAgICAgICAgICAobG9vcCAoK2Z4IGkgNikgKCtm
eCBjIDEpKSkKICAgICAgICAoKHN1YnN0cmluZy1hdD8gc3RyICImIyIgaSkKICAgICAgICAgIChs
ZXQgbGlpcCAoKGkgKCtmeCBpIDIpKSkKICAgICAgICAoY29uZAogICAgICAgICAgICAoKD1meCBp
IG9sKQogICAgICAgICAgICBjKQogICAgICAgICAgICAoKGNoYXItbnVtZXJpYz8gKHN0cmluZy1y
ZWYgc3RyIGkpKQogICAgICAgICAgICAobGlpcCAoK2Z4IGkgMSkpKQogICAgICAgICAgICAoZWxz
ZQogICAgICAgICAgICAobG9vcCAoK2Z4IGkgMSkgKCtmeCBjIDEpKSkpKSkKICAgICAgICAoZWxz
ZQogICAgICAgICAgKGxvb3AgKCtmeCBpIDEpICgrZnggYyAxKSkpKSkKICAgIChlbHNlCiAgICAg
IChsb29wICgrZnggaSAxKSAoK2Z4IGMgMSkpKSkpKQoKOyotLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwo7KiAgICB4
bWwtZGVjb2RlIC4uLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgKi8KOyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwooZGVmaW5lICh4bWwtZGVjb2RlISBzdHIgcmVzIG9s
IG5sKQogIChsZXQgbG9vcCAoKGkgMCkKICAgICAgICAgIChqIDApKQogICAgICAoY29uZAogICAg
KCg9ZnggaSBvbCkKICAgICAgcmVzKQogICAgKChjaGFyPT8gKHN0cmluZy1yZWYgc3RyIGkpICNc
JikKICAgICAgKGNvbmQKICAgICAgICAoKHN1YnN0cmluZy1hdD8gc3RyICImbHQ7IiBpKQogICAg
ICAgICAgKHN0cmluZy1zZXQhIHJlcyBqICNcPCkKICAgICAgICAgIChsb29wICgrZnggaSA0KSAo
K2Z4IGogMSkpKQogICAgICAgICgoc3Vic3RyaW5nLWF0PyBzdHIgIiZndDsiIGkpCiAgICAgICAg
ICAoc3RyaW5nLXNldCEgcmVzIGogI1w+KQogICAgICAgICAgKGxvb3AgKCtmeCBpIDQpICgrZngg
aiAxKSkpCiAgICAgICAgKChzdWJzdHJpbmctYXQ/IHN0ciAiJmFtcDsiIGkpCiAgICAgICAgICAo
c3RyaW5nLXNldCEgcmVzIGogI1wmKQogICAgICAgICAgKGxvb3AgKCtmeCBpIDUpICgrZnggaiAx
KSkpCiAgICAgICAgKChzdWJzdHJpbmctYXQ/IHN0ciAiJnF1b3Q7IiBpKQogICAgICAgICAgKHN0
cmluZy1zZXQhIHJlcyBqICNcIikKICAgICAgICAgIChsb29wICgrZnggaSA2KSAoK2Z4IGogMSkp
KQogICAgICAgICgoc3Vic3RyaW5nLWF0PyBzdHIgIiZuYnNwOyIgaSkKICAgICAgICAgIChzdHJp
bmctc2V0ISByZXMgaiAjXHNwYWNlKQogICAgICAgICAgKGxvb3AgKCtmeCBpIDYpICgrZnggaiAx
KSkpCiAgICAgICAgKChzdWJzdHJpbmctYXQ/IHN0ciAiJiMiIGkpCiAgICAgICAgICAobGV0IGxp
aXAgKChpICgrZnggaSAyKSkKICAgICAgICAgICAgKG4gMCkpCiAgICAgICAgKGlmICg9ZnggaSBv
bCkKICAgICAgICAgICAgcmVzCiAgICAgICAgICAgIChsZXQgKChjIChzdHJpbmctcmVmIHN0ciBp
KSkpCiAgICAgICAgICAgIChpZiAoY2hhci1udW1lcmljPyBjKQogICAgICAgICAgICAgICAgKGxp
aXAgKCtmeCBpIDEpCiAgICAgICAgICAgICAgICAgICgrZnggKCpmeCBuIDEwKQogICAgICAgICAg
ICAgICAgICAoLWZ4IChjaGFyLT5pbnRlZ2VyIGMpCiAgICAgICAgICAgICAgICAgICAgKGNoYXIt
PmludGVnZXIgI1wwKSkpKQogICAgICAgICAgICAgICAgKGJlZ2luCiAgICAgICAgICAgICAgICAg
IChzdHJpbmctc2V0ISByZXMgaiAoaW50ZWdlci0+Y2hhciBuKSkKICAgICAgICAgICAgICAgICAg
KGxvb3AgKCtmeCBpIDEpICgrZnggaiAxKSkpKSkpKSkKICAgICAgICAoZWxzZQogICAgICAgICAg
KHN0cmluZy1zZXQhIHJlcyBqIChzdHJpbmctcmVmIHN0ciBpKSkKICAgICAgICAgIChsb29wICgr
ZnggaSAxKSAoK2Z4IGogMSkpKSkpCiAgICAoZWxzZQogICAgICAoc3RyaW5nLXNldCEgcmVzIGog
KHN0cmluZy1yZWYgc3RyIGkpKQogICAgICAobG9vcCAoK2Z4IGkgMSkgKCtmeCBqIDEpKSkpKSkK
CjsqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tKi8KOyogICAgeG1sLXN0cmluZy1kZWNvZGUgLi4uICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwo7Ki0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCihkZWZp
bmUgKHhtbC1zdHJpbmctZGVjb2RlIHN0cikKICAobGV0ICgob2wgKHN0cmluZy1sZW5ndGggc3Ry
KSkpCiAgICAgIChpZiAoPj1meCBvbCAzKQogICAgICAobGV0ICgobmwgKHhtbC1jb3VudCBzdHIg
b2wpKSkKICAgICAgICAoaWYgKD1meCBubCBvbCkKICAgICAgICAoc3RyaW5nLWNvcHkgc3RyKQog
ICAgICAgIChsZXQgKChyZXMgKG1ha2Utc3RyaW5nIG5sKSkpCiAgICAgICAgICAgICh4bWwtZGVj
b2RlISBzdHIgcmVzIG9sIG5sKQogICAgICAgICAgICByZXMpKSkKICAgICAgKHN0cmluZy1jb3B5
IHN0cikpKSkKCjsqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KOyogICAgeG1sLXN0cmluZy1kZWNvZGUhIC4uLiAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCjsqLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
Ki8KKGRlZmluZSAoeG1sLXN0cmluZy1kZWNvZGUhIHN0cikKICAobGV0ICgob2wgKHN0cmluZy1s
ZW5ndGggc3RyKSkpCiAgICAgIChpZiAoPj1meCBvbCAzKQogICAgICAobGV0ICgobmwgKHhtbC1j
b3VudCBzdHIgb2wpKSkKICAgICAgICAoaWYgKD1meCBubCBvbCkKICAgICAgICBzdHIKICAgICAg
ICAoYmVnaW4KICAgICAgICAgICAgKHhtbC1kZWNvZGUhIHN0ciBzdHIgb2wgbmwpCiAgICAgICAg
ICAgIChzdHJpbmctc2hyaW5rISBzdHIgbmwpKSkpCiAgICAgIHN0cikpKQoKOyotLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0qLwo7KiAgICB4bWwtc3RyaW5nLWVuY29kZSAuLi4gICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICovCjsqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKGRlZmluZSAoeG1sLXN0cmlu
Zy1lbmNvZGUgc3RyKQogIChkZWZpbmUgKGNvdW50IHN0ciBvbCkKICAgICAgKGxldCBsb29wICgo
aSAwKQogICAgICAgIChuIDApKQogICAgKGlmICg9ZnggaSBvbCkKICAgICAgICBuCiAgICAgICAg
KGxldCAoKGMgKHN0cmluZy1yZWYgc3RyIGkpKSkKICAgICAgICAoY2FzZSBjCiAgICAgICAgICAo
KCNcIikKICAgICAgICAgICAgKGxvb3AgKCtmeCBpIDEpICgrZnggbiA2KSkpCiAgICAgICAgICAo
KCNcJikKICAgICAgICAgICAgKGxvb3AgKCtmeCBpIDEpICgrZnggbiA1KSkpCiAgICAgICAgICAo
KCNcPCAjXD4pCiAgICAgICAgICAgIChsb29wICgrZnggaSAxKSAoK2Z4IG4gNCkpKQogICAgICAg
ICAgKGVsc2UKICAgICAgICAgICAgKGxvb3AgKCtmeCBpIDEpICgrZnggbiAxKSkpKSkpKSkKICAo
ZGVmaW5lIChlbmNvZGUgc3RyIG9sIG5sKQogICAgICAoaWYgKD1meCBubCBvbCkKICAgICAgc3Ry
CiAgICAgIChsZXQgKChyZXMgKG1ha2Utc3RyaW5nIG5sKSkpCiAgICAgICAgKGxldCBsb29wICgo
aSAwKQogICAgICAgICAgICAoaiAwKSkKICAgICAgICAoaWYgKD1meCBqIG5sKQogICAgICAgICAg
ICByZXMKICAgICAgICAgICAgKGxldCAoKGMgKHN0cmluZy1yZWYgc3RyIGkpKSkKICAgICAgICAg
ICAgICAoY2FzZSBjCiAgICAgICAgICAgICAgKCgjXDwpCiAgICAgICAgICAgICAgKGJsaXQtc3Ry
aW5nISAiJmx0OyIgMCByZXMgaiA0KQogICAgICAgICAgICAgIChsb29wICgrZnggaSAxKSAoK2Z4
IGogNCkpKQogICAgICAgICAgICAgICgoI1w+KQogICAgICAgICAgICAgIChibGl0LXN0cmluZyEg
IiZndDsiIDAgcmVzIGogNCkKICAgICAgICAgICAgICAobG9vcCAoK2Z4IGkgMSkgKCtmeCBqIDQp
KSkKICAgICAgICAgICAgICAoKCNcJikKICAgICAgICAgICAgICAoYmxpdC1zdHJpbmchICImYW1w
OyIgMCByZXMgaiA1KQogICAgICAgICAgICAgIChsb29wICgrZnggaSAxKSAoK2Z4IGogNSkpKQog
ICAgICAgICAgICAgICgoI1wiKQogICAgICAgICAgICAgIChibGl0LXN0cmluZyEgIiZxdW90OyIg
MCByZXMgaiA2KQogICAgICAgICAgICAgIChsb29wICgrZnggaSAxKSAoK2Z4IGogNikpKQogICAg
ICAgICAgICAgIChlbHNlCiAgICAgICAgICAgICAgKHN0cmluZy1zZXQhIHJlcyBqIGMpCiAgICAg
ICAgICAgICAgKGxvb3AgKCtmeCBpIDEpICgrZnggaiAxKSkpKSkpKSkpKQogIChsZXQgKChvbCAo
c3RyaW5nLWxlbmd0aCBzdHIpKSkKICAgICAgKGVuY29kZSBzdHIgb2wgKGNvdW50IHN0ciBvbCkp
KSkKCjsqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tKi8KOyogICAgcmVhZC14bWwgLi4uICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCjsqLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKGRl
ZmluZSAocmVhZC14bWwgIyFvcHRpb25hbCAocG9ydDo6aW5wdXQtcG9ydCAoY3VycmVudC1pbnB1
dC1wb3J0KSkpCiAgKHhtbC1wYXJzZSBwb3J0KSkKCjsqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KOyogICAgeG1s
LW1ldGFkYXRhIC4uLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICovCjsqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKGRlZmluZSAoeG1sLW1ldGFkYXRhIHhtbCkKICAobGV0
ICgoeG1sLXZlciAjZikKICAgICh4bWwtZW5jICNmKQogICAgKHhtbC1sYW5nICNmKQogICAgKHJv
b3QtdmVyIDAuMCkKICAgICh4bWwtcm9vdCAjZikKICAgICh4bWwtbnMgJygpKSkKICAgICAgKGxl
dCBsb29wMSAoKGwgeG1sKSkKICAgICh3aGVuIChwYWlyPyBsKQogICAgICAgIChtYXRjaC1jYXNl
IChjYXIgbCkKICAgICAgICAgICgoeG1sLWRlY2wgLiAoYW5kID9hdHRyICg/LSAuID8tKSkpCiAg
ICAgICAgKGZvci1lYWNoIChsYW1iZGEgKGF0KQogICAgICAgICAgICAgICAgKGNhc2UgKGNhciBh
dCkKICAgICAgICAgICAgICAgICgodmVyc2lvbikgKHNldCEgeG1sLXZlciAoY2RyIGF0dHIpKSkK
ICAgICAgICAgICAgICAgICgoZW5jb2RpbmcpIChzZXQhIHhtbC1lbmMgKGNkciBhdHRyKSkpKSkK
ICAgICAgICAgICAgICBhdHRyKSkKICAgICAgICAgICgoP21hcmsgP2xhdHRyIC4gPy0pCiAgICAg
ICAgKGxldCBsb29wMyAoKGxhdHRyIGxhdHRyKSkKICAgICAgICAgICh1bmxlc3MgeG1sLXJvb3Qg
KHNldCEgeG1sLXJvb3QgbWFyaykpCiAgICAgICAgICAod2hlbiAocGFpcj8gbGF0dHIpCiAgICAg
ICAgICAgICAgKGxldCAoKGF0dHIgKGNhciBsYXR0cikpKQogICAgICAgICAgICAoY2FzZSAoY2Fy
IGF0dHIpCiAgICAgICAgICAgICAgICAoKHhtbDpsYW5nKQogICAgICAgICAgICAgICAgKHNldCEg
eG1sLWxhbmcgKGNkciBhdHRyKSkpCiAgICAgICAgICAgICAgICAoKHhtbG5zKQogICAgICAgICAg
ICAgICAgKHNldCEgeG1sLXJvb3QgKGNvbnMgKGNkciBhdHRyKSB4bWwtcm9vdCkpKQogICAgICAg
ICAgICAgICAgKCh2ZXJzaW9uKQogICAgICAgICAgICAgICAgKHNldCEgcm9vdC12ZXIgKHN0cmlu
Zy0+bnVtYmVyIChjZHIgYXR0cikpKSkKICAgICAgICAgICAgICAgIChlbHNlCiAgICAgICAgICAg
ICAgICAobGV0ICgoc3RyIChzeW1ib2wtPnN0cmluZyAoY2FyIGF0dHIpKSkpCiAgICAgICAgICAg
ICAgICAod2hlbiAoc3Vic3RyaW5nPT8gc3RyICJ4bWxuczoiIDYpCiAgICAgICAgICAgICAgICAg
IChsZXQqICgobCAoc3RyaW5nLWxlbmd0aCBzdHIpKQogICAgICAgICAgICAgICAgICAgICAgKHMg
KHN1YnN0cmluZyBzdHIgNiBsKSkKICAgICAgICAgICAgICAgICAgICAgIChzaSAoc3RyaW5nLT5z
eW1ib2wgcykpKQogICAgICAgICAgICAgICAgICAgICAgKHNldCEgeG1sLW5zCiAgICAgICAgICAg
ICAgICAgICAgICAgIChjb25zIChjb25zIChjZHIgYXR0cikgc2kpCiAgICAgICAgICAgICAgICAg
ICAgICAgICAgeG1sLW5zKSkpKSkpKQogICAgICAgICAgICAobG9vcDMgKGNkciBsYXR0cikpKSkp
KSkKICAgICAgICAobG9vcDEgKGNkciBsKSkpKQogICAgICAodW5sZXNzIHhtbC1yb290CiAgICAo
ZXJyb3IgInhtbC1tZXRhZGF0YSIgIkVtcHR5IFhNTCBkb2N1bWVudCAhIiB4bWwpKQogICAgICA7
OyBWYWx1ZXMgYXJlIDoKICAgICAgOzsgLSBYTUwgVmVyc2lvbiAoMS4wIG9yIDEuMSkgb3IgI2YK
ICAgICAgOzsgLSBYTUwgRW5jb2RpbmcgKCNmIGlmIHVua25vd24pCiAgICAgIDs7IC0geG1sOmxh
bmcgdmFsdWUKICAgICAgOzsgLSBQYWlyLCB3aGljaCBjYXIgaXMgdGhlIGZpcnN0IGRhdGEgbWFy
a3VwLCBhbmQKICAgICAgOzsgIGNkciB0aGUgZGVmYXVsdCBuYW1lc3BhY2UKICAgICAgOzsgLSB4
bWwgZmlyc3QgZGF0YSBtYXJrdXAgdmVyc2lvbiBhdHRyaWJ1dGUgKDAgaWYgdW5zcGVjaWZpZWQp
CiAgICAgIDs7IC0gbGlzdCBvZiBwcmVmaXhlZCBuYW1lc3BhY2VzIChwcmVmaXggLiBwYXRoKQog
ICAgICAodmFsdWVzIHhtbC12ZXIgeG1sLWVuYyB4bWwtbGFuZyB4bWwtcm9vdCByb290LXZlciB4
bWwtbnMpKSk=
------=_Part_2025032_514358573.1644858248258--