add `raco link'

includes a rewrite the "Module Basics" section of the Guide
This commit is contained in:
Matthew Flatt 2011-08-22 15:00:05 -06:00
parent b7bad5cc8a
commit a7855e20a8
36 changed files with 2180 additions and 832 deletions

View File

@ -144,12 +144,12 @@
(let ([zo (append-zo-suffix b)])
(compile-to-zo f zo n prefix verbose? mod?)))))
(define (compile-directory-visitor dir info worker
(define (compile-directory-visitor dir info worker omit-root
#:verbose [verbose? #t]
#:skip-path [orig-skip-path #f]
#:skip-doc-sources? [skip-docs? #f])
(define info* (or info (lambda (key mk-default) (mk-default))))
(define omit-paths (omitted-paths dir c-get-info/full))
(define omit-paths (omitted-paths dir c-get-info/full omit-root))
(define skip-path (and orig-skip-path (path->bytes
(simplify-path (if (string? orig-skip-path)
(string->path orig-skip-path)
@ -191,7 +191,7 @@
(for/fold ([init init]) ([p (directory-list dir)])
(let ([p* (build-path dir p)])
(if (and (directory-exists? p*) (not (member p omit-paths)))
(compile-directory-visitor p* (c-get-info/full p*) worker
(compile-directory-visitor p* (c-get-info/full p*) worker omit-root
#:verbose verbose?
#:skip-path skip-path
#:skip-doc-sources? skip-docs?)
@ -202,10 +202,11 @@
#:skip-path [orig-skip-path #f]
#:skip-doc-sources? [skip-docs? #f]
#:managed-compile-zo [managed-compile-zo
(make-caching-managed-compile-zo)])
(make-caching-managed-compile-zo)]
#:omit-root [omit-root dir])
(define (worker prev sses)
(for-each managed-compile-zo sses))
(compile-directory-visitor dir info worker
(compile-directory-visitor dir info worker omit-root
#:verbose verbose?
#:skip-path orig-skip-path
#:skip-doc-sources? skip-docs?))
@ -215,21 +216,29 @@
#:skip-path [orig-skip-path #f]
#:skip-doc-sources? [skip-docs? #f]
#:managed-compile-zo [managed-compile-zo
(make-caching-managed-compile-zo)])
(compile-directory-visitor dir info append
(make-caching-managed-compile-zo)]
#:omit-root [omit-root dir])
(compile-directory-visitor dir info append omit-root
#:verbose verbose?
#:skip-path orig-skip-path
#:skip-doc-sources? skip-docs?
#:managed-compile-zo managed-compile-zo))
(define unspec (gensym))
(define (compile-collection-zos collection
#:skip-path [skip-path #f]
#:skip-doc-sources? [skip-docs? #f]
#:managed-compile-zo [managed-compile-zo
(make-caching-managed-compile-zo)]
#:omit-root [omit-root unspec]
. cp)
(compile-directory (apply collection-path collection cp)
(define dir (apply collection-path collection cp))
(compile-directory dir
(c-get-info (cons collection cp))
#:omit-root (if (eq? omit-root unspec)
dir
omit-root)
#:verbose #f
#:skip-path skip-path
#:skip-doc-sources? skip-docs?

1
collects/config/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/links.rktd

View File

@ -890,6 +890,7 @@
(current-library-collection-paths))
(read-bytecode ,(PLANET-BASE-DIR))
(exists ,(find-system-path 'addon-dir))
(read ,(find-system-path 'links-file))
,@(compute-permissions allow)
,@(sandbox-path-permissions))]
;; general info

View File

@ -203,32 +203,50 @@ access languages like @filepath{literal.rkt} and
@filepath{literal.rkt} into a Racket @tech{collection} named
@filepath{literal}.
To install a collection, you can create a directory either in the main
Racket installation or in a user-specific directory. Use
@racket[find-collects-dir] or @racket[find-user-collects-dir] from
@racketmodname[setup/dirs] to find the directory:
There are two ways to create the @filepath{literal} collection (see
also @secref["link-collection"]):
@interaction[
(require setup/dirs)
(eval:alts (find-user-collects-dir)
@itemlist[
@item{You can create a directory either in the main Racket
installation or in a user-specific directory. Use
@racket[find-collects-dir] or @racket[find-user-collects-dir]
from @racketmodname[setup/dirs] to find the directory:
@interaction[
(require setup/dirs)
(eval:alts (find-user-collects-dir)
(build-path "/home/racketeer/.racket/"
(version)
"collects"))
]
]
Move @filepath{literal.rkt} to @filepath{literal/lang/reader.rkt}
within the directory reported by @racket[find-collects-dir] or
@racket[find-user-collects-dir]. That is, the file
@filepath{literal.rkt} must be renamed to @filepath{reader.rkt} and
placed in a @filepath{lang} sub-directory of the @filepath{literal}
collection.
Move @filepath{literal.rkt} to
@filepath{literal/lang/reader.rkt} within the directory reported
by @racket[find-collects-dir] or
@racket[find-user-collects-dir]. That is, the file
@filepath{literal.rkt} must be renamed to @filepath{reader.rkt}
and placed in a @filepath{lang} sub-directory of the
@filepath{literal} collection.
@racketblock[
.... @#,elem{(the main installation or the user's space)}
@racketblock[
.... @#,elem{(the main installation or the user's space)}
!- @#,filepath{collects}
!- @#,filepath{literal}
!- @#,filepath{lang}
!- @#,filepath{reader.rkt}
]}
@item{Alternatively, move @filepath{literal.rkt} to
@filepath{literal/lang/reader.rkt} for any directory name
@filepath{literal}. Then, in the directory that contains
@filepath{literal}, use the command line
@commandline{raco link literal}
to register the @filepath{literal} directory as the
@filepath{literal} collection.}
]
After moving the file, you can use @racket[literal] directly after
@ -247,17 +265,17 @@ for more information on using @exec{raco}.}
You can also package a collection for others to install by using the
@exec{raco pack} command-line tool:
@commandline{raco pack --collection literal.plt literal}
@commandline{raco pack --collect literal.plt literal}
Then, others can install the @filepath{literal} collection using
@exec{raco setup}:
@commandline{raco setup literal.plt}
@commandline{raco setup -A literal.plt}
@margin-note{See @other-manual['(lib "planet/planet.scrbl")] for more
information about @|PLaneT| packages.}
A better approach may be to distribute your language as a @|PLaneT|
Another approach is to distribute your language as a @|PLaneT|
package. A drawback of using a @|PLaneT| package is that users must
type @racket[@#,hash-lang[] @#,racketmodname[planet]] followed by a
@|PLaneT| path to access the language. The great advantages are that the

View File

@ -1,38 +1,47 @@
#lang scribble/doc
@(require scribble/manual scribble/eval "guide-utils.rkt"
(for-label setup/dirs))
@(require scribble/manual
scribble/eval
"guide-utils.rkt"
"module-hier.rkt"
(for-label setup/dirs
setup/link
racket/date))
@title[#:tag "module-basics"]{Module Basics}
The space of module names is distinct from the space of normal Racket
definitions. Indeed, since modules typically reside in files, the
space of module names is explicitly tied to the filesystem at run
time. For example, if the file @filepath{/home/molly/cake.rkt} contains
Each Racket module typically resides in its own file. For example,
suppose the file @filepath{cake.rkt} contains the following module:
@racketmod[
#:file "cake.rkt"
racket
(provide print-cake)
(code:comment @#,t{draws a cake with @racket[n] candles})
(define (print-cake n)
(printf " ~a \n" (make-string n #\.))
(printf " .-~a-.\n" (make-string n #\|))
(printf " | ~a |\n" (make-string n #\space))
(printf "---~a---\n" (make-string n #\-)))
(show " ~a " n #\.)
(show " .-~a-. " n #\|)
(show " | ~a | " n #\space)
(show "---~a---" n #\-))
(define (show fmt n ch)
(printf fmt (make-string n ch))
(newline))
]
then it can be used as the source of a module whose full name is based
on the path @filepath{/home/molly/cake.rkt}. The @racket[provide] line
exports the definition @racket[print-cake] so that it can be used
outside the module.
Then, other modules can import @filepath{cake.rkt} to use the
@racket[print-cake] function, since the @racket[provide] line in
@filepath{cake.rkt} explicitly exports the definition
@racket[print-cake]. The @racket[show] function is private to
@filepath{cake.rkt} (i.e., it cannot be used from other modules),
since @racket[show] is not exported.
Instead of using its full path, a module is more likely to be
referenced by a relative path. For example, a file
@filepath{/home/molly/random-cake.rkt} could use the @filepath{cake.rkt} module
like this:
The following @filepath{random-cake.rkt} module imports
@filepath{cake.rkt}:
@racketmod[
#:file "random-cake.rkt"
racket
(require "cake.rkt")
@ -41,17 +50,90 @@ racket
]
The relative reference @racket["cake.rkt"] in the import
@racket[(require "cake.rkt")] works because the @filepath{cake.rkt} module
source is in the same directory as the @filepath{random-cake.rkt}
file. (Unix-style relative paths are used for relative module
references on all platforms, much like relative URLs.)
@racket[(require "cake.rkt")] works if the @filepath{cake.rkt} and
@filepath{random-cake.rkt} modules are in the same
directory. (Unix-style relative paths are used for relative module
references on all platforms, much like relative URLs in HTML pages.)
Library modules that are distributed with Racket are usually
referenced through an unquoted, suffixless path. The path is relative
to the library installation directory, which contains directories for
individual library @deftech{collections}. The module below refers to
the @filepath{date.rkt} library that is part of the @filepath{racket}
@tech{collection}.
@; ----------------------------------------
@section[#:tag "module-org"]{Organizing Modules}
The @filepath{cake.rkt} and @filepath{random-cake.rkt} example
demonstrates the most common way to organize a program into modules:
put all module files in a single directory (perhaps with
subdirectories), and then have the modules reference each other
through relative paths. A directory of modules can act as a
project, since it can be moved around on the filesystem or copied to
other machines, and relative paths preserve the connections among
modules.
As another example, if you are building a candy-sorting program, you
might have a main @filepath{sort.rkt} module that uses other modules
to access a candy database and a control sorting machine. If the
candy-database module itself is organized into sub-modules that handle
barcode and manufacturer information, then the database module could
be @filepath{db/lookup.rkt} that uses helper modules
@filepath{db/barcodes.rkt} and @filepath{db/makers.rkt}. Similarly,
the sorting-machine driver @filepath{machine/control.rkt} might use
helper modules @filepath{machine/sensors.rkt} and
@filepath{machine/actuators.rkt}.
@centerline[module-hierarchy]
The @filepath{sort.rkt} module uses the relative paths
@filepath{db/lookup.rkt} and @filepath{machine/control.rkt} to import
from the database and machine-control libraries:
@racketmod[
#:file "sort.rkt"
racket
(require "db/lookup.rkt" "machine/control.rkt")
....]
The @filepath{db/lookup.rkt} module similarly uses paths relative to
its own source to access the @filepath{db/barcodes.rkt} and
@filepath{db/makers.rkt} modules:
@racketmod[
#:file "db/lookup.rkt"
racket
(require "barcode.rkt" "makers.rkt")
....]
Ditto for @filepath{machine/control.rkt}:
@racketmod[
#:file "machine/control.rkt"
racket
(require "sensors.rkt" "actuators.rkt")
....]
Racket tools all work automatically with relative paths. For example,
@commandline{racket sort.rkt}
on the comamnd line runs the @filepath{sort.rkt} program and
automatically loads and compiles required modules. With a large enough
program, compilation from source can take too long, so use
@commandline{raco make sort.rkt}
to compile @filepath{sort.rkt} and all its dependencies to bytecode
files. Running @exec{racket sort.rkt} will automatically use bytecode
files when they are present.
@margin-note{See @secref[#:doc '(lib "scribblings/raco/raco.scrbl")
"make"] for more information on @exec{raco make}.}
@; ----------------------------------------
@section{Library Collections}
A @deftech{collection} is a set of installed library modules. A
module in a @tech{collection} is referenced through an unquoted,
suffixless path. For example, the following module refers to the
@filepath{date.rkt} library that is part of the @filepath{racket}
@tech{collection}:
@racketmod[
racket
@ -62,12 +144,41 @@ racket
(date->string (seconds->date (current-seconds))))
]
In addition to the main @tech{collection} directory, which contains
all collections that are part of the installation, collections can
also be installed in a user-specific location. Finally, additional
collection directories can be specified in configuration files or
through the @envvar{PLTCOLLECTS} search path. Try running the
following program to find out where your collections are:
When you search the online Racket documentation, the search results
indicate the module that provides each binding. Alternatively, if you
reach a binding's documentation by clicking on hyperlinks, you can
hover over the binding name to find out which modules provide
it.
A module reference like @racketmodname[racket/date] looks like an
identifier, but it is not treated in the same way as @racket[printf]
or @racket[date->string]. Instead, when @racket[require] sees a module
reference that is unquoted, it converts the reference to a
collection-based module path:
@itemlist[
@item{First, if the unquoted path contains no @litchar{/}, then
@racket[require] automatically adds a @filepath{/main} to the
reference. For example, @racket[(require
@#,racketmodname[slideshow])] is equivalent to @racket[(require
slideshow/main)].}
@item{Second, @racket[require] implicitly adds a @filepath{.rkt}
suffix to the path.}
@item{Finally, @racket[require] treats the path as relative to the
installation location of the collection, instead of relative to
the enclosing module's path.}
]
The @filepath{racket} collection is located in a directory with the
Racket installation. A user-specific directory can contain additional
collections, and even more collection directories can be specified in
configuration files or through the @envvar{PLTCOLLECTS} search
path. Try running the following program to find out how your
collection search path is configured:
@racketmod[
racket
@ -79,5 +190,84 @@ racket
(get-collects-search-dirs) (code:comment @#,t{complete search path})
]
We discuss more forms of module reference later in
@secref["module-paths"].
@; ----------------------------------------
@section[#:tag "link-collection"]{Adding Collections}
Looking back at the candy-sorting example of @secref["module-org"],
suppose that modules in @filepath{db/} and @filepath{machine/} need a
common set of helper functions. Helper functions could be put in a
@filepath{utils/} directory, and modules in @filepath{db/} or
@filepath{machine/} could access utility modules with relative paths
that start @filepath{../utils/}. As long as a set of modules work
together in a single project, it's best to stick with relative paths.
A programmer can follow relative-path references without knowing about
your Racket configuration.
Some libraries are meant to be used across multiple projects, so that
keeping the library source in a directory with its uses does not make
sense. In that case, you have two options:
@itemlist[
@item{Add the library to a new or existing @tech{collection}. After
the library is in a collection, it can be referenced with an
unquoted path, just like libraries that are included with the
Racket distribution.}
@item{Add the library a new or existing @|PLaneT| package. Libraries
in a @|PLaneT| package are referenced with a path of the form
@racket[(planet ....)] path.
@margin-note{See @other-doc['(lib "planet/planet.scrbl")]
for more information on @|PLaneT|.}}
]
The simplest option is to add a new collection. You could add a new
collection by placing files in the Racket installation or one of the
directories reported by @racket[(get-collects-search-dirs)]---perhaps
setting the @envvar{PLTCOLLECTS} environment variable to extend the
search path---but using @exec{raco link} is usually the best approach.
The @exec{raco link} command-line tool creates a link from a collection
name to a directory for the collection's modules. For example, suppose
you have a directory @filepath{/usr/molly/bakery} that contains the
@filepath{cake.rkt} module (from the
@seclink["module-basics"]{beginning} of this section) and other
related modules. To make the modules available as a @filepath{bakery}
collection, use
@commandline{raco link /usr/molly/bakery}
Afterward, @racket[(require bakery/cake)] from any module will import
the @racket[print-cake] function from
@filepath{/usr/molly/bakery/cake.rkt}.
To make a collection name different from the name of the directory
that contains the collection's modules, use the @DFlag{name} or
@Flag{n} option for @exec{raco link}. By default, @exec{raco link}
installs a collection link only for the current user, but you can
supply the @DFlag{installation} or @Flag{i} flag to install the link
for all users of your Racket installation.
@margin-note{See @secref[#:doc '(lib "scribblings/raco/raco.scrbl")
"link"] for more information on @exec{raco link}.}
If you intend to distribute your library collection to others, choose
the collection name carefully. The collection namespace is
hierarchical, but (unlike @|PLaneT|) the collection system has no
built-in feature to avoid conflicts from different producers or
different versions. Consider putting one-off libraries under some
top-level name like @filepath{molly} that identifies the producer.
Use a collection name like @filepath{bakery} when producing the
definitive collection of baked-goods libraries.
After your libraries are in a @tech{collection}, then you can still
use @exec{raco make} to compile the library sources, but it's better
and more convenient to use @exec{raco setup}. The @exec{raco setup}
command takes a collection name (as opposed to a file name) and
compiles all libraries within the collection. In addition, it can
build documentation for the collection and add it to the documentation
index, as specified by a @filepath{info.rkt} module in the collection.
See @secref[#:doc '(lib "scribblings/raco/raco.scrbl") "setup"] for
more information on @exec{raco setup}.

View File

@ -0,0 +1,97 @@
#lang racket/base
(require slideshow/pict
racket/draw
racket/class
racket/math)
(provide module-hierarchy)
(define GAP 12)
(define file-color (make-object color% #xEC #xF5 #xF5))
(define folder
(let ()
(define W 200)
(define H 144)
(define dy (* -8/3 2))
(define p (make-object dc-path%))
(send p move-to 0 50)
(send p arc 0 (+ 22 dy) 8 8 pi (/ pi 2) #f)
(send p arc 2 (+ 18 dy) 4 4 (/ pi -2) 0 #t)
(send p arc 6 0 20 20 pi (/ pi 2) #f)
(send p line-to 60 0)
(send p arc 50 0 20 20 (/ pi 2) 0 #f)
(send p arc 70 (+ 22 dy) 2 2 pi (* 3/2 pi))
(send p arc 180 (+ 24 dy) 20 20 (/ pi 2) 0 #f)
(send p arc 180 120 20 20 0 (/ pi -2) #f)
(send p arc 0 120 20 20 (/ pi -2) (- pi) #f)
(send p close)
(scale
(dc (lambda (dc x y)
(define b (send dc get-brush))
(send dc set-brush file-color 'solid)
(send dc draw-path p x y)
(send dc set-brush b))
W H)
12/32)))
(define file
(file-icon (/ 75 2) 54 file-color))
(define (lbl i t)
(vc-append 4 i (text t '(bold . modern) 12)))
(define (listing p)
(frame (inset p GAP)
#:color "blue"))
(define db-folder (launder folder))
(define mach-folder (launder folder))
(define db-listing
(listing
(vc-append
GAP
(lbl file "control.rkt")
(hc-append (* 2 GAP)
(lbl file "sensors.rkt")
(lbl file "actuators.rkt")))))
(define mach-listing
(listing
(vc-append
GAP
(lbl file "lookup.rkt")
(hc-append (* 2 GAP)
(lbl file "barcodes.rkt")
(lbl file "makers.rkt")))))
(define (zoom from to p)
(pin-line
(pin-line p
from lb-find
to lt-find
#:style 'dot)
from rb-find
to rt-find
#:style 'dot))
(define module-hierarchy
(inset
(zoom
db-folder db-listing
(zoom
mach-folder mach-listing
(vc-append
(* 3 GAP)
(listing
(hc-append (* 4 GAP)
(lbl file "sort.rkt")
(lbl db-folder "db")
(lbl mach-folder "machine")))
(hc-append
(* 2 GAP)
db-listing
mach-listing))))
2))

View File

@ -162,9 +162,14 @@ racket
(extract "the cat out of the bag")
]
then it is a complete program that prints ``cat'' when run. To
package this program as an executable, choose one of the following
options:
then it is a complete program that prints ``cat'' when run. You can
run the program within DrRacket or using @racket[enter!] in
@exec{racket}, but if the program is saved in @nonterm{src-filename},
you can also run it from a command line with
@commandline{racket @nonterm{src-filename}}
To package the program as an executable, you have a few options:
@itemize[

View File

@ -1,7 +1,11 @@
#lang scheme/base
(require scribble/manual)
(provide inside-doc)
(provide inside-doc
reference-doc)
(define inside-doc
'(lib "scribblings/inside/inside.scrbl"))
(define reference-doc
'(lib "scribblings/reference/reference.scrbl"))

View File

@ -0,0 +1,107 @@
#lang scribble/doc
@(require scribble/manual
scribble/bnf
"common.rkt"
(for-label racket/base))
@title[#:tag "link"]{@exec{raco link}: Library Collection Links}
The @exec{raco link} command inspects and modifies a @tech[#:doc
reference-doc]{collection links file} to display, add, or remove
mappings from collection names to filesystem directories.
For example, the command
@commandline{raco link maze}
installs a user-specific link for the @racket["maze"] collection,
mapping it to the @filepath{maze} subdirectory of the current
directory. Supply multiple directory paths to create multiple links at
once, especially with a command-shell wildcard:
@commandline{raco link *}
By default, the linked collection name is the same as each directory's
name, but the collection name can be set separately for a single
directory with the @DFlag{name} flag.
To remove the link created by the first example above, use
@commandline{raco link --remove maze}
or
@commandline{raco link -r maze}
Like link-adding mode, removing mode accepts multiple directory paths to
remove multiple links, and all links that match any directory are
removed. If @DFlag{name} is used with @DFlag{remove}, then only
links matching both the collection name and directory are removed.
Full command-line options:
@itemlist[
@item{@Flag{s} or @DFlag{show} --- Shows the current link table. If
any other command-line arguments are provided that modify the
link table, the table is shown after modifications. If no
directory arguments are provided, and if none of @Flag{r},
@DFlag{remove}, @Flag{i}, @DFlag{installation}, @Flag{f}, or
@DFlag{file} are specified, then the link table is shown for
both the user-specific and installation-wide @tech[#:doc
reference-doc]{collection links files}.}
@item{@Flag{n} @nonterm{name} or @DFlag{name} @nonterm{name} --- Sets
the collection name for adding or removing a single link. By
default, the collection name for an added link is derived from
the directory name. When the @Flag{r} or @DFlag{remove} flag is
also used, only links with a collection name matching
@nonterm{name} are removed.}
@item{@Flag{x} @nonterm{regexp} or @DFlag{version-regexp}
@nonterm{regexp} --- Sets a version regexp that limits the link
to use only by Racket versions (as reported by
@racket[version]) matching @nonterm{regexp}. When the @Flag{r}
or @DFlag{remove} flag is also used, only links with a
version regexp matching @nonterm{regexp} are removed.}
@item{@Flag{i} or @DFlag{installation} --- Reads and writes links in
installation-wide @tech[#:doc reference-doc]{collection links
file} instead of the user-specific @tech[#:doc
reference-doc]{collection links file}. This flag is mutally
exclusive with @Flag{f} and @DFlag{file}.}
@item{@Flag{f} @nonterm{file} or @DFlag{file} @nonterm{file} ---
Reads and writes links in @nonterm{file} instead of the
user-specific @tech[#:doc reference-doc]{collection links
file}. This flag is mutally exclusive with @Flag{i} and
@DFlag{installation}.}
@item{@DFlag{repair} --- Enables repairs to the existing file content
when the content is erroneous. The file is repaired by deleting
individual links when possible.}
]
@; ----------------------------------------
@section{API for Collection Links}
@defmodule[setup/link]
@defproc[(links [dirs (listof path?)]
[#:file file path-string? (find-system-path 'links-file)]
[#:name name (or/c string? #f) #f]
[#:version-regexp version-regexp (or/c regexp? #f) #f]
[#:error error-proc (symbol? string? any/c ... . -> . any) error]
[#:remove? remove? any/c #f]
[#:show? show? any/c #f]
[#:repair? repair? any/c #f])
(listof string?)]{
A function version of the @exec{raco link} command. The
@racket[error-proc] argument is called to raise exceptions that would
be fatal to the @exec{raco link} command.
The result is a list of top-level collections that are mapped by
@racket[file] and that apply to the running version of Racket.}

View File

@ -16,6 +16,7 @@ a typical Racket installation.
@table-of-contents[]
@include-section["make.scrbl"]
@include-section["link.scrbl"]
@include-section["exe.scrbl"]
@include-section["dist.scrbl"]
@include-section["plt.scrbl"]

View File

@ -2,6 +2,7 @@
@(require scribble/manual
scribble/bnf
"common.rkt"
(for-label racket
racket/future
setup/setup-unit
@ -1086,16 +1087,13 @@ An @deftech{unpackable} is one of the following:
@defproc[(find-relevant-directories
(syms (listof symbol?))
(mode (symbols 'preferred 'all-available) 'preferred)) (listof path?)]{
(mode (or/c 'preferred 'all-available 'no-planet) 'preferred)) (listof path?)]{
Returns a list of paths identifying installed directories (i.e.,
collections and installed @|PLaneT| packages) whose
@filepath{info.rkt} file defines one or more of the given
symbols. The result is based on a cache that is computed by
@exec{raco setup} and stored in the @indexed-file{info-domain}
sub-directory of each collection directory (as determined by the
@envvar{PLT_COLLECTION_PATHS} environment variable, etc.) and the
file @filepath{cache.rkt} in the user add-on directory.
@exec{raco setup}.
Note that the cache may be out of date by the time you call
@racket[get-info/full], so do not assume that it won't return
@racket[#f].
@ -1105,20 +1103,27 @@ An @deftech{unpackable} is one of the following:
providing to @racket[get-info/full].
If @racket[mode] is specified, it must be either
@racket['preferred] (the default) or @racket['all-available]. If
mode is @racket['all-available], @racket[find-relevant-collections]
@racket['preferred] (the default), @racket['all-available], or @racket[no-planet]. If
@racket[mode] is @racket['all-available], @racket[find-relevant-collections]
returns all installed directories whose info files contain the
specified symbols---for instance, all installed PLaneT packages
will be searched if @racket['all-available] is specified. If mode
will be searched if @racket['all-available] is specified. If @racket[mode]
is @racket['preferred], then only a subset of ``preferred''
packages will be searched, and in particular only the directory
packages will be searched: only the directory
containing the most recent version of any PLaneT package will be
returned.
returned. If @racket[mode] is @racket['no-planet], then only PLaneT
packages are not included in the search.
No matter what @racket[mode] is specified, if more than one
collection has the same name, @racket[find-relevant-directories]
will only search the one that occurs first in the
@envvar{PLT_COLLECTION_PATHS} environment variable.}
will only search the one that occurs first in a search that through
the directories of @racket[current-library-collection-paths].
Collection links from the installation-wide @tech[#:doc
reference-doc]{collection links file} are cached with the
installation's main @filepath{collects} directory, and links from
the user-specific @tech[#:doc reference-doc]{collection links file}
are cached with the user-specific directory @racket[(build-path
(find-system-path 'addon-dir) (version) "collects")].}
@defproc[(find-relevant-directory-records
[syms (listof symbol?)]

View File

@ -5,10 +5,10 @@
A @deftech{library} is @racket[module] declaration for use by multiple
programs. Racket further groups libraries into @deftech{collections}
that can be easily distributed and easily added to a local Racket
that can be easily distributed and added to a local Racket
installation.
Some collections are distributed via @|PLaneT|. Such collections are
Some libraries are distributed via @|PLaneT| packages. Such libraries are
referenced through a @racket[planet] module path (see
@racket[require]) and are downloaded by Racket on demand.
@ -17,9 +17,11 @@ collection is a directory that is located in a @filepath{collects}
directory relative to the Racket executable. A collection can also be
installed in a user-specific directory. More generally, the search
path for installed collections can be configured through the
@racket[current-library-collection-paths] parameter. In all of these
cases, the collections are referenced through @racket[lib] paths (see
@racket[require]).
@racket[current-library-collection-paths] parameter. Finally, the
location of collections can be specified through the @tech{collection
links files}; see @secref["links-file"] for more information. In all
of these cases, the collections are referenced through @racket[lib]
paths (see @racket[require]) or symbolic shorthands.
For example, the following module uses the @filepath{getinfo.rkt}
library module from the @filepath{setup} collection, and the
@ -33,7 +35,8 @@ racket
....
]
This example is more compactly and more commonly written as
This example is more compactly and more commonly written using
symbolic shorthands:
@racketmod[
racket
@ -60,14 +63,16 @@ resolver}, as specified by the @racket[current-module-name-resolver]
parameter.
For the default @tech{module name resolver}, the search path for
collections is determined by the
@racket[current-library-collection-paths] parameter. The list of paths
in @racket[current-library-collection-paths] is searched from first to
collections is determined by the content of @racket[(find-system-path
'links-file)] (if it exists) and the
@racket[current-library-collection-paths] parameter. The collection
links and then list of paths in
@racket[current-library-collection-paths] is searched from first to
last to locate the first that contains @racket[_rel-string]. In other
words, the filesystem tree for each element in the search path is
spliced together with the filesystem trees of other path
elements. Some Racket tools rely on unique resolution of module path
names, so an installation and
words, the filesystem tree for each element in the link table and
search path is spliced together with the filesystem trees of other
path elements. Some Racket tools rely on unique resolution of module
path names, so an installation and
@racket[current-library-collection-paths] configuration should not
allow multiple files to match the same collection and file name.
@ -156,3 +161,46 @@ the directory produced by @racket[(find-system-path 'addon-dir)], are
included in search paths for collections and other files. For example,
@racket[find-library-collection-paths] omits the user-specific
collection directory when this parameter's value is @racket[#f].}
@; ----------------------------------------------------------------------
@section[#:tag "links-file"]{Collection Links}
The @deftech{collection links files} are used by
@racket[collection-file-path], @racket[collection-path], and the
default @tech{module name resolver} to locate collections before
trying the @racket[(current-library-collection-paths)] search
path. Furthermore, a user-specific @tech{collection links file} takes
precedence over an installation-wide @tech{collection links file}, but
the user-specific @tech{collection links file} is used only the
@racket[use-user-specific-search-paths] parameter is set to
@racket[#t].
The path of the user-specific @tech{collection links file} is by
@racket[(find-system-path 'links-file)], while an installation-wide
@tech{collection links file} is @filepath{links.rktd} in the
@filepath{config} collection within the installation's main collection
directory. Each @tech{collection links file} is cached by Racket, but
the file is re-read if its timestamp changes.
Each @tech{collection links file} is @racket[read] with default reader
parameter settings to obtain a list. Every element of the list must be
a link specification with either the form @racket[(_string _path)] or
the form @racket[(_string _path _regexp)]. In both cases, the
@racket[_string] names a top-level @tech{collection}, and
@racket[_path] is a path that can be used as the collection's path
(directly, as opposed to a subdirectory of @racket[_path] named by
@racket[_string]). If @racket[_path] is a relative path, it is
relative to the directory containing the @tech{collection links
file}. If @racket[_regexp] is specified in a link, then the link is
used only if @racket[(regexp-match? _regexp (version))] produces a
true result.
A single top-level collection can have multiple links in a
@tech{collection links file}. The corresponding paths are effectively
spliced together, since the paths are tried in order to locate a file
or sub-collection.
The @exec{raco link} command-link tool can display, install, and
remove links in the @tech{collection links file}. See @secref[#:doc
raco-doc "link"] in @other-manual[raco-doc] for more information.

View File

@ -85,8 +85,17 @@ by @racket[kind], which must be one of the following:
]}
@item{@indexed-racket['links-file] --- the user-specific
@tech{collection links file} for specifying the location of library
@tech{collections}. This file is specified by the
@indexed-envvar{PLTLINKSFILE} environment variable, and it can be
overridden by the @DFlag{links} or @Flag{C} command-line flag. If no
environment variable or flag is specified, or if the value is not a
legal path name, then this file defaults to @filepath{links.rktd} in
the directory reported by @racket[(find-system-path 'addon-dir)].}
@item{@indexed-racket['addon-dir] --- a directory for installing
Racket extensions. This directory is specified by the
user-specific Racket extensions. This directory is specified by the
@indexed-envvar{PLTADDONDIR} environment variable, and it can be
overridden by the @DFlag{addon} or @Flag{A} command-line flag. If no
environment variable or flag is specified, or if the value is not a

View File

@ -91,7 +91,8 @@
(provide margin-note/ref
refalso moreref Guide guideintro guidealso guidesecref
HonuManual)
HonuManual
raco-doc)
(define (margin-note/ref . s)
(apply margin-note
@ -128,6 +129,9 @@
(define HonuManual
(other-manual '(lib "scribblings/honu/honu.scrbl")))
(define raco-doc
'(lib "scribblings/raco/raco.scrbl"))
(provide speed)
(define-syntax speed
(syntax-rules ()

View File

@ -250,6 +250,15 @@ flags:
the @Flag{S}/@DFlag{dir} flag is supplied multiple times, the
search order is as supplied.}
@item{@FlagFirst{A} @nonterm{dir} or @DFlagFirst{addon}
@nonterm{dir} : Sets the directory that is returned by
@racket[(find-system-path 'addon-dir)].}
@item{@FlagFirst{C} @nonterm{file} or @DFlagFirst{links}
@nonterm{file} : Sets the user-specific @tech{collection links file} path
that is returned by @racket[(find-system-path 'links-file)];
see also @secref["links-file"].}
@item{@FlagFirst{U} or @DFlagFirst{no-user-path} : Omits
user-specific paths in the search for collections, C
libraries, etc. by initializing the
@ -405,8 +414,9 @@ language specifies run-time configuration by
A @racket['configure-runtime] query returns a list of vectors, instead
of directly configuring the environment, so that the indicated modules
to be bundled with a program when creating a stand-alone
executable; see @secref[#:doc '(lib "scribblings/raco/raco.scrbl") "exe"].
to be bundled with a program when creating a stand-alone executable;
see @secref[#:doc raco-doc "exe"] in
@other-manual[raco-doc].
For information on defining a new @hash-lang[] language, see
@racketmodname[syntax/module-reader].

View File

@ -3,6 +3,6 @@
(provide (struct-out cc))
(define-struct cc
(collection path name info root-dir info-path shadowing-policy)
(collection path name info omit-root info-root info-path info-path-mode shadowing-policy)
#:inspector #f)

View File

@ -0,0 +1,74 @@
#lang scheme/base
(require racket/cmdline
raco/command-name
"../link.rkt")
(define link-file (make-parameter #f))
(define link-name (make-parameter #f))
(define link-version (make-parameter #f))
(define remove-mode (make-parameter #f))
(define repair-mode (make-parameter #f))
(define show-mode (make-parameter #f))
(define user-mode (make-parameter #t))
(define link-symbol (string->symbol (short-program+command-name)))
(define dirs
(command-line
#:program (short-program+command-name)
#:once-each
[("-s" "--show") "Show the link table (after changes)"
(show-mode #t)]
[("-n" "--name") name "Set the collection name (for a single directory)"
(link-name name)]
[("-x" "--version-regexp") regexp "Set the version pregexp"
(with-handlers ([exn:fail:contract? (lambda (exn)
(raise-user-error link-symbol
"bad version regexp: ~a"
regexp))])
(link-version (pregexp regexp)))]
[("-r" "--remove") "Remove links for the specified directories"
(remove-mode #t)]
#:once-any
[("-i" "--installation") "Adjust user-independent links in the installation"
(user-mode #f)]
[("-f" "--file") file "Select an alternate link file"
(link-file (path->complete-path file))]
#:once-each
[("--repair") "Enable repair mode to fix existing links"
(repair-mode #t)]
#:args
dir dir))
(when (and (link-name)
(not (= 1 (length dirs))))
(raise-user-error link-symbol
"expected a single directory for `--name' mode"))
(define show-both?
(and (null? dirs)
(show-mode)
(user-mode)
(not (remove-mode))
(not (link-file))))
(when show-both?
(printf "User links:\n"))
(void
(apply links
dirs
#:user? (user-mode)
#:file (link-file)
#:name (link-name)
#:version-regexp (link-version)
#:error (lambda (who . args)
(apply raise-user-error link-symbol args))
#:remove? (remove-mode)
#:show? (show-mode)
#:repair? (repair-mode)))
(when show-both?
(printf "Installation links:\n")
(void (links #:user? #f #:show? #t)))

View File

@ -88,6 +88,7 @@
(define preferred-table #f)
(define all-available-table #f)
(define no-planet-table #f)
;; reset-relevant-directories-state! : -> void
(define (reset-relevant-directories-state!)
@ -104,7 +105,8 @@
(list i)
l))))
#f #f))
(set! all-available-table (make-table cons #f #f)))
(set! all-available-table (make-table cons #f #f))
(set! no-planet-table (make-table cons #f #f)))
(reset-relevant-directories-state!)
@ -160,20 +162,23 @@
(define t
(cond [(eq? key 'preferred) preferred-table]
[(eq? key 'all-available) all-available-table]
[(eq? key 'no-planet) no-planet-table]
[else (error 'find-relevant-directories "Invalid key: ~s" key)]))
;; A list of (cons cache.rktd-path root-dir-path)
;; If root-dir-path is not #f, then paths in the cache.rktd
;; file are relative to it. #f is used for the planet cache.rktd file.
(define search-path
(cons (cons user-infotable #f)
((if (eq? key 'no-planet) (lambda (a l) l) cons)
(cons user-infotable #f)
(map (lambda (coll)
(cons (build-path coll "info-domain" "compiled" "cache.rktd")
coll))
(current-library-collection-paths))))
(when t
(unless (equal? (table-paths t) search-path)
(set-table-ht! t (make-hasheq))
(set-table-paths! t search-path)
(populate-table! t))
(populate-table! t)))
(let ([unsorted
(if (= (length syms) 1)
;; Simple case: look up in table
@ -205,7 +210,7 @@
(get-info/full ((path?) (#:namespace (or/c namespace? #f)) . ->* . (or/c info? boolean?)))
(find-relevant-directories
(->* [(listof symbol?)]
[(lambda (x) (memq x '(preferred all-available)))]
[(lambda (x) (memq x '(preferred all-available no-planet)))]
(listof path?)))
(struct directory-record
([maj integer?]
@ -215,5 +220,5 @@
[syms (listof symbol?)]))
(find-relevant-directory-records
(->* [(listof symbol?)]
[(or/c 'preferred 'all-available)]
[(or/c 'preferred 'all-available 'no-planet)]
(listof directory-record?))))

View File

@ -5,4 +5,5 @@
(define mzscheme-launcher-libraries '("main.rkt"))
(define mzscheme-launcher-names '("Setup PLT"))
(define raco-commands '(("setup" setup/main "install and build libraries and documentation" 90)))
(define raco-commands '(("setup" setup/main "install and build libraries and documentation" 90)
("link" setup/commands/link "manage library-collection directories" 80)))

157
collects/setup/link.rkt Normal file
View File

@ -0,0 +1,157 @@
#lang scheme/base
(require racket/file
setup/dirs)
(provide links)
(define (links #:error [error error]
#:user? [user? #t]
#:file [in-file #f]
#:name [name #f]
#:version-regexp [version-regexp #f]
#:remove? [remove? #f]
#:show? [show? #f]
#:repair? [repair? #f]
. dirs)
(define file (or in-file
(if user?
(find-system-path 'links-file)
(let ([d (find-collects-dir)])
(if d
(build-path d "config" "links.rktd")
(error 'links
"cannot find installation collections path"))))))
(define need-repair? #f)
(define (content-error str v)
(if repair?
(begin
(log-warning (format "~a~e" str v))
(set! need-repair? #t)
#f)
(error 'links "~a~e" str v)))
(define table
(with-handlers ([exn:fail?
(lambda (exn)
(let ([msg (format
"error reading from link file: ~s: ~a"
file
(exn-message exn))])
(if repair?
(begin
(log-warning msg)
(set! need-repair? #t)
null)
(error 'links "~a" msg))))])
(if (file-exists? file)
(let ([l (with-input-from-file file read)])
(if (list? l)
(for/list ([e (in-list l)]
#:when
(or (and (list? e)
(or (= 2 (length e))
(= 3 (length e))))
(content-error "entry is a not a 2- or 3-element list: " e))
#:when
(or (string? (car e))
(content-error "entry's first element is not a string: " e))
#:when
(or (path-string? (cadr e))
(content-error "entry's second element is not a path string: " e))
#:when
(or (null? (cddr e))
(regexp? (caddr e))
(content-error "entry's third element is not a version regexp: " e)))
e)
(begin
(content-error "content is not a list: " l)
null)))
null)))
(define mapped (make-hash))
(define (add-entry! e)
(hash-set! mapped
(car e)
(cons (cdr e) (hash-ref mapped (car e) null))))
(for ([e (in-list table)]) (add-entry! e))
(define new-table
(reverse
(for/fold ([table (reverse table)]) ([d (in-list dirs)])
(let* ([dp (path->complete-path d)]
[a-name (or name
(let-values ([(base name dir?) (split-path dp)])
(path-element->string name)))]
[rx version-regexp]
[d (path->string dp)])
(unless remove?
(unless (directory-exists? dp)
(error 'links
"no such directory for link: ~a"
dp)))
(if remove?
(filter (lambda (e)
(or (not (equal? (cadr e) d))
(and name
(not (equal? (car e) name)))
(and version-regexp
(pair? (cddr e))
(not (equal? (caddr e) version-regexp)))))
table)
(let ([l (hash-ref mapped a-name null)]
[e (list* a-name
d
(if rx (list rx) null))])
(if (member (cdr e) l)
table
(let ()
(add-entry! e)
(cons e table)))))))))
(unless (and (not need-repair?)
(equal? new-table table))
(let ([dir (let-values ([(base name dir?) (split-path file)])
base)])
(make-directory* dir)
(let ([tmp (make-temporary-file "links~a.rktd"
#f
dir)])
(with-output-to-file tmp
#:exists 'truncate
(lambda ()
(printf "(")
(let loop ([l new-table] [prefix ""])
(cond
[(null? l) (printf ")\n")]
[else
(printf "~a~s" prefix (car l))
(unless (null? (cdr l)) (newline))
(loop (cdr l) " ")]))))
(with-handlers ([exn:fail? (lambda (exn)
(with-handlers ([exn:fail? void])
(delete-file tmp))
(raise exn))])
(rename-file-or-directory tmp file #t)))))
(when show?
(for ([e (in-list new-table)])
(printf " collection: ~s path: ~s~a\n"
(car e)
(cadr e)
(if (null? (cddr e))
""
(format " version: ~s"
(caddr e))))))
;; Return list of collections mapped for this version:
(let ([ht (make-hash)])
(for ([e (in-list new-table)])
(when (or (null? (cddr e))
(regexp-match? (caddr e) (version)))
(hash-set! ht (car e) #t)))
(hash-map ht (lambda (k e) k))))

View File

@ -82,7 +82,7 @@
implicit?
get-info/full)))))))
(define (omitted-paths* dir get-info/full)
(define (omitted-paths* dir get-info/full root-dir)
(unless (and (path-string? dir) (complete-path? dir) (directory-exists? dir))
(raise-type-error 'omitted-paths
"complete path to an existing directory" dir))
@ -90,8 +90,13 @@
[r (ormap (lambda (root+table)
(let ([r (relative-from dir* (car root+table))])
(and r (cons (reverse r) root+table))))
(force roots))]
(if root-dir
(list (list (explode-path root-dir)
(make-hash)
#t))
(force roots)))]
[r (and r (apply accumulate-omitted get-info/full r))])
(unless r
(error 'omitted-paths
"given directory path is not in any collection root: ~e" dir))
@ -101,5 +106,5 @@
(define omitted-paths-memo (make-hash))
(define (omitted-paths dir get-info/full)
(with-memo omitted-paths-memo dir (omitted-paths* dir get-info/full)))
(define (omitted-paths dir get-info/full [root-dir #f])
(with-memo omitted-paths-memo dir (omitted-paths* dir get-info/full root-dir)))

View File

@ -5,7 +5,7 @@
(provide doc-path)
;; user-doc-mode can be `false-if-missing' or `never'
(define (doc-path dir name flags [user-doc-mode #f])
(define (doc-path dir name flags under-main? [user-doc-mode #f])
(define (user-doc [sub #f])
(and (not (eq? 'never user-doc-mode))
(let ([d (find-user-doc-dir)])
@ -15,6 +15,6 @@
(cond [(memq 'main-doc-root flags) (find-doc-dir)]
[(memq 'user-doc-root flags) (user-doc)]
[(memq 'user-doc flags) (user-doc name)]
[(or (memq 'main-doc flags) (pair? (path->main-collects-relative dir)))
[(or under-main? (memq 'main-doc flags) (pair? (path->main-collects-relative dir)))
(build-path (find-doc-dir) name)]
[else (build-path dir "doc" name)]))

View File

@ -95,7 +95,7 @@
(apply validate i)))
infos)])
(and (not (memq #f infos)) infos))))
(define (get-docs i rec)
(define ((get-docs main-dirs) i rec)
(let ([s (validate-scribblings-infos (i 'scribblings))]
[dir (directory-record-path rec)])
(if s
@ -106,6 +106,7 @@
(not (memq 'user-doc-root flags))
(not (memq 'user-doc flags))
(or (memq 'main-doc flags)
(hash-ref main-dirs dir #f)
(pair? (path->main-collects-relative dir))))])
(make-doc dir
(let ([spec (directory-record-spec rec)])
@ -117,7 +118,7 @@
(list '= (directory-record-min rec)))))
(cdr spec))))
(build-path dir (car d))
(doc-path dir (cadddr d) flags)
(doc-path dir (cadddr d) flags under-main?)
flags under-main? (caddr d))))
s)
(begin (setup-printf
@ -126,8 +127,12 @@
null))))
(define docs
(let* ([recs (find-relevant-directory-records '(scribblings) 'all-available)]
[main-dirs (parameterize ([current-library-collection-paths
(list (find-collects-dir))])
(for/hash ([k (in-list (find-relevant-directories '(scribblings) 'no-planet))])
(values k #t)))]
[infos (map get-info/full (map directory-record-path recs))])
(filter-user-docs (append-map get-docs infos recs) make-user?)))
(filter-user-docs (append-map (get-docs main-dirs) infos recs) make-user?)))
(define-values (main-docs user-docs) (partition doc-under-main? docs))
(define (can-build*? docs) (can-build? only-dirs docs))
(define auto-main? (and auto-start-doc? (ormap can-build*? main-docs)))

View File

@ -1,3 +1,4 @@
;; Expects parameters to be set before invocation.
;; Calls `exit' when done.
@ -27,7 +28,8 @@
"path-to-relative.rkt"
"private/omitted-paths.rkt"
"parallel-build.rkt"
"collects.rkt")
"collects.rkt"
"link.rkt")
(define-namespace-anchor anchor)
;; read info files using whatever namespace, .zo-use, and compilation
@ -168,7 +170,7 @@
;; Find Collections ;;
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (make-cc* collection path root-dir info-path shadowing-policy)
(define (make-cc* collection path omit-root info-root info-path info-path-mode shadowing-policy)
(define info
(or (with-handlers ([exn:fail? (warning-handler #f)]) (getinfo path))
(lambda (flag mk-default) (mk-default))))
@ -186,12 +188,15 @@
"ignoring `compile-subcollections' entry in info ~a"
path-name))
;; this check is also done in compiler/compiler-unit, in compile-directory
(and (not (eq? 'all (omitted-paths path getinfo)))
(and (not (eq? 'all (omitted-paths path getinfo omit-root)))
(make-cc collection path
(if name
(format "~a (~a)" path-name name)
path-name)
info root-dir info-path shadowing-policy)))
info
omit-root
info-root info-path info-path-mode
shadowing-policy)))
(define ((warning-handler v) exn)
(setup-printf "WARNING" "~a" (exn->string exn))
@ -199,23 +204,39 @@
;; collection->cc : listof path -> cc/#f
(define collection->cc-table (make-hash))
(define (collection->cc collection-p)
(define (collection->cc collection-p
#:omit-root [omit-root #f]
#:info-root [given-info-root #f]
#:info-path [info-path #f]
#:info-path-mode [info-path-mode 'relative])
(hash-ref! collection->cc-table collection-p
(lambda ()
(define root-dir
(define info-root
(or given-info-root
(ormap (lambda (p)
(parameterize ([current-library-collection-paths (list p)])
(parameterize ([current-library-collection-paths (list p)]
;; to disable collection links file:
[use-user-specific-search-paths #f])
(and (with-handlers ([exn:fail? (lambda (x) #f)])
(apply collection-path collection-p))
p)))
(current-library-collection-paths)))
(current-library-collection-paths))))
(let ([dir (apply collection-path collection-p)])
(unless (directory-exists? dir)
(error name-sym "directory does not exist for collection: ~s"
(string-join (map path->string collection-p) "/")))
(make-cc* collection-p
(apply collection-path collection-p)
root-dir
(build-path root-dir "info-domain" "compiled" "cache.rktd")
dir
(if (eq? omit-root 'dir)
dir
omit-root) ; #f => `omitted-paths' can reconstruct it
info-root
(or info-path
(build-path info-root "info-domain" "compiled" "cache.rktd"))
info-path-mode
;; by convention, all collections have "version" 1 0. This
;; forces them to conflict with each other.
(list (cons 'lib (map path->string collection-p)) 1 0)))))
(list (cons 'lib (map path->string collection-p)) 1 0))))))
;; planet-spec->planet-list : (list string string nat nat) -> (list path string string (listof string) nat nat) | #f
;; converts a planet package spec into the information needed to create a cc structure
@ -241,8 +262,10 @@
(and (directory-exists? path)
(make-cc* #f
path
#f ; don't need root-dir; absolute paths in cache.rktd will be ok
path
#f ; don't need info-root; absolute paths in cache.rktd will be ok
(get-planet-cache-path)
'abs
(list `(planet ,owner ,pkg-file ,@extra-path) maj min))))
;; planet-cc->sub-cc : cc (listof bytes [encoded path]) -> cc
@ -268,6 +291,23 @@
(lambda ()
(let ([cc (collection->cc (list collection))])
(when cc (hash-set! ht collection cc))))))
(let ([main-collects (find-collects-dir)])
(for ([c (in-list (links #:user? #f))])
(let* ([c (string->path c)]
[cc (collection->cc (list c)
#:info-root main-collects
#:info-path-mode 'abs-in-relative
#:omit-root 'dir)])
(when cc (hash-set! ht c cc)))))
(when (make-user)
(let ([user-collects (find-user-collects-dir)])
(for ([c (in-list (links))])
(let* ([c (string->path c)]
[cc (collection->cc (list c)
#:info-root user-collects
#:info-path-mode 'abs-in-relative
#:omit-root 'dir)])
(when cc (hash-set! ht c cc))))))
(hash-map ht (lambda (k v) v))))
;; Close over sub-collections
@ -279,7 +319,7 @@
;; collection should not have been included, but we might
;; jump in if a command-line argument specified a
;; coll/subcoll
[omit (omitted-paths ccp getinfo)]
[omit (omitted-paths ccp getinfo (cc-omit-root cc))]
[subs (if (eq? 'all omit)
'()
(filter (lambda (p)
@ -292,7 +332,8 @@
(append-map (lambda (cc) (cons cc (loop (get-subs cc)))) l))))
(define (collection-tree-map collections-to-compile
#:skip-path [orig-skip-path (and (avoid-main-installation) (find-collects-dir))])
#:skip-path [orig-skip-path (and (avoid-main-installation)
(find-collects-dir))])
(define skip-path (and orig-skip-path (path->bytes
(simplify-path (if (string? orig-skip-path)
(string->path orig-skip-path)
@ -308,14 +349,18 @@
(define (build-collection-tree cc)
(define (make-child-cc parent-cc name)
(collection->cc (append (cc-collection parent-cc) (list name))))
(collection->cc (append (cc-collection parent-cc) (list name))
#:info-root (cc-info-root cc)
#:info-path (cc-info-path cc)
#:info-path-mode (cc-info-path-mode cc)
#:omit-root (cc-omit-root cc)))
(let* ([info (cc-info cc)]
[ccp (cc-path cc)]
;; note: omit can be 'all, if this happens then this
;; collection should not have been included, but we might
;; jump in if a command-line argument specified a
;; coll/subcoll
[omit (omitted-paths ccp getinfo)])
[omit (omitted-paths ccp getinfo (cc-omit-root cc))])
(let-values ([(dirs files)
(if (eq? 'all omit)
(values null null)
@ -325,7 +370,6 @@
(skip-path? p))))
(directory-list ccp))))])
(let ([children-ccs (map build-collection-tree (filter-map (lambda (x) (make-child-cc cc x)) dirs))]
[srcs (append
(filter extract-base-filename/ss files)
(if (make-docs)
@ -342,7 +386,11 @@
(define (plt-collection-closure collections-to-compile)
(define (make-children-ccs cc children)
(map (lambda (child)
(collection->cc (append (cc-collection cc) (list child))))
(collection->cc (append (cc-collection cc) (list child))
#:info-root (cc-info-root cc)
#:info-path (cc-info-path cc)
#:info-path-mode (cc-info-path-mode cc)
#:omit-root (cc-omit-root cc)))
children))
(collection-closure collections-to-compile make-children-ccs))
@ -668,6 +716,7 @@
[info (cc-info cc)])
(clean-cc dir info)
(compile-directory-zos dir info
#:omit-root (cc-omit-root cc)
#:managed-compile-zo caching-managed-compile-zo
#:skip-path (and (avoid-main-installation) (find-collects-dir))
#:skip-doc-sources? (not (make-docs))))))))
@ -748,7 +797,7 @@
(warning-handler null)])
(with-input-from-file p read))
null))])
;; Convert list to hash table. Incluse only well-formed
;; Convert list to hash table. Include only well-formed
;; list elements, and only elements whose corresponding
;; collection exists.
(let ([t (make-hash)]
@ -757,28 +806,32 @@
(set! all-ok? #t)
(for ([i l])
(match i
[(list
(? (lambda (a)
(and (bytes? a)
[(list (? bytes? a) (list (? symbol? b) ...) c (? integer? d) (? integer? e))
(let ([p (bytes->path a)])
;; If we have a root directory,
;; then the path must be relative
;; to it, otherwise it must be
;; absolute:
(and (if (cc-root-dir cc)
(relative-path? p)
(complete-path? p))
(let ([dir (if (cc-root-dir cc)
(build-path (cc-root-dir cc) p)
p)])
;; Check that the path is suitably absolute or relative:
(let ([dir (case (cc-info-path-mode cc)
[(relative abs-in-relative)
(or (and (relative-path? p)
(build-path (cc-info-root cc) p))
(and (complete-path? p)
;; `c' must be `(lib ...)'
(list? c)
(pair? c)
(eq? 'lib (car c))
(pair? (cdr c))
(andmap string? (cdr c))
;; Path must match collection resolution:
(with-handlers ([exn:fail? (lambda (exn) #f)])
(equal? p (apply collection-path (cdr c))))
p))]
[(abs)
(and (complete-path? p)
p)])])
(if (and dir
(or (file-exists? (build-path dir "info.rkt"))
(file-exists? (build-path dir "info.ss"))))))))
a)
(list (? symbol? b) ...)
c
(? integer? d)
(? integer? e))
(hash-set! t a (list b c d e))]
(file-exists? (build-path dir "info.ss"))))
(hash-set! t a (list b c d e))
(set! all-ok? #f))))]
[_ (set! all-ok? #f)])))
;; Record the table loaded for this collection root
;; in the all-roots table:
@ -792,7 +845,7 @@
;; Add this collection's info to the table, replacing any information
;; already there.
(hash-set! t
(path->bytes (if (cc-root-dir cc)
(path->bytes (if (eq? (cc-info-path-mode cc) 'relative)
;; Use relative path:
(apply build-path (cc-collection cc))
;; Use absolute path:
@ -802,11 +855,7 @@
(hash-for-each ht
(lambda (info-path ht)
(unless (equal? ht (hash-ref ht-orig info-path))
(let-values ([(base name must-be-dir?) (split-path info-path)])
(unless (path? base)
(error 'make-info-domain
"Internal error: cc had invalid info-path: ~e"
info-path))
(define-values (base name dir?) (split-path info-path))
(make-directory* base)
(let ([p info-path])
(setup-printf "updating" "~a" (path->relative-string/setup p))
@ -815,7 +864,7 @@
#:exists 'truncate/replace
(lambda ()
(write (hash-map ht cons))
(newline)))))))))))
(newline))))))))))
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Docs ;;

View File

@ -3,6 +3,7 @@
(require scribble/xref
scheme/fasl
scheme/path
setup/dirs
"getinfo.rkt"
"private/path-utils.rkt")
@ -11,6 +12,12 @@
(define cached-xref #f)
(define (get-dests)
(define main-dirs
(parameterize ([current-library-collection-paths
(let ([d (find-collects-dir)])
(if d (list d) null))])
(for/hash ([k (in-list (find-relevant-directories '(scribblings) 'no-planet))])
(values k #t))))
(for*/list ([dir (find-relevant-directories '(scribblings) 'all-available)]
[d ((get-info/full dir) 'scribblings)])
(unless (and (list? d) (pair? d))
@ -23,7 +30,7 @@
(path-replace-suffix (file-name-from-path (car d))
#"")))])
(and (not (and (len . >= . 3) (memq 'omit (caddr d))))
(let* ([d (doc-path dir name flags 'false-if-missing)]
(let* ([d (doc-path dir name flags (hash-ref main-dirs dir #f) 'false-if-missing)]
[p (and d (build-path d "out.sxref"))])
(and p (file-exists? p) p))))))

View File

@ -1,3 +1,7 @@
Version 5.1.3.4
Add support for the collection links file, including
(find-system-path 'links-file) and the raco link command
Version 5.1.3.3
unsafe/ffi: added support for C arrays and unions

View File

@ -556,6 +556,7 @@ static int run_from_cmd_line(int argc, char *_argv[],
char *prog, *sprog = NULL;
Scheme_Object *sch_argv;
Scheme_Object *collects_path = NULL, *collects_extra = NULL, *addon_dir = NULL;
Scheme_Object *links_file = NULL;
#ifndef NO_FILE_SYSTEM_UTILS
Scheme_Object *collects_paths_l, *collects_paths_r;
#endif
@ -804,6 +805,8 @@ static int run_from_cmd_line(int argc, char *_argv[],
argv[0] = "-S";
else if (!strcmp("--addon", argv[0]))
argv[0] = "-A";
else if (!strcmp("--links", argv[0]))
argv[0] = "-C";
# ifdef CMDLINE_STDIO_FLAG
else if (!strcmp("--stdio", argv[0]))
argv[0] = "-z";
@ -860,6 +863,17 @@ static int run_from_cmd_line(int argc, char *_argv[],
addon_dir = scheme_make_path(argv[0]);
was_config_flag = 1;
break;
case 'C':
if (argc < 2) {
PRINTF("%s: missing path after %s switch\n",
prog, real_switch);
goto show_need_help;
}
argv++;
--argc;
links_file = scheme_make_path(argv[0]);
was_config_flag = 1;
break;
case 'U':
scheme_set_ignore_user_paths(1);
was_config_flag = 1;
@ -1204,7 +1218,28 @@ static int run_from_cmd_line(int argc, char *_argv[],
}
}
# endif
if (addon_dir) scheme_set_addon_dir(addon_dir);
if (addon_dir) {
addon_dir = scheme_path_to_complete_path(addon_dir, NULL);
scheme_set_addon_dir(addon_dir);
}
#endif /* NO_FILE_SYSTEM_UTILS */
#ifndef NO_FILE_SYSTEM_UTILS
/* Setup path for "links" file: */
# ifdef GETENV_FUNCTION
if (!links_file) {
char *s;
s = getenv("PLTLINKSFILE");
if (s) {
s = scheme_expand_filename(s, -1, NULL, NULL, 0);
if (s) links_file = scheme_make_path(s);
}
}
# endif
if (links_file) {
links_file = scheme_path_to_complete_path(links_file, NULL);
scheme_set_links_file(links_file);
}
#endif /* NO_FILE_SYSTEM_UTILS */
/* Creates the main kernel environment */
@ -1292,6 +1327,7 @@ static int run_from_cmd_line(int argc, char *_argv[],
" -X <dir>, --collects <dir> : Main collects at <dir>\n"
" -S <dir>, --search <dir> : More collects at <dir> (after main collects)\n"
" -A <dir>, --addon <dir> : Addon directory at <dir>\n"
" -K <file>, --links <file> : Collection links at <file>\n"
" -U, --no-user-path : Ignore user-specific collects, etc.\n"
" -N <file>, --name <file> : Sets `(find-system-path 'run-file)' to <file>\n"
# ifdef MZ_USE_JIT

View File

@ -1801,6 +1801,7 @@ MZ_EXTERN Scheme_Object *scheme_set_run_cmd(char *s);
MZ_EXTERN void scheme_set_collects_path(Scheme_Object *p);
MZ_EXTERN void scheme_set_original_dir(Scheme_Object *d);
MZ_EXTERN void scheme_set_addon_dir(Scheme_Object *p);
MZ_EXTERN void scheme_set_links_file(Scheme_Object *p);
MZ_EXTERN void scheme_set_command_line_arguments(Scheme_Object *vec);
MZ_EXTERN void scheme_set_compiled_file_paths(Scheme_Object *list);

View File

@ -273,6 +273,7 @@ typedef struct Thread_Local_Variables {
int env_uid_counter_;
int scheme_overflow_count_;
struct Scheme_Object *original_pwd_;
struct Scheme_Object *inst_links_path_;
void *file_path_wc_buffer_;
intptr_t scheme_hash_request_count_;
intptr_t scheme_hash_iteration_count_;
@ -605,6 +606,7 @@ XFORM_GC_VARIABLE_STACK_THROUGH_THREAD_LOCAL;
#define env_uid_counter XOA (scheme_get_thread_local_variables()->env_uid_counter_)
#define scheme_overflow_count XOA (scheme_get_thread_local_variables()->scheme_overflow_count_)
#define original_pwd XOA (scheme_get_thread_local_variables()->original_pwd_)
#define inst_links_path XOA (scheme_get_thread_local_variables()->inst_links_path_)
#define file_path_wc_buffer XOA (scheme_get_thread_local_variables()->file_path_wc_buffer_)
#define scheme_hash_request_count XOA (scheme_get_thread_local_variables()->scheme_hash_request_count_)
#define scheme_hash_iteration_count XOA (scheme_get_thread_local_variables()->scheme_hash_iteration_count_)

View File

@ -1,5 +1,5 @@
{
SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,49,46,51,46,50,0,0,0,0,0,0,0,0,0,0,0,
SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,49,46,51,46,53,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,51,0,0,0,1,0,0,10,0,13,0,22,
0,26,0,31,0,38,0,51,0,58,0,63,0,68,0,72,0,79,0,82,0,
85,0,91,0,105,0,119,0,122,0,128,0,132,0,134,0,145,0,147,0,161,
@ -15,12 +15,12 @@
116,120,61,115,70,108,101,116,45,118,97,108,117,101,115,61,120,73,108,101,116,
114,101,99,45,118,97,108,117,101,115,66,108,97,109,98,100,97,1,20,112,97,
114,97,109,101,116,101,114,105,122,97,116,105,111,110,45,107,101,121,61,118,73,
100,101,102,105,110,101,45,118,97,108,117,101,115,97,36,11,8,240,72,76,0,
100,101,102,105,110,101,45,118,97,108,117,101,115,97,36,11,8,240,112,76,0,
0,95,159,2,17,36,36,159,2,16,36,36,159,2,16,36,36,16,20,2,4,
2,2,2,6,2,2,2,7,2,2,2,8,2,2,2,9,2,2,2,10,2,
2,2,2,6,2,2,2,8,2,2,2,7,2,2,2,9,2,2,2,10,2,
2,2,11,2,2,2,5,2,2,2,12,2,2,2,13,2,2,97,37,11,8,
240,72,76,0,0,93,159,2,16,36,37,16,2,2,3,161,2,2,37,2,3,
2,2,2,3,96,38,11,8,240,72,76,0,0,16,0,96,11,11,8,240,72,
240,112,76,0,0,93,159,2,16,36,37,16,2,2,3,161,2,2,37,2,3,
2,2,2,3,96,11,11,8,240,112,76,0,0,16,0,96,38,11,8,240,112,
76,0,0,16,0,18,98,64,104,101,114,101,13,16,5,36,2,14,2,2,11,
11,8,32,8,31,8,30,8,29,27,248,22,155,4,195,249,22,148,4,80,158,
39,36,251,22,83,2,18,248,22,98,199,12,249,22,73,2,19,248,22,100,201,
@ -30,14 +30,14 @@
74,193,249,22,148,4,80,158,39,36,251,22,83,2,18,248,22,74,199,249,22,
73,2,11,248,22,75,201,11,18,100,10,13,16,5,36,2,14,2,2,11,11,
8,32,8,31,8,30,8,29,16,4,11,11,2,20,3,1,8,101,110,118,49,
52,55,51,57,16,4,11,11,2,21,3,1,8,101,110,118,49,52,55,52,48,
52,55,57,57,16,4,11,11,2,21,3,1,8,101,110,118,49,52,56,48,48,
27,248,22,75,248,22,155,4,196,28,248,22,81,193,20,14,159,37,36,37,28,
248,22,81,248,22,75,194,248,22,74,193,249,22,148,4,80,158,39,36,250,22,
83,2,22,248,22,83,249,22,83,248,22,83,2,23,248,22,74,201,251,22,83,
2,18,2,23,2,23,249,22,73,2,13,248,22,75,204,18,100,11,13,16,5,
36,2,14,2,2,11,11,8,32,8,31,8,30,8,29,16,4,11,11,2,20,
3,1,8,101,110,118,49,52,55,52,50,16,4,11,11,2,21,3,1,8,101,
110,118,49,52,55,52,51,248,22,155,4,193,27,248,22,155,4,194,249,22,73,
3,1,8,101,110,118,49,52,56,48,50,16,4,11,11,2,21,3,1,8,101,
110,118,49,52,56,48,51,248,22,155,4,193,27,248,22,155,4,194,249,22,73,
248,22,83,248,22,74,196,248,22,75,195,27,248,22,75,248,22,155,4,23,197,
1,249,22,148,4,80,158,39,36,28,248,22,58,248,22,149,4,248,22,74,23,
198,2,27,249,22,2,32,0,88,163,8,36,37,43,11,9,222,33,40,248,22,
@ -67,8 +67,8 @@
140,9,248,22,149,4,248,22,74,200,64,101,108,115,101,10,248,22,74,197,250,
22,84,2,22,9,248,22,75,200,249,22,73,2,5,248,22,75,202,99,13,16,
5,36,2,14,2,2,11,11,8,32,8,31,8,30,8,29,16,4,11,11,2,
20,3,1,8,101,110,118,49,52,55,54,53,16,4,11,11,2,21,3,1,8,
101,110,118,49,52,55,54,54,18,158,94,10,64,118,111,105,100,8,48,27,248,
20,3,1,8,101,110,118,49,52,56,50,53,16,4,11,11,2,21,3,1,8,
101,110,118,49,52,56,50,54,18,158,94,10,64,118,111,105,100,8,48,27,248,
22,75,248,22,155,4,196,249,22,148,4,80,158,39,36,28,248,22,58,248,22,
149,4,248,22,74,197,250,22,83,2,28,248,22,83,248,22,74,199,248,22,98,
198,27,248,22,149,4,248,22,74,197,250,22,83,2,28,248,22,83,248,22,74,
@ -98,410 +98,496 @@
EVAL_ONE_SIZED_STR((char *)expr, 2004);
}
{
SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,49,46,51,46,50,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,82,0,0,0,1,0,0,8,0,21,0,26,
0,43,0,58,0,76,0,92,0,106,0,128,0,146,0,166,0,182,0,200,0,
231,0,4,1,26,1,40,1,46,1,60,1,65,1,75,1,83,1,111,1,143,
1,188,1,194,1,201,1,207,1,252,1,20,2,59,2,73,2,76,2,79,2,
89,2,100,2,113,2,115,2,117,2,27,3,117,4,231,4,89,5,130,5,203,
6,33,7,119,7,219,7,47,8,61,8,194,8,168,9,252,9,10,10,31,11,
235,11,249,11,141,16,156,17,45,18,30,19,12,20,19,20,98,20,179,20,122,
21,136,21,146,21,187,22,33,23,56,23,73,23,21,25,124,25,138,25,42,26,
235,27,244,27,253,27,23,28,151,28,0,0,2,32,0,0,67,35,37,117,116,
105,108,115,72,112,97,116,104,45,115,116,114,105,110,103,63,64,98,115,98,115,
76,110,111,114,109,97,108,45,99,97,115,101,45,112,97,116,104,74,45,99,104,
101,99,107,45,114,101,108,112,97,116,104,77,45,99,104,101,99,107,45,99,111,
108,108,101,99,116,105,111,110,75,99,111,108,108,101,99,116,105,111,110,45,112,
97,116,104,73,102,105,110,100,45,99,111,108,45,102,105,108,101,1,20,99,111,
108,108,101,99,116,105,111,110,45,102,105,108,101,45,112,97,116,104,77,99,104,
101,99,107,45,115,117,102,102,105,120,45,99,97,108,108,79,112,97,116,104,45,
114,101,112,108,97,99,101,45,115,117,102,102,105,120,75,112,97,116,104,45,97,
100,100,45,115,117,102,102,105,120,77,108,111,97,100,47,117,115,101,45,99,111,
109,112,105,108,101,100,1,29,102,105,110,100,45,108,105,98,114,97,114,121,45,
99,111,108,108,101,99,116,105,111,110,45,112,97,116,104,115,1,27,112,97,116,
104,45,108,105,115,116,45,115,116,114,105,110,103,45,62,112,97,116,104,45,108,
105,115,116,1,20,102,105,110,100,45,101,120,101,99,117,116,97,98,108,101,45,
112,97,116,104,73,101,109,98,101,100,100,101,100,45,108,111,97,100,65,113,117,
111,116,101,29,94,2,18,68,35,37,112,97,114,97,109,122,11,64,108,111,111,
112,69,101,120,101,99,45,102,105,108,101,67,119,105,110,100,111,119,115,6,25,
25,112,97,116,104,32,111,114,32,118,97,108,105,100,45,112,97,116,104,32,115,
116,114,105,110,103,6,29,29,126,97,58,32,105,110,118,97,108,105,100,32,114,
101,108,97,116,105,118,101,32,112,97,116,104,58,32,126,115,6,42,42,126,97,
58,32,99,111,108,108,101,99,116,105,111,110,32,110,111,116,32,102,111,117,110,
100,58,32,126,115,32,105,110,32,97,110,121,32,111,102,58,32,126,115,65,99,
108,111,111,112,6,4,4,46,114,107,116,6,3,3,46,115,115,6,42,42,112,
97,116,104,32,40,102,111,114,32,97,110,121,32,115,121,115,116,101,109,41,32,
111,114,32,118,97,108,105,100,45,112,97,116,104,32,115,116,114,105,110,103,6,
21,21,115,116,114,105,110,103,32,111,114,32,98,121,116,101,32,115,116,114,105,
110,103,6,36,36,99,97,110,110,111,116,32,97,100,100,32,97,32,115,117,102,
102,105,120,32,116,111,32,97,32,114,111,111,116,32,112,97,116,104,58,32,6,
11,11,80,76,84,67,79,76,76,69,67,84,83,6,0,0,6,0,0,69,97,
100,100,111,110,45,100,105,114,6,8,8,99,111,108,108,101,99,116,115,72,99,
111,108,108,101,99,116,115,45,100,105,114,5,0,5,0,27,20,13,159,80,159,
37,52,37,250,80,159,40,53,37,249,22,27,11,80,159,42,52,37,22,186,13,
10,248,22,190,5,23,196,2,28,248,22,189,6,23,194,2,12,86,94,248,22,
148,9,23,194,1,27,20,13,159,80,159,38,52,37,250,80,159,41,53,37,249,
22,27,11,80,159,43,52,37,22,186,13,10,248,22,190,5,23,197,2,28,248,
22,189,6,23,194,2,12,86,94,248,22,148,9,23,194,1,27,20,13,159,80,
159,39,52,37,250,80,159,42,53,37,249,22,27,11,80,159,44,52,37,22,186,
13,10,248,22,190,5,23,198,2,28,248,22,189,6,23,194,2,12,86,94,248,
22,148,9,23,194,1,248,80,159,40,57,39,197,28,248,22,81,23,195,2,9,
27,248,22,74,23,196,2,27,28,248,22,172,14,23,195,2,23,194,1,28,248,
22,171,14,23,195,2,249,22,173,14,23,196,1,250,80,158,43,50,248,22,188,
14,2,21,11,10,250,80,158,41,50,248,22,188,14,2,21,23,197,1,10,28,
23,193,2,249,22,73,248,22,175,14,249,22,173,14,23,198,1,247,22,189,14,
27,248,22,75,23,200,1,28,248,22,81,23,194,2,9,27,248,22,74,23,195,
SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,49,46,51,46,53,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,107,0,0,0,1,0,0,8,0,21,0,26,
0,43,0,65,0,94,0,109,0,127,0,143,0,157,0,179,0,195,0,212,0,
234,0,245,0,251,0,4,1,11,1,18,1,30,1,46,1,70,1,102,1,120,
1,140,1,156,1,174,1,205,1,219,1,224,1,234,1,242,1,251,1,253,1,
255,1,27,2,59,2,72,2,78,2,117,2,121,2,166,2,190,2,229,2,243,
2,246,2,249,2,3,3,14,3,181,3,25,5,143,5,5,6,46,6,119,7,
142,7,159,7,107,9,210,9,224,9,128,10,57,12,66,12,75,12,89,12,99,
12,140,13,242,13,72,14,158,14,2,15,86,15,100,15,214,15,42,16,56,16,
9,17,17,17,123,17,172,17,174,17,18,18,78,18,83,18,189,18,10,19,168,
20,190,20,199,20,192,21,210,21,224,21,183,22,202,22,140,25,4,30,110,30,
255,30,240,31,222,32,229,32,54,33,137,33,222,33,248,33,121,34,0,0,221,
38,0,0,67,35,37,117,116,105,108,115,72,112,97,116,104,45,115,116,114,105,
110,103,63,64,98,115,98,115,76,110,111,114,109,97,108,45,99,97,115,101,45,
112,97,116,104,1,20,102,105,110,100,45,101,120,101,99,117,116,97,98,108,101,
45,112,97,116,104,1,27,112,97,116,104,45,108,105,115,116,45,115,116,114,105,
110,103,45,62,112,97,116,104,45,108,105,115,116,74,45,99,104,101,99,107,45,
114,101,108,112,97,116,104,77,45,99,104,101,99,107,45,99,111,108,108,101,99,
116,105,111,110,75,99,111,108,108,101,99,116,105,111,110,45,112,97,116,104,73,
102,105,110,100,45,99,111,108,45,102,105,108,101,1,20,99,111,108,108,101,99,
116,105,111,110,45,102,105,108,101,45,112,97,116,104,75,117,115,101,114,45,108,
105,110,107,115,45,112,97,116,104,76,117,115,101,114,45,108,105,110,107,115,45,
99,97,99,104,101,1,20,117,115,101,114,45,108,105,110,107,115,45,116,105,109,
101,115,116,97,109,112,70,108,105,110,107,115,45,112,97,116,104,65,113,117,111,
116,101,68,35,37,112,97,114,97,109,122,29,94,2,16,2,17,11,29,94,2,
16,2,17,11,71,108,105,110,107,115,45,99,97,99,104,101,75,108,105,110,107,
115,45,116,105,109,101,115,116,97,109,112,1,22,103,101,116,45,108,105,110,107,
101,100,45,99,111,108,108,101,99,116,105,111,110,115,1,30,110,111,114,109,97,
108,105,122,101,45,99,111,108,108,101,99,116,105,111,110,45,114,101,102,101,114,
101,110,99,101,77,99,104,101,99,107,45,115,117,102,102,105,120,45,99,97,108,
108,79,112,97,116,104,45,114,101,112,108,97,99,101,45,115,117,102,102,105,120,
75,112,97,116,104,45,97,100,100,45,115,117,102,102,105,120,77,108,111,97,100,
47,117,115,101,45,99,111,109,112,105,108,101,100,1,29,102,105,110,100,45,108,
105,98,114,97,114,121,45,99,111,108,108,101,99,116,105,111,110,45,112,97,116,
104,115,73,101,109,98,101,100,100,101,100,45,108,111,97,100,64,108,111,111,112,
69,101,120,101,99,45,102,105,108,101,67,119,105,110,100,111,119,115,68,114,101,
108,97,116,105,118,101,5,0,5,0,6,25,25,112,97,116,104,32,111,114,32,
118,97,108,105,100,45,112,97,116,104,32,115,116,114,105,110,103,6,29,29,126,
97,58,32,105,110,118,97,108,105,100,32,114,101,108,97,116,105,118,101,32,112,
97,116,104,58,32,126,115,72,99,111,108,108,101,99,116,115,45,100,105,114,65,
101,114,114,111,114,6,36,36,101,114,114,111,114,32,114,101,97,100,105,110,103,
32,108,105,110,107,101,100,32,99,111,108,108,101,99,116,105,111,110,115,58,32,
126,97,6,1,1,47,6,42,42,112,97,116,104,32,40,102,111,114,32,97,110,
121,32,115,121,115,116,101,109,41,32,111,114,32,118,97,108,105,100,45,112,97,
116,104,32,115,116,114,105,110,103,6,21,21,115,116,114,105,110,103,32,111,114,
32,98,121,116,101,32,115,116,114,105,110,103,6,36,36,99,97,110,110,111,116,
32,97,100,100,32,97,32,115,117,102,102,105,120,32,116,111,32,97,32,114,111,
111,116,32,112,97,116,104,58,32,6,11,11,80,76,84,67,79,76,76,69,67,
84,83,6,0,0,6,0,0,69,97,100,100,111,110,45,100,105,114,6,8,8,
99,111,108,108,101,99,116,115,27,20,13,159,80,159,37,51,37,250,80,159,40,
52,37,249,22,27,11,80,159,42,51,37,22,186,13,10,248,22,190,5,23,196,
2,28,248,22,189,6,23,194,2,12,86,94,248,22,148,9,23,194,1,27,20,
13,159,80,159,38,51,37,250,80,159,41,52,37,249,22,27,11,80,159,43,51,
37,22,186,13,10,248,22,190,5,23,197,2,28,248,22,189,6,23,194,2,12,
86,94,248,22,148,9,23,194,1,27,20,13,159,80,159,39,51,37,250,80,159,
42,52,37,249,22,27,11,80,159,44,51,37,22,186,13,10,248,22,190,5,23,
198,2,28,248,22,189,6,23,194,2,12,86,94,248,22,148,9,23,194,1,248,
80,159,40,8,31,39,197,28,248,22,81,23,195,2,9,27,248,22,74,23,196,
2,27,28,248,22,172,14,23,195,2,23,194,1,28,248,22,171,14,23,195,2,
249,22,173,14,23,196,1,250,80,158,48,50,248,22,188,14,2,21,11,10,250,
80,158,46,50,248,22,188,14,2,21,23,197,1,10,28,23,193,2,249,22,73,
248,22,175,14,249,22,173,14,23,198,1,247,22,189,14,248,80,159,46,56,39,
248,22,75,23,199,1,86,94,23,193,1,248,80,159,44,56,39,248,22,75,23,
249,22,173,14,23,196,1,250,80,159,43,39,39,248,22,188,14,2,31,11,10,
250,80,159,41,39,39,248,22,188,14,2,31,23,197,1,10,28,23,193,2,249,
22,73,248,22,175,14,249,22,173,14,23,198,1,247,22,189,14,27,248,22,75,
23,200,1,28,248,22,81,23,194,2,9,27,248,22,74,23,195,2,27,28,248,
22,172,14,23,195,2,23,194,1,28,248,22,171,14,23,195,2,249,22,173,14,
23,196,1,250,80,159,48,39,39,248,22,188,14,2,31,11,10,250,80,159,46,
39,39,248,22,188,14,2,31,23,197,1,10,28,23,193,2,249,22,73,248,22,
175,14,249,22,173,14,23,198,1,247,22,189,14,248,80,159,46,8,30,39,248,
22,75,23,199,1,86,94,23,193,1,248,80,159,44,8,30,39,248,22,75,23,
197,1,86,94,23,193,1,27,248,22,75,23,198,1,28,248,22,81,23,194,2,
9,27,248,22,74,23,195,2,27,28,248,22,172,14,23,195,2,23,194,1,28,
248,22,171,14,23,195,2,249,22,173,14,23,196,1,250,80,158,46,50,248,22,
188,14,2,21,11,10,250,80,158,44,50,248,22,188,14,2,21,23,197,1,10,
28,23,193,2,249,22,73,248,22,175,14,249,22,173,14,23,198,1,247,22,189,
14,248,80,159,44,56,39,248,22,75,23,199,1,248,80,159,42,56,39,248,22,
75,196,28,248,22,81,23,195,2,9,27,248,22,74,23,196,2,27,28,248,22,
172,14,23,195,2,23,194,1,28,248,22,171,14,23,195,2,249,22,173,14,23,
196,1,250,80,158,43,50,248,22,188,14,2,21,11,10,250,80,158,41,50,248,
22,188,14,2,21,23,197,1,10,28,23,193,2,249,22,73,248,22,175,14,249,
22,173,14,23,198,1,247,22,189,14,248,80,159,41,55,39,248,22,75,23,200,
1,248,80,159,39,55,39,248,22,75,197,28,248,22,81,23,195,2,9,27,248,
22,74,23,196,2,27,28,248,22,172,14,23,195,2,23,194,1,28,248,22,171,
14,23,195,2,249,22,173,14,23,196,1,250,80,158,43,50,248,22,188,14,2,
21,11,10,250,80,158,41,50,248,22,188,14,2,21,23,197,1,10,28,23,193,
2,249,22,73,248,22,175,14,249,22,173,14,23,198,1,247,22,189,14,248,80,
159,41,54,39,248,22,75,23,200,1,248,80,159,39,54,39,248,22,75,197,27,
248,22,148,14,23,195,2,28,23,193,2,192,86,94,23,193,1,28,248,22,130,
7,23,195,2,27,248,22,170,14,195,28,192,192,248,22,171,14,195,11,86,94,
28,28,248,22,149,14,23,195,2,10,28,248,22,148,14,23,195,2,10,28,248,
22,130,7,23,195,2,28,248,22,170,14,23,195,2,10,248,22,171,14,23,195,
2,11,12,250,22,176,9,76,110,111,114,109,97,108,45,112,97,116,104,45,99,
97,115,101,6,42,42,112,97,116,104,32,40,102,111,114,32,97,110,121,32,115,
121,115,116,101,109,41,32,111,114,32,118,97,108,105,100,45,112,97,116,104,32,
115,116,114,105,110,103,23,197,2,28,28,248,22,149,14,23,195,2,249,22,140,
9,248,22,150,14,23,197,2,2,22,249,22,140,9,247,22,152,8,2,22,27,
28,248,22,130,7,23,196,2,23,195,2,248,22,142,8,248,22,153,14,23,197,
2,28,249,22,139,15,0,21,35,114,120,34,94,91,92,92,93,91,92,92,93,
91,63,93,91,92,92,93,34,23,195,2,28,248,22,130,7,195,248,22,156,14,
195,194,27,248,22,169,7,23,195,1,249,22,157,14,248,22,145,8,250,22,147,
15,0,6,35,114,120,34,47,34,28,249,22,139,15,0,22,35,114,120,34,91,
47,92,92,93,91,46,32,93,43,91,47,92,92,93,42,36,34,23,201,2,23,
199,1,250,22,147,15,0,19,35,114,120,34,91,32,46,93,43,40,91,47,92,
92,93,42,41,36,34,23,202,1,6,2,2,92,49,80,159,44,37,38,2,22,
28,248,22,130,7,194,248,22,156,14,194,193,86,94,28,28,248,22,148,14,23,
195,2,10,28,248,22,130,7,23,195,2,28,248,22,170,14,23,195,2,10,248,
22,171,14,23,195,2,11,12,250,22,176,9,23,196,2,2,23,23,197,2,28,
248,22,170,14,23,195,2,12,248,22,162,12,249,22,168,11,248,22,159,7,250,
22,178,7,2,24,23,200,1,23,201,1,247,22,23,86,94,28,28,248,22,148,
14,23,195,2,10,28,248,22,130,7,23,195,2,28,248,22,170,14,23,195,2,
10,248,22,171,14,23,195,2,11,12,250,22,176,9,23,196,2,2,23,23,197,
2,28,248,22,170,14,23,195,2,12,248,22,162,12,249,22,168,11,248,22,159,
7,250,22,178,7,2,24,23,200,1,23,201,1,247,22,23,86,94,86,94,28,
28,248,22,148,14,23,195,2,10,28,248,22,130,7,23,195,2,28,248,22,170,
14,23,195,2,10,248,22,171,14,23,195,2,11,12,250,22,176,9,195,2,23,
23,197,2,28,248,22,170,14,23,195,2,12,248,22,162,12,249,22,168,11,248,
22,159,7,250,22,178,7,2,24,199,23,201,1,247,22,23,249,22,3,88,163,
8,36,37,50,11,9,223,2,33,47,196,86,94,28,28,248,22,148,14,23,194,
2,10,28,248,22,130,7,23,194,2,28,248,22,170,14,23,194,2,10,248,22,
171,14,23,194,2,11,12,250,22,176,9,2,7,2,23,23,196,2,28,248,22,
170,14,23,194,2,12,248,22,162,12,249,22,168,11,248,22,159,7,250,22,178,
7,2,24,2,7,23,200,1,247,22,23,32,50,88,163,8,36,41,56,11,2,
26,222,33,51,28,248,22,81,23,197,2,86,94,23,196,1,28,23,197,2,196,
86,94,23,197,1,248,22,162,12,249,22,137,12,251,22,178,7,2,25,2,7,
28,248,22,81,23,203,2,86,94,23,202,1,23,201,1,250,22,1,22,166,14,
23,204,1,23,205,1,23,200,1,247,22,23,27,249,22,166,14,248,22,74,23,
200,2,23,197,2,28,248,22,161,14,23,194,2,27,250,22,1,22,166,14,23,
197,1,199,28,248,22,161,14,193,192,252,2,50,199,200,201,248,22,75,203,203,
252,2,50,198,199,200,248,22,75,202,202,86,94,86,94,86,94,28,28,248,22,
248,22,171,14,23,195,2,249,22,173,14,23,196,1,250,80,159,46,39,39,248,
22,188,14,2,31,11,10,250,80,159,44,39,39,248,22,188,14,2,31,23,197,
1,10,28,23,193,2,249,22,73,248,22,175,14,249,22,173,14,23,198,1,247,
22,189,14,248,80,159,44,8,30,39,248,22,75,23,199,1,248,80,159,42,8,
30,39,248,22,75,196,28,248,22,81,23,195,2,9,27,248,22,74,23,196,2,
27,28,248,22,172,14,23,195,2,23,194,1,28,248,22,171,14,23,195,2,249,
22,173,14,23,196,1,250,80,159,43,39,39,248,22,188,14,2,31,11,10,250,
80,159,41,39,39,248,22,188,14,2,31,23,197,1,10,28,23,193,2,249,22,
73,248,22,175,14,249,22,173,14,23,198,1,247,22,189,14,248,80,159,41,8,
29,39,248,22,75,23,200,1,248,80,159,39,8,29,39,248,22,75,197,28,248,
22,81,23,195,2,9,27,248,22,74,23,196,2,27,28,248,22,172,14,23,195,
2,23,194,1,28,248,22,171,14,23,195,2,249,22,173,14,23,196,1,250,80,
159,43,39,39,248,22,188,14,2,31,11,10,250,80,159,41,39,39,248,22,188,
14,2,31,23,197,1,10,28,23,193,2,249,22,73,248,22,175,14,249,22,173,
14,23,198,1,247,22,189,14,248,80,159,41,8,28,39,248,22,75,23,200,1,
248,80,159,39,8,28,39,248,22,75,197,27,248,22,148,14,23,195,2,28,23,
193,2,192,86,94,23,193,1,28,248,22,130,7,23,195,2,27,248,22,170,14,
195,28,192,192,248,22,171,14,195,11,86,94,28,28,248,22,149,14,23,195,2,
10,28,248,22,148,14,23,195,2,10,28,248,22,130,7,23,195,2,28,248,22,
170,14,23,195,2,10,248,22,171,14,23,195,2,11,12,250,22,176,9,76,110,
111,114,109,97,108,45,112,97,116,104,45,99,97,115,101,6,42,42,112,97,116,
104,32,40,102,111,114,32,97,110,121,32,115,121,115,116,101,109,41,32,111,114,
32,118,97,108,105,100,45,112,97,116,104,32,115,116,114,105,110,103,23,197,2,
28,28,248,22,149,14,23,195,2,249,22,140,9,248,22,150,14,23,197,2,2,
32,249,22,140,9,247,22,152,8,2,32,27,28,248,22,130,7,23,196,2,23,
195,2,248,22,142,8,248,22,153,14,23,197,2,28,249,22,139,15,0,21,35,
114,120,34,94,91,92,92,93,91,92,92,93,91,63,93,91,92,92,93,34,23,
195,2,28,248,22,130,7,195,248,22,156,14,195,194,27,248,22,169,7,23,195,
1,249,22,157,14,248,22,145,8,250,22,147,15,0,6,35,114,120,34,47,34,
28,249,22,139,15,0,22,35,114,120,34,91,47,92,92,93,91,46,32,93,43,
91,47,92,92,93,42,36,34,23,201,2,23,199,1,250,22,147,15,0,19,35,
114,120,34,91,32,46,93,43,40,91,47,92,92,93,42,41,36,34,23,202,1,
6,2,2,92,49,80,159,44,37,38,2,32,28,248,22,130,7,194,248,22,156,
14,194,193,32,56,88,163,8,36,39,53,11,70,102,111,117,110,100,45,101,120,
101,99,222,33,59,32,57,88,163,8,36,40,58,11,64,110,101,120,116,222,33,
58,27,248,22,174,14,23,196,2,28,249,22,142,9,23,195,2,23,197,1,11,
28,248,22,170,14,23,194,2,27,249,22,166,14,23,197,1,23,196,1,28,23,
197,2,90,159,39,11,89,161,39,36,11,248,22,169,14,23,197,2,86,95,23,
195,1,23,194,1,27,28,23,202,2,27,248,22,174,14,23,199,2,28,249,22,
142,9,23,195,2,23,200,2,11,28,248,22,170,14,23,194,2,250,2,56,23,
205,2,23,206,2,249,22,166,14,23,200,2,23,198,1,250,2,56,23,205,2,
23,206,2,23,196,1,11,28,23,193,2,192,86,94,23,193,1,27,28,248,22,
148,14,23,196,2,27,249,22,166,14,23,198,2,23,205,2,28,28,248,22,161,
14,193,10,248,22,160,14,193,192,11,11,28,23,193,2,192,86,94,23,193,1,
28,23,203,2,11,27,248,22,174,14,23,200,2,28,249,22,142,9,23,195,2,
23,201,1,11,28,248,22,170,14,23,194,2,250,2,56,23,206,1,23,207,1,
249,22,166,14,23,201,1,23,198,1,250,2,56,205,206,195,192,86,94,23,194,
1,28,23,196,2,90,159,39,11,89,161,39,36,11,248,22,169,14,23,197,2,
86,95,23,195,1,23,194,1,27,28,23,201,2,27,248,22,174,14,23,199,2,
28,249,22,142,9,23,195,2,23,200,2,11,28,248,22,170,14,23,194,2,250,
2,56,23,204,2,23,205,2,249,22,166,14,23,200,2,23,198,1,250,2,56,
23,204,2,23,205,2,23,196,1,11,28,23,193,2,192,86,94,23,193,1,27,
28,248,22,148,14,23,196,2,27,249,22,166,14,23,198,2,23,204,2,28,28,
248,22,161,14,193,10,248,22,160,14,193,192,11,11,28,23,193,2,192,86,94,
23,193,1,28,23,202,2,11,27,248,22,174,14,23,200,2,28,249,22,142,9,
23,195,2,23,201,1,11,28,248,22,170,14,23,194,2,250,2,56,23,205,1,
23,206,1,249,22,166,14,23,201,1,23,198,1,250,2,56,204,205,195,192,28,
23,193,2,90,159,39,11,89,161,39,36,11,248,22,169,14,23,199,2,86,95,
23,195,1,23,194,1,27,28,23,198,2,251,2,57,23,198,2,23,203,2,23,
201,2,23,202,2,11,28,23,193,2,192,86,94,23,193,1,27,28,248,22,148,
14,195,27,249,22,166,14,197,200,28,28,248,22,161,14,193,10,248,22,160,14,
193,192,11,11,28,192,192,28,198,11,251,2,57,198,203,201,202,194,32,60,88,
163,8,36,40,58,11,2,30,222,33,61,28,248,22,81,23,197,2,11,27,248,
22,173,14,248,22,74,23,199,2,27,249,22,166,14,23,196,1,23,197,2,28,
248,22,160,14,23,194,2,250,2,56,198,199,195,86,94,23,193,1,27,248,22,
75,23,200,1,28,248,22,81,23,194,2,11,27,248,22,173,14,248,22,74,23,
196,2,27,249,22,166,14,23,196,1,23,200,2,28,248,22,160,14,23,194,2,
250,2,56,201,202,195,86,94,23,193,1,27,248,22,75,23,197,1,28,248,22,
81,23,194,2,11,27,248,22,173,14,248,22,74,195,27,249,22,166,14,23,196,
1,202,28,248,22,160,14,193,250,2,56,204,205,195,251,2,60,204,205,206,248,
22,75,199,86,95,28,28,248,22,148,14,23,195,2,10,28,248,22,130,7,23,
195,2,28,248,22,170,14,23,195,2,10,248,22,171,14,23,195,2,11,12,250,
22,176,9,2,5,6,25,25,112,97,116,104,32,111,114,32,115,116,114,105,110,
103,32,40,115,97,110,115,32,110,117,108,41,23,197,2,28,28,23,195,2,28,
28,248,22,148,14,23,196,2,10,28,248,22,130,7,23,196,2,28,248,22,170,
14,23,196,2,10,248,22,171,14,23,196,2,11,248,22,170,14,23,196,2,11,
10,12,250,22,176,9,2,5,6,29,29,35,102,32,111,114,32,114,101,108,97,
116,105,118,101,32,112,97,116,104,32,111,114,32,115,116,114,105,110,103,23,198,
2,28,28,248,22,170,14,23,195,2,90,159,39,11,89,161,39,36,11,248,22,
169,14,23,198,2,249,22,140,9,194,2,33,11,27,248,22,150,8,6,4,4,
80,65,84,72,27,28,23,194,2,27,249,80,158,41,40,23,197,1,9,28,249,
22,140,9,247,22,152,8,2,32,249,22,73,248,22,157,14,5,1,46,194,192,
86,94,23,194,1,9,28,248,22,81,23,194,2,11,27,248,22,173,14,248,22,
74,23,196,2,27,249,22,166,14,23,196,1,23,200,2,28,248,22,160,14,23,
194,2,250,2,56,201,202,195,86,94,23,193,1,27,248,22,75,23,197,1,28,
248,22,81,23,194,2,11,27,248,22,173,14,248,22,74,23,196,2,27,249,22,
166,14,23,196,1,23,203,2,28,248,22,160,14,23,194,2,250,2,56,204,205,
195,86,94,23,193,1,27,248,22,75,23,197,1,28,248,22,81,23,194,2,11,
27,248,22,173,14,248,22,74,195,27,249,22,166,14,23,196,1,205,28,248,22,
160,14,193,250,2,56,23,15,23,16,195,251,2,60,23,15,23,16,23,17,248,
22,75,199,27,248,22,173,14,23,196,1,28,248,22,160,14,193,250,2,56,198,
199,195,11,250,80,159,39,39,39,196,197,11,250,80,159,39,39,39,196,11,11,
32,65,88,163,8,36,39,57,11,2,30,222,33,67,0,8,35,114,120,35,34,
92,34,34,27,249,22,135,15,23,197,2,23,198,2,28,23,193,2,86,94,23,
196,1,27,248,22,98,23,195,2,27,27,248,22,107,23,197,1,27,249,22,135,
15,23,201,2,23,196,2,28,23,193,2,86,94,23,194,1,27,248,22,98,23,
195,2,27,250,2,65,23,203,2,23,204,1,248,22,107,23,199,1,28,249,22,
191,7,23,196,2,2,34,249,22,87,23,202,2,194,249,22,73,248,22,157,14,
28,249,22,140,9,247,22,152,8,2,32,250,22,147,15,2,66,23,200,1,2,
35,23,197,1,194,86,95,23,199,1,23,193,1,28,249,22,191,7,23,196,2,
2,34,249,22,87,23,200,2,9,249,22,73,248,22,157,14,28,249,22,140,9,
247,22,152,8,2,32,250,22,147,15,2,66,23,200,1,2,35,23,197,1,9,
28,249,22,191,7,23,196,2,2,34,249,22,87,197,194,86,94,23,196,1,249,
22,73,248,22,157,14,28,249,22,140,9,247,22,152,8,2,32,250,22,147,15,
2,66,23,200,1,2,35,23,197,1,194,86,94,23,193,1,28,249,22,191,7,
23,198,2,2,34,249,22,87,195,9,86,94,23,194,1,249,22,73,248,22,157,
14,28,249,22,140,9,247,22,152,8,2,32,250,22,147,15,2,66,23,202,1,
2,35,23,199,1,9,86,95,28,28,248,22,183,7,194,10,248,22,130,7,194,
12,250,22,176,9,2,6,6,21,21,98,121,116,101,32,115,116,114,105,110,103,
32,111,114,32,115,116,114,105,110,103,196,28,28,248,22,82,195,249,22,4,22,
148,14,196,11,12,250,22,176,9,2,6,6,13,13,108,105,115,116,32,111,102,
32,112,97,116,104,115,197,250,2,65,197,195,28,248,22,130,7,197,248,22,144,
8,197,196,86,94,28,28,248,22,148,14,23,195,2,10,28,248,22,130,7,23,
195,2,28,248,22,170,14,23,195,2,10,248,22,171,14,23,195,2,11,12,250,
22,176,9,23,196,2,2,36,23,197,2,28,248,22,170,14,23,195,2,12,248,
22,162,12,249,22,168,11,248,22,159,7,250,22,178,7,2,37,23,200,1,23,
201,1,247,22,23,86,94,28,28,248,22,148,14,23,195,2,10,28,248,22,130,
7,23,195,2,28,248,22,170,14,23,195,2,10,248,22,171,14,23,195,2,11,
12,250,22,176,9,23,196,2,2,36,23,197,2,28,248,22,170,14,23,195,2,
12,248,22,162,12,249,22,168,11,248,22,159,7,250,22,178,7,2,37,23,200,
1,23,201,1,247,22,23,86,94,86,94,28,28,248,22,148,14,23,195,2,10,
28,248,22,130,7,23,195,2,28,248,22,170,14,23,195,2,10,248,22,171,14,
23,195,2,11,12,250,22,176,9,195,2,36,23,197,2,28,248,22,170,14,23,
195,2,12,248,22,162,12,249,22,168,11,248,22,159,7,250,22,178,7,2,37,
199,23,201,1,247,22,23,249,22,3,88,163,8,36,37,50,11,9,223,2,33,
70,196,86,94,28,28,248,22,148,14,23,194,2,10,28,248,22,130,7,23,194,
2,28,248,22,170,14,23,194,2,10,248,22,171,14,23,194,2,11,12,250,22,
176,9,2,9,2,36,23,196,2,28,248,22,170,14,23,194,2,12,248,22,162,
12,249,22,168,11,248,22,159,7,250,22,178,7,2,37,2,9,23,200,1,247,
22,23,248,22,162,12,249,22,137,12,23,196,1,247,22,23,86,94,86,94,86,
94,28,28,248,22,148,14,194,10,28,248,22,130,7,194,28,248,22,170,14,194,
10,248,22,171,14,194,11,12,250,22,176,9,2,9,2,36,196,28,248,22,170,
14,194,12,248,22,162,12,249,22,168,11,248,22,159,7,250,22,178,7,2,37,
2,9,200,247,22,23,249,22,3,32,0,88,163,8,36,37,49,11,9,222,33,
72,196,252,80,158,41,44,2,9,32,0,88,163,8,36,37,45,11,9,222,33,
73,198,199,11,86,94,28,28,248,22,148,14,23,194,2,10,28,248,22,130,7,
23,194,2,28,248,22,170,14,23,194,2,10,248,22,171,14,23,194,2,11,12,
250,22,176,9,2,11,2,36,23,196,2,28,248,22,170,14,23,194,2,12,248,
22,162,12,249,22,168,11,248,22,159,7,250,22,178,7,2,37,2,11,23,200,
1,247,22,23,248,22,162,12,249,22,137,12,23,196,1,247,22,23,86,95,86,
94,28,28,248,22,148,14,194,10,28,248,22,130,7,194,28,248,22,170,14,194,
10,248,22,171,14,194,11,12,250,22,176,9,2,11,2,36,196,28,248,22,170,
14,194,12,248,22,162,12,249,22,168,11,248,22,159,7,250,22,178,7,2,37,
2,11,200,247,22,23,86,94,86,94,28,28,248,22,148,14,23,196,2,10,28,
248,22,130,7,23,196,2,28,248,22,170,14,23,196,2,10,248,22,171,14,23,
196,2,11,12,250,22,176,9,2,11,2,36,23,198,2,28,248,22,170,14,23,
196,2,12,248,22,162,12,249,22,168,11,248,22,159,7,250,22,178,7,2,37,
2,11,23,202,2,247,22,23,249,22,3,32,0,88,163,8,36,37,49,11,9,
222,33,75,23,198,2,249,22,166,14,252,80,158,43,44,2,11,32,0,88,163,
8,36,37,45,11,9,222,33,76,23,202,1,23,203,1,200,195,0,6,45,105,
110,102,46,48,27,248,22,188,14,2,38,27,28,248,22,171,14,23,195,2,193,
20,13,159,80,159,38,51,37,250,80,159,41,52,37,249,22,27,11,80,159,43,
51,37,22,189,14,248,22,188,14,68,111,114,105,103,45,100,105,114,27,248,22,
188,14,2,31,250,80,159,42,39,39,23,196,1,23,198,1,11,28,192,250,22,
166,14,195,6,6,6,99,111,110,102,105,103,6,10,10,108,105,110,107,115,46,
114,107,116,100,11,86,94,27,247,22,131,10,28,249,22,188,9,23,195,2,2,
39,251,22,191,9,23,197,1,2,39,249,22,178,7,2,40,248,22,160,11,23,
202,1,247,22,23,12,248,193,247,22,133,2,2,78,86,95,27,247,22,131,10,
28,249,22,188,9,23,195,2,2,39,251,22,191,9,23,197,1,2,39,249,22,
178,7,2,40,248,22,160,11,23,205,1,247,22,23,12,28,192,28,194,86,94,
20,18,159,11,80,158,39,47,247,22,133,2,20,18,159,11,80,158,39,48,192,
86,94,20,18,159,11,80,158,39,53,247,22,133,2,20,18,159,11,80,158,39,
54,192,12,248,194,247,22,133,2,20,20,94,248,22,190,5,23,194,2,28,248,
22,189,6,248,22,190,5,23,195,1,12,248,22,173,9,6,30,30,101,120,112,
101,99,116,101,100,32,97,32,115,105,110,103,108,101,32,83,45,101,120,112,114,
101,115,115,105,111,110,248,22,178,5,193,28,248,22,82,23,194,2,28,28,249,
22,184,3,38,248,22,86,23,196,2,10,249,22,184,3,39,248,22,86,23,196,
2,28,248,22,130,7,248,22,74,23,195,2,28,27,248,22,98,194,28,248,22,
148,14,23,194,2,10,28,248,22,130,7,23,194,2,28,248,22,170,14,23,194,
2,10,248,22,171,14,23,194,2,11,12,250,22,176,9,2,7,2,23,23,196,
2,28,248,22,170,14,23,194,2,12,248,22,162,12,249,22,168,11,248,22,159,
7,250,22,178,7,2,24,2,7,23,200,2,247,22,23,249,22,3,32,0,88,
163,8,36,37,49,11,9,222,33,49,23,196,2,27,247,22,190,14,28,248,22,
81,23,194,2,248,22,162,12,249,22,137,12,251,22,178,7,2,25,2,7,28,
248,22,81,23,203,2,86,94,23,202,1,23,201,1,250,22,1,22,166,14,23,
204,1,23,205,1,23,200,1,247,22,23,27,249,22,166,14,248,22,74,23,197,
2,23,197,2,28,248,22,161,14,23,194,2,27,250,22,1,22,166,14,23,197,
1,199,28,248,22,161,14,193,192,252,2,50,199,200,201,248,22,75,200,11,252,
2,50,198,199,200,248,22,75,199,11,86,94,28,28,248,22,148,14,23,194,2,
10,28,248,22,130,7,23,194,2,28,248,22,170,14,23,194,2,10,248,22,171,
14,23,194,2,11,12,250,22,176,9,2,9,2,23,23,196,2,28,248,22,170,
14,23,194,2,12,248,22,162,12,249,22,168,11,248,22,159,7,250,22,178,7,
2,24,2,9,23,200,1,247,22,23,32,54,88,163,8,36,42,59,11,2,26,
222,33,55,28,248,22,81,23,198,2,86,95,23,197,1,23,194,1,28,23,198,
2,197,86,94,23,198,1,248,22,162,12,249,22,137,12,251,22,178,7,2,25,
2,9,28,248,22,81,23,204,2,86,94,23,203,1,23,202,1,250,22,1,22,
166,14,23,205,1,23,206,1,23,200,1,247,22,23,27,249,22,166,14,248,22,
74,23,201,2,23,198,2,28,248,22,161,14,23,194,2,27,250,22,1,22,166,
14,23,197,1,23,201,2,28,248,22,161,14,23,194,2,28,23,196,2,28,28,
248,22,160,14,249,22,166,14,195,198,10,27,28,248,22,148,14,197,248,22,152,
14,197,196,27,248,22,133,7,23,195,2,27,28,249,22,188,3,23,196,2,40,
28,249,22,136,7,2,27,249,22,152,7,23,199,2,249,22,176,3,23,200,2,
40,249,22,153,7,250,22,152,7,23,200,1,36,249,22,176,3,23,201,1,40,
2,28,86,95,23,195,1,23,194,1,11,11,28,23,193,2,248,22,160,14,249,
22,166,14,198,23,196,1,11,192,253,2,54,200,201,202,203,248,22,75,205,28,
205,205,198,192,253,2,54,200,201,202,203,248,22,75,205,205,253,2,54,199,200,
201,202,248,22,75,204,204,86,95,86,94,28,28,248,22,148,14,193,10,28,248,
22,130,7,193,28,248,22,170,14,193,10,248,22,171,14,193,11,12,250,22,176,
9,2,9,2,23,195,28,248,22,170,14,193,12,248,22,162,12,249,22,168,11,
248,22,159,7,250,22,178,7,2,24,2,9,199,247,22,23,86,94,86,94,28,
28,248,22,148,14,23,195,2,10,28,248,22,130,7,23,195,2,28,248,22,170,
14,23,195,2,10,248,22,171,14,23,195,2,11,12,250,22,176,9,2,9,2,
23,23,197,2,28,248,22,170,14,23,195,2,12,248,22,162,12,249,22,168,11,
248,22,159,7,250,22,178,7,2,24,2,9,23,201,2,247,22,23,249,22,3,
32,0,88,163,8,36,37,49,11,9,222,33,53,23,197,2,249,22,166,14,27,
247,22,190,14,253,2,54,23,199,2,201,23,203,1,23,204,1,23,199,1,11,
194,32,57,88,163,36,44,8,29,11,2,26,222,33,58,28,248,22,81,23,200,
2,86,95,23,199,1,23,198,1,28,23,200,2,199,86,94,23,200,1,248,23,
196,1,251,22,178,7,2,25,23,199,1,28,248,22,81,23,203,2,86,94,23,
202,1,23,201,1,250,22,1,22,166,14,23,204,1,23,205,1,23,198,1,27,
249,22,166,14,248,22,74,23,203,2,23,199,2,28,248,22,161,14,23,194,2,
27,250,22,1,22,166,14,23,197,1,23,202,2,28,248,22,161,14,23,194,2,
28,23,200,2,28,28,248,22,160,14,249,22,166,14,23,196,2,23,203,2,10,
27,28,248,22,148,14,23,202,2,248,22,152,14,23,202,2,23,201,2,27,248,
22,133,7,23,195,2,27,28,249,22,188,3,23,196,2,40,28,249,22,136,7,
2,27,249,22,152,7,23,199,2,249,22,176,3,23,200,2,40,249,22,153,7,
250,22,152,7,23,200,1,36,249,22,176,3,23,201,1,40,2,28,86,95,23,
195,1,23,194,1,11,11,28,23,193,2,248,22,160,14,249,22,166,14,23,199,
2,23,196,1,11,192,27,248,22,75,23,203,1,27,28,23,204,2,86,94,23,
195,1,23,204,1,86,94,23,204,1,23,195,1,28,248,22,81,23,195,2,86,
95,23,202,1,23,194,1,28,23,193,2,192,86,94,23,193,1,248,23,200,1,
251,22,178,7,2,25,23,203,1,28,248,22,81,23,207,2,86,94,23,206,1,
23,205,1,250,22,1,22,166,14,23,208,1,23,209,1,23,202,1,27,249,22,
166,14,248,22,74,23,198,2,23,203,2,28,248,22,161,14,23,194,2,27,250,
22,1,22,166,14,23,197,1,23,206,2,28,248,22,161,14,23,194,2,28,23,
204,2,28,28,248,22,160,14,249,22,166,14,195,206,10,27,28,248,22,148,14,
205,248,22,152,14,205,204,27,248,22,133,7,23,195,2,27,28,249,22,188,3,
23,196,2,40,28,249,22,136,7,2,27,249,22,152,7,23,199,2,249,22,176,
3,23,200,2,40,249,22,153,7,250,22,152,7,23,200,1,36,249,22,176,3,
23,201,1,40,2,28,86,95,23,195,1,23,194,1,11,11,28,23,193,2,248,
22,160,14,249,22,166,14,198,23,196,1,11,192,26,8,2,57,206,23,15,23,
16,23,17,23,18,23,19,248,22,75,204,28,202,202,200,192,26,8,2,57,206,
23,15,23,16,23,17,23,18,23,19,248,22,75,204,202,26,8,2,57,205,206,
23,15,23,16,23,17,23,18,248,22,75,203,201,192,27,248,22,75,23,203,1,
28,248,22,81,23,194,2,86,95,23,201,1,23,193,1,28,23,203,2,202,86,
94,23,203,1,248,23,199,1,251,22,178,7,2,25,23,202,1,28,248,22,81,
23,206,2,86,94,23,205,1,23,204,1,250,22,1,22,166,14,23,207,1,23,
208,1,23,201,1,27,249,22,166,14,248,22,74,23,197,2,23,202,2,28,248,
22,161,14,23,194,2,27,250,22,1,22,166,14,23,197,1,23,205,2,28,248,
22,161,14,23,194,2,28,23,203,2,28,28,248,22,160,14,249,22,166,14,195,
205,10,27,28,248,22,148,14,204,248,22,152,14,204,203,27,248,22,133,7,23,
195,2,27,28,249,22,188,3,23,196,2,40,28,249,22,136,7,2,27,249,22,
152,7,23,199,2,249,22,176,3,23,200,2,40,249,22,153,7,250,22,152,7,
23,200,1,36,249,22,176,3,23,201,1,40,2,28,86,95,23,195,1,23,194,
1,11,11,28,23,193,2,248,22,160,14,249,22,166,14,198,23,196,1,11,192,
26,8,2,57,205,206,23,15,23,16,23,17,23,18,248,22,75,203,28,23,20,
23,20,200,192,26,8,2,57,205,206,23,15,23,16,23,17,23,18,248,22,75,
203,23,20,26,8,2,57,204,205,206,23,15,23,16,23,17,248,22,75,202,23,
19,86,94,23,193,1,27,248,22,75,23,202,1,28,248,22,81,23,194,2,86,
95,23,200,1,23,193,1,28,23,202,2,201,86,94,23,202,1,248,23,198,1,
251,22,178,7,2,25,23,201,1,28,248,22,81,23,205,2,86,94,23,204,1,
23,203,1,250,22,1,22,166,14,23,206,1,23,207,1,23,200,1,27,249,22,
166,14,248,22,74,23,197,2,23,201,2,28,248,22,161,14,23,194,2,27,250,
22,1,22,166,14,23,197,1,23,204,2,28,248,22,161,14,23,194,2,28,23,
202,2,28,28,248,22,160,14,249,22,166,14,195,204,10,27,28,248,22,148,14,
203,248,22,152,14,203,202,27,248,22,133,7,23,195,2,27,28,249,22,188,3,
23,196,2,40,28,249,22,136,7,2,27,249,22,152,7,23,199,2,249,22,176,
3,23,200,2,40,249,22,153,7,250,22,152,7,23,200,1,36,249,22,176,3,
23,201,1,40,2,28,86,95,23,195,1,23,194,1,11,11,28,23,193,2,248,
22,160,14,249,22,166,14,198,23,196,1,11,192,26,8,2,57,204,205,206,23,
15,23,16,23,17,248,22,75,203,28,23,19,23,19,200,192,26,8,2,57,204,
205,206,23,15,23,16,23,17,248,22,75,203,23,19,26,8,2,57,203,204,205,
206,23,15,23,16,248,22,75,202,23,18,27,247,22,190,14,28,248,22,81,23,
194,2,86,94,23,198,1,248,23,196,1,251,22,178,7,2,25,23,199,1,28,
248,22,81,23,203,2,86,94,23,202,1,23,201,1,250,22,1,22,166,14,23,
204,1,23,205,1,23,198,1,27,249,22,166,14,248,22,74,23,197,2,23,199,
2,28,248,22,161,14,23,194,2,27,250,22,1,22,166,14,23,197,1,23,202,
2,28,248,22,161,14,23,194,2,28,23,200,2,28,28,248,22,160,14,249,22,
166,14,195,202,10,27,28,248,22,148,14,201,248,22,152,14,201,200,27,248,22,
133,7,23,195,2,27,28,249,22,188,3,23,196,2,40,28,249,22,136,7,2,
27,249,22,152,7,23,199,2,249,22,176,3,23,200,2,40,249,22,153,7,250,
22,152,7,23,200,1,36,249,22,176,3,23,201,1,40,2,28,86,95,23,195,
2,10,248,22,171,14,23,194,1,11,27,248,22,81,248,22,100,195,28,192,192,
248,22,148,15,248,22,107,195,11,11,11,11,28,28,248,22,81,248,22,100,23,
197,2,10,249,22,139,15,248,22,107,23,198,2,247,22,148,8,27,248,22,61,
248,22,74,23,198,2,250,22,151,2,23,197,2,23,196,2,249,22,73,248,22,
125,249,22,173,14,248,22,98,23,205,1,23,203,1,250,22,153,2,23,202,1,
23,201,1,9,12,20,13,159,80,159,37,56,37,88,163,36,37,51,11,9,223,
2,33,80,27,250,22,183,14,28,23,197,2,80,159,41,46,38,80,159,41,49,
38,11,32,0,88,163,8,36,36,41,11,9,222,33,81,28,249,22,186,3,23,
195,2,28,23,196,2,80,158,40,48,80,158,40,54,20,13,159,80,159,38,56,
37,20,20,94,88,163,36,37,54,8,240,0,24,6,0,9,226,2,1,3,0,
33,82,23,196,1,20,13,159,80,159,38,51,37,26,29,80,159,8,31,52,37,
249,22,27,11,80,159,8,33,51,37,22,182,13,10,22,183,13,10,22,184,13,
10,22,187,13,10,22,186,13,10,22,188,13,10,22,185,13,10,22,189,13,10,
22,190,13,10,22,191,13,10,22,128,14,10,22,129,14,10,22,130,14,11,22,
180,13,11,27,249,22,169,5,28,196,80,159,41,46,38,80,159,41,49,38,66,
98,105,110,97,114,121,27,250,22,40,22,31,88,163,8,36,36,44,11,9,223,
4,33,83,20,20,94,88,163,36,36,43,11,9,223,4,33,84,23,197,1,86,
94,28,28,248,22,82,23,194,2,249,22,4,32,0,88,163,8,36,37,45,11,
9,222,33,85,23,195,2,11,12,248,22,173,9,6,18,18,105,108,108,45,102,
111,114,109,101,100,32,99,111,110,116,101,110,116,27,247,22,133,2,27,90,159,
39,11,89,161,39,36,11,248,22,169,14,28,201,80,159,46,46,38,80,159,46,
49,38,192,86,95,249,22,3,20,20,94,88,163,8,36,37,54,11,9,224,2,
3,33,86,23,195,1,23,197,1,28,197,86,94,20,18,159,11,80,158,42,47,
193,20,18,159,11,80,158,42,48,196,86,94,20,18,159,11,80,158,42,53,193,
20,18,159,11,80,158,42,54,196,193,28,193,80,158,38,47,80,158,38,53,248,
22,8,88,163,8,32,37,8,40,8,240,0,188,23,0,9,224,1,2,33,87,
0,7,35,114,120,34,47,43,34,28,248,22,130,7,23,195,2,27,249,22,137,
15,2,89,196,28,192,28,249,22,184,3,248,22,97,195,248,22,174,3,248,22,
133,7,198,249,22,7,250,22,152,7,199,36,248,22,97,198,197,249,22,7,250,
22,152,7,199,36,248,22,97,198,249,22,73,249,22,152,7,200,248,22,99,199,
199,249,22,7,196,197,90,159,39,11,89,161,39,36,11,248,22,169,14,23,198,
1,86,94,23,195,1,28,249,22,140,9,23,195,2,2,33,249,22,7,195,199,
27,249,22,73,23,197,1,23,201,1,28,248,22,130,7,23,195,2,27,249,22,
137,15,2,89,196,28,192,28,249,22,184,3,248,22,97,195,248,22,174,3,248,
22,133,7,198,249,22,7,250,22,152,7,199,36,248,22,97,198,195,249,22,7,
250,22,152,7,199,36,248,22,97,198,249,22,73,249,22,152,7,200,248,22,99,
199,197,249,22,7,196,195,90,159,39,11,89,161,39,36,11,248,22,169,14,23,
198,1,28,249,22,140,9,194,2,33,249,22,7,195,197,249,80,159,45,57,39,
194,249,22,73,197,199,32,91,88,163,36,44,8,36,11,65,99,108,111,111,112,
222,33,96,32,92,88,163,8,36,37,55,11,2,30,222,33,93,28,248,22,81,
248,22,75,23,195,2,248,22,83,27,248,22,74,23,196,1,28,248,22,148,14,
23,194,2,248,22,152,14,23,194,1,192,250,22,84,27,248,22,74,23,198,2,
28,248,22,148,14,23,194,2,248,22,152,14,23,194,1,192,2,41,27,248,22,
75,23,198,1,28,248,22,81,248,22,75,23,195,2,248,22,83,27,248,22,74,
23,196,1,28,248,22,148,14,23,194,2,248,22,152,14,23,194,1,192,250,22,
84,27,248,22,74,23,198,2,28,248,22,148,14,23,194,2,248,22,152,14,23,
194,1,192,2,41,27,248,22,75,23,198,1,28,248,22,81,248,22,75,23,195,
2,248,22,83,27,248,22,74,23,196,1,28,248,22,148,14,23,194,2,248,22,
152,14,23,194,1,192,250,22,84,27,248,22,74,23,198,2,28,248,22,148,14,
23,194,2,248,22,152,14,23,194,1,192,2,41,248,2,92,248,22,75,23,198,
1,32,94,88,163,8,36,38,57,11,66,102,105,108,116,101,114,222,33,95,28,
248,22,81,23,195,2,9,28,248,23,194,2,248,22,74,23,196,2,249,22,73,
248,22,74,23,197,2,27,248,22,75,23,198,1,28,248,22,81,23,194,2,9,
28,248,23,197,2,248,22,74,23,195,2,249,22,73,248,22,74,23,196,2,27,
248,22,75,23,197,1,28,248,22,81,23,194,2,9,28,248,23,200,2,248,22,
74,23,195,2,249,22,73,248,22,74,23,196,2,27,248,22,75,23,197,1,28,
248,22,81,23,194,2,9,28,248,23,203,2,248,22,74,23,195,2,249,22,73,
248,22,74,23,196,2,249,2,94,23,206,1,248,22,75,23,198,1,249,2,94,
23,204,1,248,22,75,23,196,1,27,248,22,75,23,195,1,28,248,22,81,23,
194,2,9,28,248,23,201,2,248,22,74,23,195,2,249,22,73,248,22,74,23,
196,2,249,2,94,23,204,1,248,22,75,23,198,1,249,2,94,23,202,1,248,
22,75,23,196,1,27,248,22,75,23,195,1,28,248,22,81,23,194,2,9,28,
248,23,198,2,248,22,74,23,195,2,249,22,73,248,22,74,23,196,2,27,248,
22,75,23,197,1,28,248,22,81,23,194,2,9,28,248,23,201,2,248,22,74,
23,195,2,249,22,73,248,22,74,23,196,2,249,2,94,23,204,1,248,22,75,
23,198,1,249,2,94,23,202,1,248,22,75,23,196,1,27,248,22,75,23,195,
1,28,248,22,81,23,194,2,9,28,248,23,199,2,248,22,74,23,195,2,249,
22,73,248,22,74,23,196,2,249,2,94,23,202,1,248,22,75,23,198,1,249,
2,94,23,200,1,248,22,75,23,196,1,27,248,22,75,23,196,1,28,248,22,
81,23,194,2,9,28,248,23,195,2,248,22,74,23,195,2,249,22,73,248,22,
74,23,196,2,27,248,22,75,23,197,1,28,248,22,81,23,194,2,9,28,248,
23,198,2,248,22,74,23,195,2,249,22,73,248,22,74,23,196,2,27,248,22,
75,23,197,1,28,248,22,81,23,194,2,9,28,248,23,201,2,248,22,74,23,
195,2,249,22,73,248,22,74,23,196,2,249,2,94,23,204,1,248,22,75,23,
198,1,249,2,94,23,202,1,248,22,75,23,196,1,27,248,22,75,23,195,1,
28,248,22,81,23,194,2,9,28,248,23,199,2,248,22,74,23,195,2,249,22,
73,248,22,74,23,196,2,249,2,94,23,202,1,248,22,75,23,198,1,249,2,
94,23,200,1,248,22,75,23,196,1,27,248,22,75,23,195,1,28,248,22,81,
23,194,2,9,28,248,23,196,2,248,22,74,23,195,2,249,22,73,248,22,74,
23,196,2,27,248,22,75,23,197,1,28,248,22,81,23,194,2,9,28,248,23,
199,2,248,22,74,23,195,2,249,22,73,248,22,74,23,196,2,249,2,94,23,
202,1,248,22,75,23,198,1,249,2,94,23,200,1,248,22,75,23,196,1,27,
248,22,75,23,195,1,28,248,22,81,23,194,2,9,28,248,23,197,2,248,22,
74,23,195,2,249,22,73,248,22,74,23,196,2,249,2,94,23,200,1,248,22,
75,23,198,1,249,2,94,197,248,22,75,195,28,248,22,81,23,200,2,86,95,
23,199,1,23,198,1,28,23,200,2,199,86,94,23,200,1,27,28,248,22,81,
23,197,2,6,0,0,249,22,1,22,153,7,248,2,92,23,199,2,248,23,199,
1,252,22,178,7,6,44,44,126,97,58,32,99,111,108,108,101,99,116,105,111,
110,32,110,111,116,32,102,111,117,110,100,58,32,126,115,32,105,110,32,97,110,
121,32,111,102,58,32,126,115,126,97,23,203,1,28,248,22,81,23,203,1,28,
248,22,148,14,23,202,2,248,22,152,14,23,202,1,23,201,1,250,22,153,7,
28,248,22,148,14,23,205,2,248,22,152,14,23,205,1,23,204,1,6,1,1,
47,23,202,2,28,248,22,81,23,201,2,9,28,248,22,148,14,248,22,74,23,
202,2,249,22,73,248,22,74,23,203,2,27,248,22,75,23,204,2,28,248,22,
81,23,194,2,9,28,248,22,148,14,248,22,74,23,195,2,249,22,73,248,22,
74,23,196,2,27,248,22,75,23,197,1,28,248,22,81,23,194,2,9,28,248,
22,148,14,248,22,74,23,195,2,249,22,73,248,22,74,23,196,2,249,2,94,
22,148,14,248,22,75,23,198,1,249,2,94,22,148,14,248,22,75,23,196,1,
27,248,22,75,23,195,1,28,248,22,81,23,194,2,9,28,248,22,148,14,248,
22,74,23,195,2,249,22,73,248,22,74,23,196,2,249,2,94,22,148,14,248,
22,75,23,198,1,249,2,94,22,148,14,248,22,75,23,196,1,27,248,22,75,
23,202,2,28,248,22,81,23,194,2,9,28,248,22,148,14,248,22,74,23,195,
2,249,22,73,248,22,74,23,196,2,27,248,22,75,23,197,1,28,248,22,81,
23,194,2,9,28,248,22,148,14,248,22,74,23,195,2,249,22,73,248,22,74,
23,196,2,249,2,94,22,148,14,248,22,75,23,198,1,249,2,94,22,148,14,
248,22,75,23,196,1,27,248,22,75,23,195,1,28,248,22,81,23,194,2,9,
28,248,22,148,14,248,22,74,23,195,2,249,22,73,248,22,74,23,196,2,249,
2,94,22,148,14,248,22,75,23,198,1,249,2,94,22,148,14,248,22,75,23,
196,1,28,249,22,5,22,127,23,202,2,250,22,178,7,6,21,21,32,111,114,
58,32,126,115,32,105,110,32,97,110,121,32,111,102,58,32,126,115,23,202,1,
249,22,2,22,128,2,28,248,22,81,23,206,2,86,94,23,205,1,9,28,248,
22,127,248,22,74,23,207,2,249,22,73,248,22,74,23,208,2,27,248,22,75,
23,209,1,28,248,22,81,23,194,2,9,28,248,22,127,248,22,74,23,195,2,
249,22,73,248,22,74,23,196,2,27,248,22,75,23,197,1,28,248,22,81,23,
194,2,9,28,248,22,127,248,22,74,23,195,2,249,22,73,248,22,74,23,196,
2,249,2,94,22,127,248,22,75,23,198,1,249,2,94,22,127,248,22,75,23,
196,1,27,248,22,75,23,195,1,28,248,22,81,23,194,2,9,28,248,22,127,
248,22,74,23,195,2,249,22,73,248,22,74,23,196,2,249,2,94,22,127,248,
22,75,23,198,1,249,2,94,22,127,248,22,75,23,196,1,27,248,22,75,23,
207,1,28,248,22,81,23,194,2,9,28,248,22,127,248,22,74,23,195,2,249,
22,73,248,22,74,23,196,2,27,248,22,75,23,197,1,28,248,22,81,23,194,
2,9,28,248,22,127,248,22,74,23,195,2,249,22,73,248,22,74,23,196,2,
249,2,94,22,127,248,22,75,23,198,1,249,2,94,22,127,248,22,75,23,196,
1,27,248,22,75,23,195,1,28,248,22,81,23,194,2,9,28,248,22,127,248,
22,74,23,195,2,249,22,73,248,22,74,23,196,2,249,2,94,22,127,248,22,
75,23,198,1,249,2,94,22,127,248,22,75,23,196,1,86,94,23,199,1,6,
0,0,27,248,22,74,23,201,2,27,28,248,22,148,14,23,195,2,249,22,166,
14,23,196,1,23,198,2,248,22,128,2,23,195,1,28,28,248,22,148,14,248,
22,74,23,203,2,248,22,161,14,23,194,2,10,27,250,22,1,22,166,14,23,
197,1,23,201,2,28,28,248,22,81,23,199,2,10,248,22,161,14,23,194,2,
28,23,201,2,28,28,248,22,160,14,249,22,166,14,195,203,10,27,28,248,22,
148,14,202,248,22,152,14,202,201,27,248,22,133,7,23,195,2,27,28,249,22,
188,3,23,196,2,40,28,249,22,136,7,6,4,4,46,114,107,116,249,22,152,
7,23,199,2,249,22,176,3,23,200,2,40,249,22,153,7,250,22,152,7,23,
200,1,36,249,22,176,3,23,201,1,40,6,3,3,46,115,115,86,95,23,195,
1,23,194,1,11,11,28,23,193,2,248,22,160,14,249,22,166,14,198,23,196,
1,11,192,26,8,2,57,202,203,204,205,206,23,15,248,22,75,203,200,192,26,
8,2,57,202,203,204,205,206,23,15,248,22,75,203,11,26,8,2,57,201,202,
203,204,205,206,248,22,75,202,11,86,95,28,28,248,22,149,14,23,194,2,10,
28,248,22,148,14,23,194,2,10,28,248,22,130,7,23,194,2,28,248,22,170,
14,23,194,2,10,248,22,171,14,23,194,2,11,12,252,22,176,9,23,200,2,
2,29,36,23,198,2,23,199,2,28,28,248,22,130,7,23,195,2,10,248,22,
183,7,23,195,2,86,94,23,194,1,12,252,22,176,9,23,200,2,2,30,37,
23,198,2,23,199,1,90,159,39,11,89,161,39,36,11,248,22,169,14,23,197,
2,86,94,23,195,1,86,94,28,192,12,250,22,177,9,23,201,1,2,31,23,
199,1,249,22,7,194,195,90,159,38,11,89,161,38,36,11,86,95,28,28,248,
22,149,14,23,196,2,10,28,248,22,148,14,23,196,2,10,28,248,22,130,7,
23,196,2,28,248,22,170,14,23,196,2,10,248,22,171,14,23,196,2,11,12,
252,22,176,9,2,11,2,29,36,23,200,2,23,201,2,28,28,248,22,130,7,
23,197,2,10,248,22,183,7,23,197,2,12,252,22,176,9,2,11,2,30,37,
23,200,2,23,201,2,90,159,39,11,89,161,39,36,11,248,22,169,14,23,199,
2,86,94,23,195,1,86,94,28,192,12,250,22,177,9,2,11,2,31,23,201,
2,249,22,7,194,195,27,249,22,158,14,250,22,146,15,0,20,35,114,120,35,
34,40,63,58,91,46,93,91,94,46,93,42,124,41,36,34,248,22,154,14,23,
201,1,28,248,22,130,7,23,203,2,249,22,145,8,23,204,1,8,63,23,202,
1,11,192,26,8,2,91,203,204,205,206,23,15,23,16,248,22,75,23,18,28,
23,18,23,18,200,192,26,8,2,91,203,204,205,206,23,15,23,16,248,22,75,
23,18,23,18,26,8,2,91,202,203,204,205,206,23,15,248,22,75,23,17,23,
17,90,159,38,11,89,161,38,36,11,249,80,159,40,57,39,23,200,1,23,201,
1,27,248,22,61,28,248,22,148,14,195,248,22,152,14,195,194,27,250,22,87,
28,247,22,128,15,250,22,153,2,248,80,159,47,55,39,10,23,200,2,9,9,
28,80,159,43,49,38,250,22,153,2,248,80,159,47,55,39,11,23,200,1,9,
86,94,23,197,1,9,247,22,190,14,26,8,2,91,200,202,203,205,206,23,17,
200,11,86,95,28,28,248,22,149,14,23,194,2,10,28,248,22,148,14,23,194,
2,10,28,248,22,130,7,23,194,2,28,248,22,170,14,23,194,2,10,248,22,
171,14,23,194,2,11,12,252,22,176,9,23,200,2,2,42,36,23,198,2,23,
199,2,28,28,248,22,130,7,23,195,2,10,248,22,183,7,23,195,2,86,94,
23,194,1,12,252,22,176,9,23,200,2,2,43,37,23,198,2,23,199,1,90,
159,39,11,89,161,39,36,11,248,22,169,14,23,197,2,86,94,23,195,1,86,
94,28,192,12,250,22,177,9,23,201,1,2,44,23,199,1,249,22,7,194,195,
90,159,38,11,89,161,38,36,11,86,95,28,28,248,22,149,14,23,196,2,10,
28,248,22,148,14,23,196,2,10,28,248,22,130,7,23,196,2,28,248,22,170,
14,23,196,2,10,248,22,171,14,23,196,2,11,12,252,22,176,9,2,25,2,
42,36,23,200,2,23,201,2,28,28,248,22,130,7,23,197,2,10,248,22,183,
7,23,197,2,12,252,22,176,9,2,25,2,43,37,23,200,2,23,201,2,90,
159,39,11,89,161,39,36,11,248,22,169,14,23,199,2,86,94,23,195,1,86,
94,28,192,12,250,22,177,9,2,25,2,44,23,201,2,249,22,7,194,195,27,
249,22,158,14,250,22,146,15,0,20,35,114,120,35,34,40,63,58,91,46,93,
91,94,46,93,42,124,41,36,34,248,22,154,14,23,201,1,28,248,22,130,7,
23,203,2,249,22,145,8,23,204,1,8,63,23,202,1,28,248,22,149,14,23,
199,2,248,22,150,14,23,199,1,86,94,23,198,1,247,22,151,14,28,248,22,
148,14,194,249,22,166,14,195,194,192,90,159,38,11,89,161,38,36,11,86,95,
28,28,248,22,149,14,23,196,2,10,28,248,22,148,14,23,196,2,10,28,248,
22,130,7,23,196,2,28,248,22,170,14,23,196,2,10,248,22,171,14,23,196,
2,11,12,252,22,176,9,2,26,2,42,36,23,200,2,23,201,2,28,28,248,
22,130,7,23,197,2,10,248,22,183,7,23,197,2,12,252,22,176,9,2,26,
2,43,37,23,200,2,23,201,2,90,159,39,11,89,161,39,36,11,248,22,169,
14,23,199,2,86,94,23,195,1,86,94,28,192,12,250,22,177,9,2,26,2,
44,23,201,2,249,22,7,194,195,27,249,22,158,14,249,22,131,8,250,22,147,
15,0,9,35,114,120,35,34,91,46,93,34,248,22,154,14,23,203,1,6,1,
1,95,28,248,22,130,7,23,202,2,249,22,145,8,23,203,1,8,63,23,201,
1,28,248,22,149,14,23,199,2,248,22,150,14,23,199,1,86,94,23,198,1,
247,22,151,14,28,248,22,148,14,194,249,22,166,14,195,194,192,90,159,38,11,
89,161,38,36,11,86,95,28,28,248,22,149,14,23,196,2,10,28,248,22,148,
14,23,196,2,10,28,248,22,130,7,23,196,2,28,248,22,170,14,23,196,2,
10,248,22,171,14,23,196,2,11,12,252,22,176,9,2,12,2,29,36,23,200,
2,23,201,2,28,28,248,22,130,7,23,197,2,10,248,22,183,7,23,197,2,
12,252,22,176,9,2,12,2,30,37,23,200,2,23,201,2,90,159,39,11,89,
161,39,36,11,248,22,169,14,23,199,2,86,94,23,195,1,86,94,28,192,12,
250,22,177,9,2,12,2,31,23,201,2,249,22,7,194,195,27,249,22,158,14,
249,22,131,8,250,22,147,15,0,9,35,114,120,35,34,91,46,93,34,248,22,
154,14,23,203,1,6,1,1,95,28,248,22,130,7,23,202,2,249,22,145,8,
23,203,1,8,63,23,201,1,28,248,22,149,14,23,199,2,248,22,150,14,23,
199,1,86,94,23,198,1,247,22,151,14,28,248,22,148,14,194,249,22,166,14,
195,194,192,249,247,22,158,5,194,11,27,247,22,128,15,249,80,158,39,49,28,
23,195,2,27,248,22,150,8,2,32,28,192,192,2,33,2,34,27,28,23,196,
1,250,22,166,14,248,22,188,14,2,35,247,22,148,8,2,36,11,27,248,80,
159,42,54,39,250,22,87,9,248,22,83,248,22,188,14,2,37,9,28,193,249,
22,73,195,194,192,27,247,22,128,15,249,80,158,39,49,28,23,195,2,27,248,
22,150,8,2,32,28,192,192,2,33,2,34,27,28,23,196,1,250,22,166,14,
248,22,188,14,2,35,247,22,148,8,2,36,11,27,248,80,159,42,55,39,250,
22,87,23,203,1,248,22,83,248,22,188,14,2,37,9,28,193,249,22,73,195,
194,192,27,247,22,128,15,249,80,158,39,49,28,23,195,2,27,248,22,150,8,
2,32,28,192,192,2,33,2,34,27,28,23,196,1,250,22,166,14,248,22,188,
14,2,35,247,22,148,8,2,36,11,27,27,250,22,87,23,203,1,248,22,83,
248,22,188,14,2,37,23,204,1,28,248,22,81,23,194,2,9,27,248,22,74,
23,195,2,27,28,248,22,172,14,23,195,2,23,194,1,28,248,22,171,14,23,
195,2,249,22,173,14,23,196,1,250,80,158,49,50,248,22,188,14,2,21,11,
10,250,80,158,47,50,248,22,188,14,2,21,23,197,1,10,28,23,193,2,249,
22,73,248,22,175,14,249,22,173,14,23,198,1,247,22,189,14,248,80,159,47,
56,39,248,22,75,23,199,1,86,94,23,193,1,248,80,159,45,56,39,248,22,
75,23,197,1,28,193,249,22,73,195,194,192,32,67,88,163,8,36,39,57,11,
2,20,222,33,69,0,8,35,114,120,35,34,92,34,34,27,249,22,135,15,23,
197,2,23,198,2,28,23,193,2,86,94,23,196,1,27,248,22,98,23,195,2,
27,27,248,22,107,23,197,1,27,249,22,135,15,23,201,2,23,196,2,28,23,
193,2,86,94,23,194,1,27,248,22,98,23,195,2,27,250,2,67,23,203,2,
23,204,1,248,22,107,23,199,1,28,249,22,191,7,23,196,2,2,38,249,22,
87,23,202,2,194,249,22,73,248,22,157,14,28,249,22,140,9,247,22,152,8,
2,22,250,22,147,15,2,68,23,200,1,2,39,23,197,1,194,86,95,23,199,
1,23,193,1,28,249,22,191,7,23,196,2,2,38,249,22,87,23,200,2,9,
249,22,73,248,22,157,14,28,249,22,140,9,247,22,152,8,2,22,250,22,147,
15,2,68,23,200,1,2,39,23,197,1,9,28,249,22,191,7,23,196,2,2,
38,249,22,87,197,194,86,94,23,196,1,249,22,73,248,22,157,14,28,249,22,
140,9,247,22,152,8,2,22,250,22,147,15,2,68,23,200,1,2,39,23,197,
1,194,86,94,23,193,1,28,249,22,191,7,23,198,2,2,38,249,22,87,195,
9,86,94,23,194,1,249,22,73,248,22,157,14,28,249,22,140,9,247,22,152,
8,2,22,250,22,147,15,2,68,23,202,1,2,39,23,199,1,9,86,95,28,
28,248,22,183,7,194,10,248,22,130,7,194,12,250,22,176,9,2,15,6,21,
21,98,121,116,101,32,115,116,114,105,110,103,32,111,114,32,115,116,114,105,110,
103,196,28,28,248,22,82,195,249,22,4,22,148,14,196,11,12,250,22,176,9,
2,15,6,13,13,108,105,115,116,32,111,102,32,112,97,116,104,115,197,250,2,
67,197,195,28,248,22,130,7,197,248,22,144,8,197,196,32,71,88,163,8,36,
39,53,11,70,102,111,117,110,100,45,101,120,101,99,222,33,74,32,72,88,163,
8,36,40,58,11,64,110,101,120,116,222,33,73,27,248,22,174,14,23,196,2,
28,249,22,142,9,23,195,2,23,197,1,11,28,248,22,170,14,23,194,2,27,
249,22,166,14,23,197,1,23,196,1,28,23,197,2,90,159,39,11,89,161,39,
36,11,248,22,169,14,23,197,2,86,95,23,195,1,23,194,1,27,28,23,202,
2,27,248,22,174,14,23,199,2,28,249,22,142,9,23,195,2,23,200,2,11,
28,248,22,170,14,23,194,2,250,2,71,23,205,2,23,206,2,249,22,166,14,
23,200,2,23,198,1,250,2,71,23,205,2,23,206,2,23,196,1,11,28,23,
193,2,192,86,94,23,193,1,27,28,248,22,148,14,23,196,2,27,249,22,166,
14,23,198,2,23,205,2,28,28,248,22,161,14,193,10,248,22,160,14,193,192,
11,11,28,23,193,2,192,86,94,23,193,1,28,23,203,2,11,27,248,22,174,
14,23,200,2,28,249,22,142,9,23,195,2,23,201,1,11,28,248,22,170,14,
23,194,2,250,2,71,23,206,1,23,207,1,249,22,166,14,23,201,1,23,198,
1,250,2,71,205,206,195,192,86,94,23,194,1,28,23,196,2,90,159,39,11,
89,161,39,36,11,248,22,169,14,23,197,2,86,95,23,195,1,23,194,1,27,
28,23,201,2,27,248,22,174,14,23,199,2,28,249,22,142,9,23,195,2,23,
200,2,11,28,248,22,170,14,23,194,2,250,2,71,23,204,2,23,205,2,249,
22,166,14,23,200,2,23,198,1,250,2,71,23,204,2,23,205,2,23,196,1,
11,28,23,193,2,192,86,94,23,193,1,27,28,248,22,148,14,23,196,2,27,
249,22,166,14,23,198,2,23,204,2,28,28,248,22,161,14,193,10,248,22,160,
14,193,192,11,11,28,23,193,2,192,86,94,23,193,1,28,23,202,2,11,27,
248,22,174,14,23,200,2,28,249,22,142,9,23,195,2,23,201,1,11,28,248,
22,170,14,23,194,2,250,2,71,23,205,1,23,206,1,249,22,166,14,23,201,
1,23,198,1,250,2,71,204,205,195,192,28,23,193,2,90,159,39,11,89,161,
39,36,11,248,22,169,14,23,199,2,86,95,23,195,1,23,194,1,27,28,23,
198,2,251,2,72,23,198,2,23,203,2,23,201,2,23,202,2,11,28,23,193,
2,192,86,94,23,193,1,27,28,248,22,148,14,195,27,249,22,166,14,197,200,
28,28,248,22,161,14,193,10,248,22,160,14,193,192,11,11,28,192,192,28,198,
11,251,2,72,198,203,201,202,194,32,75,88,163,8,36,40,58,11,2,20,222,
33,76,28,248,22,81,23,197,2,11,27,248,22,173,14,248,22,74,23,199,2,
27,249,22,166,14,23,196,1,23,197,2,28,248,22,160,14,23,194,2,250,2,
71,198,199,195,86,94,23,193,1,27,248,22,75,23,200,1,28,248,22,81,23,
194,2,11,27,248,22,173,14,248,22,74,23,196,2,27,249,22,166,14,23,196,
1,23,200,2,28,248,22,160,14,23,194,2,250,2,71,201,202,195,86,94,23,
193,1,27,248,22,75,23,197,1,28,248,22,81,23,194,2,11,27,248,22,173,
14,248,22,74,195,27,249,22,166,14,23,196,1,202,28,248,22,160,14,193,250,
2,71,204,205,195,251,2,75,204,205,206,248,22,75,199,86,95,28,28,248,22,
148,14,23,195,2,10,28,248,22,130,7,23,195,2,28,248,22,170,14,23,195,
2,10,248,22,171,14,23,195,2,11,12,250,22,176,9,2,16,6,25,25,112,
97,116,104,32,111,114,32,115,116,114,105,110,103,32,40,115,97,110,115,32,110,
117,108,41,23,197,2,28,28,23,195,2,28,28,248,22,148,14,23,196,2,10,
28,248,22,130,7,23,196,2,28,248,22,170,14,23,196,2,10,248,22,171,14,
23,196,2,11,248,22,170,14,23,196,2,11,10,12,250,22,176,9,2,16,6,
29,29,35,102,32,111,114,32,114,101,108,97,116,105,118,101,32,112,97,116,104,
32,111,114,32,115,116,114,105,110,103,23,198,2,28,28,248,22,170,14,23,195,
2,90,159,39,11,89,161,39,36,11,248,22,169,14,23,198,2,249,22,140,9,
194,68,114,101,108,97,116,105,118,101,11,27,248,22,150,8,6,4,4,80,65,
84,72,27,28,23,194,2,27,249,80,159,41,49,38,23,197,1,9,28,249,22,
140,9,247,22,152,8,2,22,249,22,73,248,22,157,14,5,1,46,194,192,86,
94,23,194,1,9,28,248,22,81,23,194,2,11,27,248,22,173,14,248,22,74,
23,196,2,27,249,22,166,14,23,196,1,23,200,2,28,248,22,160,14,23,194,
2,250,2,71,201,202,195,86,94,23,193,1,27,248,22,75,23,197,1,28,248,
22,81,23,194,2,11,27,248,22,173,14,248,22,74,23,196,2,27,249,22,166,
14,23,196,1,23,203,2,28,248,22,160,14,23,194,2,250,2,71,204,205,195,
86,94,23,193,1,27,248,22,75,23,197,1,28,248,22,81,23,194,2,11,27,
248,22,173,14,248,22,74,195,27,249,22,166,14,23,196,1,205,28,248,22,160,
14,193,250,2,71,23,15,23,16,195,251,2,75,23,15,23,16,23,17,248,22,
75,199,27,248,22,173,14,23,196,1,28,248,22,160,14,193,250,2,71,198,199,
195,11,250,80,159,39,50,39,196,197,11,250,80,159,39,50,39,196,11,11,86,
94,249,22,183,6,247,22,154,5,195,248,22,145,6,249,22,128,4,36,249,22,
176,3,197,198,27,28,23,197,2,86,95,23,196,1,23,195,1,23,197,1,86,
94,23,197,1,27,248,22,188,14,2,21,27,250,80,159,42,50,39,23,197,1,
11,11,27,248,22,131,4,23,199,1,27,28,23,194,2,23,194,1,86,94,23,
194,1,36,27,248,22,131,4,23,202,1,27,28,23,194,2,23,194,1,86,94,
23,194,1,36,249,22,185,5,23,199,1,20,20,95,88,163,8,36,36,48,11,
9,224,4,2,33,80,23,195,1,23,197,1,27,248,22,170,5,23,195,1,248,
80,159,39,57,39,193,159,36,20,112,159,36,16,1,11,16,0,20,26,142,2,
1,2,1,29,11,11,11,11,11,10,43,80,158,36,36,20,112,159,40,16,18,
2,2,2,3,2,4,2,5,2,6,2,7,2,8,2,9,2,10,2,11,2,
12,2,13,2,14,2,15,2,16,2,17,30,2,19,1,20,112,97,114,97,109,
101,116,101,114,105,122,97,116,105,111,110,45,107,101,121,5,30,2,19,1,23,
101,120,116,101,110,100,45,112,97,114,97,109,101,116,101,114,105,122,97,116,105,
111,110,3,16,0,16,0,36,16,0,36,16,4,2,6,2,5,2,3,2,10,
40,11,11,39,36,11,11,16,12,2,9,2,7,2,17,2,8,2,16,2,14,
2,13,2,4,2,12,2,15,2,11,2,2,16,12,11,11,11,11,11,11,11,
11,11,11,11,11,16,12,2,9,2,7,2,17,2,8,2,16,2,14,2,13,
2,4,2,12,2,15,2,11,2,2,48,48,37,11,11,16,0,16,0,16,0,
36,36,11,11,11,16,0,16,0,16,0,36,36,16,0,16,20,20,15,16,2,
88,163,8,36,37,51,8,240,0,0,35,0,2,20,223,0,33,40,80,159,36,
57,39,20,15,16,2,88,163,8,36,37,56,8,240,0,64,16,0,2,20,223,
0,33,41,80,159,36,56,39,20,15,16,2,88,163,8,36,37,51,8,240,0,
64,8,0,2,20,223,0,33,42,80,159,36,55,39,20,15,16,2,88,163,8,
36,37,51,8,240,0,64,4,0,2,20,223,0,33,43,80,159,36,54,39,20,
15,16,2,32,0,88,163,36,37,45,11,2,2,222,33,44,80,159,36,36,37,
20,15,16,2,249,22,132,7,7,92,7,92,80,159,36,37,37,20,15,16,2,
88,163,36,37,54,38,2,4,223,0,33,45,80,159,36,38,37,20,15,16,2,
32,0,88,163,8,36,38,50,11,2,5,222,33,46,80,159,36,39,37,20,15,
16,2,32,0,88,163,8,36,39,51,11,2,6,222,33,48,80,159,36,40,37,
20,15,16,2,32,0,88,163,8,45,38,54,11,2,7,222,33,52,80,159,36,
41,37,20,15,16,2,32,0,88,163,45,39,53,11,2,9,222,33,56,80,159,
36,43,37,20,15,16,2,32,0,88,163,36,41,59,11,2,8,222,33,59,80,
159,36,42,37,20,15,16,2,32,0,88,163,36,39,50,11,2,10,222,33,60,
80,159,36,44,37,20,15,16,2,32,0,88,163,36,38,53,11,2,11,222,33,
61,80,159,36,45,37,20,15,16,2,32,0,88,163,36,38,54,11,2,12,222,
33,62,80,159,36,46,37,20,15,16,2,32,0,88,163,36,37,44,11,2,13,
222,33,63,80,159,36,47,37,20,15,16,2,20,25,96,2,14,88,163,36,36,
53,8,240,0,32,4,0,9,223,0,33,64,88,163,36,37,54,8,240,0,32,
8,0,9,223,0,33,65,88,163,36,38,58,8,240,0,96,16,0,9,223,0,
33,66,80,159,36,48,37,20,15,16,2,27,248,22,131,15,248,22,144,8,27,
28,249,22,140,9,247,22,152,8,2,22,6,1,1,59,6,1,1,58,250,22,
178,7,6,14,14,40,91,94,126,97,93,42,41,126,97,40,46,42,41,23,196,
2,23,196,1,88,163,8,36,38,48,11,2,15,223,0,33,70,80,159,36,49,
37,20,15,16,2,20,25,96,2,16,88,163,8,36,39,8,24,8,128,128,9,
223,0,33,77,88,163,8,36,38,47,8,240,0,64,0,0,9,223,0,33,78,
88,163,8,36,37,46,8,240,0,64,0,0,9,223,0,33,79,80,159,36,50,
37,20,15,16,2,88,163,8,36,39,54,8,240,0,64,32,0,2,17,223,0,
33,81,80,159,36,51,37,94,29,94,2,18,68,35,37,107,101,114,110,101,108,
11,29,94,2,18,69,35,37,109,105,110,45,115,116,120,11,9,9,9,36,0};
EVAL_ONE_SIZED_STR((char *)expr, 8399);
247,22,151,14,28,248,22,148,14,194,249,22,166,14,195,194,192,249,247,22,158,
5,194,11,27,247,22,128,15,249,80,159,39,40,38,28,23,195,2,27,248,22,
150,8,2,45,28,192,192,2,46,2,47,27,28,23,196,1,250,22,166,14,248,
22,188,14,2,48,247,22,148,8,2,49,11,27,248,80,159,42,8,28,39,250,
22,87,9,248,22,83,248,22,188,14,2,38,9,28,193,249,22,73,195,194,192,
27,247,22,128,15,249,80,159,39,40,38,28,23,195,2,27,248,22,150,8,2,
45,28,192,192,2,46,2,47,27,28,23,196,1,250,22,166,14,248,22,188,14,
2,48,247,22,148,8,2,49,11,27,248,80,159,42,8,29,39,250,22,87,23,
203,1,248,22,83,248,22,188,14,2,38,9,28,193,249,22,73,195,194,192,27,
247,22,128,15,249,80,159,39,40,38,28,23,195,2,27,248,22,150,8,2,45,
28,192,192,2,46,2,47,27,28,23,196,1,250,22,166,14,248,22,188,14,2,
48,247,22,148,8,2,49,11,27,248,80,159,42,8,30,39,250,22,87,23,203,
1,248,22,83,248,22,188,14,2,38,23,204,1,28,193,249,22,73,195,194,192,
86,94,249,22,183,6,247,22,154,5,195,248,22,145,6,249,22,128,4,36,249,
22,176,3,197,198,27,28,23,197,2,86,95,23,196,1,23,195,1,23,197,1,
86,94,23,197,1,27,248,22,188,14,2,31,27,250,80,159,42,39,39,23,197,
1,11,11,27,248,22,131,4,23,199,1,27,28,23,194,2,23,194,1,86,94,
23,194,1,36,27,248,22,131,4,23,202,1,27,28,23,194,2,23,194,1,86,
94,23,194,1,36,249,22,185,5,23,199,1,20,20,95,88,163,8,36,36,48,
11,9,224,4,2,33,105,23,195,1,23,197,1,27,248,22,170,5,23,195,1,
248,80,159,39,8,31,39,193,159,36,20,112,159,36,16,1,11,16,0,20,26,
142,2,1,2,1,29,11,11,11,11,11,10,43,80,158,36,36,20,112,159,40,
16,28,2,2,2,3,2,4,2,5,2,6,2,7,2,8,2,9,2,10,2,
11,2,12,2,13,2,14,2,15,30,2,18,76,102,105,110,100,45,108,105,110,
107,115,45,112,97,116,104,33,4,30,2,19,1,20,112,97,114,97,109,101,116,
101,114,105,122,97,116,105,111,110,45,107,101,121,6,30,2,19,1,23,101,120,
116,101,110,100,45,112,97,114,97,109,101,116,101,114,105,122,97,116,105,111,110,
3,2,20,2,21,2,22,30,2,18,1,21,101,120,99,101,112,116,105,111,110,
45,104,97,110,100,108,101,114,45,107,101,121,2,2,23,2,24,2,25,2,26,
2,27,2,28,2,29,16,0,16,0,36,16,0,36,16,12,2,8,2,7,2,
3,2,24,2,22,2,20,2,15,2,21,2,23,2,13,2,12,2,14,48,11,
11,39,36,11,11,16,12,2,11,2,9,2,29,2,10,2,5,2,28,2,27,
2,4,2,26,2,6,2,25,2,2,16,12,11,11,11,11,11,11,11,11,11,
11,11,11,16,12,2,11,2,9,2,29,2,10,2,5,2,28,2,27,2,4,
2,26,2,6,2,25,2,2,48,48,37,11,11,16,0,16,0,16,0,36,36,
11,11,11,16,0,16,0,16,0,36,36,16,0,16,28,20,15,16,2,88,163,
8,36,37,51,16,2,8,240,0,128,0,0,8,240,1,128,0,0,2,30,223,
0,33,50,80,159,36,8,31,39,20,15,16,2,88,163,8,36,37,56,16,2,
44,8,240,0,64,0,0,2,30,223,0,33,51,80,159,36,8,30,39,20,15,
16,2,88,163,8,36,37,51,16,2,44,8,128,128,2,30,223,0,33,52,80,
159,36,8,29,39,20,15,16,2,88,163,8,36,37,51,16,2,44,8,128,64,
2,30,223,0,33,53,80,159,36,8,28,39,20,15,16,2,32,0,88,163,36,
37,45,11,2,2,222,33,54,80,159,36,36,37,20,15,16,2,249,22,132,7,
7,92,7,92,80,159,36,37,37,20,15,16,2,88,163,36,37,54,38,2,4,
223,0,33,55,80,159,36,38,37,20,15,16,2,20,25,96,2,5,88,163,8,
36,39,8,24,52,9,223,0,33,62,88,163,36,38,47,44,9,223,0,33,63,
88,163,36,37,46,44,9,223,0,33,64,80,159,36,39,37,20,15,16,2,27,
248,22,131,15,248,22,144,8,27,28,249,22,140,9,247,22,152,8,2,32,6,
1,1,59,6,1,1,58,250,22,178,7,6,14,14,40,91,94,126,97,93,42,
41,126,97,40,46,42,41,23,196,2,23,196,1,88,163,8,36,38,48,11,2,
6,223,0,33,68,80,159,36,40,37,20,15,16,2,32,0,88,163,8,36,38,
50,11,2,7,222,33,69,80,159,36,41,37,20,15,16,2,32,0,88,163,8,
36,39,51,11,2,8,222,33,71,80,159,36,42,37,20,15,16,2,88,163,45,
38,51,8,128,4,2,9,223,0,33,74,80,159,36,43,37,20,15,16,2,88,
163,45,39,52,8,128,4,2,11,223,0,33,77,80,159,36,45,37,20,15,16,
2,248,22,188,14,70,108,105,110,107,115,45,102,105,108,101,80,159,36,46,37,
20,15,16,2,247,22,133,2,80,158,36,47,20,15,16,2,2,78,80,158,36,
48,20,15,16,2,248,80,159,37,50,37,88,163,36,36,49,8,240,8,128,1,
0,9,223,1,33,79,80,159,36,49,37,20,15,16,2,247,22,133,2,80,158,
36,53,20,15,16,2,2,78,80,158,36,54,20,15,16,2,88,163,36,37,44,
8,240,0,188,23,0,2,22,223,0,33,88,80,159,36,55,37,20,15,16,2,
88,163,36,38,56,8,240,0,0,32,0,2,23,223,0,33,90,80,159,36,57,
37,20,15,16,2,88,163,36,41,59,8,240,0,32,40,0,2,10,223,0,33,
97,80,159,36,44,37,20,15,16,2,32,0,88,163,36,39,50,11,2,24,222,
33,98,80,159,36,58,37,20,15,16,2,32,0,88,163,36,38,53,11,2,25,
222,33,99,80,159,36,59,37,20,15,16,2,32,0,88,163,36,38,54,11,2,
26,222,33,100,80,159,36,8,24,37,20,15,16,2,32,0,88,163,36,37,44,
11,2,27,222,33,101,80,159,36,8,25,37,20,15,16,2,20,25,96,2,28,
88,163,36,36,53,16,2,52,8,128,64,9,223,0,33,102,88,163,36,37,54,
16,2,52,8,128,128,9,223,0,33,103,88,163,36,38,55,16,2,52,8,240,
0,64,0,0,9,223,0,33,104,80,159,36,8,26,37,20,15,16,2,88,163,
8,36,39,54,16,2,44,8,240,0,128,0,0,2,29,223,0,33,106,80,159,
36,8,27,37,95,29,94,2,16,68,35,37,107,101,114,110,101,108,11,29,94,
2,16,69,35,37,109,105,110,45,115,116,120,11,2,18,9,9,9,36,0};
EVAL_ONE_SIZED_STR((char *)expr, 10204);
}
{
SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,49,46,51,46,50,0,0,0,0,0,0,0,0,0,0,0,
SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,49,46,51,46,53,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,12,0,0,0,1,0,0,15,0,40,0,57,
0,75,0,97,0,120,0,140,0,162,0,169,0,176,0,183,0,0,0,178,1,
0,0,74,35,37,112,108,97,99,101,45,115,116,114,117,99,116,1,23,115,116,
@ -528,7 +614,7 @@
EVAL_ONE_SIZED_STR((char *)expr, 499);
}
{
SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,49,46,51,46,50,0,0,0,0,0,0,0,0,0,0,0,
SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,49,46,51,46,53,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,65,0,0,0,1,0,0,7,0,18,0,45,
0,51,0,64,0,73,0,80,0,102,0,124,0,150,0,158,0,170,0,185,0,
201,0,219,0,239,0,251,0,11,1,34,1,46,1,77,1,84,1,89,1,94,
@ -788,14 +874,14 @@
142,2,1,2,1,29,11,11,11,11,11,10,38,80,158,36,36,20,112,159,40,
16,26,2,2,2,3,30,2,5,72,112,97,116,104,45,115,116,114,105,110,103,
63,11,30,2,5,75,112,97,116,104,45,97,100,100,45,115,117,102,102,105,120,
8,30,2,7,2,8,5,30,2,7,1,23,101,120,116,101,110,100,45,112,97,
8,30,2,7,2,8,6,30,2,7,1,23,101,120,116,101,110,100,45,112,97,
114,97,109,101,116,101,114,105,122,97,116,105,111,110,3,2,9,2,10,2,11,
2,12,2,13,2,14,2,15,2,16,2,17,2,18,2,19,2,20,2,21,30,
2,22,2,8,5,30,2,5,79,112,97,116,104,45,114,101,112,108,97,99,101,
2,22,2,8,6,30,2,5,79,112,97,116,104,45,114,101,112,108,97,99,101,
45,115,117,102,102,105,120,10,30,2,5,73,102,105,110,100,45,99,111,108,45,
102,105,108,101,3,30,2,5,76,110,111,114,109,97,108,45,99,97,115,101,45,
112,97,116,104,7,2,23,2,24,30,2,22,74,114,101,112,97,114,97,109,101,
116,101,114,105,122,101,6,16,0,16,0,36,16,0,36,16,14,2,15,2,16,
116,101,114,105,122,101,7,16,0,16,0,36,16,0,36,16,14,2,15,2,16,
2,10,2,12,2,17,2,18,2,11,2,3,2,9,2,2,2,13,2,14,2,
19,2,21,50,11,11,39,36,11,11,16,3,2,23,2,20,2,24,16,3,11,
11,11,16,3,2,23,2,20,2,24,39,39,37,11,11,16,0,16,0,16,0,
@ -829,7 +915,7 @@
EVAL_ONE_SIZED_STR((char *)expr, 6244);
}
{
SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,49,46,51,46,50,0,0,0,0,0,0,0,0,0,0,0,
SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,49,46,51,46,53,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,11,0,0,0,1,0,0,10,0,16,0,29,
0,44,0,58,0,78,0,90,0,104,0,118,0,170,0,0,0,97,1,0,0,
69,35,37,98,117,105,108,116,105,110,65,113,117,111,116,101,29,94,2,2,67,
@ -837,7 +923,7 @@
107,11,29,94,2,2,68,35,37,112,97,114,97,109,122,11,29,94,2,2,74,
35,37,112,108,97,99,101,45,115,116,114,117,99,116,11,29,94,2,2,66,35,
37,98,111,111,116,11,29,94,2,2,68,35,37,101,120,112,111,98,115,11,29,
94,2,2,68,35,37,107,101,114,110,101,108,11,97,36,11,8,240,204,77,0,
94,2,2,68,35,37,107,101,114,110,101,108,11,97,36,11,8,240,28,78,0,
0,100,159,2,3,36,36,159,2,4,36,36,159,2,5,36,36,159,2,6,36,
36,159,2,7,36,36,159,2,8,36,36,159,2,9,36,36,159,2,9,36,36,
16,0,159,36,20,112,159,36,16,1,11,16,0,20,26,142,2,1,2,1,29,

View File

@ -227,12 +227,15 @@ READ_ONLY static Scheme_Object *doc_dir_symbol, *desk_dir_symbol;
READ_ONLY static Scheme_Object *init_dir_symbol, *init_file_symbol, *sys_dir_symbol;
READ_ONLY static Scheme_Object *exec_file_symbol, *run_file_symbol, *collects_dir_symbol;
READ_ONLY static Scheme_Object *pref_file_symbol, *orig_dir_symbol, *addon_dir_symbol;
READ_ONLY static Scheme_Object *links_file_symbol;
SHARED_OK static Scheme_Object *exec_cmd;
SHARED_OK static Scheme_Object *run_cmd;
SHARED_OK static Scheme_Object *collects_path;
THREAD_LOCAL_DECL(static Scheme_Object *original_pwd);
SHARED_OK static Scheme_Object *addon_dir;
SHARED_OK static Scheme_Object *links_file;
THREAD_LOCAL_DECL(static Scheme_Object *inst_links_path);
#endif
READ_ONLY static Scheme_Object *windows_symbol, *unix_symbol;
@ -275,6 +278,7 @@ void scheme_init_file(Scheme_Env *env)
REGISTER_SO(collects_dir_symbol);
REGISTER_SO(orig_dir_symbol);
REGISTER_SO(addon_dir_symbol);
REGISTER_SO(links_file_symbol);
#endif
REGISTER_SO(windows_symbol);
REGISTER_SO(unix_symbol);
@ -302,6 +306,7 @@ void scheme_init_file(Scheme_Env *env)
collects_dir_symbol = scheme_intern_symbol("collects-dir");
orig_dir_symbol = scheme_intern_symbol("orig-dir");
addon_dir_symbol = scheme_intern_symbol("addon-dir");
links_file_symbol = scheme_intern_symbol("links-file");
#endif
windows_symbol = scheme_intern_symbol("windows");
@ -5826,7 +5831,8 @@ enum {
id_init_dir,
id_init_file,
id_sys_dir,
id_addon_dir
id_addon_dir,
id_links_file
};
Scheme_Object *scheme_get_run_cmd(void)
@ -5877,6 +5883,15 @@ find_system_path(int argc, Scheme_Object **argv)
} else if (argv[0] == addon_dir_symbol) {
if (addon_dir) return addon_dir;
which = id_addon_dir;
} else if (argv[0] == links_file_symbol) {
if (links_file) return links_file;
if (addon_dir) {
Scheme_Object *pa[2];
pa[0] = addon_dir;
pa[1] = scheme_make_path("links.rktd");
return scheme_build_path(2, pa);
}
which = id_links_file;
} else {
scheme_wrong_type("find-system-path", "system-path-symbol",
0, argc, argv);
@ -5919,9 +5934,11 @@ find_system_path(int argc, Scheme_Object **argv)
if ((which == id_pref_dir)
|| (which == id_pref_file)
|| (which == id_addon_dir)) {
|| (which == id_addon_dir)
|| (which == id_links_file)) {
#if defined(OS_X) && !defined(XONX)
if (which == id_addon_dir)
if ((which == id_addon_dir)
|| (which == id_links_file))
home_str = "~/Library/Racket/";
else
home_str = "~/Library/Preferences/";
@ -5968,6 +5985,8 @@ find_system_path(int argc, Scheme_Object **argv)
return append_path(home, scheme_make_path("/racket-prefs.rktd" + ends_in_slash));
#endif
}
if (which == id_links_file)
return append_path(home, scheme_make_path("/links.rktd" + ends_in_slash));
}
#endif
@ -6005,7 +6024,8 @@ find_system_path(int argc, Scheme_Object **argv)
if ((which == id_addon_dir)
|| (which == id_pref_dir)
|| (which == id_pref_file))
|| (which == id_pref_file)
|| (which == id_links_file))
which_folder = CSIDL_APPDATA;
else if (which == id_doc_dir) {
# ifndef CSIDL_PERSONAL
@ -6109,6 +6129,8 @@ find_system_path(int argc, Scheme_Object **argv)
return append_path(home, scheme_make_path("\\racketrc.rktl" + ends_in_slash));
if (which == id_pref_file)
return append_path(home, scheme_make_path("\\racket-prefs.rktd" + ends_in_slash));
if (which == id_links_file)
return append_path(home, scheme_make_path("\\links.rktd" + ends_in_slash));
return home;
}
#endif
@ -6177,6 +6199,26 @@ void scheme_set_addon_dir(Scheme_Object *p)
addon_dir = p;
}
/* should only called from main */
void scheme_set_links_file(Scheme_Object *p)
{
if (!links_file) {
REGISTER_SO(links_file);
}
links_file = p;
}
Scheme_Object *scheme_find_links_path(int argc, Scheme_Object *argv[])
{
if (inst_links_path)
return inst_links_path;
REGISTER_SO(inst_links_path);
inst_links_path = scheme_apply(argv[0], 0, NULL);
return inst_links_path;
}
/********************************************************************************/
#ifdef DOS_FILE_SYSTEM

View File

@ -3358,6 +3358,8 @@ Scheme_Object *scheme_get_fd_identity(Scheme_Object *port, intptr_t fd, char *pa
Scheme_Object *scheme_extract_relative_to(Scheme_Object *obj, Scheme_Object *dir);
Scheme_Object *scheme_find_links_path(int argc, Scheme_Object *argv[]);
#ifdef DOS_FILE_SYSTEM
# define WIDE_PATH(s) scheme_convert_to_wchar(s, 0)
# define WIDE_PATH_COPY(s) scheme_convert_to_wchar(s, 1)

View File

@ -13,12 +13,12 @@
consistently.)
*/
#define MZSCHEME_VERSION "5.1.3.3"
#define MZSCHEME_VERSION "5.1.3.5"
#define MZSCHEME_VERSION_X 5
#define MZSCHEME_VERSION_Y 1
#define MZSCHEME_VERSION_Z 3
#define MZSCHEME_VERSION_W 3
#define MZSCHEME_VERSION_W 5
#define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y)
#define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W)

View File

@ -133,7 +133,7 @@
);
EVAL_ONE_STR(
"(module #%utils '#%kernel"
"(#%require '#%min-stx)"
"(#%require '#%min-stx '#%paramz)"
"(#%provide path-string?"
" normal-case-path"
" path-replace-suffix"
@ -178,6 +178,83 @@
" 'windows)))))"
"((string? s)(string->path s))"
"(else s))))"
"(define-values(find-executable-path)"
"(case-lambda "
"((program libpath reverse?)"
"(unless(path-string? program) "
" (raise-type-error 'find-executable-path \"path or string (sans nul)\" program))"
"(unless(or(not libpath)(and(path-string? libpath) "
"(relative-path? libpath)))"
" (raise-type-error 'find-executable-path \"#f or relative path or string\" libpath))"
"(letrec((found-exec"
"(lambda(exec-name)"
"(if libpath"
"(let-values(((base name isdir?)(split-path exec-name)))"
"(let((next"
"(lambda()"
"(let((resolved(resolve-path exec-name)))"
"(cond"
"((equal? resolved exec-name) #f)"
"((relative-path? resolved)"
"(found-exec(build-path base resolved)))"
"(else(found-exec resolved)))))))"
"(or(and reverse?(next))"
"(if(path? base)"
"(let((lib(build-path base libpath)))"
"(and(or(directory-exists? lib) "
"(file-exists? lib))"
" lib))"
" #f)"
"(and(not reverse?)(next)))))"
" exec-name))))"
"(if(and(relative-path? program)"
"(let-values(((base name dir?)(split-path program)))"
"(eq? base 'relative)))"
" (let ((paths-str (getenv \"PATH\"))"
"(win-add(lambda(s)(if(eq?(system-type) 'windows) "
" (cons (bytes->path #\".\") s) "
" s))))"
"(let loop((paths(if paths-str "
"(win-add(path-list-string->path-list paths-str null))"
" null)))"
"(if(null? paths)"
" #f"
"(let*((base(path->complete-path(car paths)))"
"(name(build-path base program)))"
"(if(file-exists? name)"
"(found-exec name)"
"(loop(cdr paths)))))))"
"(let((p(path->complete-path program)))"
"(and(file-exists? p)(found-exec p))))))"
"((program libpath)(find-executable-path program libpath #f))"
"((program)(find-executable-path program #f #f))))"
"(define-values(path-list-string->path-list)"
"(let((r(byte-regexp(string->bytes/utf-8"
"(let((sep(if(eq?(system-type) 'windows)"
" \";\"\n"
" \":\")))"
" (format \"([^~a]*)~a(.*)\" sep sep)))))"
"(cons-path(lambda(default s l) "
" (if (bytes=? s #\"\")"
"(append default l)"
"(cons(bytes->path(if(eq?(system-type) 'windows)"
" (regexp-replace* #rx#\"\\\"\" s #\"\")"
" s))"
" l)))))"
"(lambda(s default)"
"(unless(or(bytes? s)"
"(string? s))"
" (raise-type-error 'path-list-string->path-list \"byte string or string\" s))"
"(unless(and(list? default)"
"(andmap path? default))"
" (raise-type-error 'path-list-string->path-list \"list of paths\" default))"
"(let loop((s(if(string? s)"
"(string->bytes/utf-8 s)"
" s)))"
"(let((m(regexp-match r s)))"
"(if m"
"(cons-path default(cadr m)(loop(caddr m)))"
"(cons-path default s null)))))))"
"(define-values(-check-relpath)"
"(lambda(who s)"
"(unless(path-string? s)"
@ -210,23 +287,196 @@
" collection collection-path"
" file-name)"
" file-name)))"
"(define-values(user-links-path)(find-system-path 'links-file))"
"(define-values(user-links-cache)(make-hasheq))"
"(define-values(user-links-timestamp) -inf.0)"
"(define-values(links-path)(find-links-path!"
"(lambda()"
"(let((d(let((c(find-system-path 'collects-dir)))"
"(if(absolute-path? c)"
" c"
"(parameterize((current-directory(find-system-path 'orig-dir)))"
"(find-executable-path(find-system-path 'exec-file) c))))))"
"(and d"
" (build-path d \"config\" \"links.rktd\"))))))"
"(define-values(links-cache)(make-hasheq))"
"(define-values(links-timestamp) -inf.0)"
"(define-values(get-linked-collections)"
"(lambda(user?)"
"(call/ec(lambda(esc)"
"(define-values(make-handler)"
"(lambda(ts)"
"(lambda(exn)"
"(let((l(current-logger)))"
"(when(log-level? l 'error)"
"(log-message l 'error "
"(format"
" \"error reading linked collections: ~a\""
"(exn-message exn))"
"(current-continuation-marks))))"
"(when ts"
"(if user?"
"(begin"
"(set! user-links-cache(make-hasheq))"
"(set! user-links-timestamp ts))"
"(begin"
"(set! links-cache(make-hasheq))"
"(set! links-timestamp ts))))"
"(esc(make-hasheq)))))"
"(with-continuation-mark"
" exception-handler-key"
"(make-handler #f)"
"(let((ts(file-or-directory-modify-seconds(if user?"
" user-links-path"
" links-path)"
" #f "
"(lambda() -inf.0))))"
"(if(ts . > .(if user? user-links-timestamp links-timestamp))"
"(with-continuation-mark"
" exception-handler-key"
"(make-handler ts)"
"(parameterize((read-case-sensitive #t)"
"(read-square-bracket-as-paren #t)"
"(read-curly-brace-as-paren #t)"
"(read-accept-box #t)"
"(read-accept-compiled #t)"
"(read-accept-bar-quote #t)"
"(read-accept-graph #t)"
"(read-decimal-as-inexact #t)"
"(read-accept-dot #t)"
"(read-accept-infix-dot #t)"
"(read-accept-quasiquote #t)"
"(read-accept-reader #t)"
"(read-accept-lang #f)"
"(current-readtable #f))"
"(let((v(let((p(open-input-file(if user? user-links-path links-path)"
" 'binary)))"
"(dynamic-wind"
" void"
"(lambda() "
"(begin0"
"(read p)"
"(unless(eof-object?(read p))"
" (error \"expected a single S-expression\"))))"
"(lambda()(close-input-port p))))))"
"(unless(and(list? v)"
"(andmap(lambda(p)"
"(and(list? p)"
"(or(= 2(length p))"
"(= 3(length p)))"
"(string?(car p))"
"(path-string?(cadr p))"
"(or(null?(cddr p))"
"(regexp?(caddr p)))))"
" v))"
" (error \"ill-formed content\"))"
"(let((ht(make-hasheq))"
"(dir(let-values(((base name dir?)(split-path(if user?"
" user-links-path"
" links-path))))"
" base)))"
"(for-each"
"(lambda(p)"
"(when(or(null?(cddr p))"
"(regexp-match?(caddr p)(version)))"
"(let((s(string->symbol(car p))))"
"(hash-set! ht s(cons(box(path->complete-path(cadr p) dir))"
"(hash-ref ht s null))))))"
" v)"
"(if user?"
"(begin"
"(set! user-links-cache ht)"
"(set! user-links-timestamp ts))"
"(begin"
"(set! links-cache ht)"
"(set! links-timestamp ts)))"
" ht))))"
"(if user?"
" user-links-cache"
" links-cache))))))))"
"(define-values(normalize-collection-reference)"
"(lambda(collection collection-path)"
"(cond"
"((string? collection)"
" (let ((m (regexp-match-positions #rx\"/+\" collection)))"
"(if m"
"(cond"
"((=(caar m)(sub1(string-length collection)))"
"(values(substring collection 0(caar m)) collection-path))"
"(else"
"(values(substring collection 0(caar m))"
"(cons(substring collection(cdar m))"
" collection-path))))"
"(values collection collection-path))))"
"(else"
"(let-values(((base name dir?)(split-path collection)))"
"(if(eq? base 'relative)"
"(values name collection-path)"
"(normalize-collection-reference base(cons name collection-path))))))))"
"(define-values(find-col-file)"
"(lambda(who fail collection collection-path file-name)"
"(let((all-paths(current-library-collection-paths)))"
"(let-values(((collection collection-path)"
"(normalize-collection-reference collection collection-path)))"
"(let((all-paths(let((sym(string->symbol(if(path? collection)"
"(path->string collection)"
" collection))))"
"(append"
"(if(use-user-specific-search-paths)"
"(hash-ref(get-linked-collections #t) sym null)"
" null)"
"(if links-path"
"(hash-ref(get-linked-collections #f) sym null)"
" null)"
"(current-library-collection-paths)))))"
"(define-values(*build-path-rep)"
"(lambda(p c)"
"(if(path? p)"
"(build-path p c)"
"(unbox p))))"
"(define-values(*directory-exists?)"
"(lambda(orig p)"
"(if(path? orig)"
"(directory-exists? p)"
" #t)))"
"(define-values(to-string)(lambda(p)(if(path? p)(path->string p) p)))"
"(let cloop((paths all-paths)(found-col #f))"
"(if(null? paths)"
"(if found-col"
" found-col"
"(let((rest-coll"
"(if(null? collection-path)"
" \"\""
"(apply"
" string-append"
"(let loop((cp collection-path))"
"(if(null?(cdr cp))"
"(list(to-string(car cp)))"
" (list* (to-string (car cp)) \"/\" (loop (cdr cp)))))))))"
"(define-values(filter)"
"(lambda(f l)"
"(if(null? l)"
" null"
"(if(f(car l))"
"(cons(car l)(filter f(cdr l)))"
"(filter f(cdr l))))))"
"(fail"
" (format \"~a: collection not found: ~s in any of: ~s\" "
" who(if(null? collection-path)"
" collection"
"(apply build-path collection collection-path))"
" all-paths)))"
"(let((dir(build-path(car paths) collection)))"
"(if(directory-exists? dir)"
" (format \"~a: collection not found: ~s in any of: ~s~a\" "
" who"
"(if(null? collection-path)"
"(to-string collection)"
" (string-append (to-string collection) \"/\" rest-coll))"
"(filter path? all-paths)"
"(if(ormap box? all-paths)"
" (format \" or: ~s in any of: ~s\" "
" rest-coll "
"(map unbox(filter box? all-paths)))"
" \"\")))))"
"(let((dir(*build-path-rep(car paths) collection)))"
"(if(*directory-exists?(car paths) dir)"
"(let((cpath(apply build-path dir collection-path)))"
"(if(directory-exists? cpath)"
"(if(if(null? collection-path)"
" #t"
"(directory-exists? cpath))"
"(if file-name"
"(if(or(file-exists?(build-path cpath file-name))"
"(let((alt-file-name"
@ -243,7 +493,7 @@
"(cloop(cdr paths)(or found-col cpath)))"
" cpath)"
"(cloop(cdr paths) found-col)))"
"(cloop(cdr paths) found-col))))))))"
"(cloop(cdr paths) found-col)))))))))"
"(define-values(check-suffix-call)"
"(lambda(s sfx who)"
"(unless(or(path-for-some-system? s)"
@ -324,83 +574,6 @@
"(cons(simplify-path(path->complete-path v(current-directory)))"
"(loop(cdr l)))"
"(loop(cdr l))))))))))))"
"(define-values(path-list-string->path-list)"
"(let((r(byte-regexp(string->bytes/utf-8"
"(let((sep(if(eq?(system-type) 'windows)"
" \";\"\n"
" \":\")))"
" (format \"([^~a]*)~a(.*)\" sep sep)))))"
"(cons-path(lambda(default s l) "
" (if (bytes=? s #\"\")"
"(append default l)"
"(cons(bytes->path(if(eq?(system-type) 'windows)"
" (regexp-replace* #rx#\"\\\"\" s #\"\")"
" s))"
" l)))))"
"(lambda(s default)"
"(unless(or(bytes? s)"
"(string? s))"
" (raise-type-error 'path-list-string->path-list \"byte string or string\" s))"
"(unless(and(list? default)"
"(andmap path? default))"
" (raise-type-error 'path-list-string->path-list \"list of paths\" default))"
"(let loop((s(if(string? s)"
"(string->bytes/utf-8 s)"
" s)))"
"(let((m(regexp-match r s)))"
"(if m"
"(cons-path default(cadr m)(loop(caddr m)))"
"(cons-path default s null)))))))"
"(define-values(find-executable-path)"
"(case-lambda "
"((program libpath reverse?)"
"(unless(path-string? program) "
" (raise-type-error 'find-executable-path \"path or string (sans nul)\" program))"
"(unless(or(not libpath)(and(path-string? libpath) "
"(relative-path? libpath)))"
" (raise-type-error 'find-executable-path \"#f or relative path or string\" libpath))"
"(letrec((found-exec"
"(lambda(exec-name)"
"(if libpath"
"(let-values(((base name isdir?)(split-path exec-name)))"
"(let((next"
"(lambda()"
"(let((resolved(resolve-path exec-name)))"
"(cond"
"((equal? resolved exec-name) #f)"
"((relative-path? resolved)"
"(found-exec(build-path base resolved)))"
"(else(found-exec resolved)))))))"
"(or(and reverse?(next))"
"(if(path? base)"
"(let((lib(build-path base libpath)))"
"(and(or(directory-exists? lib) "
"(file-exists? lib))"
" lib))"
" #f)"
"(and(not reverse?)(next)))))"
" exec-name))))"
"(if(and(relative-path? program)"
"(let-values(((base name dir?)(split-path program)))"
"(eq? base 'relative)))"
" (let ((paths-str (getenv \"PATH\"))"
"(win-add(lambda(s)(if(eq?(system-type) 'windows) "
" (cons (bytes->path #\".\") s) "
" s))))"
"(let loop((paths(if paths-str "
"(win-add(path-list-string->path-list paths-str null))"
" null)))"
"(if(null? paths)"
" #f"
"(let*((base(path->complete-path(car paths)))"
"(name(build-path base program)))"
"(if(file-exists? name)"
"(found-exec name)"
"(loop(cdr paths)))))))"
"(let((p(path->complete-path program)))"
"(and(file-exists? p)(found-exec p))))))"
"((program libpath)(find-executable-path program libpath #f))"
"((program)(find-executable-path program #f #f))))"
"(define(embedded-load start end str)"
"(let*((s(if str"
" str"

View File

@ -179,7 +179,7 @@
;; (along with much of '#%kernel)
(module #%utils '#%kernel
(#%require '#%min-stx)
(#%require '#%min-stx '#%paramz)
(#%provide path-string?
normal-case-path
@ -230,6 +230,87 @@
[(string? s) (string->path s)]
[else s])))
;; ------------------------------ executable path ------------------------------
(define-values (find-executable-path)
(case-lambda
[(program libpath reverse?)
(unless (path-string? program)
(raise-type-error 'find-executable-path "path or string (sans nul)" program))
(unless (or (not libpath) (and (path-string? libpath)
(relative-path? libpath)))
(raise-type-error 'find-executable-path "#f or relative path or string" libpath))
(letrec ([found-exec
(lambda (exec-name)
(if libpath
(let-values ([(base name isdir?) (split-path exec-name)])
(let ([next
(lambda ()
(let ([resolved (resolve-path exec-name)])
(cond
[(equal? resolved exec-name) #f]
[(relative-path? resolved)
(found-exec (build-path base resolved))]
[else (found-exec resolved)])))])
(or (and reverse? (next))
(if (path? base)
(let ([lib (build-path base libpath)])
(and (or (directory-exists? lib)
(file-exists? lib))
lib))
#f)
(and (not reverse?) (next)))))
exec-name))])
(if (and (relative-path? program)
(let-values ([(base name dir?) (split-path program)])
(eq? base 'relative)))
(let ([paths-str (getenv "PATH")]
[win-add (lambda (s) (if (eq? (system-type) 'windows)
(cons (bytes->path #".") s)
s))])
(let loop ([paths (if paths-str
(win-add (path-list-string->path-list paths-str null))
null)])
(if (null? paths)
#f
(let* ([base (path->complete-path (car paths))]
[name (build-path base program)])
(if (file-exists? name)
(found-exec name)
(loop (cdr paths)))))))
(let ([p (path->complete-path program)])
(and (file-exists? p) (found-exec p)))))]
[(program libpath) (find-executable-path program libpath #f)]
[(program) (find-executable-path program #f #f)]))
(define-values (path-list-string->path-list)
(let ((r (byte-regexp (string->bytes/utf-8
(let ((sep (if (eq? (system-type) 'windows)
";"
":")))
(format "([^~a]*)~a(.*)" sep sep)))))
(cons-path (lambda (default s l)
(if (bytes=? s #"")
(append default l)
(cons (bytes->path (if (eq? (system-type) 'windows)
(regexp-replace* #rx#"\"" s #"")
s))
l)))))
(lambda (s default)
(unless (or (bytes? s)
(string? s))
(raise-type-error 'path-list-string->path-list "byte string or string" s))
(unless (and (list? default)
(andmap path? default))
(raise-type-error 'path-list-string->path-list "list of paths" default))
(let loop ([s (if (string? s)
(string->bytes/utf-8 s)
s)])
(let ([m (regexp-match r s)])
(if m
(cons-path default (cadr m) (loop (caddr m)))
(cons-path default s null)))))))
;; ------------------------------ Collections ------------------------------
(define-values (-check-relpath)
@ -268,23 +349,210 @@
file-name)
file-name)))
(define-values (user-links-path) (find-system-path 'links-file))
(define-values (user-links-cache) (make-hasheq))
(define-values (user-links-timestamp) -inf.0)
(define-values (links-path) (find-links-path!
;; This thunk is called once per place, and the result
;; is remembered for later invocations. Otherwise, the
;; search for the config file can trip over filesystem
;; restrictions imposed by security guards.
(lambda ()
(let ([d (let ([c (find-system-path 'collects-dir)])
(if (absolute-path? c)
c
(parameterize ([current-directory (find-system-path 'orig-dir)])
(find-executable-path (find-system-path 'exec-file) c))))])
(and d
(build-path d "config" "links.rktd"))))))
(define-values (links-cache) (make-hasheq))
(define-values (links-timestamp) -inf.0)
(define-values (get-linked-collections)
(lambda (user?)
(call/ec (lambda (esc)
(define-values (make-handler)
(lambda (ts)
(lambda (exn)
(let ([l (current-logger)])
(when (log-level? l 'error)
(log-message l 'error
(format
"error reading linked collections: ~a"
(exn-message exn))
(current-continuation-marks))))
(when ts
(if user?
(begin
(set! user-links-cache (make-hasheq))
(set! user-links-timestamp ts))
(begin
(set! links-cache (make-hasheq))
(set! links-timestamp ts))))
(esc (make-hasheq)))))
(with-continuation-mark
exception-handler-key
(make-handler #f)
(let ([ts (file-or-directory-modify-seconds (if user?
user-links-path
links-path)
#f
(lambda () -inf.0))])
(if (ts . > . (if user? user-links-timestamp links-timestamp))
(with-continuation-mark
exception-handler-key
(make-handler ts)
(parameterize ([read-case-sensitive #t]
[read-square-bracket-as-paren #t]
[read-curly-brace-as-paren #t]
[read-accept-box #t]
[read-accept-compiled #t]
[read-accept-bar-quote #t]
[read-accept-graph #t]
[read-decimal-as-inexact #t]
[read-accept-dot #t]
[read-accept-infix-dot #t]
[read-accept-quasiquote #t]
[read-accept-reader #t]
[read-accept-lang #f]
[current-readtable #f])
(let ([v (let ([p (open-input-file (if user? user-links-path links-path)
'binary)])
(dynamic-wind
void
(lambda ()
(begin0
(read p)
(unless (eof-object? (read p))
(error "expected a single S-expression"))))
(lambda () (close-input-port p))))])
(unless (and (list? v)
(andmap (lambda (p)
(and (list? p)
(or (= 2 (length p))
(= 3 (length p)))
(string? (car p))
(path-string? (cadr p))
(or (null? (cddr p))
(regexp? (caddr p)))))
v))
(error "ill-formed content"))
(let ([ht (make-hasheq)]
[dir (let-values ([(base name dir?) (split-path (if user?
user-links-path
links-path))])
base)])
(for-each
(lambda (p)
(when (or (null? (cddr p))
(regexp-match? (caddr p) (version)))
(let ([s (string->symbol (car p))])
(hash-set! ht s (cons (box (path->complete-path (cadr p) dir))
(hash-ref ht s null))))))
v)
(if user?
(begin
(set! user-links-cache ht)
(set! user-links-timestamp ts))
(begin
(set! links-cache ht)
(set! links-timestamp ts)))
ht))))
(if user?
user-links-cache
links-cache))))))))
(define-values (normalize-collection-reference)
(lambda (collection collection-path)
;; make sure that `collection' is a top-level collection name,
(cond
[(string? collection)
(let ([m (regexp-match-positions #rx"/+" collection)])
(if m
(cond
[(= (caar m) (sub1 (string-length collection)))
(values (substring collection 0 (caar m)) collection-path)]
[else
(values (substring collection 0 (caar m))
(cons (substring collection (cdar m))
collection-path))])
(values collection collection-path)))]
[else
(let-values ([(base name dir?) (split-path collection)])
(if (eq? base 'relative)
(values name collection-path)
(normalize-collection-reference base (cons name collection-path))))])))
(define-values (find-col-file)
(lambda (who fail collection collection-path file-name)
(let ([all-paths (current-library-collection-paths)])
(let cloop ([paths all-paths][found-col #f])
(let-values ([(collection collection-path)
(normalize-collection-reference collection collection-path)])
(let ([all-paths (let ([sym (string->symbol (if (path? collection)
(path->string collection)
collection))])
(append
;; list of (box path)s:
(if (use-user-specific-search-paths)
(hash-ref (get-linked-collections #t) sym null)
null)
;; list of (box path)s:
(if links-path
(hash-ref (get-linked-collections #f) sym null)
null)
;; list of paths:
(current-library-collection-paths)))])
(define-values (*build-path-rep)
(lambda (p c)
(if (path? p)
(build-path p c)
;; box => from links table for c
(unbox p))))
(define-values (*directory-exists?)
(lambda (orig p)
(if (path? orig)
(directory-exists? p)
;; orig is box => from links table
#t)))
(define-values (to-string) (lambda (p) (if (path? p) (path->string p) p)))
(let cloop ([paths all-paths] [found-col #f])
(if (null? paths)
(if found-col
found-col
(let ([rest-coll
(if (null? collection-path)
""
(apply
string-append
(let loop ([cp collection-path])
(if (null? (cdr cp))
(list (to-string (car cp)))
(list* (to-string (car cp)) "/" (loop (cdr cp)))))))])
(define-values (filter)
(lambda (f l)
(if (null? l)
null
(if (f (car l))
(cons (car l) (filter f (cdr l)))
(filter f (cdr l))))))
(fail
(format "~a: collection not found: ~s in any of: ~s"
who (if (null? collection-path)
collection
(apply build-path collection collection-path))
all-paths)))
(let ([dir (build-path (car paths) collection)])
(if (directory-exists? dir)
(format "~a: collection not found: ~s in any of: ~s~a"
who
(if (null? collection-path)
(to-string collection)
(string-append (to-string collection) "/" rest-coll))
(filter path? all-paths)
(if (ormap box? all-paths)
(format " or: ~s in any of: ~s"
rest-coll
(map unbox (filter box? all-paths)))
"")))))
(let ([dir (*build-path-rep (car paths) collection)])
(if (*directory-exists? (car paths) dir)
(let ([cpath (apply build-path dir collection-path)])
(if (directory-exists? cpath)
(if (if (null? collection-path)
#t
(directory-exists? cpath))
(if file-name
(if (or (file-exists? (build-path cpath file-name))
(let ([alt-file-name
@ -306,7 +574,7 @@
;; sub-collection not here; try next instance
;; of the top-level collection
(cloop (cdr paths) found-col)))
(cloop (cdr paths) found-col))))))))
(cloop (cdr paths) found-col)))))))))
(define-values (check-suffix-call)
(lambda (s sfx who)
@ -394,85 +662,6 @@
(loop (cdr l)))
(loop (cdr l)))))))))]))
(define-values (path-list-string->path-list)
(let ((r (byte-regexp (string->bytes/utf-8
(let ((sep (if (eq? (system-type) 'windows)
";"
":")))
(format "([^~a]*)~a(.*)" sep sep)))))
(cons-path (lambda (default s l)
(if (bytes=? s #"")
(append default l)
(cons (bytes->path (if (eq? (system-type) 'windows)
(regexp-replace* #rx#"\"" s #"")
s))
l)))))
(lambda (s default)
(unless (or (bytes? s)
(string? s))
(raise-type-error 'path-list-string->path-list "byte string or string" s))
(unless (and (list? default)
(andmap path? default))
(raise-type-error 'path-list-string->path-list "list of paths" default))
(let loop ([s (if (string? s)
(string->bytes/utf-8 s)
s)])
(let ([m (regexp-match r s)])
(if m
(cons-path default (cadr m) (loop (caddr m)))
(cons-path default s null)))))))
(define-values (find-executable-path)
(case-lambda
[(program libpath reverse?)
(unless (path-string? program)
(raise-type-error 'find-executable-path "path or string (sans nul)" program))
(unless (or (not libpath) (and (path-string? libpath)
(relative-path? libpath)))
(raise-type-error 'find-executable-path "#f or relative path or string" libpath))
(letrec ([found-exec
(lambda (exec-name)
(if libpath
(let-values ([(base name isdir?) (split-path exec-name)])
(let ([next
(lambda ()
(let ([resolved (resolve-path exec-name)])
(cond
[(equal? resolved exec-name) #f]
[(relative-path? resolved)
(found-exec (build-path base resolved))]
[else (found-exec resolved)])))])
(or (and reverse? (next))
(if (path? base)
(let ([lib (build-path base libpath)])
(and (or (directory-exists? lib)
(file-exists? lib))
lib))
#f)
(and (not reverse?) (next)))))
exec-name))])
(if (and (relative-path? program)
(let-values ([(base name dir?) (split-path program)])
(eq? base 'relative)))
(let ([paths-str (getenv "PATH")]
[win-add (lambda (s) (if (eq? (system-type) 'windows)
(cons (bytes->path #".") s)
s))])
(let loop ([paths (if paths-str
(win-add (path-list-string->path-list paths-str null))
null)])
(if (null? paths)
#f
(let* ([base (path->complete-path (car paths))]
[name (build-path base program)])
(if (file-exists? name)
(found-exec name)
(loop (cdr paths)))))))
(let ([p (path->complete-path program)])
(and (file-exists? p) (found-exec p)))))]
[(program libpath) (find-executable-path program libpath #f)]
[(program) (find-executable-path program #f #f)]))
;; used for the -k command-line argument:
(define (embedded-load start end str)
(let* ([s (if str

View File

@ -636,6 +636,7 @@ void scheme_init_paramz(Scheme_Env *env)
GLOBAL_PRIM_W_ARITY("check-for-break" , check_break_now , 0, 0, newenv);
GLOBAL_PRIM_W_ARITY("reparameterize" , reparameterize , 1, 1, newenv);
GLOBAL_PRIM_W_ARITY("make-custodian-from-main", make_custodian_from_main, 0, 0, newenv);
GLOBAL_PRIM_W_ARITY("find-links-path!" , scheme_find_links_path , 1, 1, newenv);
scheme_finish_primitive_module(newenv);
scheme_protect_primitive_provide(newenv, NULL);