]> gitweb.factorcode.org Git - factor.git/commitdiff
Fix conflicts
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Tue, 2 Dec 2008 02:39:43 +0000 (20:39 -0600)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Tue, 2 Dec 2008 02:39:43 +0000 (20:39 -0600)
217 files changed:
README.txt
basis/alien/c-types/c-types.factor
basis/alien/parser/parser.factor [new file with mode: 0644]
basis/alien/strings/strings.factor
basis/alien/structs/fields/fields.factor
basis/alien/structs/structs-tests.factor
basis/alien/structs/structs.factor
basis/alien/syntax/syntax-docs.factor
basis/alien/syntax/syntax.factor
basis/bit-vectors/bit-vectors-tests.factor
basis/bootstrap/image/image.factor
basis/bootstrap/stage2.factor
basis/boxes/boxes.factor
basis/calendar/calendar-docs.factor
basis/calendar/calendar-tests.factor
basis/calendar/calendar.factor
basis/calendar/format/format.factor
basis/channels/remote/remote.factor
basis/checksums/openssl/openssl.factor
basis/checksums/sha1/sha1.factor
basis/checksums/sha2/sha2.factor
basis/cocoa/application/application.factor
basis/cocoa/dialogs/dialogs.factor
basis/cocoa/messages/messages.factor
basis/cocoa/pasteboard/pasteboard.factor
basis/cocoa/subclassing/subclassing.factor
basis/cocoa/views/views.factor
basis/cocoa/windows/windows.factor
basis/command-line/command-line-docs.factor
basis/command-line/command-line-tests.factor [deleted file]
basis/command-line/command-line.factor
basis/compiler/alien/alien.factor
basis/compiler/cfg/def-use/def-use.factor
basis/compiler/cfg/instructions/instructions.factor
basis/compiler/cfg/intrinsics/intrinsics.factor
basis/compiler/codegen/codegen.factor
basis/compiler/codegen/fixup/fixup.factor
basis/compiler/tests/intrinsics.factor
basis/concurrency/conditions/conditions.factor
basis/concurrency/count-downs/count-downs.factor
basis/concurrency/distributed/distributed-tests.factor
basis/concurrency/exchangers/exchangers.factor
basis/concurrency/flags/flags-tests.factor
basis/concurrency/flags/flags.factor
basis/concurrency/futures/futures.factor
basis/concurrency/locks/locks-tests.factor
basis/concurrency/locks/locks.factor
basis/concurrency/mailboxes/mailboxes.factor
basis/concurrency/messaging/messaging-docs.factor
basis/concurrency/messaging/messaging.factor
basis/concurrency/promises/promises.factor
basis/concurrency/semaphores/semaphores.factor
basis/core-foundation/core-foundation.factor
basis/core-foundation/fsevents/fsevents.factor
basis/cpu/architecture/architecture.factor
basis/cpu/ppc/ppc.factor
basis/cpu/x86/32/32.factor
basis/cpu/x86/64/64.factor
basis/cpu/x86/64/unix/unix.factor
basis/cpu/x86/64/winnt/winnt.factor
basis/cpu/x86/assembler/assembler.factor
basis/cpu/x86/x86.factor
basis/db/db.factor
basis/db/postgresql/lib/lib.factor
basis/db/queries/queries.factor
basis/delegate/delegate-docs.factor
basis/delegate/delegate.factor
basis/dlists/dlists-tests.factor
basis/dlists/dlists.factor
basis/editors/editors.factor
basis/environment/environment.factor
basis/farkup/farkup.factor
basis/furnace/sessions/sessions.factor
basis/grouping/grouping.factor
basis/hash2/hash2.factor
basis/heaps/heaps.factor
basis/help/cookbook/cookbook.factor
basis/help/lint/summary.txt
basis/help/tutorial/tutorial.factor
basis/hints/hints-docs.factor
basis/hints/hints.factor
basis/inspector/inspector.factor
basis/io/launcher/launcher.factor
basis/io/pipes/pipes.factor
basis/io/ports/ports.factor
basis/io/servers/connection/connection-docs.factor
basis/io/servers/connection/connection.factor
basis/io/sockets/secure/secure-docs.factor
basis/io/sockets/secure/secure.factor
basis/io/sockets/sockets-docs.factor
basis/io/sockets/sockets.factor
basis/io/streams/duplex/duplex.factor
basis/io/unix/files/files.factor
basis/io/unix/launcher/launcher.factor
basis/io/unix/select/select.factor
basis/io/unix/sockets/secure/debug/debug.factor [new file with mode: 0644]
basis/io/unix/sockets/secure/secure-tests.factor
basis/io/unix/sockets/secure/secure.factor
basis/io/unix/sockets/sockets.factor
basis/linked-assocs/linked-assocs.factor
basis/math/complex/complex.factor
basis/math/functions/functions.factor
basis/math/partial-dispatch/partial-dispatch-tests.factor
basis/math/partial-dispatch/partial-dispatch.factor
basis/math/points/points.factor
basis/math/ranges/ranges.factor
basis/math/vectors/vectors.factor
basis/mime/multipart/multipart-tests.factor
basis/mime/multipart/multipart.factor
basis/opengl/gl/extensions/extensions.factor
basis/regexp/regexp-tests.factor
basis/smtp/server/server.factor
basis/smtp/smtp-docs.factor
basis/smtp/smtp-tests.factor
basis/smtp/smtp.factor
basis/stack-checker/backend/backend.factor
basis/stack-checker/inlining/inlining.factor
basis/tools/deploy/shaker/shaker.factor
basis/tools/hexdump/summary.txt
basis/tools/vocabs/monitor/monitor.factor
basis/ui/cocoa/cocoa.factor
basis/ui/cocoa/views/views-tests.factor [new file with mode: 0644]
basis/ui/cocoa/views/views.factor
basis/ui/freetype/freetype.factor
basis/ui/gadgets/buttons/buttons-docs.factor
basis/ui/gadgets/editors/editors-docs.factor
basis/ui/gadgets/editors/editors.factor [changed mode: 0644->0755]
basis/ui/gadgets/gadgets-tests.factor
basis/ui/gadgets/gadgets.factor
basis/ui/gadgets/grids/grids.factor
basis/ui/gadgets/labelled/labelled.factor
basis/ui/gadgets/menus/menus-docs.factor
basis/ui/gadgets/menus/menus.factor
basis/ui/gadgets/packs/packs-tests.factor
basis/ui/gadgets/packs/packs.factor
basis/ui/gadgets/panes/panes.factor
basis/ui/gadgets/paragraphs/paragraphs.factor
basis/ui/gadgets/presentations/presentations.factor
basis/ui/gadgets/sliders/sliders.factor
basis/ui/gadgets/worlds/worlds.factor
basis/ui/gestures/gestures.factor
basis/ui/operations/operations.factor
basis/ui/render/render.factor
basis/ui/tools/deploy/deploy.factor
basis/ui/tools/interactor/interactor.factor
basis/ui/traverse/traverse.factor
basis/ui/ui-docs.factor
basis/ui/windows/windows.factor
basis/ui/x11/x11.factor [changed mode: 0644->0755]
basis/unix/process/process.factor
basis/unix/statfs/netbsd/netbsd.factor
basis/unix/unix.factor
basis/x11/glx/glx.factor
core/assocs/assocs.factor
core/classes/intersection/intersection.factor
core/classes/tuple/tuple.factor
core/io/io-docs.factor
core/io/io.factor
core/math/floats/floats-tests.factor
core/math/floats/floats.factor
core/memory/memory-docs.factor
core/parser/parser.factor
core/sequences/sequences.factor
core/vocabs/loader/loader-docs.factor
core/vocabs/loader/loader.factor
core/words/words.factor
extra/asn1/asn1.factor
extra/assocs/lib/lib.factor
extra/benchmark/fannkuch/fannkuch.factor [new file with mode: 0644]
extra/benchmark/nbody/nbody.factor [new file with mode: 0644]
extra/boids/boids.factor
extra/boids/ui/authors.txt [deleted file]
extra/boids/ui/deploy.factor [deleted file]
extra/boids/ui/tags.txt [deleted file]
extra/boids/ui/ui.factor [deleted file]
extra/combinators/cleave/enhanced/enhanced.factor [new file with mode: 0644]
extra/combinators/lib/lib.factor
extra/contributors/contributors.factor
extra/flatland/flatland.factor [new file with mode: 0644]
extra/html/parser/parser.factor
extra/jamshred/tunnel/tunnel.factor
extra/lisp/authors.txt [deleted file]
extra/lisp/lisp-docs.factor [deleted file]
extra/lisp/lisp-tests.factor [deleted file]
extra/lisp/lisp.factor [deleted file]
extra/lisp/parser/authors.txt [deleted file]
extra/lisp/parser/parser-docs.factor [deleted file]
extra/lisp/parser/parser-tests.factor [deleted file]
extra/lisp/parser/parser.factor [deleted file]
extra/lisp/parser/summary.txt [deleted file]
extra/lisp/parser/tags.txt [deleted file]
extra/lisp/summary.txt [deleted file]
extra/lisp/tags.txt [deleted file]
extra/money/money-tests.factor
extra/money/money.factor
extra/multi-method-syntax/multi-method-syntax.factor [new file with mode: 0644]
extra/pong/pong.factor [new file with mode: 0644]
extra/taxes/usa/usa-tests.factor
extra/taxes/utils/utils.factor [deleted file]
extra/webapps/ip/ip.factor
misc/factor.el
unmaintained/lisp/authors.txt [new file with mode: 0644]
unmaintained/lisp/lisp-docs.factor [new file with mode: 0644]
unmaintained/lisp/lisp-tests.factor [new file with mode: 0644]
unmaintained/lisp/lisp.factor [new file with mode: 0644]
unmaintained/lisp/parser/authors.txt [new file with mode: 0644]
unmaintained/lisp/parser/parser-docs.factor [new file with mode: 0644]
unmaintained/lisp/parser/parser-tests.factor [new file with mode: 0644]
unmaintained/lisp/parser/parser.factor [new file with mode: 0644]
unmaintained/lisp/parser/summary.txt [new file with mode: 0644]
unmaintained/lisp/parser/tags.txt [new file with mode: 0644]
unmaintained/lisp/summary.txt [new file with mode: 0644]
unmaintained/lisp/tags.txt [new file with mode: 0644]
vm/cpu-ppc.S
vm/os-unix.h
vm/os-windows.h
vm/utilities.c

index 754791aa1a39f47bcacd661f5d4aa55eac0606bd..98616539d20d9c6f6366928dadf0bf27b1a5549f 100755 (executable)
@@ -43,13 +43,10 @@ Compilation will yield an executable named 'factor' on Unix,
 
 For X11 support, you need recent development libraries for libc,
 Freetype, X11, OpenGL and GLUT. On a Debian-derived Linux distribution
-(like Ubuntu), you can use the line
+(like Ubuntu), you can use the following line to grab everything:
 
     sudo apt-get install libc6-dev libfreetype6-dev libx11-dev glutg3-dev
 
-to grab everything (if you're on a non-debian-derived distro please tell
-us what the equivalent command is on there and it can be added).
-
 * Bootstrapping the Factor image
 
 Once you have compiled the Factor runtime, you must bootstrap the Factor
index 7500a12832b62a0a83f5042c923be022440aae40..5fe139a56fe9ead4741474d2c2d7e22c7d5d57a5 100644 (file)
@@ -52,7 +52,7 @@ GENERIC: c-type ( name -- type ) foldable
 
 : parse-array-type ( name -- array )
     "[" split unclip
-    >r [ "]" ?tail drop string>number ] map r> prefix ;
+    [ [ "]" ?tail drop string>number ] map ] dip prefix ;
 
 M: string c-type ( name -- type )
     CHAR: ] over member? [
@@ -201,10 +201,10 @@ M: byte-array byte-length length ;
     1 swap malloc-array ; inline
 
 : malloc-byte-array ( byte-array -- alien )
-    dup length dup malloc [ -rot memcpy ] keep ;
+    dup length [ nip malloc dup ] 2keep memcpy ;
 
 : memory>byte-array ( alien len -- byte-array )
-    dup <byte-array> [ -rot memcpy ] keep ;
+    [ nip <byte-array> dup ] 2keep memcpy ;
 
 : byte-array>memory ( byte-array base -- )
     swap dup length memcpy ;
diff --git a/basis/alien/parser/parser.factor b/basis/alien/parser/parser.factor
new file mode 100644 (file)
index 0000000..193893f
--- /dev/null
@@ -0,0 +1,19 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: alien alien.c-types arrays assocs effects grouping kernel
+parser sequences splitting words fry locals ;
+IN: alien.parser
+
+: parse-arglist ( parameters return -- types effect )
+    [ 2 group unzip [ "," ?tail drop ] map ]
+    [ [ { } ] [ 1array ] if-void ]
+    bi* <effect> ;
+
+: function-quot ( return library function types -- quot )
+    '[ _ _ _ _ alien-invoke ] ;
+
+:: define-function ( return library function parameters -- )
+    function create-in dup reset-generic
+    return library function
+    parameters return parse-arglist [ function-quot ] dip
+    define-declared ;
index b0faadb7fcc9c108243ec218cfc04b383ada167f..54a6cbfb4a5d4a39461618db9cfe7f08984a071b 100644 (file)
@@ -9,7 +9,7 @@ IN: alien.strings
 GENERIC# alien>string 1 ( c-ptr encoding -- string/f )
 
 M: c-ptr alien>string
-    >r <memory-stream> r> <decoder>
+    [ <memory-stream> ] [ <decoder> ] bi*
     "\0" swap stream-read-until drop ;
 
 M: f alien>string
index 19e5b8c326e17bd8043bd4504d2eabf9b1857548..17294aed87365b3347b6730bf09431240f39033c 100644 (file)
@@ -29,10 +29,10 @@ PREDICATE: slot-writer < word "writing" word-prop >boolean ;
     writer>> swap "writing" set-word-prop ;
 
 : reader-word ( class name vocab -- word )
-    >r >r "-" r> 3append r> create ;
+    [ "-" swap 3append ] dip create ;
 
 : writer-word ( class name vocab -- word )
-    >r [ swap "set-" % % "-" % % ] "" make r> create ;
+    [ [ swap "set-" % % "-" % % ] "" make ] dip create ;
 
 : <field-spec> ( struct-name vocab type field-name -- spec )
     field-spec new
@@ -52,25 +52,21 @@ PREDICATE: slot-writer < word "writing" word-prop >boolean ;
         [ (>>offset) ] [ type>> heap-size + ] 2bi
     ] reduce ;
 
-: define-struct-slot-word ( spec word quot -- )
-    rot offset>> prefix define-inline ;
+: define-struct-slot-word ( word quot spec -- )
+    offset>> prefix define-inline ;
 
 : define-getter ( type spec -- )
     [ set-reader-props ] keep
-    [ ]
     [ reader>> ]
     [
         type>>
         [ c-getter ] [ c-type-boxer-quot ] bi append
-    ] tri
-    define-struct-slot-word ;
+    ]
+    [ ] tri define-struct-slot-word ;
 
 : define-setter ( type spec -- )
     [ set-writer-props ] keep
-    [ ]
-    [ writer>> ]
-    [ type>> c-setter ] tri
-    define-struct-slot-word ;
+    [ writer>> ] [ type>> c-setter ] [ ] tri define-struct-slot-word ;
 
 : define-field ( type spec -- )
     [ define-getter ] [ define-setter ] 2bi ;
index 8c7d9f9b29daadaffeb01beede959617e377a848..ec0c01c2e7088dad9054c87e6bb9b267035eea1d 100644 (file)
@@ -38,7 +38,7 @@ C-UNION: barx
 [ 120 ] [ "barx" heap-size ] unit-test
 
 "help" vocab [
-    "help" "help" lookup "help" set
+    "print-topic" "help" lookup "help" set
     [ ] [ \ foox-x "help" get execute ] unit-test
     [ ] [ \ set-foox-x "help" get execute ] unit-test
 ] when
index eb1528b649079a5d3ec336653fb2e304af0fdd5e..9bbb5ce2aa1ad57d7f5e7d8ea5bc99440d959d9f 100644 (file)
@@ -39,7 +39,7 @@ M: struct-type stack-size
 : c-struct? ( type -- ? ) (c-type) struct-type? ;
 
 : (define-struct) ( name size align fields -- )
-    >r [ align ] keep r>
+    [ [ align ] keep ] dip
     struct-type boa
     swap typedef ;
 
@@ -50,11 +50,11 @@ M: struct-type stack-size
     [ c-type-align ] map supremum ;
 
 : define-struct ( name vocab fields -- )
-    pick >r
-    [ struct-offsets ] keep
-    [ [ type>> ] map compute-struct-align ] keep
-    [ (define-struct) ] keep
-    r> [ swap define-field ] curry each ;
+    pick [
+        [ struct-offsets ] keep
+        [ [ type>> ] map compute-struct-align ] keep
+        [ (define-struct) ] keep
+    ] dip [ swap define-field ] curry each ;
 
 : define-union ( name vocab members -- )
     [ expand-constants ] map
index 37cbd12801930fd2864c42e056a6ee6a2b1a59b9..586bb974028978b2e78e663c9b6061f21d49d0bf 100644 (file)
@@ -1,5 +1,5 @@
 IN: alien.syntax
-USING: alien alien.c-types alien.structs alien.syntax.private
+USING: alien alien.c-types alien.parser alien.structs
 help.markup help.syntax ;
 
 HELP: DLL"
@@ -54,12 +54,6 @@ HELP: TYPEDEF:
 { $description "Aliases the C type " { $snippet "old" } " under the name " { $snippet "new" } " if ." }
 { $notes "This word differs from " { $link typedef } " in that it runs at parse time, to ensure correct ordering of operations when loading source files. Words defined in source files are compiled before top-level forms are run, so if a source file defines C binding words and uses " { $link typedef } ", the type alias won't be available at compile time." } ;
 
-HELP: TYPEDEF-IF:
-{ $syntax "TYPEDEF-IF: word old new" }
-{ $values { "word" "a word with stack effect " { $snippet "( -- ? )" } } { "old" "a C type" } { "new" "a C type" } }
-{ $description "Aliases the C type " { $snippet "old" } " under the name " { $snippet "new" } " if " { $snippet "word" } " evaluates to a true value." }
-{ $notes "This word differs from " { $link typedef } " in that it runs at parse time, to ensure correct ordering of operations when loading source files. Words defined in source files are compiled before top-level forms are run, so if a source file defines C binding words and uses " { $link typedef } ", the type alias won't be available at compile time." } ;
-
 HELP: C-STRUCT:
 { $syntax "C-STRUCT: name pairs... ;" }
 { $values { "name" "a new C type name" } { "pairs" "C type / field name string pairs" } }
@@ -88,7 +82,7 @@ HELP: typedef
 { $description "Alises the C type " { $snippet "old" } " under the name " { $snippet "new" } "." }
 { $notes "Using this word in the same source file which defines C bindings can cause problems, because words are compiled before top-level forms are run. Use the " { $link POSTPONE: TYPEDEF: } " word instead." } ;
 
-{ POSTPONE: TYPEDEF-IF: POSTPONE: TYPEDEF: typedef } related-words
+{ POSTPONE: TYPEDEF: typedef } related-words
 
 HELP: c-struct?
 { $values { "type" "a string" } { "?" "a boolean" } }
index 7629897fc0fa48238ee5651e87f588fc21dfd56c..a204b1621c50a768d0fb0c7fb8c4f24a1907cde1 100644 (file)
@@ -4,35 +4,9 @@ USING: accessors arrays alien alien.c-types alien.structs
 alien.arrays alien.strings kernel math namespaces parser
 sequences words quotations math.parser splitting grouping
 effects prettyprint prettyprint.sections prettyprint.backend
-assocs combinators lexer strings.parser ;
+assocs combinators lexer strings.parser alien.parser ;
 IN: alien.syntax
 
-<PRIVATE
-
-: parse-arglist ( return seq -- types effect )
-    2 group dup keys swap values [ "," ?tail drop ] map
-    rot dup "void" = [ drop { } ] [ 1array ] if <effect> ;
-
-: function-quot ( type lib func types -- quot )
-    [ alien-invoke ] 2curry 2curry ;
-
-: define-function ( return library function parameters -- )
-    >r pick r> parse-arglist
-    pick create-in dup reset-generic
-    >r >r function-quot r> r> 
-    -rot define-declared ;
-
-PRIVATE>
-
-: indirect-quot ( function-ptr-quot return types abi -- quot )
-    [ alien-indirect ] 3curry compose ;
-
-: define-indirect ( abi return function-ptr-quot function-name parameters -- )
-    >r pick r> parse-arglist
-    rot create-in dup reset-generic
-    >r >r swapd roll indirect-quot r> r>
-    -rot define-declared ;
-
 : DLL" lexer get skip-blank parse-string dlopen parsed ; parsing
 
 : ALIEN: scan string>number <alien> parsed ; parsing
@@ -49,13 +23,10 @@ PRIVATE>
 : TYPEDEF:
     scan scan typedef ; parsing
 
-: TYPEDEF-IF:
-    scan-word execute scan scan rot [ typedef ] [ 2drop ] if ; parsing
-
 : C-STRUCT:
     scan in get
     parse-definition
-    >r 2dup r> define-struct-early
+    [ 2dup ] dip define-struct-early
     define-struct ; parsing
 
 : C-UNION:
@@ -64,7 +35,7 @@ PRIVATE>
 : C-ENUM:
     ";" parse-tokens
     dup length
-    [ >r create-in r> 1quotation define ] 2each ;
+    [ [ create-in ] dip 1quotation define ] 2each ;
     parsing
 
 M: alien pprint*
index dff9a8db37f2da33682a712da04a1e6961505471..31327999e73fceccb6ecd6c38ee9ff036cfaf3d2 100644 (file)
@@ -4,7 +4,7 @@ USING: tools.test bit-vectors vectors sequences kernel math ;
 [ 0 ] [ 123 <bit-vector> length ] unit-test\r
 \r
 : do-it\r
-    1234 swap [ >r even? r> push ] curry each ;\r
+    1234 swap [ [ even? ] dip push ] curry each ;\r
 \r
 [ t ] [\r
     3 <bit-vector> dup do-it\r
index e2203031aa08253e01de1a79c110c66456b04f4f..f352a4a2545703145c557dad8bcfbd71c65f85de 100644 (file)
@@ -72,7 +72,7 @@ SYMBOL: objects
 : put-object ( n obj -- ) (objects) set-at ;
 
 : cache-object ( obj quot -- value )
-    >r (objects) r> [ obj>> ] prepose cache ; inline
+    [ (objects) ] dip [ obj>> ] prepose cache ; inline
 
 ! Constants
 
@@ -97,10 +97,10 @@ SYMBOL: sub-primitives
     { [ { } make ] [ ] [ ] [ ] } spread 4array ; inline
 
 : jit-define ( quot rc rt offset name -- )
-    >r make-jit r> set ; inline
+    [ make-jit ] dip set ; inline
 
 : define-sub-primitive ( quot rc rt offset word -- )
-    >r make-jit r> sub-primitives get set-at ;
+    [ make-jit ] dip sub-primitives get set-at ;
 
 ! The image being constructed; a vector of word-size integers
 SYMBOL: image
@@ -205,7 +205,7 @@ SYMBOL: undefined-quot
 : emit-fixnum ( n -- ) tag-fixnum emit ;
 
 : emit-object ( header tag quot -- addr )
-    swap here-as >r swap tag-fixnum emit call align-here r> ;
+    swap here-as [ swap tag-fixnum emit call align-here ] dip ;
     inline
 
 ! Write an object to the image.
index f310944d024adbfe7b9d57e213f6d82bd4d04a5f..4ab36ec94e9361a6efbf23a2a2550416735c9738 100644 (file)
@@ -59,9 +59,9 @@ SYMBOL: bootstrap-time
     "math compiler threads help io tools ui ui.tools unicode handbook" "include" set-global
     "" "exclude" set-global
 
-    parse-command-line
+    (command-line) parse-command-line
 
-    "-no-crossref" cli-args member? [ do-crossref ] unless
+    do-crossref
 
     ! Set dll paths
     os wince? [ "windows.ce" require ] when
@@ -92,12 +92,7 @@ SYMBOL: bootstrap-time
         [
             boot
             do-init-hooks
-            [
-                parse-command-line
-                run-user-init
-                "run" get run
-                output-stream get [ stream-flush ] when*
-            ] [ print-error 1 exit ] recover
+            handle-command-line
         ] set-boot-quot
 
         millis swap - bootstrap-time set-global
index 9e2e8a4673a788ab744da1497f5c57ce95e43d91..39f8eb44cc354c3a68e19396a0dd69943e21d963 100644 (file)
@@ -23,4 +23,4 @@ ERROR: box-empty box ;
     dup occupied>> [ box> t ] [ drop f f ] if ;\r
 \r
 : if-box? ( box quot -- )\r
-    >r ?box r> [ drop ] if ; inline\r
+    [ ?box ] dip [ drop ] if ; inline\r
index 433459cb24457823fd5b61c253f88132580c0d19..748f9d124c0a7ad3fdd5e5ba91d3997daef27997 100644 (file)
@@ -99,6 +99,48 @@ HELP: seconds-per-year
 { $values { "integer" integer } }
 { $description "Returns the number of seconds in a year averaged over 400 years. Used internally for adding an arbitrary real number of seconds to a timestamp." } ;
 
+HELP: biweekly
+{ $values
+     { "x" number }
+     { "y" number }
+}
+{ $description "Divides a number by the number of two week periods in a year." } ;
+
+HELP: daily-360
+{ $values
+     { "x" number }
+     { "y" number }
+}
+{ $description "Divides a number by the number of days in a 360-day year." } ;
+
+HELP: daily-365
+{ $values
+     { "x" number }
+     { "y" number }
+}
+{ $description "Divides a number by the number of days in a 365-day year." } ;
+
+HELP: monthly
+{ $values
+     { "x" number }
+     { "y" number }
+}
+{ $description "Divides a number by the number of months in a year." } ;
+
+HELP: semimonthly
+{ $values
+     { "x" number }
+     { "y" number }
+}
+{ $description "Divides a number by the number of half-months in a year. Note that biweekly has two more periods than semimonthly." } ;
+
+HELP: weekly
+{ $values
+     { "x" number }
+     { "y" number }
+}
+{ $description "Divides a number by the number of weeks in a year." } ;
+
 HELP: julian-day-number
 { $values { "year" integer } { "month" integer } { "day" integer } { "n" integer } }
 { $description "Calculates the Julian day number from a year, month, and day.  The difference between two Julian day numbers is the number of days that have elapsed between the two corresponding dates." }
@@ -540,6 +582,8 @@ ARTICLE: "calendar" "Calendar"
 { $subsection "years" }
 { $subsection "months" }
 { $subsection "days" }
+"Calculating amounts per period of time:"
+{ $subsection "time-period-calculations" }
 "Meta-data about the calendar:"
 { $subsection "calendar-facts" }
 ;
@@ -626,6 +670,18 @@ ARTICLE: "calendar-facts" "Calendar facts"
 { $subsection day-of-week }
 ;
 
+ARTICLE: "time-period-calculations" "Calculations over periods of time"
+{ $subsection monthly }
+{ $subsection semimonthly }
+{ $subsection biweekly }
+{ $subsection weekly }
+{ $subsection daily-360 }
+{ $subsection daily-365 }
+{ $subsection biweekly }
+{ $subsection biweekly }
+{ $subsection biweekly }
+;
+
 ARTICLE: "years" "Year operations"
 "Leap year predicate:"
 { $subsection leap-year? }
index 00d5730745728979aa94b2e49007e9e0f7327e07..943ba8c3d56eccb35a1f089f5d56a286e914e580 100644 (file)
@@ -167,3 +167,5 @@ IN: calendar.tests
 [ t ] [ now 50 milliseconds sleep now before? ] unit-test
 [ t ] [ now 50 milliseconds sleep now swap after? ] unit-test
 [ t ] [ now 50 milliseconds sleep now 50 milliseconds sleep now swapd between? ] unit-test
+
+[ 4+1/6 ] [ 100 semimonthly ] unit-test
index a78cf60eb0147d204966fbf8c5783df5ba639f47..e2564b5a28874f7294cb130b4eee0031aea16fa9 100644 (file)
@@ -89,6 +89,13 @@ PRIVATE>
 : minutes-per-year ( -- ratio ) 5259492/10 ; inline
 : seconds-per-year ( -- integer ) 31556952 ; inline
 
+: monthly ( x -- y ) 12 / ; inline
+: semimonthly ( x -- y ) 24 / ; inline
+: biweekly ( x -- y ) 26 / ; inline
+: weekly ( x -- y ) 52 / ; inline
+: daily-360 ( x -- y ) 360 / ; inline
+: daily-365 ( x -- y ) 365 / ; inline
+
 :: julian-day-number ( year month day -- n )
     #! Returns a composite date number
     #! Not valid before year -4800
@@ -173,7 +180,7 @@ M: real +year ( timestamp n -- timestamp )
     12 /rem dup zero? [ drop 1- 12 ] when swap ; inline
 
 M: integer +month ( timestamp n -- timestamp )
-    [ over month>> + months/years >r >>month r> +year ] unless-zero ;
+    [ over month>> + months/years [ >>month ] dip +year ] unless-zero ;
 
 M: real +month ( timestamp n -- timestamp )
     [ float>whole-part swapd average-month * +day swap +month ] unless-zero ;
@@ -181,7 +188,7 @@ M: real +month ( timestamp n -- timestamp )
 M: integer +day ( timestamp n -- timestamp )
     [
         over >date< julian-day-number + julian-day-number>date
-        >r >r >>year r> >>month r> >>day
+        [ >>year ] [ >>month ] [ >>day ] tri*
     ] unless-zero ;
 
 M: real +day ( timestamp n -- timestamp )
@@ -191,7 +198,7 @@ M: real +day ( timestamp n -- timestamp )
     24 /rem swap ;
 
 M: integer +hour ( timestamp n -- timestamp )
-    [ over hour>> + hours/days >r >>hour r> +day ] unless-zero ;
+    [ over hour>> + hours/days [ >>hour ] dip +day ] unless-zero ;
 
 M: real +hour ( timestamp n -- timestamp )
     float>whole-part swapd 60 * +minute swap +hour ;
@@ -200,7 +207,7 @@ M: real +hour ( timestamp n -- timestamp )
     60 /rem swap ;
 
 M: integer +minute ( timestamp n -- timestamp )
-    [ over minute>> + minutes/hours >r >>minute r> +hour ] unless-zero ;
+    [ over minute>> + minutes/hours [ >>minute ] dip +hour ] unless-zero ;
 
 M: real +minute ( timestamp n -- timestamp )
     [ float>whole-part swapd 60 * +second swap +minute ] unless-zero ;
@@ -209,7 +216,7 @@ M: real +minute ( timestamp n -- timestamp )
     60 /rem swap >integer ;
 
 M: number +second ( timestamp n -- timestamp )
-    [ over second>> + seconds/minutes >r >>second r> +minute ] unless-zero ;
+    [ over second>> + seconds/minutes [ >>second ] dip +minute ] unless-zero ;
 
 : (time+)
     [ second>> +second ] keep
@@ -226,7 +233,7 @@ PRIVATE>
 GENERIC# time+ 1 ( time1 time2 -- time3 )
 
 M: timestamp time+
-    >r clone r> (time+) drop ;
+    [ clone ] dip (time+) drop ;
 
 M: duration time+
     dup timestamp? [
@@ -284,7 +291,7 @@ M: timestamp <=> ( ts1 ts2 -- n )
 : (time-) ( timestamp timestamp -- n )
     [ >gmt ] bi@
     [ [ >date< julian-day-number ] bi@ - 86400 * ] 2keep
-    [ >time< >r >r 3600 * r> 60 * r> + + ] bi@ - + ;
+    [ >time< [ [ 3600 * ] [ 60 * ] bi* ] dip + + ] bi@ - + ;
 
 M: timestamp time-
     #! Exact calendar-time difference
@@ -320,13 +327,13 @@ M: duration time-
     1970 1 1 0 0 0 instant <timestamp> ;
 
 : millis>timestamp ( x -- timestamp )
-    >r unix-1970 r> milliseconds time+ ;
+    [ unix-1970 ] dip milliseconds time+ ;
 
 : timestamp>millis ( timestamp -- n )
     unix-1970 (time-) 1000 * >integer ;
 
 : micros>timestamp ( x -- timestamp )
-    >r unix-1970 r> microseconds time+ ;
+    [ unix-1970 ] dip microseconds time+ ;
 
 : timestamp>micros ( timestamp -- n )
     unix-1970 (time-) 1000000 * >integer ;
@@ -343,10 +350,11 @@ M: duration time-
     #! Zeller Congruence
     #! http://web.textfiles.com/computers/formulas.txt
     #! good for any date since October 15, 1582
-    >r dup 2 <= [ 12 + >r 1- r> ] when
-    >r dup [ 4 /i + ] keep [ 100 /i - ] keep 400 /i + r>
-        [ 1+ 3 * 5 /i + ] keep 2 * + r>
-    1+ + 7 mod ;
+    [
+        dup 2 <= [ [ 1- ] [ 12 + ] bi* ] when
+        [ dup [ 4 /i + ] keep [ 100 /i - ] keep 400 /i + ] dip
+        [ 1+ 3 * 5 /i + ] keep 2 * +
+    ] dip 1+ + 7 mod ;
 
 GENERIC: days-in-year ( obj -- n )
 
index b15da4240998ddd4ffeca4b9dbba53a347ec4a7c..8d34e8a3a4ee15dc76dc74d109227bd5ba4644b1 100644 (file)
@@ -138,11 +138,11 @@ M: timestamp year. ( timestamp -- )
 \r
 : read-rfc3339-gmt-offset ( ch -- dt )\r
     dup CHAR: Z = [ drop instant ] [\r
-        >r\r
-        read-00 hours\r
-        read1 { { CHAR: : [ read-00 ] } { f [ 0 ] } } case minutes\r
-        time+\r
-        r> signed-gmt-offset\r
+        [\r
+            read-00 hours\r
+            read1 { { CHAR: : [ read-00 ] } { f [ 0 ] } } case minutes\r
+            time+\r
+        ] dip signed-gmt-offset\r
     ] if ;\r
 \r
 : read-ymd ( -- y m d )\r
@@ -152,8 +152,9 @@ M: timestamp year. ( timestamp -- )
     read-00 ":" expect read-00 ":" expect read-00 ;\r
 \r
 : read-rfc3339-seconds ( s -- s' ch )\r
-    "+-Z" read-until >r\r
-    [ string>number ] [ length 10 swap ^ ] bi / + r> ;\r
+    "+-Z" read-until [\r
+        [ string>number ] [ length 10 swap ^ ] bi / +\r
+    ] dip ;\r
 \r
 : (rfc3339>timestamp) ( -- timestamp )\r
     read-ymd\r
@@ -181,9 +182,9 @@ ERROR: invalid-timestamp-format ;
 \r
 : parse-rfc822-gmt-offset ( string -- dt )\r
     dup "GMT" = [ drop instant ] [\r
-        unclip >r\r
-        2 cut [ string>number ] bi@ [ hours ] [ minutes ] bi* time+\r
-        r> signed-gmt-offset\r
+        unclip \r
+            2 cut [ string>number ] bi@ [ hours ] [ minutes ] bi* time+\r
+        ] dip signed-gmt-offset\r
     ] if ;\r
 \r
 : (rfc822>timestamp) ( -- timestamp )\r
index 1a7addac12583fcb5646e529951d40336f76db7a..6e10b23407f2630eda925ac253e889774a6a76ae 100644 (file)
@@ -14,7 +14,7 @@ IN: channels.remote
 PRIVATE>
 
 : publish ( channel -- id )
-    256 random-bits dup >r remote-channels set-at r> ;
+    256 random-bits dup [ remote-channels set-at ] dip ;
 
 : get-channel ( id -- channel )
     remote-channels at ;
index d42febb541e15128edb62422b007ea7236ebf9f9..821cbe2f3afe282195aacc66dbd075cdb8d7e0c5 100644 (file)
@@ -28,7 +28,7 @@ M: evp-md-context dispose
     handle>> EVP_MD_CTX_cleanup drop ;
 
 : with-evp-md-context ( quot -- )
-    maybe-init-ssl >r <evp-md-context> r> with-disposal ; inline
+    maybe-init-ssl [ <evp-md-context> ] dip with-disposal ; inline
 
 : digest-named ( name -- md )
     dup EVP_get_digestbyname
index bbae421b16fe0d1d86e86c9d44e3be955ec8a5d7..3767af7c5590877907c9882380c8e58352e6edf6 100644 (file)
@@ -41,9 +41,9 @@ SYMBOLS: h0 h1 h2 h3 h4 A B C D E w K ;
 : sha1-f ( B C D t -- f_tbcd )
     20 /i
     {   
-        { 0 [ >r over bitnot r> bitand >r bitand r> bitor ] }
+        { 0 [ [ over bitnot ] dip bitand [ bitand ] dip bitor ] }
         { 1 [ bitxor bitxor ] }
-        { 2 [ 2dup bitand >r pick bitand >r bitand r> r> bitor bitor ] }
+        { 2 [ 2dup bitand [ pick bitand [ bitand ] dip ] dip bitor bitor ] }
         { 3 [ bitxor bitxor ] }
     } case ;
 
index 0a6d8c26ab335c53b69f1af41e9da3e18355d766..beb657bd3e1ab5b0b332ca64805e0f85959ebd7e 100644 (file)
@@ -59,7 +59,7 @@ SYMBOLS: vars M K H S0 S1 process-M word-size block-size ;
     [ 15 - swap nth s0-256 ] 2keep
     [ 7 - swap nth ] 2keep
     [ 2 - swap nth s1-256 ] 2keep
-    >r >r + + w+ r> r> swap set-nth ; inline
+    [ + + w+ ] 2dip swap set-nth ; inline
 
 : prepare-message-schedule ( seq -- w-seq )
     word-size get group [ be> ] map block-size get 0 pad-right
@@ -71,7 +71,7 @@ SYMBOLS: vars M K H S0 S1 process-M word-size block-size ;
     [ bitxor bitand ] keep bitxor ;
 
 : maj ( x y z -- x' )
-    >r [ bitand ] 2keep bitor r> bitand bitor ;
+    [ [ bitand ] 2keep bitor ] dip bitand bitor ;
 
 : S0-256 ( x -- x' )
     [ -2 bitroll-32 ] keep
@@ -83,7 +83,7 @@ SYMBOLS: vars M K H S0 S1 process-M word-size block-size ;
     [ -11 bitroll-32 ] keep
     -25 bitroll-32 bitxor bitxor ; inline
 
-: slice3 ( n seq -- a b c ) >r dup 3 + r> <slice> first3 ; inline
+: slice3 ( n seq -- a b c ) [ dup 3 + ] dip <slice> first3 ; inline
 
 : T1 ( W n -- T1 )
     [ swap nth ] keep
@@ -105,7 +105,7 @@ SYMBOLS: vars M K H S0 S1 process-M word-size block-size ;
     d c pick exchange
     c b pick exchange
     b a pick exchange
-    >r w+ a r> set-nth ;
+    [ w+ a ] dip set-nth ;
 
 : process-chunk ( M -- )
     H get clone vars set
@@ -118,7 +118,7 @@ SYMBOLS: vars M K H S0 S1 process-M word-size block-size ;
 
 : preprocess-plaintext ( string big-endian? -- padded-string )
     #! pad 0x80 then 00 til 8 bytes left, then 64bit length in bits
-    >r >sbuf r> over [
+    [ >sbuf ] dip over [
         HEX: 80 ,
         dup length HEX: 3f bitand
         calculate-pad-length 0 <string> %
index 8f32782d765dc01055fd8f7f1d2506dbb40e4e17..c62fab0f155f6d6b86daeab71b3890ecc33cbc50 100644 (file)
@@ -40,12 +40,13 @@ FUNCTION: void NSBeep ( ) ;
     dup next-event [ -> sendEvent: t ] [ drop f ] if* ;
 
 : add-observer ( observer selector name object -- )
-    >r >r >r >r NSNotificationCenter -> defaultCenter
-    r> r> sel_registerName
-    r> r> -> addObserver:selector:name:object: ;
+    [
+        [ NSNotificationCenter -> defaultCenter ] 2dip
+        sel_registerName
+    ] 2dip -> addObserver:selector:name:object: ;
 
 : remove-observer ( observer -- )
-    >r NSNotificationCenter -> defaultCenter r>
+    [ NSNotificationCenter -> defaultCenter ] dip
     -> removeObserver: ;
 
 : finish-launching ( -- ) NSApp -> finishLaunching ;
index 662b4a7bae784f481dd92e5cf94434318185e87c..2b01c5d751215eced96995d3e87779e27f7c4930 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (C) 2006, 2007 Slava Pestov
+! Copyright (C) 2006, 2008 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel cocoa cocoa.messages cocoa.classes
 cocoa.application sequences splitting core-foundation ;
@@ -29,6 +29,6 @@ IN: cocoa.dialogs
     "/" split1-last [ <NSString> ] bi@ ;
 
 : save-panel ( path -- paths )
-    <NSSavePanel> dup
-    rot split-path -> runModalForDirectory:file: NSOKButton =
+    [ <NSSavePanel> dup ] dip
+    split-path -> runModalForDirectory:file: NSOKButton =
     [ -> filename CF>string ] [ drop f ] if ;
index 09b225591359a19e098084977ea1ce5594e3524a..5bcd6d6f607160ef272222debd0063e9c11c402d 100644 (file)
@@ -5,7 +5,7 @@ combinators compiler compiler.alien kernel math namespaces make
 parser prettyprint prettyprint.sections quotations sequences
 strings words cocoa.runtime io macros memoize debugger
 io.encodings.ascii effects libc libc.private parser lexer init
-core-foundation fry ;
+core-foundation fry generalizations ;
 IN: cocoa.messages
 
 : make-sender ( method function -- quot )
@@ -27,7 +27,7 @@ super-message-senders global [ H{ } assoc-like ] change-at
 
 : cache-stub ( method function hash -- )
     [
-        over get [ 2drop ] [ over >r sender-stub r> set ] if
+        over get [ 2drop ] [ over [ sender-stub ] dip set ] if
     ] bind ;
 
 : cache-stubs ( method -- )
@@ -37,7 +37,7 @@ super-message-senders global [ H{ } assoc-like ] change-at
 
 : <super> ( receiver -- super )
     "objc-super" <c-object> [
-        >r dup object_getClass class_getSuperclass r>
+        [ dup object_getClass class_getSuperclass ] dip
         set-objc-super-class
     ] keep
     [ set-objc-super-receiver ] keep ;
@@ -62,23 +62,18 @@ objc-methods global [ H{ } assoc-like ] change-at
     dup objc-methods get at
     [ ] [ "No such method: " prepend throw ] ?if ;
 
-: make-dip ( quot n -- quot' )
-    dup
-    \ >r <repetition> >quotation -rot
-    \ r> <repetition> >quotation 3append ;
-
 MEMO: make-prepare-send ( selector method super? -- quot )
     [
         [ \ <super> , ] when
         swap <selector> , \ selector ,
     ] [ ] make
-    swap second length 2 - make-dip ;
+    swap second length 2 - '[ _ _ ndip ] ;
 
 MACRO: (send) ( selector super? -- quot )
-    >r dup lookup-method r>
+    [ dup lookup-method ] dip
     [ make-prepare-send ] 2keep
     super-message-senders message-senders ? get at
-    [ slip execute ] 2curry ;
+    '[ _ call _ execute ] ;
 
 : send ( receiver args... selector -- return... ) f (send) ; inline
 
@@ -165,14 +160,14 @@ objc>alien-types get [ swap ] assoc-map
 assoc-union alien>objc-types set-global
 
 : objc-struct-type ( i string -- ctype )
-    2dup CHAR: = -rot index-from swap subseq
+    [ CHAR: = ] 2keep index-from swap subseq
     dup c-types get key? [
         "Warning: no such C type: " write dup print
         drop "void*"
     ] unless ;
 
 : (parse-objc-type) ( i string -- ctype )
-    2dup nth >r >r 1+ r> r> {
+    [ [ 1+ ] dip ] [ nth ] 2bi {
         { [ dup "rnNoORV" member? ] [ drop (parse-objc-type) ] }
         { [ dup CHAR: ^ = ] [ 3drop "void*" ] }
         { [ dup CHAR: { = ] [ drop objc-struct-type ] }
@@ -223,22 +218,23 @@ assoc-union alien>objc-types set-global
 : class-exists? ( string -- class ) objc_getClass >boolean ;
 
 : unless-defined ( class quot -- )
-    >r class-exists? r> unless ; inline
+    [ class-exists? ] dip unless ; inline
 
 : define-objc-class-word ( name quot -- )
     [
         over , , \ unless-defined , dup , \ objc-class ,
-    ] [ ] make >r "cocoa.classes" create r>
+    ] [ ] make [ "cocoa.classes" create ] dip
     (( -- class )) define-declared ;
 
 : import-objc-class ( name quot -- )
     2dup unless-defined
     dupd define-objc-class-word
-    [
+    '[
+        _
         dup
         objc-class register-objc-methods
         objc-meta-class register-objc-methods
-    ] curry try ;
+    ] try ;
 
 : root-class ( class -- root )
     dup class_getSuperclass [ root-class ] [ ] ?if ;
index d266c2452f849d0ad10e7d2fceffa3071a7bd8e0..9302097adff00219b7bc5a2e69ca6178b4c48a30 100644 (file)
@@ -20,7 +20,7 @@ IN: cocoa.pasteboard
 : set-pasteboard-string ( str pasteboard -- )
     NSStringPboardType <NSString>
     dup 1array pick set-pasteboard-types
-    >r swap <NSString> r> -> setString:forType: drop ;
+    [ swap <NSString> ] dip -> setString:forType: drop ;
 
 : pasteboard-error ( error -- f )
     "Pasteboard does not hold a string" <NSString>
index fd18c7fa89d738e07c95d3831fd8b238e8e0f6a4..40f21d25b8ffb4f8803b4d8327c10bcf7032ed50 100644 (file)
@@ -36,7 +36,7 @@ IN: cocoa.subclassing
     ] map concat ;
 
 : prepare-method ( ret types quot -- type imp )
-    >r [ encode-types ] 2keep r> [
+    [ [ encode-types ] 2keep ] dip [
         "cdecl" swap 4array % \ alien-callback ,
     ] [ ] make define-temp ;
 
index 3e7bd26965860577a0e618b9df10a1d55769e4a9..be67f03184e12347b8596f897c6c3c8ce16b1663 100644 (file)
@@ -74,7 +74,7 @@ PRIVATE>
     -> autorelease ;
 
 : <GLView> ( class dim -- view )
-    >r -> alloc 0 0 r> first2 <NSRect> <PixelFormat>
+    [ -> alloc 0 0 ] dip first2 <NSRect> <PixelFormat>
     -> initWithFrame:pixelFormat:
     dup 1 -> setPostsBoundsChangedNotifications:
     dup 1 -> setPostsFrameChangedNotifications: ;
@@ -85,10 +85,11 @@ PRIVATE>
     swap NSRect-h >fixnum 2array ;
 
 : mouse-location ( view event -- loc )
-    over >r
-    -> locationInWindow f -> convertPoint:fromView:
-    dup NSPoint-x swap NSPoint-y
-    r> -> frame NSRect-h swap - 2array ;
+    [
+        -> locationInWindow f -> convertPoint:fromView:
+        [ NSPoint-x ] [ NSPoint-y ] bi
+    ] [ drop -> frame NSRect-h ] 2bi
+    swap - 2array ;
 
 USE: opengl.gl
 USE: alien.syntax
index dd2d1bfd41f3ad7a61359d1cc2037fd49b7570d6..3a53a1cc3cfde331251e64bb92cb6cc04052380d 100644 (file)
@@ -34,5 +34,6 @@ IN: cocoa.windows
     dup 0 -> setReleasedWhenClosed: ;
 
 : window-content-rect ( window -- rect )
-    NSWindow over -> frame rot -> styleMask
+    [ NSWindow ] dip
+    [ -> frame ] [ -> styleMask ] bi
     -> contentRectForFrameRect:styleMask: ;
index 65d290df3ab9f8022c668e68619574ebd4b0367a..3d06bd97b7a88232a44a2ea69e222d893a4660f6 100644 (file)
@@ -1,4 +1,5 @@
-USING: help.markup help.syntax parser vocabs.loader strings ;
+USING: help.markup help.syntax parser vocabs.loader strings
+command-line.private ;
 IN: command-line
 
 HELP: run-bootstrap-init
@@ -7,7 +8,10 @@ HELP: run-bootstrap-init
 HELP: run-user-init
 { $description "Runs the startup initialization file in the user's home directory, unless the " { $snippet "-no-user-init" } " command line switch was given. This file is named " { $snippet ".factor-rc" } " on Unix and " { $snippet "factor-rc" } " on Windows." } ;
 
-HELP: cli-param
+HELP: load-vocab-roots
+{ $description "Loads the newline-separated list of additional vocabulary roots from the file named " { $snippet ".factor-roots" } " on Unix and " { $snippet "factor-roots" } " on Windows." } ;
+
+HELP: param
 { $values { "param" string } }
 { $description "Process a command-line switch."
 $nl
@@ -17,10 +21,13 @@ $nl
 $nl
 "Otherwise, sets the global variable named by the parameter to " { $link t } "." } ;
 
-HELP: cli-args
+HELP: (command-line)
 { $values { "args" "a sequence of strings" } }
 { $description "Outputs the command line parameters which were passed to the Factor VM on startup." } ;
 
+HELP: command-line
+{ $var-description "The command line parameters which follow the name of the script on the command line." } ;
+
 HELP: main-vocab-hook
 { $var-description "Global variable holding a quotation which outputs a vocabulary name. UI backends set this so that the UI can automatically start if the prerequisites are met (for example, " { $snippet "$DISPLAY" } " being set on X11)." } ;
 
@@ -35,9 +42,6 @@ HELP: ignore-cli-args?
 { $values { "?" "a boolean" } }
 { $description "On Mac OS X, source files to run are supplied by the Cocoa API, so to avoid running them twice the startup code has to call this word." } ;
 
-HELP: parse-command-line
-{ $description "Called on startup to process command line arguments. This sets global variables with " { $link cli-param } ", runs source files, and evaluates the string given by the " { $snippet "-e" } " switch, if there is one." } ;
-
 ARTICLE: "runtime-cli-args" "Command line switches for the VM"
 "A handful of command line switches are processed by the VM and not the library. They control low-level features."
 { $table
@@ -64,9 +68,12 @@ ARTICLE: "bootstrap-cli-args" "Command line switches for bootstrap"
 }
 "Bootstrap can load various optional components:"
 { $table
+    { { $snippet "math" } "Rational and complex number support." }
+    { { $snippet "threads" } "Thread support." }
     { { $snippet "compiler" } "The compiler." }
     { { $snippet "tools" } "Terminal-based developer tools." }
     { { $snippet "help" } "The help system." }
+    { { $snippet "help.handbook" } "The help handbook." }
     { { $snippet "ui" } "The graphical user interface." }
     { { $snippet "ui.tools" } "Graphical developer tools." }
     { { $snippet "io" } "Non-blocking I/O and networking." }
@@ -86,7 +93,6 @@ ARTICLE: "standard-cli-args" "Command line switches for general usage"
     { { $snippet "-run=" { $emphasis "vocab" } } { { $snippet { $emphasis "vocab" } } " is the name of a vocabulary with a " { $link POSTPONE: MAIN: } " hook to run on startup, for example " { $vocab-link "listener" } ", " { $vocab-link "ui" } " or " { $vocab-link "none" } "." } }
     { { $snippet "-no-user-init" } { "Inhibits the running of user initialization files on startup. See " { $link "rc-files" } "." } }
     { { $snippet "-quiet" } { "If set, " { $link run-file } " and " { $link require } " will not print load messages." } }
-    { { $snippet "-script" } { "Equivalent to " { $snippet "-quiet -run=none" } "." $nl "On Unix systems, Factor can be used for scripting - just create an executable text file whose first line is:" { $code "#! /usr/local/bin/factor -script" } "The space after " { $snippet "#!" } " is necessary because of Factor syntax." } }
 } ;
 
 ARTICLE: "factor-boot-rc" "Bootstrap initialization file"
@@ -102,11 +108,18 @@ $nl
 "A word to run this file from an existing Factor session:"
 { $subsection run-user-init } ;
 
+ARTICLE: "factor-roots" "Additional vocabulary roots file"
+"The vocabulary roots file is named " { $snippet "factor-roots" } " on Windows and " { $snippet ".factor-roots" } " on Unix. If it exists, it is loaded every time Factor starts. It contains a newline-separated list of " { $link "vocabs.roots" } "."
+$nl
+"A word to run this file from an existing Factor session:"
+{ $subsection load-vocab-roots } ;
+
 ARTICLE: "rc-files" "Running code on startup"
-"Factor looks for two files in your home directory."
+"Factor looks for three optional files in your home directory."
 { $subsection "factor-boot-rc" }
 { $subsection "factor-rc" }
-"The " { $snippet "-no-user-init" } " command line switch will inhibit the running of these files."
+{ $subsection "factor-roots" }
+"The " { $snippet "-no-user-init" } " command line switch will inhibit loading running of these files."
 $nl
 "If you are unsure where the files should be located, evaluate the following code:"
 { $code
@@ -122,8 +135,16 @@ $nl
     "100 dpi set-global"
 } ;
 
-ARTICLE: "cli" "Command line usage"
-"Zero or more command line arguments may be passed to the Factor runtime. Command line arguments starting with a dash (" { $snippet "-" } ") is interpreted as switches. All other arguments are taken to be file names to be run by " { $link run-file } "."
+ARTICLE: "cli" "Command line arguments"
+"Factor command line usage:"
+{ $code "factor [system switches...] [script args...]" }
+"Zero or more system switches can be passed in, followed by an optional script file name. If the script file is specified, it will be run on startup, any arguments after the script file are stored in a variable, with no further processing by Factor itself:"
+{ $subsection command-line }
+"Instead of running a script, it is also possible to run a vocabulary; this invokes the vocabulary's " { $link POSTPONE: MAIN: } " word:"
+{ $code "factor [system switches...] -run=<vocab name>" }
+"If no script file or " { $snippet "-run=" } " switch is specified, Factor will start " { $link "listener" } " or " { $link "ui-tools" } ", depending on the operating system."
+$nl
+"As stated above, arguments in the first part of the command line, before the optional script name, are interpreted by to the Factor system. These arguments all start with a dash (" { $snippet "-" } ")."
 $nl
 "Switches can take one of the following three forms:"
 { $list
@@ -134,9 +155,9 @@ $nl
 { $subsection "runtime-cli-args" }
 { $subsection "bootstrap-cli-args" }
 { $subsection "standard-cli-args" }
-"The list of command line arguments can be obtained and inspected directly:"
-{ $subsection cli-args }
-"There is a way to override the default vocabulary to run on startup:"
+"The raw list of command line arguments can also be obtained and inspected directly:"
+{ $subsection (command-line) }
+"There is a way to override the default vocabulary to run on startup, if no script name or " { $snippet "-run" } " switch is specified:"
 { $subsection main-vocab-hook } ;
 
 ABOUT: "cli"
diff --git a/basis/command-line/command-line-tests.factor b/basis/command-line/command-line-tests.factor
deleted file mode 100644 (file)
index 226765b..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-USING: namespaces tools.test kernel command-line ;
-IN: command-line.tests
-
-[
-    [ f ] [ "-no-user-init" cli-arg ] unit-test
-    [ f ] [ "user-init" get ] unit-test
-
-    [ f ] [ "-user-init" cli-arg ] unit-test
-    [ t ] [ "user-init" get ] unit-test
-    
-    [ "sdl.factor" ] [ "sdl.factor" cli-arg ] unit-test
-] with-scope
index 7691f6877bb6ababbd9a7ce0c3b3412897074d21..1b58053b64d2af681760f542902957fb147bd51f 100644 (file)
@@ -1,10 +1,15 @@
 ! Copyright (C) 2003, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: init continuations debugger hashtables io kernel
-kernel.private namespaces parser sequences strings system
-splitting io.files eval ;
+USING: init continuations debugger hashtables io
+io.encodings.utf8 io.files kernel kernel.private namespaces
+parser sequences strings system splitting eval vocabs.loader ;
 IN: command-line
 
+SYMBOL: script
+SYMBOL: command-line
+
+: (command-line) ( -- args ) 10 getenv sift ;
+
 : rc-path ( name -- path )
     os windows? [ "." prepend ] unless
     home prepend-path ;
@@ -19,17 +24,33 @@ IN: command-line
         "factor-rc" rc-path ?run-file
     ] when ;
 
-: cli-var-param ( name value -- ) swap set-global ;
+: load-vocab-roots ( -- )
+    "user-init" get [
+        "factor-roots" rc-path dup exists? [
+            utf8 file-lines [ add-vocab-root ] each
+        ] [ drop ] if
+    ] when ;
+
+<PRIVATE
+
+: var-param ( name value -- ) swap set-global ;
+
+: bool-param ( name -- ) "no-" ?head not var-param ;
 
-: cli-bool-param ( name -- ) "no-" ?head not cli-var-param ;
+: param ( param -- )
+    "=" split1 [ var-param ] [ bool-param ] if* ;
 
-: cli-param ( param -- )
-    "=" split1 [ cli-var-param ] [ cli-bool-param ] if* ;
+: run-script ( file -- )
+    t "quiet" set-global run-file ;
 
-: cli-arg ( argument -- argument )
-    "-" ?head [ cli-param f ] when ;
+PRIVATE>
 
-: cli-args ( -- args ) 10 getenv ;
+: parse-command-line ( args -- )
+    [ command-line off script off ] [
+        unclip "-" ?head
+        [ param parse-command-line ]
+        [ script set command-line set ] if
+    ] if-empty ;
 
 SYMBOL: main-vocab-hook
 
@@ -53,14 +74,17 @@ SYMBOL: main-vocab-hook
 : ignore-cli-args? ( -- ? )
     os macosx? "run" get "ui" = and ;
 
-: script-mode ( -- )
-    t "quiet" set-global
-    "none" "run" set-global ;
+: script-mode ( -- ) ;
 
-: parse-command-line ( -- )
-    cli-args [ cli-arg ] filter
-    "script" get [ script-mode ] when
-    ignore-cli-args? [ drop ] [ [ run-file ] each ] if
-    "e" get [ eval ] when* ;
+: handle-command-line ( -- )
+    [
+        (command-line) parse-command-line
+        load-vocab-roots
+        run-user-init
+        "e" get [ eval ] when*
+        ignore-cli-args? not script get and
+        [ run-script ] [ "run" get run ] if*
+        output-stream get [ stream-flush ] when*
+    ] [ print-error 1 exit ] recover ;
 
 [ default-cli-args ] "command-line" add-init-hook
index e414d6e29b7d8a31919cb94bf049b0651792e633..4a41014ab2c9ac7bae447d4b757c5fe4cd243893 100644 (file)
@@ -18,7 +18,7 @@ IN: compiler.alien
     dup c-type-stack-align? [ c-type-align ] [ drop cell ] if ;
 
 : parameter-align ( n type -- n delta )
-    over >r c-type-stack-align align dup r> - ;
+    [ c-type-stack-align align dup ] [ drop ] 2bi - ;
 
 : parameter-sizes ( types -- total offsets )
     #! Compute stack frame locations.
index 7e97961eb3efd461201e05485bd799c68eb37a63..3825ae480e17b1f74b09ac507999c601e67bff79 100644 (file)
@@ -18,6 +18,8 @@ M: ##string-nth defs-vregs dst/tmp-vregs ;
 M: ##compare defs-vregs dst/tmp-vregs ;
 M: ##compare-imm defs-vregs dst/tmp-vregs ;
 M: ##compare-float defs-vregs dst/tmp-vregs ;
+M: ##fixnum-mul defs-vregs [ temp1>> ] [ temp2>> ] bi 2array ;
+M: ##fixnum-mul-tail defs-vregs [ temp1>> ] [ temp2>> ] bi 2array ;
 M: insn defs-vregs drop f ;
 
 M: ##unary uses-vregs src>> 1array ;
index 9e82851c12ef95a5f21ed4fd66e506a70cae2a32..62d4990c92bc5f6af5f7b1387341697fce35a006 100644 (file)
@@ -98,8 +98,8 @@ INSN: ##fixnum-add < ##fixnum-overflow ;
 INSN: ##fixnum-add-tail < ##fixnum-overflow ;
 INSN: ##fixnum-sub < ##fixnum-overflow ;
 INSN: ##fixnum-sub-tail < ##fixnum-overflow ;
-INSN: ##fixnum-mul < ##fixnum-overflow ;
-INSN: ##fixnum-mul-tail < ##fixnum-overflow ;
+INSN: ##fixnum-mul < ##fixnum-overflow temp1 temp2 ;
+INSN: ##fixnum-mul-tail < ##fixnum-overflow temp1 temp2 ;
 
 : ##tag-fixnum ( dst src -- ) tag-bits get ##shl-imm ; inline
 : ##untag-fixnum ( dst src -- ) tag-bits get ##sar-imm ; inline
index 6c6c2955c9d62af138b63b0a2542e9667c6c6ef0..aaa45c39372aca87b023f379a6bf6f1c924310a6 100644 (file)
@@ -26,6 +26,7 @@ IN: compiler.cfg.intrinsics
     math.private:both-fixnums?
     math.private:fixnum+
     math.private:fixnum-
+    math.private:fixnum*
     math.private:fixnum+fast
     math.private:fixnum-fast
     math.private:fixnum-bitand
@@ -89,16 +90,13 @@ IN: compiler.cfg.intrinsics
         alien.accessors:set-alien-double
     } [ t "intrinsic" set-word-prop ] each ;
 
-: enable-fixnum*-intrinsic ( -- )
-    \ math.private:fixnum* t "intrinsic" set-word-prop ;
-
 : emit-intrinsic ( node word -- node/f )
     {
         { \ kernel.private:tag [ drop emit-tag iterate-next ] }
         { \ math.private:both-fixnums? [ drop emit-both-fixnums? iterate-next ] }
         { \ math.private:fixnum+ [ drop [ ##fixnum-add ] [ ##fixnum-add-tail ] emit-fixnum-overflow-op ] }
         { \ math.private:fixnum- [ drop [ ##fixnum-sub ] [ ##fixnum-sub-tail ] emit-fixnum-overflow-op ] }
-        { \ math.private:fixnum* [ drop [ ##fixnum-mul ] [ ##fixnum-mul-tail ] emit-fixnum-overflow-op ] }
+        { \ math.private:fixnum* [ drop [ i i ##fixnum-mul ] [ i i ##fixnum-mul-tail ] emit-fixnum-overflow-op ] }
         { \ math.private:fixnum+fast [ [ ^^add ] [ ^^add-imm ] emit-fixnum-op iterate-next ] }
         { \ math.private:fixnum-fast [ [ ^^sub ] [ ^^sub-imm ] emit-fixnum-op iterate-next ] }
         { \ math.private:fixnum-bitand [ [ ^^and ] [ ^^and-imm ] emit-fixnum-op iterate-next ] }
index b66b6a11c73e776c611ba8400b189522fa105843..2161c8b09145b224b1a65d3d848592d4a44c7735 100644 (file)
@@ -159,12 +159,15 @@ M: ##not     generate-insn dst/src       %not     ;
 : src1/src2 ( insn -- src1 src2 )
     [ src1>> register ] [ src2>> register ] bi ; inline
 
+: src1/src2/temp1/temp2 ( insn -- src1 src2 temp1 temp2 )
+    [ src1/src2 ] [ temp1>> register ] [ temp2>> register ] tri ; inline
+
 M: ##fixnum-add generate-insn src1/src2 %fixnum-add ;
 M: ##fixnum-add-tail generate-insn src1/src2 %fixnum-add-tail ;
 M: ##fixnum-sub generate-insn src1/src2 %fixnum-sub ;
 M: ##fixnum-sub-tail generate-insn src1/src2 %fixnum-sub-tail ;
-M: ##fixnum-mul generate-insn src1/src2 %fixnum-mul ;
-M: ##fixnum-mul-tail generate-insn src1/src2 %fixnum-mul-tail ;
+M: ##fixnum-mul generate-insn src1/src2/temp1/temp2 %fixnum-mul ;
+M: ##fixnum-mul-tail generate-insn src1/src2/temp1/temp2 %fixnum-mul-tail ;
 
 : dst/src/temp ( insn -- dst src temp )
     [ dst/src ] [ temp>> register ] bi ; inline
@@ -274,7 +277,7 @@ M: object reg-class-full?
 
 : spill-param ( reg-class -- n reg-class )
     stack-params get
-    >r reg-size cell align stack-params +@ r>
+    [ reg-size cell align stack-params +@ ] dip
     stack-params ;
 
 : fastcall-param ( reg-class -- n reg-class )
@@ -310,10 +313,10 @@ M: long-long-type flatten-value-type ( type -- types )
     ] { } make ;
 
 : each-parameter ( parameters quot -- )
-    >r [ parameter-sizes nip ] keep r> 2each ; inline
+    [ [ parameter-sizes nip ] keep ] dip 2each ; inline
 
 : reverse-each-parameter ( parameters quot -- )
-    >r [ parameter-sizes nip ] keep r> 2reverse-each ; inline
+    [ [ parameter-sizes nip ] keep ] dip 2reverse-each ; inline
 
 : reset-freg-counts ( -- )
     { int-regs float-regs stack-params } [ 0 swap set ] each ;
@@ -326,15 +329,13 @@ M: long-long-type flatten-value-type ( type -- types )
     #! Moves values from C stack to registers (if word is
     #! %load-param-reg) and registers to C stack (if word is
     #! %save-param-reg).
-    >r
-    alien-parameters
-    flatten-value-types
-    r> '[ alloc-parameter _ execute ] each-parameter ;
-    inline
+    [ alien-parameters flatten-value-types ]
+    [ '[ alloc-parameter _ execute ] ]
+    bi* each-parameter ; inline
 
 : unbox-parameters ( offset node -- )
     parameters>> [
-        %prepare-unbox >r over + r> unbox-parameter
+        %prepare-unbox [ over + ] dip unbox-parameter
     ] reverse-each-parameter drop ;
 
 : prepare-box-struct ( node -- offset )
index 06abec59688afa5b0918e5c6ccebb3918b359bc4..0302218652c013a4ff699a98f20756aabe3f98d4 100755 (executable)
@@ -46,28 +46,27 @@ M: integer fixup* , ;
 : indq ( elt seq -- n ) [ eq? ] with find drop ;
 
 : adjoin* ( obj table -- n )
-    2dup indq [ 2nip ] [ dup length >r push r> ] if* ;
+    2dup indq [ 2nip ] [ dup length [ push ] dip ] if* ;
 
 SYMBOL: literal-table
 
 : add-literal ( obj -- n ) literal-table get adjoin* ;
 
 : add-dlsym-literals ( symbol dll -- )
-    >r string>symbol r> 2array literal-table get push-all ;
+    [ string>symbol ] dip 2array literal-table get push-all ;
 
 : rel-dlsym ( name dll class -- )
-    >r literal-table get length >r
-    add-dlsym-literals
-    r> r> rt-dlsym rel-fixup ;
+    [ literal-table get length [ add-dlsym-literals ] dip ] dip
+    rt-dlsym rel-fixup ;
 
 : rel-word ( word class -- )
-    >r add-literal r> rt-xt rel-fixup ;
+    [ add-literal ] dip rt-xt rel-fixup ;
 
 : rel-primitive ( word class -- )
-    >r def>> first r> rt-primitive rel-fixup ;
+    [ def>> first ] dip rt-primitive rel-fixup ;
 
 : rel-immediate ( literal class -- )
-    >r add-literal r> rt-immediate rel-fixup ;
+    [ add-literal ] dip rt-immediate rel-fixup ;
 
 : rel-this ( class -- )
     0 swap rt-label rel-fixup ;
index 3c4741272d0ec3d72549fba54046fda3782caff7..df5f484952b71a1df3c73cba2887ab1a9e6e98a8 100644 (file)
@@ -213,6 +213,7 @@ IN: compiler.tests
 [ -1 ] [ [ -123 -64 fixnum-shift ] compile-call ] unit-test
 [ -1 ] [ -123 -64 [ fixnum-shift ] compile-call ] unit-test
 
+[ HEX: 10000000 ] [ HEX: 1000000 HEX: 10 [ fixnum* ] compile-call ] unit-test
 [ HEX: 10000000 ] [ HEX: -10000000 >fixnum [ 0 swap fixnum- ] compile-call ] unit-test
 [ HEX: 10000000 ] [ HEX: -fffffff >fixnum [ 1 swap fixnum- ] compile-call ] unit-test
 
index 43374d312754d6d35d5ecb469eca432ee1c6934c..11e624110c634e790eb1d88cd4ba41f20c84da91 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2008 Slava Pestov.\r
 ! See http://factorcode.org/license.txt for BSD license.\r
-USING: deques threads kernel arrays sequences alarms ;\r
+USING: deques threads kernel arrays sequences alarms fry ;\r
 IN: concurrency.conditions\r
 \r
 : notify-1 ( deque -- )\r
@@ -12,15 +12,18 @@ IN: concurrency.conditions
 : queue-timeout ( queue timeout -- alarm )\r
     #! Add an alarm which removes the current thread from the\r
     #! queue, and resumes it, passing it a value of t.\r
-    >r [ self swap push-front* ] keep [\r
-        [ delete-node ] [ drop node-value ] 2bi\r
-        t swap resume-with\r
-    ] 2curry r> later ;\r
+    [\r
+        [ self swap push-front* ] keep '[\r
+            _ _\r
+            [ delete-node ] [ drop node-value ] 2bi\r
+            t swap resume-with\r
+        ]\r
+    ] dip later ;\r
 \r
 : wait ( queue timeout status -- )\r
     over [\r
-        >r queue-timeout [ drop ] r> suspend\r
+        [ queue-timeout [ drop ] ] dip suspend\r
         [ "Timeout" throw ] [ cancel-alarm ] if\r
     ] [\r
-        >r drop [ push-front ] curry r> suspend drop\r
+        [ drop '[ _ push-front ] ] dip suspend drop\r
     ] if ;\r
index c4bc92c688145c09945c2354eef123fbb41982c6..d79cfbf1c91b9863801cd9dcc03eec2cae4634d0 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Slava Pestov.\r
 ! See http://factorcode.org/license.txt for BSD license.\r
 USING: dlists kernel math concurrency.promises\r
-concurrency.mailboxes debugger accessors ;\r
+concurrency.mailboxes debugger accessors fry ;\r
 IN: concurrency.count-downs\r
 \r
 ! http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/CountDownLatch.html\r
@@ -26,12 +26,12 @@ ERROR: count-down-already-done ;
     [ 1- >>n count-down-check ] if ;\r
 \r
 : await-timeout ( count-down timeout -- )\r
-    >r promise>> r> ?promise-timeout ?linked t assert= ;\r
+    [ promise>> ] dip ?promise-timeout ?linked t assert= ;\r
 \r
 : await ( count-down -- )\r
     f await-timeout ;\r
 \r
 : spawn-stage ( quot count-down -- )\r
-    [ [ count-down ] curry compose ] keep\r
+    [ '[ @ _ count-down ] ] keep\r
     "Count down stage"\r
     swap promise>> mailbox>> spawn-linked-to drop ;\r
index 528e1956b88f88b52248d0a43cd4018af326ee17..1087823aa0ff2e93ee623c2068b2e8c58a8a3954 100644 (file)
@@ -15,7 +15,7 @@ concurrency.messaging continuations accessors prettyprint ;
 
 [ ] [
     [
-        receive first2 >r 3 + r> send
+        receive first2 [ 3 + ] dip send
         "thread-a" unregister-process
     ] "Thread A" spawn
     "thread-a" swap register-process
index 6b44886eda86cfb51edf467e094bb4ad180b552a..97b3c14fe41cd29c4ac1185119b10463fcece045 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2008 Slava Pestov.\r
 ! See http://factorcode.org/license.txt for BSD license.\r
-USING: kernel threads boxes accessors ;\r
+USING: kernel threads boxes accessors fry ;\r
 IN: concurrency.exchangers\r
 \r
 ! Motivated by\r
@@ -14,8 +14,8 @@ TUPLE: exchanger thread object ;
 : exchange ( obj exchanger -- newobj )\r
     dup thread>> occupied>> [\r
         dup object>> box>\r
-        >r thread>> box> resume-with r>\r
+        [ thread>> box> resume-with ] dip\r
     ] [\r
         [ object>> >box ] keep\r
-        [ thread>> >box ] curry "exchange" suspend\r
+        '[ _ thread>> >box ] "exchange" suspend\r
     ] if ;\r
index 0f78183abaade2cd0d4aa2ed645f3c7dc3128a46..a66629331652532fed94f07fdbd0fb24496deed3 100644 (file)
@@ -2,7 +2,7 @@ IN: concurrency.flags.tests
 USING: tools.test concurrency.flags concurrency.combinators\r
 kernel threads locals accessors calendar ;\r
 \r
-:: flag-test-1 ( -- )\r
+:: flag-test-1 ( -- val )\r
     [let | f [ <flag> ] |\r
         [ f raise-flag ] "Flag test" spawn drop\r
         f lower-flag\r
@@ -20,7 +20,7 @@ kernel threads locals accessors calendar ;
 \r
 [ f ] [ flag-test-2 ] unit-test\r
 \r
-:: flag-test-3 ( -- )\r
+:: flag-test-3 ( -- val )\r
     [let | f [ <flag> ] |\r
         f raise-flag\r
         f value>>\r
@@ -28,7 +28,7 @@ kernel threads locals accessors calendar ;
 \r
 [ t ] [ flag-test-3 ] unit-test\r
 \r
-:: flag-test-4 ( -- )\r
+:: flag-test-4 ( -- val )\r
     [let | f [ <flag> ] |\r
         [ f raise-flag ] "Flag test" spawn drop\r
         f wait-for-flag\r
@@ -37,7 +37,7 @@ kernel threads locals accessors calendar ;
 \r
 [ t ] [ flag-test-4 ] unit-test\r
 \r
-:: flag-test-5 ( -- )\r
+:: flag-test-5 ( -- val )\r
     [let | f [ <flag> ] |\r
         [ 1 seconds sleep f raise-flag ] "Flag test" spawn drop\r
         f wait-for-flag\r
index ec260961d0417c7ca3a2407d2ba320cb92c2a3be..c65171a3f00b2d8c1c28c7d8ea6ccfcf8cbd240e 100644 (file)
@@ -11,7 +11,7 @@ TUPLE: flag value threads ;
     dup value>> [ drop ] [ t >>value threads>> notify-all ] if ;
 
 : wait-for-flag-timeout ( flag timeout -- )
-    over value>> [ 2drop ] [ >r threads>> r> "flag" wait ] if ;
+    over value>> [ 2drop ] [ [ threads>> ] dip "flag" wait ] if ;
 
 : wait-for-flag ( flag -- )
     f wait-for-flag-timeout ;
index 132342aff1fdda735153304afbe2b959a01ffce2..a1f4f57af63eb417811d8405a1759f465bcfa13c 100644 (file)
@@ -1,12 +1,12 @@
 ! Copyright (C) 2005, 2008 Chris Double, Slava Pestov.\r
 ! See http://factorcode.org/license.txt for BSD license.\r
 USING: concurrency.promises concurrency.mailboxes kernel arrays\r
-continuations accessors ;\r
+continuations accessors fry ;\r
 IN: concurrency.futures\r
 \r
 : future ( quot -- future )\r
     <promise> [\r
-        [ [ >r call r> fulfill ] 2curry "Future" ] keep\r
+        [ '[ @ _ fulfill ] "Future" ] keep\r
         mailbox>> spawn-linked-to drop\r
     ] keep ; inline\r
 \r
index 7696e6c1ebe061a010ae0bf78da4cafda2a15863..8f82aa88baa997c56780e6b51e6b17117a7fa71f 100644 (file)
@@ -3,7 +3,7 @@ USING: tools.test concurrency.locks concurrency.count-downs
 concurrency.messaging concurrency.mailboxes locals kernel\r
 threads sequences calendar accessors ;\r
 \r
-:: lock-test-0 ( -- )\r
+:: lock-test-0 ( -- )\r
     [let | v [ V{ } clone ]\r
            c [ 2 <count-down> ] |\r
 \r
@@ -27,7 +27,7 @@ threads sequences calendar accessors ;
            v\r
     ] ;\r
 \r
-:: lock-test-1 ( -- )\r
+:: lock-test-1 ( -- )\r
     [let | v [ V{ } clone ]\r
            l [ <lock> ]\r
            c [ 2 <count-down> ] |\r
@@ -79,7 +79,7 @@ threads sequences calendar accessors ;
 \r
 [ ] [ <rw-lock> dup [ [ ] with-read-lock ] with-write-lock ] unit-test\r
 \r
-:: rw-lock-test-1 ( -- )\r
+:: rw-lock-test-1 ( -- )\r
     [let | l [ <rw-lock> ]\r
            c [ 1 <count-down> ]\r
            c' [ 1 <count-down> ]\r
@@ -129,7 +129,7 @@ threads sequences calendar accessors ;
 \r
 [ V{ 1 2 3 4 5 6 } ] [ rw-lock-test-1 ] unit-test\r
 \r
-:: rw-lock-test-2 ( -- )\r
+:: rw-lock-test-2 ( -- )\r
     [let | l [ <rw-lock> ]\r
            c [ 1 <count-down> ]\r
            c' [ 2 <count-down> ]\r
@@ -160,7 +160,7 @@ threads sequences calendar accessors ;
 [ V{ 1 2 3 } ] [ rw-lock-test-2 ] unit-test\r
 \r
 ! Test lock timeouts\r
-:: lock-timeout-test ( -- )\r
+:: lock-timeout-test ( -- )\r
     [let | l [ <lock> ] |\r
         [\r
             l [ 1 seconds sleep ] with-lock\r
@@ -177,19 +177,6 @@ threads sequences calendar accessors ;
     thread>> name>> "Lock timeout-er" =\r
 ] must-fail-with\r
 \r
-:: read/write-test ( -- )\r
-    [let | l [ <lock> ] |\r
-        [\r
-            l [ 1 seconds sleep ] with-lock\r
-        ] "Lock holder" spawn drop\r
-\r
-        [\r
-            l 1/10 seconds [ ] with-lock-timeout\r
-        ] "Lock timeout-er" spawn-linked drop\r
-\r
-        receive\r
-    ] ;\r
-\r
 [\r
     <rw-lock> dup [\r
         1 seconds [ ] with-write-lock-timeout\r
index 8c1392dbfb667cf84aa9d2621ddd98efc6c93787..0094f3323d709d26f22850b02ee2a206ab12a537 100644 (file)
@@ -1,7 +1,8 @@
 ! Copyright (C) 2008 Slava Pestov.\r
 ! See http://factorcode.org/license.txt for BSD license.\r
 USING: deques dlists kernel threads continuations math\r
-concurrency.conditions combinators.short-circuit accessors ;\r
+concurrency.conditions combinators.short-circuit accessors\r
+locals ;\r
 IN: concurrency.locks\r
 \r
 ! Simple critical sections\r
@@ -17,16 +18,16 @@ TUPLE: lock threads owner reentrant? ;
 \r
 : acquire-lock ( lock timeout -- )\r
     over owner>>\r
-    [ 2dup >r threads>> r> "lock" wait ] when drop\r
+    [ 2dup [ threads>> ] dip "lock" wait ] when drop\r
     self >>owner drop ;\r
 \r
 : release-lock ( lock -- )\r
     f >>owner\r
     threads>> notify-1 ;\r
 \r
-: do-lock ( lock timeout quot acquire release -- )\r
-    >r >r pick rot r> call ! use up  timeout acquire\r
-    swap r> curry [ ] cleanup ; inline\r
+:: do-lock ( lock timeout quot acquire release -- )\r
+    lock timeout acquire call\r
+    quot lock release curry [ ] cleanup ; inline\r
 \r
 : (with-lock) ( lock timeout quot -- )\r
     [ acquire-lock ] [ release-lock ] do-lock ; inline\r
@@ -60,7 +61,7 @@ TUPLE: rw-lock readers writers reader# writer ;
 \r
 : acquire-read-lock ( lock timeout -- )\r
     over writer>>\r
-    [ 2dup >r readers>> r> "read lock" wait ] when drop\r
+    [ 2dup [ readers>> ] dip "read lock" wait ] when drop\r
     add-reader ;\r
 \r
 : notify-writer ( lock -- )\r
@@ -75,7 +76,7 @@ TUPLE: rw-lock readers writers reader# writer ;
 \r
 : acquire-write-lock ( lock timeout -- )\r
     over writer>> pick reader#>> 0 > or\r
-    [ 2dup >r writers>> r> "write lock" wait ] when drop\r
+    [ 2dup [ writers>> ] dip "write lock" wait ] when drop\r
     self >>writer drop ;\r
 \r
 : release-write-lock ( lock -- )\r
index 39b21e0943d3571ba49f5e5d49548193ba531798..63707041a23f59b508e361ce22d2bf0c12305ced 100644 (file)
@@ -4,7 +4,7 @@ IN: concurrency.mailboxes
 USING: dlists deques threads sequences continuations\r
 destructors namespaces math quotations words kernel\r
 arrays assocs init system concurrency.conditions accessors\r
-debugger debugger.threads locals ;\r
+debugger debugger.threads locals fry ;\r
 \r
 TUPLE: mailbox threads data disposed ;\r
 \r
@@ -21,7 +21,7 @@ M: mailbox dispose* threads>> notify-all ;
     [ threads>> notify-all ] bi yield ;\r
 \r
 : wait-for-mailbox ( mailbox timeout -- )\r
-    >r threads>> r> "mailbox" wait ;\r
+    [ threads>> ] dip "mailbox" wait ;\r
 \r
 :: block-unless-pred ( mailbox timeout pred: ( message -- ? ) -- )\r
     mailbox check-disposed\r
@@ -57,11 +57,11 @@ M: mailbox dispose* threads>> notify-all ;
     f mailbox-get-all-timeout ;\r
 \r
 : while-mailbox-empty ( mailbox quot -- )\r
-    [ [ mailbox-empty? ] curry ] dip [ ] while ; inline\r
+    [ '[ _ mailbox-empty? ] ] dip [ ] while ; inline\r
 \r
 : mailbox-get-timeout? ( mailbox timeout pred -- obj )\r
     [ block-unless-pred ]\r
-    [ nip >r data>> r> delete-node-if ]\r
+    [ [ drop data>> ] dip delete-node-if ]\r
     3bi ; inline\r
 \r
 : mailbox-get? ( mailbox pred -- obj )\r
@@ -90,7 +90,7 @@ M: linked-thread error-in-thread
     [ <linked-error> ] [ supervisor>> ] bi mailbox-put ;\r
 \r
 : <linked-thread> ( quot name mailbox -- thread' )\r
-    >r linked-thread new-thread r> >>supervisor ;\r
+    [ linked-thread new-thread ] dip >>supervisor ;\r
 \r
 : spawn-linked-to ( quot name mailbox -- thread )\r
     <linked-thread> [ (spawn) ] keep ;\r
index 6c9e530d9b28ce6a84f6005c90a9f29c56a3facd..25538cd5948552a65771426f1f1c6102cc382fca 100644 (file)
@@ -55,7 +55,7 @@ ARTICLE: { "concurrency" "synchronous-sends" } "Synchronous sends"
 { $example
     "USING: concurrency.messaging kernel threads ;"
     ": pong-server ( -- )"
-    "    receive >r \"pong\" r> reply-synchronous ;"
+    "    receive [ \"pong\" ] dip reply-synchronous ;"
     "[ pong-server t ] \"pong-server\" spawn-server"
     "\"ping\" swap send-synchronous ."
     "\"pong\""
index 9aeb24ed723d12f889de09e86a05005819ca2734..7a00f62e9ebdc95bd7c06f2864713c768d984918 100644 (file)
@@ -1,10 +1,7 @@
 ! Copyright (C) 2005, 2008 Chris Double, Slava Pestov.\r
 ! See http://factorcode.org/license.txt for BSD license.\r
-!\r
-! Concurrency library for Factor, based on Erlang/Termite style\r
-! concurrency.\r
 USING: kernel threads concurrency.mailboxes continuations\r
-namespaces assocs accessors summary ;\r
+namespaces assocs accessors summary fry ;\r
 IN: concurrency.messaging\r
 \r
 GENERIC: send ( message thread -- )\r
@@ -32,7 +29,7 @@ M: thread send ( message thread -- )
     my-mailbox -rot mailbox-get-timeout? ?linked ; inline\r
 \r
 : rethrow-linked ( error process supervisor -- )\r
-    >r <linked-error> r> send ;\r
+    [ <linked-error> ] dip send ;\r
 \r
 : spawn-linked ( quot name -- thread )\r
     my-mailbox spawn-linked-to ;\r
@@ -48,9 +45,7 @@ TUPLE: reply data tag ;
     tag>> \ reply boa ;\r
 \r
 : synchronous-reply? ( response synchronous -- ? )\r
-    over reply?\r
-    [ >r tag>> r> tag>> = ]\r
-    [ 2drop f ] if ;\r
+    over reply? [ [ tag>> ] bi@ = ] [ 2drop f ] if ;\r
 \r
 ERROR: cannot-send-synchronous-to-self message thread ;\r
 \r
@@ -61,8 +56,8 @@ M: cannot-send-synchronous-to-self summary
     dup self eq? [\r
         cannot-send-synchronous-to-self\r
     ] [\r
-        >r <synchronous> dup r> send\r
-        [ synchronous-reply? ] curry receive-if\r
+        [ <synchronous> dup ] dip send\r
+        '[ _ synchronous-reply? ] receive-if\r
         data>>\r
     ] if ;\r
 \r
index 382697e04f1c7cb2b9c409ff3cc312d96895ffa7..2ff338c4e33a6eef62b3f89945a643cb75f245fd 100644 (file)
@@ -20,7 +20,7 @@ ERROR: promise-already-fulfilled promise ;
     ] if ;\r
 \r
 : ?promise-timeout ( promise timeout -- result )\r
-    >r mailbox>> r> block-if-empty mailbox-peek ;\r
+    [ mailbox>> ] dip block-if-empty mailbox-peek ;\r
 \r
 : ?promise ( promise -- result )\r
     f ?promise-timeout ;\r
index 1b55c7afa5641ffde0cdf5b4763e70fdc25b15a5..59518f4c8d7320d449f092345d519a24ad322048 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Slava Pestov.\r
 ! See http://factorcode.org/license.txt for BSD license.\r
 USING: dlists kernel threads math concurrency.conditions\r
-continuations accessors summary ;\r
+continuations accessors summary locals fry ;\r
 IN: concurrency.semaphores\r
 \r
 TUPLE: semaphore count threads ;\r
@@ -30,9 +30,9 @@ M: negative-count-semaphore summary
     [ 1+ ] change-count\r
     threads>> notify-1 ;\r
 \r
-: with-semaphore-timeout ( semaphore timeout quot -- )\r
-    pick rot acquire-timeout swap\r
-    [ release ] curry [ ] cleanup ; inline\r
+:: with-semaphore-timeout ( semaphore timeout quot -- )\r
+    semaphore timeout acquire-timeout\r
+    quot [ semaphore release ] [ ] cleanup ; inline\r
 \r
 : with-semaphore ( semaphore quot -- )\r
-    over acquire swap [ release ] curry [ ] cleanup ; inline\r
+    swap dup acquire '[ _ release ] [ ] cleanup ; inline\r
index 00bf73e9ddc8329a2036961b66f9d5fd46d496da..8a5bd1d24015f77574a4776aa6fd1500207b2933 100644 (file)
@@ -90,14 +90,14 @@ FUNCTION: CFTypeID CFGetTypeID ( CFTypeRef cf ) ;
 : <CFArray> ( seq -- alien )
     [ f swap length f CFArrayCreateMutable ] keep
     [ length ] keep
-    [ >r dupd r> CFArraySetValueAtIndex ] 2each ;
+    [ [ dupd ] dip CFArraySetValueAtIndex ] 2each ;
 
 : <CFString> ( string -- alien )
     f swap dup length CFStringCreateWithCharacters ;
 
 : CF>string ( alien -- string )
     dup CFStringGetLength 1+ "ushort" <c-array> [
-        >r 0 over CFStringGetLength r> CFStringGetCharacters
+        [ 0 over CFStringGetLength ] dip CFStringGetCharacters
     ] keep utf16n alien>string ;
 
 : CF>string-array ( alien -- seq )
@@ -107,8 +107,8 @@ FUNCTION: CFTypeID CFGetTypeID ( CFTypeRef cf ) ;
     [ <CFString> ] map dup <CFArray> swap [ CFRelease ] each ;
 
 : <CFFileSystemURL> ( string dir? -- url )
-    >r <CFString> f over kCFURLPOSIXPathStyle
-    r> CFURLCreateWithFileSystemPath swap CFRelease ;
+    [ <CFString> f over kCFURLPOSIXPathStyle ] dip
+    CFURLCreateWithFileSystemPath swap CFRelease ;
 
 : <CFURL> ( string -- url )
     <CFString>
index 6bec4b23c0958453baea559550e09fb818c27dc3..80678ec3dae7bfdee478e3f7471b0dd2825309f4 100644 (file)
@@ -4,7 +4,7 @@ USING: alien alien.c-types alien.strings alien.syntax kernel
 math sequences namespaces make assocs init accessors
 continuations combinators core-foundation
 core-foundation.run-loop core-foundation.run-loop.thread
-io.encodings.utf8 destructors ;
+io.encodings.utf8 destructors locals arrays ;
 IN: core-foundation.fsevents
 
 : kFSEventStreamCreateFlagUseCFTypes 2 ; inline
@@ -105,15 +105,14 @@ FUNCTION: CFStringRef FSEventStreamCopyDescription ( FSEventStreamRef streamRef
     "FSEventStreamContext" <c-object>
     [ set-FSEventStreamContext-info ] keep ;
 
-: <FSEventStream> ( callback info paths latency flags -- event-stream )
-    >r >r >r >r >r
+:: <FSEventStream> ( callback info paths latency flags -- event-stream )
     f ! allocator
-    r> ! callback
-    r> make-FSEventStreamContext
-    r> <CFStringArray> ! paths
+    callback
+    info make-FSEventStreamContext
+    paths <CFStringArray>
     FSEventStreamEventIdSinceNow ! sinceWhen
-    r> ! latency
-    r> ! flags
+    latency
+    flags
     FSEventStreamCreate ;
 
 : kCFRunLoopCommonModes ( -- string )
@@ -161,13 +160,11 @@ SYMBOL: event-stream-callbacks
 : remove-event-source-callback ( id -- )
     event-stream-callbacks get delete-at ;
 
-: >event-triple ( n eventPaths eventFlags eventIds -- triple )
-    [
-        >r >r >r dup dup
-        r> void*-nth utf8 alien>string ,
-        r> int-nth ,
-        r> longlong-nth ,
-    ] { } make ;
+:: >event-triple ( n eventPaths eventFlags eventIds -- triple )
+    n eventPaths void*-nth utf8 alien>string
+    n eventFlags int-nth
+    n eventIds longlong-nth
+    3array ;
 
 : master-event-source-callback ( -- alien )
     "void"
index 2fdad0132aa722ecf9a13d7ff86ef32f6006d4fa..12b6809df94e9afd3112709008217aed930b0a59 100644 (file)
@@ -81,8 +81,8 @@ HOOK: %fixnum-add cpu ( src1 src2 -- )
 HOOK: %fixnum-add-tail cpu ( src1 src2 -- )
 HOOK: %fixnum-sub cpu ( src1 src2 -- )
 HOOK: %fixnum-sub-tail cpu ( src1 src2 -- )
-HOOK: %fixnum-mul cpu ( src1 src2 -- )
-HOOK: %fixnum-mul-tail cpu ( src1 src2 -- )
+HOOK: %fixnum-mul cpu ( src1 src2 temp1 temp2 -- )
+HOOK: %fixnum-mul-tail cpu ( src1 src2 temp1 temp2 -- )
 
 HOOK: %integer>bignum cpu ( dst src temp -- )
 HOOK: %bignum>integer cpu ( dst src temp -- )
index 8632d236cc21fc61cbd3c69388fde8e7093b51a6..6b5158575004434f2c1ede91cae51a4ae3eb7428 100644 (file)
@@ -17,7 +17,6 @@ IN: cpu.ppc
 ! f30, f31: float scratch
 
 enable-float-intrinsics
-enable-fixnum*-intrinsic
 
 << \ ##integer>float t frame-required? set-word-prop
 \ ##float>integer t frame-required? set-word-prop >>
@@ -187,30 +186,32 @@ M: ppc %not     NOT ;
         [ 3 src1 MR 4 src2 MR ]
     } cond ;
 
+: clear-xer ( -- )
+    0 0 LI
+    0 MTXER ; inline
+
 :: overflow-template ( src1 src2 insn func -- )
     "no-overflow" define-label
-    0 0 LI
-    0 MTXER
+    clear-xer
     scratch-reg src2 src1 insn call
     scratch-reg ds-reg 0 STW
     "no-overflow" get BNO
-    src2 src1 move>args
+    src1 src2 move>args
     %prepare-alien-invoke
     func f %alien-invoke
     "no-overflow" resolve-label ; inline
 
 :: overflow-template-tail ( src1 src2 insn func -- )
     "overflow" define-label
-    0 0 LI
-    0 MTXER
+    clear-xer
     scratch-reg src2 src1 insn call
     "overflow" get BO
     scratch-reg ds-reg 0 STW
     BLR
     "overflow" resolve-label
-    src2 src1 move>args
+    src1 src2 move>args
     %prepare-alien-invoke
-    func f %alien-invoke-tail ;
+    func f %alien-invoke-tail ; inline
 
 M: ppc %fixnum-add ( src1 src2 -- )
     [ ADDO. ] "overflow_fixnum_add" overflow-template ;
@@ -224,32 +225,30 @@ M: ppc %fixnum-sub ( src1 src2 -- )
 M: ppc %fixnum-sub-tail ( src1 src2 -- )
     [ SUBFO. ] "overflow_fixnum_subtract" overflow-template-tail ;
 
-M:: ppc %fixnum-mul ( src1 src2 -- )
+M:: ppc %fixnum-mul ( src1 src2 temp1 temp2 -- )
     "no-overflow" define-label
-    0 0 LI
-    0 MTXER
-    scratch-reg src1 tag-bits get SRAWI
-    scratch-reg scratch-reg src2 MULLWO.
-    scratch-reg ds-reg 0 STW
+    clear-xer
+    temp1 src1 tag-bits get SRAWI
+    temp2 temp1 src2 MULLWO.
+    temp2 ds-reg 0 STW
     "no-overflow" get BNO
     src2 src2 tag-bits get SRAWI
-    scratch-reg src2 move>args
+    temp1 src2 move>args
     %prepare-alien-invoke
     "overflow_fixnum_multiply" f %alien-invoke
     "no-overflow" resolve-label ;
 
-M:: ppc %fixnum-mul-tail ( src1 src2 -- )
+M:: ppc %fixnum-mul-tail ( src1 src2 temp1 temp2 -- )
     "overflow" define-label
-    0 0 LI
-    0 MTXER
-    scratch-reg src1 tag-bits get SRAWI
-    scratch-reg scratch-reg src2 MULLWO.
+    clear-xer
+    temp1 src1 tag-bits get SRAWI
+    temp2 temp1 src2 MULLWO.
     "overflow" get BO
-    scratch-reg ds-reg 0 STW
+    temp2 ds-reg 0 STW
     BLR
     "overflow" resolve-label
     src2 src2 tag-bits get SRAWI
-    scratch-reg src2 move>args
+    temp1 src2 move>args
     %prepare-alien-invoke
     "overflow_fixnum_multiply" f %alien-invoke-tail ;
 
index 9fd133075776f9ccd3dee17ccd33d865de5aab88..3df072208d9bc6cfa9fd6574458d0274a63ea87d 100755 (executable)
@@ -307,7 +307,7 @@ FUNCTION: bool check_sse2 ( ) ;
 : sse2? ( -- ? )
     check_sse2 ;
 
-"-no-sse2" cli-args member? [
+"-no-sse2" (command-line) member? [
     [ optimized-recompile-hook ] recompile-hook
     [ { check_sse2 } compile ] with-variable
 
index b6c76a78fd9f4caf5ce2b91ab03f08b61385ded0..6472ec0edf3cbf4df863313903e441c1f85dcb4c 100644 (file)
@@ -21,8 +21,6 @@ M: x86.64 machine-registers
 M: x86.64 ds-reg R14 ;
 M: x86.64 rs-reg R15 ;
 M: x86.64 stack-reg RSP ;
-M: x86.64 temp-reg-1 R8 ;
-M: x86.64 temp-reg-2 R9 ;
 
 M:: x86.64 %dispatch ( src temp offset -- )
     ! Load jump table base.
index ddb412873a60be0e136f177befa93b41d0b80b1f..f5fb5b9640c3f1eb16be0fd3428eda6dbf55dc80 100644 (file)
@@ -52,3 +52,7 @@ M: x86.64 dummy-stack-params? f ;
 M: x86.64 dummy-int-params? f ;
 
 M: x86.64 dummy-fp-params? f ;
+
+M: x86.64 temp-reg-1 R8 ;
+
+M: x86.64 temp-reg-2 R9 ;
index 629ba23e06aeb00afdd63c37b2466858cd031714..4c6af6c1e71242074560fe7893bca715210f9e2c 100644 (file)
@@ -20,6 +20,10 @@ M: x86.64 dummy-int-params? t ;
 
 M: x86.64 dummy-fp-params? t ;
 
+M: x86.64 temp-reg-1 RAX ;
+
+M: x86.64 temp-reg-2 RCX ;
+
 <<
 "longlong" "ptrdiff_t" typedef
 "longlong" "intptr_t" typedef
index c51c3783d45944c9823c4eae1e60a3ea92f7ed68..05fe3a80939ac1437523ca42b5c641a47dd45174 100644 (file)
@@ -300,7 +300,7 @@ PREDICATE: callable < word register? not ;
 
 GENERIC: MOV ( dst src -- )
 M: immediate MOV swap (MOV-I) ;
-M: callable MOV 0 rot (MOV-I) rc-absolute-cell rel-word ;
+M: callable MOV [ 0 ] 2dip (MOV-I) rc-absolute-cell rel-word ;
 M: operand MOV HEX: 88 2-operand ;
 
 : LEA ( dst src -- ) swap HEX: 8d 2-operand ;
index 104a1f155b58ebf37debc0b19fef37a90a5661b0..b7dffb849ea2bd48355fadaff3bdfefb2f8abf7d 100644 (file)
@@ -145,6 +145,35 @@ M: x86 %fixnum-sub ( src1 src2 -- )
 M: x86 %fixnum-sub-tail ( src1 src2 -- )
     [ SUB ] [ ADD ] "overflow_fixnum_subtract" overflow-template-tail ;
 
+M:: x86 %fixnum-mul ( src1 src2 temp1 temp2 -- )
+    "no-overflow" define-label
+    temp1 src1 MOV
+    temp1 tag-bits get SAR
+    src2 temp1 IMUL2
+    ds-reg [] temp1 MOV
+    "no-overflow" get JNO
+    src1 src2 move>args
+    param-reg-1 tag-bits get SAR
+    param-reg-2 tag-bits get SAR
+    %prepare-alien-invoke
+    "overflow_fixnum_multiply" f %alien-invoke
+    "no-overflow" resolve-label ;
+
+M:: x86 %fixnum-mul-tail ( src1 src2 temp1 temp2 -- )
+    "overflow" define-label
+    temp1 src1 MOV
+    temp1 tag-bits get SAR
+    src2 temp1 IMUL2
+    "overflow" get JO
+    ds-reg [] temp1 MOV
+    0 RET
+    "overflow" resolve-label
+    src1 src2 move>args
+    param-reg-1 tag-bits get SAR
+    param-reg-2 tag-bits get SAR
+    %prepare-alien-invoke
+    "overflow_fixnum_multiply" f %alien-invoke-tail ;
+
 : bignum@ ( reg n -- op )
     cells bignum tag-number - [+] ; inline
 
index 3ee0fe3d09a3e1c9d2c355f8316c95279c735604..b7bd8218a2e0d832e9083ec95d75a78ed4cd2e98 100644 (file)
@@ -48,7 +48,7 @@ GENERIC: more-rows? ( result-set -- ? )
 : new-result-set ( query handle class -- result-set )
     new
         swap >>handle
-        >r [ sql>> ] [ in-params>> ] [ out-params>> ] tri r>
+        [ [ sql>> ] [ in-params>> ] [ out-params>> ] tri ] dip
         swap >>out-params
         swap >>in-params
         swap >>sql ;
index 0a12f4374ab1cdc0a4b45ece00a3b51e719fe7c6..5149d14f3d8986d5a77c1b015b970cc010244e45 100644 (file)
@@ -76,7 +76,7 @@ M: postgresql-result-null summary ( obj -- str )
 : param-values ( statement -- seq seq2 )
     [ bind-params>> ] [ in-params>> ] bi
     [
-        >r value>> r> type>> {
+        [ value>> ] [ type>> ] bi* {
             { FACTOR-BLOB [
                 dup [ object>bytes malloc-byte-array/length ] [ 0 ] if
             ] }
@@ -99,7 +99,7 @@ M: postgresql-result-null summary ( obj -- str )
 
 : do-postgresql-bound-statement ( statement -- res )
     [
-        >r db get handle>> r>
+        [ db get handle>> ] dip
         {
             [ sql>> ]
             [ bind-params>> length ]
@@ -117,7 +117,7 @@ M: postgresql-result-null summary ( obj -- str )
 
 : pq-get-string ( handle row column -- obj )
     3dup PQgetvalue utf8 alien>string
-    dup empty? [ >r pq-get-is-null f r> ? ] [ 3nip ] if ;
+    dup empty? [ [ pq-get-is-null f ] dip ? ] [ 3nip ] if ;
 
 : pq-get-number ( handle row column -- obj )
     pq-get-string dup [ string>number ] when ;
index 49de6ee5fcfd15def5bd8116360312486929b489..b181aab23bc51949633854dcf3343a059f06f12d 100644 (file)
@@ -95,7 +95,7 @@ M: random-id-generator eval-generator ( singleton -- obj )
         3drop
     ] [
         pick column-name>> 0%
-        >r first2 r> interval-comparison 0%
+        [ first2 ] dip interval-comparison 0%
         bind#
     ] if ;
 
@@ -201,7 +201,7 @@ M: db <count-statement> ( query -- statement )
 
 : create-index ( index-name table-name columns -- )
     [
-        >r >r "create index " % % r> " on " % % r> "(" %
+        [ [ "create index " % % ] dip " on " % % ] dip "(" %
         "," join % ")" %
     ] "" make sql-command ;
 
index 0d2f94c13de177daa4bed07f63c20eb45945fc35..5a2f4802e9bc85f4234d9e392dcfb2cd8dc4bb7f 100644 (file)
@@ -28,21 +28,21 @@ HELP: group-words
 { $values { "group" "a group" } { "words" "an array of words" } }
 { $description "Given a protocol or tuple class, this returns the corresponding generic words that this group contains." } ;
 
-ARTICLE: { "delegate" "intro" } "Delegation"
+ARTICLE: "delegate" "Delegation"
 "The " { $vocab-link "delegate" } " vocabulary implements run-time consultation for method dispatch."
 $nl
-"Fundamental to the concept of " { $emphasis "protocols" } ", which are groups of tuple slot accessors, or groups of arbtirary generic words."
+"A " { $emphasis "protocol" } " is a collection of related generic words. An object is said to " { $emphasis "consult" } " another object if it implements a protocol by forwarding all methods onto the other object."
 $nl
-"This allows an object to implement a certain protocol by passing the method calls to another object."
+"Using this vocabulary, protocols can be defined and consulation can be set up without any repetitive boilerplate."
 $nl
 "Unlike " { $link "tuple-subclassing" } ", which expresses " { $emphasis "is-a" } " relationships by statically including the methods and slots of the superclass in all subclasses, consultation forwards generic word calls to another distinct object."
 $nl
-"Fundamentally, a protocol is a word which has a method for " { $link group-words } ". One type of protocol is a tuple, which consists of the slot accessors. To define a protocol as a set of words, use"
+"Defining new protocols:"
 { $subsection POSTPONE: PROTOCOL: }
 { $subsection define-protocol }
-"The literal syntax and defining word are:"
+"Defining consultation:"
 { $subsection POSTPONE: CONSULT: }
 { $subsection define-consult }
-"The " { $vocab-link "delegate.protocols" } " vocabulary defines formal protocols for the various informal protocols used in the Factor core, such as " { $link "sequence-protocol" } ", " { $link "assocs-protocol" } " or " { $link "stream-protocol" } ;
+"Every tuple class has an associated protocol consisting of all of its slot accessor methods. The " { $vocab-link "delegate.protocols" } " vocabulary defines formal protocols for the various informal protocols used in the Factor core, such as " { $link "sequence-protocol" } ", " { $link "assocs-protocol" } " or " { $link "stream-protocol" } ;
 
-ABOUT: { "delegate" "intro" }
+ABOUT: "delegate"
index 3a7cecb8005eb5fdb768688c0c31694260c90195..e7ea370b8dc3335ebe7b5b67a1befed3cc434ceb 100644 (file)
@@ -36,7 +36,7 @@ M: tuple-class group-words
 
 : define-consult ( group class quot -- )
     [ register-protocol ]
-    [ rot group-words -rot [ consult-method ] 2curry each ]
+    [ [ group-words ] 2dip [ consult-method ] 2curry each ]
     3bi ;
 
 : CONSULT:
index 6df3e306ddb97345a7a5962ebce82aad427fc583..084aa0ac8951050ce75f2d90d309281babd66416 100644 (file)
@@ -75,3 +75,7 @@ IN: dlists.tests
     dup clone 3 over push-back
     [ dlist>seq ] bi@
 ] unit-test
+
+[ V{ f 3 1 f } ] [ <dlist> 1 over push-front 3 over push-front f over push-front f over push-back dlist>seq ] unit-test
+
+[ V{ } ] [ <dlist> dlist>seq ] unit-test
index 549dbf947de90910d631b9447ef0bdc1a67ac468..dcff476166ac47545274c5ce907fc4850057c3fc 100644 (file)
@@ -57,11 +57,11 @@ M: dlist-node node-value obj>> ;
 : (dlist-find-node) ( dlist-node quot: ( node -- ? ) -- node/f ? )
     over [
         [ call ] 2keep rot
-        [ drop t ] [ >r next>> r> (dlist-find-node) ] if
+        [ drop t ] [ [ next>> ] dip (dlist-find-node) ] if
     ] [ 2drop f f ] if ; inline recursive
 
 : dlist-find-node ( dlist quot -- node/f ? )
-    >r front>> r> (dlist-find-node) ; inline
+    [ front>> ] dip (dlist-find-node) ; inline
 
 : dlist-each-node ( dlist quot -- )
     [ f ] compose dlist-find-node 2drop ; inline
@@ -93,11 +93,11 @@ M: dlist peek-front ( dlist -- obj )
 
 M: dlist pop-front* ( dlist -- )
     [
-        dup front>> [ empty-dlist ] unless*
-        dup next>>
-        f rot (>>next)
-        f over set-prev-when
-        swap (>>front)
+        [
+            [ empty-dlist ] unless*
+            [ f ] change-next drop
+            f over set-prev-when
+        ] change-front drop
     ] keep
     normalize-back ;
 
@@ -106,11 +106,11 @@ M: dlist peek-back ( dlist -- obj )
 
 M: dlist pop-back* ( dlist -- )
     [
-        dup back>> [ empty-dlist ] unless*
-        dup prev>>
-        f rot (>>prev)
-        f over set-next-when
-        swap (>>back)
+        [
+            [ empty-dlist ] unless*
+            [ f ] change-prev drop
+            f over set-next-when
+        ] change-back drop
     ] keep
     normalize-front ;
 
@@ -154,7 +154,7 @@ M: dlist clear-deque ( dlist -- )
     [ obj>> ] prepose dlist-each-node ; inline
 
 : dlist>seq ( dlist -- seq )
-    [ ] pusher [ dlist-each ] dip ;
+    [ ] accumulator [ dlist-each ] dip ;
 
 : 1dlist ( obj -- dlist ) <dlist> [ push-front ] keep ;
 
index 1e2bb8d85c86954d04511768624f06315e87d146..6b49c939c38ba2723479e702309382332d0afe44 100644 (file)
@@ -26,8 +26,7 @@ SYMBOL: edit-hook
     require ;
 
 : edit-location ( file line -- )
-    >r (normalize-path) r>
-    edit-hook get-global
+    [ (normalize-path) ] dip edit-hook get-global
     [ call ] [ no-edit-hook edit-location ] if* ;
 
 : edit ( defspec -- )
index 492925c7c0f86ebdce5bac74a5e251843ec30226..ca78c3efa7cd6727fb87214db13fe9e403e0f960 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: assocs combinators kernel sequences splitting system
-vocabs.loader ;
+vocabs.loader init ;
 IN: environment
 
 HOOK: os-env os ( key -- value )
@@ -25,3 +25,8 @@ HOOK: (set-os-envs) os ( seq -- )
     { [ os winnt? ] [ "environment.winnt" require ] }
     { [ os wince? ] [ ] }
 } cond
+
+[
+    "FACTOR_ROOTS" os-env os windows? ";" ":" ? split
+    [ add-vocab-root ] each
+] "environment" add-init-hook
index 77a9038cd990aec6d3ec462d8d15a0ff4c5c73ac..284d5758a334b24fbc0c2cf4014e3110840fe2ae 100644 (file)
@@ -167,7 +167,7 @@ stand-alone
     } cond ;
 
 : escape-link ( href text -- href-esc text-esc )
-    >r check-url escape-quoted-string r> escape-string ;
+    [ check-url escape-quoted-string ] dip escape-string ;
 
 : write-link ( href text -- )
     escape-link
@@ -185,7 +185,7 @@ stand-alone
     ] if ;
 
 : render-code ( string mode -- string' )
-    >r string-lines r>
+    [ string-lines ] dip
     [
         <pre>
             htmlize-lines
index cde95f28316152ad50d78898f22141570834d1c3..8b7e1ab83f1789550b0d129a4245921dfe622a59 100644 (file)
@@ -3,7 +3,7 @@
 USING: assocs kernel math.intervals math.parser namespaces
 strings random accessors quotations hashtables sequences
 continuations fry calendar combinators combinators.short-circuit
-destructors alarms io.servers.connection db db.tuples db.types
+destructors alarms io.sockets db db.tuples db.types
 http http.server http.server.dispatchers http.server.filters
 html.elements furnace.cache furnace.scopes furnace.utilities ;
 IN: furnace.sessions
index 4a1b8c7b90c3a39071b058fbce6c670a43c2ccee..0fa20b41fc43b63918a6c20cc0892625bfbb11b2 100644 (file)
@@ -11,7 +11,7 @@ TUPLE: chunking-seq { seq read-only } { n read-only } ;
 : check-groups dup 0 <= [ "Invalid group count" throw ] when ; inline
 
 : new-groups ( seq n class -- groups )
-    >r check-groups r> boa ; inline
+    [ check-groups ] dip boa ; inline
 
 GENERIC: group@ ( n groups -- from to seq )
 
index 893273e6647c843c57d64b78ee2f242025ebf917..6e8c7ee63a7e9fa6d32fa5e43542420b942b3240 100644 (file)
@@ -14,25 +14,25 @@ IN: hash2
 : <hash2> ( size -- hash2 ) f <array> ;
 
 : 2= ( a b pair -- ? )
-    first2 swapd >r >r = r> r> = and ; inline
+    first2 swapd [ = ] 2bi@ and ; inline
 
 : (assoc2) ( a b alist -- {a,b,val} )
-    [ >r 2dup r> 2= ] find >r 3drop r> ; inline
+    [ 2= ] with with find nip ; inline
 
 : assoc2 ( a b alist -- value )
     (assoc2) dup [ third ] when ; inline
 
 : set-assoc2 ( value a b alist -- alist )
-    >r rot 3array r> ?push ; inline
+    [ rot 3array ] dip ?push ; inline
 
 : hash2@ ( a b hash2 -- a b bucket hash2 )
-    >r 2dup hashcode2 r> [ length mod ] keep ; inline
+    [ 2dup hashcode2 ] dip [ length mod ] keep ; inline
 
 : hash2 ( a b hash2 -- value/f )
-    hash2@ nth [ assoc2 ] [ 2drop f ] if* ;
+    hash2@ nth dup [ assoc2 ] [ 3drop f ] if ;
 
 : set-hash2 ( a b value hash2 -- )
-    >r -rot r> hash2@ [ set-assoc2 ] change-nth ;
+    [ -rot ] dip hash2@ [ set-assoc2 ] change-nth ;
 
 : alist>hash2 ( alist size -- hash2 )
-    <hash2> [ over >r first3 r> set-hash2 ] reduce ; inline
+    <hash2> [ over [ first3 ] dip set-hash2 ] reduce ; inline
index 92146755d9db30cb2060510961b220340a825a00..ba95a9f249d201ba841cb53c7ee5029bf07f62a0 100644 (file)
@@ -18,7 +18,7 @@ GENERIC: heap-size ( heap -- n )
 TUPLE: heap data ;
 
 : <heap> ( class -- heap )
-    >r V{ } clone r> boa ; inline
+    [ V{ } clone ] dip boa ; inline
 
 TUPLE: entry value key heap index ;
 
@@ -52,16 +52,16 @@ M: heap heap-size ( heap -- n )
     data>> nth-unsafe ; inline
 
 : up-value ( n heap -- entry )
-    >r up r> data-nth ; inline
+    [ up ] dip data-nth ; inline
 
 : left-value ( n heap -- entry )
-    >r left r> data-nth ; inline
+    [ left ] dip data-nth ; inline
 
 : right-value ( n heap -- entry )
-    >r right r> data-nth ; inline
+    [ right ] dip data-nth ; inline
 
 : data-set-nth ( entry n heap -- )
-    >r [ >>index drop ] 2keep r>
+    [ [ >>index drop ] 2keep ] dip
     data>> set-nth-unsafe ; inline
 
 : data-push ( entry heap -- n )
@@ -82,8 +82,8 @@ M: heap heap-size ( heap -- n )
     data>> first ; inline
 
 : data-exchange ( m n heap -- )
-    [ tuck data-nth >r data-nth r> ] 3keep
-    tuck >r >r data-set-nth r> r> data-set-nth ; inline
+    [ tuck data-nth [ data-nth ] dip ] 3keep
+    tuck [ data-set-nth ] 2dip data-set-nth ; inline
 
 GENERIC: heap-compare ( pair1 pair2 heap -- ? )
 
@@ -97,10 +97,10 @@ M: max-heap heap-compare (heap-compare) +lt+ eq? ;
     heap-size >= ; inline
 
 : left-bounds-check? ( m heap -- ? )
-    >r left r> heap-bounds-check? ; inline
+    [ left ] dip heap-bounds-check? ; inline
 
 : right-bounds-check? ( m heap -- ? )
-    >r right r> heap-bounds-check? ; inline
+    [ right ] dip heap-bounds-check? ; inline
 
 : continue? ( m up[m] heap -- ? )
     [ data-nth swap ] keep [ data-nth ] keep
@@ -109,7 +109,7 @@ M: max-heap heap-compare (heap-compare) +lt+ eq? ;
 DEFER: up-heap
 
 : (up-heap) ( n heap -- )
-    >r dup up r>
+    [ dup up ] dip
     3dup continue? [
         [ data-exchange ] 2keep up-heap
     ] [
@@ -121,7 +121,7 @@ DEFER: up-heap
 
 : (child) ( m heap -- n )
     2dup right-value
-    >r 2dup left-value r>
+    [ 2dup left-value ] dip
     rot heap-compare
     [ right ] [ left ] if ;
 
index 711712a4bca3fcd0bf21e6499ace36b879340698..65b40543af6e0ca8e2862becc9eb240202807fe1 100644 (file)
@@ -1,6 +1,6 @@
 USING: help.markup help.syntax io kernel math namespaces parser
 prettyprint sequences vocabs.loader namespaces stack-checker
-help ;
+help command-line multiline ;
 IN: help.cookbook
 
 ARTICLE: "cookbook-syntax" "Basic syntax cookbook"
@@ -263,15 +263,65 @@ ARTICLE: "cookbook-application" "Application cookbook"
 ARTICLE: "cookbook-scripts" "Scripting cookbook"
 "Factor can be used for command-line scripting on Unix-like systems."
 $nl
-"A text file can begin with a comment like the following, and made executable:"
-{ $code "#! /usr/bin/env factor -script" }
-"Running the text file will run it through Factor, assuming the " { $snippet "factor" } " binary is in your " { $snippet "$PATH" } "."
+"To run a script, simply pass it as an argument to the Factor executable:"
+{ $code "./factor cleanup.factor" }
+"The script may access command line arguments by inspecting the value of the " { $link command-line } " variable. It can also get its own path from the " { $link script } " variable."
+{ $heading "Example: ls" }
+"Here is an example implementing a simplified version of the Unix " { $snippet "ls" } " command in Factor:"
+{ $code
+    <" USING: command-line namespaces io io.files io.files.listing
+sequences kernel ;
+
+command-line get [
+    current-directory get directory.
+] [
+    dup length 1 = [ first directory. ] [
+        [ [ nl write ":" print ] [ directory. ] bi ] each
+    ] if
+] if-empty">
+}
+"You can put it in a file named " { $snippet "ls.factor" } ", and then run it, to list the " { $snippet "/usr/bin" } " directory for example:"
+{ $code "./factor ls.factor /usr/bin" }
+{ $heading "Example: grep" }
+"The following is a more complicated example, implementing something like the Unix " { $snippet "grep" } " command:"
+{ $code <" USING: kernel fry io io.files io.encodings.ascii sequences
+regexp command-line namespaces ;
+IN: grep
+
+: grep-lines ( pattern -- )
+    '[ dup _ matches? [ print ] [ drop ] if ] each-line ;
+
+: grep-file ( pattern filename -- )
+    ascii [ grep-lines ] with-file-reader ;
+
+: grep-usage ( -- )
+    "Usage: factor grep.factor <pattern> [<file>...]" print ;
+
+command-line get [
+    grep-usage
+] [
+    unclip <regexp> swap [
+        grep-lines
+    ] [
+        [ grep-file ] with each
+    ] if-empty
+] if-empty"> }
+"You can run it like so,"
+{ $code "./factor grep.factor '.*hello.*' myfile.txt" }
+"You'll notice this script takes a while to start. This is because it is loading and compiling the " { $vocab-link "regexp" } " vocabulary every time. To speed up startup, load the vocabulary into your image, and save the image:"
+{ $code "USE: regexp" "save" }
+"Now, the " { $snippet "grep.factor" } " script will start up much faster. See " { $link "images" } " for details."
+{ $heading "Executable scripts" }
+"It is also possible to make executable scripts. A Factor file can begin with a comment like the following:"
+{ $code "#! /usr/bin/env factor" }
+"If the text file is made executable, then it can be run, assuming the " { $snippet "factor" } " binary is in your " { $snippet "$PATH" } "."
 $nl
-"The space between " { $snippet "#!" } " and " { $snippet "/usr/bin/env" } " is necessary, since " { $link POSTPONE: #! } " is a parsing word, and a syntax error would otherwise result. The " { $snippet "-script" } " switch suppresses compiler messages, and exits Factor when the script finishes."
+"The space between " { $snippet "#!" } " and " { $snippet "/usr/bin/env" } " is necessary, since " { $link POSTPONE: #! } " is a parsing word, and a syntax error would otherwise result."
 { $references
     { }
     "cli"
     "cookbook-application"
+    "images"
 } ;
 
 ARTICLE: "cookbook-philosophy" "Factor philosophy"
@@ -325,15 +375,6 @@ ARTICLE: "cookbook-pitfalls" "Pitfalls to avoid"
     { "If " { $link run-file } " throws a stack depth assertion, it means that the top-level form in the file left behind values on the stack. The stack depth is compared before and after loading a source file, since this type of situation is almost always an error. If you have a legitimate need to load a source file which returns data in some manner, define a word in the source file which produces this data on the stack and call the word after loading the file." }
 } ;
 
-ARTICLE: "cookbook-images" "Image file cookbook"
-"Factor has the ability to save the entire state of the system into an " { $emphasis "image file" } "."
-$nl
-"You can save a custom image if you find yourself loading the same libraries in every Factor session; some libraries take a little while to compile, so saving an image with those libraries loaded can save you a lot of time."
-$nl
-"For example, to save an image with the web framework loaded,"
-{ $code "USE: furnace" "save" }
-"See " { $link "images" } " for details." ;
-
 ARTICLE: "cookbook-next" "Next steps"
 "Once you have read through " { $link "first-program" } " and " { $link "cookbook" } ", the best way to keep learning Factor is to start looking at some simple example programs. Here are a few particularly nice vocabularies which should keep you busy for a little while:"
 { $list
@@ -358,7 +399,6 @@ ARTICLE: "cookbook" "Factor cookbook"
 { $subsection "cookbook-application" }
 { $subsection "cookbook-scripts" }
 { $subsection "cookbook-compiler" }
-{ $subsection "cookbook-images" }
 { $subsection "cookbook-philosophy" }
 { $subsection "cookbook-pitfalls" }
 { $subsection "cookbook-next" } ;
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..d4d7034a8fde4d63a3e33660ac64f111ae15a9d2 100644 (file)
@@ -0,0 +1 @@
+Help lint tool
index afa16bbf8a966a610950614bdc51c0d9c64aae53..9ed36ac77cbf453e53c7c9ad930b23e4ca686894 100644 (file)
@@ -13,6 +13,8 @@ $nl
 { $code "\"resource:work\" \"palindrome\" scaffold-vocab" }
 "If you look at the output, you will see that a few files were created in your ``work'' directory. The following phrase will print the full path of your work directory:"
 { $code "\"work\" resource-path ." }
+"The work directory is one of several " { $link "vocabs.roots" } " where Factor searches for vocabularies. It is possible to define new vocabulary roots; see " { $link "add-vocab-roots" } ". To keep things simple in this tutorial, we'll just use the work directory, though."
+$nl
 "Open the work directory in your file manager, and open the subdirectory named " { $snippet "palindrome" } ". Inside this subdirectory you will see a file named " { $snippet "palindrome.factor" } ". We will be editing this file."
 $nl
 "Notice that the file ends with an " { $link POSTPONE: IN: } " form telling Factor that all definitions in this source file should go into the " { $snippet "palindrome" } " vocabulary using the " { $link POSTPONE: IN: } " word:"
index 347cfd3ef43f0120e785d864d1ef8cb2ed8dcd33..b8bda22ddc5889f855bb69e4e0364dcafbfc9a35 100644 (file)
@@ -1,10 +1,10 @@
 IN: hints
-USING: help.markup help.syntax words quotations sequences ;
+USING: help.markup help.syntax words quotations sequences kernel ;
 
 ARTICLE: "hints" "Compiler specialization hints"
 "Specialization hints help the compiler generate efficient code."
 $nl
-"Specialization hints can help words which call a lot of generic words on the same object - perhaps in a loop - and in most cases, it is anticipated that this object is of a certain class. Using specialization hints, the compiler can be instructed to compile a branch at the beginning of the word; if the branch is taken, the input object has the assumed class, and inlining of generic methods can take place."
+"Specialization hints can help words which call a lot of generic words on the same object - perhaps in a loop - and in most cases, it is anticipated that this object is of a certain class, or even " { $link eq? } " to some literal. Using specialization hints, the compiler can be instructed to compile a branch at the beginning of the word; if the branch is taken, the input object has the assumed class or value, and inlining of generic methods can take place."
 $nl
 "Specialization hints are not declarations; if the inputs do not match what is specified, the word will still run, possibly slower if the compiled code cannot inline methods because of insufficient static type information."
 $nl
@@ -20,10 +20,10 @@ HELP: specialized-def
 { $description "Outputs the definition of a word after it has been split into specialized branches. This is the definition which will actually be compiled by the compiler." } ;
 
 HELP: HINTS:
-{ $values { "defspec" "a definition specifier" } { "hints..." "a list of sequences of classes" } }
+{ $values { "defspec" "a definition specifier" } { "hints..." "a list of sequences of classes or literals" } }
 { $description "Defines specialization hints for a word or a method."
 $nl
-"Each sequence of classes in the list will cause a specialized version of the word to be compiled." }
+"Each sequence in the list will cause a specialized version of the word to be compiled. Classes are tested for using their predicate, and literals are tested using " { $link eq? } "." }
 { $examples "The " { $link append } " word has a specializer for the very common case where two strings or two arrays are appended:"
 { $code "HINTS: append { string string } { array array } ;" }
 "Specializers can also be defined on methods:"
index 06ca209caee2e86cca04003c09df9bea62ad0166..240acf74b1fa073672d34158b5f30fbe3f555402 100644 (file)
@@ -3,25 +3,34 @@
 USING: parser words definitions kernel sequences assocs arrays
 kernel.private fry combinators accessors vectors strings sbufs
 byte-arrays byte-vectors io.binary io.streams.string splitting
-math generic generic.standard generic.standard.engines ;
+math generic generic.standard generic.standard.engines classes ;
 IN: hints
 
-: (make-specializer) ( class picker -- quot )
-    swap "predicate" word-prop append ;
+GENERIC: specializer-predicate ( spec -- quot )
 
-: make-specializer ( classes -- quot )
+M: class specializer-predicate "predicate" word-prop ;
+
+M: object specializer-predicate '[ _ eq? ] ;
+
+GENERIC: specializer-declaration ( spec -- class )
+
+M: class specializer-declaration ;
+
+M: object specializer-declaration class ;
+
+: make-specializer ( specs -- quot )
     dup length <reversed>
     [ (picker) 2array ] 2map
     [ drop object eq? not ] assoc-filter
     [ [ t ] ] [
-        [ (make-specializer) ] { } assoc>map
+        [ swap specializer-predicate append ] { } assoc>map
         unclip [ swap [ f ] \ if 3array append [ ] like ] reduce
     ] if-empty ;
 
 : specializer-cases ( quot word -- default alist )
     dup [ array? ] all? [ 1array ] unless [
         [ make-specializer ] keep
-        '[ _ declare ] pick append
+        [ specializer-declaration ] map '[ _ declare ] pick append
     ] { } map>assoc ;
 
 : method-declaration ( method -- quot )
index 7b451d5266e29b485ba8b5f8bc9f719e2199a045..b47426f5bbd9ce140f69239f649baece62fde7ce 100644 (file)
@@ -49,10 +49,8 @@ SYMBOL: +editable+
     ] [ keys ] if ;
 
 : describe* ( obj mirror keys -- )
-    rot summary.
-    [
-        drop
-    ] [
+    [ summary. ] 2dip
+    [ drop ] [
         dup enum? [ +sequence+ on ] when
         standard-table-style [
             swap [ -rot describe-row ] curry each-index
index bdccfc3f5713375ac66349497b3fb233a3402d56..0ed10e63c3418330775c111090bcddce7293c596 100644 (file)
@@ -183,16 +183,18 @@ M: object run-pipeline-element
 
 : <process-reader*> ( desc encoding -- stream process )
     [
-        >r (pipe) {
-            [ |dispose drop ]
-            [
-                swap >process
-                    [ swap out>> or ] change-stdout
-                run-detached
-            ]
-            [ out>> dispose ]
-            [ in>> <input-port> ]
-        } cleave r> <decoder> swap
+        [
+            (pipe) {
+                [ |dispose drop ]
+                [
+                    swap >process
+                        [ swap out>> or ] change-stdout
+                    run-detached
+                ]
+                [ out>> dispose ]
+                [ in>> <input-port> ]
+            } cleave
+        ] dip <decoder> swap
     ] with-destructors ;
 
 : <process-reader> ( desc encoding -- stream )
@@ -205,16 +207,18 @@ M: object run-pipeline-element
 
 : <process-writer*> ( desc encoding -- stream process )
     [
-        >r (pipe) {
-            [ |dispose drop ]
-            [
-                swap >process
-                    [ swap in>> or ] change-stdin
-                run-detached
-            ]
-            [ in>> dispose ]
-            [ out>> <output-port> ]
-        } cleave r> <encoder> swap
+        [
+            (pipe) {
+                [ |dispose drop ]
+                [
+                    swap >process
+                        [ swap in>> or ] change-stdin
+                    run-detached
+                ]
+                [ in>> dispose ]
+                [ out>> <output-port> ]
+            } cleave
+        ] dip <encoder> swap
     ] with-destructors ;
 
 : <process-writer> ( desc encoding -- stream )
@@ -227,17 +231,19 @@ M: object run-pipeline-element
 
 : <process-stream*> ( desc encoding -- stream process )
     [
-        >r (pipe) (pipe) {
-            [ [ |dispose drop ] bi@ ]
-            [
-                rot >process
-                    [ swap in>> or ] change-stdin
-                    [ swap out>> or ] change-stdout
-                run-detached
-            ]
-            [ [ out>> dispose ] [ in>> dispose ] bi* ]
-            [ [ in>> <input-port> ] [ out>> <output-port> ] bi* ]
-        } 2cleave r> <encoder-duplex> swap
+        [
+            (pipe) (pipe) {
+                [ [ |dispose drop ] bi@ ]
+                [
+                    rot >process
+                        [ swap in>> or ] change-stdin
+                        [ swap out>> or ] change-stdout
+                    run-detached
+                ]
+                [ [ out>> dispose ] [ in>> dispose ] bi* ]
+                [ [ in>> <input-port> ] [ out>> <output-port> ] bi* ]
+            } 2cleave
+        ] dip <encoder-duplex> swap
     ] with-destructors ;
 
 : <process-stream> ( desc encoding -- stream )
@@ -254,23 +260,6 @@ M: object run-pipeline-element
     f >>handle
     drop ;
 
-GENERIC: underlying-handle ( stream -- handle )
-
-M: port underlying-handle handle>> ;
-
-ERROR: invalid-duplex-stream ;
-
-M: duplex-stream underlying-handle
-    [ in>> underlying-handle ]
-    [ out>> underlying-handle ] bi
-    [ = [ invalid-duplex-stream ] when ] keep ;
-
-M: encoder underlying-handle
-    stream>> underlying-handle ;
-
-M: decoder underlying-handle
-    stream>> underlying-handle ;
-
 {
     { [ os unix? ] [ "io.unix.launcher" require ] }
     { [ os winnt? ] [ "io.windows.nt.launcher" require ] }
index ca4046fe0783abbb62cb86ddac4e44a82d14b604..3a7fa5a2e09366cf8163919729ae4c4578a7c639 100644 (file)
@@ -15,9 +15,10 @@ HOOK: (pipe) io-backend ( -- pipe )
 
 : <pipe> ( encoding -- stream )
     [
-        >r (pipe) |dispose
-        [ in>> <input-port> ] [ out>> <output-port> ] bi
-        r> <encoder-duplex>
+        [
+            (pipe) |dispose
+            [ in>> <input-port> ] [ out>> <output-port> ] bi
+        ] dip <encoder-duplex>
     ] with-destructors ;
 
 <PRIVATE
@@ -32,8 +33,7 @@ GENERIC: run-pipeline-element ( input-fd output-fd obj -- quot )
 
 M: callable run-pipeline-element
     [
-        >r [ ?reader ] [ ?writer ] bi*
-        r> with-streams*
+        [ [ ?reader ] [ ?writer ] bi* ] dip with-streams*
     ] with-destructors ;
 
 : <pipes> ( n -- pipes )
@@ -48,8 +48,8 @@ PRIVATE>
 : run-pipeline ( seq -- results )
     [ length dup zero? [ drop { } ] [ 1- <pipes> ] if ] keep
     [
-        >r [ first in>> ] [ second out>> ] bi
-        r> run-pipeline-element
+        [ [ first in>> ] [ second out>> ] bi ] dip
+        run-pipeline-element
     ] 2parallel-map ;
 
 {
index 9fb9755d4b16ee0d7f58c63e0a3d8d86b99ee2b4..0432fe4a396c6090b25c4584a698c957d789624b 100644 (file)
@@ -46,7 +46,7 @@ M: input-port stream-read1
 
 M: input-port stream-read-partial ( max stream -- byte-array/f )
     dup check-disposed
-    >r 0 max >integer r> read-step ;
+    [ 0 max >integer ] dip read-step ;
 
 : read-loop ( count port accum -- )
     pick over length - dup 0 > [
@@ -61,7 +61,7 @@ M: input-port stream-read-partial ( max stream -- byte-array/f )
 
 M: input-port stream-read
     dup check-disposed
-    >r 0 max >fixnum r>
+    [ 0 max >fixnum ] dip
     2dup read-step dup [
         pick over length > [
             pick <byte-vector>
@@ -76,21 +76,21 @@ M: input-port stream-read
 
 : read-until-loop ( seps port buf -- separator/f )
     2over read-until-step over [
-        >r over push-all r> dup [
-            >r 3drop r>
+        [ over push-all ] dip dup [
+            [ 3drop ] dip
         ] [
             drop read-until-loop
         ] if
     ] [
-        >r 2drop 2drop r>
+        [ 2drop 2drop ] dip
     ] if ;
 
 M: input-port stream-read-until ( seps port -- str/f sep/f )
-    2dup read-until-step dup [ >r 2nip r> ] [
+    2dup read-until-step dup [ [ 2drop ] 2dip ] [
         over [
             drop
             BV{ } like [ read-until-loop ] keep B{ } like swap
-        ] [ >r 2nip r> ] if
+        ] [ [ 2drop ] 2dip ] if
     ] if ;
 
 TUPLE: output-port < buffered-port ;
@@ -114,7 +114,7 @@ M: output-port stream-write
         [ [ stream-write ] curry ] bi
         each
     ] [
-        [ >r length r> wait-to-write ]
+        [ [ length ] dip wait-to-write ]
         [ buffer>> >buffer ] 2bi
     ] if ;
 
@@ -153,6 +153,18 @@ M: port dispose*
         bi
     ] with-destructors ;
 
+GENERIC: underlying-port ( stream -- port )
+
+M: port underlying-port ;
+
+M: encoder underlying-port stream>> underlying-port ;
+
+M: decoder underlying-port stream>> underlying-port ;
+
+GENERIC: underlying-handle ( stream -- handle )
+
+M: object underlying-handle underlying-port handle>> ;
+
 ! Fast-path optimization
 USING: hints strings io.encodings.utf8 io.encodings.ascii
 io.encodings.private ;
index b093840987d7545f5aea06c23c5cf4815faa1dc0..67c7cb13dda8a8d2075038828af63ff6ee46dbc3 100644 (file)
@@ -66,11 +66,11 @@ ARTICLE: "io.servers.connection" "Threaded servers"
 "Stopping the server:"
 { $subsection stop-server }
 "From within the dynamic scope of a client handler, several words can be used to interact with the threaded server:"
-{ $subsection remote-address }
 { $subsection stop-this-server }
 { $subsection secure-port }
 { $subsection insecure-port }
-"Additionally, the " { $link local-address } " variable is set, as in " { $link with-client } "." ;
+"Additionally, the " { $link local-address } " and "
+{ $subsection remote-address } " variables are set, as in " { $link with-client } "." ;
 
 ABOUT: "io.servers.connection"
 
index 942bdb041d6bd593089df516581132cabad1abe0..6c7ff7e0f1826e480be396f4c8ef3593edd3488e 100644 (file)
@@ -39,8 +39,6 @@ ready ;
 : <threaded-server> ( -- threaded-server )
     threaded-server new-threaded-server ;
 
-SYMBOL: remote-address
-
 GENERIC: handle-client* ( threaded-server -- )
 
 <PRIVATE
index 632af969ca266b39af4f55e8503940b27b0eb1c3..01f64dfccfd061175de6b07a578ad377e0996e4e 100644 (file)
@@ -1,5 +1,5 @@
+USING: io help.markup help.syntax calendar quotations io.sockets ;
 IN: io.sockets.secure
-USING: help.markup help.syntax calendar quotations io.sockets ;
 
 HELP: secure-socket-timeout
 { $var-description "Timeout for operations not associated with a constructed port instance, such as SSL handshake and shutdown. Represented as a " { $link duration } "." } ;
@@ -99,6 +99,23 @@ $nl
 { $subsection <secure> }
 "Instances of this class can wrap an " { $link inet } ", " { $link inet4 } " or an " { $link inet6 } ", although note that certificate validation is only performed for instances of " { $link inet } " since otherwise the host name is not available." ;
 
+HELP: send-secure-handshake
+{ $contract "Upgrades the socket connection of the current " { $link with-client } " scope to a secure connection and initiates a SSL/TLS handshake." }
+{ $errors "Throws " { $link upgrade-on-non-socket } " or " { $link upgrade-buffers-full } " if used improperly." }
+{ $examples "This word is used by the " { $vocab-link "smtp" } " library to implement SMTP-TLS." } ;
+
+HELP: accept-secure-handshake
+{ $contract "Upgrades the socket connection stored in the " { $link input-stream } " and " { $link output-stream } " variables to a secure connection and waits for an SSL/TLS handshake." }
+{ $errors "Throws " { $link upgrade-on-non-socket } " or " { $link upgrade-buffers-full } " if used improperly." } ;
+
+ARTICLE: "ssl-upgrade" "Upgrading existing connections"
+"Some protocols, such as HTTPS, require that the connection be established as an SSL/TLS connection. Others, such as secure SMTP and POP3 require that the client and server initiate an SSL/TLS handshake upon the client sending a plain-text request. The latter use-case is accomodated by a pair of words."
+$nl
+"Upgrading a connection to a secure socket by initiating an SSL/TLS handshake with the server:"
+{ $subsection send-secure-handshake }
+"Upgrading a connection to a secure socket by waiting for an SSL/TLS handshake from the client:"
+{ $subsection accept-secure-handshake } ;
+
 HELP: premature-close
 { $error-description "Thrown if an SSL connection is closed without the proper " { $snippet "close_notify" } " sequence. This error is never reported for " { $link SSLv2 } " connections because there is no distinction between expected and unexpected connection closure in that case." } ;
 
@@ -106,20 +123,34 @@ HELP: certificate-verify-error
 { $error-description "Thrown if certificate verification failed. The " { $snippet "result" } " slot contains an object identifying the low-level error that occurred." } ;
 
 HELP: common-name-verify-error
-{ $error-description "Thrown during certificate verification if the host name on the certificate does not match the host name the socket was connected to. This indicates a potential man-in-the-middle attack. The " { $snippet "expected" } " and " { $snippet "got" } " slots contain the mismatched host names." } ;
+{ $error-description "Thrown during certificate verification if the host name on the certificate does not match the host name the socket was connected to. This indicates a potential man-in-the-middle attack. The " { $slot "expected" } " and " { $slot "got" } " slots contain the mismatched host names." } ;
+
+HELP: upgrade-on-non-socket
+{ $error-description "Thrown if " { $link send-secure-handshake } " or " { $link accept-secure-handshake } " is called with the " { $link input-stream } " and " { $link output-stream } " variables not set to a socket. This error can also indicate that the connection has already been upgraded to a secure connection." } ;
+
+HELP: upgrade-buffers-full
+{ $error-description "Thrown if " { $link send-secure-handshake } " or " { $link accept-secure-handshake } " is called when there is still data which hasn't been read or written." }
+{ $notes "Clients should ensure to " { $link flush } " their last command to the server before calling " { $link send-secure-handshake } "." } ;
 
 ARTICLE: "ssl-errors" "Secure socket errors"
 "Secure sockets can throw one of several errors in addition to the usual I/O errors:"
 { $subsection premature-close }
 { $subsection certificate-verify-error }
-{ $subsection common-name-verify-error } ;
+{ $subsection common-name-verify-error }
+"The " { $link send-secure-handshake } " word can throw one of two errors:"
+{ $subsection upgrade-on-non-socket }
+{ $subsection upgrade-buffers-full } ;
 
 ARTICLE: "io.sockets.secure" "Secure sockets (SSL, TLS)"
 "The " { $vocab-link "io.sockets.secure" } " vocabulary implements secure, encrypted sockets using the OpenSSL library."
+$nl
+"At present, this vocabulary only works on Unix, and not on Windows."
+$nl
+"This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (" { $url "http://www.openssl.org/" } "), cryptographic software written by Eric Young (eay@cryptsoft.com) and software written by Tim Hudson (tjh@cryptsoft.com)."
 { $subsection "ssl-config" }
 { $subsection "ssl-contexts" }
 { $subsection "ssl-addresses" }
-{ $subsection "ssl-errors" }
-"This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (" { $url "http://www.openssl.org/" } "), cryptographic software written by Eric Young (eay@cryptsoft.com) and software written by Tim Hudson (tjh@cryptsoft.com)." ;
+{ $subsection "ssl-upgrade" }
+{ $subsection "ssl-errors" } ;
 
 ABOUT: "io.sockets.secure"
index 42ca7276530e9f58f3160cdcf1c7fb7f2b2f4c62..e752e7c328d02d86425a7bfdc0ae3275afc3319a 100644 (file)
@@ -1,8 +1,8 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors kernel symbols namespaces continuations
-destructors io.sockets sequences summary calendar delegate
-system vocabs.loader combinators present ;
+destructors io debugger io.sockets sequences summary calendar
+delegate system vocabs.loader combinators present ;
 IN: io.sockets.secure
 
 SYMBOL: secure-socket-timeout
@@ -52,10 +52,10 @@ M: secure resolve-host ( secure -- seq )
 
 HOOK: check-certificate secure-socket-backend ( host handle -- )
 
-<PRIVATE
-
 PREDICATE: secure-inet < secure addrspec>> inet? ;
 
+<PRIVATE
+
 M: secure-inet (client)
     [
         [ resolve-host (client) [ |dispose ] dip ] keep
@@ -79,6 +79,23 @@ ERROR: common-name-verify-error expected got ;
 M: common-name-verify-error summary
     drop "Common name verification failed" ;
 
+ERROR: upgrade-on-non-socket ;
+
+M: upgrade-on-non-socket summary
+    drop
+    "send-secure-handshake can only be used if input-stream and" print
+    "output-stream are a socket" ;
+
+ERROR: upgrade-buffers-full ;
+
+M: upgrade-buffers-full summary
+    drop
+    "send-secure-handshake can only be used if buffers are empty" ;
+
+HOOK: send-secure-handshake secure-socket-backend ( -- )
+
+HOOK: accept-secure-handshake secure-socket-backend ( -- )
+
 {
     { [ os unix? ] [ "io.unix.sockets.secure" require ] }
     { [ os windows? ] [ "openssl" require ] }
index 25401293f5c3130af4f333f308adf44962736d01..cfc33a02f6a29b0658cf276679cf14e44a2cea08 100644 (file)
@@ -105,7 +105,7 @@ HELP: <client>
 
 HELP: with-client
 { $values { "remote" "an address specifier" } { "encoding" "an encoding descriptor" } { "quot" quotation } }
-{ $description "Opens a network connection and calls the quotation in a new dynamic scope with " { $link input-stream } " and " { $link output-stream } " rebound to the network streams. The local address the socket is bound to is stored in the " { $link local-address } " variable." }
+{ $description "Opens a network connection and calls the quotation in a new dynamic scope with " { $link input-stream } " and " { $link output-stream } " rebound to the network streams. The local address the socket is connected to is stored in the " { $link local-address } " variable, and the remote address is stored in the " { $link remote-address } " variable." }
 { $errors "Throws an error if the connection cannot be established." } ;
 
 HELP: <server>
index c704382dd447ecc9eb8863c57a26f0ffe7bb1821..ce7c4f6dddee2900a3fbfd75fc325d52781152af 100644 (file)
@@ -6,7 +6,7 @@ sequences arrays io.encodings io.ports io.streams.duplex
 io.encodings.ascii alien.strings io.binary accessors destructors
 classes debugger byte-arrays system combinators parser
 alien.c-types math.parser splitting grouping math assocs summary
-system vocabs.loader combinators present ;
+system vocabs.loader combinators present fry ;
 IN: io.sockets
 
 << {
@@ -89,7 +89,7 @@ M: inet4 make-sockaddr ( inet -- sockaddr )
     rot inet-pton *uint over set-sockaddr-in-addr ;
 
 M: inet4 parse-sockaddr
-    >r dup sockaddr-in-addr <uint> r> inet-ntop
+    [ dup sockaddr-in-addr <uint> ] dip inet-ntop
     swap sockaddr-in-port ntohs <inet4> ;
 
 TUPLE: inet6 < abstract-inet ;
@@ -144,7 +144,7 @@ M: inet6 make-sockaddr ( inet -- sockaddr )
     rot inet-pton over set-sockaddr-in6-addr ;
 
 M: inet6 parse-sockaddr
-    >r dup sockaddr-in6-addr r> inet-ntop
+    [ dup sockaddr-in6-addr ] dip inet-ntop
     swap sockaddr-in6-port ntohs <inet6> ;
 
 : addrspec-of-family ( af -- addrspec )
@@ -184,7 +184,7 @@ M: object (client) ( remote -- client-in client-out local )
     [
         [ ((client)) ] keep
         [
-            >r <ports> [ |dispose ] bi@ dup r>
+            [ <ports> [ |dispose ] bi@ dup ] dip
             establish-connection
         ]
         [ get-local-address ]
@@ -192,13 +192,19 @@ M: object (client) ( remote -- client-in client-out local )
     ] with-destructors ;
 
 : <client> ( remote encoding -- stream local )
-    >r (client) -rot r> <encoder-duplex> swap ;
+    [ (client) -rot ] dip <encoder-duplex> swap ;
 
 SYMBOL: local-address
 
+SYMBOL: remote-address
+
 : with-client ( remote encoding quot -- )
-    >r <client> [ local-address set ] curry
-    r> compose with-stream ; inline
+    [
+        [
+            over remote-address set
+            <client> local-address set
+        ] dip with-stream
+    ] with-scope ; inline
 
 TUPLE: server-port < port addr encoding ;
 
@@ -209,10 +215,11 @@ TUPLE: server-port < port addr encoding ;
 GENERIC: (server) ( addrspec -- handle )
 
 : <server> ( addrspec encoding -- server )
-    >r
-    [ (server) ] keep
-    [ drop server-port <port> ] [ get-local-address ] 2bi
-    >>addr r> >>encoding ;
+    [
+        [ (server) ] keep
+        [ drop server-port <port> ] [ get-local-address ] 2bi
+        >>addr
+    ] dip >>encoding ;
 
 GENERIC: (accept) ( server addrspec -- handle sockaddr )
 
@@ -281,7 +288,7 @@ C: <inet> inet
     IPPROTO_TCP over set-addrinfo-protocol ;
 
 : fill-in-ports ( addrspecs port -- addrspecs )
-    [ >>port ] curry map ;
+    '[ _ >>port ] map ;
 
 M: inet resolve-host
     [ port>> ] [ host>> ] bi [
index 6f3be15016b5d0b6e0bb791f4433ba91ebe5a60a..2ba504c6536c211d216b2a55ebd8f03193e6bc1a 100644 (file)
@@ -1,8 +1,8 @@
 ! Copyright (C) 2005, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel continuations destructors io io.encodings
-io.encodings.private io.timeouts debugger summary listener
-accessors delegate delegate.protocols ;
+io.encodings.private io.timeouts io.ports debugger summary
+listener accessors delegate delegate.protocols ;
 IN: io.streams.duplex
 
 TUPLE: duplex-stream in out ;
@@ -30,7 +30,15 @@ M: duplex-stream dispose
     tuck re-encode >r re-decode r> <duplex-stream> ;
 
 : with-stream* ( stream quot -- )
-    >r [ in>> ] [ out>> ] bi r> with-streams* ; inline
+    [ [ in>> ] [ out>> ] bi ] dip with-streams* ; inline
 
 : with-stream ( stream quot -- )
-    >r [ in>> ] [ out>> ] bi r> with-streams ; inline
+    [ [ in>> ] [ out>> ] bi ] dip with-streams ; inline
+
+ERROR: invalid-duplex-stream ;
+
+M: duplex-stream underlying-handle
+    [ in>> underlying-handle ]
+    [ out>> underlying-handle ] bi
+    [ = [ invalid-duplex-stream ] when ] keep ;
+
index 9fa1727e16c241dadd46f9b40e2e46a381dfdea5..07ef0e2574ee8270cbf584d43312aa723f746727 100644 (file)
@@ -167,19 +167,23 @@ M: unix (directory-entries) ( path -- seq )
 
 : stat-mode ( path -- mode )
     normalize-path file-status stat-st_mode ;
-    
-: chmod-set-bit ( path mask ? -- ) 
-    [ dup stat-mode ] 2dip 
+
+: chmod-set-bit ( path mask ? -- )
+    [ dup stat-mode ] 2dip
     [ bitor ] [ unmask ] if chmod io-error ;
 
-: file-mode? ( path mask -- ? ) [ stat-mode ] dip mask? ;
+GENERIC# file-mode? 1 ( obj mask -- ? )
+
+M: integer file-mode? mask? ;
+M: string file-mode? [ stat-mode ] dip mask? ;
+M: file-info file-mode? [ permissions>> ] dip mask? ;
 
 PRIVATE>
 
 : ch>file-type ( ch -- type )
     {
         { CHAR: b [ +block-device+ ] }
-        { CHAR: c [ +character-device+ ] }   
+        { CHAR: c [ +character-device+ ] }
         { CHAR: d [ +directory+ ] }
         { CHAR: l [ +symbolic-link+ ] }
         { CHAR: s [ +socket+ ] }
@@ -205,29 +209,29 @@ PRIVATE>
 : STICKY        OCT: 0001000 ; inline
 : USER-ALL      OCT: 0000700 ; inline
 : USER-READ     OCT: 0000400 ; inline
-: USER-WRITE    OCT: 0000200 ; inline 
-: USER-EXECUTE  OCT: 0000100 ; inline   
+: USER-WRITE    OCT: 0000200 ; inline
+: USER-EXECUTE  OCT: 0000100 ; inline
 : GROUP-ALL     OCT: 0000070 ; inline
-: GROUP-READ    OCT: 0000040 ; inline 
-: GROUP-WRITE   OCT: 0000020 ; inline  
-: GROUP-EXECUTE OCT: 0000010 ; inline    
+: GROUP-READ    OCT: 0000040 ; inline
+: GROUP-WRITE   OCT: 0000020 ; inline
+: GROUP-EXECUTE OCT: 0000010 ; inline
 : OTHER-ALL     OCT: 0000007 ; inline
 : OTHER-READ    OCT: 0000004 ; inline
-: OTHER-WRITE   OCT: 0000002 ; inline  
-: OTHER-EXECUTE OCT: 0000001 ; inline    
-
-GENERIC: uid? ( obj -- ? )
-GENERIC: gid? ( obj -- ? )
-GENERIC: sticky? ( obj -- ? )
-GENERIC: user-read? ( obj -- ? )
-GENERIC: user-write? ( obj -- ? )
-GENERIC: user-execute? ( obj -- ? )
-GENERIC: group-read? ( obj -- ? )
-GENERIC: group-write? ( obj -- ? )
-GENERIC: group-execute? ( obj -- ? )
-GENERIC: other-read? ( obj -- ? )
-GENERIC: other-write? ( obj -- ? )
-GENERIC: other-execute? ( obj -- ? )
+: OTHER-WRITE   OCT: 0000002 ; inline
+: OTHER-EXECUTE OCT: 0000001 ; inline
+
+: uid? ( obj -- ? ) UID file-mode? ;
+: gid? ( obj -- ? ) GID file-mode? ;
+: sticky? ( obj -- ? ) STICKY file-mode? ;
+: user-read? ( obj -- ? ) USER-READ file-mode? ;
+: user-write? ( obj -- ? ) USER-WRITE file-mode? ;
+: user-execute? ( obj -- ? ) USER-EXECUTE file-mode? ;
+: group-read? ( obj -- ? ) GROUP-READ file-mode? ;
+: group-write? ( obj -- ? ) GROUP-WRITE file-mode? ;
+: group-execute? ( obj -- ? ) GROUP-EXECUTE file-mode? ;
+: other-read? ( obj -- ? ) OTHER-READ file-mode? ;
+: other-write? ( obj -- ? ) OTHER-WRITE file-mode? ;
+: other-execute? ( obj -- ? ) OTHER-EXECUTE file-mode? ;
 
 : any-read? ( obj -- ? )
     { [ user-read? ] [ group-read? ] [ other-read? ] } 1|| ;
@@ -238,56 +242,17 @@ GENERIC: other-execute? ( obj -- ? )
 : any-execute? ( obj -- ? )
     { [ user-execute? ] [ group-execute? ] [ other-execute? ] } 1|| ;
 
-M: integer uid? ( integer -- ? ) UID mask? ;
-M: integer gid? ( integer -- ? ) GID mask? ;
-M: integer sticky? ( integer -- ? ) STICKY mask? ;
-M: integer user-read? ( integer -- ? ) USER-READ mask? ;
-M: integer user-write? ( integer -- ? ) USER-WRITE mask? ;
-M: integer user-execute? ( integer -- ? ) USER-EXECUTE mask? ;
-M: integer group-read? ( integer -- ? ) GROUP-READ mask? ;
-M: integer group-write? ( integer -- ? ) GROUP-WRITE mask? ;
-M: integer group-execute? ( integer -- ? ) GROUP-EXECUTE mask? ;
-M: integer other-read? ( integer -- ? ) OTHER-READ mask? ;
-M: integer other-write? ( integer -- ? ) OTHER-WRITE mask? ; 
-M: integer other-execute? ( integer -- ? ) OTHER-EXECUTE mask? ;
-
-M: file-info uid? ( file-info -- ? ) permissions>> uid? ;
-M: file-info gid? ( file-info -- ? ) permissions>> gid? ;
-M: file-info sticky? ( file-info -- ? ) permissions>> sticky? ;
-M: file-info user-read? ( file-info -- ? ) permissions>> user-read? ;
-M: file-info user-write? ( file-info -- ? ) permissions>> user-write? ;
-M: file-info user-execute? ( file-info -- ? ) permissions>> user-execute? ;
-M: file-info group-read? ( file-info -- ? ) permissions>> group-read? ;
-M: file-info group-write? ( file-info -- ? ) permissions>> group-write? ;
-M: file-info group-execute? ( file-info -- ? ) permissions>> group-execute? ;
-M: file-info other-read? ( file-info -- ? ) permissions>> other-read? ;
-M: file-info other-write? ( file-info -- ? ) permissions>> other-write? ;
-M: file-info other-execute? ( file-info -- ? ) permissions>> other-execute? ;
-
-M: string uid? ( path -- ? ) UID file-mode? ;
-M: string gid? ( path -- ? ) GID file-mode? ;
-M: string sticky? ( path -- ? ) STICKY file-mode? ;
-M: string user-read? ( path -- ? ) USER-READ file-mode? ;
-M: string user-write? ( path -- ? ) USER-WRITE file-mode? ;
-M: string user-execute? ( path -- ? ) USER-EXECUTE file-mode? ;
-M: string group-read? ( path -- ? ) GROUP-READ file-mode? ;
-M: string group-write? ( path -- ? ) GROUP-WRITE file-mode? ;
-M: string group-execute? ( path -- ? ) GROUP-EXECUTE file-mode? ;
-M: string other-read? ( path -- ? ) OTHER-READ file-mode? ;
-M: string other-write? ( path -- ? ) OTHER-WRITE file-mode? ; 
-M: string other-execute? ( path -- ? ) OTHER-EXECUTE file-mode? ;
-
 : set-uid ( path ? -- ) UID swap chmod-set-bit ;
 : set-gid ( path ? -- ) GID swap chmod-set-bit ;
 : set-sticky ( path ? -- ) STICKY swap chmod-set-bit ;
 : set-user-read ( path ? -- ) USER-READ swap chmod-set-bit ;
-: set-user-write ( path ? -- ) USER-WRITE swap chmod-set-bit ; 
+: set-user-write ( path ? -- ) USER-WRITE swap chmod-set-bit ;
 : set-user-execute ( path ? -- ) USER-EXECUTE swap chmod-set-bit ;
 : set-group-read ( path ? -- ) GROUP-READ swap chmod-set-bit ;
-: set-group-write ( path ? -- ) GROUP-WRITE swap chmod-set-bit ; 
+: set-group-write ( path ? -- ) GROUP-WRITE swap chmod-set-bit ;
 : set-group-execute ( path ? -- ) GROUP-EXECUTE swap chmod-set-bit ;
 : set-other-read ( path ? -- ) OTHER-READ swap chmod-set-bit ;
-: set-other-write ( path ? -- ) OTHER-WRITE swap chmod-set-bit ; 
+: set-other-write ( path ? -- ) OTHER-WRITE swap chmod-set-bit ;
 : set-other-execute ( path ? -- ) OTHER-EXECUTE swap chmod-set-bit ;
 
 : set-file-permissions ( path n -- )
@@ -334,10 +299,10 @@ M: integer set-file-user ( path uid -- )
 
 M: string set-file-user ( path string -- )
     user-id f set-file-ids ;
-    
+
 M: integer set-file-group ( path gid -- )
     f swap set-file-ids ;
-    
+
 M: string set-file-group ( path string -- )
     group-id
     f swap set-file-ids ;
index 421e12a92fbe994008212321a91d9a755e224eb8..7a1cac3ff19dc01b20a3c57312390482a5bbc577 100644 (file)
@@ -40,14 +40,13 @@ USE: unix
     3drop ;
 
 : redirect-file ( obj mode fd -- )
-    >r >r normalize-path r> file-mode
-    open-file r> redirect-fd ;
+    [ [ normalize-path ] dip file-mode open-file ] dip redirect-fd ;
 
 : redirect-file-append ( obj mode fd -- )
-    >r drop path>> normalize-path open-append r> redirect-fd ;
+    [ drop path>> normalize-path open-append ] dip redirect-fd ;
 
 : redirect-closed ( obj mode fd -- )
-    >r >r drop "/dev/null" r> r> redirect-file ;
+    [ drop "/dev/null" ] 2dip redirect-file ;
 
 : redirect ( obj mode fd -- )
     {
@@ -55,8 +54,8 @@ USE: unix
         { [ pick string? ] [ redirect-file ] }
         { [ pick appender? ] [ redirect-file-append ] }
         { [ pick +closed+ eq? ] [ redirect-closed ] }
-        { [ pick fd? ] [ >r drop fd>> dup reset-fd r> redirect-fd ] }
-        [ >r >r underlying-handle r> r> redirect ]
+        { [ pick fd? ] [ [ drop fd>> dup reset-fd ] dip redirect-fd ] }
+        [ [ underlying-handle ] 2dip redirect ]
     } cond ;
 
 : ?closed ( obj -- obj' )
index 530dfe7ab3467b99ac644c81a957d9bec6275b83..1dd1d51e87065aeb50f8f136d9f6193b22897692 100644 (file)
@@ -19,7 +19,7 @@ TUPLE: select-mx < mx read-fdset write-fdset ;
         FD_SETSIZE 8 * <bit-array> >>write-fdset ;
 
 : clear-nth ( n seq -- ? )
-    [ nth ] [ f -rot set-nth ] 2bi ;
+    [ nth ] [ [ f ] 2dip set-nth ] 2bi ;
 
 :: check-fd ( fd fdset mx quot -- )
     fd munge fdset clear-nth [ fd mx quot call ] when ; inline
diff --git a/basis/io/unix/sockets/secure/debug/debug.factor b/basis/io/unix/sockets/secure/debug/debug.factor
new file mode 100644 (file)
index 0000000..cd5353e
--- /dev/null
@@ -0,0 +1,11 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors io.sockets.secure kernel ;
+IN: io.unix.sockets.secure.debug
+
+: with-test-context ( quot -- )
+    <secure-config>
+        "resource:basis/openssl/test/server.pem" >>key-file
+        "resource:basis/openssl/test/dh1024.pem" >>dh-file
+        "password" >>password
+    swap with-secure-context ; inline
index d2a1649686796dfb89d4914d48643459d689ac83..0816dd270b6f0395cc3475ab0608d33fd0e788a3 100644 (file)
@@ -2,20 +2,14 @@ IN: io.sockets.secure.tests
 USING: accessors kernel namespaces io io.sockets
 io.sockets.secure io.encodings.ascii io.streams.duplex
 io.unix.backend classes words destructors threads tools.test
-concurrency.promises byte-arrays locals calendar io.timeouts ;
+concurrency.promises byte-arrays locals calendar io.timeouts
+io.unix.sockets.secure.debug ;
 
 \ <secure-config> must-infer
 { 1 0 } [ [ ] with-secure-context ] must-infer-as
 
 [ ] [ <promise> "port" set ] unit-test
 
-: with-test-context ( quot -- )
-    <secure-config>
-        "resource:basis/openssl/test/server.pem" >>key-file
-        "resource:basis/openssl/test/dh1024.pem" >>dh-file
-        "password" >>password
-    swap with-secure-context ; inline
-
 :: server-test ( quot -- )
     [
         [
index fb5ed939781a3b7868a98ccfa7ad6557dfbefb36..a096380b74b8ca9adc6008e60f44481223697c19 100644 (file)
@@ -3,10 +3,10 @@
 USING: accessors unix byte-arrays kernel debugger sequences
 namespaces math math.order combinators init alien alien.c-types
 alien.strings libc continuations destructors openssl
-openssl.libcrypto openssl.libssl io.files io.ports
+openssl.libcrypto openssl.libssl io io.files io.ports
 io.unix.backend io.unix.sockets io.encodings.ascii io.buffers
 io.sockets io.sockets.secure io.sockets.secure.openssl
-io.timeouts system summary ;
+io.timeouts system summary fry ;
 IN: io.unix.sockets.secure
 
 M: ssl-handle handle-fd file>> handle-fd ;
@@ -18,9 +18,7 @@ M: ssl-handle handle-fd file>> handle-fd ;
             { -1 [ err_no ECONNRESET = [ premature-close ] [ (io-error) ] if ] }
             { 0 [ premature-close ] }
         } case
-    ] [
-        nip (ssl-error)
-    ] if ;
+    ] [ nip (ssl-error) ] if ;
 
 : check-accept-response ( handle r -- event )
     over handle>> over SSL_get_error
@@ -36,7 +34,7 @@ M: ssl-handle handle-fd file>> handle-fd ;
 
 : do-ssl-accept ( ssl-handle -- )
     dup dup handle>> SSL_accept check-accept-response dup
-    [ >r dup file>> r> wait-for-fd do-ssl-accept ] [ 2drop ] if ;
+    [ [ dup file>> ] dip wait-for-fd do-ssl-accept ] [ 2drop ] if ;
 
 : maybe-handshake ( ssl-handle -- )
     dup connected>> [ drop ] [
@@ -130,24 +128,23 @@ M: secure (get-local-address) addrspec>> (get-local-address) ;
     [ [ handle>> SSL_get1_session ] dip save-session ]
     2bi ;
 
-: secure-connection ( ssl-handle addrspec -- )
-    dup get-session [ resume-session ] [ begin-session ] ?if ;
+: secure-connection ( client-out addrspec -- )
+    [ handle>> ] dip
+    [
+        '[
+            _ dup get-session
+            [ resume-session ] [ begin-session ] ?if
+        ] with-timeout
+    ] [ drop t >>connected drop ] 2bi ;
 
 M: secure establish-connection ( client-out remote -- )
-    addrspec>>
-    [ establish-connection ]
-    [
-        [ handle>> ] dip
-        [ [ secure-connection ] curry with-timeout ]
-        [ drop t >>connected drop ]
-        2bi
-    ] 2bi ;
+    addrspec>> [ establish-connection ] [ secure-connection ] 2bi ;
 
 M: secure (server) addrspec>> (server) ;
 
 M: secure (accept)
     [
-        addrspec>> (accept) >r |dispose <ssl-socket> r>
+        addrspec>> (accept) [ |dispose <ssl-socket> ] dip
     ] with-destructors ;
 
 : check-shutdown-response ( handle r -- event )
@@ -172,3 +169,32 @@ M: ssl-handle shutdown
     dup connected>> [
         f >>connected [ (shutdown) ] with-timeout
     ] [ drop ] if ;
+
+: check-buffer ( port -- port )
+    dup buffer>> buffer-empty? [ upgrade-buffers-full ] unless ;
+
+: input/output-ports ( -- input output )
+    input-stream output-stream
+    [ get underlying-port check-buffer ] bi@
+    2dup [ handle>> ] bi@ eq? [ upgrade-on-non-socket ] unless ;
+
+: make-input/output-secure ( input output -- )
+    dup handle>> fd? [ upgrade-on-non-socket ] unless
+    [ <ssl-socket> ] change-handle
+    handle>> >>handle drop ;
+
+: (send-secure-handshake) ( output -- )
+    remote-address get [ upgrade-on-non-socket ] unless*
+    secure-connection ;
+
+M: openssl send-secure-handshake
+    input/output-ports
+    [ make-input/output-secure ] keep
+    [ (send-secure-handshake) ] keep
+    remote-address get dup inet? [
+        host>> swap handle>> check-certificate
+    ] [ 2drop ] if ;
+
+M: openssl accept-secure-handshake
+    input/output-ports
+    make-input/output-secure ;
index 8f9ff4f06673fed038317307ef7c3931999fe742..a98432b84db6a0f7cbd0a664df304e2f2b98e1dd 100644 (file)
@@ -114,7 +114,7 @@ SYMBOL: receive-buffer
     ] call ;
 
 M: unix (receive) ( datagram -- packet sockaddr )
-    dup do-receive dup [ rot drop ] [
+    dup do-receive dup [ [ drop ] 2dip ] [
         2drop [ +input+ wait-for-port ] [ (receive) ] bi
     ] if ;
 
index 7330ac1a567c658d6b0874a5f0fca7d73400a283..f9f84fbbaed2338e8a12ec1cc9437d99aafe94cf 100644 (file)
@@ -28,9 +28,6 @@ M: linked-assoc set-at
     [ 2dup assoc>> key? [ 2dup delete-at ] when add-to-dlist ] 2keep
     assoc>> set-at ;
 
-: dlist>seq ( dlist -- seq )
-    [ ] pusher [ dlist-each ] dip ;
-
 M: linked-assoc >alist
     dlist>> dlist>seq ;
 
index acc8a9d6d6f9505da81b43b1bb436d9ddd8ec059..c228684e321f1ae61ef091af4bf16793aee5abdd 100644 (file)
@@ -14,8 +14,8 @@ M: complex imaginary-part imaginary>> ;
 M: complex absq >rect [ sq ] bi@ + ;
 
 : 2>rect ( x y -- xr yr xi yi )
-    [ [ real-part ] bi@ ] 2keep
-    [ imaginary-part ] bi@ ; inline
+    [ [ real-part ] bi@ ]
+    [ [ imaginary-part ] bi@ ] 2bi ; inline
 
 M: complex hashcode*
     nip >rect [ hashcode ] bi@ bitxor ;
@@ -28,21 +28,21 @@ M: complex equal?
 M: complex number=
     2>rect number= [ number= ] [ 2drop f ] if ;
 
-: *re ( x y -- xr*yr xi*ri ) 2>rect * >r * r> ; inline
-: *im ( x y -- xi*yr xr*yi ) 2>rect >r * swap r> * ; inline
+: *re ( x y -- xr*yr xi*ri ) 2>rect [ * ] 2bi@ ; inline
+: *im ( x y -- xi*yr xr*yi ) 2>rect [ * swap ] dip * ; inline
 
-M: complex + 2>rect + >r + r> (rect>) ;
-M: complex - 2>rect - >r - r> (rect>) ;
-M: complex * 2dup *re - -rot *im + (rect>) ;
+M: complex + 2>rect [ + ] 2bi@ (rect>) ;
+M: complex - 2>rect [ - ] 2bi@ (rect>) ;
+M: complex * [ *re - ] [ *im + ] 2bi (rect>) ;
 
 : complex/ ( x y -- r i m )
-    dup absq >r 2dup *re + -rot *im - r> ; inline
+    [ [ *re + ] [ *im - ] 2bi ] keep absq ; inline
 
-M: complex / complex/ tuck / >r / r> (rect>) ;
+M: complex / complex/ tuck [ / ] 2bi@ (rect>) ;
 
 M: complex abs absq >float fsqrt ;
 
-M: complex sqrt >polar swap fsqrt swap 2.0 / polar> ;
+M: complex sqrt >polar [ fsqrt ] [ 2.0 / ] bi* polar> ;
 
 IN: syntax
 
index 1cea0a74dd3790305ef47b967a0436caac33e94f..8411baf94ca310e063e7a68150985ab9d725b773 100644 (file)
@@ -92,16 +92,6 @@ PRIVATE>
 : 0^ ( x -- z )
     dup zero? [ drop 0./0. ] [ 0 < 1./0. 0 ? ] if ; inline
 
-PRIVATE>
-
-: ^ ( x y -- z )
-    {
-        { [ over zero? ] [ nip 0^ ] }
-        { [ dup integer? ] [ integer^ ] }
-        { [ 2dup real^? ] [ fpow ] }
-        [ ^complex ]
-    } cond ; inline
-
 : (^mod) ( n x y -- z )
     1 swap [
         [ dupd * pick mod ] when [ sq over mod ] dip
@@ -114,6 +104,16 @@ PRIVATE>
         swap [ /mod [ over * swapd - ] dip ] keep (gcd)
     ] if ;
 
+PRIVATE>
+
+: ^ ( x y -- z )
+    {
+        { [ over zero? ] [ nip 0^ ] }
+        { [ dup integer? ] [ integer^ ] }
+        { [ 2dup real^? ] [ fpow ] }
+        [ ^complex ]
+    } cond ; inline
+
 : gcd ( x y -- a d )
     [ 0 1 ] 2dip (gcd) dup 0 < [ neg ] when ; foldable
 
@@ -177,9 +177,9 @@ M: complex log >polar swap flog swap rect> ;
 GENERIC: cos ( x -- y ) foldable
 
 M: complex cos
-    >float-rect 2dup
-    fcosh swap fcos * -rot
-    fsinh swap fsin neg * rect> ;
+    >float-rect
+    [ [ fcos ] [ fcosh ] bi* * ]
+    [ [ fsin neg ] [ fsinh ] bi* * ] 2bi rect> ;
 
 M: real cos fcos ;
 
@@ -188,9 +188,9 @@ M: real cos fcos ;
 GENERIC: cosh ( x -- y ) foldable
 
 M: complex cosh
-    >float-rect 2dup
-    fcos swap fcosh * -rot
-    fsin swap fsinh * rect> ;
+    >float-rect
+    [ [ fcosh ] [ fcos ] bi* * ]
+    [ [ fsinh ] [ fsin ] bi* * ] 2bi rect> ;
 
 M: real cosh fcosh ;
 
@@ -199,9 +199,9 @@ M: real cosh fcosh ;
 GENERIC: sin ( x -- y ) foldable
 
 M: complex sin
-    >float-rect 2dup
-    fcosh swap fsin * -rot
-    fsinh swap fcos * rect> ;
+    >float-rect
+    [ [ fsin ] [ fcosh ] bi* * ]
+    [ [ fcos ] [ fsinh ] bi* * ] 2bi rect> ;
 
 M: real sin fsin ;
 
@@ -210,9 +210,9 @@ M: real sin fsin ;
 GENERIC: sinh ( x -- y ) foldable
 
 M: complex sinh 
-    >float-rect 2dup
-    fcos swap fsinh * -rot
-    fsin swap fcosh * rect> ;
+    >float-rect
+    [ [ fsinh ] [ fcos ] bi* * ]
+    [ [ fcosh ] [ fsin ] bi* * ] 2bi rect> ;
 
 M: real sinh fsinh ;
 
index 388b4127cdac380d7e64ae584358a4afa55e908d..bcf7bb77b0c7fde12eec3732ec5ef99513be1d27 100644 (file)
@@ -11,6 +11,8 @@ tools.test math kernel sequences ;
 [ f ] [ \ number= fixnum object math-both-known? ] unit-test
 [ t ] [ \ number= integer fixnum math-both-known? ] unit-test
 [ f ] [ \ >fixnum \ shift derived-ops memq? ] unit-test
+[ f ] [ \ >integer \ /i derived-ops memq? ] unit-test
+[ t ] [ \ fixnum-shift \ shift derived-ops memq? ] unit-test
 
 [ { integer fixnum } ] [ \ +-integer-fixnum integer-op-input-classes ] unit-test
 [ { fixnum fixnum } ] [ \ fixnum+ integer-op-input-classes ] unit-test
@@ -24,4 +26,3 @@ tools.test math kernel sequences ;
 [ fixnum-bitnot ] [ \ bitnot modular-variant ] unit-test
 [ fixnum+fast ] [ \ fixnum+ modular-variant ] unit-test
 [ fixnum+fast ] [ \ fixnum+fast modular-variant ] unit-test
-
index ddde4e124498ae1a7b590b9c9d69085aa7de2ae5..56da09ccddc76a5a212b5d9089150839615a812d 100644 (file)
@@ -117,7 +117,9 @@ M: word integer-op-input-classes
     { fixnum bignum float }
     [ [ dup 3array ] [ swap method ] 2bi ] with { } map>assoc
     [ nip ] assoc-filter
-    [ def>> peek ] assoc-map % ;
+    [ def>> ] assoc-map
+    [ nip length 1 = ] assoc-filter
+    [ first ] assoc-map % ;
 
 SYMBOL: math-ops
 
@@ -150,7 +152,7 @@ SYMBOL: fast-math-ops
 : integer-derived-ops ( word -- words )
     [ math-ops get (derived-ops) ] [ fast-math-ops get (derived-ops) ] bi
     [
-            [
+        [
             drop
             [ second integer class<= ]
             [ third integer class<= ]
@@ -172,7 +174,6 @@ SYMBOL: fast-math-ops
         \ +       define-math-ops
         \ -       define-math-ops
         \ *       define-math-ops
-        \ shift   define-math-ops
         \ mod     define-math-ops
         \ /i      define-math-ops
 
@@ -186,6 +187,9 @@ SYMBOL: fast-math-ops
         \ >=      define-math-ops
         \ number= define-math-ops
 
+        { { shift bignum bignum } bignum-shift } ,
+        { { shift fixnum fixnum } fixnum-shift } ,
+
         \ + \ fixnum+ \ bignum+ define-integer-ops
         \ - \ fixnum- \ bignum- define-integer-ops
         \ * \ fixnum* \ bignum* define-integer-ops
index c8654869e2d727ce99330188a1d5540db7f28bdc..107e81d51f5ea14b1a57321e616fec9f3b22b07f 100644 (file)
@@ -22,6 +22,5 @@ PRIVATE>
 : rise ( pt2 pt1 -- n ) [ second ] bi@ - ;
 : run ( pt2 pt1 -- n ) [ first ] bi@ - ;
 : slope ( pt pt -- slope ) [ rise ] [ run ] 2bi / ;
-: distance ( point point -- float ) v- norm ;
 : midpoint ( point point -- point ) v+ 2 v/n ;
 : linear-solution ( pt pt -- x ) [ drop first2 ] [ slope ] 2bi / - ;
\ No newline at end of file
index 388d11795957d3771cb9582f5df7446169eb8de7..f7b3b37e257c5ba6c19681ae17dd234ae5a2f633 100644 (file)
@@ -22,9 +22,9 @@ INSTANCE: range immutable-sequence
 
 : twiddle 2dup > -1 1 ? ; inline
 
-: (a, dup roll + -rot ; inline
+: (a, dup [ + ] curry 2dip ; inline
 
-: ,b) dup neg rot + swap ; inline
+: ,b) dup [ - ] curry dip ; inline
 
 : [a,b] ( a b -- range ) twiddle <range> ; inline
 
index 01a421b4e7e210d41161743452b71986de1da5e6..a6967a7218bb86be4343ff188d380e4d0bfe891b 100644 (file)
@@ -24,6 +24,8 @@ IN: math.vectors
 : norm ( v -- x ) norm-sq sqrt ;
 : normalize ( u -- v ) dup norm v/n ;
 
+: distance ( u v -- x ) [ - absq ] [ + ] 2map-reduce sqrt ;
+
 : set-axis ( u v axis -- w )
     [ [ zero? 2over ? ] dip swap nth ] map-index 2nip ;
 
@@ -31,6 +33,7 @@ HINTS: vneg { array } ;
 HINTS: norm-sq { array } ;
 HINTS: norm { array } ;
 HINTS: normalize { array } ;
+HINTS: distance { array array } ;
 
 HINTS: n*v { object array } ;
 HINTS: v*n { array object } ;
index 68b4bff26651f708d2c87f0ec1a78e90bfa1b7f1..1445af8309e38566c8442944224ac9c824d92fa9 100644 (file)
-USING: accessors io io.streams.string kernel mime.multipart
-tools.test make multiline strings ;
+USING: accessors checksums checksums.md5 io io.encodings.ascii
+io.encodings.binary io.files io.streams.byte-array
+io.streams.string kernel make mime.multipart
+mime.multipart.private multiline sequences strings tools.test ;
 IN: mime.multipart.tests
 
-[ { "a" } ] [
+[ { "a" } ] [
     [
         "azzbzzczzdzz" <string-reader> "z" <multipart-stream> 1 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
-[ { "a" } ] [
+[ { "a" } ] [
     [
         "azzbzzczzdzz" <string-reader> "z" <multipart-stream> 2 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
-[ { "a" } ] [
+[ { "a" } ] [
     [
         "azzbzzczzdzz" <string-reader> "z" <multipart-stream> 3 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
-[ { "a" } ] [
+[ { "a" } ] [
     [
         "azzbzzczzdzz" <string-reader> "z" <multipart-stream> 4 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
-[ { "a" } ] [
+[ { "a" } ] [
     [
         "azzbzzczzdzz" <string-reader> "z" <multipart-stream> 5 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
 
-[ { "a" "a" } ] [
+[ { "a" "a" } ] [
     [
         "aazzbzzczzdzz" <string-reader> "z" <multipart-stream> 1 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
-[ { "aa" } ] [
+[ { "aa" } ] [
     [
         "aazzbzzczzdzz" <string-reader> "z" <multipart-stream> 2 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
-[ { "aa" } ] [
+[ { "aa" } ] [
     [
         "aazzbzzczzdzz" <string-reader> "z" <multipart-stream> 3 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
-[ { "aa" } ] [
+[ { "aa" } ] [
     [
         "aazzbzzczzdzz" <string-reader> "z" <multipart-stream> 4 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
-[ { "aa" } ] [
+[ { "aa" } ] [
     [
         "aazzbzzczzdzz" <string-reader> "z" <multipart-stream> 5 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
 
 
-[ { "a" } ] [
+[ { "a" } ] [
     [
         "azzbzzczzdzz" <string-reader> "zz" <multipart-stream> 1 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
 [ { "a" "z" "z" "b" "z" "z" "c" "z" "z" "d" "zz" } ] [
     [
         "azzbzzczzdzz" <string-reader> "zzz" <multipart-stream> 1 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
-[ { "a" "z" "z" "b" "z" "z" "c" "z" "z" "d" } ] [
+[ { "a" "z" "z" "b" "z" "z" "c" "z" "z" "d" } ] [
     [
         "azzbzzczzdzzz" <string-reader> "zzz" <multipart-stream> 1 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
-[ { "az" "zb" "zz" "cz" "zd" } ] [
+[ { "az" "zb" "zz" "cz" "zd" } ] [
     [
         "azzbzzczzdzzz" <string-reader> "zzz" <multipart-stream> 2 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
-[ { "a" "zzb" "zzc" "zzd" } ] [
+[ { "a" "zzb" "zzc" "zzd" } ] [
     [
         "azzbzzczzdzzz" <string-reader> "zzz" <multipart-stream> 3 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
-[ { "az" "zbzz" "czzd" } ] [
+[ { "az" "zbzz" "czzd" } ] [
     [
         "azzbzzczzdzzz" <string-reader> "zzz" <multipart-stream> 4 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
-[ { "azz" "bzzcz" "zd" } ] [
+[ { "azz" "bzzcz" "zd" } ] [
     [
         "azzbzzczzdzzz" <string-reader> "zzz" <multipart-stream> 5 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
 
-[ { "a" f f "b" f f "c" f f "d" f f } ] [
-    [
-        "azzbzzczzdzz" <string-reader> "z" <multipart-stream> 1 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
-
-[ { "a" f f "b" f f "c" f f "d" f f } ] [
-    [
-        "azzbzzczzdzz" <string-reader> "z" <multipart-stream> 2 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
-
-[ { "a" f f "b" f f "c" f f "d" f f } ] [
-    [
-        "azzbzzczzdzz" <string-reader> "z" <multipart-stream> 3 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
-
-[ { "a" f f "b" f f "c" f f "d" f f } ] [
-    [
-        "azzbzzczzdzz" <string-reader> "z" <multipart-stream> 4 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
-
-[ { "a" f f "b" f f "c" f f "d" f f } ] [
-    [
-        "azzbzzczzdzz" <string-reader> "z" <multipart-stream> 5 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
 
+: dog-test-empty-bytes-safari ( -- bytes )
+    B{
+        45 45 45 45 45 45 87 101 98 75 105 116 70 111 114 109 66
+        111 117 110 100 97 114 121 74 57 98 119 65 87 115 51 121
+        110 112 113 115 72 53 75 13 10 67 111 110 116 101 110 116
+        45 68 105 115 112 111 115 105 116 105 111 110 58 32 102 111
+        114 109 45 100 97 116 97 59 32 110 97 109 101 61 34 102 105
+        108 101 49 34 59 32 102 105 108 101 110 97 109 101 61 34
+        100 111 103 46 106 112 103 34 13 10 67 111 110 116 101 110
+        116 45 84 121 112 101 58 32 105 109 97 103 101 47 106 112
+        101 103 13 10 13 10 255 216 255 224 0 16 74 70 73 70 0 1 1
+        0 0 1 0 1 0 0 255 219 0 67 0 5 3 4 4 4 3 5 4 4 4 5 5 5 6 7
+        12 8 7 7 7 7 15 11 11 9 12 17 15 18 18 17 15 17 17 19 22 28
+        23 19 20 26 21 17 17 24 33 24 26 29 29 31 31 31 19 23 34 36
+        34 30 36 28 30 31 30 255 219 0 67 1 5 5 5 7 6 7 14 8 8 14
+        30 20 17 20 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
+        30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
+        30 30 30 30 30 30 30 30 30 30 30 30 30 30 255 192 0 17 8 1
+        49 1 64 3 1 34 0 2 17 1 3 17 1 255 196 0 29 0 0 2 2 3 1 1 1
+        0 0 0 0 0 0 0 0 0 4 5 6 7 2 3 8 0 1 9 255 196 0 74 16 0 2 1
+        3 3 2 4 4 3 4 5 10 5 3 5 1 1 2 3 0 4 17 5 18 33 6 49 19 34
+        65 81 7 50 97 113 20 35 129 21 51 66 82 36 52 145 161 177 8
+        53 83 98 114 115 147 178 193 209 22 37 67 116 241 99 130
+        240 23 68 84 100 146 225 255 196 0 25 1 0 3 1 1 1 0 0 0 0 0
+        0 0 0 0 0 0 1 2 3 0 4 5 255 196 0 39 17 0 2 2 2 2 3 0 2 1 5
+        1 0 0 0 0 0 0 1 2 17 3 33 18 49 34 50 65 19 81 4 5 20 35 66
+        97 82 255 218 0 12 3 1 0 2 17 3 17 0 63 0 228 200 149 136
+        219 131 200 207 233 68 196 145 112 60 21 45 234 91 181 57
+        177 178 138 75 56 95 111 152 196 51 250 209 11 167 198 14
+        118 138 22 138 153 104 150 118 82 46 217 45 161 98 79 242
+        102 157 38 151 98 174 64 211 237 72 247 49 46 104 11 8 140
+        111 229 247 166 194 70 137 12 146 112 61 235 57 36 172 31
+        82 7 154 199 78 244 176 178 255 0 132 41 100 195 76 15 183
+        240 118 60 31 244 85 237 126 241 237 237 157 213 176 113
+        197 66 158 254 234 82 74 49 45 187 144 42 49 155 158 217
+        108 152 99 21 68 214 88 116 217 83 17 218 218 171 250 109
+        138 180 254 6 221 83 205 109 1 199 115 225 10 141 90 106 23
+        106 187 95 59 73 239 237 77 44 111 89 79 136 24 186 250 131
+        235 86 199 166 71 143 20 52 181 211 237 24 143 232 150 236
+        61 140 66 155 65 167 233 251 64 252 5 158 127 221 45 3 99
+        42 220 42 186 240 79 247 83 139 38 86 92 21 57 20 76 246
+        140 78 155 98 88 31 217 246 125 191 209 45 108 253 159 97
+        255 0 240 44 255 0 225 45 22 216 200 199 181 99 88 74 98 77
+        99 78 178 69 111 14 194 213 23 28 226 48 15 246 212 30 242
+        21 252 105 8 145 170 103 178 213 137 172 121 162 127 181 87
+        151 141 182 247 31 235 210 180 216 209 28 88 217 219 120 99
+        250 52 100 255 0 172 155 168 248 108 109 11 103 240 208 127
+        194 173 118 82 71 225 47 148 246 163 11 169 30 74 81 140
+        102 182 178 35 203 97 104 62 162 46 104 41 45 109 119 127
+        86 131 254 21 48 144 225 9 198 104 105 198 24 118 53 76 77
+        81 141 73 105 109 143 234 176 127 193 21 146 89 219 110 63
+        209 97 255 0 131 69 65 183 110 15 39 218 182 144 160 159 41
+        6 169 102 5 22 54 138 114 109 45 216 123 24 184 53 177 45
+        44 137 231 79 179 237 254 138 179 118 101 112 167 159 181
+        102 131 140 212 35 236 99 95 224 172 119 143 252 190 207
+        254 21 18 186 125 129 92 254 2 207 254 16 172 15 148 230
+        182 71 46 225 198 106 178 78 204 40 213 237 109 83 33 45
+        224 237 223 195 199 247 214 189 30 222 222 69 45 37 165 187
+        156 227 12 161 177 245 230 143 214 212 8 75 123 138 15 69
+        96 7 220 214 159 169 135 31 129 177 192 198 159 102 120 255
+        0 68 181 240 216 217 12 15 217 214 156 246 252 165 230 137
+        139 205 235 128 7 204 123 80 183 154 148 118 202 66 225 156
+        118 62 148 169 174 38 91 55 193 167 233 191 60 214 22 96 14
+        249 137 107 84 199 69 137 246 174 157 100 255 0 65 18 210
+        43 237 82 105 148 188 108 64 254 31 102 164 243 223 204 146
+        249 155 39 233 73 38 50 84 137 156 112 233 19 200 4 118 54
+        201 238 22 33 68 54 153 166 52 96 173 149 163 15 115 16 205
+        66 244 189 77 141 226 40 115 143 90 155 91 73 192 116 245
+        29 141 77 233 140 177 169 46 64 109 167 88 45 203 31 217
+        246 92 127 244 171 19 97 99 226 16 218 125 152 227 63 186
+        20 100 204 56 247 245 175 66 84 145 191 147 235 246 174 140
+        125 18 180 125 183 211 108 72 7 246 125 158 63 221 45 109
+        151 77 177 219 254 111 179 255 0 132 180 68 76 163 133 206
+        51 197 103 43 0 184 166 158 144 72 133 244 54 113 220 5 91
+        120 50 59 254 77 7 120 109 188 48 22 8 1 207 242 98 152 106
+        170 191 137 45 239 218 149 93 41 97 129 239 73 97 143 96 19
+        172 103 204 161 23 232 181 164 71 152 93 143 173 110 117
+        101 67 90 142 239 195 55 165 97 229 251 37 122 124 138 182
+        48 118 253 210 81 66 116 250 82 123 2 205 103 108 55 30 99
+        31 221 218 140 134 63 56 221 200 169 147 26 90 229 159 56
+        20 109 242 171 89 16 217 251 80 214 190 80 49 197 110 212
+        63 168 147 234 107 74 62 44 166 36 156 209 17 234 235 140
+        193 26 170 182 230 227 21 40 248 113 208 240 234 214 169 53
+        194 224 63 166 57 168 167 85 55 136 34 5 87 126 124 170 123
+        26 233 15 129 214 42 221 59 108 123 112 51 27 14 223 90 142
+        61 68 233 206 227 249 58 35 7 224 252 57 252 133 141 91 25
+        82 71 24 255 0 189 44 212 254 21 222 99 16 171 120 139 234
+        160 97 171 165 99 81 143 5 145 74 142 199 29 171 239 225 99
+        121 138 149 80 127 133 241 205 22 229 96 121 19 84 145 199
+        250 231 77 106 61 62 210 25 35 114 189 212 1 198 43 237 133
+        210 72 71 24 56 228 125 107 167 186 179 163 236 245 93 61
+        149 35 76 148 42 43 154 186 195 167 175 58 123 85 149 9 37
+        67 103 63 74 117 39 123 37 151 26 110 226 20 14 64 53 246
+        132 211 174 22 234 21 216 217 111 83 69 22 80 72 197 89 245
+        103 61 238 128 117 60 155 121 15 174 218 174 239 8 23 141
+        158 251 170 192 213 36 219 11 175 169 28 85 123 169 237 93
+        64 240 57 52 99 32 142 45 89 191 15 229 231 154 46 201 155
+        60 214 141 48 43 69 141 163 24 162 109 227 61 199 21 57 118
+        96 244 57 92 227 52 43 198 219 143 126 244 68 18 3 88 202
+        172 141 134 108 147 205 8 107 64 62 65 223 145 131 239 91
+        25 188 199 39 38 181 163 99 191 122 250 112 199 118 59 213
+        83 160 114 54 59 46 211 239 89 39 203 90 93 89 88 115 197
+        110 64 74 113 83 138 169 5 59 62 183 35 214 189 16 193 197
+        124 109 202 123 154 251 19 13 199 35 38 170 242 69 62 194
+        105 214 255 0 171 138 85 166 169 82 204 164 237 60 103 235
+        77 181 129 226 66 184 98 163 220 82 155 73 24 202 45 34 81
+        201 239 75 44 138 141 7 114 72 110 146 203 36 73 12 42 207
+        150 193 197 73 52 191 135 215 186 168 241 220 180 113 177
+        206 49 200 90 153 124 40 248 122 110 151 241 183 65 66 12
+        48 207 191 189 94 54 186 61 165 156 94 28 123 10 149 10 78
+        59 138 231 109 252 58 163 8 163 159 236 254 19 73 53 176 86
+        80 176 175 171 1 197 107 185 248 77 101 105 103 51 204 187
+        36 199 24 25 39 255 0 249 93 18 176 195 18 157 177 168 30
+        212 191 85 132 201 109 39 134 138 204 227 110 8 160 175 232
+        210 227 196 226 14 170 210 27 66 215 60 46 54 110 5 72 31
+        227 82 141 57 214 72 145 137 198 64 237 70 127 148 13 146
+        219 107 208 145 150 5 240 91 211 245 165 58 75 237 130 48
+        72 36 47 117 237 71 39 113 4 23 248 216 202 224 96 100 114
+        107 24 148 183 126 62 213 182 101 57 231 145 89 70 6 7 2
+        174 221 35 133 71 102 248 84 40 245 172 110 57 38 182 175 3
+        140 86 19 1 142 194 145 182 199 34 250 129 197 226 100 241
+        154 211 52 121 77 194 182 234 67 117 238 223 236 162 150 17
+        248 81 218 138 116 52 72 228 225 183 246 21 241 148 126 30
+        79 76 46 234 62 234 16 27 181 7 34 55 135 55 63 250 116 232
+        210 118 168 117 167 172 127 132 183 220 224 15 13 127 187
+        189 16 10 135 194 144 69 43 176 144 155 88 23 212 71 70 32
+        110 251 129 165 170 25 99 99 139 78 127 182 179 213 220 199
+        167 141 190 86 35 191 189 42 241 228 132 174 50 65 246 162
+        53 9 89 172 227 221 158 212 178 151 139 54 61 100 68 118
+        241 86 227 89 182 132 121 247 72 1 2 186 187 225 157 184
+        131 70 182 143 28 162 128 203 234 167 235 92 181 211 246 87
+        23 221 92 145 198 173 133 144 121 192 249 107 170 250 103
+        242 236 35 241 147 194 157 84 6 99 252 85 36 169 34 249 98
+        229 34 100 89 89 139 43 6 97 192 35 211 233 95 94 86 17 2
+        199 56 238 105 119 226 188 171 223 183 39 222 190 27 172 16
+        95 113 79 95 173 16 199 30 134 246 242 11 133 60 242 59 212
+        75 226 103 77 91 235 58 101 204 138 159 154 145 147 145 235
+        78 97 152 171 248 145 200 10 31 65 222 138 155 100 200 21
+        178 222 167 29 171 5 87 211 144 110 214 109 31 80 240 36
+        111 32 39 57 244 57 237 77 224 152 92 69 226 174 49 142 126
+        149 105 124 86 232 27 125 70 22 187 178 132 9 2 229 177 247
+        53 76 66 38 209 181 65 109 48 111 8 156 18 123 81 229 20
+        170 201 101 196 253 163 208 94 161 14 251 105 27 217 106
+        189 213 20 11 226 125 51 138 177 181 70 205 153 104 249 87
+        28 85 117 117 253 117 247 251 241 84 87 240 231 26 233 108
+        192 5 3 131 77 145 78 243 74 180 213 193 7 138 115 18 229
+        137 172 227 33 27 48 183 64 24 26 202 126 13 108 140 169
+        242 142 9 236 79 106 26 92 150 228 250 209 140 93 140 124
+        254 48 107 34 195 39 154 215 255 0 231 122 247 191 253 234
+        188 65 196 223 27 151 24 144 101 253 40 152 179 130 49 233
+        90 109 85 29 124 217 163 226 218 19 28 98 163 123 176 165
+        64 46 219 13 122 22 223 39 28 147 216 86 219 133 4 19 90 1
+        240 161 50 28 131 252 52 91 131 219 55 144 62 189 56 91 68
+        133 88 110 245 30 213 37 248 49 210 178 106 58 188 51 73
+        144 138 119 19 233 140 208 189 61 210 211 245 12 232 193 79
+        204 57 32 226 186 51 161 250 90 195 65 211 161 138 8 255 0
+        51 104 46 125 106 115 146 78 145 124 17 113 143 146 37 26
+        85 188 122 109 132 113 68 184 96 49 159 165 125 185 185 85
+        59 90 64 119 124 198 180 205 43 5 43 156 31 79 181 10 178
+        36 44 26 70 222 205 223 30 148 165 210 177 139 150 149 10
+        227 98 142 192 250 214 155 147 253 28 199 177 88 122 238
+        244 250 208 171 52 155 134 88 98 133 150 237 164 36 46 112
+        15 53 129 56 190 145 65 255 0 148 77 158 235 69 153 118 182
+        199 218 54 118 239 154 175 116 73 72 181 129 135 204 203
+        218 174 31 142 22 18 234 26 36 203 2 72 21 60 229 64 253
+        225 207 106 165 244 67 38 194 37 36 178 240 51 90 91 175
+        248 104 234 13 18 169 228 221 230 127 46 43 5 151 196 228
+        214 55 127 186 221 238 43 85 187 100 227 158 213 94 71 20
+        180 232 103 23 43 197 125 145 84 168 201 230 176 135 182 43
+        100 156 40 165 9 22 212 144 45 249 247 163 161 254 174 40
+        93 79 157 67 62 153 166 22 234 166 1 197 96 53 98 235 149
+        12 167 222 147 234 3 242 102 81 220 71 82 41 99 12 59 129
+        74 117 91 114 45 167 117 31 250 103 251 169 148 140 129 45
+        55 44 17 99 253 29 23 12 204 28 6 3 20 20 19 127 71 139 159
+        253 42 223 28 129 136 7 156 154 103 208 255 0 153 177 205
+        170 120 204 3 12 12 240 69 111 213 199 134 145 66 163 36
+        143 90 246 154 141 148 231 143 74 203 89 138 67 123 11 6 57
+        199 21 63 134 139 243 68 211 224 110 159 102 218 140 243
+        189 188 178 60 152 249 192 192 171 213 173 128 140 176 141
+        15 25 193 244 168 39 193 43 63 15 79 19 76 7 140 199 206
+        184 171 30 250 50 146 43 42 228 48 193 168 219 163 177 55
+        200 71 226 254 97 228 140 28 99 210 183 69 117 30 226 31
+        105 30 222 148 46 161 152 75 141 229 148 156 226 149 60 140
+        70 248 137 80 189 241 75 143 34 186 101 158 54 201 25 102
+        241 55 70 35 3 216 118 162 108 39 87 144 66 242 108 61 243
+        239 244 168 180 119 82 49 253 233 136 123 10 206 207 82 89
+        36 88 174 150 38 195 121 37 76 247 250 213 123 36 224 214
+        201 204 169 20 145 60 61 148 240 72 245 170 127 227 23 70
+        172 150 134 226 214 223 107 103 141 130 173 155 70 86 183
+        66 28 179 3 250 26 58 242 194 43 232 66 92 66 187 79 189
+        115 201 108 56 230 163 105 156 115 105 60 208 196 214 23 80
+        148 145 71 5 135 122 132 235 145 201 29 249 42 188 22 245
+        174 164 248 151 240 207 198 70 212 45 21 81 145 142 204 10
+        160 186 163 71 154 222 77 183 49 8 157 84 246 254 35 239 93
+        112 206 180 145 203 60 93 201 116 37 211 39 10 0 126 41 220
+        119 81 1 144 213 22 120 174 35 92 237 226 135 146 250 234
+        33 235 143 65 87 228 217 13 50 87 226 199 254 144 126 149
+        245 166 141 200 243 10 133 46 162 232 115 146 72 172 206
+        175 41 238 191 223 67 147 9 51 12 132 227 114 214 82 120
+        106 56 113 80 209 170 72 88 5 76 31 189 20 215 178 152 212
+        149 201 197 50 102 37 118 211 195 242 150 227 222 140 18 71
+        129 181 137 168 84 119 151 1 73 197 49 180 191 153 148 110
+        200 199 106 231 250 104 246 74 29 148 174 230 227 29 177 89
+        232 58 77 246 183 172 195 20 112 177 141 125 135 6 153 244
+        151 75 234 157 65 36 113 136 241 9 0 230 186 15 162 250 19
+        79 208 225 79 42 25 145 130 183 31 74 76 146 138 71 84 49
+        211 183 209 143 68 244 245 174 149 167 6 252 56 86 28 246
+        169 45 207 130 182 134 66 222 30 61 187 214 251 192 182 235
+        26 15 40 39 210 144 107 247 22 176 249 46 37 36 124 193 127
+        155 233 83 91 118 86 172 214 151 14 236 220 228 103 130 222
+        213 147 204 138 164 48 86 39 185 168 228 218 149 196 206 56
+        17 91 129 133 81 243 17 88 53 227 180 137 28 114 56 92 122
+        247 170 27 241 177 225 187 24 231 251 171 43 85 241 50 170
+        14 15 36 154 87 109 34 151 27 134 121 167 54 108 225 129 12
+        118 251 82 185 168 151 112 226 129 250 130 194 222 77 30
+        118 120 247 237 140 250 122 215 48 107 54 169 103 169 201
+        224 163 129 188 240 195 138 235 187 203 101 109 50 82 205
+        130 227 143 181 115 71 197 11 55 183 214 228 88 219 17 239
+        224 1 244 162 157 171 57 102 252 68 107 48 54 234 27 24 175
+        68 15 114 49 158 213 166 218 19 37 160 207 38 140 137 120
+        10 220 145 86 198 173 108 227 123 9 130 182 203 218 181 195
+        216 240 59 214 215 70 49 131 73 244 196 91 80 99 248 197 62
+        230 152 193 145 111 145 75 245 24 207 226 147 159 90 109
+        103 31 244 97 158 115 84 140 28 140 40 184 185 117 148 100
+        12 118 173 183 172 143 165 92 48 193 34 39 175 186 149 168
+        14 24 142 49 64 220 201 183 78 157 87 129 225 61 43 84 232
+        196 94 55 155 195 207 134 216 61 168 155 89 101 241 16 108
+        61 232 168 236 220 219 161 11 198 208 223 219 91 173 172
+        157 100 86 32 119 166 109 80 30 201 95 79 166 228 30 245
+        150 187 129 127 18 255 0 101 110 209 23 195 43 246 175 107
+        136 5 253 171 30 119 29 181 54 44 125 209 127 252 28 119
+        147 73 72 230 142 40 215 60 31 122 156 223 199 182 38 200
+        192 3 32 212 119 225 21 138 174 131 12 155 67 115 220 84
+        183 91 141 148 97 89 64 199 32 251 84 228 244 119 67 216
+        175 53 163 38 215 30 25 199 112 213 29 69 63 48 152 73 159
+        65 233 83 13 65 48 37 1 124 167 249 170 55 61 169 40 20 109
+        200 254 90 129 218 4 247 78 190 70 24 83 220 214 80 238 154
+        69 16 176 14 14 87 234 104 11 230 104 238 90 118 5 84 252
+        202 125 190 148 126 152 158 21 202 220 69 135 4 103 13 217
+        215 233 250 215 70 55 226 38 88 187 39 154 13 208 252 34
+        163 33 141 193 243 231 212 251 211 251 121 149 85 1 97 130
+        112 191 90 135 90 206 197 188 64 27 45 201 207 127 214 134
+        215 181 195 98 143 189 138 237 77 203 207 99 70 147 236 131
+        99 174 169 234 43 123 77 62 84 37 70 88 247 53 203 223 20
+        122 138 214 234 127 203 100 102 12 71 7 177 230 180 252 80
+        248 131 123 168 93 92 217 90 92 48 143 126 11 3 85 179 199
+        52 132 72 237 36 140 199 144 125 105 163 26 232 132 230 210
+        164 48 75 217 26 50 178 31 175 216 86 192 177 179 120 114
+        70 67 241 199 223 181 123 78 176 141 158 25 60 57 29 36 94
+        123 112 125 170 77 160 116 237 205 192 152 92 70 3 69 180
+        142 14 72 30 149 94 150 201 70 42 93 246 70 127 3 111 32 5
+        156 28 246 30 245 190 13 46 213 184 24 7 252 106 204 181
+        232 39 188 134 25 214 2 158 110 1 167 211 252 45 149 128
+        217 22 112 6 10 158 230 167 249 25 79 192 83 113 90 218 43
+        149 217 141 188 156 214 187 150 139 38 69 97 207 165 90 154
+        223 195 91 168 237 85 150 18 178 103 7 158 226 163 250 159
+        68 74 152 183 104 138 133 245 230 154 51 108 73 97 165 178
+        2 110 35 93 185 140 228 246 250 214 22 218 145 75 144 79 49
+        169 237 237 76 239 180 139 136 30 225 167 183 116 136 113
+        19 250 19 244 164 87 118 130 221 66 140 239 113 150 255 0
+        84 123 26 210 236 17 199 79 146 58 87 225 47 85 90 20 133
+        99 120 217 252 48 184 7 154 188 44 181 72 110 33 115 28 138
+        189 178 107 243 247 73 212 245 13 34 238 43 139 91 150 86
+        86 224 103 130 43 161 190 21 117 252 218 133 187 199 52 195
+        196 199 42 79 57 169 101 130 173 150 89 37 47 133 243 123
+        62 27 184 205 66 250 153 228 158 87 72 219 242 128 203 31
+        230 250 83 11 125 67 241 86 98 67 184 239 92 140 119 20 179
+        85 146 97 108 214 246 225 124 118 236 237 217 7 169 53 139
+        136 77 210 199 8 240 215 106 142 5 122 9 94 225 177 34 149
+        251 208 119 94 29 164 113 164 108 89 229 206 11 127 16 254
+        111 181 21 167 69 35 196 145 178 183 3 230 247 165 148 171
+        163 166 41 164 130 109 86 72 238 147 99 239 32 246 21 50
+        208 67 51 13 202 70 225 138 143 217 91 1 54 246 198 79 106
+        149 105 49 31 46 210 1 250 210 91 125 141 149 166 135 114
+        167 244 87 221 194 162 96 31 173 115 103 199 23 118 190 241
+        36 82 160 55 148 159 90 234 47 194 238 179 39 25 59 121 246
+        174 109 255 0 40 116 120 110 193 194 99 119 97 84 199 217
+        231 101 232 129 88 15 19 77 12 127 74 223 28 124 80 182 50
+        40 176 133 70 70 70 236 125 40 181 124 40 198 106 216 211
+        226 206 89 109 155 34 93 166 136 112 118 10 12 51 23 28 26
+        222 242 16 170 190 227 251 40 168 180 18 63 170 115 121 30
+        61 233 149 159 238 69 44 213 124 179 41 200 224 209 54 210
+        55 130 49 197 27 163 25 220 166 238 105 102 167 24 91 9 200
+        239 225 63 20 222 94 35 207 189 5 169 47 244 9 255 0 221 61
+        43 70 54 233 208 175 236 235 101 33 79 228 35 103 244 175
+        52 113 171 249 177 244 197 37 178 189 151 240 22 235 26 231
+        108 64 22 250 14 212 76 115 74 236 190 76 156 214 148 120
+        148 135 25 116 137 30 154 114 195 142 115 199 181 103 212 2
+        69 22 211 42 134 41 38 15 181 97 165 135 104 187 109 230
+        137 213 70 52 183 247 83 145 247 160 73 170 154 103 65 124
+        33 150 245 186 106 18 99 120 198 121 199 106 156 223 50 181
+        177 103 80 95 24 21 0 248 17 121 29 215 79 197 27 206 216 7
+        154 178 245 45 63 242 188 72 206 83 28 87 61 118 206 200 63
+        34 5 170 47 149 155 113 35 212 123 82 11 169 21 163 11 24
+        218 71 114 106 73 171 90 72 204 237 27 21 199 124 122 212
+        102 246 53 149 138 188 133 0 61 197 37 89 217 29 136 53 75
+        171 111 21 13 192 196 108 112 91 218 137 211 97 109 58 34
+        151 18 135 183 97 186 25 129 206 207 245 126 212 171 82 145
+        33 117 180 155 5 91 129 159 74 81 38 165 119 166 23 181 185
+        13 36 64 111 140 154 120 107 68 242 77 217 59 186 215 99
+        183 178 109 201 135 81 232 121 199 215 235 84 183 196 238
+        182 55 119 18 90 219 202 225 135 145 142 107 221 79 213 32
+        192 235 24 33 241 140 3 233 239 85 212 183 17 202 254 44
+        222 116 39 42 87 230 253 106 177 77 156 83 157 61 31 45 237
+        237 239 1 102 27 100 118 207 29 137 246 21 186 210 206 226
+        234 117 88 99 32 227 102 0 229 79 210 134 131 114 220 179
+        91 169 147 235 31 106 184 62 29 116 188 215 205 14 160 145
+        168 115 141 216 236 79 184 250 85 23 138 217 40 183 116 197
+        93 13 210 179 94 74 18 230 213 114 14 72 92 240 106 230 233
+        14 149 201 182 205 143 49 182 210 72 249 254 245 48 233 30
+        132 176 210 209 47 24 174 233 57 97 252 167 218 167 186 85
+        149 188 100 34 145 133 57 28 122 212 102 220 186 58 97 20
+        182 200 190 129 210 227 194 72 103 183 201 140 229 192 28
+        17 78 83 165 195 162 4 143 96 7 111 126 245 58 210 108 148
+        90 143 40 231 191 214 137 154 200 237 77 168 54 171 110 34
+        137 185 113 123 101 115 115 210 176 184 101 150 223 113 81
+        198 106 35 212 61 46 204 146 44 118 104 3 38 204 227 176
+        247 251 213 241 45 180 101 119 0 9 35 251 41 14 173 104 170
+        73 101 10 153 224 208 119 240 50 148 89 202 157 87 210 48
+        77 60 202 214 110 145 193 229 140 1 199 222 169 174 161 208
+        175 22 242 86 75 117 218 95 31 252 215 114 106 218 69 181
+        227 52 71 111 57 46 113 223 138 169 250 227 225 231 131 110
+        90 216 198 94 224 22 231 209 126 149 162 223 45 154 81 168
+        156 164 246 105 35 152 164 140 41 67 203 122 15 160 172 244
+        205 66 77 47 82 51 89 54 17 78 55 19 203 125 233 247 94 105
+        223 178 174 22 205 16 237 44 124 64 125 90 162 182 234 136
+        155 102 138 70 62 137 31 173 94 124 90 57 84 156 54 116 39
+        195 190 179 134 247 78 137 124 92 52 99 12 24 250 84 190
+        125 74 222 228 22 13 148 35 12 7 241 125 15 210 185 131 65
+        214 164 211 239 247 12 162 231 205 138 181 180 30 166 140
+        66 173 183 114 133 221 180 251 251 212 163 217 104 57 61
+        217 45 187 183 48 52 154 150 161 34 137 37 242 67 26 246 81
+        232 61 233 182 153 49 100 85 229 112 63 90 138 45 212 147
+        203 251 79 82 37 80 183 229 102 164 26 9 252 67 120 146 72
+        85 91 145 72 227 114 59 160 237 18 88 219 116 161 128 194
+        250 98 164 218 66 175 145 152 176 31 74 141 233 144 188 234
+        35 221 177 148 246 247 169 118 137 110 210 97 23 142 49 73
+        246 131 54 146 29 92 206 230 219 109 190 115 183 140 251 87
+        51 255 0 148 20 183 13 170 120 78 170 124 221 249 174 164
+        185 130 27 123 23 50 76 82 69 143 129 239 92 167 241 178
+        239 241 93 84 144 43 29 170 196 55 214 169 141 83 103 14 94
+        136 60 113 50 75 18 174 79 229 246 52 94 226 2 231 223 154
+        250 84 199 50 150 228 142 7 218 177 118 12 221 171 162 18
+        75 71 56 79 139 25 101 81 243 99 244 172 165 198 194 27 185
+        239 143 74 24 174 210 24 112 43 207 32 216 41 219 179 8 181
+        86 62 48 237 222 143 178 93 208 45 3 170 168 241 215 143 90
+        105 166 46 97 24 246 169 72 198 115 174 16 41 251 208 58
+        145 99 167 93 28 124 176 57 31 217 76 167 70 35 147 64 234
+        8 223 179 47 121 255 0 246 207 255 0 45 82 49 209 133 58
+        116 91 236 237 155 215 195 163 214 53 35 105 60 208 186 71
+        245 59 111 247 99 251 232 167 39 120 199 189 115 61 187 58
+        49 244 62 211 27 106 40 244 11 138 206 245 131 90 52 110
+        112 15 124 250 80 182 59 150 60 230 183 93 131 52 5 27 128
+        123 98 175 195 198 206 121 123 23 111 194 141 25 19 165 163
+        146 25 150 25 163 228 146 123 213 139 166 235 6 72 132 55
+        16 182 244 227 196 61 136 170 231 225 154 76 186 12 22 208
+        179 49 99 134 250 138 156 221 168 180 182 82 216 81 234 125
+        123 87 36 175 164 117 198 187 96 58 228 214 203 59 186 202
+        20 145 242 147 193 53 1 215 181 21 183 159 204 200 184 60
+        224 240 43 87 94 245 125 134 157 20 166 73 17 216 118 25
+        230 168 174 178 235 171 237 81 90 222 215 114 199 158 72
+        239 250 86 132 91 208 207 34 142 209 51 235 190 160 181 86
+        120 81 64 43 192 57 245 168 68 189 85 123 61 177 130 95 57
+        67 149 63 78 212 133 26 107 169 12 183 147 177 200 245 61
+        205 1 113 118 200 204 145 224 15 173 118 67 29 171 100 178
+        229 182 25 125 127 150 37 188 197 251 168 238 15 189 39 185
+        59 88 239 96 227 233 90 204 153 36 243 156 250 214 80 71 44
+        242 42 170 239 102 56 81 158 230 153 164 142 87 119 100 211
+        225 206 159 38 163 172 70 24 180 11 24 192 157 144 149 39
+        254 181 215 159 13 186 114 107 91 40 63 18 33 155 114 143
+        204 72 246 156 125 126 149 76 255 0 147 198 143 171 90 193
+        29 212 150 211 92 187 159 201 137 149 118 238 29 192 231 57
+        31 95 210 186 179 67 253 204 19 79 111 28 23 17 128 94 51
+        243 21 255 0 10 231 148 172 183 14 42 205 194 198 51 182 56
+        212 246 239 76 244 141 60 52 109 25 57 246 62 245 140 23
+        182 18 93 21 158 101 66 237 144 163 184 167 169 60 62 42
+        219 197 177 155 211 111 183 189 78 154 232 101 145 208 77
+        140 91 97 53 181 215 56 86 224 19 201 175 182 255 0 153 207
+        99 244 237 88 207 34 169 11 131 222 155 95 72 74 219 179 99
+        70 54 96 118 28 10 87 127 110 100 144 112 118 47 115 77 147
+        204 156 80 119 141 180 129 42 159 15 233 220 208 119 240
+        104 57 39 178 37 117 96 85 213 147 200 51 198 125 105 102
+        187 166 69 54 157 34 149 46 249 193 30 255 0 74 152 93 203
+        101 248 35 47 136 164 33 198 65 165 111 61 188 182 243 165
+        187 70 230 70 249 143 96 43 36 238 217 105 100 109 81 202
+        255 0 26 122 94 231 240 119 19 36 177 69 30 60 177 32 36
+        177 255 0 189 115 30 160 38 130 83 13 194 52 108 59 6 24 56
+        175 208 63 136 208 223 92 105 207 21 134 158 207 19 103 243
+        21 87 43 199 98 73 239 92 75 241 71 69 212 236 122 138 225
+        174 109 229 104 249 35 198 24 32 125 72 227 251 234 139 100
+        114 69 209 22 180 152 162 121 78 1 245 167 218 70 173 115
+        107 34 186 254 98 142 224 122 138 138 6 100 227 248 79 106
+        221 5 228 177 159 47 98 49 85 171 22 46 145 97 69 213 51 92
+        95 197 248 179 182 5 249 99 61 254 245 105 116 222 187 111
+        113 98 30 50 170 84 236 7 61 207 181 115 221 153 241 206
+        226 88 47 185 244 52 108 26 166 163 165 220 175 225 238 11
+        170 182 229 0 240 77 35 196 213 179 170 57 18 143 103 91
+        244 253 212 110 23 116 170 167 102 50 125 13 77 116 75 168
+        109 109 131 33 103 25 229 147 214 185 131 161 190 34 36 211
+        8 175 36 104 229 7 140 227 7 251 234 246 233 77 90 222 254
+        213 26 9 55 2 61 235 145 220 101 208 202 74 107 178 77 121
+        113 115 170 188 145 70 36 181 135 30 99 47 241 253 171 159
+        62 46 90 90 218 245 34 77 104 193 54 183 0 213 253 169 91
+        200 150 203 113 19 96 168 36 227 218 185 235 226 187 51 106
+        194 86 112 70 227 192 239 84 199 53 100 178 105 82 35 18 57
+        99 90 7 239 43 4 155 33 91 156 123 86 107 203 110 174 142
+        36 101 166 19 130 0 200 199 21 237 170 121 39 154 248 155
+        177 230 32 214 71 129 156 142 105 210 179 8 245 140 248 163
+        138 109 163 200 162 223 130 51 138 85 173 224 74 87 190 61
+        69 29 163 254 235 244 161 40 152 57 183 51 103 6 131 213 8
+        93 58 247 60 127 71 127 249 104 238 62 180 22 177 183 246
+        101 239 127 234 239 255 0 45 20 233 24 85 167 73 26 216 65
+        158 254 18 86 70 100 50 129 159 90 89 104 199 240 86 236
+        199 63 150 63 186 178 133 100 146 225 112 199 147 197 69 37
+        101 99 145 116 137 133 143 154 42 223 50 31 8 149 228 138
+        209 167 127 87 0 247 94 9 162 157 136 78 14 51 222 171 242
+        136 228 246 39 127 8 122 155 193 211 165 220 219 222 54 192
+        218 113 254 52 71 92 124 78 134 206 23 182 242 187 28 252
+        196 228 113 244 170 88 223 220 219 207 44 80 206 241 239
+        239 180 227 38 144 234 211 205 121 49 73 228 101 63 206 79
+        45 244 169 180 145 73 78 162 107 234 29 90 235 92 212 101
+        113 39 229 150 254 34 104 102 133 173 146 56 230 104 163 6
+        61 202 249 206 107 11 155 118 183 143 115 52 123 72 227 117
+        42 184 144 147 183 57 35 142 15 24 167 142 136 115 114 14
+        212 175 140 155 18 48 170 23 212 122 208 18 51 72 219 155
+        143 181 124 141 89 188 217 237 82 45 15 165 239 239 228 64
+        35 220 172 50 60 164 211 60 180 168 122 182 34 182 181 150
+        105 22 52 83 150 56 21 119 124 40 232 61 22 11 120 117 14
+        162 91 71 193 223 137 156 141 163 244 168 207 76 244 169
+        183 63 136 212 18 225 18 57 54 168 100 219 185 135 63 225
+        91 58 183 90 125 107 82 255 0 195 61 62 206 225 188 133 223
+        130 120 244 164 82 82 209 69 162 234 185 248 149 211 250 36
+        150 134 27 173 53 90 60 43 62 205 196 168 237 185 135 124
+        122 30 226 143 31 29 52 104 209 202 95 254 32 5 27 100 36
+        236 45 159 148 10 175 236 62 14 116 119 78 233 49 106 29
+        125 173 188 6 78 209 228 140 254 148 143 173 126 25 244 255
+        0 254 31 184 234 111 135 186 191 237 75 11 33 253 58 212
+        252 240 131 193 111 211 138 203 18 248 105 41 203 127 11 55
+        77 248 167 13 230 169 52 150 247 62 32 50 141 165 57 219
+        192 206 71 176 171 175 165 122 166 5 180 105 218 238 57 174
+        14 11 190 120 198 63 135 233 92 19 209 178 53 191 80 219
+        134 145 158 37 96 36 8 112 28 122 30 61 49 87 123 245 75
+        105 182 99 207 52 183 69 118 195 26 0 16 169 237 74 213 104
+        10 171 71 82 105 125 92 178 27 168 173 231 133 252 12 41 37
+        143 45 235 68 75 172 79 115 181 162 5 128 229 177 233 84
+        103 195 200 167 142 199 241 23 49 151 121 21 93 163 36 242
+        199 230 63 165 90 218 115 72 203 28 109 148 86 95 48 30 130
+        163 46 131 68 134 62 164 146 22 88 78 21 152 231 46 120 197
+        44 126 179 134 226 226 72 124 104 153 146 79 13 129 39 0
+        251 253 170 55 212 64 44 102 54 86 40 36 33 28 158 7 21 76
+        245 62 169 115 211 218 200 159 30 37 165 208 49 206 224 240
+        62 181 88 250 152 177 62 34 245 140 58 102 239 2 121 12 14
+        222 120 80 249 147 237 244 168 54 141 241 163 78 211 141
+        197 165 197 196 110 210 203 184 16 199 40 158 223 78 113
+        222 160 191 17 53 127 196 104 134 75 123 167 145 74 17 20
+        217 230 63 175 255 0 62 245 82 116 190 137 169 117 70 175
+        107 165 233 240 120 183 183 79 225 199 158 199 156 150 111
+        160 28 213 97 20 214 197 201 168 218 58 99 87 248 221 161
+        73 107 36 48 234 16 164 172 70 232 230 77 202 62 162 133
+        213 239 186 63 173 172 13 173 252 186 108 175 26 9 160 13
+        46 213 115 245 3 147 81 85 248 123 240 135 79 184 58 54 177
+        212 210 207 171 96 36 146 110 10 187 253 64 250 103 181 70
+        126 35 124 48 190 232 99 6 191 161 221 181 213 145 243 70
+        249 7 2 179 138 55 41 69 121 116 68 62 34 244 106 232 154
+        139 73 100 209 61 179 246 17 146 66 253 179 80 146 152 39
+        131 199 28 213 195 105 171 105 157 87 161 143 26 59 165 188
+        183 127 13 178 23 185 254 44 14 194 162 250 143 68 106 158
+        61 204 107 110 234 144 30 119 14 228 250 214 186 216 120
+        166 66 226 186 146 33 181 64 42 79 57 166 150 183 81 221 67
+        28 108 18 34 131 27 135 115 75 245 13 58 230 209 218 57 151
+        105 30 148 26 50 169 243 12 143 106 111 201 100 165 221 14
+        110 45 100 30 29 202 108 93 231 201 176 249 179 245 169 239
+        195 46 190 155 65 116 134 233 140 202 14 56 39 138 173 172
+        165 241 167 102 114 65 246 205 29 45 139 162 248 204 228
+        123 82 154 13 217 214 154 111 94 193 127 103 35 13 219 89
+        59 103 214 170 30 176 184 55 250 195 158 200 28 241 237 81
+        14 158 212 46 196 42 137 52 136 163 140 3 222 158 137 55
+        121 155 204 199 185 62 181 62 153 119 177 106 33 86 39 146
+        15 247 81 80 227 28 214 137 102 84 57 35 143 81 91 33 60 96
+        250 242 42 184 246 182 77 236 45 72 53 242 65 229 28 154
+        249 12 110 20 229 189 107 50 141 142 244 244 97 14 171 216
+        100 246 245 166 26 88 99 0 35 218 130 215 35 41 149 62 180
+        126 145 34 139 101 76 115 75 35 4 237 124 253 43 70 167 206
+        153 122 63 254 179 255 0 203 71 73 185 87 191 122 7 80 255
+        0 54 94 255 0 237 223 254 90 41 42 48 158 198 216 61 132 13
+        234 34 76 10 223 4 91 101 25 226 129 180 188 95 192 192 168
+        74 159 13 123 253 40 136 174 55 56 243 115 92 231 71 24 168
+        162 77 103 194 133 29 143 173 23 183 3 142 104 29 53 183 69
+        159 173 28 161 137 32 48 31 122 183 250 156 242 236 132 107
+        158 77 85 199 161 245 165 154 157 228 75 20 143 224 147 38
+        208 160 254 180 95 83 57 138 255 0 123 28 143 97 222 163 23
+        119 6 86 113 187 3 28 3 64 73 118 105 188 158 75 137 188 71
+        96 196 142 62 149 164 43 30 194 155 233 90 68 247 146 69 24
+        134 76 56 200 101 82 71 247 84 150 223 225 254 169 117 125
+        13 172 54 206 217 30 128 228 208 177 150 50 61 211 246 17
+        93 221 197 19 50 151 102 24 78 228 254 149 210 29 55 105 99
+        164 244 220 104 153 154 237 211 1 35 143 5 190 134 190 116
+        95 193 91 125 52 67 53 238 212 144 12 22 9 206 126 149 105
+        216 232 54 58 126 158 27 240 202 229 60 161 207 115 250 84
+        178 100 101 225 138 145 205 127 16 35 235 141 54 194 107
+        169 173 82 194 202 102 43 28 64 121 177 238 126 181 183 252
+        152 180 184 110 186 206 59 139 153 55 120 114 255 0 23 124
+        138 184 254 36 90 166 177 166 141 46 104 35 142 4 39 108
+        140 60 196 227 176 199 115 84 102 142 215 157 3 174 165 245
+        152 155 98 49 145 210 65 182 66 185 239 131 86 197 41 73 81
+        57 175 22 75 126 54 92 222 106 189 105 168 45 206 80 193 62
+        200 131 127 20 127 74 19 225 245 222 151 210 147 38 181 113
+        169 69 121 103 125 101 56 212 44 99 102 221 6 60 168 178
+        103 131 158 249 20 247 171 250 255 0 225 55 87 218 197 168
+        106 38 238 29 67 24 153 33 139 7 31 169 239 80 253 42 199
+        77 234 9 221 244 173 34 120 116 93 223 60 242 238 146 225
+        135 191 176 197 36 63 140 227 147 155 122 59 223 245 28 95
+        218 44 42 62 68 123 167 116 185 33 117 214 20 71 109 12 210
+        51 36 95 197 180 158 0 171 51 165 244 73 181 27 215 191 191
+        183 154 71 150 61 177 2 56 219 239 254 213 35 135 77 93 99
+        94 75 88 99 72 173 161 199 135 10 231 9 138 187 122 35 69
+        184 136 199 113 225 112 23 204 91 181 105 61 158 122 116
+        182 109 183 177 142 215 72 137 99 152 44 139 202 169 238
+        135 220 211 173 10 247 84 145 37 105 49 49 72 240 127 183
+        230 20 195 195 180 216 86 107 115 34 158 225 69 108 183 146
+        21 220 177 126 90 40 200 92 115 82 158 217 76 73 209 23 188
+        188 186 187 184 17 77 43 73 110 173 231 66 57 205 36 235 93
+        26 222 248 180 239 3 92 196 188 182 206 202 49 86 11 61 188
+        190 105 20 200 254 158 80 48 43 69 253 168 184 183 219 28
+        107 27 24 246 133 127 95 236 162 131 61 28 197 173 216 222
+        88 217 13 44 226 43 73 31 242 89 255 0 139 239 65 124 52
+        190 183 232 190 169 212 34 186 137 37 188 186 211 165 252
+        20 241 182 10 183 7 106 159 114 1 171 31 226 39 74 188 150
+        165 68 82 126 72 47 156 241 159 165 66 44 180 219 125 107
+        79 75 123 168 137 187 181 36 199 112 14 10 48 237 131 86
+        134 153 9 78 169 175 217 28 191 211 109 173 111 109 205 190
+        165 6 167 45 196 98 226 89 34 13 152 157 143 40 229 191 136
+        122 213 219 240 252 182 169 240 123 92 211 245 15 204 134
+        221 191 163 153 62 94 59 129 85 78 147 168 244 85 173 233
+        139 172 44 181 29 51 80 138 76 59 194 229 163 155 253 110
+        121 201 246 169 111 88 252 86 233 143 252 53 7 76 244 23
+        143 35 72 140 37 121 34 218 50 125 205 8 97 148 95 43 61 95
+        231 255 0 59 22 124 80 140 35 180 82 80 254 51 75 234 219
+        152 244 185 25 31 199 17 162 17 228 111 191 210 174 222 139
+        139 169 109 103 71 234 59 16 208 73 134 91 132 28 99 218
+        162 191 15 58 89 110 181 4 213 181 39 113 32 199 134 93 114
+        142 255 0 82 43 162 180 147 22 161 107 2 222 219 198 147
+        162 132 64 7 148 175 189 35 200 250 103 18 132 111 179 158
+        126 54 232 182 47 178 234 216 143 12 182 230 34 169 75 216
+        226 86 62 11 7 25 238 43 184 58 167 161 44 181 120 36 73 6
+        204 140 99 195 4 19 238 42 138 248 143 240 98 250 192 126
+        51 78 18 73 30 114 219 87 3 251 40 197 162 83 195 78 202 44
+        103 52 211 78 187 145 54 164 135 122 127 47 168 167 119 125
+        31 117 14 158 39 146 60 72 6 74 169 228 212 106 230 9 109
+        91 44 172 185 28 110 20 233 139 199 137 59 211 30 223 194 6
+        21 216 9 228 123 154 117 19 21 183 101 35 181 68 58 114 224
+        52 41 184 147 232 64 247 169 58 179 120 108 164 130 77 35
+        236 22 8 208 254 98 209 16 202 21 112 8 197 15 63 136 172 6
+        112 125 43 234 35 110 238 0 255 0 173 87 23 65 24 66 236
+        121 193 197 109 144 238 21 170 15 42 121 151 28 214 213 59
+        184 170 24 79 174 144 84 145 216 246 173 250 79 238 135 218
+        133 214 206 213 17 144 115 69 105 35 49 45 99 12 223 228
+        160 245 15 243 101 239 254 217 255 0 229 163 101 24 10 191
+        74 11 81 227 77 189 255 0 219 191 252 181 140 66 237 225
+        152 136 216 103 105 143 138 42 222 57 150 117 57 39 154 107
+        103 110 162 194 219 10 63 171 171 126 167 189 98 177 159 20
+        10 230 67 56 162 65 166 16 176 15 122 57 202 178 141 172
+        115 64 88 198 124 49 205 27 28 101 92 179 114 41 211 177 27
+        43 190 181 38 61 66 76 115 159 127 74 142 91 196 102 157 87
+        146 88 212 151 174 163 111 198 6 254 126 212 171 167 182
+        166 169 24 144 2 50 57 62 156 208 151 236 120 165 106 206
+        132 248 59 209 94 38 135 22 165 116 100 87 219 133 80 70 49
+        138 180 58 43 73 68 189 154 226 52 220 241 182 23 35 56 160
+        58 34 72 173 250 58 47 54 209 225 129 24 247 207 173 79 186
+        31 77 16 218 248 219 67 25 6 226 42 13 203 224 242 236 123
+        167 216 226 13 203 26 128 188 231 57 255 0 26 95 212 86 203
+        14 38 0 224 17 188 125 42 75 20 6 20 41 26 240 252 40 164
+        186 234 187 174 24 60 133 78 89 87 218 149 187 209 148 221
+        236 138 245 22 157 60 140 183 218 74 1 34 249 247 204 160
+        162 241 142 213 79 245 47 72 111 89 117 61 99 84 182 187
+        158 103 33 174 166 206 10 255 0 42 133 245 251 213 175 213
+        218 164 50 217 172 77 44 214 192 54 8 65 153 36 250 40 165
+        235 164 216 95 233 145 223 73 17 140 91 201 143 195 177 220
+        227 244 236 198 173 6 250 55 37 118 206 124 181 232 213 212
+        181 136 196 118 238 246 80 74 54 160 1 90 97 239 159 229
+        171 3 81 179 134 222 91 125 63 77 88 108 247 70 21 97 132
+        238 43 245 53 45 120 119 180 159 135 218 145 202 124 24 230
+        10 1 96 59 138 144 116 239 76 219 104 202 250 174 165 4 101
+        194 238 201 94 91 218 157 201 213 11 26 91 162 47 209 221
+        26 52 117 23 55 18 44 146 183 32 241 146 126 181 97 105 233
+        20 118 239 243 120 107 243 2 121 52 161 18 107 251 179 117
+        35 164 17 70 249 66 107 125 213 247 138 230 59 119 1 148
+        224 149 236 106 118 51 105 187 99 27 235 207 20 237 133 85
+        51 237 90 163 140 144 27 36 55 175 214 176 176 141 3 171 57
+        220 128 242 222 212 213 32 181 101 44 179 99 53 59 41 141
+        241 20 200 230 41 119 134 56 245 197 31 105 121 29 194 42
+        177 193 3 134 254 42 198 107 120 2 16 178 100 251 210 153
+        213 161 184 13 20 228 145 243 173 50 86 9 53 123 50 234 11
+        11 107 132 41 134 60 99 35 4 255 0 125 85 157 71 210 82 232
+        87 15 123 4 237 225 49 203 32 28 15 92 241 86 153 120 245
+        40 4 33 140 12 220 54 239 152 214 173 37 225 148 75 165 223
+        70 178 197 38 80 59 12 213 185 19 139 75 225 77 117 119 76
+        218 117 23 78 199 47 225 99 146 248 121 146 242 54 243 3
+        252 172 191 245 164 29 51 210 246 205 122 209 95 27 104 110
+        162 249 76 132 248 83 143 117 43 87 61 247 76 54 135 118
+        243 89 248 81 68 91 43 159 95 113 205 124 211 116 235 59
+        199 54 23 81 195 110 249 202 133 64 54 122 231 39 248 104
+        114 98 73 236 91 209 125 35 169 105 98 107 75 29 66 7 178
+        150 60 155 57 0 59 121 244 39 154 176 161 130 56 45 161 131
+        240 242 36 164 237 44 221 179 244 168 206 172 145 216 106
+        169 111 43 77 19 68 121 184 135 229 199 250 223 79 168 169
+        93 165 218 234 150 209 172 106 222 64 48 87 215 30 166 167
+        40 219 177 137 5 164 77 225 36 102 48 236 7 36 210 254 160
+        178 221 27 70 208 171 41 249 151 210 159 105 140 205 10 22
+        12 209 109 192 217 232 126 191 90 251 119 110 165 6 236 183
+        213 187 209 72 45 183 217 69 183 75 195 125 121 61 155 100
+        5 30 184 205 115 207 198 174 155 151 68 213 222 32 25 161
+        83 228 98 7 34 186 207 88 181 139 79 234 23 149 155 247 220
+        10 163 255 0 202 41 80 99 115 120 135 178 3 252 67 6 155 28
+        147 208 117 84 202 79 164 121 159 185 198 123 26 153 3 129
+        233 81 14 155 253 250 152 252 188 224 129 233 82 233 50 23
+        235 76 227 178 79 197 31 83 243 62 113 147 239 69 69 10 17
+        207 56 237 66 70 234 20 224 115 68 71 56 0 125 120 167 197
+        209 141 160 49 250 250 86 74 25 125 43 234 28 14 56 205 101
+        147 239 84 48 155 89 82 249 46 54 159 165 109 209 219 49
+        125 171 29 96 150 206 121 226 190 232 192 180 71 21 140 53
+        145 153 136 192 29 168 109 70 54 253 151 120 205 192 54 207
+        255 0 45 18 119 46 57 244 172 117 94 116 59 175 253 179 255
+        0 202 107 24 142 89 51 27 24 6 15 238 146 183 163 13 224
+        100 103 53 170 197 15 224 160 237 251 164 175 174 140 178
+        175 110 245 199 99 146 109 59 247 127 173 22 85 73 60 208
+        90 110 68 32 159 122 34 114 206 190 203 233 142 245 117 29
+        89 39 221 16 158 179 54 177 220 6 150 54 101 29 212 54 9
+        253 107 111 65 52 119 55 208 199 14 159 167 164 123 191 120
+        209 111 147 191 189 1 214 76 222 33 221 130 113 71 252 41
+        88 255 0 104 199 36 165 130 171 100 227 214 150 79 84 58
+        126 71 78 217 170 67 162 91 71 31 38 76 42 17 235 86 191 71
+        218 226 40 183 157 227 104 3 30 245 85 116 252 107 47 224
+        147 147 26 121 176 106 212 209 200 68 130 221 153 131 103
+        118 229 237 138 136 242 236 147 52 74 210 101 92 7 94 113
+        81 206 163 180 146 65 45 212 115 0 66 224 212 170 13 172 85
+        149 148 48 60 230 163 157 92 118 146 241 130 177 200 118 96
+        251 227 63 244 167 125 0 170 250 146 107 143 26 41 174 154
+        105 32 81 183 100 67 37 142 104 141 62 226 225 44 37 156
+        192 167 127 149 93 184 194 251 154 34 85 150 107 205 145
+        176 9 27 121 178 56 175 107 55 45 34 236 114 145 219 47 4
+        142 9 164 10 179 239 79 89 193 97 27 94 77 34 162 47 152 51
+        30 13 9 170 235 147 234 243 24 80 18 177 156 130 61 69 71
+        239 239 159 88 188 88 85 21 45 226 60 5 39 154 51 80 158
+        223 65 182 73 37 184 54 225 70 230 4 14 70 59 81 76 106 190
+        198 23 55 145 91 233 127 141 105 132 48 198 48 238 199 3
+        255 0 154 174 58 155 227 6 147 167 135 139 69 183 123 233
+        84 238 241 230 249 11 85 101 241 47 174 53 30 162 190 154
+        40 100 123 125 56 54 216 237 225 111 46 51 220 253 106 53
+        162 195 249 223 155 143 15 235 70 43 147 7 137 100 15 139
+        93 115 122 210 203 111 115 4 1 223 248 98 193 3 233 91 224
+        235 142 190 159 44 117 201 23 112 254 17 66 244 246 143 9
+        132 58 170 159 165 53 93 29 113 226 5 35 43 144 0 167 81
+        127 161 185 68 15 255 0 212 47 136 86 174 118 234 178 76 23
+        130 28 113 138 249 167 124 105 234 91 59 198 143 87 180 181
+        188 182 99 229 35 190 62 148 116 154 76 126 31 238 219 44
+        57 200 168 119 85 233 118 246 170 74 40 12 79 4 246 20 90
+        111 224 27 139 46 222 152 235 237 19 169 151 109 140 198
+        218 240 156 61 180 237 134 79 246 126 181 34 212 21 229 41
+        26 161 241 147 204 8 244 250 215 29 239 158 206 100 158 41
+        36 142 88 206 229 120 216 130 167 220 123 213 223 240 171
+        175 165 212 172 19 76 214 36 205 194 174 216 238 9 229 135
+        177 164 118 129 73 244 93 58 63 80 195 169 35 105 23 135
+        108 177 46 6 238 198 129 182 183 146 199 89 146 65 27 74
+        210 38 207 15 196 194 129 244 164 122 189 171 181 132 55 80
+        183 134 20 238 18 47 175 222 138 210 117 111 218 67 240 247
+        18 5 184 78 3 10 91 12 83 110 168 207 85 150 225 110 90 222
+        68 144 6 95 202 42 60 195 234 79 173 72 186 125 111 38 252
+        53 180 146 166 118 124 222 189 251 26 213 115 190 234 201 0
+        88 214 88 142 85 241 233 68 116 235 184 34 119 145 222 69
+        109 187 113 253 244 108 220 75 31 72 181 120 160 48 25 4
+        128 12 144 43 116 176 199 248 15 13 99 98 8 230 182 105 222
+        91 96 164 129 43 97 183 30 216 199 106 209 172 188 98 216
+        198 172 195 234 180 91 36 221 58 43 158 186 142 72 46 32
+        154 67 149 13 159 189 85 31 25 237 148 233 226 85 240 156
+        21 220 168 235 184 30 61 69 91 221 94 127 21 104 95 4 140
+        121 126 149 89 245 117 172 87 90 116 126 59 200 27 105 92
+        142 64 21 37 26 118 91 134 172 230 221 62 226 221 53 16 143
+        103 28 110 78 73 133 246 47 255 0 230 164 55 238 134 37 218
+        70 61 57 165 29 89 165 92 104 218 195 188 136 230 34 124
+        178 122 99 222 178 134 224 188 74 172 114 64 239 86 82 100
+        166 188 67 34 108 46 115 69 71 38 229 238 41 100 47 199 122
+        54 221 129 166 140 184 137 45 58 24 219 252 167 62 245 183
+        156 103 210 180 68 234 171 94 150 96 20 14 106 139 34 97 0
+        213 121 25 29 141 124 210 37 111 8 166 59 26 245 243 6 77
+        163 248 123 159 122 195 70 238 212 121 196 195 144 196 247
+        21 163 84 35 246 77 208 245 17 57 63 109 180 65 27 87 60 80
+        154 145 255 0 203 111 127 246 207 254 24 173 206 38 21 233
+        188 216 219 159 254 146 127 133 110 4 9 121 25 161 108 37
+        85 177 183 95 85 140 110 250 226 136 143 243 36 7 208 26
+        228 41 30 199 214 25 240 78 71 173 109 150 64 16 143 95 65
+        239 88 90 16 109 248 227 28 86 139 146 119 231 60 142 213
+        107 124 73 201 121 16 206 172 95 26 80 23 191 175 210 166
+        191 9 186 121 141 170 220 180 51 57 39 129 129 239 222 144
+        217 105 82 234 218 199 131 179 11 184 110 53 209 157 23 211
+        214 182 122 44 81 201 48 241 182 0 61 49 74 24 251 14 122
+        66 214 229 94 48 208 133 80 63 139 189 88 90 72 96 192 54
+        56 236 105 7 78 88 164 31 52 129 163 94 88 231 204 79 181
+        74 32 134 75 123 116 196 68 156 118 110 226 145 143 46 198
+        179 58 65 18 179 74 219 207 112 59 84 115 170 46 217 180
+        249 95 121 44 62 81 237 245 251 209 183 119 81 180 108 184
+        238 42 25 212 90 162 174 228 102 93 157 155 119 96 41 152
+        42 207 186 29 184 107 71 154 87 35 185 99 238 106 35 214 90
+        132 78 5 157 187 22 99 232 41 157 222 169 44 26 83 52 101
+        76 44 48 54 118 53 26 208 109 228 190 214 33 145 162 12 12
+        152 25 246 164 47 12 111 76 155 124 53 233 149 16 45 197
+        218 110 64 114 115 235 84 239 199 221 101 78 177 123 102
+        140 26 56 188 160 102 186 123 67 179 75 123 51 101 8 13 193
+        12 127 147 235 92 107 241 198 27 139 126 176 212 98 152 146
+        230 124 159 246 105 148 28 132 134 68 242 52 200 12 48 44
+        118 198 237 149 195 183 37 15 202 62 213 165 53 63 1 131 60
+        39 195 251 84 155 168 46 180 217 180 109 62 218 212 51 92
+        54 12 161 7 205 247 165 87 82 89 54 159 36 87 22 142 140 62
+        94 59 85 34 168 156 161 110 209 97 124 56 215 45 245 8 28
+        170 12 227 145 237 86 5 215 225 226 75 113 12 108 254 77
+        217 110 56 170 35 225 13 243 91 235 38 53 243 161 111 238
+        171 123 169 245 84 91 139 104 17 137 65 24 17 253 15 181
+        116 66 105 160 113 67 109 70 91 88 173 214 118 0 239 5 72
+        81 218 169 78 186 234 56 127 27 45 154 167 136 55 144 49
+        222 173 110 160 212 29 58 101 228 42 5 202 198 66 12 122
+        123 215 62 233 243 164 250 255 0 141 116 60 92 49 242 142
+        237 247 161 55 72 220 80 93 188 222 50 8 230 132 164 141
+        199 110 5 49 209 255 0 242 221 97 24 23 216 28 40 223 199
+        127 181 107 189 186 73 119 50 219 202 189 176 224 114 121
+        166 125 93 62 159 113 248 25 172 29 213 196 65 164 200 238
+        213 12 177 114 141 153 73 69 209 212 95 8 26 223 168 186 54
+        104 166 219 35 68 72 81 246 21 27 234 77 54 125 23 88 18
+        236 216 132 242 69 51 255 0 37 139 27 166 208 175 174 74
+        150 141 66 149 95 114 123 212 179 226 94 151 227 217 181
+        196 42 36 98 114 19 249 126 149 25 174 40 188 50 46 64 61
+        45 117 107 170 89 51 69 38 14 57 7 189 109 179 111 194 245
+        10 13 196 46 60 195 211 25 168 15 76 222 92 88 234 70 5 5
+        73 60 113 145 82 150 213 51 126 143 112 34 19 99 128 135
+        119 30 249 255 0 165 104 116 52 210 79 69 167 109 119 185
+        17 22 66 87 119 13 235 138 35 83 11 140 198 229 199 166 106
+        45 162 220 120 138 36 207 25 230 164 81 75 226 40 88 227
+        223 143 74 214 115 53 228 70 181 136 157 225 117 141 64 227
+        133 53 93 235 150 179 52 130 23 132 62 14 0 95 191 173 90
+        250 196 56 152 49 219 150 249 75 118 6 161 215 246 48 139
+        215 146 105 24 130 48 71 240 211 36 55 39 209 207 127 20 33
+        179 180 212 101 79 6 102 89 24 46 201 62 82 113 220 84 6 88
+        22 44 52 44 206 159 94 226 174 175 140 58 47 137 104 38 179
+        101 148 71 150 81 184 6 83 244 205 83 54 30 42 72 232 246
+        243 3 159 48 200 110 126 244 64 246 104 220 241 131 186 137
+        182 184 64 57 110 107 102 161 110 172 9 141 65 30 254 212
+        166 104 218 35 156 253 42 148 128 210 100 129 46 99 63 197
+        95 39 148 99 200 115 72 34 149 193 201 99 138 221 248 229
+        67 207 106 87 20 128 208 222 233 129 143 30 222 190 245 142
+        151 235 247 165 175 125 226 2 84 226 143 210 100 5 194 255
+        0 53 40 7 133 191 44 80 90 144 206 153 122 114 127 171 61
+        109 150 224 46 87 219 138 26 250 101 109 34 233 189 225 112
+        126 213 168 70 221 137 52 247 111 194 91 140 28 136 249 166
+        118 114 121 192 160 116 224 166 24 71 111 203 163 173 194
+        248 234 5 98 204 146 89 170 152 115 187 239 66 223 99 5 148
+        225 63 157 62 106 105 99 25 48 42 199 183 39 190 104 203
+        189 29 230 179 1 21 83 112 249 143 111 238 172 37 48 14 133
+        210 188 109 107 241 144 164 50 46 209 151 99 130 13 116 78
+        131 56 158 218 20 150 81 189 80 13 158 131 235 85 223 195
+        94 156 59 143 226 99 12 217 225 135 21 108 90 233 166 36 79
+        10 30 0 239 88 172 152 218 198 23 133 149 225 96 185 238
+        126 148 254 207 12 187 34 137 143 243 63 165 35 182 146 88
+        80 35 67 128 79 239 15 240 253 41 148 55 50 71 3 198 155
+        223 63 59 227 185 250 86 20 246 175 9 49 238 137 75 194 7
+        14 59 26 171 122 185 101 146 252 170 221 70 138 79 57 171
+        19 90 190 184 150 223 207 136 198 60 160 85 91 173 91 79
+        121 123 35 126 42 20 85 57 229 143 253 169 39 236 52 59 21
+        95 71 52 120 85 189 141 19 24 193 61 254 181 38 232 109 62
+        56 84 95 120 139 52 177 12 70 23 208 251 210 8 45 33 102 62
+        35 69 113 183 143 43 28 138 150 244 28 129 53 1 12 177 109
+        133 56 69 30 223 90 89 71 145 87 58 90 44 222 153 135 108
+        45 112 24 137 64 59 200 35 39 138 160 63 202 143 164 236
+        110 35 77 90 16 177 220 71 31 157 207 118 63 203 255 0 95
+        210 186 59 76 240 101 45 113 224 67 10 200 219 34 218 152
+        57 168 199 95 116 226 234 154 109 212 19 66 158 32 207 206
+        14 8 193 237 93 81 141 66 145 199 109 202 217 193 218 38
+        143 125 172 92 206 182 82 120 115 194 3 167 250 199 216 81
+        186 229 182 179 114 195 76 184 142 52 153 64 252 208 57 63
+        83 79 238 108 238 58 51 172 102 142 72 93 32 119 36 100 119
+        25 197 72 174 109 109 245 43 132 213 172 128 119 83 202 159
+        81 83 166 116 173 171 43 142 148 209 167 210 53 87 186 109
+        225 20 130 8 29 254 212 255 0 168 117 88 99 189 18 151 121
+        75 184 112 15 163 10 115 169 205 104 214 160 109 219 47 168
+        3 24 168 70 191 34 35 161 50 198 74 190 79 218 171 23 76 95
+        199 68 203 87 214 37 213 236 26 53 97 28 146 199 220 255 0
+        102 42 186 135 166 111 237 101 123 191 50 170 19 133 35 150
+        251 84 183 68 104 4 177 177 98 112 6 125 170 84 82 27 248
+        197 189 188 97 156 253 56 169 202 77 176 113 118 65 83 78
+        215 58 130 206 36 216 150 214 208 121 188 131 131 250 210
+        254 157 210 219 80 215 226 210 252 97 8 241 48 197 189 106
+        194 214 117 11 77 19 76 125 54 215 30 57 82 9 28 3 79 255 0
+        201 219 162 228 212 181 51 171 222 70 35 241 27 10 204 14
+        59 131 237 70 9 216 217 101 20 182 116 135 194 61 10 223 71
+        233 107 107 59 21 100 11 15 159 61 137 250 208 157 71 12 97
+        154 215 143 1 137 222 171 83 13 26 218 43 88 139 75 108 35
+        139 110 197 57 225 143 189 38 234 185 161 181 211 101 183
+        48 140 177 224 142 226 182 98 56 211 178 137 234 75 3 103
+        126 235 13 210 69 179 144 73 173 130 222 67 20 99 241 145
+        191 102 220 13 27 168 199 28 215 18 77 53 184 93 195 130 79
+        106 16 88 52 155 213 111 32 12 167 182 227 255 0 106 132
+        186 59 155 209 97 116 84 108 85 3 72 36 56 192 34 167 80 70
+        200 128 172 81 179 175 24 61 234 176 232 167 154 223 242
+        154 101 45 191 131 159 165 88 208 95 93 44 106 165 81 128
+        31 50 250 211 199 212 228 105 169 108 211 171 31 16 177 142
+        51 27 145 202 159 74 142 94 195 25 140 200 192 22 94 114 87
+        52 250 250 105 35 117 104 83 45 234 27 185 165 119 214 183
+        19 184 62 25 85 110 227 183 52 76 85 255 0 17 132 154 166
+        147 37 186 248 46 20 21 7 110 222 125 170 129 155 79 252 60
+        230 39 32 182 79 145 107 171 122 135 68 142 75 86 221 25 92
+        100 146 59 26 162 186 143 167 38 135 88 220 138 165 119 28
+        30 107 24 133 203 14 207 44 159 150 79 240 175 99 75 110 45
+        85 216 243 83 62 164 210 229 135 108 166 18 138 125 248 34
+        163 110 129 92 228 86 17 232 71 37 152 0 226 130 158 215
+        239 82 48 136 202 124 190 180 37 197 190 92 129 142 244 105
+        152 143 205 19 33 242 127 109 63 233 213 252 149 242 146
+        217 228 214 155 139 85 10 78 40 189 15 8 59 113 154 120 166
+        96 249 147 50 29 220 26 211 168 68 19 72 186 62 190 11 147
+        246 162 174 15 230 134 247 21 167 84 255 0 50 221 55 24 107
+        119 24 162 97 14 159 36 102 218 32 205 180 248 116 198 213
+        226 87 83 188 147 154 81 107 167 220 53 140 18 7 35 242 249
+        163 44 237 37 105 17 119 28 131 147 82 28 156 233 82 143 18
+        49 232 69 79 180 187 75 121 32 92 220 73 28 184 249 68 69
+        133 65 186 106 197 231 158 36 49 201 38 61 87 210 174 190
+        145 211 94 68 137 95 195 66 171 140 177 231 245 172 97 191
+        72 233 106 109 6 103 93 195 186 142 230 167 58 110 155 149
+        2 36 4 1 146 204 199 138 15 167 44 108 128 241 124 25 230
+        127 226 240 71 203 82 107 123 49 34 172 113 248 241 71 156
+        226 65 131 88 87 42 6 22 110 1 241 219 196 92 121 84 129
+        138 211 5 149 227 238 88 149 84 19 252 93 170 65 111 103
+        146 84 149 104 151 251 65 172 166 82 241 42 66 205 41 31
+        194 220 17 253 148 44 28 209 92 245 109 181 212 113 110 220
+        74 129 192 30 181 84 206 151 127 141 151 198 194 3 192 4
+        213 229 213 154 108 146 218 14 114 49 230 95 229 174 127
+        235 72 166 211 53 41 87 12 242 147 223 39 129 83 156 188
+        139 225 142 218 26 233 208 201 11 157 171 16 82 114 78 78
+        106 95 211 141 17 148 180 69 153 211 137 31 248 84 253 106
+        187 210 229 27 98 154 234 102 10 87 29 253 106 99 211 247
+        50 71 229 137 138 237 243 73 143 226 31 90 220 138 100 73
+        45 23 31 79 177 184 177 104 84 141 225 195 120 141 198 71
+        208 83 253 66 55 75 114 242 175 137 43 240 0 25 207 21 16
+        233 137 18 107 104 217 110 11 55 0 15 166 123 84 230 250
+        120 225 136 200 204 200 137 128 8 25 197 118 65 218 60 188
+        146 119 163 156 190 49 244 36 186 173 171 92 181 143 225
+        228 44 85 153 187 143 94 42 128 158 223 90 233 105 158 56
+        219 198 133 143 215 143 181 117 247 196 9 154 123 217 165
+        105 34 104 200 206 194 249 195 127 241 84 31 89 91 238 184
+        157 99 133 30 82 55 40 29 143 214 169 197 23 199 41 112 162
+        186 185 214 103 186 102 123 219 95 57 239 33 24 3 251 42 61
+        172 120 51 36 69 109 119 3 47 206 61 78 15 21 33 184 142
+        230 221 222 9 70 84 15 54 125 169 116 176 205 24 93 141 132
+        241 6 6 59 26 159 17 249 72 198 214 241 98 108 27 117 4 224
+        149 92 211 111 252 65 168 64 98 75 43 87 17 129 229 44 56
+        199 233 205 3 107 110 99 99 52 152 50 150 56 99 237 154 123
+        211 176 77 38 160 37 101 223 31 177 237 70 43 246 110 82 10
+        232 190 141 212 53 205 71 241 87 143 28 140 88 121 125 43
+        171 254 26 232 50 233 22 137 111 248 16 144 42 133 223 142
+        9 170 163 225 212 126 10 143 13 109 192 115 128 31 230 253
+        42 249 232 235 223 11 77 134 25 36 73 90 110 236 15 57 166
+        215 194 25 174 84 55 189 178 97 21 188 74 235 225 15 54 210
+        121 53 5 235 9 86 234 105 118 131 187 119 150 33 243 84 243
+        168 21 134 153 148 145 35 216 255 0 49 238 56 170 163 172
+        110 246 221 148 183 185 203 147 193 90 134 99 163 9 14 213
+        90 57 49 224 176 111 230 87 226 144 79 4 139 52 147 43 196
+        140 253 129 124 12 209 122 205 212 6 227 198 110 1 242 103
+        63 197 239 81 141 94 238 226 25 194 40 87 70 244 127 81 244
+        174 103 45 29 138 28 145 48 233 15 198 27 192 146 18 27 119
+        163 2 63 76 85 189 164 89 221 73 26 42 185 200 28 131 85
+        191 195 29 42 75 141 146 194 172 24 159 144 255 0 15 30 149
+        113 233 150 55 16 170 135 252 206 60 210 123 85 99 234 114
+        229 146 230 1 29 155 9 135 226 87 9 252 254 162 190 157 54
+        73 150 76 206 179 156 121 119 112 64 253 42 68 34 23 10 4
+        109 226 159 76 208 151 54 110 238 87 196 43 32 237 232 7
+        222 137 62 104 132 107 26 118 99 219 226 136 152 14 121 205
+        86 125 99 167 175 237 5 105 110 23 96 62 102 65 87 101 229
+        188 101 30 59 139 121 159 159 51 70 50 13 67 181 253 46 209
+        204 177 194 198 53 217 156 74 7 6 176 201 217 68 117 172 48
+        8 222 72 228 50 38 223 33 116 108 230 160 19 129 180 62 59
+        174 113 87 71 94 233 47 38 158 234 139 184 43 97 86 169 187
+        184 158 34 241 200 48 85 138 129 236 43 2 74 221 128 250
+        103 222 176 101 39 229 25 53 159 210 179 135 230 170 115 85
+        64 52 201 22 80 150 24 56 161 172 78 217 8 0 119 166 23 142
+        190 27 113 233 75 237 10 155 130 2 253 105 224 237 24 105
+        58 110 10 223 74 18 255 0 63 178 110 193 244 129 218 143
+        149 149 99 11 142 72 160 117 31 243 85 217 61 204 78 15 218
+        131 236 193 186 90 198 116 139 76 50 159 232 201 254 21 240
+        8 214 109 220 18 57 24 165 154 124 231 246 109 170 238 218
+        22 221 20 215 212 185 118 155 195 29 189 234 35 147 62 151
+        185 63 180 227 85 109 196 243 145 232 125 170 240 233 87
+        154 98 130 117 42 224 113 159 90 231 254 159 141 77 220 110
+        210 109 243 14 213 208 95 13 174 45 209 81 90 100 44 23 203
+        187 146 127 178 177 139 91 167 68 45 106 163 233 147 24 238
+        194 164 246 194 223 193 93 177 201 193 236 190 159 122 65
+        161 25 226 95 204 138 16 51 198 79 27 105 254 159 226 186
+        121 152 39 60 39 253 105 146 178 13 219 8 84 102 112 4 112
+        237 246 207 52 108 80 71 23 155 240 209 243 245 175 145 32
+        81 150 82 62 181 181 229 80 128 114 126 212 234 128 38 234
+        59 17 121 1 113 181 118 131 149 240 176 107 157 254 36 105
+        145 172 225 132 94 57 82 119 47 168 174 150 190 241 164 6
+        72 31 195 35 212 142 106 176 235 237 5 174 124 86 101 12
+        216 221 187 24 57 164 156 20 138 96 157 62 69 19 13 184 134
+        214 71 243 120 132 102 52 147 248 105 222 141 61 221 194
+        172 215 18 131 50 12 125 90 134 154 19 103 168 120 18 237
+        96 217 0 125 104 103 241 173 101 252 106 134 27 79 111 74
+        229 105 166 119 57 114 90 45 126 140 184 86 180 102 55 40 8
+        237 205 78 191 31 60 86 95 135 107 229 220 190 111 47 36
+        241 242 213 27 163 234 202 176 41 241 140 81 191 112 123
+        211 185 186 180 219 217 198 209 221 168 144 143 56 99 206
+        43 167 30 95 140 228 201 141 223 67 62 185 190 0 22 88 89
+        78 194 89 166 24 85 62 245 68 234 173 20 200 146 120 151 15
+        39 140 216 192 249 177 223 21 100 234 93 81 167 222 233 242
+        121 135 138 27 206 9 24 97 75 172 109 244 123 201 222 118
+        186 72 146 21 59 6 6 11 55 106 235 82 137 57 41 69 21 69
+        244 107 60 211 93 169 222 178 249 75 55 4 26 2 230 55 93
+        145 140 130 91 129 142 245 120 75 240 222 29 147 220 75 118
+        30 222 100 81 28 157 134 226 70 72 166 215 191 0 76 154 124
+        23 81 107 2 210 70 149 7 157 187 131 233 218 133 196 73 100
+        226 172 231 200 35 12 21 130 144 9 218 51 234 105 173 147
+        53 180 47 106 237 55 154 81 38 213 29 143 181 92 250 183
+        193 155 93 2 226 207 241 55 27 217 230 97 184 158 15 181 0
+        157 15 107 160 194 127 107 93 71 0 157 155 135 97 207 177
+        173 113 30 18 114 86 36 232 155 166 181 212 229 142 20 15
+        143 149 27 248 143 181 95 61 33 125 178 213 99 141 94 2 163
+        115 73 32 242 131 237 84 149 189 254 147 167 202 177 171
+        167 138 174 4 135 0 227 235 82 24 186 206 56 238 36 138 210
+        113 176 227 37 143 31 165 36 164 146 26 172 183 53 139 233
+        37 145 47 13 228 65 72 33 147 61 170 172 234 89 213 239 76
+        97 195 43 49 243 10 217 127 212 139 61 152 48 202 93 149
+        124 192 17 222 162 154 181 244 173 190 4 254 177 41 201 39
+        176 251 87 62 73 166 138 98 139 176 77 70 226 105 110 227
+        128 248 50 89 41 255 0 238 31 106 9 108 115 118 169 36 98
+        88 216 249 95 209 13 31 102 134 210 220 137 35 60 142 239
+        220 83 222 137 209 164 212 174 195 188 108 235 158 0 251
+        215 53 72 232 121 20 116 139 19 225 174 154 190 12 107 17
+        119 219 130 199 244 255 0 10 182 236 213 161 183 40 171 147
+        237 81 142 150 210 174 172 237 217 18 40 227 82 0 5 187 212
+        174 22 216 118 158 113 234 59 26 234 132 93 108 243 231 92
+        172 209 53 180 127 188 240 78 87 156 30 213 161 217 164 25
+        154 48 24 118 49 242 113 76 193 89 99 56 237 67 205 20 120
+        199 202 125 13 55 16 8 111 196 76 140 161 37 39 25 203 14
+        213 1 234 117 1 164 101 229 74 96 55 189 88 23 183 19 70
+        204 138 137 142 217 62 181 21 215 72 134 54 150 70 183 84
+        245 221 158 63 186 183 18 176 119 162 142 235 107 139 179
+        101 112 48 74 131 149 250 213 55 169 21 153 101 109 195 118
+        226 49 87 143 197 11 59 89 172 228 240 238 163 86 11 193 86
+        242 213 7 168 41 183 153 227 13 189 119 119 20 133 31 26 4
+        138 53 225 183 114 56 162 35 249 141 99 16 93 166 190 134
+        10 199 218 177 51 11 207 221 183 218 128 179 230 224 227
+        154 97 117 242 31 181 45 179 202 206 87 215 189 82 14 145
+        135 197 65 136 103 142 40 13 74 48 116 219 220 28 255 0 70
+        122 48 73 249 67 52 22 160 196 88 93 242 60 240 56 20 89
+        132 246 173 33 176 131 211 242 147 181 25 98 164 202 55 122
+        241 90 172 99 38 202 223 63 232 146 141 137 10 48 53 33 195
+        237 36 17 76 55 59 140 28 241 86 191 194 221 82 71 187 85
+        134 86 137 241 229 144 138 169 145 73 66 203 220 28 154 150
+        252 57 214 154 199 83 71 134 72 163 97 235 39 106 198 58
+        223 67 121 30 205 68 246 178 34 103 201 57 60 49 250 84 166
+        202 250 59 114 171 42 153 28 140 2 7 97 80 110 157 214 5
+        238 147 18 27 150 57 60 113 156 126 149 55 208 161 152 66
+        38 143 136 200 198 120 57 63 173 89 164 186 57 199 169 35
+        72 23 119 0 142 213 189 35 81 233 199 181 13 8 118 33 179
+        192 224 209 101 148 32 227 154 6 62 50 174 119 99 129 233
+        74 122 130 205 110 173 152 236 11 246 29 233 163 72 161 114
+        71 21 131 48 145 10 178 239 83 233 237 65 179 45 20 167 88
+        244 52 211 91 27 203 104 80 178 18 119 122 231 218 171 11
+        187 123 200 110 31 78 189 93 162 67 243 123 87 79 107 176
+        53 157 147 186 43 75 17 238 139 232 125 234 136 248 146 177
+        73 114 100 84 96 155 185 13 195 126 181 25 70 203 225 156
+        147 164 35 210 116 152 166 184 16 52 171 42 149 202 236 247
+        170 207 226 54 139 175 105 90 204 242 61 196 190 11 28 198
+        83 149 219 237 83 222 151 214 197 133 218 194 100 240 225
+        249 67 96 114 61 170 196 212 52 152 117 189 17 90 56 209
+        212 12 238 35 56 21 60 77 73 157 83 132 226 185 72 228 251
+        45 112 139 146 26 86 59 20 134 4 156 22 162 52 205 98 226
+        222 203 242 166 62 57 186 18 54 227 193 3 211 237 83 78 185
+        248 112 99 190 184 149 45 13 188 32 231 116 125 152 213 121
+        169 104 183 182 101 130 238 0 252 153 238 5 116 62 206 120
+        228 82 123 39 58 151 88 245 117 197 134 159 165 75 124 86
+        218 24 205 202 70 184 218 7 177 53 60 215 254 43 117 237
+        199 75 232 182 247 182 18 89 199 225 44 214 243 173 187 21
+        184 10 123 130 51 199 189 115 249 107 184 36 221 151 221
+        141 188 156 241 237 82 109 7 226 31 89 104 177 71 109 109
+        172 94 4 130 217 160 129 50 8 138 54 238 160 17 218 154 133
+        88 87 254 139 31 226 175 196 126 181 234 43 13 48 94 88 61
+        132 70 63 26 222 88 247 33 125 191 196 51 233 144 106 29
+        212 157 103 212 58 189 165 140 186 165 244 83 35 32 88 176
+        131 32 47 114 126 181 19 213 186 147 168 117 153 33 159 81
+        212 174 238 154 217 12 80 120 178 110 240 211 249 71 211
+        147 66 44 55 19 90 71 181 75 159 155 25 236 115 90 135 73
+        46 221 140 238 53 67 251 78 238 95 20 178 77 146 50 121 205
+        104 210 245 75 139 217 34 181 134 232 137 3 16 192 3 154 47
+        67 232 251 173 64 201 227 187 71 35 225 148 14 248 207 106
+        185 62 27 244 16 178 195 61 132 105 48 148 18 242 96 22 95
+        214 132 163 171 4 230 170 162 7 208 29 47 125 30 141 53 238
+        172 242 178 203 251 188 30 64 199 253 232 177 103 28 123
+        100 241 137 149 120 84 110 199 239 83 126 177 191 182 208
+        237 37 183 143 116 44 56 85 36 55 24 244 170 238 202 83 123
+        118 94 66 67 19 148 106 228 116 203 168 73 18 94 153 233
+        253 83 95 144 76 202 76 46 112 163 31 227 87 31 73 116 153
+        210 204 49 204 170 14 1 194 210 111 135 23 11 20 34 8 35
+        145 159 56 201 3 21 104 90 90 27 93 175 36 126 35 176 206
+        242 79 31 74 233 199 7 86 206 60 143 97 118 241 133 77 187
+        118 129 233 239 91 90 53 199 28 125 171 21 155 60 50 225
+        171 238 252 119 170 217 42 53 58 136 187 51 42 250 129 65
+        234 23 94 12 69 100 143 35 221 123 138 60 149 151 229 20 27
+        169 71 219 252 62 223 90 1 35 215 115 43 40 113 32 251 55
+        124 84 47 171 100 186 49 179 184 154 201 65 231 124 91 149
+        170 85 173 98 202 233 252 103 42 224 121 152 199 145 223
+        251 170 186 248 147 214 183 90 125 177 91 107 171 105 7 250
+        223 246 53 138 68 162 190 47 107 186 95 138 214 49 248 190
+        48 28 73 25 198 223 211 181 87 209 0 214 161 139 51 100 247
+        110 244 87 94 106 67 88 234 55 186 240 194 31 92 113 154 14
+        73 213 85 87 233 82 4 244 244 124 133 130 190 211 235 68 52
+        89 229 73 52 2 183 155 121 163 109 174 50 160 131 233 88 17
+        102 171 131 149 35 233 75 163 27 110 179 76 238 20 96 210
+        213 254 179 85 198 149 14 54 149 179 26 231 142 61 41 102
+        163 41 252 21 194 142 194 39 166 50 168 48 131 244 165 151
+        202 63 5 63 251 167 162 251 17 183 102 122 48 63 179 160
+        224 254 233 43 126 71 137 143 90 203 72 79 252 174 220 129
+        222 36 197 18 45 198 75 17 81 101 227 217 227 251 146 61 77
+        15 111 122 246 87 65 149 118 227 187 30 213 235 171 133 141
+        128 57 237 90 226 219 121 34 110 71 40 7 56 28 154 186 143
+        40 137 47 99 167 126 4 117 157 174 161 167 172 63 153 44
+        136 120 24 171 231 78 212 65 81 225 218 249 118 231 115 28
+        0 107 144 190 28 89 173 188 130 77 54 89 34 32 231 105 56
+        39 237 138 178 180 238 161 234 84 87 102 17 76 136 48 6 9
+        199 215 154 14 60 65 197 51 163 45 102 103 1 100 216 170
+        121 5 78 69 99 169 220 54 192 163 201 236 199 214 170 77 11
+        171 245 39 17 71 112 168 23 28 248 35 183 223 62 181 53 209
+        175 226 185 45 33 153 131 255 0 44 188 98 164 251 19 36 117
+        72 147 192 159 42 72 164 38 120 62 244 112 27 80 5 35 111
+        160 165 118 19 120 142 1 96 223 202 1 230 152 44 168 80 110
+        202 243 142 105 211 64 173 30 154 21 153 25 100 25 82 48 69
+        84 255 0 18 122 82 19 35 155 101 32 179 100 10 183 3 46 56
+        96 104 109 66 202 27 200 240 200 140 222 153 173 40 218 27
+        28 169 232 228 91 238 152 186 91 147 43 63 135 20 71 60 142
+        255 0 74 125 211 93 69 117 98 88 93 200 22 221 92 4 207 160
+        171 91 173 250 76 108 150 72 227 80 51 187 143 106 165 250
+        146 41 68 141 111 29 187 8 213 253 185 205 113 188 124 37
+        103 124 36 178 42 147 44 121 46 108 53 205 177 220 69 249
+        108 155 65 247 250 212 119 170 190 23 217 155 104 37 134
+        225 10 63 203 143 240 164 218 37 252 214 58 188 112 204 228
+        64 202 48 79 189 89 90 93 253 188 177 237 89 214 103 253
+        214 210 123 15 113 245 170 71 43 229 103 52 177 46 52 138
+        27 93 248 99 116 151 210 44 86 251 160 69 196 44 163 211
+        220 84 30 247 64 107 107 182 140 171 56 31 46 7 173 118 133
+        237 180 90 149 144 93 194 54 141 118 57 42 57 250 138 137
+        106 125 33 167 197 120 100 88 86 104 216 96 101 107 174 50
+        199 37 105 28 235 179 155 116 14 140 186 212 193 240 55 51
+        49 206 208 188 226 167 125 55 240 195 54 203 45 210 186 72
+        143 198 70 55 15 122 186 52 46 153 179 177 138 55 182 217
+        20 217 228 99 140 83 173 90 104 225 84 141 97 141 86 49 134
+        36 96 181 53 165 234 138 37 201 144 171 110 135 210 116 79
+        10 226 121 20 205 225 229 4 124 130 107 238 173 212 150 246
+        54 203 105 24 72 156 55 151 216 241 254 53 171 169 181 136
+        109 237 36 219 112 30 68 114 145 166 114 77 87 147 73 121
+        168 91 139 182 87 46 210 121 71 176 174 73 101 116 209 214
+        176 213 51 45 96 106 26 245 227 195 122 216 99 204 45 232 5
+        54 233 30 147 152 202 177 205 147 199 3 20 227 163 244 134
+        213 30 40 228 140 164 138 70 25 187 26 185 250 111 167 99
+        183 132 60 209 70 37 3 154 92 80 79 108 76 217 56 233 25
+        116 63 79 219 217 233 161 221 79 138 125 79 165 74 23 229
+        25 227 28 115 88 194 137 12 33 19 140 119 175 179 58 38 55
+        56 31 90 233 163 142 105 182 99 58 163 46 230 96 160 118
+        165 215 146 52 67 197 102 150 48 222 168 51 69 207 44 126
+        25 60 176 250 14 212 174 246 96 84 171 178 178 5 200 32 240
+        69 103 163 40 114 26 137 15 135 230 81 199 203 187 179 80
+        83 95 73 202 136 33 56 255 0 91 154 134 235 29 68 108 99 48
+        219 9 166 0 124 199 24 63 110 106 11 172 117 110 189 53 203
+        197 225 196 233 140 169 112 114 181 135 88 210 44 46 168
+        215 33 143 79 157 228 73 85 84 16 222 249 250 87 37 124 96
+        235 11 91 205 78 75 11 75 153 21 131 19 137 70 56 171 39 86
+        212 53 237 70 57 32 188 185 82 161 14 28 13 187 87 254 188
+        213 69 213 58 29 188 241 201 42 67 113 123 118 92 225 136 0
+        99 251 107 112 79 232 106 136 45 172 37 228 105 14 112 123
+        31 122 33 161 221 231 60 55 108 125 40 217 99 104 81 97 112
+        145 183 177 239 65 22 96 73 244 237 74 218 163 27 60 53 9
+        206 43 43 104 195 112 57 172 21 183 33 251 215 212 98 157
+        142 13 32 12 175 65 7 145 74 155 137 197 57 148 111 83 187
+        154 73 38 127 24 71 165 60 69 147 25 187 226 49 142 120 165
+        247 103 117 189 217 247 183 113 250 209 172 165 163 31 106
+        22 244 40 211 231 199 205 225 62 105 133 25 233 30 109 42
+        213 113 140 198 159 225 154 57 216 44 44 48 59 119 160 52
+        103 85 211 44 148 142 76 8 127 93 180 85 196 171 225 242 42
+        71 74 116 70 181 2 242 94 14 113 199 97 247 169 87 65 219
+        36 215 177 195 40 220 8 228 47 113 253 180 141 109 252 107
+        213 37 60 184 239 237 83 174 143 211 149 39 87 0 110 35 200
+        195 131 138 180 102 170 137 190 236 187 58 103 166 236 35
+        48 52 114 32 24 221 133 249 170 91 107 165 194 210 5 148 4
+        24 192 56 168 247 77 204 176 89 68 222 55 138 83 229 76 14
+        126 149 52 209 238 55 145 226 76 129 217 126 87 3 129 90 82
+        85 70 74 194 44 116 24 227 153 78 119 103 182 208 48 71 214
+        155 92 104 236 214 174 17 76 111 252 203 220 211 109 38 72
+        100 140 6 240 164 218 118 249 123 230 152 203 11 109 9 28
+        140 152 244 32 100 84 69 110 136 158 149 251 66 218 111 194
+        218 184 47 158 78 114 5 72 45 159 86 128 156 172 114 40 93
+        204 199 57 253 41 93 196 81 199 127 137 15 131 38 120 34
+        155 219 106 64 58 195 28 121 80 57 111 115 72 60 23 137 178
+        29 74 89 38 86 154 45 171 252 195 176 251 209 173 121 8 5
+        150 64 9 249 72 245 173 55 48 174 4 182 234 178 49 30 104
+        207 111 191 222 180 189 188 19 219 238 145 124 39 95 238
+        166 78 76 87 75 160 203 219 113 121 98 20 190 254 57 35 214
+        161 183 93 11 13 220 146 220 54 84 224 236 80 7 38 165 58
+        35 53 189 185 93 199 104 244 166 73 134 1 135 108 230 179
+        175 160 230 215 69 41 170 244 5 221 179 37 204 176 248 171
+        17 59 84 14 231 235 81 248 244 109 67 78 159 196 11 34 144
+        251 184 245 174 141 101 220 140 49 201 239 154 73 168 104
+        208 238 105 240 173 207 153 113 72 240 193 236 172 103 162
+        162 147 168 46 237 252 56 132 78 217 143 156 131 205 101
+        107 212 23 37 89 165 134 70 77 222 78 15 53 53 189 211 108
+        154 225 166 107 120 194 42 144 191 65 65 219 221 104 214 54
+        107 248 235 88 252 36 82 219 206 125 234 111 148 53 101 249
+        127 194 40 122 138 227 204 86 41 3 231 142 15 106 211 125
+        123 169 234 176 162 109 146 54 3 146 163 189 74 236 166 211
+        53 75 176 109 97 70 129 135 151 138 145 105 90 109 177 111
+        195 248 9 145 242 253 41 146 151 105 153 78 190 21 78 149
+        210 55 151 72 200 33 98 31 141 199 146 15 189 75 116 79 135
+        114 8 209 111 35 196 123 118 140 119 31 90 179 52 205 54 27
+        24 246 140 125 168 227 207 113 84 73 62 200 203 249 18 122
+        100 95 167 186 102 29 46 97 225 64 133 23 213 187 231 222
+        164 83 203 28 108 25 164 31 111 122 251 43 108 224 71 147
+        239 154 80 109 218 109 77 228 152 17 30 121 25 239 77 72
+        156 83 126 193 247 23 107 26 144 60 205 232 40 24 111 174
+        166 111 14 8 145 142 78 75 103 138 222 87 50 5 130 208 2 59
+        190 79 21 153 11 103 110 207 18 6 62 173 236 105 28 218 10
+        236 85 123 38 178 45 252 88 165 81 144 67 32 30 148 134 222
+        198 235 80 184 114 210 22 10 249 108 30 62 195 233 79 46 46
+        86 123 98 100 102 137 7 30 94 228 214 26 28 69 220 52 56 95
+        109 180 109 181 108 51 175 245 23 221 104 208 203 25 13 31
+        229 129 194 251 210 27 221 6 56 84 182 239 46 120 12 163 2
+        172 115 20 110 160 110 19 183 169 110 21 62 216 168 230 179
+        52 101 156 43 64 138 157 234 170 104 69 127 74 251 80 209
+        225 184 180 144 51 194 168 14 15 166 106 191 234 221 39 75
+        179 211 165 184 146 21 154 112 126 84 98 23 245 171 39 87
+        185 202 186 49 71 82 114 25 71 106 174 122 230 37 156 40 50
+        77 55 180 64 0 15 246 86 228 53 20 87 81 74 130 251 153 35
+        67 39 101 143 36 99 238 104 9 50 234 54 142 213 35 235 13
+        19 195 45 36 96 65 27 252 170 57 231 245 168 229 186 201 20
+        4 73 195 103 24 247 20 128 122 116 122 47 148 253 235 9 178
+        172 72 247 172 226 32 3 159 122 215 63 53 128 213 133 195
+        34 136 200 60 253 233 61 209 254 151 156 12 102 155 69 26
+        176 198 222 244 166 249 130 92 5 250 211 196 70 168 105 11
+        47 131 230 224 80 87 255 0 212 238 63 221 191 248 86 208
+        219 160 3 210 133 190 99 248 41 249 255 0 210 122 167 17 92
+        141 118 127 137 253 159 1 207 30 18 86 196 51 186 156 182
+        87 212 211 13 50 12 216 64 27 31 186 76 140 246 162 217 225
+        136 120 123 80 41 224 115 206 106 40 232 98 43 123 241 111
+        55 242 128 113 147 235 86 7 70 235 76 246 230 31 197 68 140
+        195 200 164 237 96 62 135 214 163 182 90 28 218 158 99 130
+        221 164 59 178 0 198 15 235 239 83 110 151 232 9 102 141 45
+        238 237 102 138 39 28 156 252 191 98 41 210 160 39 68 255 0
+        165 250 138 212 58 193 170 73 178 233 134 228 73 134 1 30
+        245 97 104 186 198 154 206 169 103 118 214 236 71 158 25
+        198 232 228 63 70 244 168 62 133 208 169 21 164 118 179 70
+        211 148 27 99 71 200 199 234 65 53 34 178 233 77 74 194 47
+        232 114 58 143 68 151 133 31 99 89 171 11 157 178 203 176
+        99 185 30 56 210 54 198 74 171 102 50 61 193 247 166 203
+        120 56 63 32 61 188 78 23 244 53 94 105 26 213 214 151 34
+        65 172 88 220 66 190 147 198 165 215 63 92 122 84 202 206
+        234 75 168 188 68 219 34 158 79 151 1 190 191 74 70 19 118
+        187 11 222 67 44 177 177 18 6 220 184 239 75 186 90 250 71
+        102 183 153 124 225 176 64 244 250 211 153 97 142 226 50
+        193 164 82 7 96 188 138 91 106 39 134 247 250 138 202 231
+        141 231 130 71 181 35 84 131 21 240 154 167 49 34 238 13
+        199 24 160 103 45 29 214 214 82 84 247 241 56 81 69 217 110
+        49 40 48 52 89 28 140 19 254 21 246 250 214 73 151 104 141
+        217 125 8 28 212 219 108 77 38 107 71 120 216 109 66 69 16
+        38 82 128 134 28 156 80 86 73 58 66 99 117 124 158 57 70
+        255 0 181 100 201 60 78 89 81 153 49 200 8 114 63 186 130
+        116 48 99 44 138 63 45 178 123 226 132 186 185 120 226 220
+        97 102 63 196 69 97 52 178 170 171 68 178 242 57 204 109
+        255 0 106 85 169 92 92 179 21 69 112 185 231 32 138 22 195
+        24 41 50 63 213 151 154 140 182 87 118 246 208 73 27 225
+        138 101 126 149 203 122 183 93 117 30 165 38 161 167 94 204
+        208 248 19 164 109 30 48 78 61 8 174 179 185 188 189 92 25
+        97 105 87 248 252 157 197 85 223 17 250 3 72 234 125 66 13
+        98 214 217 180 157 71 112 23 37 99 32 78 61 73 24 239 79 39
+        25 157 120 230 177 233 171 1 248 55 105 213 17 233 144 222
+        220 248 50 217 52 132 194 7 204 23 255 0 154 187 244 141 66
+        229 131 52 208 177 193 218 131 28 154 143 104 115 197 97
+        103 13 142 159 96 237 28 40 168 143 225 156 240 63 252 52
+        217 46 47 152 134 48 50 182 253 196 178 145 71 81 68 114 91
+        118 137 97 184 157 190 85 49 159 102 172 252 67 180 110 96
+        88 154 77 109 119 50 219 170 24 228 45 252 71 109 24 101
+        102 64 162 57 11 247 225 73 197 73 79 147 209 37 141 160
+        167 186 40 14 197 220 115 130 7 165 7 113 54 223 48 243 159
+        85 126 194 182 71 11 42 110 109 229 255 0 216 108 127 133
+        105 72 101 150 243 196 145 88 133 236 2 54 15 247 83 59 176
+        85 5 105 241 55 134 93 243 188 118 52 46 171 34 67 3 185
+        145 93 199 101 3 36 83 68 142 84 92 172 100 125 233 38 189
+        36 203 4 135 240 108 231 30 163 138 165 94 128 145 12 135
+        241 90 158 160 99 86 111 12 54 91 105 201 21 39 134 85 183
+        137 98 82 177 198 6 60 79 251 82 189 46 217 152 134 104 12
+        1 142 78 208 114 104 235 213 217 228 142 57 60 188 6 101
+        237 246 166 173 81 154 62 94 77 44 150 225 83 42 23 213 199
+        155 244 21 29 213 174 34 181 133 247 220 69 1 3 45 52 190
+        103 31 65 255 0 106 47 91 215 45 44 81 252 95 21 220 29 171
+        26 33 44 199 219 21 16 190 126 161 214 8 240 109 13 165 190
+        237 202 146 99 113 250 241 154 41 1 161 62 179 175 104 240
+        69 36 239 49 42 23 205 52 173 134 99 238 61 170 187 215 53
+        233 37 34 230 214 241 150 215 186 60 131 195 76 125 9 239
+        86 14 163 209 114 73 40 146 238 54 109 195 45 189 72 254
+        193 138 135 117 47 195 150 190 148 93 78 178 76 35 253 216
+        201 217 143 246 79 21 130 138 135 172 58 169 217 198 39 142
+        64 252 43 3 197 34 211 238 191 16 134 70 238 220 131 232 69
+        75 117 206 133 188 138 228 205 37 140 174 15 206 242 112
+        168 61 197 71 36 129 44 93 193 85 69 221 181 85 152 3 143
+        240 166 143 96 146 189 131 187 237 63 74 196 29 195 53 186
+        102 73 6 236 167 232 192 255 0 133 106 85 227 140 99 239 79
+        45 128 38 30 212 162 251 139 174 120 230 156 64 8 250 15
+        189 1 168 70 11 124 188 147 223 35 20 189 9 35 116 37 90
+        223 5 128 29 243 65 234 18 255 0 67 184 255 0 116 244 90 41
+        16 1 142 195 222 151 106 24 252 61 194 110 27 188 54 227 61
+        179 78 165 162 110 34 139 47 220 55 251 165 160 238 251 175
+        251 85 234 245 73 118 116 190 131 109 63 174 219 83 53 253
+        234 126 181 234 245 80 80 139 143 222 15 189 122 95 221 143
+        189 122 189 88 198 235 207 234 95 253 163 252 107 86 155
+        251 179 246 175 87 169 31 209 144 77 191 121 255 0 217 173
+        49 127 90 95 246 133 122 189 74 198 143 99 214 236 104 22
+        253 243 125 235 213 234 148 69 126 198 211 251 197 175 79
+        251 179 94 175 80 8 60 191 187 95 181 100 191 184 74 245
+        122 153 244 62 46 204 26 180 183 239 79 218 189 94 166 47
+        30 205 144 126 248 81 147 250 215 171 213 136 100 236 244
+        63 45 125 184 253 239 255 0 109 122 189 80 143 177 51 91
+        252 181 157 167 205 94 175 85 95 208 154 161 175 147 126
+        234 111 246 63 235 94 175 83 46 204 129 173 191 131 237 91
+        117 15 221 138 245 122 156 192 58 215 249 246 111 247 149
+        242 127 221 39 251 85 234 245 17 88 116 223 212 135 218 148
+        220 254 224 87 171 212 16 77 109 253 105 105 76 159 214 222
+        189 94 162 140 205 87 255 0 50 255 0 179 88 71 242 10 245
+        122 156 64 133 253 217 161 174 254 85 255 0 106 189 94 165
+        125 139 35 47 253 58 105 99 253 68 255 0 186 175 87 168 174
+        133 63 255 217 13 10 45 45 45 45 45 45 87 101 98 75 105 116
+        70 111 114 109 66 111 117 110 100 97 114 121 74 57 98 119
+        65 87 115 51 121 110 112 113 115 72 53 75 13 10 67 111 110
+        116 101 110 116 45 68 105 115 112 111 115 105 116 105 111
+        110 58 32 102 111 114 109 45 100 97 116 97 59 32 110 97 109
+        101 61 34 102 105 108 101 50 34 59 32 102 105 108 101 110
+        97 109 101 61 34 116 101 115 116 46 116 120 116 34 13 10 67
+        111 110 116 101 110 116 45 84 121 112 101 58 32 116 101 120
+        116 47 112 108 97 105 110 13 10 13 10 116 101 115 116 10 13
+        10 45 45 45 45 45 45 87 101 98 75 105 116 70 111 114 109 66
+        111 117 110 100 97 114 121 74 57 98 119 65 87 115 51 121
+        110 112 113 115 72 53 75 13 10 67 111 110 116 101 110 116
+        45 68 105 115 112 111 115 105 116 105 111 110 58 32 102 111
+        114 109 45 100 97 116 97 59 32 110 97 109 101 61 34 102 105
+        108 101 51 34 59 32 102 105 108 101 110 97 109 101 61 34 34
+        13 10 13 10 13 10 45 45 45 45 45 45 87 101 98 75 105 116 70
+        111 114 109 66 111 117 110 100 97 114 121 74 57 98 119 65
+        87 115 51 121 110 112 113 115 72 53 75 45 45 13 10
+    } ;
 
-[ { "a" "a" f f "b" f f "c" f f "d" f f } ] [
-    [
-        "aazzbzzczzdzz" <string-reader> "z" <multipart-stream> 1 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
-
-[ { "aa" f f "b" f f "c" f f "d" f f } ] [
-    [
-        "aazzbzzczzdzz" <string-reader> "z" <multipart-stream> 2 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
-
-[ { "aa" f f "b" f f "c" f f "d" f f } ] [
-    [
-        "aazzbzzczzdzz" <string-reader> "z" <multipart-stream> 3 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
-
-[ { "aa" f f "b" f f "c" f f "d" f f } ] [
-    [
-        "aazzbzzczzdzz" <string-reader> "z" <multipart-stream> 4 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
-
-[ { "aa" f f "b" f f "c" f f "d" f f } ] [
-    [
-        "aazzbzzczzdzz" <string-reader> "z" <multipart-stream> 5 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
-
-
-
-[ { "a" f "b" f "c" f "d" f } ] [
-    [
-        "azzbzzczzdzz" <string-reader> "zz" <multipart-stream> 1 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
-
-[ { "a" "z" "z" "b" "z" "z" "c" "z" "z" "d" "zz" } ] [
-    [
-        "azzbzzczzdzz" <string-reader> "zzz" <multipart-stream> 1 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
-
-[ { "a" "z" "z" "b" "z" "z" "c" "z" "z" "d" f } ] [
-    [
-        "azzbzzczzdzzz" <string-reader> "zzz" <multipart-stream> 1 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
-
-[ { "az" "zb" "zz" "cz" "zd" f } ] [
-    [
-        "azzbzzczzdzzz" <string-reader> "zzz" <multipart-stream> 2 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
+: dog-test-empty-bytes-firefox ( -- bytes )
+    B{
+        45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45
+        45 45 45 45 45 45 45 45 45 49 49 51 55 53 50 50 53 48 51 49
+        52 52 49 50 56 50 51 50 55 49 54 53 51 49 55 50 57 13 10 67
+        111 110 116 101 110 116 45 68 105 115 112 111 115 105 116
+        105 111 110 58 32 102 111 114 109 45 100 97 116 97 59 32
+        110 97 109 101 61 34 102 105 108 101 49 34 59 32 102 105
+        108 101 110 97 109 101 61 34 100 111 103 46 106 112 103 34
+        13 10 67 111 110 116 101 110 116 45 84 121 112 101 58 32
+        105 109 97 103 101 47 106 112 101 103 13 10 13 10 255 216
+        255 224 0 16 74 70 73 70 0 1 1 0 0 1 0 1 0 0 255 219 0 67 0
+        5 3 4 4 4 3 5 4 4 4 5 5 5 6 7 12 8 7 7 7 7 15 11 11 9 12 17
+        15 18 18 17 15 17 17 19 22 28 23 19 20 26 21 17 17 24 33 24
+        26 29 29 31 31 31 19 23 34 36 34 30 36 28 30 31 30 255 219
+        0 67 1 5 5 5 7 6 7 14 8 8 14 30 20 17 20 30 30 30 30 30 30
+        30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
+        30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
+        30 30 30 30 255 192 0 17 8 1 49 1 64 3 1 34 0 2 17 1 3 17 1
+        255 196 0 29 0 0 2 2 3 1 1 1 0 0 0 0 0 0 0 0 0 4 5 6 7 2 3
+        8 0 1 9 255 196 0 74 16 0 2 1 3 3 2 4 4 3 4 5 10 5 3 5 1 1
+        2 3 0 4 17 5 18 33 6 49 19 34 65 81 7 50 97 113 20 35 129
+        21 51 66 82 36 52 145 161 177 8 53 83 98 114 115 147 178
+        193 209 22 37 67 116 241 99 130 240 23 68 84 100 146 225
+        255 196 0 25 1 0 3 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 2 3 0 4 5
+        255 196 0 39 17 0 2 2 2 2 3 0 2 1 5 1 0 0 0 0 0 0 1 2 17 3
+        33 18 49 34 50 65 19 81 4 5 20 35 66 97 82 255 218 0 12 3 1
+        0 2 17 3 17 0 63 0 228 200 149 136 219 131 200 207 233 68
+        196 145 112 60 21 45 234 91 181 57 177 178 138 75 56 95 111
+        152 196 51 250 209 11 167 198 14 118 138 22 138 153 104 150
+        118 82 46 217 45 161 98 79 242 102 157 38 151 98 174 64 211
+        237 72 247 49 46 104 11 8 140 111 229 247 166 194 70 137 12
+        146 112 61 235 57 36 172 31 82 7 154 199 78 244 176 178 255
+        0 132 41 100 195 76 15 183 240 118 60 31 244 85 237 126 241
+        237 237 157 213 176 113 197 66 158 254 234 82 74 49 45 187
+        144 42 49 155 158 217 108 152 99 21 68 214 88 116 217 83 17
+        218 218 171 250 109 138 180 254 6 221 83 205 109 1 199 115
+        225 10 141 90 106 23 106 187 95 59 73 239 237 77 44 111 89
+        79 136 24 186 250 131 235 86 199 166 71 143 20 52 181 211
+        237 24 143 232 150 236 61 140 66 155 65 167 233 251 64 252
+        5 158 127 221 45 3 99 42 220 42 186 240 79 247 83 139 38 86
+        92 21 57 20 76 246 140 78 155 98 88 31 217 246 125 191 209
+        45 108 253 159 97 255 0 240 44 255 0 225 45 22 216 200 199
+        181 99 88 74 98 77 99 78 178 69 111 14 194 213 23 28 226 48
+        15 246 212 30 242 21 252 105 8 145 170 103 178 213 137 172
+        121 162 127 181 87 151 141 182 247 31 235 210 180 216 209
+        28 88 217 219 120 99 250 52 100 255 0 172 155 168 248 108
+        109 11 103 240 208 127 194 173 118 82 71 225 47 148 246 163
+        11 169 30 74 81 140 102 182 178 35 203 97 104 62 162 46 104
+        41 45 109 119 127 86 131 254 21 48 144 225 9 198 104 105
+        198 24 118 53 76 77 81 141 73 105 109 143 234 176 127 193
+        21 146 89 219 110 63 209 97 255 0 131 69 65 183 110 15 39
+        218 182 144 160 159 41 6 169 102 5 22 54 138 114 109 45 216
+        123 24 184 53 177 45 44 137 231 79 179 237 254 138 179 118
+        101 112 167 159 181 102 131 140 212 35 236 99 95 224 172
+        119 143 252 190 207 254 21 18 186 125 129 92 254 2 207 254
+        16 172 15 148 230 182 71 46 225 198 106 178 78 204 40 213
+        237 109 83 33 45 224 237 223 195 199 247 214 189 30 222 222
+        69 45 37 165 187 156 227 12 161 177 245 230 143 214 212 8
+        75 123 138 15 69 96 7 220 214 159 169 135 31 129 177 192
+        198 159 102 120 255 0 68 181 240 216 217 12 15 217 214 156
+        246 252 165 230 137 139 205 235 128 7 204 123 80 183 154
+        148 118 202 66 225 156 118 62 148 169 174 38 91 55 193 167
+        233 191 60 214 22 96 14 249 137 107 84 199 69 137 246 174
+        157 100 255 0 65 18 210 43 237 82 105 148 188 108 64 254 31
+        102 164 243 223 204 146 249 155 39 233 73 38 50 84 137 156
+        112 233 19 200 4 118 54 201 238 22 33 68 54 153 166 52 96
+        173 149 163 15 115 16 205 66 244 189 77 141 226 40 115 143
+        90 155 91 73 192 116 245 29 141 77 233 140 177 169 46 64
+        109 167 88 45 203 31 217 246 92 127 244 171 19 97 99 226 16
+        218 125 152 227 63 186 20 100 204 56 247 245 175 66 84 145
+        191 147 235 246 174 140 125 18 180 125 183 211 108 72 7 246
+        125 158 63 221 45 109 151 77 177 219 254 111 179 255 0 132
+        180 68 76 163 133 206 51 197 103 43 0 184 166 158 144 72
+        133 244 54 113 220 5 91 120 50 59 254 77 7 120 109 188 48
+        22 8 1 207 242 98 152 106 170 191 137 45 239 218 149 93 41
+        97 129 239 73 97 143 96 19 172 103 204 161 23 232 181 164
+        71 152 93 143 173 110 117 101 67 90 142 239 195 55 165 97
+        229 251 37 122 124 138 182 48 118 253 210 81 66 116 250 82
+        123 2 205 103 108 55 30 99 31 221 218 140 134 63 56 221 200
+        169 147 26 90 229 159 56 20 109 242 171 89 16 217 251 80
+        214 190 80 49 197 110 212 63 168 147 234 107 74 62 44 166
+        36 156 209 17 234 235 140 193 26 170 182 230 227 21 40 248
+        113 208 240 234 214 169 53 194 224 63 166 57 168 167 85 55
+        136 34 5 87 126 124 170 123 26 233 15 129 214 42 221 59 108
+        123 112 51 27 14 223 90 142 61 68 233 206 227 249 58 35 7
+        224 252 57 252 133 141 91 25 82 71 24 255 0 189 44 212 254
+        21 222 99 16 171 120 139 234 160 97 171 165 99 81 143 5 145
+        74 142 199 29 171 239 225 99 121 138 149 80 127 133 241 205
+        22 229 96 121 19 84 145 199 250 231 77 106 61 62 210 25 35
+        114 189 212 1 198 43 237 133 210 72 71 24 56 228 125 107
+        167 186 179 163 236 245 93 61 149 35 76 148 42 43 154 186
+        195 167 175 58 123 85 149 9 37 67 103 63 74 117 39 123 37
+        151 26 110 226 20 14 64 53 246 132 211 174 22 234 21 216
+        217 111 83 69 22 80 72 197 89 245 103 61 238 128 117 60 155
+        121 15 174 218 174 239 8 23 141 158 251 170 192 213 36 219
+        11 175 169 28 85 123 169 237 93 64 240 57 52 99 32 142 45
+        89 191 15 229 231 154 46 201 155 60 214 141 48 43 69 141
+        163 24 162 109 227 61 199 21 57 118 96 244 57 92 227 52 43
+        198 219 143 126 244 68 18 3 88 202 172 141 134 108 147 205
+        8 107 64 62 65 223 145 131 239 91 25 188 199 39 38 181 163
+        99 191 122 250 112 199 118 59 213 83 160 114 54 59 46 211
+        239 89 39 203 90 93 89 88 115 197 110 64 74 113 83 138 169
+        5 59 62 183 35 214 189 16 193 197 124 109 202 123 154 251
+        19 13 199 35 38 170 242 69 62 194 105 214 255 0 171 138 85
+        166 169 82 204 164 237 60 103 235 77 181 129 226 66 184 98
+        163 220 82 155 73 24 202 45 34 81 201 239 75 44 138 141 7
+        114 72 110 146 203 36 73 12 42 207 150 193 197 73 52 191
+        135 215 186 168 241 220 180 113 177 206 49 200 90 153 124
+        40 248 122 110 151 241 183 65 66 12 48 207 191 189 94 54
+        186 61 165 156 94 28 123 10 149 10 78 59 138 231 109 252 58
+        163 8 163 159 236 254 19 73 53 176 86 80 176 175 171 1 197
+        107 185 248 77 101 105 103 51 204 187 36 199 24 25 39 255 0
+        249 93 18 176 195 18 157 177 168 30 212 191 85 132 201 109
+        39 134 138 204 227 110 8 160 175 232 210 227 196 226 14 170
+        210 27 66 215 60 46 54 110 5 72 31 227 82 141 57 214 72 145
+        137 198 64 237 70 127 148 13 146 219 107 208 145 150 5 240
+        91 211 245 165 58 75 237 130 48 72 36 47 117 237 71 39 113
+        4 23 248 216 202 224 96 100 114 107 24 148 183 126 62 213
+        182 101 57 231 145 89 70 6 7 2 174 221 35 133 71 102 248 84
+        40 245 172 110 57 38 182 175 3 140 86 19 1 142 194 145 182
+        199 34 250 129 197 226 100 241 154 211 52 121 77 194 182
+        234 67 117 238 223 236 162 150 17 248 81 218 138 116 52 72
+        228 225 183 246 21 241 148 126 30 79 76 46 234 62 234 16 27
+        181 7 34 55 135 55 63 250 116 232 210 118 168 117 167 172
+        127 132 183 220 224 15 13 127 187 189 16 10 135 194 144 69
+        43 176 144 155 88 23 212 71 70 32 110 251 129 165 170 25 99
+        99 139 78 127 182 179 213 220 199 167 141 190 86 35 191 189
+        42 241 228 132 174 50 65 246 162 53 9 89 172 227 221 158
+        212 178 151 139 54 61 100 68 118 241 86 227 89 182 132 121
+        247 72 1 2 186 187 225 157 184 131 70 182 143 28 162 128
+        203 234 167 235 92 181 211 246 87 23 221 92 145 198 173 133
+        144 121 192 249 107 170 250 103 242 236 35 241 147 194 157
+        84 6 99 252 85 36 169 34 249 98 229 34 100 89 89 139 43 6
+        97 192 35 211 233 95 94 86 17 2 199 56 238 105 119 226 188
+        171 223 183 39 222 190 27 172 16 95 113 79 95 173 16 199 30
+        134 246 242 11 133 60 242 59 212 75 226 103 77 91 235 58
+        101 204 138 159 154 145 147 145 235 78 97 152 171 248 145
+        200 10 31 65 222 138 155 100 200 21 178 222 167 29 171 5 87
+        211 144 110 214 109 31 80 240 36 111 32 39 57 244 57 237 77
+        224 152 92 69 226 174 49 142 126 149 105 124 86 232 27 125
+        70 22 187 178 132 9 2 229 177 247 53 76 66 38 209 181 65
+        109 48 111 8 156 18 123 81 229 20 170 201 101 196 253 163
+        208 94 161 14 251 105 27 217 106 189 213 20 11 226 125 51
+        138 177 181 70 205 153 104 249 87 28 85 117 117 253 117 247
+        251 241 84 87 240 231 26 233 108 192 5 3 131 77 145 78 243
+        74 180 213 193 7 138 115 18 229 137 172 227 33 27 48 183 64
+        24 26 202 126 13 108 140 169 242 142 9 236 79 106 26 92 150
+        228 250 209 140 93 140 124 254 48 107 34 195 39 154 215 255
+        0 231 122 247 191 253 234 188 65 196 223 27 151 24 144 101
+        253 40 152 179 130 49 233 90 109 85 29 124 217 163 226 218
+        19 28 98 163 123 176 165 64 46 219 13 122 22 223 39 28 147
+        216 86 219 133 4 19 90 1 240 161 50 28 131 252 52 91 131
+        219 55 144 62 189 56 91 68 133 88 110 245 30 213 37 248 49
+        210 178 106 58 188 51 73 144 138 119 19 233 140 208 189 61
+        210 211 245 12 232 193 79 204 57 32 226 186 51 161 250 90
+        195 65 211 161 138 8 255 0 51 104 46 125 106 115 146 78 145
+        124 17 113 143 146 37 26 85 188 122 109 132 113 68 184 96
+        49 159 165 125 185 185 85 59 90 64 119 124 198 180 205 43 5
+        43 156 31 79 181 10 178 36 44 26 70 222 205 223 30 148 165
+        210 177 139 150 149 10 227 98 142 192 250 214 155 147 253
+        28 199 177 88 122 238 244 250 208 171 52 155 134 88 98 133
+        150 237 164 36 46 112 15 53 129 56 190 145 65 255 0 148 77
+        158 235 69 153 118 182 199 218 54 118 239 154 175 116 73 72
+        181 129 135 204 203 218 174 31 142 22 18 234 26 36 203 2 72
+        21 60 229 64 253 225 207 106 165 244 67 38 194 37 36 178
+        240 51 90 91 175 248 104 234 13 18 169 228 221 230 127 46
+        43 5 151 196 228 214 55 127 186 221 238 43 85 187 100 227
+        158 213 94 71 20 180 232 103 23 43 197 125 145 84 168 201
+        230 176 135 182 43 100 156 40 165 9 22 212 144 45 249 247
+        163 161 254 174 40 93 79 157 67 62 153 166 22 234 166 1 197
+        96 53 98 235 149 12 167 222 147 234 3 242 102 81 220 71 82
+        41 99 12 59 129 74 117 91 114 45 167 117 31 250 103 251 169
+        148 140 129 45 55 44 17 99 253 29 23 12 204 28 6 3 20 20 19
+        127 71 139 159 253 42 223 28 129 136 7 156 154 103 208 255
+        0 153 177 205 170 120 204 3 12 12 240 69 111 213 199 134
+        145 66 163 36 143 90 246 154 141 148 231 143 74 203 89 138
+        67 123 11 6 57 199 21 63 134 139 243 68 211 224 110 159 102
+        218 140 243 189 188 178 60 152 249 192 192 171 213 173 128
+        140 176 141 15 25 193 244 168 39 193 43 63 15 79 19 76 7
+        140 199 206 184 171 30 250 50 146 43 42 228 48 193 168 219
+        163 177 55 200 71 226 254 97 228 140 28 99 210 183 69 117
+        30 226 31 105 30 222 148 46 161 152 75 141 229 148 156 226
+        149 60 140 70 248 137 80 189 241 75 143 34 186 101 158 54
+        201 25 102 241 55 70 35 3 216 118 162 108 39 87 144 66 242
+        108 61 243 239 244 168 180 119 82 49 253 233 136 123 10 206
+        207 82 89 36 88 174 150 38 195 121 37 76 247 250 213 123 36
+        224 214 201 204 169 20 145 60 61 148 240 72 245 170 127 227
+        23 70 172 150 134 226 214 223 107 103 141 130 173 155 70 86
+        183 66 28 179 3 250 26 58 242 194 43 232 66 92 66 187 79
+        189 115 201 108 56 230 163 105 156 115 105 60 208 196 214
+        23 80 148 145 71 5 135 122 132 235 145 201 29 249 42 188 22
+        245 174 164 248 151 240 207 198 70 212 45 21 81 145 142 204
+        10 160 186 163 71 154 222 77 183 49 8 157 84 246 254 35 239
+        93 112 206 180 145 203 60 93 201 116 37 211 39 10 0 126 41
+        220 119 81 1 144 213 22 120 174 35 92 237 226 135 146 250
+        234 33 235 143 65 87 228 217 13 50 87 226 199 254 144 126
+        149 245 166 141 200 243 10 133 46 162 232 115 146 72 172
+        206 175 41 238 191 223 67 147 9 51 12 132 227 114 214 82
+        120 106 56 113 80 209 170 72 88 5 76 31 189 20 215 178 152
+        212 149 201 197 50 102 37 118 211 195 242 150 227 222 140
+        18 71 129 181 137 168 84 119 151 1 73 197 49 180 191 153
+        148 110 200 199 106 231 250 104 246 74 29 148 174 230 227
+        29 177 89 232 58 77 246 183 172 195 20 112 177 141 125 135
+        6 153 244 151 75 234 157 65 36 113 136 241 9 0 230 186 15
+        162 250 19 79 208 225 79 42 25 145 130 183 31 74 76 146 138
+        71 84 49 211 183 209 143 68 244 245 174 149 167 6 252 56 86
+        28 246 169 45 207 130 182 134 66 222 30 61 187 214 251 192
+        182 235 26 15 40 39 210 144 107 247 22 176 249 46 37 36 124
+        193 127 155 233 83 91 118 86 172 214 151 14 236 220 228 103
+        130 222 213 147 204 138 164 48 86 39 185 168 228 218 149
+        196 206 56 17 91 129 133 81 243 17 88 53 227 180 137 28 114
+        56 92 122 247 170 27 241 177 225 187 24 231 251 171 43 85
+        241 50 170 14 15 36 154 87 109 34 151 27 134 121 167 54 108
+        225 129 12 118 251 82 185 168 151 112 226 129 250 130 194
+        222 77 30 118 120 247 237 140 250 122 215 48 107 54 169 103
+        169 201 224 163 129 188 240 195 138 235 187 203 101 109 50
+        82 205 130 227 143 181 115 71 197 11 55 183 214 228 88 219
+        17 239 224 1 244 162 157 171 57 102 252 68 107 48 54 234 27
+        24 175 68 15 114 49 158 213 166 218 19 37 160 207 38 140
+        137 120 10 220 145 86 198 173 108 227 123 9 130 182 203 218
+        181 195 216 240 59 214 215 70 49 131 73 244 196 91 80 99
+        248 197 62 230 152 193 145 111 145 75 245 24 207 226 147
+        159 90 109 103 31 244 97 158 115 84 140 28 140 40 184 185
+        117 148 100 12 118 173 183 172 143 165 92 48 193 34 39 175
+        186 149 168 14 24 142 49 64 220 201 183 78 157 87 129 225
+        61 43 84 232 196 94 55 155 195 207 134 216 61 168 155 89
+        101 241 16 108 61 232 168 236 220 219 161 11 198 208 223
+        219 91 173 172 157 100 86 32 119 166 109 80 30 201 95 79
+        166 228 30 245 150 187 129 127 18 255 0 101 110 209 23 195
+        43 246 175 107 136 5 253 171 30 119 29 181 54 44 125 209
+        127 252 28 119 147 73 72 230 142 40 215 60 31 122 156 223
+        199 182 38 200 192 3 32 212 119 225 21 138 174 131 12 155
+        67 115 220 84 183 91 141 148 97 89 64 199 32 251 84 228 244
+        119 67 216 175 53 163 38 215 30 25 199 112 213 29 69 63 48
+        152 73 159 65 233 83 13 65 48 37 1 124 167 249 170 55 61
+        169 40 20 109 200 254 90 129 218 4 247 78 190 70 24 83 220
+        214 80 238 154 69 16 176 14 14 87 234 104 11 230 104 238 90
+        118 5 84 252 202 125 190 148 126 152 158 21 202 220 69 135
+        4 103 13 217 215 233 250 215 70 55 226 38 88 187 39 154 13
+        208 252 34 163 33 141 193 243 231 212 251 211 251 121 149
+        85 1 97 130 112 191 90 135 90 206 197 188 64 27 45 201 207
+        127 214 134 215 181 195 98 143 189 138 237 77 203 207 99 70
+        147 236 131 99 174 169 234 43 123 77 62 84 37 70 88 247 53
+        203 223 20 122 138 214 234 127 203 100 102 12 71 7 177 230
+        180 252 80 248 131 123 168 93 92 217 90 92 48 143 126 11 3
+        85 179 199 52 132 72 237 36 140 199 144 125 105 163 26 232
+        132 230 210 164 48 75 217 26 50 178 31 175 216 86 192 177
+        179 120 114 70 67 241 199 223 181 123 78 176 141 158 25 60
+        57 29 36 94 123 112 125 170 77 160 116 237 205 192 152 92
+        70 3 69 180 142 14 72 30 149 94 150 201 70 42 93 246 70 127
+        3 111 32 5 156 28 246 30 245 190 13 46 213 184 24 7 252 106
+        204 181 232 39 188 134 25 214 2 158 110 1 167 211 252 45
+        149 128 217 22 112 6 10 158 230 167 249 25 79 192 83 113 90
+        218 43 149 217 141 188 156 214 187 150 139 38 69 97 207 165
+        90 154 223 195 91 168 237 85 150 18 178 103 7 158 226 163
+        250 159 68 74 152 183 104 138 133 245 230 154 51 108 73 97
+        165 178 2 110 35 93 185 140 228 246 250 214 22 218 145 75
+        144 79 49 169 237 237 76 239 180 139 136 30 225 167 183 116
+        136 113 19 250 19 244 164 87 118 130 221 66 140 239 113 150
+        255 0 84 123 26 210 236 17 199 79 146 58 87 225 47 85 90 20
+        133 99 120 217 252 48 184 7 154 188 44 181 72 110 33 115 28
+        138 189 178 107 243 247 73 212 245 13 34 238 43 139 91 150
+        86 86 224 103 130 43 161 190 21 117 252 218 133 187 199 52
+        195 196 199 42 79 57 169 101 130 173 150 89 37 47 133 243
+        123 62 27 184 205 66 250 153 228 158 87 72 219 242 128 203
+        31 230 250 83 11 125 67 241 86 98 67 184 239 92 140 119 20
+        179 85 146 97 108 214 246 225 124 118 236 237 217 7 169 53
+        139 136 77 210 199 8 240 215 106 142 5 122 9 94 225 177 34
+        149 251 208 119 94 29 164 113 164 108 89 229 206 11 127 16
+        254 111 181 21 167 69 35 196 145 178 183 3 230 247 165 148
+        171 163 166 41 164 130 109 86 72 238 147 99 239 32 246 21
+        50 208 67 51 13 202 70 225 138 143 217 91 1 54 246 198 79
+        106 149 105 49 31 46 210 1 250 210 91 125 141 149 166 135
+        114 167 244 87 221 194 162 96 31 173 115 103 199 23 118 190
+        241 36 82 160 55 148 159 90 234 47 194 238 179 39 25 59 121
+        246 174 109 255 0 40 116 120 110 193 194 99 119 97 84 199
+        217 231 101 232 129 88 15 19 77 12 127 74 223 28 124 80 182
+        50 40 176 133 70 70 70 236 125 40 181 124 40 198 106 216
+        211 226 206 89 109 155 34 93 166 136 112 118 10 12 51 23 28
+        26 222 242 16 170 190 227 251 40 168 180 18 63 170 115 121
+        30 61 233 149 159 238 69 44 213 124 179 41 200 224 209 54
+        210 55 130 49 197 27 163 25 220 166 238 105 102 167 24 91 9
+        200 239 225 63 20 222 94 35 207 189 5 169 47 244 9 255 0
+        221 61 43 70 54 233 208 175 236 235 101 33 79 228 35 103
+        244 175 52 113 171 249 177 244 197 37 178 189 151 240 22
+        235 26 231 108 64 22 250 14 212 76 115 74 236 190 76 156
+        214 148 120 148 135 25 116 137 30 154 114 195 142 115 199
+        181 103 212 2 69 22 211 42 134 41 38 15 181 97 165 135 104
+        187 109 230 137 213 70 52 183 247 83 145 247 160 73 170 154
+        103 65 124 33 150 245 186 106 18 99 120 198 121 199 106 156
+        223 50 181 177 103 80 95 24 21 0 248 17 121 29 215 79 197
+        27 206 216 7 154 178 245 45 63 242 188 72 206 83 28 87 61
+        118 206 200 63 34 5 170 47 149 155 113 35 212 123 82 11 169
+        21 163 11 24 218 71 114 106 73 171 90 72 204 237 27 21 199
+        124 122 212 102 246 53 149 138 188 133 0 61 197 37 89 217
+        29 136 53 75 171 111 21 13 192 196 108 112 91 218 137 211
+        97 109 58 34 151 18 135 183 97 186 25 129 206 207 245 126
+        212 171 82 145 33 117 180 155 5 91 129 159 74 81 38 165 119
+        166 23 181 185 13 36 64 111 140 154 120 107 68 242 77 217
+        59 186 215 99 183 178 109 201 135 81 232 121 199 215 235 84
+        183 196 238 182 55 119 18 90 219 202 225 135 145 142 107
+        221 79 213 32 192 235 24 33 241 140 3 233 239 85 212 183 17
+        202 254 44 222 116 39 42 87 230 253 106 177 77 156 83 157
+        61 31 45 237 237 239 1 102 27 100 118 207 29 137 246 21 186
+        210 206 226 234 117 88 99 32 227 102 0 229 79 210 134 131
+        114 220 179 91 169 147 235 31 106 184 62 29 116 188 215 205
+        14 160 145 168 115 141 216 236 79 184 250 85 23 138 217 40
+        183 116 197 93 13 210 179 94 74 18 230 213 114 14 72 92 240
+        106 230 233 14 149 201 182 205 143 49 182 210 72 249 254
+        245 48 233 30 132 176 210 209 47 24 174 233 57 97 252 167
+        218 167 186 85 149 188 100 34 145 133 57 28 122 212 102 220
+        186 58 97 20 182 200 190 129 210 227 194 72 103 183 201 140
+        229 192 28 17 78 83 165 195 162 4 143 96 7 111 126 245 58
+        210 108 148 90 143 40 231 191 214 137 154 200 237 77 168 54
+        171 110 34 137 185 113 123 101 115 115 210 176 184 101 150
+        223 113 81 198 106 35 212 61 46 204 146 44 118 104 3 38 204
+        227 176 247 251 213 241 45 180 101 119 0 9 35 251 41 14 173
+        104 170 73 101 10 153 224 208 119 240 50 148 89 202 157 87
+        210 48 77 60 202 214 110 145 193 229 140 1 199 222 169 174
+        161 208 175 22 242 86 75 117 218 95 31 252 215 114 106 218
+        69 181 227 52 71 111 57 46 113 223 138 169 250 227 225 231
+        131 110 90 216 198 94 224 22 231 209 126 149 162 223 45 154
+        81 168 156 164 246 105 35 152 164 140 41 67 203 122 15 160
+        172 244 205 66 77 47 82 51 89 54 17 78 55 19 203 125 233
+        247 94 105 223 178 174 22 205 16 237 44 124 64 125 90 162
+        182 234 136 155 102 138 70 62 137 31 173 94 124 90 57 84
+        156 54 116 39 195 190 179 134 247 78 137 124 92 52 99 12 24
+        250 84 190 125 74 222 228 22 13 148 35 12 7 241 125 15 210
+        185 131 65 214 164 211 239 247 12 162 231 205 138 181 180
+        30 166 140 66 173 183 114 133 221 180 251 251 212 163 217
+        104 57 61 217 45 187 183 48 52 154 150 161 34 137 37 242 67
+        26 246 81 232 61 233 182 153 49 100 85 229 112 63 90 138 45
+        212 147 203 251 79 82 37 80 183 229 102 164 26 9 252 67 120
+        146 72 85 91 145 72 227 114 59 160 237 18 88 219 116 161
+        128 194 250 98 164 218 66 175 145 152 176 31 74 141 233 144
+        188 234 35 221 177 148 246 247 169 118 137 110 210 97 23
+        142 49 73 246 131 54 146 29 92 206 230 219 109 190 115 183
+        140 251 87 51 255 0 148 20 183 13 170 120 78 170 124 221
+        249 174 164 185 130 27 123 23 50 76 82 69 143 129 239 92
+        167 241 178 239 241 93 84 144 43 29 170 196 55 214 169 141
+        83 103 14 94 136 60 113 50 75 18 174 79 229 246 52 94 226 2
+        231 223 154 250 84 199 50 150 228 142 7 218 177 118 12 221
+        171 162 18 75 71 56 79 139 25 101 81 243 99 244 172 165 198
+        194 27 185 239 143 74 24 174 210 24 112 43 207 32 216 41
+        219 179 8 181 86 62 48 237 222 143 178 93 208 45 3 170 168
+        241 215 143 90 105 166 46 97 24 246 169 72 198 115 174 16
+        41 251 208 58 145 99 167 93 28 124 176 57 31 217 76 167 70
+        35 147 64 234 8 223 179 47 121 255 0 246 207 255 0 45 82 49
+        209 133 58 116 91 236 237 155 215 195 163 214 53 35 105 60
+        208 186 71 245 59 111 247 99 251 232 167 39 120 199 189 115
+        61 187 58 49 244 62 211 27 106 40 244 11 138 206 245 131 90
+        52 110 112 15 124 250 80 182 59 150 60 230 183 93 131 52 5
+        27 128 123 98 175 195 198 206 121 123 23 111 194 141 25 19
+        165 163 146 25 150 25 163 228 146 123 213 139 166 235 6 72
+        132 55 16 182 244 227 196 61 136 170 231 225 154 76 186 12
+        22 208 179 49 99 134 250 138 156 221 168 180 182 82 216 81
+        234 125 123 87 36 175 164 117 198 187 96 58 228 214 203 59
+        186 202 20 145 242 147 193 53 1 215 181 21 183 159 204 200
+        184 60 224 240 43 87 94 245 125 134 157 20 166 73 17 216
+        118 25 230 168 174 178 235 171 237 81 90 222 215 114 199
+        158 72 239 250 86 132 91 208 207 34 142 209 51 235 190 160
+        181 86 120 81 64 43 192 57 245 168 68 189 85 123 61 177 130
+        95 57 67 149 63 78 212 133 26 107 169 12 183 147 177 200
+        245 61 205 1 113 118 200 204 145 224 15 173 118 67 29 171
+        100 178 229 182 25 125 127 150 37 188 197 251 168 238 15
+        189 39 185 59 88 239 96 227 233 90 204 153 36 243 156 250
+        214 80 71 44 242 42 170 239 102 56 81 158 230 153 164 142
+        87 119 100 211 225 206 159 38 163 172 70 24 180 11 24 192
+        157 144 149 39 254 181 215 159 13 186 114 107 91 40 63 18
+        33 155 114 143 204 72 246 156 125 126 149 76 255 0 147 198
+        143 171 90 193 29 212 150 211 92 187 159 201 137 149 118
+        238 29 192 231 57 31 95 210 186 179 67 253 204 19 79 111 28
+        23 17 128 94 51 243 21 255 0 10 231 148 172 183 14 42 205
+        194 198 51 182 56 212 246 239 76 244 141 60 52 109 25 57
+        246 62 245 140 23 182 18 93 21 158 101 66 237 144 163 184
+        167 169 60 62 42 219 197 177 155 211 111 183 189 78 154 232
+        101 145 208 77 140 91 97 53 181 215 56 86 224 19 201 175
+        182 255 0 153 207 99 244 237 88 207 34 169 11 131 222 155
+        95 72 74 219 179 99 70 54 96 118 28 10 87 127 110 100 144
+        112 118 47 115 77 147 204 156 80 119 141 180 129 42 159 15
+        233 220 208 119 240 104 57 39 178 37 117 96 85 213 147 200
+        51 198 125 105 102 187 166 69 54 157 34 149 46 249 193 30
+        255 0 74 152 93 203 101 248 35 47 136 164 33 198 65 165 111
+        61 188 182 243 165 187 70 230 70 249 143 96 43 36 238 217
+        105 100 109 81 202 255 0 26 122 94 231 240 119 19 36 177 69
+        30 60 177 32 36 177 255 0 189 115 30 160 38 130 83 13 194
+        52 108 59 6 24 56 175 208 63 136 208 223 92 105 207 21 134
+        158 207 19 103 243 21 87 43 199 98 73 239 92 75 241 71 69
+        212 236 122 138 225 174 109 229 104 249 35 198 24 32 125 72
+        227 251 234 139 100 114 69 209 22 180 152 162 121 78 1 245
+        167 218 70 173 115 107 34 186 254 98 142 224 122 138 138 6
+        100 227 248 79 106 221 5 228 177 159 47 98 49 85 171 22 46
+        145 97 69 213 51 92 95 197 248 179 182 5 249 99 61 254 245
+        105 116 222 187 111 113 98 30 50 170 84 236 7 61 207 181
+        115 221 153 241 206 226 88 47 185 244 52 108 26 166 163 165
+        220 175 225 238 11 170 182 229 0 240 77 35 196 213 179 170
+        57 18 143 103 91 244 253 212 110 23 116 170 167 102 50 125
+        13 77 116 75 168 109 109 131 33 103 25 229 147 214 185 131
+        161 190 34 36 211 8 175 36 104 229 7 140 227 7 251 234 246
+        233 77 90 222 254 213 26 9 55 2 61 235 145 220 101 208 202
+        74 107 178 77 121 113 115 170 188 145 70 36 181 135 30 99
+        47 241 253 171 159 62 46 90 90 218 245 34 77 104 193 54 183
+        0 213 253 169 91 200 150 203 113 19 96 168 36 227 218 185
+        235 226 187 51 106 194 86 112 70 227 192 239 84 199 53 100
+        178 105 82 35 18 57 99 90 7 239 43 4 155 33 91 156 123 86
+        107 203 110 174 142 36 101 166 19 130 0 200 199 21 237 170
+        121 39 154 248 155 177 230 32 214 71 129 156 142 105 210
+        179 8 245 140 248 163 138 109 163 200 162 223 130 51 138 85
+        173 224 74 87 190 61 69 29 163 254 235 244 161 40 152 57
+        183 51 103 6 131 213 8 93 58 247 60 127 71 127 249 104 238
+        62 180 22 177 183 246 101 239 127 234 239 255 0 45 20 233
+        24 85 167 73 26 216 65 158 254 18 86 70 100 50 129 159 90
+        89 104 199 240 86 236 199 63 150 63 186 178 133 100 146 225
+        112 199 147 197 69 37 101 99 145 116 137 133 143 154 42 223
+        50 31 8 149 228 138 209 167 127 87 0 247 94 9 162 157 136
+        78 14 51 222 171 242 136 228 246 39 127 8 122 155 193 211
+        165 220 219 222 54 192 218 113 254 52 71 92 124 78 134 206
+        23 182 242 187 28 252 196 228 113 244 170 88 223 220 219
+        207 44 80 206 241 239 239 180 227 38 144 234 211 205 121 49
+        73 228 101 63 206 79 45 244 169 180 145 73 78 162 107 234
+        29 90 235 92 212 101 113 39 229 150 254 34 104 102 133 173
+        146 56 230 104 163 6 61 202 249 206 107 11 155 118 183 143
+        115 52 123 72 227 117 42 184 144 147 183 57 35 142 15 24
+        167 142 136 115 114 14 212 175 140 155 18 48 170 23 212 122
+        208 18 51 72 219 155 143 181 124 141 89 188 217 237 82 45
+        15 165 239 239 228 64 35 220 172 50 60 164 211 60 180 168
+        122 182 34 182 181 150 105 22 52 83 150 56 21 119 124 40
+        232 61 22 11 120 117 14 162 91 71 193 223 137 156 141 163
+        244 168 207 76 244 169 183 63 136 212 18 225 18 57 54 168
+        100 219 185 135 63 225 91 58 183 90 125 107 82 255 0 195 61
+        62 206 225 188 133 223 130 120 244 164 82 82 209 69 162 234
+        185 248 149 211 250 36 150 134 27 173 53 90 60 43 62 205
+        196 168 237 185 135 124 122 30 226 143 31 29 52 104 209 202
+        95 254 32 5 27 100 36 236 45 159 148 10 175 236 62 14 116
+        119 78 233 49 106 29 125 173 188 6 78 209 228 140 254 148
+        143 173 126 25 244 255 0 254 31 184 234 111 135 186 191 237
+        75 11 33 253 58 212 252 240 131 193 111 211 138 203 18 248
+        105 41 203 127 11 55 77 248 167 13 230 169 52 150 247 62 32
+        50 141 165 57 219 192 206 71 176 171 175 165 122 166 5 180
+        105 218 238 57 174 14 11 190 120 198 63 135 233 92 19 209
+        178 53 191 80 219 134 145 158 37 96 36 8 112 28 122 30 61
+        49 87 123 245 75 105 182 99 207 52 183 69 118 195 26 0 16
+        169 237 74 213 104 10 171 71 82 105 125 92 178 27 168 173
+        231 133 252 12 41 37 143 45 235 68 75 172 79 115 181 162 5
+        128 229 177 233 84 103 195 200 167 142 199 241 23 49 151
+        121 21 93 163 36 242 199 230 63 165 90 218 115 72 203 28
+        109 148 86 95 48 30 130 163 46 131 68 134 62 164 146 22 88
+        78 21 152 231 46 120 197 44 126 179 134 226 226 72 124 104
+        153 146 79 13 129 39 0 251 253 170 55 212 64 44 102 54 86
+        40 36 33 28 158 7 21 76 245 62 169 115 211 218 200 159 30
+        37 165 208 49 206 224 240 62 181 88 250 152 177 62 34 245
+        140 58 102 239 2 121 12 14 222 120 80 249 147 237 244 168
+        54 141 241 163 78 211 141 197 165 197 196 110 210 203 184
+        16 199 40 158 223 78 113 222 160 191 17 53 127 196 104 134
+        75 123 167 145 74 17 20 217 230 63 175 255 0 62 245 82 116
+        190 137 169 117 70 175 107 165 233 240 120 183 183 79 225
+        199 158 199 156 150 111 160 28 213 97 20 214 197 201 168
+        218 58 99 87 248 221 161 73 107 36 48 234 16 164 172 70 232
+        230 77 202 62 162 133 213 239 186 63 173 172 13 173 252 186
+        108 175 26 9 160 13 46 213 115 245 3 147 81 85 248 123 240
+        135 79 184 58 54 177 212 210 207 171 96 36 146 110 10 187
+        253 64 250 103 181 70 126 35 124 48 190 232 99 6 191 161
+        221 181 213 145 243 70 249 7 2 179 138 55 41 69 121 116 68
+        62 34 244 106 232 154 139 73 100 209 61 179 246 17 146 66
+        253 179 80 146 152 39 131 199 28 213 195 105 171 105 157 87
+        161 143 26 59 165 188 183 127 13 178 23 185 254 44 14 194
+        162 250 143 68 106 158 61 204 107 110 234 144 30 119 14 228
+        250 214 186 216 120 166 66 226 186 146 33 181 64 42 79 57
+        166 150 183 81 221 67 28 108 18 34 131 27 135 115 75 245 13
+        58 230 209 218 57 151 105 30 148 26 50 169 243 12 143 106
+        111 201 100 165 221 14 110 45 100 30 29 202 108 93 231 201
+        176 249 179 245 169 239 195 46 190 155 65 116 134 233 140
+        202 14 56 39 138 173 172 165 241 167 102 114 65 246 205 29
+        45 139 162 248 204 228 123 82 154 13 217 214 154 111 94 193
+        127 103 35 13 219 89 59 103 214 170 30 176 184 55 250 195
+        158 200 28 241 237 81 14 158 212 46 196 42 137 52 136 163
+        140 3 222 158 137 55 121 155 204 199 185 62 181 62 153 119
+        177 106 33 86 39 146 15 247 81 80 227 28 214 137 102 84 57
+        35 143 81 91 33 60 96 250 242 42 184 246 182 77 236 45 72
+        53 242 65 229 28 154 249 12 110 20 229 189 107 50 141 142
+        244 244 97 14 171 216 100 246 245 166 26 88 99 0 35 218 130
+        215 35 41 149 62 180 126 145 34 139 101 76 115 75 35 4 237
+        124 253 43 70 167 206 153 122 63 254 179 255 0 203 71 73
+        185 87 191 122 7 80 255 0 54 94 255 0 237 223 254 90 41 42
+        48 158 198 216 61 132 13 234 34 76 10 223 4 91 101 25 226
+        129 180 188 95 192 192 168 74 159 13 123 253 40 136 174 55
+        56 243 115 92 231 71 24 168 162 77 103 194 133 29 143 173
+        23 183 3 142 104 29 53 183 69 159 173 28 161 137 32 48 31
+        122 183 250 156 242 236 132 107 158 77 85 199 161 245 165
+        154 157 228 75 20 143 224 147 38 208 160 254 180 95 83 57
+        138 255 0 123 28 143 97 222 163 23 119 6 86 113 187 3 28 3
+        64 73 118 105 188 158 75 137 188 71 96 196 142 62 149 164
+        43 30 194 155 233 90 68 247 146 69 24 134 76 56 200 101 82
+        71 247 84 150 223 225 254 169 117 125 13 172 54 206 217 30
+        128 228 208 177 150 50 61 211 246 17 93 221 197 19 50 151
+        102 24 78 228 254 149 210 29 55 105 99 164 244 220 104 153
+        154 237 211 1 35 143 5 190 134 190 116 95 193 91 125 52 67
+        53 238 212 144 12 22 9 206 126 149 105 216 232 54 58 126
+        158 27 240 202 229 60 161 207 115 250 84 178 100 101 225
+        138 145 205 127 16 35 235 141 54 194 107 169 173 82 194 202
+        102 43 28 64 121 177 238 126 181 183 252 152 180 184 110
+        186 206 59 139 153 55 120 114 255 0 23 124 138 184 254 36
+        90 166 177 166 141 46 104 35 142 4 39 108 140 60 196 227
+        176 199 115 84 102 142 215 157 3 174 165 245 152 155 98 49
+        145 210 65 182 66 185 239 131 86 197 41 73 81 57 175 22 75
+        126 54 92 222 106 189 105 168 45 206 80 193 62 200 131 127
+        20 127 74 19 225 245 222 151 210 147 38 181 113 169 69 121
+        103 125 101 56 212 44 99 102 221 6 60 168 178 103 131 158
+        249 20 247 171 250 255 0 225 55 87 218 197 168 106 38 238
+        29 67 24 153 33 139 7 31 169 239 80 253 42 199 77 234 9 221
+        244 173 34 120 116 93 223 60 242 238 146 225 135 191 176
+        197 36 63 140 227 147 155 122 59 223 245 28 95 218 44 42 62
+        68 123 167 116 185 33 117 214 20 71 109 12 210 51 36 95 197
+        180 158 0 171 51 165 244 73 181 27 215 191 191 183 154 71
+        150 61 177 2 56 219 239 254 213 35 135 77 93 99 94 75 88 99
+        72 173 161 199 135 10 231 9 138 187 122 35 69 184 136 199
+        113 225 112 23 204 91 181 105 61 158 122 116 182 109 183
+        177 142 215 72 137 99 152 44 139 202 169 238 135 220 211
+        173 10 247 84 145 37 105 49 49 72 240 127 183 230 20 195
+        195 180 216 86 107 115 34 158 225 69 108 183 146 21 220 177
+        126 90 40 200 92 115 82 158 217 76 73 209 23 188 188 186
+        187 184 17 77 43 73 110 173 231 66 57 205 36 235 93 26 222
+        248 180 239 3 92 196 188 182 206 202 49 86 11 61 188 190
+        105 20 200 254 158 80 48 43 69 253 168 184 183 219 28 107
+        27 24 246 133 127 95 236 162 131 61 28 197 173 216 222 88
+        217 13 44 226 43 73 31 242 89 255 0 139 239 65 124 52 190
+        183 232 190 169 212 34 186 137 37 188 186 211 165 252 20
+        241 182 10 183 7 106 159 114 1 171 31 226 39 74 188 150 165
+        68 82 126 72 47 156 241 159 165 66 44 180 219 125 107 79 75
+        123 168 137 187 181 36 199 112 14 10 48 237 131 86 134 153
+        9 78 169 175 217 28 191 211 109 173 111 109 205 190 165 6
+        167 45 196 98 226 89 34 13 152 157 143 40 229 191 136 122
+        213 219 240 252 182 169 240 123 92 211 245 15 204 134 221
+        191 163 153 62 94 59 129 85 78 147 168 244 85 173 233 139
+        172 44 181 29 51 80 138 76 59 194 229 163 155 253 110 121
+        201 246 169 111 88 252 86 233 143 252 53 7 76 244 23 143 35
+        72 140 37 121 34 218 50 125 205 8 97 148 95 43 61 95 231
+        255 0 59 22 124 80 140 35 180 82 80 254 51 75 234 219 152
+        244 185 25 31 199 17 162 17 228 111 191 210 174 222 139 139
+        169 109 103 71 234 59 16 208 73 134 91 132 28 99 218 162
+        191 15 58 89 110 181 4 213 181 39 113 32 199 134 93 114 142
+        255 0 82 43 162 180 147 22 161 107 2 222 219 198 147 162
+        132 64 7 148 175 189 35 200 250 103 18 132 111 179 158 126
+        54 232 182 47 178 234 216 143 12 182 230 34 169 75 216 226
+        86 62 11 7 25 238 43 184 58 167 161 44 181 120 36 73 6 204
+        140 99 195 4 19 238 42 138 248 143 240 98 250 192 126 51 78
+        18 73 30 114 219 87 3 251 40 197 162 83 195 78 202 44 103
+        52 211 78 187 145 54 164 135 122 127 47 168 167 119 125 31
+        117 14 158 39 146 60 72 6 74 169 228 212 106 230 9 109 91
+        44 172 185 28 110 20 233 139 199 137 59 211 30 223 194 6 21
+        216 9 228 123 154 117 19 21 183 101 35 181 68 58 114 224 52
+        41 184 147 232 64 247 169 58 179 120 108 164 130 77 35 236
+        22 8 208 254 98 209 16 202 21 112 8 197 15 63 136 172 6 112
+        125 43 234 35 110 238 0 255 0 173 87 23 65 24 66 236 121
+        193 197 109 144 238 21 170 15 42 121 151 28 214 213 59 184
+        170 24 79 174 144 84 145 216 246 173 250 79 238 135 218 133
+        214 206 213 17 144 115 69 105 35 49 45 99 12 223 228 160
+        245 15 243 101 239 254 217 255 0 229 163 101 24 10 191 74
+        11 81 227 77 189 255 0 219 191 252 181 140 66 237 225 152
+        136 216 103 105 143 138 42 222 57 150 117 57 39 154 107 103
+        110 162 194 219 10 63 171 171 126 167 189 98 177 159 20 10
+        230 67 56 162 65 166 16 176 15 122 57 202 178 141 172 115
+        64 88 198 124 49 205 27 28 101 92 179 114 41 211 177 27 43
+        190 181 38 61 66 76 115 159 127 74 142 91 196 102 157 87
+        146 88 212 151 174 163 111 198 6 254 126 212 171 167 182
+        166 169 24 144 2 50 57 62 156 208 151 236 120 165 106 206
+        132 248 59 209 94 38 135 22 165 116 100 87 219 133 80 70 49
+        138 180 58 43 73 68 189 154 226 52 220 241 182 23 35 56 160
+        58 34 72 173 250 58 47 54 209 225 129 24 247 207 173 79 186
+        31 77 16 218 248 219 67 25 6 226 42 13 203 224 242 236 123
+        167 216 226 13 203 26 128 188 231 57 255 0 26 95 212 86 203
+        14 38 0 224 17 188 125 42 75 20 6 20 41 26 240 252 40 164
+        186 234 187 174 24 60 133 78 89 87 218 149 187 209 148 221
+        236 138 245 22 157 60 140 183 218 74 1 34 249 247 204 160
+        162 241 142 213 79 245 47 72 111 89 117 61 99 84 182 187
+        158 103 33 174 166 206 10 255 0 42 133 245 251 213 175 213
+        218 164 50 217 172 77 44 214 192 54 8 65 153 36 250 40 165
+        235 164 216 95 233 145 223 73 17 140 91 201 143 195 177 220
+        227 244 236 198 173 6 250 55 37 118 206 124 181 232 213 212
+        181 136 196 118 238 246 80 74 54 160 1 90 97 239 159 229
+        171 3 81 179 134 222 91 125 63 77 88 108 247 70 21 97 132
+        238 43 245 53 45 120 119 180 159 135 218 145 202 124 24 230
+        10 1 96 59 138 144 116 239 76 219 104 202 250 174 165 4 101
+        194 238 201 94 91 218 157 201 213 11 26 91 162 47 209 221
+        26 52 117 23 55 18 44 146 183 32 241 146 126 181 97 105 233
+        20 118 239 243 120 107 243 2 121 52 161 18 107 251 179 117
+        35 164 17 70 249 66 107 125 213 247 138 230 59 119 1 148
+        224 149 236 106 118 51 105 187 99 27 235 207 20 237 133 85
+        51 237 90 163 140 144 27 36 55 175 214 176 176 141 3 171 57
+        220 128 242 222 212 213 32 181 101 44 179 99 53 59 41 141
+        241 20 200 230 41 119 134 56 245 197 31 105 121 29 194 42
+        177 193 3 134 254 42 198 107 120 2 16 178 100 251 210 153
+        213 161 184 13 20 228 145 243 173 50 86 9 53 123 50 234 11
+        11 107 132 41 134 60 99 35 4 255 0 125 85 157 71 210 82 232
+        87 15 123 4 237 225 49 203 32 28 15 92 241 86 153 120 245
+        40 4 33 140 12 220 54 239 152 214 173 37 225 148 75 165 223
+        70 178 197 38 80 59 12 213 185 19 139 75 225 77 117 119 76
+        218 117 23 78 199 47 225 99 146 248 121 146 242 54 243 3
+        252 172 191 245 164 29 51 210 246 205 122 209 95 27 104 110
+        162 249 76 132 248 83 143 117 43 87 61 247 76 54 135 118
+        243 89 248 81 68 91 43 159 95 113 205 124 211 116 235 59
+        199 54 23 81 195 110 249 202 133 64 54 122 231 39 248 104
+        114 98 73 236 91 209 125 35 169 105 98 107 75 29 66 7 178
+        150 60 155 57 0 59 121 244 39 154 176 161 130 56 45 161 131
+        240 242 36 164 237 44 221 179 244 168 206 172 145 216 106
+        169 111 43 77 19 68 121 184 135 229 199 250 223 79 168 169
+        93 165 218 234 150 209 172 106 222 64 48 87 215 30 166 167
+        40 219 177 137 5 164 77 225 36 102 48 236 7 36 210 254 160
+        178 221 27 70 208 171 41 249 151 210 159 105 140 205 10 22
+        12 209 109 192 217 232 126 191 90 251 119 110 165 6 236 183
+        213 187 209 72 45 183 217 69 183 75 195 125 121 61 155 100
+        5 30 184 205 115 207 198 174 155 151 68 213 222 32 25 161
+        83 228 98 7 34 186 207 88 181 139 79 234 23 149 155 247 220
+        10 163 255 0 202 41 80 99 115 120 135 178 3 252 67 6 155 28
+        147 208 117 84 202 79 164 121 159 185 198 123 26 153 3 129
+        233 81 14 155 253 250 152 252 188 224 129 233 82 233 50 23
+        235 76 227 178 79 197 31 83 243 62 113 147 239 69 69 10 17
+        207 56 237 66 70 234 20 224 115 68 71 56 0 125 120 167 197
+        209 141 160 49 250 250 86 74 25 125 43 234 28 14 56 205 101
+        147 239 84 48 155 89 82 249 46 54 159 165 109 209 219 49
+        125 171 29 96 150 206 121 226 190 232 192 180 71 21 140 53
+        145 153 136 192 29 168 109 70 54 253 151 120 205 192 54 207
+        255 0 45 18 119 46 57 244 172 117 94 116 59 175 253 179 255
+        0 202 107 24 142 89 51 27 24 6 15 238 146 183 163 13 224
+        100 103 53 170 197 15 224 160 237 251 164 175 174 140 178
+        175 110 245 199 99 146 109 59 247 127 173 22 85 73 60 208
+        90 110 68 32 159 122 34 114 206 190 203 233 142 245 117 29
+        89 39 221 16 158 179 54 177 220 6 150 54 101 29 212 54 9
+        253 107 111 65 52 119 55 208 199 14 159 167 164 123 191 120
+        209 111 147 191 189 1 214 76 222 33 221 130 113 71 252 41
+        88 255 0 104 199 36 165 130 171 100 227 214 150 79 84 58
+        126 71 78 217 170 67 162 91 71 31 38 76 42 17 235 86 191 71
+        218 226 40 183 157 227 104 3 30 245 85 116 252 107 47 224
+        147 147 26 121 176 106 212 209 200 68 130 221 153 131 103
+        118 229 237 138 136 242 236 147 52 74 210 101 92 7 94 113
+        81 206 163 180 146 65 45 212 115 0 66 224 212 170 13 172 85
+        149 148 48 60 230 163 157 92 118 146 241 130 177 200 118 96
+        251 227 63 244 167 125 0 170 250 146 107 143 26 41 174 154
+        105 32 81 183 100 67 37 142 104 141 62 226 225 44 37 156
+        192 167 127 149 93 184 194 251 154 34 85 150 107 205 145
+        176 9 27 121 178 56 175 107 55 45 34 236 114 145 219 47 4
+        142 9 164 10 179 239 79 89 193 97 27 94 77 34 162 47 152 51
+        30 13 9 170 235 147 234 243 24 80 18 177 156 130 61 69 71
+        239 239 159 88 188 88 85 21 45 226 60 5 39 154 51 80 158
+        223 65 182 73 37 184 54 225 70 230 4 14 70 59 81 76 106 190
+        198 23 55 145 91 233 127 141 105 132 48 198 48 238 199 3
+        255 0 154 174 58 155 227 6 147 167 135 139 69 183 123 233
+        84 238 241 230 249 11 85 101 241 47 174 53 30 162 190 154
+        40 100 123 125 56 54 216 237 225 111 46 51 220 253 106 53
+        162 195 249 223 155 143 15 235 70 43 147 7 137 100 15 139
+        93 115 122 210 203 111 115 4 1 223 248 98 193 3 233 91 224
+        235 142 190 159 44 117 201 23 112 254 17 66 244 246 143 9
+        132 58 170 159 165 53 93 29 113 226 5 35 43 144 0 167 81
+        127 161 185 68 15 255 0 212 47 136 86 174 118 234 178 76 23
+        130 28 113 138 249 167 124 105 234 91 59 198 143 87 180 181
+        188 182 99 229 35 190 62 148 116 154 76 126 31 238 219 44
+        57 200 168 119 85 233 118 246 170 74 40 12 79 4 246 20 90
+        111 224 27 139 46 222 152 235 237 19 169 151 109 140 198
+        218 240 156 61 180 237 134 79 246 126 181 34 212 21 229 41
+        26 161 241 147 204 8 244 250 215 29 239 158 206 100 158 41
+        36 142 88 206 229 120 216 130 167 220 123 213 223 240 171
+        175 165 212 172 19 76 214 36 205 194 174 216 238 9 229 135
+        177 164 118 129 73 244 93 58 63 80 195 169 35 105 23 135
+        108 177 46 6 238 198 129 182 183 146 199 89 146 65 27 74
+        210 38 207 15 196 194 129 244 164 122 189 171 181 132 55 80
+        183 134 20 238 18 47 175 222 138 210 117 111 218 67 240 247
+        18 5 184 78 3 10 91 12 83 110 168 207 85 150 225 110 90 222
+        68 144 6 95 202 42 60 195 234 79 173 72 186 125 111 38 252
+        53 180 146 166 118 124 222 189 251 26 213 115 190 234 201 0
+        88 214 88 142 85 241 233 68 116 235 184 34 119 145 222 69
+        109 187 113 253 244 108 220 75 31 72 181 120 160 48 25 4
+        128 12 144 43 116 176 199 248 15 13 99 98 8 230 182 105 222
+        91 96 164 129 43 97 183 30 216 199 106 209 172 188 98 216
+        198 172 195 234 180 91 36 221 58 43 158 186 142 72 46 32
+        154 67 149 13 159 189 85 31 25 237 148 233 226 85 240 156
+        21 220 168 235 184 30 61 69 91 221 94 127 21 104 95 4 140
+        121 126 149 89 245 117 172 87 90 116 126 59 200 27 105 92
+        142 64 21 37 26 118 91 134 172 230 221 62 226 221 53 16 143
+        103 28 110 78 73 133 246 47 255 0 230 164 55 238 134 37 218
+        70 61 57 165 29 89 165 92 104 218 195 188 136 230 34 124
+        178 122 99 222 178 134 224 188 74 172 114 64 239 86 82 100
+        166 188 67 34 108 46 115 69 71 38 229 238 41 100 47 199 122
+        54 221 129 166 140 184 137 45 58 24 219 252 167 62 245 183
+        156 103 210 180 68 234 171 94 150 96 20 14 106 139 34 97 0
+        213 121 25 29 141 124 210 37 111 8 166 59 26 245 243 6 77
+        163 248 123 159 122 195 70 238 212 121 196 195 144 196 247
+        21 163 84 35 246 77 208 245 17 57 63 109 180 65 27 87 60 80
+        154 145 255 0 203 111 127 246 207 254 24 173 206 38 21 233
+        188 216 219 159 254 146 127 133 110 4 9 121 25 161 108 37
+        85 177 183 95 85 140 110 250 226 136 143 243 36 7 208 26
+        228 41 30 199 214 25 240 78 71 173 109 150 64 16 143 95 65
+        239 88 90 16 109 248 227 28 86 139 146 119 231 60 142 213
+        107 124 73 201 121 16 206 172 95 26 80 23 191 175 210 166
+        191 9 186 121 141 170 220 180 51 57 39 129 129 239 222 144
+        217 105 82 234 218 199 131 179 11 184 110 53 209 157 23 211
+        214 182 122 44 81 201 48 241 182 0 61 49 74 24 251 14 122
+        66 214 229 94 48 208 133 80 63 139 189 88 90 72 96 192 54
+        56 236 105 7 78 88 164 31 52 129 163 94 88 231 204 79 181
+        74 32 134 75 123 116 196 68 156 118 110 226 145 143 46 198
+        179 58 65 18 179 74 219 207 112 59 84 115 170 46 217 180
+        249 95 121 44 62 81 237 245 251 209 183 119 81 180 108 184
+        238 42 25 212 90 162 174 228 102 93 157 155 119 96 41 152
+        42 207 186 29 184 107 71 154 87 35 185 99 238 106 35 214 90
+        132 78 5 157 187 22 99 232 41 157 222 169 44 26 83 52 101
+        76 44 48 54 118 53 26 208 109 228 190 214 33 145 162 12 12
+        152 25 246 164 47 12 111 76 155 124 53 233 149 16 45 197
+        218 110 64 114 115 235 84 239 199 221 101 78 177 123 102
+        140 26 56 188 160 102 186 123 67 179 75 123 51 101 8 13 193
+        12 127 147 235 92 107 241 198 27 139 126 176 212 98 152 146
+        230 124 159 246 105 148 28 132 134 68 242 52 200 12 48 44
+        118 198 237 149 195 183 37 15 202 62 213 165 53 63 1 131 60
+        39 195 251 84 155 168 46 180 217 180 109 62 218 212 51 92
+        54 12 161 7 205 247 165 87 82 89 54 159 36 87 22 142 140 62
+        94 59 85 34 168 156 161 110 209 97 124 56 215 45 245 8 28
+        170 12 227 145 237 86 5 215 225 226 75 113 12 108 254 77
+        217 110 56 170 35 225 13 243 91 235 38 53 243 161 111 238
+        171 123 169 245 84 91 139 104 17 137 65 24 17 253 15 181
+        116 66 105 160 113 67 109 70 91 88 173 214 118 0 239 5 72
+        81 218 169 78 186 234 56 127 27 45 154 167 136 55 144 49
+        222 173 110 160 212 29 58 101 228 42 5 202 198 66 12 122
+        123 215 62 233 243 164 250 255 0 141 116 60 92 49 242 142
+        237 247 161 55 72 220 80 93 188 222 50 8 230 132 164 141
+        199 110 5 49 209 255 0 242 221 97 24 23 216 28 40 223 199
+        127 181 107 189 186 73 119 50 219 202 189 176 224 114 121
+        166 125 93 62 159 113 248 25 172 29 213 196 65 164 200 238
+        213 12 177 114 141 153 73 69 209 212 95 8 26 223 168 186 54
+        104 166 219 35 68 72 81 246 21 27 234 77 54 125 23 88 18
+        236 216 132 242 69 51 255 0 37 139 27 166 208 175 174 74
+        150 141 66 149 95 114 123 212 179 226 94 151 227 217 181
+        196 42 36 98 114 19 249 126 149 25 174 40 188 50 46 64 61
+        45 117 107 170 89 51 69 38 14 57 7 189 109 179 111 194 245
+        10 13 196 46 60 195 211 25 168 15 76 222 92 88 234 70 5 5
+        73 60 113 145 82 150 213 51 126 143 112 34 19 99 128 135
+        119 30 249 255 0 165 104 116 52 210 79 69 167 109 119 185
+        17 22 66 87 119 13 235 138 35 83 11 140 198 229 199 166 106
+        45 162 220 120 138 36 207 25 230 164 81 75 226 40 88 227
+        223 143 74 214 115 53 228 70 181 136 157 225 117 141 64 227
+        133 53 93 235 150 179 52 130 23 132 62 14 0 95 191 173 90
+        250 196 56 152 49 219 150 249 75 118 6 161 215 246 48 139
+        215 146 105 24 130 48 71 240 211 36 55 39 209 207 127 20 33
+        179 180 212 101 79 6 102 89 24 46 201 62 82 113 220 84 6 88
+        22 44 52 44 206 159 94 226 174 175 140 58 47 137 104 38 179
+        101 148 71 150 81 184 6 83 244 205 83 54 30 42 72 232 246
+        243 3 159 48 200 110 126 244 64 246 104 220 241 131 186 137
+        182 184 64 57 110 107 102 161 110 172 9 141 65 30 254 212
+        166 104 218 35 156 253 42 148 128 210 100 129 46 99 63 197
+        95 39 148 99 200 115 72 34 149 193 201 99 138 221 248 229
+        67 207 106 87 20 128 208 222 233 129 143 30 222 190 245 142
+        151 235 247 165 175 125 226 2 84 226 143 210 100 5 194 255
+        0 53 40 7 133 191 44 80 90 144 206 153 122 114 127 171 61
+        109 150 224 46 87 219 138 26 250 101 109 34 233 189 225 112
+        126 213 168 70 221 137 52 247 111 194 91 140 28 136 249 166
+        118 114 121 192 160 116 224 166 24 71 111 203 163 173 194
+        248 234 5 98 204 146 89 170 152 115 187 239 66 223 99 5 148
+        225 63 157 62 106 105 99 25 48 42 199 183 39 190 104 203
+        189 29 230 179 1 21 83 112 249 143 111 238 172 37 48 14 133
+        210 188 109 107 241 144 164 50 46 209 151 99 130 13 116 78
+        131 56 158 218 20 150 81 189 80 13 158 131 235 85 223 195
+        94 156 59 143 226 99 12 217 225 135 21 108 90 233 166 36 79
+        10 30 0 239 88 172 152 218 198 23 133 149 225 96 185 238
+        126 148 254 207 12 187 34 137 143 243 63 165 35 182 146 88
+        80 35 67 128 79 239 15 240 253 41 148 55 50 71 3 198 155
+        223 63 59 227 185 250 86 20 246 175 9 49 238 137 75 194 7
+        14 59 26 171 122 185 101 146 252 170 221 70 138 79 57 171
+        19 90 190 184 150 223 207 136 198 60 160 85 91 173 91 79
+        121 123 35 126 42 20 85 57 229 143 253 169 39 236 52 59 21
+        95 71 52 120 85 189 141 19 24 193 61 254 181 38 232 109 62
+        56 84 95 120 139 52 177 12 70 23 208 251 210 8 45 33 102 62
+        35 69 113 183 143 43 28 138 150 244 28 129 53 1 12 177 109
+        133 56 69 30 223 90 89 71 145 87 58 90 44 222 153 135 108
+        45 112 24 137 64 59 200 35 39 138 160 63 202 143 164 236
+        110 35 77 90 16 177 220 71 31 157 207 118 63 203 255 0 95
+        210 186 59 76 240 101 45 113 224 67 10 200 219 34 218 152
+        57 168 199 95 116 226 234 154 109 212 19 66 158 32 207 206
+        14 8 193 237 93 81 141 66 145 199 109 202 217 193 218 38
+        143 125 172 92 206 182 82 120 115 194 3 167 250 199 216 81
+        186 229 182 179 114 195 76 184 142 52 153 64 252 208 57 63
+        83 79 238 108 238 58 51 172 102 142 72 93 32 119 36 100 119
+        25 197 72 174 109 109 245 43 132 213 172 128 119 83 202 159
+        81 83 166 116 173 171 43 142 148 209 167 210 53 87 186 109
+        225 20 130 8 29 254 212 255 0 168 117 88 99 189 18 151 121
+        75 184 112 15 163 10 115 169 205 104 214 160 109 219 47 168
+        3 24 168 70 191 34 35 161 50 198 74 190 79 218 171 23 76 95
+        199 68 203 87 214 37 213 236 26 53 97 28 146 199 220 255 0
+        102 42 186 135 166 111 237 101 123 191 50 170 19 133 35 150
+        251 84 183 68 104 4 177 177 98 112 6 125 170 84 82 27 248
+        197 189 188 97 156 253 56 169 202 77 176 113 118 65 83 78
+        215 58 130 206 36 216 150 214 208 121 188 131 131 250 210
+        254 157 210 219 80 215 226 210 252 97 8 241 48 197 189 106
+        194 214 117 11 77 19 76 125 54 215 30 57 82 9 28 3 79 255 0
+        201 219 162 228 212 181 51 171 222 70 35 241 27 10 204 14
+        59 131 237 70 9 216 217 101 20 182 116 135 194 61 10 223 71
+        233 107 107 59 21 100 11 15 159 61 137 250 208 157 71 12 97
+        154 215 143 1 137 222 171 83 13 26 218 43 88 139 75 108 35
+        139 110 197 57 225 143 189 38 234 185 161 181 211 101 183
+        48 140 177 224 142 226 182 98 56 211 178 137 234 75 3 103
+        126 235 13 210 69 179 144 73 173 130 222 67 20 99 241 145
+        191 102 220 13 27 168 199 28 215 18 77 53 184 93 195 130 79
+        106 16 88 52 155 213 111 32 12 167 182 227 255 0 106 132
+        186 59 155 209 97 116 84 108 85 3 72 36 56 192 34 167 80 70
+        200 128 172 81 179 175 24 61 234 176 232 167 154 223 242
+        154 101 45 191 131 159 165 88 208 95 93 44 106 165 81 128
+        31 50 250 211 199 212 228 105 169 108 211 171 31 16 177 142
+        51 27 145 202 159 74 142 94 195 25 140 200 192 22 94 114 87
+        52 250 250 105 35 117 104 83 45 234 27 185 165 119 214 183
+        19 184 62 25 85 110 227 183 52 76 85 255 0 17 132 154 166
+        147 37 186 248 46 20 21 7 110 222 125 170 129 155 79 252 60
+        230 39 32 182 79 145 107 171 122 135 68 142 75 86 221 25 92
+        100 146 59 26 162 186 143 167 38 135 88 220 138 165 119 28
+        30 107 24 133 203 14 207 44 159 150 79 240 175 99 75 110 45
+        85 216 243 83 62 164 210 229 135 108 166 18 138 125 248 34
+        163 110 129 92 228 86 17 232 71 37 152 0 226 130 158 215
+        239 82 48 136 202 124 190 180 37 197 190 92 129 142 244 105
+        152 143 205 19 33 242 127 109 63 233 213 252 149 242 146
+        217 228 214 155 139 85 10 78 40 189 15 8 59 113 154 120 166
+        96 249 147 50 29 220 26 211 168 68 19 72 186 62 190 11 147
+        246 162 174 15 230 134 247 21 167 84 255 0 50 221 55 24 107
+        119 24 162 97 14 159 36 102 218 32 205 180 248 116 198 213
+        226 87 83 188 147 154 81 107 167 220 53 140 18 7 35 242 249
+        163 44 237 37 105 17 119 28 131 147 82 28 156 233 82 143 18
+        49 232 69 79 180 187 75 121 32 92 220 73 28 184 249 68 69
+        133 65 186 106 197 231 158 36 49 201 38 61 87 210 174 190
+        145 211 94 68 137 95 195 66 171 140 177 231 245 172 97 191
+        72 233 106 109 6 103 93 195 186 142 230 167 58 110 155 149
+        2 36 4 1 146 204 199 138 15 167 44 108 128 241 124 25 230
+        127 226 240 71 203 82 107 123 49 34 172 113 248 241 71 156
+        226 65 131 88 87 42 6 22 110 1 241 219 196 92 121 84 129
+        138 211 5 149 227 238 88 149 84 19 252 93 170 65 111 103
+        146 84 149 104 151 251 65 172 166 82 241 42 66 205 41 31
+        194 220 17 253 148 44 28 209 92 245 109 181 212 113 110 220
+        74 129 192 30 181 84 206 151 127 141 151 198 194 3 192 4
+        213 229 213 154 108 146 218 14 114 49 230 95 229 174 127
+        235 72 166 211 53 41 87 12 242 147 223 39 129 83 156 188
+        139 225 142 218 26 233 208 201 11 157 171 16 82 114 78 78
+        106 95 211 141 17 148 180 69 153 211 137 31 248 84 253 106
+        187 210 229 27 98 154 234 102 10 87 29 253 106 99 211 247
+        50 71 229 137 138 237 243 73 143 226 31 90 220 138 100 73
+        45 23 31 79 177 184 177 104 84 141 225 195 120 141 198 71
+        208 83 253 66 55 75 114 242 175 137 43 240 0 25 207 21 16
+        233 137 18 107 104 217 110 11 55 0 15 166 123 84 230 250
+        120 225 136 200 204 200 137 128 8 25 197 118 65 218 60 188
+        146 119 163 156 190 49 244 36 186 173 171 92 181 143 225
+        228 44 85 153 187 143 94 42 128 158 223 90 233 105 158 56
+        219 198 133 143 215 143 181 117 247 196 9 154 123 217 165
+        105 34 104 200 206 194 249 195 127 241 84 31 89 91 238 184
+        157 99 133 30 82 55 40 29 143 214 169 197 23 199 41 112 162
+        186 185 214 103 186 102 123 219 95 57 239 33 24 3 251 42 61
+        172 120 51 36 69 109 119 3 47 206 61 78 15 21 33 184 142
+        230 221 222 9 70 84 15 54 125 169 116 176 205 24 93 141 132
+        241 6 6 59 26 159 17 249 72 198 214 241 98 108 27 117 4 224
+        149 92 211 111 252 65 168 64 98 75 43 87 17 129 229 44 56
+        199 233 205 3 107 110 99 99 52 152 50 150 56 99 237 154 123
+        211 176 77 38 160 37 101 223 31 177 237 70 43 246 110 82 10
+        232 190 141 212 53 205 71 241 87 143 28 140 88 121 125 43
+        171 254 26 232 50 233 22 137 111 248 16 144 42 133 223 142
+        9 170 163 225 212 126 10 143 13 109 192 115 128 31 230 253
+        42 249 232 235 223 11 77 134 25 36 73 90 110 236 15 57 166
+        215 194 25 174 84 55 189 178 97 21 188 74 235 225 15 54 210
+        121 53 5 235 9 86 234 105 118 131 187 119 150 33 243 84 243
+        168 21 134 153 148 145 35 216 255 0 49 238 56 170 163 172
+        110 246 221 148 183 185 203 147 193 90 134 99 163 9 14 213
+        90 57 49 224 176 111 230 87 226 144 79 4 139 52 147 43 196
+        140 253 129 124 12 209 122 205 212 6 227 198 110 1 242 103
+        63 197 239 81 141 94 238 226 25 194 40 87 70 244 127 81 244
+        174 103 45 29 138 28 145 48 233 15 198 27 192 146 18 27 119
+        163 2 63 76 85 189 164 89 221 73 26 42 185 200 28 131 85
+        191 195 29 42 75 141 146 194 172 24 159 144 255 0 15 30 149
+        113 233 150 55 16 170 135 252 206 60 210 123 85 99 234 114
+        229 146 230 1 29 155 9 135 226 87 9 252 254 162 190 157 54
+        73 150 76 206 179 156 121 119 112 64 253 42 68 34 23 10 4
+        109 226 159 76 208 151 54 110 238 87 196 43 32 237 232 7
+        222 137 62 104 132 107 26 118 99 219 226 136 152 14 121 205
+        86 125 99 167 175 237 5 105 110 23 96 62 102 65 87 101 229
+        188 101 30 59 139 121 159 159 51 70 50 13 67 181 253 46 209
+        204 177 194 198 53 217 156 74 7 6 176 201 217 68 117 172 48
+        8 222 72 228 50 38 223 33 116 108 230 160 19 129 180 62 59
+        174 113 87 71 94 233 47 38 158 234 139 184 43 97 86 169 187
+        184 158 34 241 200 48 85 138 129 236 43 2 74 221 128 250
+        103 222 176 101 39 229 25 53 159 210 179 135 230 170 115 85
+        64 52 201 22 80 150 24 56 161 172 78 217 8 0 119 166 23 142
+        190 27 113 233 75 237 10 155 130 2 253 105 224 237 24 105
+        58 110 10 223 74 18 255 0 63 178 110 193 244 129 218 143
+        149 149 99 11 142 72 160 117 31 243 85 217 61 204 78 15 218
+        131 236 193 186 90 198 116 139 76 50 159 232 201 254 21 240
+        8 214 109 220 18 57 24 165 154 124 231 246 109 170 238 218
+        22 221 20 215 212 185 118 155 195 29 189 234 35 147 62 151
+        185 63 180 227 85 109 196 243 145 232 125 170 240 233 87
+        154 98 130 117 42 224 113 159 90 231 254 159 141 77 220 110
+        210 109 243 14 213 208 95 13 174 45 209 81 90 100 44 23 203
+        187 146 127 178 177 139 91 167 68 45 106 163 233 147 24 238
+        194 164 246 194 223 193 93 177 201 193 236 190 159 122 65
+        161 25 226 95 204 138 16 51 198 79 27 105 254 159 226 186
+        121 152 39 60 39 253 105 146 178 13 219 8 84 102 112 4 112
+        237 246 207 52 108 80 71 23 155 240 209 243 245 175 145 32
+        81 150 82 62 181 181 229 80 128 114 126 212 234 128 38 234
+        59 17 121 1 113 181 118 131 149 240 176 107 157 254 36 105
+        145 172 225 132 94 57 82 119 47 168 174 150 190 241 164 6
+        72 31 195 35 212 142 106 176 235 237 5 174 124 86 101 12
+        216 221 187 24 57 164 156 20 138 96 157 62 69 19 13 184 134
+        214 71 243 120 132 102 52 147 248 105 222 141 61 221 194
+        172 215 18 131 50 12 125 90 134 154 19 103 168 120 18 237
+        96 217 0 125 104 103 241 173 101 252 106 134 27 79 111 74
+        229 105 166 119 57 114 90 45 126 140 184 86 180 102 55 40 8
+        237 205 78 191 31 60 86 95 135 107 229 220 190 111 47 36
+        241 242 213 27 163 234 202 176 41 241 140 81 191 112 123
+        211 185 186 180 219 217 198 209 221 168 144 143 56 99 206
+        43 167 30 95 140 228 201 141 223 67 62 185 190 0 22 88 89
+        78 194 89 166 24 85 62 245 68 234 173 20 200 146 120 151 15
+        39 140 216 192 249 177 223 21 100 234 93 81 167 222 233 242
+        121 135 138 27 206 9 24 97 75 172 109 244 123 201 222 118
+        186 72 146 21 59 6 6 11 55 106 235 82 137 57 41 69 21 69
+        244 107 60 211 93 169 222 178 249 75 55 4 26 2 230 55 93
+        145 140 130 91 129 142 245 120 75 240 222 29 147 220 75 118
+        30 222 100 81 28 157 134 226 70 72 166 215 191 0 76 154 124
+        23 81 107 2 210 70 149 7 157 187 131 233 218 133 196 73 100
+        226 172 231 200 35 12 21 130 144 9 218 51 234 105 173 147
+        53 180 47 106 237 55 154 81 38 213 29 143 181 92 250 183
+        193 155 93 2 226 207 241 55 27 217 230 97 184 158 15 181 0
+        157 15 107 160 194 127 107 93 71 0 157 155 135 97 207 177
+        173 113 30 18 114 86 36 232 155 166 181 212 229 142 20 15
+        143 149 27 248 143 181 95 61 33 125 178 213 99 141 94 2 163
+        115 73 32 242 131 237 84 149 189 254 147 167 202 177 171
+        167 138 174 4 135 0 227 235 82 24 186 206 56 238 36 138 210
+        113 176 227 37 143 31 165 36 164 146 26 172 183 53 139 233
+        37 145 47 13 228 65 72 33 147 61 170 172 234 89 213 239 76
+        97 195 43 49 243 10 217 127 212 139 61 152 48 202 93 149
+        124 192 17 222 162 154 181 244 173 190 4 254 177 41 201 39
+        176 251 87 62 73 166 138 98 139 176 77 70 226 105 110 227
+        128 248 50 89 41 255 0 238 31 106 9 108 115 118 169 36 98
+        88 216 249 95 209 13 31 102 134 210 220 137 35 60 142 239
+        220 83 222 137 209 164 212 174 195 188 108 235 158 0 251
+        215 53 72 232 121 20 116 139 19 225 174 154 190 12 107 17
+        119 219 130 199 244 255 0 10 182 236 213 161 183 40 171 147
+        237 81 142 150 210 174 172 237 217 18 40 227 82 0 5 187 212
+        174 22 216 118 158 113 234 59 26 234 132 93 108 243 231 92
+        172 209 53 180 127 188 240 78 87 156 30 213 161 217 164 25
+        154 48 24 118 49 242 113 76 193 89 99 56 237 67 205 20 120
+        199 202 125 13 55 16 8 111 196 76 140 161 37 39 25 203 14
+        213 1 234 117 1 164 101 229 74 96 55 189 88 23 183 19 70
+        204 138 137 142 217 62 181 21 215 72 134 54 150 70 183 84
+        245 221 158 63 186 183 18 176 119 162 142 235 107 139 179
+        101 112 48 74 131 149 250 213 55 169 21 153 101 109 195 118
+        226 49 87 143 197 11 59 89 172 228 240 238 163 86 11 193 86
+        242 213 7 168 41 183 153 227 13 189 119 119 20 133 31 26 4
+        138 53 225 183 114 56 162 35 249 141 99 16 93 166 190 134
+        10 199 218 177 51 11 207 221 183 218 128 179 230 224 227
+        154 97 117 242 31 181 45 179 202 206 87 215 189 82 14 145
+        135 197 65 136 103 142 40 13 74 48 116 219 220 28 255 0 70
+        122 48 73 249 67 52 22 160 196 88 93 242 60 240 56 20 89
+        132 246 173 33 176 131 211 242 147 181 25 98 164 202 55 122
+        241 90 172 99 38 202 223 63 232 146 141 137 10 48 53 33 195
+        237 36 17 76 55 59 140 28 241 86 191 194 221 82 71 187 85
+        134 86 137 241 229 144 138 169 145 73 66 203 220 28 154 150
+        252 57 214 154 199 83 71 134 72 163 97 235 39 106 198 58
+        223 67 121 30 205 68 246 178 34 103 201 57 60 49 250 84 166
+        202 250 59 114 171 42 153 28 140 2 7 97 80 110 157 214 5
+        238 147 18 27 150 57 60 113 156 126 149 55 208 161 152 66
+        38 143 136 200 198 120 57 63 173 89 164 186 57 199 169 35
+        72 23 119 0 142 213 189 35 81 233 199 181 13 8 118 33 179
+        192 224 209 101 148 32 227 154 6 62 50 174 119 99 129 233
+        74 122 130 205 110 173 152 236 11 246 29 233 163 72 161 114
+        71 21 131 48 145 10 178 239 83 233 237 65 179 45 20 167 88
+        244 52 211 91 27 203 104 80 178 18 119 122 231 218 171 11
+        187 123 200 110 31 78 189 93 162 67 243 123 87 79 107 176
+        53 157 147 186 43 75 17 238 139 232 125 234 136 248 146 177
+        73 114 100 84 96 155 185 13 195 126 181 25 70 203 225 156
+        147 164 35 210 116 152 166 184 16 52 171 42 149 202 236 247
+        170 207 226 54 139 175 105 90 204 242 61 196 190 11 28 198
+        83 149 219 237 83 222 151 214 197 133 218 194 100 240 225
+        249 67 96 114 61 170 196 212 52 152 117 189 17 90 56 209
+        212 12 238 35 56 21 60 77 73 157 83 132 226 185 72 228 251
+        45 112 139 146 26 86 59 20 134 4 156 22 162 52 205 98 226
+        222 203 242 166 62 57 186 18 54 227 193 3 211 237 83 78 185
+        248 112 99 190 184 149 45 13 188 32 231 116 125 152 213 121
+        169 104 183 182 101 130 238 0 252 153 238 5 116 62 206 120
+        228 82 123 39 58 151 88 245 117 197 134 159 165 75 124 86
+        218 24 205 202 70 184 218 7 177 53 60 215 254 43 117 237
+        199 75 232 182 247 182 18 89 199 225 44 214 243 173 187 21
+        184 10 123 130 51 199 189 115 249 107 184 36 221 151 221
+        141 188 156 241 237 82 109 7 226 31 89 104 177 71 109 109
+        172 94 4 130 217 160 129 50 8 138 54 238 160 17 218 154 133
+        88 87 254 139 31 226 175 196 126 181 234 43 13 48 94 88 61
+        132 70 63 26 222 88 247 33 125 191 196 51 233 144 106 29
+        212 157 103 212 58 189 165 140 186 165 244 83 35 32 88 176
+        131 32 47 114 126 181 19 213 186 147 168 117 153 33 159 81
+        212 174 238 154 217 12 80 120 178 110 240 211 249 71 211
+        147 66 44 55 19 90 71 181 75 159 155 25 236 115 90 135 73
+        46 221 140 238 53 67 251 78 238 95 20 178 77 146 50 121 205
+        104 210 245 75 139 217 34 181 134 232 137 3 16 192 3 154 47
+        67 232 251 173 64 201 227 187 71 35 225 148 14 248 207 106
+        185 62 27 244 16 178 195 61 132 105 48 148 18 242 96 22 95
+        214 132 163 171 4 230 170 162 7 208 29 47 125 30 141 53 238
+        172 242 178 203 251 188 30 64 199 253 232 177 103 28 123
+        100 241 137 149 120 84 110 199 239 83 126 177 191 182 208
+        237 37 183 143 116 44 56 85 36 55 24 244 170 238 202 83 123
+        118 94 66 67 19 148 106 228 116 203 168 73 18 94 153 233
+        253 83 95 144 76 202 76 46 112 163 31 227 87 31 73 116 153
+        210 204 49 204 170 14 1 194 210 111 135 23 11 20 34 8 35
+        145 159 56 201 3 21 104 90 90 27 93 175 36 126 35 176 206
+        242 79 31 74 233 199 7 86 206 60 143 97 118 241 133 77 187
+        118 129 233 239 91 90 53 199 28 125 171 21 155 60 50 225
+        171 238 252 119 170 217 42 53 58 136 187 51 42 250 129 65
+        234 23 94 12 69 100 143 35 221 123 138 60 149 151 229 20 27
+        169 71 219 252 62 223 90 1 35 215 115 43 40 113 32 251 55
+        124 84 47 171 100 186 49 179 184 154 201 65 231 124 91 149
+        170 85 173 98 202 233 252 103 42 224 121 152 199 145 223
+        251 170 186 248 147 214 183 90 125 177 91 107 171 105 7 250
+        223 246 53 138 68 162 190 47 107 186 95 138 214 49 248 190
+        48 28 73 25 198 223 211 181 87 209 0 214 161 139 51 100 247
+        110 244 87 94 106 67 88 234 55 186 240 194 31 92 113 154 14
+        73 213 85 87 233 82 4 244 244 124 133 130 190 211 235 68 52
+        89 229 73 52 2 183 155 121 163 109 174 50 160 131 233 88 17
+        102 171 131 149 35 233 75 163 27 110 179 76 238 20 96 210
+        213 254 179 85 198 149 14 54 149 179 26 231 142 61 41 102
+        163 41 252 21 194 142 194 39 166 50 168 48 131 244 165 151
+        202 63 5 63 251 167 162 251 17 183 102 122 48 63 179 160
+        224 254 233 43 126 71 137 143 90 203 72 79 252 174 220 129
+        222 36 197 18 45 198 75 17 81 101 227 217 227 251 146 61 77
+        15 111 122 246 87 65 149 118 227 187 30 213 235 171 133 141
+        128 57 237 90 226 219 121 34 110 71 40 7 56 28 154 186 143
+        40 137 47 99 167 126 4 117 157 174 161 167 172 63 153 44
+        136 120 24 171 231 78 212 65 81 225 218 249 118 231 115 28
+        0 107 144 190 28 89 173 188 130 77 54 89 34 32 231 105 56
+        39 237 138 178 180 238 161 234 84 87 102 17 76 136 48 6 9
+        199 215 154 14 60 65 197 51 163 45 102 103 1 100 216 170
+        121 5 78 69 99 169 220 54 192 163 201 236 199 214 170 77 11
+        171 245 39 17 71 112 168 23 28 248 35 183 223 62 181 53 209
+        175 226 185 45 33 153 131 255 0 44 188 98 164 251 19 36 117
+        72 147 192 159 42 72 164 38 120 62 244 112 27 80 5 35 111
+        160 165 118 19 120 142 1 96 223 202 1 230 152 44 168 80 110
+        202 243 142 105 211 64 173 30 154 21 153 25 100 25 82 48 69
+        84 255 0 18 122 82 19 35 155 101 32 179 100 10 183 3 46 56
+        96 104 109 66 202 27 200 240 200 140 222 153 173 40 218 27
+        28 169 232 228 91 238 152 186 91 147 43 63 135 20 71 60 142
+        255 0 74 125 211 93 69 117 98 88 93 200 22 221 92 4 207 160
+        171 91 173 250 76 108 150 72 227 80 51 187 143 106 165 250
+        146 41 68 141 111 29 187 8 213 253 185 205 113 188 124 37
+        103 124 36 178 42 147 44 121 46 108 53 205 177 220 69 249
+        108 155 65 247 250 212 119 170 190 23 217 155 104 37 134
+        225 10 63 203 143 240 164 218 37 252 214 58 188 112 204 228
+        64 202 48 79 189 89 90 93 253 188 177 237 89 214 103 253
+        214 210 123 15 113 245 170 71 43 229 103 52 177 46 52 138
+        27 93 248 99 116 151 210 44 86 251 160 69 196 44 163 211
+        220 84 30 247 64 107 107 182 140 171 56 31 46 7 173 118 133
+        237 180 90 149 144 93 194 54 141 118 57 42 57 250 138 137
+        106 125 33 167 197 120 100 88 86 104 216 96 101 107 174 50
+        199 37 105 28 235 179 155 116 14 140 186 212 193 240 55 51
+        49 206 208 188 226 167 125 55 240 195 54 203 45 210 186 72
+        143 198 70 55 15 122 186 52 46 153 179 177 138 55 182 217
+        20 217 228 99 140 83 173 90 104 225 84 141 97 141 86 49 134
+        36 96 181 53 165 234 138 37 201 144 171 110 135 210 116 79
+        10 226 121 20 205 225 229 4 124 130 107 238 173 212 150 246
+        54 203 105 24 72 156 55 151 216 241 254 53 171 169 181 136
+        109 237 36 219 112 30 68 114 145 166 114 77 87 147 73 121
+        168 91 139 182 87 46 210 121 71 176 174 73 101 116 209 214
+        176 213 51 45 96 106 26 245 227 195 122 216 99 204 45 232 5
+        54 233 30 147 152 202 177 205 147 199 3 20 227 163 244 134
+        213 30 40 228 140 164 138 70 25 187 26 185 250 111 167 99
+        183 132 60 209 70 37 3 154 92 80 79 108 76 217 56 233 25
+        116 63 79 219 217 233 161 221 79 138 125 79 165 74 23 229
+        25 227 28 115 88 194 137 12 33 19 140 119 175 179 58 38 55
+        56 31 90 233 163 142 105 182 99 58 163 46 230 96 160 118
+        165 215 146 52 67 197 102 150 48 222 168 51 69 207 44 126
+        25 60 176 250 14 212 174 246 96 84 171 178 178 5 200 32 240
+        69 103 163 40 114 26 137 15 135 230 81 199 203 187 179 80
+        83 95 73 202 136 33 56 255 0 91 154 134 235 29 68 108 99 48
+        219 9 166 0 124 199 24 63 110 106 11 172 117 110 189 53 203
+        197 225 196 233 140 169 112 114 181 135 88 210 44 46 168
+        215 33 143 79 157 228 73 85 84 16 222 249 250 87 37 124 96
+        235 11 91 205 78 75 11 75 153 21 131 19 137 70 56 171 39 86
+        212 53 237 70 57 32 188 185 82 161 14 28 13 187 87 254 188
+        213 69 213 58 29 188 241 201 42 67 113 123 118 92 225 136 0
+        99 251 107 112 79 232 106 136 45 172 37 228 105 14 112 123
+        31 122 33 161 221 231 60 55 108 125 40 217 99 104 81 97 112
+        145 183 177 239 65 22 96 73 244 237 74 218 163 27 60 53 9
+        206 43 43 104 195 112 57 172 21 183 33 251 215 212 98 157
+        142 13 32 12 175 65 7 145 74 155 137 197 57 148 111 83 187
+        154 73 38 127 24 71 165 60 69 147 25 187 226 49 142 120 165
+        247 103 117 189 217 247 183 113 250 209 172 165 163 31 106
+        22 244 40 211 231 199 205 225 62 105 133 25 233 30 109 42
+        213 113 140 198 159 225 154 57 216 44 44 48 59 119 160 52
+        103 85 211 44 148 142 76 8 127 93 180 85 196 171 225 242 42
+        71 74 116 70 181 2 242 94 14 113 199 97 247 169 87 65 219
+        36 215 177 195 40 220 8 228 47 113 253 180 141 109 252 107
+        213 37 60 184 239 237 83 174 143 211 149 39 87 0 110 35 200
+        195 131 138 180 102 170 137 190 236 187 58 103 166 236 35
+        48 52 114 32 24 221 133 249 170 91 107 165 194 210 5 148 4
+        24 192 56 168 247 77 204 176 89 68 222 55 138 83 229 76 14
+        126 149 52 209 238 55 145 226 76 129 217 126 87 3 129 90 82
+        85 70 74 194 44 116 24 227 153 78 119 103 182 208 48 71 214
+        155 92 104 236 214 174 17 76 111 252 203 220 211 109 38 72
+        100 140 6 240 164 218 118 249 123 230 152 203 11 109 9 28
+        140 152 244 32 100 84 69 110 136 158 149 251 66 218 111 194
+        218 184 47 158 78 114 5 72 45 159 86 128 156 172 114 40 93
+        204 199 57 253 41 93 196 81 199 127 137 15 131 38 120 34
+        155 219 106 64 58 195 28 121 80 57 111 115 72 60 23 137 178
+        29 74 89 38 86 154 45 171 252 195 176 251 209 173 121 8 5
+        150 64 9 249 72 245 173 55 48 174 4 182 234 178 49 30 104
+        207 111 191 222 180 189 188 19 219 238 145 124 39 95 238
+        166 78 76 87 75 160 203 219 113 121 98 20 190 254 57 35 214
+        161 183 93 11 13 220 146 220 54 84 224 236 80 7 38 165 58
+        35 53 189 185 93 199 104 244 166 73 134 1 135 108 230 179
+        175 160 230 215 69 41 170 244 5 221 179 37 204 176 248 171
+        17 59 84 14 231 235 81 248 244 109 67 78 159 196 11 34 144
+        251 184 245 174 141 101 220 140 49 201 239 154 73 168 104
+        208 238 105 240 173 207 153 113 72 240 193 236 172 103 162
+        162 147 168 46 237 252 56 132 78 217 143 156 131 205 101
+        107 212 23 37 89 165 134 70 77 222 78 15 53 53 189 211 108
+        154 225 166 107 120 194 42 144 191 65 65 219 221 104 214 54
+        107 248 235 88 252 36 82 219 206 125 234 111 148 53 101 249
+        127 194 40 122 138 227 204 86 41 3 231 142 15 106 211 125
+        123 169 234 176 162 109 146 54 3 146 163 189 74 236 166 211
+        53 75 176 109 97 70 129 135 151 138 145 105 90 109 177 111
+        195 248 9 145 242 253 41 146 151 105 153 78 190 21 78 149
+        210 55 151 72 200 33 98 31 141 199 146 15 189 75 116 79 135
+        114 8 209 111 35 196 123 118 140 119 31 90 179 52 205 54 27
+        24 246 140 125 168 227 207 113 84 73 62 200 203 249 18 122
+        100 95 167 186 102 29 46 97 225 64 133 23 213 187 231 222
+        164 83 203 28 108 25 164 31 111 122 251 43 108 224 71 147
+        239 154 80 109 218 109 77 228 152 17 30 121 25 239 77 72
+        156 83 126 193 247 23 107 26 144 60 205 232 40 24 111 174
+        166 111 14 8 145 142 78 75 103 138 222 87 50 5 130 208 2 59
+        190 79 21 153 11 103 110 207 18 6 62 173 236 105 28 218 10
+        236 85 123 38 178 45 252 88 165 81 144 67 32 30 148 134 222
+        198 235 80 184 114 210 22 10 249 108 30 62 195 233 79 46 46
+        86 123 98 100 102 137 7 30 94 228 214 26 28 69 220 52 56 95
+        109 180 109 181 108 51 175 245 23 221 104 208 203 25 13 31
+        229 129 194 251 210 27 221 6 56 84 182 239 46 120 12 163 2
+        172 115 20 110 160 110 19 183 169 110 21 62 216 168 230 179
+        52 101 156 43 64 138 157 234 170 104 69 127 74 251 80 209
+        225 184 180 144 51 194 168 14 15 166 106 191 234 221 39 75
+        179 211 165 184 146 21 154 112 126 84 98 23 245 171 39 87
+        185 202 186 49 71 82 114 25 71 106 174 122 230 37 156 40 50
+        77 55 180 64 0 15 246 86 228 53 20 87 81 74 130 251 153 35
+        67 39 101 143 36 99 238 104 9 50 234 54 142 213 35 235 13
+        19 195 45 36 96 65 27 252 170 57 231 245 168 229 186 201 20
+        4 73 195 103 24 247 20 128 122 116 122 47 148 253 235 9 178
+        172 72 247 172 226 32 3 159 122 215 63 53 128 213 133 195
+        34 136 200 60 253 233 61 209 254 151 156 12 102 155 69 26
+        176 198 222 244 166 249 130 92 5 250 211 196 70 168 105 11
+        47 131 230 224 80 87 255 0 212 238 63 221 191 248 86 208
+        219 160 3 210 133 190 99 248 41 249 255 0 210 122 167 17 92
+        141 118 127 137 253 159 1 207 30 18 86 196 51 186 156 182
+        87 212 211 13 50 12 216 64 27 31 186 76 140 246 162 217 225
+        136 120 123 80 41 224 115 206 106 40 232 98 43 123 241 111
+        55 242 128 113 147 235 86 7 70 235 76 246 230 31 197 68 140
+        195 200 164 237 96 62 135 214 163 182 90 28 218 158 99 130
+        221 164 59 178 0 198 15 235 239 83 110 151 232 9 102 141 45
+        238 237 102 138 39 28 156 252 191 98 41 210 160 39 68 255 0
+        165 250 138 212 58 193 170 73 178 233 134 228 73 134 1 30
+        245 97 104 186 198 154 206 169 103 118 214 236 71 158 25
+        198 232 228 63 70 244 168 62 133 208 169 21 164 118 179 70
+        211 148 27 99 71 200 199 234 65 53 34 178 233 77 74 194 47
+        232 114 58 143 68 151 133 31 99 89 171 11 157 178 203 176
+        99 185 30 56 210 54 198 74 171 102 50 61 193 247 166 203
+        120 56 63 32 61 188 78 23 244 53 94 105 26 213 214 151 34
+        65 172 88 220 66 190 147 198 165 215 63 92 122 84 202 206
+        234 75 168 188 68 219 34 158 79 151 1 190 191 74 70 19 118
+        187 11 222 67 44 177 177 18 6 220 184 239 75 186 90 250 71
+        102 183 153 124 225 176 64 244 250 211 153 97 142 226 50
+        193 164 82 7 96 188 138 91 106 39 134 247 250 138 202 231
+        141 231 130 71 181 35 84 131 21 240 154 167 49 34 238 13
+        199 24 160 103 45 29 214 214 82 84 247 241 56 81 69 217 110
+        49 40 48 52 89 28 140 19 254 21 246 250 214 73 151 104 141
+        217 125 8 28 212 219 108 77 38 107 71 120 216 109 66 69 16
+        38 82 128 134 28 156 80 86 73 58 66 99 117 124 158 57 70
+        255 0 181 100 201 60 78 89 81 153 49 200 8 114 63 186 130
+        116 48 99 44 138 63 45 178 123 226 132 186 185 120 226 220
+        97 102 63 196 69 97 52 178 170 171 68 178 242 57 204 109
+        255 0 106 85 169 92 92 179 21 69 112 185 231 32 138 22 195
+        24 41 50 63 213 151 154 140 182 87 118 246 208 73 27 225
+        138 101 126 149 203 122 183 93 117 30 165 38 161 167 94 204
+        208 248 19 164 109 30 48 78 61 8 174 179 185 188 189 92 25
+        97 105 87 248 252 157 197 85 223 17 250 3 72 234 125 66 13
+        98 214 217 180 157 71 112 23 37 99 32 78 61 73 24 239 79 39
+        25 157 120 230 177 233 171 1 248 55 105 213 17 233 144 222
+        220 248 50 217 52 132 194 7 204 23 255 0 154 187 244 141 66
+        229 131 52 208 177 193 218 131 28 154 143 104 115 197 97
+        103 13 142 159 96 237 28 40 168 143 225 156 240 63 252 52
+        217 46 47 152 134 48 50 182 253 196 178 145 71 81 68 114 91
+        118 137 97 184 157 190 85 49 159 102 172 252 67 180 110 96
+        88 154 77 109 119 50 219 170 24 228 45 252 71 109 24 101
+        102 64 162 57 11 247 225 73 197 73 79 147 209 37 141 160
+        167 186 40 14 197 220 115 130 7 165 7 113 54 223 48 243 159
+        85 126 194 182 71 11 42 110 109 229 255 0 216 108 127 133
+        105 72 101 150 243 196 145 88 133 236 2 54 15 247 83 59 176
+        85 5 105 241 55 134 93 243 188 118 52 46 171 34 67 3 185
+        145 93 199 101 3 36 83 68 142 84 92 172 100 125 233 38 189
+        36 203 4 135 240 108 231 30 163 138 165 94 128 145 12 135
+        241 90 158 160 99 86 111 12 54 91 105 201 21 39 134 85 183
+        137 98 82 177 198 6 60 79 251 82 189 46 217 152 134 104 12
+        1 142 78 208 114 104 235 213 217 228 142 57 60 188 6 101
+        237 246 166 173 81 154 62 94 77 44 150 225 83 42 23 213 199
+        155 244 21 29 213 174 34 181 133 247 220 69 1 3 45 52 190
+        103 31 65 255 0 106 47 91 215 45 44 81 252 95 21 220 29 171
+        26 33 44 199 219 21 16 190 126 161 214 8 240 109 13 165 190
+        237 202 146 99 113 250 241 154 41 1 161 62 179 175 104 240
+        69 36 239 49 42 23 205 52 173 134 99 238 61 170 187 215 53
+        233 37 34 230 214 241 150 215 186 60 131 195 76 125 9 239
+        86 14 163 209 114 73 40 146 238 54 109 195 45 189 72 254
+        193 138 135 117 47 195 150 190 148 93 78 178 76 35 253 216
+        201 217 143 246 79 21 130 138 135 172 58 169 217 198 39 142
+        64 252 43 3 197 34 211 238 191 16 134 70 238 220 131 232 69
+        75 117 206 133 188 138 228 205 37 140 174 15 206 242 112
+        168 61 197 71 36 129 44 93 193 85 69 221 181 85 152 3 143
+        240 166 143 96 146 189 131 187 237 63 74 196 29 195 53 186
+        102 73 6 236 167 232 192 255 0 133 106 85 227 140 99 239 79
+        45 128 38 30 212 162 251 139 174 120 230 156 64 8 250 15
+        189 1 168 70 11 124 188 147 223 35 20 189 9 35 116 37 90
+        223 5 128 29 243 65 234 18 255 0 67 184 255 0 116 244 90 41
+        16 1 142 195 222 151 106 24 252 61 194 110 27 188 54 227 61
+        179 78 165 162 110 34 139 47 220 55 251 165 160 238 251 175
+        251 85 234 245 73 118 116 190 131 109 63 174 219 83 53 253
+        234 126 181 234 245 80 80 139 143 222 15 189 122 95 221 143
+        189 122 189 88 198 235 207 234 95 253 163 252 107 86 155
+        251 179 246 175 87 169 31 209 144 77 191 121 255 0 217 173
+        49 127 90 95 246 133 122 189 74 198 143 99 214 236 104 22
+        253 243 125 235 213 234 148 69 126 198 211 251 197 175 79
+        251 179 94 175 80 8 60 191 187 95 181 100 191 184 74 245
+        122 153 244 62 46 204 26 180 183 239 79 218 189 94 166 47
+        30 205 144 126 248 81 147 250 215 171 213 136 100 236 244
+        63 45 125 184 253 239 255 0 109 122 189 80 143 177 51 91
+        252 181 157 167 205 94 175 85 95 208 154 161 175 147 126
+        234 111 246 63 235 94 175 83 46 204 129 173 191 131 237 91
+        117 15 221 138 245 122 156 192 58 215 249 246 111 247 149
+        242 127 221 39 251 85 234 245 17 88 116 223 212 135 218 148
+        220 254 224 87 171 212 16 77 109 253 105 105 76 159 214 222
+        189 94 162 140 205 87 255 0 50 255 0 179 88 71 242 10 245
+        122 156 64 133 253 217 161 174 254 85 255 0 106 189 94 165
+        125 139 35 47 253 58 105 99 253 68 255 0 186 175 87 168 174
+        133 63 255 217 13 10 45 45 45 45 45 45 45 45 45 45 45 45 45
+        45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 49 49 51 55
+        53 50 50 53 48 51 49 52 52 49 50 56 50 51 50 55 49 54 53 51
+        49 55 50 57 13 10 67 111 110 116 101 110 116 45 68 105 115
+        112 111 115 105 116 105 111 110 58 32 102 111 114 109 45
+        100 97 116 97 59 32 110 97 109 101 61 34 102 105 108 101 50
+        34 59 32 102 105 108 101 110 97 109 101 61 34 116 101 115
+        116 46 116 120 116 34 13 10 67 111 110 116 101 110 116 45
+        84 121 112 101 58 32 116 101 120 116 47 112 108 97 105 110
+        13 10 13 10 116 101 115 116 10 13 10 45 45 45 45 45 45 45
+        45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45
+        45 45 49 49 51 55 53 50 50 53 48 51 49 52 52 49 50 56 50 51
+        50 55 49 54 53 51 49 55 50 57 13 10 67 111 110 116 101 110
+        116 45 68 105 115 112 111 115 105 116 105 111 110 58 32 102
+        111 114 109 45 100 97 116 97 59 32 110 97 109 101 61 34 102
+        105 108 101 51 34 59 32 102 105 108 101 110 97 109 101 61
+        34 34 13 10 67 111 110 116 101 110 116 45 84 121 112 101 58
+        32 97 112 112 108 105 99 97 116 105 111 110 47 111 99 116
+        101 116 45 115 116 114 101 97 109 13 10 13 10 13 10 45 45
+        45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45
+        45 45 45 45 45 45 45 49 49 51 55 53 50 50 53 48 51 49 52 52
+        49 50 56 50 51 50 55 49 54 53 51 49 55 50 57 45 45 13 10
+    } ;
 
-[ { "a" "zzb" "zzc" "zzd" f } ] [
-    [
-        "azzbzzczzdzzz" <string-reader> "zzz" <multipart-stream> 3 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
+: test-file ( bytes -- seq )
+    binary <byte-reader> parse-multipart ;
 
-[ { "az" "zbzz" "czzd" f } ] [
-    [
-        "azzbzzczzdzzz" <string-reader> "zzz" <multipart-stream> 4 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
+: test-file1 ( bytes -- ? )
+    test-file
+    first [ filename>> "dog.jpg" = ] [ name>> "file1" = ]
+    [ path>> md5 checksum-file B{ 172 192 179 2 18 210 155 156 115 186 169 30 147 51 91 82 } = ] tri and and ;
 
-[ { "azz" "bzzcz" "zd" f } ] [
-    [
-        "azzbzzczzdzzz" <string-reader> "zzz" <multipart-stream> 5 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
+: test-file2 ( bytes -- ? )
+    test-file
+    second [ filename>> "test.txt" = ] [ name>> "file2" = ]
+    [ path>> ascii file-contents "test\n" = ] tri and and ;
 
+: test-file3 ( bytes -- ? )
+    test-file
+    third [ filename>> "" = ]
+    [ name>> "file3" = ]
+    [ path>> file-info size>> 0 = ] tri and and ;
 
-: dog-upload ( -- string )
-    B{
-        45 45 45 45 45 45 87 101 98 75 105 116 70 111 114 109 66
-        111 117 110 100 97 114 121 115 105 103 113 43 53 113 87 116
-        54 79 114 122 56 76 79 13 10 67 111 110 116 101 110 116 45
-        68 105 115 112 111 115 105 116 105 111 110 58 32 102 111
-        114 109 45 100 97 116 97 59 32 110 97 109 101 61 34 102 105
-        108 101 34 59 32 102 105 108 101 110 97 109 101 61 34 100
-        111 103 46 106 112 103 34 13 10 67 111 110 116 101 110 116
-        45 84 121 112 101 58 32 105 109 97 103 101 47 106 112 101
-        103 13 10 13 10 253 253 253 253 0 16 74 70 73 70 0 1 1 0 0
-        1 0 1 0 0 253 253 0 67 0 5 3 4 4 4 3 5 4 4 4 5 5 5 6 7 12 8
-        7 7 7 7 15 11 11 9 12 17 15 18 18 17 15 17 17 19 22 28 23
-        19 20 26 21 17 17 24 33 24 26 29 29 31 31 31 19 23 34 36 34
-        30 36 28 30 31 30 253 253 0 67 1 5 5 5 7 6 7 14 8 8 14 30
-        20 17 20 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
-        30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
-        30 30 30 30 30 30 30 30 30 30 30 30 30 253 253 0 17 8 1 49
-        1 64 3 1 34 0 2 17 1 3 17 1 253 253 0 29 0 0 2 2 3 1 1 1 0
-        0 0 0 0 0 0 0 0 4 5 6 7 2 3 8 0 1 9 253 253 0 74 16 0 2 1 3
-        3 2 4 4 3 4 5 10 5 3 5 1 1 2 3 0 4 17 5 18 33 6 49 19 34 65
-        81 7 50 97 113 20 35 253 21 51 66 82 36 52 253 253 253 8 53
-        83 98 114 115 253 253 253 253 22 37 67 116 253 99 253 253
-        23 68 84 100 253 253 253 253 0 25 1 0 3 1 1 1 0 0 0 0 0 0 0
-        0 0 0 0 1 2 3 0 4 5 253 253 0 39 17 0 2 2 2 2 3 0 2 1 5 1 0
-        0 0 0 0 0 1 2 17 3 33 18 49 34 50 65 19 81 4 5 20 35 66 97
-        82 253 253 0 12 3 1 0 2 17 3 17 0 63 0 253 253 253 253 253
-        253 253 253 253 68 253 253 112 60 21 45 253 91 253 57 253
-        253 253 75 56 95 111 253 253 51 253 253 11 253 253 14 118
-        253 22 253 253 104 253 118 82 46 253 45 253 98 79 253 102
-        253 38 253 98 253 64 253 253 72 253 49 46 104 11 8 253 111
-        253 253 253 253 70 253 12 253 112 61 253 57 36 253 31 82 7
-        253 253 78 253 253 253 253 0 253 41 100 253 76 15 253 253
-        118 60 31 253 85 253 126 253 253 253 253 253 253 113 253 66
-        253 253 253 82 74 49 45 253 253 42 49 253 253 253 108 253
-        99 21 68 253 88 116 253 83 17 253 253 253 253 109 253 253
-        253 6 253 83 253 109 1 253 115 253 10 253 90 106 23 106 253
-        95 59 73 253 253 77 44 111 89 79 253 24 253 253 253 253 86
-        253 253 71 253 20 52 253 253 253 24 253 253 253 253 61 253
-        66 253 65 253 253 253 64 253 5 253 127 253 45 3 99 42 253
-        42 253 253 79 253 83 253 38 86 92 21 57 20 76 253 253 78
-        253 98 88 31 253 253 125 253 253 45 108 253 253 97 253 0
-        253 44 253 0 253 45 22 253 253 253 253 99 88 74 98 77 99 78
-        253 69 111 14 253 253 23 28 253 48 15 253 253 30 253 21 253
-        105 8 253 253 103 253 253 253 253 121 253 127 253 87 253
-        253 253 253 31 253 253 253 253 253 28 88 253 253 120 99 253
-        52 100 253 0 253 253 253 253 108 109 11 103 253 253 127 253
-        253 118 82 71 253 47 253 253 253 11 253 30 74 81 253 102
-        253 253 35 253 97 104 62 253 46 104 41 45 109 119 127 86
-        253 253 21 48 253 253 9 253 104 105 253 24 118 53 76 77 81
-        253 73 105 109 253 253 253 127 253 21 253 89 253 110 63 253
-        97 253 0 253 69 65 253 110 15 39 253 253 253 253 253 41 6
-        253 102 5 22 54 253 114 109 45 253 123 24 253 53 253 45 44
-        253 253 79 253 253 253 253 253 118 101 112 253 253 253 102
-        253 253 253 35 253 99 95 253 253 119 253 253 253 253 253 21
-        18 253 125 253 92 253 2 253 253 16 253 15 253 253 253 71 46
-        253 253 106 253 78 253 40 253 253 109 83 33 45 253 253 253
-        253 253 253 253 253 30 253 253 69 45 37 253 253 253 253 12
-        253 253 253 253 253 253 253 8 75 123 253 15 69 96 7 253 253
-        253 253 253 31 253 253 253 253 253 102 120 253 0 68 253 253
-        253 253 12 15 253 253 253 253 253 253 253 253 253 253 253
-        253 7 253 123 80 253 253 253 118 253 66 253 253 118 62 253
-        253 253 38 91 55 253 253 253 253 60 253 22 96 14 253 253
-        107 84 253 69 253 253 253 253 100 253 0 65 18 253 43 253 82
-        105 253 253 108 64 253 31 102 253 253 253 253 253 253 253
-        39 253 73 38 50 84 253 253 112 253 19 253 4 118 54 253 253
-        22 33 68 54 253 253 52 96 253 253 253 15 115 16 253 66 253
-        253 77 253 253 40 115 253 90 253 91 73 253 116 253 29 253
-        77 253 253 253 253 46 64 109 253 88 45 253 31 253 253 92
-        127 253 253 19 97 99 253 16 253 125 253 253 63 253 20 100
-        253 56 253 253 253 66 84 253 253 253 253 253 253 253 125 18
-        253 125 253 253 108 72 7 253 125 253 63 253 45 109 253 77
-        253 253 253 111 253 253 0 253 253 68 76 253 253 253 51 253
-        103 43 0 253 253 253 253 72 253 253 54 113 253 5 91 120 50
-        59 253 77 7 120 109 253 48 22 8 1 253 253 98 253 106 253
-        253 253 45 253 253 253 93 41 97 253 253 73 97 253 96 19 253
-        103 253 253 23 253 253 253 71 253 93 253 253 110 117 101 67
-        90 253 253 253 55 253 97 253 253 37 122 124 253 253 48 118
-        253 253 81 66 116 253 82 123 2 253 103 108 55 30 99 31 253
-        253 253 253 63 56 253 253 253 253 26 90 253 253 56 20 109
-        253 253 89 16 253 253 80 253 253 80 49 253 110 253 63 253
-        253 253 107 74 62 44 253 36 253 253 17 253 253 253 253 26
-        253 253 253 253 21 40 253 113 253 253 253 253 253 53 253
-        253 63 253 57 253 253 85 55 253 34 5 87 126 124 253 123 26
-        253 15 253 253 42 253 59 108 123 112 51 27 14 253 90 253 61
-        68 253 253 253 253 58 35 7 253 253 57 253 253 253 91 25 82
-        71 24 253 0 253 44 253 253 21 253 99 16 253 120 253 253 253
-        97 253 253 99 81 253 5 253 74 253 253 29 253 253 253 99 121
-        253 253 80 127 253 253 253 22 253 96 121 19 84 253 253 253
-        253 77 106 61 62 253 25 35 114 253 253 1 253 43 253 253 253
-        72 71 24 56 253 125 107 253 253 253 253 253 253 93 61 253
-        35 76 253 42 43 253 253 253 253 253 58 123 85 253 9 37 67
-        103 63 74 117 39 123 37 253 26 110 253 20 14 64 53 253 253
-        253 253 22 253 21 253 253 111 83 69 22 80 72 253 89 253 103
-        61 253 253 117 60 253 121 15 253 253 253 253 8 23 253 253
-        253 253 253 253 36 253 11 253 253 28 85 123 253 253 93 64
-        253 57 52 99 32 253 45 89 253 15 253 253 253 46 253 253 60
-        253 253 48 43 69 253 253 24 253 109 253 61 253 21 57 118 96
-        253 57 92 253 52 43 253 253 253 126 253 68 18 3 88 253 253
-        253 253 108 253 253 8 107 64 62 65 253 253 253 253 91 25
-        253 253 39 38 253 253 99 253 122 253 112 253 118 59 253 83
-        253 114 54 59 46 253 253 89 39 253 90 93 89 88 115 253 110
-        64 74 113 83 253 253 5 59 62 253 35 253 253 16 253 253 124
-        109 253 123 253 253 19 13 253 35 38 253 253 69 62 253 105
-        253 253 0 253 253 85 253 253 82 253 253 253 60 103 253 77
-        253 253 253 66 253 98 253 253 82 253 73 24 253 45 34 81 253
-        253 75 44 253 253 7 114 72 110 253 253 36 73 12 42 253 253
-        253 253 73 52 253 253 253 253 253 253 253 253 113 253 253
-        49 253 90 253 124 40 253 122 110 253 253 253 65 66 12 48
-        253 253 253 94 54 253 61 253 253 94 28 123 10 253 10 78 59
-        253 253 109 253 58 253 8 253 253 253 253 19 73 53 253 86 80
-        253 253 253 1 253 107 253 253 77 101 105 103 51 253 253 36
-        253 24 25 39 253 0 253 93 18 253 253 18 253 253 253 30 253
-        253 85 253 253 109 39 253 253 253 253 110 8 253 253 253 253
-        253 253 253 14 253 253 27 66 253 60 46 54 110 5 72 31 253
-        82 253 57 253 72 253 253 253 64 253 70 127 253 13 253 253
-        107 253 253 253 5 253 91 253 253 253 58 75 253 253 48 72 36
-        47 117 253 71 39 113 4 23 253 253 253 253 96 100 114 107 24
-        253 253 126 62 253 253 101 57 253 253 89 70 6 7 2 253 253
-        35 253 71 102 253 84 40 253 253 110 57 38 253 253 3 253 86
-        19 1 253 253 253 253 253 34 253 253 253 253 100 253 253 253
-        52 121 77 253 253 253 67 117 253 253 253 253 253 17 253 81
-        253 253 116 52 72 253 253 253 253 21 253 253 126 30 79 76
-        46 253 62 253 16 27 253 7 34 55 253 55 63 253 116 253 253
-        118 253 117 253 253 127 253 253 253 253 15 13 127 253 253
-        16 10 253 253 253 69 43 253 253 253 88 23 253 71 70 32 110
-        253 253 253 253 25 99 99 253 78 127 253 253 253 253 253 253
-        253 253 86 35 253 253 42 253 253 253 253 50 65 253 253 53 9
-        89 253 253 253 253 253 253 253 253 54 61 100 68 118 253 86
-        253 89 253 253 121 253 72 1 2 253 253 253 253 253 253 70
-        253 253 28 253 253 253 253 253 253 92 253 253 253 87 23 253
-        92 253 253 253 253 253 121 253 253 107 253 253 103 253 253
-        35 253 253 253 253 84 6 99 253 85 36 253 34 253 98 253 34
-        100 89 89 253 43 6 97 253 35 253 253 95 94 86 17 2 253 56
-        253 105 119 253 253 253 253 253 39 253 253 27 253 16 95 113
-        79 95 253 16 253 30 253 253 253 11 253 60 253 59 253 75 253
-        103 77 91 253 58 101 253 253 253 253 253 253 253 253 78 97
-        253 253 253 253 253 10 31 65 253 253 253 100 253 21 253 253
-        253 29 253 5 87 253 253 110 253 109 31 80 253 36 111 32 39
-        57 253 57 253 77 253 253 92 69 253 253 49 253 126 253 105
-        124 86 253 27 125 70 22 253 253 253 9 2 253 253 253 53 76
-        66 38 253 253 65 109 48 111 8 253 18 123 81 253 20 253 253
-        101 253 253 253 253 94 253 14 253 105 27 253 106 253 253 20
-        11 253 125 51 253 253 253 70 253 253 104 253 87 28 85 117
-        117 253 117 253 253 253 84 87 253 253 26 253 108 253 5 3
-        253 77 253 78 253 74 253 253 253 7 253 115 18 253 253 253
-        253 33 27 48 253 64 24 26 253 126 13 108 253 253 253 253 9
-        253 79 106 26 92 253 253 253 253 253 93 253 124 253 48 107
-        34 253 39 253 253 253 0 253 122 253 253 253 253 253 65 253
-        253 27 253 24 253 101 253 40 253 253 253 49 253 90 109 85
-        29 124 253 253 253 253 19 28 98 253 123 253 253 64 46 253
-        13 122 22 253 39 28 253 253 86 253 253 4 19 90 1 253 253 50
-        28 253 253 52 91 253 253 55 253 62 253 56 91 68 253 88 110
-        253 30 253 37 253 49 253 253 106 58 253 51 73 253 253 119
-        19 253 253 253 253 61 253 253 253 12 253 253 79 253 57 32
-        253 253 51 253 253 90 253 65 253 253 253 8 253 0 51 104 46
-        125 106 115 253 78 253 124 17 113 253 253 37 26 85 253 122
-        109 253 113 68 253 96 49 253 253 125 253 253 85 59 90 64
-        119 124 253 253 253 43 5 43 253 31 79 253 10 253 36 44 26
-        70 253 253 253 30 253 253 253 253 253 253 253 10 253 98 253
-        253 253 253 253 253 253 28 253 253 88 122 253 253 253 253
-        253 52 253 253 88 98 253 253 253 253 36 46 112 15 53 253 56
-        253 253 65 253 0 253 77 253 253 69 253 118 253 253 253 54
-        118 253 253 253 116 73 72 253 253 253 253 253 253 253 31
-        253 22 18 253 26 36 253 2 72 21 60 253 64 253 253 253 106
-        253 253 67 38 253 37 36 253 253 51 90 91 253 253 104 253 13
-        18 253 253 253 253 127 46 43 5 253 253 253 253 55 127 253
-        253 253 43 85 253 100 253 253 253 94 71 20 253 253 103 23
-        43 253 125 253 84 253 253 253 253 253 253 43 100 253 40 253
-        9 22 253 253 45 253 253 253 253 253 253 40 93 79 253 67 62
-        253 253 22 253 253 1 253 96 53 98 253 253 12 253 253 253
-        253 3 253 102 81 253 71 82 41 99 12 59 253 74 117 91 114 45
-        253 117 31 253 103 253 253 253 253 253 45 55 44 17 99 253
-        29 23 12 253 28 6 3 20 20 19 127 71 253 253 253 42 253 28
-        253 253 7 253 253 103 253 253 0 253 253 253 253 120 253 3
-        12 12 253 69 111 253 253 253 253 66 253 36 253 90 253 253
-        253 253 253 253 74 253 89 253 67 123 11 6 57 253 21 63 253
-        253 253 68 253 253 110 253 102 253 253 253 253 253 253 60
-        253 253 253 253 253 253 253 253 253 253 253 15 25 253 253
-        253 39 253 43 63 15 79 19 76 7 253 253 253 253 253 30 253
-        50 253 43 42 253 48 253 253 253 253 253 55 253 71 253 253
-        97 253 253 28 99 253 253 69 117 30 253 31 105 30 253 253 46
-        253 253 75 253 253 253 253 253 253 60 253 70 253 253 80 253
-        253 75 253 34 253 101 253 54 253 25 102 253 55 70 35 3 253
-        118 253 108 39 87 253 66 253 108 61 253 253 253 253 253 119
-        82 49 253 253 253 123 10 253 253 82 89 36 88 253 253 38 253
-        121 37 76 253 253 253 123 36 253 253 253 253 253 20 253 60
-        61 253 253 72 253 253 127 253 23 70 253 253 253 253 253 253
-        107 103 253 253 253 253 70 86 253 66 28 253 3 253 26 58 253
-        253 43 253 66 92 66 253 79 253 115 253 108 56 253 253 105
-        253 115 105 60 253 253 253 23 80 253 253 71 5 253 122 253
-        253 253 253 29 253 42 253 22 253 253 253 253 253 253 253
-        253 70 253 45 21 81 253 253 253 10 253 253 253 71 253 253
-        77 253 49 8 253 84 253 253 35 253 93 112 253 253 253 253 60
-        93 253 116 37 253 39 10 0 126 41 253 119 81 1 253 253 22
-        120 253 35 92 253 253 253 253 253 253 33 253 253 65 87 253
-        253 13 50 87 253 253 253 253 126 253 253 253 253 253 253 10
-        253 46 253 253 115 253 72 253 253 253 41 253 253 253 67 253
-        9 51 12 253 253 114 253 82 120 106 56 113 80 253 253 72 88
-        5 76 31 253 20 253 253 253 253 253 253 253 50 102 37 118
-        253 253 253 253 253 253 253 18 71 253 253 253 253 84 119
-        253 1 73 253 49 253 253 253 253 110 253 253 106 253 253 104
-        253 74 29 253 253 253 253 29 253 89 253 58 77 253 253 253
-        253 20 112 253 253 125 253 6 253 253 253 75 253 253 65 36
-        113 253 253 9 0 253 253 15 253 253 19 79 253 253 79 42 25
-        253 253 253 31 74 76 253 253 71 84 49 253 253 253 253 68
-        253 253 253 253 253 6 253 56 86 28 253 253 45 253 253 253
-        253 66 253 30 61 253 253 253 253 253 253 26 15 40 39 253
-        253 107 253 22 253 253 46 37 36 124 253 127 253 253 83 91
-        118 86 253 253 253 14 253 253 253 103 253 253 253 253 253
-        253 253 48 86 39 253 253 253 253 253 253 253 56 17 91 253
-        253 81 253 17 88 53 253 253 253 28 114 56 92 122 253 253 27
-        253 253 253 253 24 253 253 253 43 85 253 50 253 14 15 36
-        253 87 109 34 253 27 253 121 253 54 108 253 253 12 118 253
-        82 253 253 253 112 253 253 253 253 253 253 77 30 118 120
-        253 253 253 253 122 253 48 107 54 253 103 253 253 253 253
-        253 253 253 253 253 253 253 253 101 109 50 82 253 253 253
-        253 253 115 71 253 11 55 253 253 253 88 253 17 253 253 1
-        253 253 253 253 57 102 253 68 107 48 54 253 27 24 253 68 15
-        114 49 253 253 253 253 19 37 253 253 38 253 253 120 10 253
-        253 86 253 253 108 253 123 9 253 253 253 253 253 253 253
-        253 59 253 253 70 49 253 73 253 253 91 80 99 253 253 62 253
-        253 253 253 111 253 75 253 24 253 253 253 253 90 109 103 31
-        253 97 253 115 84 253 28 253 40 253 253 117 253 100 12 118
-        253 253 253 253 253 92 48 253 34 39 253 253 253 253 14 24
-        253 49 64 253 253 253 78 253 87 253 253 61 43 84 253 253 94
-        55 253 253 253 253 253 61 253 253 89 101 253 16 108 61 253
-        253 253 253 253 253 11 253 253 253 253 91 253 253 253 100
-        86 32 119 253 109 80 30 253 95 79 253 253 30 253 253 253
-        253 127 18 253 0 101 110 253 23 253 43 253 253 107 253 5
-        253 253 30 119 29 253 54 44 125 253 127 253 28 119 253 73
-        72 253 253 40 253 60 31 122 253 253 253 253 38 253 253 3 32
-        253 119 253 21 253 253 253 12 253 67 115 253 84 253 91 253
-        253 97 89 64 253 32 253 84 253 253 119 67 253 253 53 253 38
-        253 30 25 253 112 253 29 69 63 48 253 73 253 65 253 83 13
-        65 48 37 1 124 253 253 253 55 61 253 40 20 109 253 253 90
-        253 253 4 253 78 253 70 24 83 253 253 80 253 253 69 16 253
-        14 14 87 253 104 11 253 104 253 90 118 5 84 253 253 125 253
-        253 126 253 253 21 253 253 69 253 4 103 13 253 253 253 253
-        253 70 55 253 38 88 253 39 253 13 253 253 34 253 33 253 253
-        253 253 253 253 253 253 121 253 85 1 97 253 112 253 90 253
-        90 253 253 253 64 27 45 253 253 127 253 253 253 253 253 98
-        253 253 253 253 77 253 253 99 70 253 253 253 99 253 253 253
-        43 123 77 62 84 37 70 88 253 53 253 253 20 122 253 253 253
-        127 253 100 102 12 71 7 253 253 253 253 80 253 253 123 253
-        93 92 253 90 92 48 253 126 11 3 85 253 253 52 253 72 253 36
-        253 253 253 125 105 253 26 253 253 253 253 253 48 75 253 26
-        50 253 31 253 253 86 253 253 253 120 114 70 67 253 253 253
-        253 123 78 253 253 253 25 60 57 29 36 94 123 112 125 253 77
-        253 116 253 253 253 253 92 70 3 69 253 253 14 72 30 253 94
-        253 253 70 42 93 253 70 127 3 111 32 5 253 28 253 30 253
-        253 13 46 253 253 24 7 253 106 253 253 253 39 253 253 25
-        253 2 253 110 1 253 253 253 45 253 253 253 22 112 6 10 253
-        253 253 253 25 79 253 83 113 90 253 43 253 253 253 253 253
-        253 253 253 253 38 69 97 253 253 90 253 253 253 91 253 253
-        85 253 18 253 103 7 253 253 253 253 253 68 74 253 253 104
-        253 253 253 253 253 51 108 73 97 253 253 2 110 35 93 253
-        253 253 253 253 253 22 253 253 75 253 79 49 253 253 253 76
-        253 253 253 253 30 253 253 253 116 253 113 19 253 19 253
-        253 87 118 253 253 66 253 253 113 253 253 0 84 123 26 253
-        253 17 253 79 253 58 87 253 47 85 90 20 253 99 120 253 253
-        48 253 7 253 253 44 253 72 110 33 115 28 253 253 253 107
-        253 253 73 253 253 13 34 253 43 253 91 253 86 86 253 103
-        253 43 253 253 21 117 253 253 253 253 253 52 253 253 253 42
-        79 57 253 101 253 253 253 89 37 47 253 253 123 62 27 253
-        253 66 253 253 253 253 87 72 253 253 253 253 31 253 253 83
-        11 125 67 253 86 98 67 253 253 92 253 119 20 253 85 253 97
-        108 253 253 253 124 118 253 253 253 7 253 53 253 253 77 253
-        253 8 253 253 106 253 5 122 9 94 253 253 34 253 253 253 119
-        94 29 253 113 253 108 89 253 253 11 127 16 253 111 253 21
-        253 69 35 253 253 253 253 3 253 253 253 253 253 253 253 41
-        253 253 109 86 72 253 253 99 253 32 253 21 50 253 67 51 13
-        253 70 253 253 253 253 91 1 54 253 253 79 106 253 105 49 31
-        46 253 1 253 253 91 125 253 253 253 253 114 253 253 87 253
-        253 253 96 31 253 115 103 253 23 118 253 253 36 82 253 55
-        253 253 90 253 47 253 253 253 39 25 59 121 253 253 109 253
-        0 40 116 120 110 253 253 99 119 97 84 253 253 253 101 253
-        253 88 15 19 77 12 127 74 253 28 124 80 253 50 40 253 253
-        70 70 70 253 125 40 253 124 40 253 106 253 253 253 253 89
-        109 253 34 93 253 253 112 118 10 12 51 23 28 26 253 253 16
-        253 253 253 253 40 253 253 18 63 253 115 121 30 61 253 253
-        253 253 69 44 253 124 253 41 253 253 253 54 253 55 253 49
-        253 27 253 25 253 253 253 105 102 253 24 91 9 253 253 253
-        63 20 253 94 35 253 253 5 253 47 253 9 253 0 253 61 43 70
-        54 253 253 253 253 253 101 33 79 253 35 103 253 253 52 113
-        253 253 253 253 253 37 253 253 253 253 22 253 26 253 108 64
-        22 253 14 253 76 115 74 253 253 76 253 253 253 120 253 253
-        25 116 253 30 253 114 253 253 115 253 253 103 253 2 69 22
-        253 42 253 41 38 15 253 97 253 253 104 253 109 253 253 253
-        70 52 253 253 83 253 253 253 73 253 253 103 65 124 33 253
-        253 253 106 18 99 120 253 121 253 106 253 253 50 253 253
-        103 80 95 24 21 0 253 17 121 29 253 79 253 27 253 253 7 253
-        253 253 45 63 253 253 72 253 83 28 87 61 118 253 253 63 34
-        5 253 47 253 253 113 35 253 123 82 11 253 21 253 11 24 253
-        71 114 106 73 253 90 72 253 253 27 21 253 124 122 253 102
-        253 53 253 253 253 253 0 61 253 37 89 253 29 253 53 75 253
-        111 21 13 253 253 108 112 91 253 253 253 97 109 58 34 253
-        18 253 253 97 253 25 253 253 253 253 126 253 253 82 253 33
-        117 253 253 5 91 253 253 74 81 38 253 119 253 23 253 253 13
-        36 64 111 253 253 120 107 68 253 77 253 59 253 253 99 253
-        253 109 253 253 81 253 121 253 253 253 84 253 253 253 253
-        55 119 18 90 253 253 253 253 253 253 107 253 79 253 32 253
-        253 24 33 253 253 3 253 253 85 253 253 17 253 253 44 253
-        116 39 42 87 253 253 106 253 77 253 83 253 61 31 45 253 253
-        253 1 102 27 100 118 253 29 253 253 21 253 253 253 253 253
-        117 88 99 32 253 102 0 253 79 253 253 253 114 253 253 91
-        253 253 253 31 106 253 62 29 116 253 253 253 14 253 253 253
-        115 253 253 253 79 253 253 85 23 253 253 40 253 116 253 93
-        13 253 253 94 74 18 253 253 114 14 72 92 253 106 253 253 14
-        253 253 253 253 253 49 253 253 72 253 253 253 48 253 30 253
-        253 253 253 47 24 253 253 57 97 253 253 253 253 253 85 253
-        253 100 34 253 253 57 28 122 253 102 253 253 58 97 20 253
-        253 253 253 253 253 253 72 103 253 253 253 253 253 28 17 78
-        83 253 253 253 4 253 96 7 111 126 253 58 253 108 253 90 253
-        40 253 253 253 253 253 253 253 77 253 54 253 110 34 253 253
-        113 123 101 115 115 253 253 253 101 253 253 113 81 253 106
-        35 253 61 46 253 253 44 118 104 3 38 253 253 253 253 253
-        253 253 45 253 101 119 0 9 35 253 41 14 253 104 253 73 101
-        10 253 253 253 119 253 50 253 89 253 253 87 253 48 77 60
-        253 253 110 253 253 253 253 1 253 253 253 253 253 253 253
-        22 253 86 75 117 253 95 31 253 253 114 106 253 69 253 253
-        52 71 111 57 46 113 253 253 253 253 253 253 253 253 110 90
-        253 253 94 253 22 253 253 126 253 253 253 45 253 81 253 253
-        253 253 105 35 253 253 253 41 67 253 122 15 253 253 253 253
-        66 77 47 82 51 89 54 17 78 55 19 253 125 253 253 94 105 253
-        253 253 22 253 16 253 44 124 64 125 90 253 253 253 253 253
-        102 253 70 62 253 31 253 94 124 90 57 84 253 54 116 39 253
-        253 253 253 253 78 253 124 92 52 99 12 24 253 84 253 125 74
-        253 253 22 13 253 35 12 7 253 125 15 253 253 253 65 253 253
-        253 253 253 12 253 253 253 253 253 253 30 253 253 66 253
-        253 114 253 253 253 253 253 253 253 253 104 57 61 253 45
-        253 253 48 52 253 253 253 34 253 37 253 67 26 253 81 253 61
-        253 253 253 49 100 85 253 112 63 90 253 45 253 253 253 253
-        79 82 37 80 253 253 102 253 26 9 253 67 120 253 72 85 91
-        253 72 253 114 59 253 253 18 88 253 116 253 253 253 253 98
-        253 253 66 253 253 253 253 31 74 253 253 253 253 253 35 253
-        253 253 253 253 253 118 253 110 253 97 23 253 49 73 253 253
-        54 253 29 92 253 253 253 109 253 115 253 253 253 87 51 253
-        0 253 20 253 13 253 120 78 253 124 253 253 253 253 253 253
-        27 123 23 50 76 82 69 253 253 253 92 253 253 253 253 253 93
-        84 253 43 29 253 253 55 253 253 253 83 103 14 94 253 60 113
-        50 75 18 253 79 253 253 52 94 253 2 253 253 253 253 84 253
-        50 253 253 253 7 253 253 118 12 253 253 253 18 75 71 56 79
-        253 25 101 81 253 99 253 253 253 253 253 27 253 253 253 74
-        24 253 253 24 112 43 253 32 253 41 253 253 8 253 86 62 48
-        253 253 253 253 93 253 45 3 253 253 253 253 253 90 105 253
-        46 97 24 253 253 72 253 115 253 16 41 253 253 58 253 99 253
-        93 28 124 253 57 31 253 76 253 70 35 253 64 253 8 253 253
-        47 121 253 0 253 253 253 0 45 82 49 253 253 58 116 91 253
-        253 253 253 253 253 253 53 35 105 60 253 253 71 253 59 111
-        253 99 253 253 253 39 120 253 253 115 61 253 58 49 253 62
-        253 27 106 40 253 11 253 253 253 253 90 52 110 112 15 124
-        253 80 253 59 253 60 253 253 93 253 52 5 27 253 123 98 253
-        253 253 253 121 123 23 111 253 253 25 19 253 253 253 25 253
-        25 253 253 253 123 253 253 253 253 6 72 253 55 16 253 253
-        253 253 61 253 253 253 253 253 76 253 12 22 253 253 49 99
-        253 253 253 253 253 253 253 253 82 253 81 253 125 123 87 36
-        253 253 117 253 253 96 58 253 253 253 59 253 253 20 253 253
-        253 253 53 1 253 253 21 253 253 253 253 253 60 253 253 43
-        87 94 253 125 253 253 20 253 73 17 253 118 25 253 253 253
-        253 253 253 253 81 90 253 253 114 253 253 72 253 253 86 253
-        91 253 253 34 253 253 51 253 253 253 253 86 120 81 64 43
-        253 57 253 253 68 253 85 123 61 253 253 95 57 67 253 63 78
-        253 253 26 107 253 12 253 253 253 253 253 61 253 1 113 118
-        253 253 253 253 15 253 118 67 29 253 100 253 253 253 25 125
-        127 253 37 253 253 253 253 253 15 253 39 253 59 88 253 96
-        253 253 90 253 253 36 253 253 253 253 80 71 44 253 42 253
-        253 102 56 81 253 253 253 253 253 87 119 100 253 253 253
-        253 38 253 253 70 24 253 11 24 253 253 253 253 39 253 253
-        253 253 13 253 114 107 91 40 63 18 33 253 114 253 253 72
-        253 253 125 126 253 76 253 0 253 253 253 253 90 253 29 253
-        253 253 92 253 253 253 253 253 118 253 29 253 253 57 31 95
-        253 253 253 67 253 253 19 79 111 28 23 17 253 94 51 253 21
-        253 0 10 253 253 253 253 14 42 253 253 253 51 253 56 253
-        253 253 76 253 253 60 52 109 25 57 253 62 253 253 23 253 18
-        93 21 253 101 66 253 253 253 253 253 253 60 62 42 253 253
-        253 253 253 111 253 253 78 253 253 101 253 253 77 253 91 97
-        53 253 253 56 86 253 19 253 253 253 253 0 253 253 99 253
-        253 88 253 34 253 11 253 253 253 95 72 74 253 253 99 70 54
-        96 118 28 10 87 127 110 100 253 112 118 47 115 77 253 253
-        253 80 119 253 253 253 42 253 15 253 253 253 119 253 104 57
-        39 253 37 117 96 85 253 253 253 51 253 125 105 102 253 253
-        69 54 253 34 253 46 253 253 30 253 0 74 253 93 253 101 253
-        35 47 253 253 33 253 65 253 111 61 253 253 253 253 253 70
-        253 70 253 253 96 43 36 253 253 105 100 109 81 253 253 0 26
-        122 94 253 253 119 19 36 253 69 30 60 253 32 36 253 253 0
-        253 115 30 253 38 253 83 13 253 52 108 59 6 24 56 253 253
-        63 253 253 253 92 105 253 21 253 253 253 19 103 253 21 87
-        43 253 98 73 253 92 75 253 71 69 253 253 122 253 253 253
-        109 253 104 253 35 253 24 32 125 72 253 253 253 253 100 114
-        69 253 22 253 253 253 121 78 1 253 253 253 70 253 115 107
-        34 253 253 98 253 253 122 253 253 6 100 253 253 79 106 253
-        5 253 253 253 47 98 49 85 253 22 46 253 97 69 253 51 92 95
-        253 253 253 253 5 253 99 61 253 253 105 116 253 253 111 113
-        98 30 50 253 84 253 7 61 253 253 115 253 253 253 253 253 88
-        47 253 253 52 108 26 253 253 253 253 253 253 253 11 253 253
-        253 0 253 77 35 253 253 253 253 57 18 253 103 91 253 253
-        253 110 23 116 253 253 102 50 125 13 77 116 75 253 109 109
-        253 33 103 25 253 253 253 253 253 253 253 34 36 253 8 253
-        36 104 253 7 253 253 7 253 253 253 253 77 90 253 253 253 26
-        9 55 2 61 253 253 253 101 253 253 74 107 253 77 121 113 115
-        253 253 253 70 36 253 253 30 99 47 253 253 253 253 62 46 90
-        90 253 253 34 77 104 253 54 253 0 253 253 253 91 253 253
-        253 113 19 96 253 36 253 253 253 253 253 253 51 106 253 86
-        112 70 253 253 253 84 253 53 100 253 105 82 35 18 57 99 90
-        7 253 43 4 253 33 91 253 123 86 107 253 110 253 253 36 101
-        253 19 253 0 253 253 21 253 253 121 39 253 253 253 253 253
-        32 253 71 253 253 253 105 253 253 8 253 253 253 253 253 109
-        253 253 253 253 253 51 253 85 253 253 74 87 253 61 69 29
-        253 253 253 253 253 40 253 57 253 51 103 6 253 253 8 93 58
-        253 60 127 71 127 253 104 253 62 253 22 253 253 253 101 253
-        127 253 253 253 0 45 20 253 24 85 253 73 26 253 65 253 253
-        18 86 70 100 50 253 253 90 89 104 253 253 86 253 253 63 253
-        63 253 253 253 100 253 253 112 253 253 253 69 37 101 99 253
-        116 253 253 253 253 42 253 50 31 8 253 253 253 253 253 127
-        87 0 253 94 9 253 253 253 78 14 51 253 253 253 253 253 253
-        39 127 8 122 253 253 253 253 253 253 253 54 253 253 113 253
-        52 71 92 124 78 253 253 23 253 253 253 28 253 253 253 113
-        253 253 88 253 253 253 253 44 80 253 253 253 253 253 253 38
-        253 253 253 253 121 49 73 253 101 63 253 79 45 253 253 253
-        253 73 78 253 107 253 29 90 253 92 253 101 113 39 253 253
-        253 34 104 102 253 253 253 56 253 104 253 6 61 253 253 253
-        107 11 253 118 253 253 115 52 123 72 253 117 42 253 253 253
-        253 57 35 253 15 24 253 253 253 115 114 14 253 253 253 253
-        18 48 253 23 253 122 253 18 51 72 253 253 253 253 124 253
-        89 253 253 253 82 45 15 253 253 253 253 64 35 253 253 50 60
-        253 253 60 253 253 122 253 34 253 253 253 105 22 52 83 253
-        56 21 119 124 40 253 61 22 11 120 117 14 253 91 71 253 253
-        253 253 253 253 253 253 253 76 253 253 253 63 253 253 18
-        253 18 57 54 253 100 253 253 253 63 253 91 58 253 90 125
-        107 82 253 0 253 61 62 253 253 253 253 253 253 120 253 253
-        82 82 253 69 253 253 253 253 253 253 253 36 253 253 27 253
-        53 90 60 43 62 253 253 253 253 253 253 124 122 30 253 253
-        31 29 52 104 253 253 95 253 32 5 27 100 36 253 45 253 253
-        10 253 253 62 14 116 119 78 253 49 106 29 125 253 253 6 78
-        253 253 253 253 253 253 253 126 25 253 253 0 253 31 253 253
-        111 253 253 253 253 75 11 33 253 58 253 253 253 253 253 111
-        253 253 253 18 253 105 41 253 127 11 55 77 253 253 13 253
-        253 52 253 253 62 32 50 253 253 57 253 253 253 71 253 253
-        253 253 122 253 5 253 105 253 253 57 253 14 11 253 120 253
-        63 253 253 92 19 253 253 53 253 80 253 253 253 253 37 96 36
-        8 112 28 122 30 61 49 87 123 253 75 105 253 99 253 52 253
-        69 118 253 26 0 16 253 253 74 253 104 10 253 71 82 105 125
-        92 253 27 253 253 253 253 253 12 41 37 253 45 253 68 75 253
-        79 115 253 253 5 253 253 253 253 84 103 253 253 253 253 253
-        253 23 49 253 121 21 93 253 36 253 253 253 63 253 90 253
-        115 72 253 28 109 253 86 95 48 30 253 253 46 253 68 253 62
-        253 253 22 88 78 21 253 253 46 120 253 44 126 253 253 253
-        253 72 124 104 253 253 79 13 253 39 0 253 253 253 55 253 64
-        44 102 54 86 40 36 33 28 253 7 21 76 253 62 253 115 253 253
-        253 253 30 37 253 253 49 253 253 253 62 253 88 253 253 253
-        62 34 253 253 58 102 253 2 121 12 14 253 120 80 253 253 253
-        253 253 54 253 253 253 78 253 253 253 253 253 253 110 253
-        253 253 16 253 40 253 253 78 113 253 253 253 17 53 127 253
-        104 253 75 123 253 253 74 17 20 253 253 63 253 253 0 62 253
-        82 116 253 253 253 117 70 253 107 253 253 253 120 253 253
-        79 253 253 253 253 253 253 111 253 28 253 97 20 253 253 253
-        253 253 58 99 87 253 253 253 73 107 36 48 253 16 253 253 70
-        253 253 77 253 62 253 253 253 253 253 63 253 253 13 253 253
-        253 108 253 26 9 253 13 46 253 115 253 3 253 81 85 253 123
-        253 253 79 253 58 54 253 253 253 253 253 96 36 253 110 10
-        253 253 64 253 103 253 70 126 35 124 48 253 253 99 6 253
-        253 253 253 253 253 253 70 253 7 2 253 253 55 41 69 121 116
-        68 62 34 253 106 253 253 253 73 100 253 61 253 253 17 253
-        66 253 253 80 253 253 39 253 253 28 253 253 105 253 105 253
-        87 253 253 26 59 253 253 253 127 13 253 23 253 253 44 14
-        253 253 253 253 68 106 253 61 253 107 110 253 253 30 119 14
-        253 253 253 253 253 120 253 66 253 253 253 33 253 64 42 79
-        57 253 253 253 81 253 67 28 108 18 34 253 27 253 115 75 253
-        13 58 253 253 253 57 253 105 30 253 26 50 253 253 12 253
-        106 111 253 100 253 253 14 110 45 100 30 29 253 108 93 253
-        253 253 253 253 253 253 253 253 46 253 253 65 116 253 253
-        253 253 14 56 39 253 253 253 253 253 253 102 114 65 253 253
-        29 45 253 253 253 253 253 123 82 253 13 253 253 253 111 94
-        253 127 103 35 13 253 89 59 103 253 253 30 253 253 55 253
-        253 253 253 28 253 253 81 14 253 253 46 253 42 253 52 253
-        253 253 3 253 253 253 55 121 253 253 253 253 62 253 62 253
-        119 253 106 33 86 39 253 15 253 81 80 253 28 253 253 102 84
-        57 35 253 81 91 33 60 96 253 253 42 253 253 253 77 253 45
-        72 53 253 65 253 28 253 253 12 110 20 253 253 107 50 253
-        253 253 253 97 14 253 253 100 253 253 253 26 88 99 0 35 253
-        253 253 35 41 253 62 253 126 253 34 253 101 76 115 75 35 4
-        253 124 253 43 70 253 253 253 122 63 253 253 253 0 253 71
-        73 253 87 253 122 7 80 253 0 54 94 253 0 253 253 253 90 41
-        42 48 253 253 253 61 253 13 253 34 76 10 253 4 91 101 25
-        253 253 253 253 95 253 253 253 74 253 13 123 253 40 253 253
-        55 56 253 115 92 253 71 24 253 253 77 103 253 253 29 253
-        253 23 253 3 253 104 29 53 253 69 253 253 28 253 253 32 48
-        31 122 253 253 253 253 253 253 107 253 77 85 253 253 253
-        253 253 253 253 75 20 253 253 253 38 253 253 253 253 95 83
-        57 253 253 0 123 28 253 97 253 253 23 119 6 86 113 253 3 28
-        3 64 73 118 105 253 253 75 253 253 71 96 253 253 62 253 253
-        43 30 253 253 253 90 68 253 253 69 24 253 76 56 253 101 82
-        71 253 84 253 253 253 253 253 117 125 13 253 54 253 253 30
-        253 253 253 253 253 50 61 253 253 17 93 253 253 19 50 253
-        102 24 78 253 253 253 253 29 55 105 99 253 253 253 104 253
-        253 253 253 1 35 253 5 253 253 253 116 95 253 91 125 52 67
-        53 253 253 253 12 22 9 253 126 253 105 253 253 54 58 126
-        253 27 253 253 253 60 253 253 115 253 84 253 100 101 253
-        253 253 253 127 16 35 253 253 54 253 107 253 253 82 253 253
-        102 43 28 64 121 253 253 126 253 253 253 253 253 253 110
-        253 253 59 253 253 55 120 114 253 0 23 124 253 253 253 36
-        90 253 253 253 253 46 104 35 253 4 39 108 253 60 253 253
-        253 253 115 84 102 253 253 253 3 253 253 253 253 253 98 49
-        253 253 65 253 66 253 253 253 86 253 41 73 81 57 253 22 75
-        126 54 92 253 106 253 105 253 45 253 80 253 62 253 253 127
-        20 127 74 19 253 253 253 253 253 253 38 253 113 253 69 121
-        103 125 101 56 253 44 99 102 253 6 60 253 253 103 253 253
-        253 20 253 253 253 253 0 253 55 87 253 253 253 106 38 253
-        29 67 24 253 33 253 7 31 253 253 80 253 42 253 77 253 9 253
-        253 253 34 120 116 93 253 60 253 253 253 253 253 253 253
-        253 36 63 253 253 253 253 122 59 253 253 28 95 253 44 42 62
-        68 123 253 116 253 33 117 253 20 71 109 12 253 51 36 95 253
-        253 253 0 253 51 253 253 73 253 27 253 253 253 253 253 71
-        253 61 253 2 56 253 253 253 253 35 253 77 93 99 94 75 88 99
-        72 253 253 253 253 10 253 9 253 253 122 35 69 253 253 253
-        113 253 112 23 253 91 253 105 61 253 122 116 253 109 253
-        253 253 253 72 253 99 253 44 253 253 253 253 253 253 253
-        253 10 253 84 253 37 105 49 49 72 253 127 253 253 20 253
-        253 253 253 86 107 115 34 253 253 69 108 253 253 21 253 253
-        126 90 40 253 92 115 82 253 253 76 73 253 23 253 253 253
-        253 253 17 77 43 73 110 253 253 66 57 253 36 253 93 26 253
-        253 253 253 3 92 253 253 253 253 253 49 86 11 61 253 253
-        105 20 253 253 253 80 48 43 69 253 253 253 253 253 28 107
-        27 24 253 253 127 95 253 253 253 61 28 253 253 253 253 88
-        253 13 44 253 43 73 31 253 89 253 0 253 253 65 124 52 253
-        253 253 253 253 253 34 253 253 37 253 253 253 253 253 20
-        253 253 10 253 7 106 253 114 1 253 31 253 39 74 253 253 253
-        68 82 126 72 47 253 253 253 253 66 44 253 253 125 107 79 75
-        123 253 253 253 253 36 253 112 14 10 48 253 253 86 253 253
-        9 78 253 253 253 28 253 253 109 253 111 109 253 253 253 6
-        253 45 253 98 253 89 34 13 253 253 253 40 253 253 253 122
-        253 253 253 253 253 253 253 123 92 253 253 15 253 253 253
-        253 253 253 62 94 59 253 85 78 253 253 253 85 253 253 253
-        253 44 253 29 51 80 253 76 59 253 253 253 253 253 110 121
-        253 253 253 111 88 253 86 253 253 253 53 7 76 253 23 253 35
-        72 253 37 121 34 253 50 125 253 8 97 253 95 43 61 95 253
-        253 0 59 22 124 80 253 35 253 82 80 253 51 75 253 253 253
-        253 253 25 31 253 17 253 17 253 111 253 253 253 253 253 253
-        253 109 103 71 253 59 16 253 73 253 91 253 28 99 253 253
-        253 15 58 89 110 253 4 253 253 39 113 32 253 253 93 114 253
-        253 0 82 43 253 253 253 22 253 107 2 253 253 253 253 253
-        253 64 7 253 253 253 35 253 253 103 18 253 111 253 253 126
-        54 253 253 47 253 253 253 253 12 253 253 34 253 75 253 253
-        86 62 11 7 25 253 43 253 58 253 253 44 253 120 36 73 6 253
-        253 99 253 4 19 253 42 253 253 253 253 98 253 253 126 51 78
-        18 73 30 114 253 87 3 253 40 253 253 83 253 78 253 44 103
-        52 253 78 253 253 54 253 253 122 127 47 253 253 119 125 31
-        117 14 253 39 253 60 72 6 74 253 253 253 106 253 9 109 91
-        44 253 253 28 110 20 253 253 253 253 59 253 30 253 253 6 21
-        253 9 253 123 253 117 19 21 253 101 35 253 68 58 114 253 52
-        41 253 253 253 64 253 253 58 253 120 108 253 253 77 35 253
-        22 8 253 253 98 253 16 253 21 112 8 253 15 63 253 253 6 112
-        125 43 253 35 110 253 0 253 0 253 87 23 65 24 66 253 121
-        253 253 109 253 253 21 253 15 42 121 253 28 253 253 59 253
-        253 24 79 253 253 84 253 253 253 253 253 79 253 253 253 253
-        253 253 253 17 253 115 69 105 35 49 45 99 12 253 253 253
-        253 15 253 101 253 253 253 253 0 253 253 101 24 10 253 74
-        11 81 253 77 253 253 0 253 253 253 253 253 66 253 253 253
-        253 253 103 105 253 253 42 253 57 253 117 57 39 253 107 103
-        110 253 253 253 10 63 253 253 126 253 253 98 253 253 20 10
-        253 67 56 253 65 253 16 253 15 122 57 253 253 253 253 115
-        64 88 253 124 49 253 27 28 101 92 253 114 41 253 253 27 43
-        253 253 38 61 66 76 115 253 127 74 253 91 253 102 253 87
-        253 88 253 253 253 253 111 253 6 253 126 253 253 253 253
-        253 253 24 253 2 50 57 62 253 253 253 253 120 253 106 253
-        253 253 59 253 94 38 253 22 253 116 100 87 253 253 80 70 49
-        253 253 58 43 73 68 253 253 253 52 253 253 253 23 35 56 253
-        58 34 72 253 253 58 47 54 253 253 253 24 253 253 253 79 253
-        31 77 16 253 253 253 67 25 6 253 42 13 253 253 253 253 123
-        253 253 253 13 253 26 253 253 253 57 253 0 26 95 253 86 253
-        14 38 0 253 17 253 125 42 75 20 6 20 41 26 253 253 40 253
-        253 253 253 253 24 60 253 78 89 87 253 253 253 253 253 253
-        253 253 253 22 253 60 253 253 253 74 1 34 253 253 253 253
-        253 253 253 253 79 253 47 72 111 89 117 61 99 84 253 253
-        253 103 33 253 253 253 10 253 0 42 253 253 253 253 253 253
-        253 253 50 253 253 77 44 253 253 54 8 65 253 36 253 40 253
-        253 253 253 95 253 253 253 73 17 253 91 253 253 253 253 253
-        253 253 253 253 253 6 253 55 37 118 253 124 253 253 253 253
-        253 253 253 118 253 253 80 74 54 253 1 90 97 253 253 253
-        253 3 81 253 253 253 91 125 63 77 88 108 253 70 21 97 253
-        253 43 253 53 45 120 119 253 253 253 253 253 253 124 24 253
-        10 1 96 59 253 253 116 253 76 253 104 253 253 253 253 4 101
-        253 253 253 94 91 253 253 253 253 11 26 91 253 47 253 253
-        26 52 117 23 55 18 44 253 253 32 253 253 126 253 97 105 253
-        20 118 253 253 120 107 253 2 121 52 253 18 107 253 253 117
-        35 253 17 70 253 66 107 125 253 253 253 253 59 119 1 253
-        253 253 253 106 118 51 105 253 99 27 253 253 20 253 253 85
-        51 253 90 253 253 253 27 36 55 253 253 253 253 253 3 253 57
-        253 253 253 253 253 253 32 253 101 44 253 99 53 59 41 253
-        253 20 253 253 41 119 253 56 253 253 31 105 121 29 253 42
-        253 253 3 253 253 42 253 107 120 2 16 253 100 253 253 253
-        253 253 253 13 20 253 253 253 253 50 86 9 53 123 50 253 11
-        11 107 253 41 253 60 99 35 4 253 0 125 85 253 71 253 82 253
-        87 15 123 4 253 253 49 253 32 28 15 92 253 86 253 120 253
-        40 4 33 253 12 253 54 253 253 253 253 37 253 253 75 253 253
-        70 253 253 38 80 59 12 253 253 19 253 75 253 77 117 119 76
-        253 117 23 78 253 47 253 99 253 253 121 253 253 54 253 3
-        253 253 253 253 253 29 51 253 253 253 122 253 95 27 104 110
-        253 253 76 253 253 83 253 117 43 87 61 253 76 54 253 118
-        253 89 253 81 68 91 43 253 95 113 253 124 253 116 253 59
-        253 54 23 81 253 110 253 253 253 64 54 122 253 39 253 104
-        114 98 73 253 91 253 125 35 253 105 98 107 75 29 66 7 253
-        253 60 253 57 0 59 121 253 39 253 253 253 253 56 45 253 253
-        253 253 36 253 253 44 253 253 253 253 253 253 253 253 106
-        253 111 43 77 19 68 121 253 253 253 253 253 253 79 253 253
-        93 253 253 253 253 253 253 106 253 64 48 87 253 30 253 253
-        40 253 253 253 5 253 77 253 36 102 48 253 7 36 253 253 253
-        253 253 27 70 253 253 41 253 253 253 253 105 253 253 10 22
-        12 253 109 253 253 253 126 253 90 253 119 110 253 6 253 253
-        253 253 253 72 45 253 253 69 253 75 253 125 121 61 253 100
-        5 30 253 253 115 253 253 253 253 253 68 253 253 32 25 253
-        83 253 98 7 34 253 253 88 253 253 79 253 23 253 253 253 253
-        10 253 253 0 253 41 80 99 115 120 253 253 3 253 67 6 253 28
-        253 253 117 84 253 79 253 121 253 253 253 123 26 253 3 253
-        253 81 14 253 253 253 253 253 253 253 253 253 82 253 50 23
-        253 76 253 253 79 253 31 83 253 62 113 253 253 69 69 10 17
-        253 56 253 66 70 253 20 253 115 68 71 56 0 125 120 253 253
-        253 253 253 49 253 253 86 74 25 125 43 253 28 14 56 253 101
-        253 253 84 48 253 89 82 253 46 54 253 253 109 253 253 49
-        125 253 29 96 253 253 121 253 253 253 253 253 71 21 253 53
-        253 253 253 253 29 253 109 70 54 253 253 120 253 253 54 253
-        253 0 45 18 119 46 57 253 253 117 94 116 59 253 253 253 253
-        0 253 107 24 253 89 51 27 24 6 15 253 253 253 253 13 253
-        100 103 53 253 253 15 253 253 253 253 253 253 253 253 253
-        253 110 253 253 99 253 109 59 253 127 253 22 85 73 60 253
-        90 110 68 32 253 122 34 114 253 253 253 253 253 253 117 29
-        89 39 253 16 253 253 54 253 253 6 253 54 101 29 253 54 9
-        253 107 111 65 52 119 55 253 253 14 253 253 253 123 253 120
-        253 111 253 253 253 1 253 76 253 33 253 253 113 71 253 41
-        88 253 0 104 253 36 253 253 253 100 253 253 253 79 84 58
-        126 71 78 253 253 67 253 91 71 31 38 76 42 17 253 86 253 71
-        253 253 40 253 253 253 104 3 30 253 85 116 253 107 47 253
-        253 253 26 121 253 106 253 253 253 68 253 253 253 253 103
-        118 253 253 253 253 253 253 253 52 74 253 101 92 7 94 113
-        81 253 253 253 253 65 45 253 115 0 66 253 253 253 13 253 85
-        253 253 48 60 253 253 253 92 118 253 253 253 253 253 118 96
-        253 253 63 253 253 125 0 253 253 253 107 253 26 41 253 253
-        105 32 81 253 100 67 37 253 104 253 62 253 253 44 37 253
-        253 253 127 253 93 253 253 253 253 34 85 253 107 253 253
-        253 9 27 121 253 56 253 107 55 45 34 253 114 253 253 47 4
-        253 9 253 10 253 253 79 89 253 97 27 94 77 34 253 47 253 51
-        30 13 9 253 253 253 253 253 24 80 18 253 253 253 61 69 71
-        253 253 253 88 253 88 85 21 45 253 60 5 39 253 51 80 253
-        253 65 253 73 37 253 54 253 70 253 4 14 70 59 81 76 106 253
-        253 23 55 253 91 253 127 253 105 253 48 253 48 253 253 3
-        253 0 253 253 58 253 253 6 253 253 253 253 69 253 123 253
-        84 253 253 253 253 11 85 101 253 47 253 53 30 253 253 253
-        40 100 123 125 56 54 253 253 253 111 46 51 253 253 106 53
-        253 253 253 253 253 253 15 253 70 43 253 7 253 100 15 253
-        93 115 122 253 253 111 115 4 1 253 253 98 253 3 253 91 253
-        253 253 253 253 44 117 253 23 112 253 17 66 253 253 253 9
-        253 58 253 253 253 53 93 29 113 253 5 35 43 253 0 253 81
-        127 253 253 68 15 253 0 253 47 253 86 253 118 253 253 76 23
-        253 28 113 253 253 253 124 105 253 91 59 253 253 87 253 253
-        253 253 99 253 35 253 62 253 116 253 76 126 31 253 253 44
-        57 253 253 119 85 253 118 253 253 74 40 12 79 4 253 20 90
-        111 253 27 253 46 253 253 253 253 19 253 253 109 253 253
-        253 253 253 61 253 253 253 79 253 126 253 34 253 21 253 41
-        26 253 253 253 253 8 253 253 253 29 253 253 253 100 253 41
-        36 253 88 253 253 120 253 253 253 253 123 253 253 253 253
-        253 253 253 253 19 76 253 36 253 253 253 253 253 9 253 253
-        253 253 118 253 73 253 93 58 63 80 253 253 35 105 23 253
-        108 253 46 6 253 253 253 253 253 253 253 89 253 65 27 74
-        253 38 253 15 253 253 253 253 253 122 253 253 253 253 55 80
-        253 253 20 253 18 47 253 253 253 253 117 111 253 67 253 253
-        18 5 253 78 3 10 91 12 83 110 253 253 85 253 253 110 90 253
-        68 253 6 95 253 42 60 253 253 79 253 72 253 125 111 38 253
-        53 253 253 253 118 124 253 253 253 26 253 115 253 253 253 0
-        88 253 88 253 85 253 253 68 116 253 253 34 119 253 253 69
-        109 253 113 253 253 108 253 75 31 72 253 120 253 48 25 4
-        253 12 253 43 116 253 253 253 15 13 99 98 8 253 253 105 253
-        91 96 253 253 43 97 253 30 253 253 106 253 253 253 98 253
-        253 253 253 253 253 91 36 253 58 43 253 253 253 72 46 32
-        253 67 253 13 253 253 85 31 25 253 253 253 253 85 253 253
-        21 253 253 253 253 30 61 69 91 253 94 127 21 104 95 4 253
-        121 126 253 89 253 117 253 87 90 116 126 59 253 27 105 92
-        253 64 21 37 26 118 91 253 253 253 253 62 253 253 53 16 253
-        103 28 110 78 73 253 253 47 253 0 253 253 55 253 253 37 253
-        70 61 57 253 29 89 253 92 104 253 253 253 253 253 34 124
-        253 122 99 253 253 253 253 253 74 253 114 64 253 86 82 100
-        253 253 67 34 108 46 115 69 71 38 253 253 41 100 47 253 122
-        54 253 253 253 253 253 253 45 58 24 253 253 253 62 253 253
-        253 103 253 253 68 253 253 94 253 96 20 14 106 253 34 97 0
-        253 121 25 29 253 124 253 37 111 8 253 59 26 253 253 6 77
-        253 253 123 253 122 253 70 253 253 121 253 253 253 253 253
-        21 253 84 35 253 77 253 253 17 57 63 109 253 65 27 87 60 80
-        253 253 253 0 253 111 127 253 253 253 24 253 253 38 21 253
-        253 253 253 253 253 253 127 253 110 4 9 121 25 253 108 37
-        85 253 253 95 85 253 110 253 253 253 253 253 36 7 253 26
-        253 41 30 253 253 25 253 78 71 253 109 253 64 16 253 95 65
-        253 88 90 16 109 253 253 28 86 253 253 119 253 60 253 253
-        107 124 73 253 121 16 253 253 95 26 80 23 253 253 253 253
-        253 9 253 121 253 253 253 253 51 57 39 253 253 253 253 253
-        253 105 82 253 253 253 253 253 11 253 110 53 253 253 23 253
-        253 253 122 44 81 253 48 253 253 0 61 49 74 24 253 14 122
-        66 253 253 94 48 253 253 80 63 253 253 88 90 72 96 253 54
-        56 253 105 7 78 88 253 31 52 253 253 94 88 253 253 79 253
-        74 32 253 75 123 116 253 68 253 118 110 253 253 253 46 253
-        253 58 65 18 253 74 253 253 112 59 84 115 253 46 253 253
-        253 95 121 44 62 81 253 253 253 253 253 119 81 253 108 253
-        253 42 25 253 90 253 253 253 102 93 253 253 119 96 41 253
-        42 253 253 29 253 107 71 253 87 35 253 99 253 106 35 253 90
-        253 78 5 253 253 22 99 253 41 253 253 253 44 26 83 52 101
-        76 44 48 54 118 53 26 253 109 253 253 253 33 253 253 12 12
-        253 25 253 253 47 12 111 76 253 124 53 253 253 16 45 253
-        253 110 64 114 115 253 84 253 253 253 101 78 253 123 102
-        253 26 56 253 253 102 253 123 67 253 75 123 51 101 8 13 253
-        12 127 253 253 92 107 253 253 27 253 126 253 253 98 253 253
-        253 124 253 253 105 253 28 253 253 68 253 52 253 12 48 44
-        118 253 253 253 253 253 37 15 253 62 253 253 53 63 1 253 60
-        39 253 253 84 253 253 46 253 253 253 109 62 253 253 51 92
-        54 12 253 7 253 253 253 87 82 89 54 253 36 87 22 253 253 62
-        94 59 85 34 253 253 253 110 253 97 124 56 253 45 253 8 28
-        253 12 253 253 253 86 5 253 253 253 75 113 12 108 253 77
-        253 110 56 253 35 253 13 253 91 253 38 53 253 253 111 253
-        253 123 253 253 84 91 253 104 17 253 65 24 17 253 15 253
-        116 66 105 253 113 67 109 70 91 88 253 253 118 0 253 5 72
-        81 253 253 78 253 253 56 127 27 45 253 253 253 55 253 49
-        253 253 110 253 253 29 58 101 253 42 5 253 253 66 12 122
-        123 253 62 253 253 253 253 253 0 253 116 60 92 49 253 253
-        253 253 253 55 72 253 80 93 253 253 50 8 253 253 253 253
-        253 110 5 49 253 253 0 253 253 97 24 23 253 28 40 253 253
-        127 253 107 253 253 73 119 50 253 253 253 253 253 114 121
-        253 125 93 62 253 113 253 25 253 29 253 253 65 253 253 253
-        253 12 253 114 253 253 73 69 253 253 95 8 26 253 253 253 54
-        104 253 253 35 68 72 81 253 21 27 253 77 54 125 23 88 18
-        253 253 253 253 69 51 253 0 37 253 27 253 253 253 253 74
-        253 253 66 253 95 114 123 253 253 253 94 253 253 253 253
-        253 42 36 98 114 19 253 126 253 25 253 40 253 50 46 64 61
-        45 117 107 253 89 51 69 38 14 57 7 253 109 253 111 253 253
-        10 13 253 46 60 253 253 25 253 15 76 253 92 88 253 70 5 5
-        73 60 113 253 82 253 253 51 126 253 112 34 19 99 253 253
-        119 30 253 253 0 253 104 116 52 253 79 69 253 109 119 253
-        17 22 66 87 119 13 253 253 35 83 11 253 253 253 253 253 106
-        45 253 253 120 253 36 253 25 253 253 81 75 253 40 88 253
-        253 253 74 253 115 53 253 70 253 253 253 253 117 253 64 253
-        253 53 93 253 253 253 52 253 23 253 62 14 0 95 253 253 90
-        253 253 56 253 49 253 253 253 75 118 6 253 253 253 48 253
-        253 253 105 24 253 48 71 253 253 36 55 39 253 253 127 20 33
-        253 253 253 101 79 6 102 89 24 46 253 62 82 113 253 84 6 88
-        22 44 52 44 253 253 94 253 253 253 253 58 47 253 104 38 253
-        101 253 71 253 81 253 6 83 253 253 83 54 30 42 72 253 253
-        253 3 253 48 253 110 126 253 64 253 104 253 253 253 253 253
-        253 253 64 57 110 107 102 253 110 253 9 253 65 30 253 253
-        253 104 253 35 253 253 42 253 253 253 100 253 46 99 63 253
-        95 39 253 99 253 115 72 34 253 253 253 99 253 253 253 253
-        67 253 106 87 20 253 253 253 253 253 253 30 253 253 253 253
-        253 253 253 253 253 125 253 2 84 253 253 253 100 5 253 253
-        0 53 40 7 253 253 44 80 90 253 253 253 122 114 127 253 61
-        109 253 253 46 87 253 253 26 253 101 109 34 253 253 253 112
-        126 253 253 70 253 253 52 253 111 253 91 253 28 253 253 253
-        118 114 121 253 253 116 253 253 24 71 111 253 253 253 253
-        253 253 5 98 253 253 89 253 253 115 253 253 66 253 99 5 253
-        253 63 253 62 106 105 99 25 48 42 253 253 39 253 104 253
-        253 29 253 253 1 21 83 112 253 253 111 253 253 37 48 14 253
-        253 253 109 107 253 253 253 50 46 253 253 99 253 13 116 78
-        253 56 253 253 20 253 81 253 80 13 253 253 253 85 253 253
-        94 253 59 253 253 99 12 253 253 253 21 108 90 253 253 36 79
-        10 30 0 253 88 253 253 253 253 23 253 253 253 96 253 253
-        126 253 253 253 12 253 34 253 253 253 63 253 35 253 253 88
-        80 35 67 253 79 253 15 253 253 41 253 55 50 71 3 253 253
-        253 63 59 253 253 253 86 20 253 253 9 49 253 253 75 253 7
-        14 59 26 253 122 253 101 253 253 253 253 70 253 79 57 253
-        19 90 253 253 253 253 253 253 253 60 253 85 91 253 91 79
-        121 123 35 126 42 20 85 57 253 253 253 253 39 253 52 59 21
-        95 71 52 120 85 253 253 19 24 253 61 253 253 38 253 109 62
-        56 84 95 120 253 52 253 12 70 23 253 253 253 8 45 33 102 62
-        35 69 113 253 253 43 28 253 253 253 28 253 53 1 12 253 109
-        253 56 69 30 253 90 89 71 253 87 58 90 44 253 253 253 108
-        45 112 24 253 64 59 253 35 39 253 253 63 253 253 253 253
-        110 35 77 90 16 253 253 71 31 253 253 118 63 253 253 0 95
-        253 253 59 76 253 101 45 113 253 67 10 253 253 34 253 253
-        57 253 253 95 116 253 253 253 109 253 19 66 253 32 253 253
-        14 8 253 253 93 81 253 66 253 253 109 253 253 253 253 38
-        253 125 253 92 253 253 82 120 115 253 3 253 253 253 253 81
-        253 253 253 253 114 253 76 253 253 52 253 64 253 253 57 63
-        83 79 253 108 253 58 51 253 102 253 72 93 32 119 36 100 119
-        25 253 72 253 109 109 253 43 253 253 253 253 119 83 253 253
-        81 83 253 116 253 253 43 253 253 253 253 253 53 87 253 109
-        253 20 253 8 29 253 253 253 0 253 117 88 99 253 18 253 121
-        75 253 112 15 253 10 115 253 253 104 253 253 109 253 47 253
-        3 24 253 70 253 34 35 253 50 253 74 253 79 253 253 23 76 95
-        253 68 253 87 253 37 253 253 26 53 97 28 253 253 253 253 0
-        102 42 253 253 253 111 253 101 123 253 50 253 19 253 35 253
-        253 84 253 68 104 4 253 253 98 112 6 125 253 84 82 27 253
-        253 253 253 97 253 253 56 253 253 77 253 113 118 65 83 78
-        253 58 253 253 36 253 253 253 253 121 253 253 253 253 253
-        253 253 253 253 80 253 253 253 253 97 8 253 48 253 253 106
-        253 253 117 11 77 19 76 125 54 253 30 57 82 9 28 3 79 253 0
-        253 253 253 253 253 253 51 253 253 70 35 253 27 10 253 14
-        59 253 253 70 9 253 253 101 20 253 116 253 253 61 10 253 71
-        253 107 107 59 21 100 11 15 253 61 253 253 253 253 71 12 97
-        253 253 253 1 253 253 253 83 13 26 253 43 88 253 75 108 35
-        253 110 253 57 253 253 253 38 253 253 253 253 253 101 253
-        48 253 253 253 253 253 253 98 56 253 253 253 253 75 3 103
-        126 253 13 253 69 253 253 73 253 253 253 67 20 99 253 253
-        253 102 253 13 27 253 253 28 253 18 77 53 253 93 253 253 79
-        106 16 88 52 253 253 111 32 12 253 253 253 253 0 106 253
-        253 59 253 253 97 116 84 108 85 3 72 36 56 253 34 253 80 70
-        253 253 253 81 253 253 24 61 253 253 253 253 253 253 253
-        253 101 45 253 253 253 253 88 253 95 93 44 106 253 81 253
-        31 50 253 253 253 253 253 105 253 108 253 253 31 16 253 253
-        51 27 253 253 253 74 253 94 253 25 253 253 253 22 94 114 87
-        52 253 253 105 35 117 104 83 45 253 27 253 253 119 253 253
-        19 253 62 25 85 110 253 253 52 76 85 253 0 17 253 253 253
-        253 37 253 253 46 20 21 7 110 253 125 253 253 253 79 253 60
-        253 39 32 253 79 253 107 253 122 253 68 253 75 86 253 25 92
-        100 253 59 26 253 253 253 253 38 253 88 253 253 253 119 28
-        30 107 24 253 253 14 253 44 253 253 79 253 253 99 75 110 45
-        85 253 253 83 62 253 253 253 253 108 253 18 253 125 253 34
-        253 110 253 92 253 86 17 253 71 37 253 0 253 253 253 253
-        253 82 48 253 253 124 253 253 37 253 253 92 253 253 253 105
-        253 253 253 19 33 253 127 109 63 253 253 253 253 253 253
-        253 253 253 253 253 85 10 78 40 253 15 8 59 113 253 120 253
-        96 253 253 50 29 253 26 253 253 68 19 72 253 62 253 11 253
-        253 253 253 15 253 253 253 21 253 84 253 0 50 253 55 24 107
-        119 24 253 97 14 253 36 102 253 32 253 253 253 116 253 253
-        253 87 83 253 253 253 81 107 253 253 53 253 18 7 35 253 253
-        253 44 253 37 105 17 119 28 253 253 82 28 253 253 82 253 18
-        49 253 69 79 253 253 75 121 32 92 253 73 28 253 253 68 69
-        253 65 253 106 253 253 253 36 49 253 38 61 87 253 253 253
-        253 253 94 68 253 95 253 66 253 253 253 253 253 253 97 253
-        72 253 106 109 6 103 93 253 253 253 253 253 58 110 253 253
-        2 36 4 1 253 253 253 253 15 253 44 108 253 253 124 25 253
-        127 253 253 71 253 82 107 123 49 34 253 113 253 253 71 253
-        253 65 253 88 87 42 6 22 110 1 253 253 253 92 121 84 253
-        253 253 5 253 253 253 88 253 84 19 253 93 253 65 111 103
-        253 84 253 104 253 253 65 253 253 82 253 42 66 253 41 31
-        253 253 17 253 253 44 28 253 92 253 109 253 253 113 110 253
-        74 253 253 30 253 84 253 253 127 253 253 253 253 3 253 4
-        253 253 253 253 108 253 253 14 114 49 253 95 253 253 127
-        253 72 253 253 53 41 87 12 253 253 253 39 253 83 253 253
-        253 253 253 253 26 253 253 253 11 253 253 16 82 114 78 78
-        106 95 253 253 17 253 253 69 253 253 253 31 253 84 253 106
-        253 253 253 27 98 253 253 102 10 87 29 253 106 99 253 253
-        50 71 253 253 253 253 253 73 253 253 31 90 253 253 100 73
-        45 23 31 79 253 253 253 104 84 253 253 253 120 253 253 71
-        253 83 253 66 55 75 114 253 253 253 43 253 0 25 253 21 16
-        253 253 18 107 104 253 110 11 55 0 15 253 123 84 253 253
-        120 253 253 253 253 253 253 253 8 25 253 118 65 253 60 253
-        253 119 253 253 253 49 253 36 253 253 253 92 253 253 253
-        253 44 85 253 253 253 94 42 253 253 253 90 253 105 253 56
-        253 253 253 253 253 253 253 117 253 253 9 253 123 253 253
-        105 34 104 253 253 253 253 253 127 253 84 31 89 91 253 253
-        253 99 253 30 82 55 40 29 253 253 253 253 23 253 41 112 253
-        253 253 253 103 253 102 123 253 95 57 253 33 24 3 253 42 61
-        253 120 51 36 69 109 119 3 47 253 61 78 15 21 33 253 253
-        253 253 253 9 70 84 15 54 125 253 116 253 253 24 93 253 253
-        253 6 6 59 26 253 17 253 72 253 253 253 98 108 27 117 4 253
-        253 92 253 111 253 65 253 64 98 75 43 87 17 253 253 44 56
-        253 253 253 3 107 110 99 99 52 253 50 253 56 99 253 253 123
-        253 253 77 38 253 37 101 253 31 253 253 70 43 253 110 82 10
-        253 253 253 253 53 253 71 253 87 253 28 253 88 121 125 43
-        253 253 26 253 50 253 22 253 111 253 16 253 42 253 253 253
-        9 253 253 253 253 126 10 253 13 109 253 115 253 31 253 253
-        42 253 253 253 253 11 77 253 25 36 73 90 110 253 15 57 253
-        253 253 25 253 84 55 253 253 97 21 253 74 253 253 15 54 253
-        121 53 5 253 9 86 253 105 118 253 253 119 253 33 253 84 253
-        253 21 253 253 253 253 35 253 253 0 49 253 56 253 253 253
-        110 253 253 253 253 253 253 253 253 90 253 99 253 9 14 253
-        90 57 49 253 253 111 253 87 253 253 79 4 253 52 253 43 253
-        253 253 253 124 12 253 122 253 253 6 253 253 110 1 253 103
-        63 253 253 81 253 94 253 253 25 253 40 87 70 253 127 81 253
-        253 103 45 29 253 28 253 48 253 15 253 27 253 253 18 27 119
-        253 2 63 76 85 253 253 89 253 73 26 42 253 253 28 253 85
-        253 253 29 42 75 253 253 253 253 24 253 253 253 0 15 30 253
-        113 253 253 55 16 253 253 253 253 60 253 123 85 99 253 114
-        253 253 253 1 29 253 9 253 253 87 9 253 253 253 253 253 54
-        73 253 76 253 253 253 121 119 112 64 253 42 68 34 23 10 4
-        109 253 253 76 253 253 54 110 253 87 253 43 32 253 253 7
-        253 253 62 104 253 107 26 118 99 253 253 253 253 14 121 253
-        86 125 99 253 253 253 5 105 110 23 96 62 102 65 87 101 253
-        253 101 30 59 253 121 253 253 51 70 50 13 67 253 253 46 253
-        253 253 253 253 53 253 253 74 7 6 253 253 253 68 117 253 48
-        8 253 72 253 50 38 253 33 116 108 253 253 19 253 253 62 59
-        253 113 87 71 94 253 47 38 253 253 253 253 43 97 86 253 253
-        253 253 34 253 253 48 85 253 253 253 43 2 74 253 253 253
-        103 253 253 101 39 253 25 53 253 253 253 253 253 253 115 85
-        64 52 253 22 80 253 24 56 253 253 78 253 8 0 119 253 23 253
-        253 27 113 253 75 253 10 253 253 2 253 105 253 253 24 105
-        58 110 10 253 74 18 253 0 63 253 110 253 253 253 253 253
-        253 253 99 11 253 72 253 117 31 253 85 253 61 253 78 15 253
-        253 253 253 253 90 253 116 253 76 50 253 253 253 253 21 253
-        8 253 109 253 18 57 24 253 253 124 253 253 109 253 253 253
-        22 253 20 253 253 253 118 253 253 29 253 253 35 253 62 253
-        253 63 253 253 85 109 253 253 253 253 125 253 253 253 87
-        253 98 253 117 42 253 113 253 90 253 253 253 253 77 253 110
-        253 109 253 14 253 253 95 13 253 45 253 81 90 100 44 23 253
-        253 253 127 253 253 253 91 253 68 45 106 253 253 253 24 253
-        253 253 253 253 253 253 93 253 253 253 253 253 253 122 65
-        253 25 253 95 253 253 16 51 253 79 27 105 253 253 253 253
-        121 253 39 60 39 253 105 253 253 13 253 8 84 102 112 4 112
-        253 253 253 52 108 80 71 23 253 253 253 253 253 253 253 32
-        81 253 82 62 253 253 253 80 253 114 126 253 253 253 38 253
-        59 17 121 1 113 253 118 253 253 253 253 107 253 253 36 105
-        253 253 253 253 94 57 82 119 47 253 253 253 253 253 253 6
-        72 31 253 35 253 253 106 253 253 253 5 253 124 86 101 12
-        253 253 253 24 57 253 253 20 253 96 253 62 69 19 13 253 253
-        253 71 253 120 253 102 52 253 253 105 253 253 61 253 253
-        253 253 18 253 50 12 125 90 253 253 19 103 253 120 18 253
-        96 253 0 125 104 103 253 253 101 253 106 253 27 79 111 74
-        253 105 253 119 57 114 90 45 126 253 253 86 253 102 55 40 8
-        253 253 78 253 31 60 86 95 253 107 253 253 253 111 47 36
-        253 253 253 27 253 253 253 253 41 253 253 81 253 112 123
-        253 253 253 253 253 253 253 253 253 253 253 253 56 99 253
-        43 253 30 95 253 253 253 253 253 67 62 253 253 0 22 88 89
-        78 253 89 253 24 85 62 253 68 253 253 20 253 253 120 253 15
-        39 253 253 253 253 253 253 21 100 253 93 81 253 253 253 253
-        121 253 253 27 253 9 24 97 75 253 109 253 123 253 253 118
-        253 72 253 21 59 6 6 11 55 106 253 82 253 57 41 69 21 69
-        253 107 60 253 93 253 253 253 253 75 55 4 26 2 253 55 93
-        253 253 253 91 253 253 253 120 75 253 253 29 253 253 75 118
-        30 253 100 81 28 253 253 253 70 72 253 253 253 0 76 253 124
-        23 81 107 2 253 70 253 7 253 253 253 253 253 253 253 73 100
-        253 253 253 253 35 12 21 253 253 9 253 51 253 105 253 253
-        53 253 47 106 253 55 253 81 38 253 29 253 253 92 253 253
-        253 253 93 2 253 253 253 55 27 253 253 97 253 253 15 253 0
-        253 15 107 253 253 127 107 93 71 0 253 253 253 97 253 253
-        253 113 30 18 114 86 36 253 253 253 253 253 253 253 20 15
-        253 253 27 253 253 253 95 61 33 125 253 253 99 253 94 2 253
-        115 73 32 253 253 253 84 253 253 253 253 253 253 253 253
-        253 253 253 4 253 0 253 253 82 24 253 253 56 253 36 253 253
-        113 253 253 37 253 31 253 36 253 253 26 253 253 53 253 253
-        37 253 47 13 253 65 72 33 253 61 253 253 253 89 253 253 76
-        97 253 43 49 253 10 253 127 253 253 61 253 48 253 93 253
-        124 253 17 253 253 253 253 253 253 253 4 253 253 41 253 39
-        253 253 87 62 73 253 253 98 253 253 77 70 253 105 110 253
-        253 253 50 89 41 253 0 253 31 106 9 108 115 118 253 36 98
-        88 253 253 95 253 13 31 102 253 253 253 253 35 60 253 253
-        253 83 253 253 253 253 253 253 253 253 108 253 253 0 253
-        253 53 72 253 121 20 116 253 19 253 253 253 253 12 107 17
-        119 253 253 253 253 253 0 10 253 253 253 253 253 40 253 253
-        253 81 253 253 253 253 253 253 253 18 40 253 82 0 5 253 253
-        253 22 253 118 253 113 253 59 26 253 253 93 108 253 253 92
-        253 253 53 253 127 253 253 78 87 253 30 253 253 253 253 25
-        253 48 24 118 49 253 113 76 253 89 99 56 253 67 253 20 120
-        253 253 125 13 55 16 8 111 253 76 253 253 37 39 25 253 14
-        253 1 253 117 1 253 101 253 74 96 55 253 88 23 253 19 70
-        253 253 253 253 253 62 253 21 253 72 253 54 253 70 253 84
-        253 253 253 63 253 253 18 253 119 253 253 253 107 253 253
-        101 112 48 74 253 253 253 253 55 253 21 253 101 109 253 118
-        253 49 87 253 253 11 59 89 253 253 253 253 253 86 11 253 86
-        253 253 7 253 41 253 253 253 13 253 119 119 20 253 31 26 4
-        253 53 253 253 114 56 253 35 253 253 99 16 93 253 253 253
-        10 253 253 253 51 11 253 253 253 253 253 253 253 253 253
-        253 97 117 253 31 253 45 253 253 253 87 253 253 82 14 253
-        253 253 65 253 103 253 40 13 74 48 116 253 253 28 253 0 70
-        122 48 73 253 67 52 22 253 253 88 93 253 60 253 56 20 89
-        253 253 253 33 253 253 253 253 253 253 25 98 253 253 55 122
-        253 90 253 99 38 253 253 63 253 253 253 253 10 48 53 33 253
-        253 36 17 76 55 59 253 28 253 86 253 253 253 82 71 253 85
-        253 86 253 253 253 253 253 253 253 73 66 253 253 28 253 253
-        253 57 253 253 253 83 71 253 72 253 97 253 39 106 253 58
-        253 67 121 30 253 68 253 253 34 103 253 57 60 49 253 84 253
-        253 253 59 114 253 42 253 28 253 2 7 97 80 110 253 253 5
-        253 253 18 27 253 57 60 113 253 126 253 55 253 253 253 66
-        38 253 253 253 253 120 57 63 253 89 253 253 57 253 253 35
-        72 23 119 0 253 253 253 35 81 253 253 253 13 8 118 33 253
-        253 253 253 101 253 32 253 253 6 62 50 253 119 99 253 253
-        74 122 253 253 110 253 253 253 11 253 29 253 253 72 253 114
-        71 21 253 48 253 10 253 253 83 253 253 65 253 45 20 253 88
-        253 52 253 91 27 253 104 80 253 18 119 122 253 253 253 11
-        253 123 253 110 31 78 253 93 253 67 253 123 87 79 107 253
-        53 253 253 253 43 75 17 253 253 253 125 253 253 253 253 253
-        73 114 100 84 96 253 253 13 253 126 253 25 70 253 253 253
-        253 253 35 253 116 253 253 253 16 52 253 42 253 253 253 253
-        253 253 253 54 253 253 105 90 253 253 61 253 253 11 28 253
-        83 253 253 253 83 253 253 253 253 253 253 253 100 253 253
-        253 67 96 114 61 253 253 253 52 253 117 253 17 90 56 253
-        253 12 253 35 56 21 60 77 73 253 83 253 253 253 72 253 253
-        45 112 253 253 26 86 59 20 253 4 253 22 253 52 253 98 253
-        253 253 253 253 62 57 253 18 54 253 253 3 253 253 83 78 253
-        253 112 99 253 253 253 45 13 253 32 253 116 125 253 253 121
-        253 104 253 253 101 253 253 0 253 253 253 5 116 62 253 120
-        253 82 123 39 58 253 88 253 117 253 253 253 253 75 124 86
-        253 24 253 253 70 253 253 7 253 53 60 253 253 43 117 253
-        253 75 253 253 253 253 18 89 253 253 44 253 253 253 253 21
-        253 10 123 253 51 253 253 115 253 107 253 36 253 253 253
-        253 253 253 253 253 82 109 7 253 31 89 104 253 71 109 109
-        253 94 4 253 253 253 253 50 8 253 54 253 253 17 253 253 253
-        88 87 253 253 31 253 253 253 126 253 253 43 13 48 94 88 61
-        253 70 63 26 253 88 253 33 125 253 253 51 253 253 106 29
-        253 253 103 253 58 253 253 253 253 253 253 83 35 32 88 253
-        253 32 47 114 126 253 19 253 253 253 253 117 253 33 253 81
-        253 253 253 253 253 12 80 120 253 110 253 253 253 71 253
-        253 66 44 55 19 90 71 253 75 253 253 25 253 115 90 253 73
-        46 253 253 253 53 67 253 78 253 95 20 253 77 253 50 121 253
-        104 253 253 75 253 253 34 253 253 253 253 3 16 253 3 253 47
-        67 253 253 253 64 253 253 253 71 35 253 253 14 253 253 106
-        253 62 27 253 16 253 253 61 253 105 48 253 18 253 96 22 95
-        253 253 253 253 4 253 253 253 7 253 29 47 125 30 253 53 253
-        253 253 253 253 253 253 30 64 253 253 253 253 103 28 123
-        100 253 253 253 120 84 110 253 253 83 126 253 253 253 253
-        253 37 253 253 116 44 56 85 36 55 24 253 253 253 253 83 123
-        118 94 66 67 19 253 106 253 116 253 253 73 18 94 253 253
-        253 83 95 253 76 253 76 46 112 253 31 253 87 31 73 116 253
-        253 253 49 253 253 14 1 253 253 111 253 23 11 20 34 8 35
-        253 253 56 253 3 21 104 90 90 27 93 253 36 126 35 253 253
-        253 79 31 74 253 253 7 86 253 60 253 97 118 253 253 77 253
-        118 253 253 253 91 90 53 253 28 125 253 21 253 60 50 253
-        253 253 253 119 253 253 42 53 58 253 253 51 42 253 253 65
-        253 23 94 12 69 100 253 35 253 123 253 60 253 253 253 20 27
-        253 71 253 253 62 253 90 1 35 253 115 43 40 113 32 253 55
-        124 84 47 253 100 253 49 253 253 253 253 65 253 124 91 253
-        253 85 253 98 253 253 253 103 42 253 121 253 253 253 253
-        253 253 253 253 253 253 253 90 125 253 91 107 253 105 7 253
-        253 253 53 253 68 253 253 47 107 253 95 253 253 49 253 253
-        48 28 73 25 253 253 253 253 87 253 0 253 253 253 51 100 253
-        110 253 87 94 106 67 88 253 55 253 253 253 31 92 113 253 14
-        73 253 85 87 253 82 4 253 253 124 253 253 253 253 253 68 52
-        89 253 73 52 2 253 253 121 253 109 253 50 253 253 253 88 17
-        102 253 253 253 35 253 75 253 27 110 253 76 253 20 96 253
-        253 253 253 85 253 253 14 54 253 253 26 253 253 61 41 102
-        253 41 253 21 253 253 253 39 253 50 253 48 253 253 253 253
-        253 63 5 63 253 253 253 253 17 253 102 122 48 63 253 253
-        253 253 253 43 126 71 253 253 90 253 72 79 253 253 253 253
-        253 36 253 18 45 253 75 17 81 101 253 253 253 253 253 61 77
-        15 111 122 253 87 65 253 118 253 253 30 253 253 253 253 253
-        253 57 253 90 253 253 121 34 110 71 40 7 56 28 253 253 253
-        40 253 47 99 253 126 4 117 253 253 253 253 253 63 253 44
-        253 120 24 253 253 78 253 65 81 253 253 253 118 253 115 28
-        0 107 253 253 28 89 253 253 253 77 54 89 34 32 253 105 56
-        39 253 253 253 253 253 253 253 84 87 102 17 76 253 48 6 9
-        253 253 253 14 60 65 253 51 253 45 102 103 1 100 253 253
-        121 5 78 69 99 253 253 54 253 253 253 253 253 253 253 77 11
-        253 253 39 17 71 112 253 23 28 253 35 253 253 62 253 53 253
-        253 253 253 45 33 253 253 253 0 44 253 98 253 253 19 36 117
-        72 253 253 253 42 72 253 38 120 62 253 112 27 80 5 35 111
-        253 253 118 19 120 253 1 96 253 253 1 253 253 44 253 80 110
-        253 253 253 105 253 64 253 30 253 21 253 25 100 25 82 48 69
-        84 253 0 18 122 82 19 35 253 101 32 253 100 10 253 3 46 56
-        96 104 109 66 253 27 253 253 253 253 253 253 253 40 253 27
-        28 253 253 253 91 253 253 253 91 253 43 63 253 20 71 60 253
-        253 0 74 125 253 93 69 117 98 88 93 253 22 253 92 4 253 253
-        253 91 253 253 76 108 253 72 253 80 51 253 253 106 253 253
-        253 41 68 253 111 29 253 8 253 253 253 253 113 253 124 37
-        103 124 36 253 42 253 44 121 46 108 53 253 253 253 69 253
-        108 253 65 253 253 253 119 253 253 23 253 253 104 37 253
-        253 10 63 253 253 253 253 253 37 253 253 58 253 112 253 253
-        64 253 48 79 253 89 90 93 253 253 253 253 89 253 103 253
-        253 253 123 15 113 253 253 71 43 253 103 52 253 46 52 253
-        27 93 253 99 116 253 253 44 86 253 253 69 253 44 253 253
-        253 84 30 253 64 107 107 253 253 253 56 31 46 7 253 118 253
-        253 253 90 253 253 93 253 54 253 118 57 42 57 253 253 253
-        106 125 33 253 253 120 100 88 86 104 253 96 101 107 253 50
-        253 37 105 28 253 253 253 116 14 253 253 253 253 253 55 51
-        49 253 253 253 253 253 125 55 253 253 54 253 45 253 253 72
-        253 253 70 55 15 122 253 52 46 253 253 253 253 55 253 253
-        20 253 253 99 253 83 253 90 104 253 84 253 97 253 86 49 253
-        36 96 253 53 253 253 253 37 253 253 253 110 253 253 116 79
-        10 253 121 20 253 253 253 4 124 253 107 253 253 253 253 253
-        54 253 105 24 72 253 55 253 253 253 253 53 253 253 253 253
-        109 253 36 253 112 30 68 114 253 253 114 77 87 253 73 121
-        253 91 253 253 87 46 253 121 71 253 253 73 101 116 253 253
-        253 253 51 45 96 106 26 253 253 253 122 253 99 253 45 253 5
-        54 253 30 253 253 253 253 253 253 253 3 20 253 253 253 253
-        253 30 40 253 253 253 253 70 25 253 26 253 253 111 253 99
-        253 253 60 253 70 37 3 253 92 80 79 108 76 253 56 253 25
-        116 63 79 253 253 253 253 253 79 253 125 79 253 74 23 253
-        25 253 28 115 88 253 253 12 33 19 253 119 253 253 58 38 55
-        56 31 90 253 253 253 105 253 99 58 253 46 253 96 253 118
-        253 253 253 52 67 253 102 253 48 253 253 51 69 253 44 126
-        25 60 253 253 14 253 253 253 96 84 253 253 253 5 253 32 253
-        69 103 253 40 114 26 253 15 253 253 81 253 253 253 253 80
-        83 95 73 253 253 33 56 253 0 91 253 253 253 29 68 108 99 48
-        253 9 253 0 124 253 24 63 110 106 11 253 117 110 253 53 253
-        253 253 253 253 253 253 112 114 253 253 88 253 44 46 253
-        253 33 253 79 253 253 73 85 84 16 253 253 253 87 37 124 96
-        253 11 91 253 78 75 11 75 253 21 253 19 253 70 56 253 39 86
-        253 53 253 70 57 32 253 253 82 253 14 28 13 253 87 253 253
-        253 69 253 58 29 253 253 253 42 67 113 123 118 92 253 253 0
-        99 253 107 112 79 253 106 253 45 253 37 253 105 14 112 123
-        31 122 33 253 253 253 60 55 108 125 40 253 99 104 81 97 112
-        253 253 253 253 65 22 96 73 253 253 74 253 253 27 60 53 9
-        253 43 43 104 253 112 57 253 21 253 33 253 253 253 98 253
-        253 13 32 12 253 65 7 253 74 253 253 253 57 253 111 83 253
-        253 73 38 127 24 71 253 60 69 253 25 253 253 49 253 120 253
-        253 103 117 253 253 253 253 113 253 253 253 253 253 31 106
-        22 253 40 253 253 253 253 253 62 105 253 25 253 30 109 42
-        253 113 253 253 253 253 253 57 253 44 44 48 59 119 253 52
-        103 85 253 44 253 253 76 8 127 93 253 85 253 253 253 253 42
-        71 74 116 70 253 2 253 94 14 113 253 97 253 253 87 65 253
-        36 253 253 253 40 253 8 253 47 113 253 253 253 109 253 107
-        253 37 60 253 253 253 83 253 253 253 253 39 87 0 110 35 253
-        253 253 253 253 102 253 253 253 253 253 58 103 253 253 35
-        48 52 114 32 24 253 253 253 253 91 107 253 253 253 5 253 4
-        24 253 56 253 253 77 253 253 89 68 253 55 253 83 253 76 14
-        126 253 52 253 253 55 253 253 76 253 253 126 87 3 253 90 82
-        85 70 74 253 44 116 24 253 253 78 119 103 253 253 48 71 253
-        253 92 104 253 253 253 17 76 111 253 253 253 253 109 38 72
-        100 253 6 253 253 253 118 253 123 253 253 253 11 109 9 28
-        253 253 253 32 100 84 69 110 253 253 253 253 66 253 111 253
-        253 253 47 253 78 114 5 72 45 253 86 253 253 253 114 40 93
-        253 253 57 253 41 93 253 81 253 127 253 15 253 38 120 34
-        253 253 106 64 58 253 28 121 80 57 111 115 72 60 23 253 253
-        29 74 89 38 86 253 45 253 253 253 253 253 253 253 121 8 5
-        253 64 9 253 72 253 253 55 48 253 4 253 253 253 49 30 104
-        253 111 253 253 253 253 253 19 253 253 253 124 39 95 253
-        253 78 76 87 75 253 253 253 113 121 98 20 253 253 57 35 253
-        253 253 93 11 13 253 253 253 54 84 253 253 80 7 38 253 58
-        35 53 253 253 93 253 104 253 253 73 253 1 253 108 253 253
-        253 253 253 253 69 41 253 253 5 253 253 37 253 253 253 253
-        17 59 84 14 253 253 81 253 253 109 67 78 253 253 11 34 253
-        253 253 253 253 253 101 253 253 49 253 253 253 73 253 104
-        253 253 105 253 253 253 253 113 72 253 253 253 253 103 253
-        253 253 253 46 253 253 56 253 78 253 253 253 253 253 101
-        107 253 23 37 89 253 253 70 77 253 78 15 53 53 253 253 108
-        253 253 253 107 120 253 42 253 253 65 65 253 253 104 253 54
-        107 253 253 88 253 36 82 253 253 125 253 111 253 53 101 253
-        127 253 40 122 253 253 253 86 41 3 253 253 15 106 253 125
-        123 253 253 253 253 109 253 54 3 253 253 253 74 253 253 253
-        53 75 253 109 97 70 253 253 253 253 253 105 90 109 253 111
-        253 253 9 253 253 253 41 253 253 105 253 78 253 21 78 253
-        253 55 253 72 253 33 98 31 253 253 253 15 253 75 116 79 253
-        114 8 253 111 35 253 123 118 253 119 31 90 253 52 253 54 27
-        24 253 253 125 253 253 253 113 84 73 62 253 253 253 18 122
-        100 95 253 253 102 29 46 97 253 64 253 23 253 253 253 253
-        253 83 253 28 108 25 253 31 111 122 253 43 108 253 71 253
-        253 253 80 109 253 109 77 253 253 17 30 121 25 253 77 72
-        253 83 126 253 253 23 107 26 253 60 253 253 40 24 111 253
-        253 111 14 8 253 253 78 75 103 253 253 87 50 5 253 253 2 59
-        253 79 21 253 11 103 110 253 18 6 62 253 253 105 28 253 10
-        253 85 123 38 253 45 253 88 253 81 253 67 32 30 253 253 253
-        253 253 80 253 114 253 22 10 253 108 30 62 253 253 79 46 46
-        86 123 98 100 102 253 7 30 94 253 253 26 28 69 253 52 56 95
-        109 253 109 253 108 51 253 253 23 253 104 253 253 25 13 31
-        253 253 253 253 253 27 253 6 56 84 253 253 46 120 12 253 2
-        253 115 20 110 253 110 19 253 253 110 21 62 253 253 253 253
-        52 101 253 43 64 253 253 253 253 104 69 127 74 253 80 253
-        253 253 253 253 51 253 253 14 15 253 106 253 253 253 39 75
-        253 253 253 253 253 21 253 112 126 84 98 23 253 253 39 87
-        253 253 253 49 71 82 114 25 71 106 253 122 253 37 253 40 50
-        77 55 253 64 0 15 253 86 253 53 20 87 81 74 253 253 253 35
-        67 39 101 253 36 99 253 104 9 50 253 54 253 253 35 253 13
-        19 253 45 36 96 65 27 253 253 57 253 253 253 253 253 253 20
-        4 73 253 103 24 253 20 253 122 116 122 47 253 253 253 9 253
-        253 72 253 253 253 32 3 253 122 253 63 53 253 253 253 253
-        34 253 253 60 253 253 61 253 253 253 253 12 102 253 69 26
-        253 253 253 253 253 253 253 92 5 253 253 253 70 253 105 11
-        47 253 253 253 80 87 253 0 253 253 63 253 253 253 86 253
-        253 253 3 253 253 253 99 253 41 253 253 0 253 122 253 17 92
-        253 118 127 253 253 253 1 253 30 18 86 253 51 253 253 253
-        87 253 253 13 50 12 253 64 27 31 253 76 253 253 253 253 253
-        253 120 123 80 41 253 115 253 106 40 253 98 43 123 253 111
-        55 253 253 113 253 253 86 7 70 253 76 253 253 31 253 68 253
-        253 253 253 253 96 62 253 253 253 253 90 28 253 253 99 253
-        253 253 59 253 0 253 15 253 253 83 110 253 253 9 102 253 45
-        253 253 102 253 39 28 253 253 253 98 41 253 253 39 68 253 0
-        253 253 253 253 58 253 253 73 253 253 253 253 73 253 1 30
-        253 97 104 253 253 253 253 253 103 118 253 253 71 253 25
-        253 253 253 63 70 253 253 62 253 253 253 21 253 118 253 70
-        253 253 27 99 71 253 253 253 65 53 34 253 253 77 74 253 47
-        253 114 58 253 68 253 253 31 99 89 253 11 253 253 253 253
-        99 253 30 56 253 54 253 74 253 102 50 61 253 253 253 253
-        120 56 63 32 61 253 78 23 253 53 94 105 26 253 253 253 34
-        65 253 88 253 66 253 253 253 253 253 63 92 122 84 253 253
-        253 75 253 253 68 253 34 253 79 253 1 253 253 74 70 19 118
-        253 11 253 67 44 253 253 18 6 253 253 253 75 253 90 253 71
-        102 253 253 124 253 253 64 253 253 253 253 97 253 253 50
-        253 253 82 7 96 253 253 91 106 39 253 253 253 253 253 253
-        253 253 253 71 253 35 84 253 21 253 253 253 49 34 253 13
-        253 24 253 103 45 29 253 253 82 84 253 253 56 81 69 253 110
-        49 40 48 52 89 28 253 19 253 21 253 253 253 73 253 104 253
-        253 125 8 28 253 253 108 77 38 107 71 120 253 109 66 69 16
-        38 82 253 253 28 253 80 86 73 58 66 99 117 124 253 57 70
-        253 0 253 100 253 60 78 89 81 253 49 253 8 114 63 253 253
-        116 48 99 44 253 63 45 253 123 253 253 253 253 120 253 253
-        97 102 63 253 69 97 52 253 253 253 68 253 253 57 253 109
-        253 0 106 85 253 92 92 253 21 69 112 253 253 32 253 22 253
-        24 41 50 63 253 253 253 253 253 87 118 253 253 73 27 253
-        253 101 126 253 253 122 253 93 117 30 253 38 253 253 94 253
-        253 253 19 253 109 30 48 78 61 8 253 253 253 253 253 92 25
-        97 105 87 253 253 253 253 85 253 17 253 3 72 253 125 66 13
-        98 253 253 253 253 71 112 23 37 99 32 78 61 73 24 253 79 39
-        25 253 120 253 253 253 253 1 253 55 105 253 17 253 253 253
-        253 253 50 253 52 253 253 7 253 23 253 0 253 253 253 253 66
-        253 253 52 253 253 253 253 253 28 253 253 104 115 253 97
-        103 13 253 253 96 253 28 40 253 253 253 253 253 63 253 52
-        253 46 47 253 253 48 50 253 253 253 253 253 71 81 68 114 91
-        118 253 97 253 253 253 85 49 253 102 253 253 67 253 110 96
-        88 253 77 109 119 50 253 253 24 253 45 253 71 109 24 101
-        102 64 253 57 11 253 253 73 253 73 79 253 253 37 253 253
-        253 253 40 14 253 253 115 253 7 253 7 113 54 253 48 253 253
-        85 126 253 253 71 11 42 110 109 253 253 0 253 108 127 253
-        105 72 101 253 253 253 253 88 253 253 2 54 15 253 83 59 253
-        85 5 105 253 55 253 93 253 253 118 52 46 253 34 67 3 253
-        253 93 253 101 3 36 83 68 253 84 92 253 100 125 253 38 253
-        36 253 4 253 253 108 253 30 253 253 253 94 253 253 12 253
-        253 90 253 253 99 86 111 12 54 91 105 253 21 39 253 85 253
-        253 98 82 253 253 6 60 79 253 82 253 46 253 253 253 104 12
-        1 253 78 253 114 104 253 253 253 253 253 57 60 253 6 101
-        253 253 253 253 81 253 62 94 77 44 253 253 83 42 23 253 253
-        253 253 21 29 253 253 34 253 253 253 253 69 1 3 45 52 253
-        103 31 65 253 0 106 47 91 253 45 44 81 253 95 21 253 29 253
-        26 33 44 253 253 21 16 253 126 253 253 8 253 109 13 253 253
-        253 253 253 99 113 253 253 253 41 1 253 62 253 253 104 253
-        69 36 253 49 42 23 253 52 253 253 99 253 61 253 253 253 53
-        253 37 34 253 253 253 253 253 253 60 253 253 76 125 9 253
-        86 14 253 253 114 73 40 253 253 54 109 253 45 253 72 253
-        253 253 253 117 47 253 253 253 253 93 78 253 76 35 253 253
-        253 253 253 253 79 21 253 253 253 253 58 253 253 253 39 253
-        64 253 43 3 253 34 253 253 253 16 253 70 253 253 253 253 69
-        75 117 253 253 253 253 253 253 37 253 253 15 253 253 112
-        253 61 253 71 36 253 44 93 253 85 69 253 253 85 253 3 253
-        253 253 253 96 253 253 253 253 253 63 74 253 29 253 53 253
-        102 73 6 253 253 253 253 253 0 253 106 85 253 253 99 253 79
-        45 253 38 30 253 253 253 253 253 120 253 253 64 8 253 15
-        253 1 253 70 11 124 253 253 253 35 20 253 9 35 116 37 90
-        253 5 253 29 253 65 253 18 253 0 67 253 253 0 116 253 90 41
-        16 1 253 253 253 253 106 24 253 61 253 110 27 253 54 253 61
-        253 78 253 253 110 34 253 47 253 55 253 253 253 253 253 253
-        253 85 253 253 73 118 116 253 253 109 63 253 253 83 53 253
-        253 126 253 253 253 80 80 253 253 253 15 253 122 95 253 253
-        253 122 253 88 253 253 253 253 95 253 253 253 107 86 253
-        253 253 253 253 87 253 31 253 253 77 253 121 253 0 253 253
-        49 127 90 95 253 253 122 253 74 253 253 99 253 253 104 22
-        253 253 125 253 253 253 253 69 126 253 253 253 253 253 79
-        253 253 94 253 80 8 60 253 253 95 253 100 253 253 74 253
-        122 253 253 62 46 253 26 253 253 253 79 253 253 94 253 47
-        30 253 253 126 253 81 253 253 253 253 253 253 100 253 253
-        63 45 125 253 253 253 253 0 109 122 253 80 253 253 51 91
-        253 253 253 253 253 94 253 85 95 253 253 253 253 253 126
-        253 111 253 63 253 94 253 83 46 253 253 253 253 253 253 91
-        117 15 253 253 253 122 253 253 58 253 253 253 111 253 253
-        253 127 253 39 253 85 253 253 17 88 116 253 253 253 253 253
-        253 253 253 87 253 253 16 77 109 253 105 105 76 253 253 253
-        253 94 253 253 253 87 253 0 50 253 0 253 88 71 253 10 253
-        122 253 64 253 253 253 253 253 253 85 253 0 106 253 94 253
-        125 253 35 47 253 58 105 99 253 68 253 0 253 253 87 253 253
-        253 63 253 253 13 10 45 45 45 45 45 45 87 101 98 75 105 116
-        70 111 114 109 66 111 117 110 100 97 114 121 115 105 103
-        113 43 53 113 87 116 54 79 114 122 56 76 79 45 45 13 10
-    } >string ;
+[ t ] [ dog-test-empty-bytes-firefox test-file1 ] unit-test
+[ t ] [ dog-test-empty-bytes-firefox test-file2 ] unit-test
+[ t ] [ dog-test-empty-bytes-firefox test-file3 ] unit-test
 
+[ t ] [ dog-test-empty-bytes-safari test-file1 ] unit-test
+[ t ] [ dog-test-empty-bytes-safari test-file2 ] unit-test
+[ t ] [ dog-test-empty-bytes-safari test-file3 ] unit-test
index 4c7b95699e6eb9e22a8b1e3abd621f41cce4b2ed..3e44f163ed1a635c0b5f89c6cb9c772b6544e3d4 100644 (file)
@@ -1,7 +1,9 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors combinators io kernel locals math multiline
-sequences splitting prettyprint ;
+sequences splitting prettyprint namespaces http.parsers
+ascii assocs unicode.case io.files.unique io.files io.encodings.binary
+byte-arrays io.encodings make fry ;
 IN: mime.multipart
 
 TUPLE: multipart-stream stream n leftover separator ;
@@ -27,37 +29,77 @@ TUPLE: multipart-stream stream n leftover separator ;
 : multipart-split ( bytes separator -- before after seq=? )
     2dup sequence= [ 2drop f f t ] [ split1 f ] if ;
 
-:: multipart-step-found ( bytes stream quot -- ? )
-    bytes [
-        quot unless-empty
-    ] [
-        stream (>>leftover)
-        quot unless-empty
-    ] if-empty f quot call f ;
+:: multipart-step-found ( bytes stream quot: ( bytes -- ) -- ? )
+    bytes [ quot unless-empty ]
+    [ stream (>>leftover) quot unless-empty ] if-empty f ; inline
 
-:: multipart-step-not-found ( stream end-stream? separator quot -- ? )
-    end-stream? [
+:: multipart-step-not-found ( bytes stream end-stream? separator quot: ( bytes -- ) -- ? )
+    bytes end-stream? [
         quot unless-empty f
     ] [
         separator length 1- ?cut* stream (>>leftover)
         quot unless-empty t
-    ] if ;
+    ] if ; inline
 
 :: multipart-step ( stream bytes end-stream? separator quot: ( bytes -- ) -- ? end-stream? )
     #! return t to loop again
     bytes separator multipart-split
-    [ 2drop f quot call f ]
+    [ 2drop f ]
     [
         [ stream quot multipart-step-found ]
         [ stream end-stream? separator quot multipart-step-not-found ] if*
-    ] if stream leftover>> end-stream? not or ;
+    ] if stream leftover>> end-stream? not or >boolean ;
 
-PRIVATE>
 
-:: multipart-step-loop ( stream quot1: ( bytes -- ) quot2: ( -- ) -- ? )
+:: multipart-step-loop ( stream quot1: ( bytes -- ) -- ? )
     stream dup [ read-n ] [ separator>> ] bi quot1 multipart-step
-    swap [ drop stream quot1 quot2 multipart-step-loop ] quot2 if ;
+    swap [ drop stream quot1 multipart-step-loop ] when ; inline recursive
+
+SYMBOL: header
+SYMBOL: parsed-header
+SYMBOL: magic-separator
+
+: trim-blanks ( str -- str' ) [ blank? ] trim ;
+
+: trim-quotes ( str -- str' )
+    [ [ CHAR: " = ] [ CHAR: ' = ] bi or ] trim ;
+
+: parse-content-disposition ( str -- content-disposition hash )
+    ";" split [ first ] [ rest-slice ] bi [ "=" split ] map
+    [ [ trim-blanks ] [ trim-quotes ] bi* ] H{ } assoc-map-as ;
+
+: parse-multipart-header ( string -- headers )
+    "\r\n" split harvest
+    [ parse-header-line first2 ] H{ } map>assoc ;
 
-: multipart-loop-all ( stream quot1: ( bytes -- ) quot2: ( -- ) -- )
-    3dup multipart-step-loop
-    [ multipart-loop-all ] [ 3drop ] if ;
+ERROR: expected-file ;
+
+TUPLE: uploaded-file path filename name ;
+
+: (parse-multipart) ( stream -- ? )
+    "\r\n\r\n" >>separator
+    header off
+    dup [ header [ prepend ] change ] multipart-step-loop drop
+    header get dup magic-separator get [ length ] bi@ < [
+        2drop f
+    ] [
+        parse-multipart-header
+        parsed-header set
+        "\r\n" magic-separator get append >>separator
+        "factor-upload" "httpd" make-unique-file tuck
+        binary [ [ write ] multipart-step-loop ] with-file-writer swap
+        "content-disposition" parsed-header get at parse-content-disposition
+        nip [ "filename" swap at ] [ "name" swap at ] bi
+        uploaded-file boa ,
+    ] if ;
+
+PRIVATE>
+
+: parse-multipart ( stream -- array )
+    [
+        "\r\n" <multipart-stream>
+        magic-separator off
+        dup [ magic-separator [ prepend ] change ]
+            multipart-step-loop drop
+        '[ [ _ (parse-multipart) ] loop ] { } make
+    ] with-scope ;
index fd547c8b5a3d3f9ae377b3efdd987423d2a4905d..ea37829d0ee13537cbf78a8993b602a4cfe2546e 100644 (file)
@@ -1,6 +1,6 @@
-USING: alien alien.syntax combinators kernel parser sequences
-system words namespaces hashtables init math arrays assocs
-continuations lexer ;
+USING: alien alien.syntax alien.parser combinators
+kernel parser sequences system words namespaces hashtables init
+math arrays assocs continuations lexer fry locals ;
 IN: opengl.gl.extensions
 
 ERROR: unknown-gl-platform ;
@@ -30,12 +30,23 @@ reset-gl-function-number-counter
 : gl-function-pointer ( names n -- funptr )
     gl-function-context 2array dup +gl-function-pointers+ get-global at
     [ 2nip ] [
-        >r [ gl-function-address ] map [ ] find nip
-        dup [ "OpenGL function not available" throw ] unless
-        dup r>
+        [
+            [ gl-function-address ] map [ ] find nip
+            dup [ "OpenGL function not available" throw ] unless
+            dup
+        ] dip
         +gl-function-pointers+ get-global set-at
     ] if* ;
 
+: indirect-quot ( function-ptr-quot return types abi -- quot )
+    '[ @  _ _ _ alien-indirect ] ;
+
+:: define-indirect ( abi return function-ptr-quot function-name parameters -- )
+    function-name create-in dup reset-generic
+    function-ptr-quot return
+    parameters return parse-arglist [ abi indirect-quot ] dip
+    define-declared ;
+
 : GL-FUNCTION:
     gl-function-calling-convention
     scan
index 27936eea1c5a23d2e93f83d99b8a5aa2de5d1235..74f06ed65be1ef7daa9ba96058dbc1db088b033c 100644 (file)
@@ -271,9 +271,9 @@ IN: regexp-tests
 
 [ "b" ] [ "aaaaaaaaaaaaaaaaaaaaaaab" "((a*)*b)*b" <regexp> first-match >string ] unit-test
 
-[ t ] [ "a:b" ".+:?" <regexp> matches? ] unit-test
+[ t ] [ "a:b" ".+:?" <regexp> matches? ] unit-test
 
-[ 1 ] [ "hello" ".+?" <regexp> match length ] unit-test
+[ 1 ] [ "hello" ".+?" <regexp> match length ] unit-test
 
 [ { "1" "2" "3" "4" } ]
 [ "1ABC2DEF3GHI4" R/ [A-Z]+/ re-split [ >string ] map ] unit-test
@@ -295,7 +295,7 @@ IN: regexp-tests
 
 [ f ] [ "ab" "a(?!b)" <regexp> first-match ] unit-test
 [ "a" ] [ "ac" "a(?!b)" <regexp> first-match >string ] unit-test
-[ t ] [ "fxxbar" "(?!foo).{3}bar" <regexp> matches? ] unit-test
+[ t ] [ "fxxbar" "(?!foo).{3}bar" <regexp> matches? ] unit-test
 [ f ] [ "foobar" "(?!foo).{3}bar" <regexp> matches? ] unit-test
 [ "a" ] [ "ab" "a(?=b)(?=b)" <regexp> first-match >string ] unit-test
 [ "a" ] [ "ba" "a(?<=b)(?<=b)" <regexp> first-match >string ] unit-test
index a6a8bb2ccaa28ced9355e514ce1dbf6c35ce9543..7de22e9af9a3ccbd8ded2a29099c0bc30d3a2d46 100644 (file)
@@ -1,13 +1,14 @@
 ! Copyright (C) 2007 Elie CHAFTARI
 ! See http://factorcode.org/license.txt for BSD license.
-USING: combinators kernel prettyprint io io.timeouts
-sequences namespaces io.sockets continuations calendar
-io.encodings.ascii io.streams.duplex destructors ;
+USING: combinators kernel prettyprint io io.timeouts sequences
+namespaces io.sockets io.sockets.secure continuations calendar
+io.encodings.ascii io.streams.duplex destructors locals
+concurrency.promises threads accessors smtp.private
+io.unix.sockets.secure.debug ;
 IN: smtp.server
 
 ! Mock SMTP server for testing purposes.
 
-! Usage: 4321 mock-smtp-server
 ! $ telnet 127.0.0.1 4321
 ! Trying 127.0.0.1...
 ! Connected to localhost.
@@ -34,41 +35,52 @@ IN: smtp.server
 SYMBOL: data-mode
 
 : process ( -- )
-    readln {
-        { [ [ dup "HELO" head? ] keep "EHLO" head? or ] [ 
-            "220 and..?\r\n" write flush t
-          ] }
-        { [ dup "QUIT" = ] [ 
-            "bye\r\n" write flush f
-          ] }
-        { [ dup "MAIL FROM:" head? ] [ 
-            "220 OK\r\n" write flush t
-          ] }
-        { [ dup "RCPT TO:" head? ] [ 
-            "220 OK\r\n" write flush t
-          ] }
-        { [ dup "DATA" = ] [
-            data-mode on 
-            "354 Enter message, ending with \".\" on a line by itself\r\n"
-            write flush t
-          ] }
-        { [ dup "." = data-mode get and ] [
-            data-mode off
-            "220 OK\r\n" write flush t
-          ] }
+    read-crlf {
+        {
+            [ dup [ "HELO" head? ] [ "EHLO" head? ] bi or ]
+            [ "220 and..?\r\n" write flush t ]
+        }
+        {
+            [ dup "STARTTLS" = ]
+            [
+                "220 2.0.0 Ready to start TLS\r\n" write flush
+                accept-secure-handshake t
+            ]
+        }
+        { [ dup "QUIT" = ] [ "220 bye\r\n" write flush f ] }
+        { [ dup "MAIL FROM:" head? ] [ "220 OK\r\n" write flush t ] }
+        { [ dup "RCPT TO:" head? ] [ "220 OK\r\n" write flush t ] }
+        {
+            [ dup "DATA" = ]
+            [
+                data-mode on 
+                "354 Enter message, ending with \".\" on a line by itself\r\n"
+                write flush t
+            ]
+        }
+        {
+            [ dup "." = data-mode get and ]
+            [
+                data-mode off
+                "220 OK\r\n" write flush t
+            ]
+        }
         { [ data-mode get ] [ dup global [ print ] bind t ] }
-        [ 
-            "500 ERROR\r\n" write flush t
-        ]
+        [ "500 ERROR\r\n" write flush t ]
     } cond nip [ process ] when ;
 
-: mock-smtp-server ( port -- )
-    "Starting SMTP server on port " write dup . flush
-    "127.0.0.1" swap <inet4> ascii <server> [
-        accept drop [
-            1 minutes timeouts
-            "220 hello\r\n" write flush
-            process
-            global [ flush ] bind
-        ] with-stream
-    ] with-disposal ;
+:: mock-smtp-server ( promise -- )
+    #! Store the port we are running on in the promise.
+    [
+        [
+            "127.0.0.1" 0 <inet4> ascii <server> [
+            dup addr>> port>> promise fulfill
+                accept drop [
+                    1 minutes timeouts
+                    "220 hello\r\n" write flush
+                    process
+                    global [ flush ] bind
+                ] with-stream
+            ] with-disposal
+        ] with-test-context
+    ] in-thread ;
index c1c2d1c1f8f151a9884c2ec5e673097966c00e51..83b9287043fbf9882aba604f173037af74b9254c 100644 (file)
@@ -5,20 +5,52 @@ io.sockets strings calendar ;
 IN: smtp
 
 HELP: smtp-domain
-{ $description "The name of the machine that is sending the email.  This variable will be filled in by the " { $link host-name } " word if not set by the user." } ;
+{ $var-description "The name of the machine that is sending the email.  This variable will be filled in by the " { $link host-name } " word if not set by the user." } ;
 
 HELP: smtp-server
-{ $description "Holds an " { $link inet } " object with the address of an SMTP server." } ;
+{ $var-description "Holds an " { $link inet } " object with the address of an SMTP server." } ;
+
+HELP: smtp-tls?
+{ $var-description "If set to true, secure socket communication will be established after connecting to the SMTP server. The server must support the " { $snippet "STARTTLS" } " command. Off by default." } ;
 
 HELP: smtp-read-timeout
-{ $description "Holds an " { $link duration } " object that specifies how long to wait for a response from the SMTP server." } ;
+{ $var-description "Holds a " { $link duration } " object that specifies how long to wait for a response from the SMTP server." } ;
+
+HELP: smtp-auth
+{ $var-description "Holds either " { $link no-auth } " or an instance of " { $link plain-auth } ", specifying how to authenticate with the SMTP server. Set to " { $link no-auth } " by default." } ;
+
+HELP: no-auth
+{ $class-description "If the " { $link smtp-auth } " variable is set to this value, no authentication will be performed." } ;
+
+HELP: plain-auth
+{ $class-description "If the " { $link smtp-auth } " variable is set to this value, plain authentication will be performed, with the username and password stored in the " { $slot "username" } " and " { $slot "password" } " slots of the tuple sent to the server as plain-text." } ;
 
-HELP: esmtp?
-{ $description "Set true by default, determines whether the SMTP client is using the Extended SMTP protocol." } ;
+HELP: <plain-auth> ( username password -- plain-auth )
+{ $values { "username" string } { "password" string } { "plain-auth" plain-auth } }
+{ $description "Creates a new " { $link plain-auth } " instance." } ;
 
 HELP: with-smtp-connection
 { $values { "quot" quotation } }
-{ $description "Connects to an SMTP server stored in " { $link smtp-server } " and calls the quotation." } ;
+{ $description "Connects to an SMTP server stored in " { $link smtp-server } " and calls the quotation." }
+{ $notes "This word is used to implement " { $link send-email } " and there is probably no reason to call it directly." } ;
+
+HELP: email
+{ $class-description "An e-mail. E-mails have the following slots:"
+    { $table
+        { { $slot "from" } "The sender of the e-mail. An e-mail address." }
+        { { $slot "to" } "The recipients of the e-mail. A sequence of e-mail addresses." }
+        { { $slot "cc" } "Carbon-copy. A sequence of e-mail addresses." }
+        { { $slot "bcc" } "Blind carbon-copy. A sequence of e-mail addresses." }
+        { { $slot "subject" } " The subject of the e-mail. A string." }
+        { { $slot "body" } " The body of the e-mail. A string." }
+    }
+"The " { $slot "from" } " and " { $slot "to" } " slots are required; the rest are optional."
+$nl
+"An e-mail address is a string in one of the following two formats:"
+{ $list
+    { $snippet "joe@groff.com" }
+    { $snippet "Joe Groff <joe@groff.com>" }
+} } ;
 
 HELP: <email>
 { $values { "email" email } }
@@ -26,9 +58,9 @@ HELP: <email>
 
 HELP: send-email
 { $values { "email" email } }
-{ $description "Sends an " { $link email } " object to an STMP server stored in the " { $link smtp-server } " variable.  The required slots are " { $slot "from" } " and " { $slot "to" } "." }
+{ $description "Sends an e-mail." }
 { $examples
-    { $unchecked-example "USING: accessors smtp ;"
+    { $code "USING: accessors smtp ;"
     "<email>"
     "    \"groucho@marx.bros\" >>from"
     "    { \"chico@marx.bros\" \"harpo@marx.bros\" } >>to"
@@ -42,10 +74,21 @@ HELP: send-email
 } ;
 
 ARTICLE: "smtp" "SMTP client library"
-"Configuring SMTP:"
+"The " { $vocab-link "smtp" } " vocabulary sends e-mail via an SMTP server."
+$nl
+"This library is configured by a set of dynamically-scoped variables:"
 { $subsection smtp-server }
+{ $subsection smtp-tls? }
 { $subsection smtp-read-timeout }
 { $subsection smtp-domain }
-{ $subsection esmtp? }
+{ $subsection smtp-auth }
+"The latter is set to an instance of one of the following:"
+{ $subsection no-auth }
+{ $subsection plain-auth }
+"Constructing an e-mail:"
+{ $subsection email }
+{ $subsection <email> }
 "Sending an email:"
 { $subsection send-email } ;
+
+ABOUT: "smtp"
index f8b321fdac465218ad4ae1d4f3d585fbfe83c984..e3638bd96918fcb527f4448bf0270e6542cc7504 100644 (file)
@@ -1,8 +1,11 @@
-USING: smtp tools.test io.streams.string io.sockets threads
-smtp.server kernel sequences namespaces logging accessors
-assocs sorting smtp.private ;
+USING: smtp tools.test io.streams.string io.sockets
+io.sockets.secure threads smtp.server kernel sequences
+namespaces logging accessors assocs sorting smtp.private
+concurrency.promises system ;
 IN: smtp.tests
 
+\ send-email must-infer
+
 { 0 0 } [ [ ] with-smtp-connection ] must-infer-as
 
 [ "hello\nworld" validate-address ] must-fail
@@ -16,15 +19,22 @@ IN: smtp.tests
     "hello\nworld" [ send-body ] with-string-writer
 ] unit-test
 
-[ "500 syntax error" check-response ] must-fail
+[ { "500 syntax error" } <response> check-response ]
+[ smtp-error? ] must-fail-with
 
-[ ] [ "220 success" check-response ] unit-test
+[ ] [ { "220 success" } <response> check-response ] unit-test
 
-[ "220 success" ] [
+[ T{ response f 220 { "220 success" } } ] [
     "220 success" [ receive-response ] with-string-reader
 ] unit-test
 
-[ "220 the end" ] [
+[
+    T{ response f 220 {
+        "220-a multiline response"
+        "250-another line"
+        "220 the end"
+    } }
+] [
     "220-a multiline response\r\n250-another line\r\n220 the end"
     [ receive-response ] with-string-reader
 ] unit-test
@@ -63,13 +73,15 @@ IN: smtp.tests
     [ from>> extract-email ] tri
 ] unit-test
 
-[ ] [ [ 4321 mock-smtp-server ] "SMTP server" spawn drop ] unit-test
+<promise> "p" set
 
-[ ] [ yield ] unit-test
+[ ] [ "p" get mock-smtp-server ] unit-test
 
 [ ] [
-    [
-        "localhost" 4321 <inet> smtp-server set
+    <secure-config> f >>verify [
+        "localhost" "p" get ?promise <inet> smtp-server set
+        no-auth smtp-auth set
+        os unix? [ smtp-tls? on ] when
 
         <email>
             "Hi guys\nBye guys" >>body
@@ -80,7 +92,5 @@ IN: smtp.tests
             } >>to
             "Doug <erg@factorcode.org>" >>from
         send-email
-    ] with-scope
+    ] with-secure-context
 ] unit-test
-
-[ ] [ yield ] unit-test
index 9dc03dfac2a8ae7314a121a3612672f1e79873e8..7f14945633b82f2b2201959ede17856d2086b209 100644 (file)
@@ -1,16 +1,31 @@
 ! Copyright (C) 2007, 2008 Elie CHAFTARI, Dirk Vleugels,
 ! Slava Pestov, Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays namespaces make io io.timeouts kernel logging
-io.sockets sequences combinators splitting assocs strings
-math.parser random system calendar io.encodings.ascii summary
-calendar.format accessors sets hashtables ;
+USING: arrays namespaces make io io.encodings.string
+io.encodings.utf8 io.timeouts io.sockets io.sockets.secure
+io.encodings.ascii kernel logging sequences combinators
+splitting assocs strings math.order math.parser random system
+calendar summary calendar.format accessors sets hashtables
+base64 debugger classes prettyprint ;
 IN: smtp
 
 SYMBOL: smtp-domain
-SYMBOL: smtp-server     "localhost" 25 <inet> smtp-server set-global
-SYMBOL: smtp-read-timeout    1 minutes smtp-read-timeout set-global
-SYMBOL: esmtp?           t esmtp? set-global
+
+SYMBOL: smtp-server
+"localhost" 25 <inet> smtp-server set-global
+
+SYMBOL: smtp-tls?
+
+SYMBOL: smtp-read-timeout
+1 minutes smtp-read-timeout set-global
+
+SINGLETON: no-auth
+
+TUPLE: plain-auth username password ;
+C: <plain-auth> plain-auth
+
+SYMBOL: smtp-auth
+no-auth smtp-auth set-global
 
 LOG: log-smtp-connection NOTICE ( addrspec -- )
 
@@ -31,15 +46,23 @@ TUPLE: email
     { subject string }
     { body string } ;
 
-: <email> ( -- email ) email new ;
+: <email> ( -- email ) email new ; inline
 
 <PRIVATE
+
 : crlf ( -- ) "\r\n" write ;
 
+: read-crlf ( -- bytes )
+    "\r" read-until
+    [ CHAR: \r assert= read1 CHAR: \n assert= ] when* ;
+
 : command ( string -- ) write crlf flush ;
 
-: helo ( -- )
-    esmtp? get "EHLO " "HELO " ? host-name append command ;
+\ command DEBUG add-input-logging
+
+: helo ( -- ) "EHLO " host-name append command ;
+
+: start-tls ( -- ) "STARTTLS" command ;
 
 ERROR: bad-email-address email ;
 
@@ -60,8 +83,7 @@ ERROR: bad-email-address email ;
 ERROR: message-contains-dot message ;
 
 M: message-contains-dot summary ( obj -- string )
-    drop
-    "Message cannot contain . on a line by itself" ;
+    drop "Message cannot contain . on a line by itself" ;
 
 : validate-message ( msg -- msg' )
     "." over member?
@@ -78,7 +100,30 @@ M: message-contains-dot summary ( obj -- string )
 
 LOG: smtp-response DEBUG
 
-ERROR: smtp-error message ;
+: multiline? ( response -- boolean )
+    3 swap ?nth CHAR: - = ;
+
+: (receive-response) ( -- )
+    read-crlf
+    [ , ]
+    [ smtp-response ]
+    [ multiline? [ (receive-response) ] when ]
+    tri ;
+
+TUPLE: response code messages ;
+
+: <response> ( lines -- response )
+    [ first 3 head string>number ] keep response boa ;
+
+: receive-response ( -- response )
+    [ (receive-response) ] { } make <response> ;
+
+ERROR: smtp-error response ;
+
+M: smtp-error error.
+    "SMTP error (" write dup class pprint ")" print
+    response>> messages>> [ print ] each ;
+
 ERROR: smtp-server-busy < smtp-error ;
 ERROR: smtp-syntax-error < smtp-error ;
 ERROR: smtp-command-not-implemented < smtp-error ;
@@ -90,42 +135,35 @@ ERROR: smtp-bad-mailbox-name < smtp-error ;
 ERROR: smtp-transaction-failed < smtp-error ;
 
 : check-response ( response -- )
-    dup smtp-response
-    {
-        { [ dup "bye" head? ] [ drop ] }
-        { [ dup "220" head? ] [ drop ] }
-        { [ dup "235" swap subseq? ] [ drop ] }
-        { [ dup "250" head? ] [ drop ] }
-        { [ dup "221" head? ] [ drop ] }
-        { [ dup "354" head? ] [ drop ] }
-        { [ dup "4" head? ] [ smtp-server-busy ] }
-        { [ dup "500" head? ] [ smtp-syntax-error ] }
-        { [ dup "501" head? ] [ smtp-command-not-implemented ] }
-        { [ dup "50" head? ] [ smtp-syntax-error ] }
-        { [ dup "53" head? ] [ smtp-bad-authentication ] }
-        { [ dup "550" head? ] [ smtp-mailbox-unavailable ] }
-        { [ dup "551" head? ] [ smtp-user-not-local ] }
-        { [ dup "552" head? ] [ smtp-exceeded-storage-allocation ] }
-        { [ dup "553" head? ] [ smtp-bad-mailbox-name ] }
-        { [ dup "554" head? ] [ smtp-transaction-failed ] }
-        [ smtp-error ]
+    dup code>> {
+        { [ dup { 220 235 250 221 354 } member? ] [ 2drop ] }
+        { [ dup 400 499 between? ] [ drop smtp-server-busy ] }
+        { [ dup 500 = ] [ drop smtp-syntax-error ] }
+        { [ dup 501 = ] [ drop smtp-command-not-implemented ] }
+        { [ dup 500 509 between? ] [ drop smtp-syntax-error ] }
+        { [ dup 530 539 between? ] [ drop smtp-bad-authentication ] }
+        { [ dup 550 = ] [ drop smtp-mailbox-unavailable ] }
+        { [ dup 551 = ] [ drop smtp-user-not-local ] }
+        { [ dup 552 = ] [ drop smtp-exceeded-storage-allocation ] }
+        { [ dup 553 = ] [ drop smtp-bad-mailbox-name ] }
+        { [ dup 554 = ] [ drop smtp-transaction-failed ] }
+        [ drop smtp-error ]
     } cond ;
 
-: multiline? ( response -- boolean )
-    3 swap ?nth CHAR: - = ;
+: get-ok ( -- ) receive-response check-response ;
 
-: process-multiline ( multiline -- response )
-    >r readln r> 2dup " " append head? [
-        drop dup smtp-response
-    ] [
-        swap check-response process-multiline
-    ] if ;
+GENERIC: send-auth ( auth -- )
 
-: receive-response ( -- response )
-    readln
-    dup multiline? [ 3 head process-multiline ] when ;
+M: no-auth send-auth drop ;
 
-: get-ok ( -- ) receive-response check-response ;
+: plain-auth-string ( username password -- string )
+    [ "\0" prepend ] bi@ append utf8 encode >base64 ;
+
+M: plain-auth send-auth
+    [ username>> ] [ password>> ] bi plain-auth-string
+    "AUTH PLAIN " prepend command get-ok ;
+
+: auth ( -- ) smtp-auth get send-auth ;
 
 ERROR: invalid-header-string string ;
 
@@ -169,7 +207,10 @@ ERROR: invalid-header-string string ;
 
 : (send-email) ( headers email -- )
     [
+        get-ok
         helo get-ok
+        smtp-tls? get [ start-tls get-ok send-secure-handshake ] when
+        auth
         dup from>> extract-email mail-from get-ok
         dup to>> [ extract-email rcpt-to get-ok ] each
         dup cc>> [ extract-email rcpt-to get-ok ] each
@@ -180,6 +221,7 @@ ERROR: invalid-header-string string ;
         body>> send-body get-ok
         quit get-ok
     ] with-smtp-connection ;
+
 PRIVATE>
 
 : send-email ( email -- )
index 94e59950f74f20d5778171175716e93b9b582aca..8bb19b82f766d15888be55619496e74df6e12cd5 100644 (file)
@@ -4,7 +4,7 @@ USING: fry arrays generic io io.streams.string kernel math
 namespaces parser prettyprint sequences strings vectors words
 quotations effects classes continuations debugger assocs
 combinators compiler.errors accessors math.order definitions
-sets generic.standard.engines.tuple stack-checker.state
+sets generic.standard.engines.tuple hints stack-checker.state
 stack-checker.visitor stack-checker.errors
 stack-checker.values stack-checker.recursive-state ;
 IN: stack-checker.backend
@@ -125,7 +125,7 @@ M: object apply-object push-literal ;
     ] 2bi ; inline
 
 : infer-word-def ( word -- )
-    [ def>> ] [ add-recursive-state ] bi infer-quot ;
+    [ specialized-def ] [ add-recursive-state ] bi infer-quot ;
 
 : check->r ( -- )
     meta-r get empty? terminated? get or
index b6a988652b8415a648b5e27f3d4ae02f7dae7277..df0145b73e27695e5ead14c835693eda3d4aff7f 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: fry namespaces assocs kernel sequences words accessors
 definitions math math.order effects classes arrays combinators
-vectors arrays
+vectors arrays hints
 stack-checker.state
 stack-checker.errors
 stack-checker.values
@@ -17,7 +17,7 @@ IN: stack-checker.inlining
 ! having to handle recursive inline words.
 
 : infer-inline-word-def ( word label -- )
-    [ drop def>> ] [ add-inline-word ] 2bi infer-quot ;
+    [ drop specialized-def ] [ add-inline-word ] 2bi infer-quot ;
 
 TUPLE: inline-recursive < identity-tuple
 id
index 00cee32ddb18b3a65aedb69c4191f7372a97bc94..53f147ccce1b93a3413113b56df912998eab5f9d 100755 (executable)
@@ -23,10 +23,8 @@ IN: tools.deploy.shaker
 
 : strip-init-hooks ( -- )
     "Stripping startup hooks" show
-    "cpu.x86" init-hooks get delete-at
-    "command-line" init-hooks get delete-at
-    "libc" init-hooks get delete-at
-    "system" init-hooks get delete-at
+    { "cpu.x86" "command-line" "libc" "system" "environment" }
+    [ init-hooks get delete-at ] each
     deploy-threads? get [
         "threads" init-hooks get delete-at
     ] unless
index d860bd7f84fd090351c1572b4a75b8922717245d..e63da3512a42249e591973f6c0d42a45ad802b54 100644 (file)
@@ -1 +1 @@
-Prints formatted hex dump of an arbitrary sequence
+Prints the formatted hex dump of a byte-array
index ed2e486ecccc86282d20b4d8ed3f5f73bb102f14..416eec91d2b164df9555f10bdba54745e868a1e1 100644 (file)
@@ -54,7 +54,6 @@ TR: convert-separators "/\\" ".." ;
     [ monitor-thread ] "Vocabulary monitor" spawn drop ;\r
 \r
 [\r
-    "-no-monitors" cli-args member? [\r
-        start-monitor-thread\r
-    ] unless\r
+    "-no-monitors" (command-line) member?\r
+    [ start-monitor-thread ] unless\r
 ] "tools.vocabs.monitor" add-init-hook\r
index 5d3b8db19df8076733c71d6a32095721efae36dc..a9b3b03b75d7314a8bde2ef5f2ba2761f716cb15 100644 (file)
@@ -33,16 +33,13 @@ M: pasteboard set-clipboard-contents
     <clipboard> selection set-global ;
 
 : world>NSRect ( world -- NSRect )
-    dup window-loc>> first2 rot rect-dim first2 <NSRect> ;
+    [ window-loc>> ] [ dim>> ] bi [ first2 ] bi@ <NSRect> ;
 
 : gadget-window ( world -- )
-    [
-        dup <FactorView>
-        dup rot world>NSRect <ViewWindow>
-        dup install-window-delegate
-        over -> release
-        <handle>
-    ] keep (>>handle) ;
+    dup <FactorView>
+    2dup swap world>NSRect <ViewWindow>
+    [ [ -> release ] [ install-window-delegate ] bi* ] [ <handle> ] 2bi
+    >>handle drop ;
 
 M: cocoa-ui-backend set-title ( string world -- )
     handle>> window>> swap <NSString> -> setTitle: ;
diff --git a/basis/ui/cocoa/views/views-tests.factor b/basis/ui/cocoa/views/views-tests.factor
new file mode 100644 (file)
index 0000000..fc64534
--- /dev/null
@@ -0,0 +1,15 @@
+IN: ui.cocoa.views.tests
+USING: ui.cocoa.views tools.test kernel math.geometry.rect
+namespaces ;
+
+[ t ] [
+    T{ rect
+        { loc { 0 0 } }
+        { dim { 1000 1000 } }
+    } "world" set
+
+    T{ rect
+        { loc { 1.5 2.25 } }
+        { dim { 13.0 14.0 } }
+    } dup "world" get rect>NSRect "world" get NSRect>rect =
+] unit-test
index 1e35fcf4b2fd72d901298838bb9eb2cdaf632b47..128fdceeb4f02065020c39f4f88741effc056470 100644 (file)
@@ -77,18 +77,22 @@ IN: ui.cocoa.views
     dup event-modifiers swap button ;
 
 : send-button-down$ ( view event -- )
-    [ mouse-event>gesture <button-down> ]
-    [ mouse-location rot window send-button-down ] 2bi ;
+    [ nip mouse-event>gesture <button-down> ]
+    [ mouse-location ]
+    [ drop window ]
+    2tri send-button-down ;
 
 : send-button-up$ ( view event -- )
-    [ mouse-event>gesture <button-up> ] 2keep
-    mouse-location rot window send-button-up ;
+    [ nip mouse-event>gesture <button-up> ]
+    [ mouse-location ]
+    [ drop window ]
+    2tri send-button-up ;
 
 : send-wheel$ ( view event -- )
-    [
-        dup -> deltaX sgn neg over -> deltaY sgn neg 2array -rot
-        mouse-location
-    ] [ drop window ] 2bi send-wheel ;
+    [ nip [ -> deltaX ] [ -> deltaY ] bi [ sgn neg ] bi@ 2array ]
+    [ mouse-location ]
+    [ drop window ]
+    2tri send-wheel ;
 
 : send-action$ ( view event gesture -- junk )
     [ drop window ] dip send-action f ;
@@ -103,21 +107,18 @@ IN: ui.cocoa.views
     [ CF>string NSStringPboardType = ] [ t ] if* ;
 
 : valid-service? ( gadget send-type return-type -- ? )
-    over string-or-nil? over string-or-nil? and [
-        drop [ gadget-selection? ] [ drop t ] if
-    ] [
-        3drop f
-    ] if ;
+    over string-or-nil? over string-or-nil? and
+    [ drop [ gadget-selection? ] [ drop t ] if ] [ 3drop f ] if ;
 
 : NSRect>rect ( NSRect world -- rect )
-    [ dup NSRect-x over NSRect-y ] dip
-    rect-dim second swap - 2array
-    over NSRect-w rot NSRect-h 2array
-    <rect> ;
+    [ [ [ NSRect-x ] [ NSRect-y ] bi ] [ dim>> second ] bi* swap - 2array ]
+    [ drop [ NSRect-w ] [ NSRect-h ] bi 2array ]
+    2bi <rect> ;
 
 : rect>NSRect ( rect world -- NSRect )
-    over rect-loc first2 rot rect-dim second swap -
-    rot rect-dim first2 <NSRect> ;
+    [ [ rect-loc first2 ] [ dim>> second ] bi* swap - ]
+    [ drop rect-dim first2 ]
+    2bi <NSRect> ;
 
 CLASS: {
     { +superclass+ "NSOpenGLView" }
@@ -342,7 +343,7 @@ CLASS: {
 
 { "initWithFrame:pixelFormat:" "id" { "id" "SEL" "NSRect" "id" }
     [
-        rot drop
+        [ drop ] 2dip
         SUPER-> initWithFrame:pixelFormat:
         dup dup add-resize-observer
     ]
@@ -351,9 +352,10 @@ CLASS: {
 { "dealloc" "void" { "id" "SEL" }
     [
         drop
-        dup unregister-window
-        dup remove-observer
-        SUPER-> dealloc
+        [ unregister-window ]
+        [ remove-observer ]
+        [ SUPER-> dealloc ]
+        tri
     ]
 } ;
 
index 41d000af263168b3055751a3b58de80c7476d35d..a4ef77e661bb1463a9ca586ab283c24de5e6bc6b 100644 (file)
@@ -97,14 +97,15 @@ SYMBOL: dpi
     dup handle>> init-descent
     dup [ ascent>> ] [ descent>> ] bi - ft-ceil >>height ; inline
 
-: set-char-size ( handle size -- )
-    0 swap 6 shift dpi get-global dup FT_Set_Char_Size freetype-error ;
+: set-char-size ( open-font size -- open-font )
+    [ dup handle>> 0 ] dip
+    6 shift dpi get-global dup FT_Set_Char_Size freetype-error ;
 
-: <font> ( handle -- font )
+: <font> ( font -- open-font )
     font new
         H{ } clone >>widths
         over first2 open-face >>handle
-        dup handle>> rot third set-char-size
+        swap third set-char-size
         init-font ;
 
 M: freetype-renderer open-font ( font -- open-font )
@@ -120,7 +121,7 @@ M: freetype-renderer open-font ( font -- open-font )
     ] cache nip ;
 
 M: freetype-renderer string-width ( open-font string -- w )
-    0 -rot [ char-width + ] with each ;
+    [ 0 ] 2dip [ char-width + ] with each ;
 
 M: freetype-renderer string-height ( open-font string -- h )
     drop height>> ;
@@ -165,8 +166,9 @@ M: freetype-renderer string-height ( open-font string -- h )
     ] with-malloc ;
 
 : glyph-texture-loc ( glyph font -- loc )
-    over glyph-hori-bearing-x ft-floor -rot
-    ascent>> swap glyph-hori-bearing-y - ft-floor 2array ;
+    [ drop glyph-hori-bearing-x ft-floor ]
+    [ ascent>> swap glyph-hori-bearing-y - ft-floor ]
+    2bi 2array ;
 
 : glyph-texture-size ( glyph -- dim )
     [ glyph-bitmap-width next-power-of-2 ]
index 4a428404c1bb65e1fe5893ac16ee578dd275778c..086ef2ca81939dbf8434e6a7064e8d1c262fb471 100644 (file)
@@ -71,3 +71,5 @@ ARTICLE: "ui.gadgets.buttons" "Button gadgets"
 { $subsection button-paint }
 "Button constructors take " { $emphasis "label specifiers" } " as input. A label specifier is either a string, an array of strings, a gadget or " { $link f } "."
 { $see-also <command-button> "ui-commands" } ;
+
+ABOUT: "ui.gadgets.buttons"
index 0cf60ff5e8848a9715d9af72bb765daf69363a09..d749b8905c02ede603fb5eb5f6c5d0ddd47e6614 100644 (file)
@@ -20,22 +20,12 @@ HELP: <editor>
 { $values { "editor" "a new " { $link editor } } }
 { $description "Creates a new " { $link editor } " with an empty document." } ;
 
-! 'editor-caret' is now an old accessor, but it's documented as a word here. Maybe move this description somewhere else.
-
-! HELP: editor-caret ( editor -- caret )
-! { $values { "editor" editor } { "caret" model } }
-! { $description "Outputs a " { $link model } " holding the current caret location." } ;
-
 { editor-caret* editor-mark* } related-words
 
 HELP: editor-caret*
 { $values { "editor" editor } { "loc" "a pair of integers" } }
 { $description "Outputs the current caret location as a line/column number pair." } ;
 
-! HELP: editor-mark ( editor -- mark )
-! { $values { "editor" editor } { "mark" model } }
-! { $description "Outputs a " { $link model } " holding the current mark location." } ;
-
 HELP: editor-mark*
 { $values { "editor" editor } { "loc" "a pair of integers" } }
 { $description "Outputs the current mark location as a line/column number pair." } ;
old mode 100644 (file)
new mode 100755 (executable)
index 59461c1..e262ac7
@@ -1,12 +1,13 @@
 ! Copyright (C) 2006, 2008 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays documents io kernel math models
+USING: accessors arrays documents kernel math models
 namespaces locals fry make opengl opengl.gl sequences strings
 io.styles math.vectors sorting colors combinators assocs
 math.order fry calendar alarms ui.clipboards ui.commands
 ui.gadgets ui.gadgets.borders ui.gadgets.buttons
 ui.gadgets.labels ui.gadgets.scrollers ui.gadgets.theme
-ui.gadgets.wrappers ui.render ui.gestures math.geometry.rect ;
+ui.gadgets.menus ui.gadgets.wrappers ui.render ui.gestures
+math.geometry.rect ;
 IN: ui.gadgets.editors
 
 TUPLE: editor < gadget
@@ -52,19 +53,21 @@ SYMBOL: blink-interval
 
 750 milliseconds blink-interval set-global
 
-: start-blinking ( editor -- )
-    t >>blink
-    dup '[ _ blink-caret ] blink-interval get every >>blink-alarm drop ;
-
 : stop-blinking ( editor -- )
     [ [ cancel-alarm ] when* f ] change-blink-alarm drop ;
 
+: start-blinking ( editor -- )
+    [ stop-blinking ] [
+        t >>blink
+        dup '[ _ blink-caret ] blink-interval get every
+        >>blink-alarm drop
+    ] bi ;
+
 : restart-blinking ( editor -- )
     dup focused?>> [
-        [ stop-blinking ]
         [ start-blinking ]
         [ relayout-1 ]
-        tri
+        bi
     ] [ drop ] if ;
 
 M: editor graft*
@@ -135,11 +138,8 @@ M: editor ungraft*
     f >>focused?
     relayout-1 ;
 
-: (offset>x) ( font col# str -- x )
-    swap head-slice string-width ;
-
 : offset>x ( col# line# editor -- x )
-    [ editor-line ] keep editor-font* -rot (offset>x) ;
+    [ editor-line ] keep editor-font* spin head-slice string-width ;
 
 : loc>x ( loc editor -- x ) [ first2 swap ] dip offset>x ;
 
@@ -218,7 +218,7 @@ M: editor ungraft*
     ] with-editor-translation ;
 
 : selection-start/end ( editor -- start end )
-    dup editor-mark* swap editor-caret* sort-pair ;
+    [ editor-mark* ] [ editor-caret* ] bi sort-pair ;
 
 : (draw-selection) ( x1 x2 -- )
     over -
@@ -227,9 +227,8 @@ M: editor ungraft*
     swap [ gl-fill-rect ] with-translation ;
 
 : draw-selected-line ( start end n -- )
-    [ start/end-on-line ] keep tuck
-    [ editor get offset>x ] 2dip
-    editor get offset>x
+    [ start/end-on-line ] keep
+    tuck [ editor get offset>x ] 2bi@
     (draw-selection) ;
 
 : draw-selection ( -- )
@@ -237,9 +236,9 @@ M: editor ungraft*
     editor get selection-start/end
     over first [
         2dup [
-            [ 2dup ] dip draw-selected-line
+            draw-selected-line
             1 translate-lines
-        ] each-line 2drop
+        ] with with each-line
     ] with-editor-translation ;
 
 M: editor draw-gadget*
@@ -513,6 +512,13 @@ editor "selection" f {
     { T{ key-down f { S+ C+ } "END" } select-end-of-document }
 } define-command-map
 
+: editor-menu ( editor -- )
+    { cut com-copy paste } show-commands-menu ;
+
+editor "misc" f {
+    { T{ button-down f f 3 } editor-menu }
+} define-command-map
+
 ! Multi-line editors
 TUPLE: multiline-editor < editor ;
 
index c3a72169100cb9582ad4bfced666bc2784adc96c..01d695c28194fd88855959a6cd380f575b880dea 100644 (file)
@@ -152,13 +152,6 @@ M: mock-gadget ungraft*
     { { f f } { f t } { t f } { t t } } [ notify-combo ] assoc-each
 ] with-string-writer print
 
-[ { { 10 30 } } ] [
-    <gadget> { 0 1 } >>orientation
-    { { 10 20 } }
-    { { 100 30 } }
-    orient
-] unit-test
-
 \ <gadget> must-infer
 \ unparent must-infer
 \ add-gadget must-infer
index 51c8f07225a43bf6b5bf285b26000f342f5115a4..baf025d11625f90d267d9ef8dacd857d584b4b04 100644 (file)
@@ -86,15 +86,12 @@ M: gadget children-on nip children>> ;
 
 : pick-up ( point gadget -- child/f )
     2dup (pick-up) dup
-    [ nip [ rect-loc v- ] keep pick-up ] [ rot 2drop ] if ;
+    [ nip [ rect-loc v- ] keep pick-up ] [ drop nip ] if ;
 
 : max-dim ( dims -- dim ) { 0 0 } [ vmax ] reduce ;
 
 : dim-sum ( seq -- dim ) { 0 0 } [ v+ ] reduce ;
 
-: orient ( gadget seq1 seq2 -- seq )
-    rot orientation>> '[ _ set-axis ] 2map ;
-
 : each-child ( gadget quot -- )
     [ children>> ] dip each ; inline
 
index 386457551f6c986c6f1da0f3c5c466f4750af160..eab8833120b21d23a552719742dea195456d8362 100644 (file)
@@ -18,14 +18,14 @@ grid
 : <grid> ( children -- grid )
     grid new-grid ;
 
-: grid-child ( grid i j -- gadget ) rot grid>> nth nth ;
+:: grid-child ( grid i j -- gadget ) i j grid grid>> nth nth ;
 
 :: grid-add ( grid child i j -- grid )
     grid i j grid-child unparent
     grid child add-gadget
     child i j grid grid>> nth set-nth ;
 
-: grid-remove ( grid i j -- grid ) <gadget> -rot grid-add ;
+: grid-remove ( grid i j -- grid ) [ <gadget> ] 2dip grid-add ;
 
 : pref-dim-grid ( grid -- dims )
     grid>> [ [ pref-dim ] map ] map ;
index e4343e6280f1c7b32f949e5f46bc4794263c169a..108c5ae461d1b3a25c38647383f02f96eb5fa4ed 100644 (file)
@@ -48,9 +48,10 @@ TUPLE: closable-gadget < frame content ;
     [ closable-gadget? ] find-parent ;
 
 : <closable-gadget> ( gadget title quot -- gadget )
-    closable-gadget new-frame
-        -rot <title-bar> @top grid-add
-        swap >>content
-        dup content>> @center grid-add ;
+    [
+        [ closable-gadget new-frame ] dip
+        [ >>content ] [ @center grid-add ] bi
+    ] 2dip
+    <title-bar> @top grid-add ;
     
 M: closable-gadget focusable-child* content>> ;
index 303eb0a13ea60b77dbdad49fc1bb86e4adfa9b5a..d7297217ed930cd56441d3d404da9195a6fa32c2 100644 (file)
@@ -3,9 +3,22 @@ kernel ;
 IN: ui.gadgets.menus
 
 HELP: <commands-menu>
-{ $values { "hook" { $quotation "( button -- )" } } { "target" object } { "commands" "a sequence of commands" } { "gadget" "a new " { $link gadget } } }
+{ $values { "target" object } { "commands" "a sequence of commands" } { "hook" { $quotation "( button -- )" } }  { "menu" "a new " { $link gadget } } }
 { $description "Creates a popup menu of commands which are to be invoked on " { $snippet "target" } ". The " { $snippet "hook" } " quotation is run before a command is invoked." } ;
 
 HELP: show-menu
-{ $values { "gadget" gadget } { "owner" gadget } }
-{ $description "Displays a popup menu in the " { $link world } " containing " { $snippet "owner" } " at the current mouse location." } ;
+{ $values { "owner" gadget } { "menu" gadget } }
+{ $description "Displays a popup menu in the " { $link world } " containing " { $snippet "owner" } " at the current mouse location. The popup menu can be any gadget." } ;
+
+HELP: show-commands-menu
+{ $values { "target" gadget } { "commands" "a sequence of commands" } }
+{ $description "Displays a popup menu with the given commands. The commands act on the target gadget. This is just a convenience word that combines " { $link <commands-menu> } " with " { $link show-menu } "." }
+{ $notes "Useful for right-click context menus." } ;
+
+ARTICLE: "ui.gadgets.menus" "Popup menus"
+"The " { $vocab-link "ui.gadgets.menus" } " vocabulary implements popup menus."
+{ $subsection <commands-menu> }
+{ $subsection show-menu }
+{ $subsection show-commands-menu } ;
+
+ABOUT: "ui.gadgets.menus"
index cbcfdb14d890e8d1e20384bf11f8d31d15327595..2aef0b8417ce14c7d6259c452dd59f493cda5be0 100644 (file)
@@ -1,10 +1,10 @@
-! Copyright (C) 2005, 2007 Slava Pestov.
+! Copyright (C) 2005, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays ui.commands ui.gadgets ui.gadgets.buttons
-ui.gadgets.worlds ui.gestures generic hashtables kernel math
-models namespaces opengl sequences math.vectors
-ui.gadgets.theme ui.gadgets.packs ui.gadgets.borders colors
-math.geometry.rect ;
+USING: locals accessors arrays ui.commands ui.gadgets
+ui.gadgets.buttons ui.gadgets.worlds ui.gestures generic
+hashtables kernel math models namespaces opengl sequences
+math.vectors ui.gadgets.theme ui.gadgets.packs
+ui.gadgets.borders colors math.geometry.rect ;
 IN: ui.gadgets.menus
 
 : menu-loc ( world menu -- loc )
@@ -12,9 +12,9 @@ IN: ui.gadgets.menus
 
 TUPLE: menu-glass < gadget ;
 
-: <menu-glass> ( menu world -- glass )
+: <menu-glass> ( world menu -- glass )
+    tuck menu-loc >>loc
     menu-glass new-gadget
-    [ over menu-loc >>loc ] dip
     swap add-gadget ;
 
 M: menu-glass layout* gadget-child prefer ;
@@ -22,30 +22,35 @@ M: menu-glass layout* gadget-child prefer ;
 : hide-glass ( world -- )
     [ [ unparent ] when* f ] change-glass drop ;
 
-: show-glass ( gadget world -- )
-    dup hide-glass
-    swap [ hand-clicked set-global ] [ >>glass ] bi
-    dup glass>> add-gadget drop ;
+: show-glass ( world gadget -- )
+    [ [ hide-glass ] [ hand-clicked set-global ] bi* ]
+    [ add-gadget drop ]
+    [ >>glass drop ]
+    2tri ;
 
-: show-menu ( gadget owner -- )
-    find-world [ <menu-glass> ] keep show-glass ;
+: show-menu ( owner menu -- )
+    [ find-world dup ] dip <menu-glass> show-glass ;
 
 \ menu-glass H{
     { T{ button-down } [ find-world [ hide-glass ] when* ] }
     { T{ drag } [ update-clicked drop ] }
 } set-gestures
 
-: <menu-item> ( hook target command -- button )
-    dup command-name -rot command-button-quot
-    swapd
-    [ hand-clicked get find-world hide-glass ]
-    3append <roll-button> ;
+:: <menu-item> ( target hook command -- button )
+    command command-name [
+        hook call
+        target command command-button-quot call
+        hand-clicked get find-world hide-glass
+    ] <roll-button> ;
 
 : menu-theme ( gadget -- gadget )
     light-gray solid-interior
     faint-boundary ;
 
-: <commands-menu> ( hook target commands -- gadget )
+: <commands-menu> ( target hook commands -- menu )
     [ <filled-pile> ] 3dip
-        [ <menu-item> add-gadget ] with with each
+    [ <menu-item> add-gadget ] with with each
     5 <border> menu-theme ;
+
+: show-commands-menu ( target commands -- )
+    [ dup [ ] ] dip <commands-menu> show-menu ;
index 065267d7be825553cb8e8804b19e6d375a38dc9e..8b52a2ad2fbee5fb31be319c5d41c8dfb8f7880a 100644 (file)
@@ -1,6 +1,7 @@
 IN: ui.gadgets.packs.tests
 USING: ui.gadgets.packs ui.gadgets.labels ui.gadgets ui.render
-kernel namespaces tools.test math.parser sequences math.geometry.rect ;
+kernel namespaces tools.test math.parser sequences math.geometry.rect
+accessors ;
 
 [ t ] [
     { 0 0 } { 100 100 } <rect> clip set
@@ -11,3 +12,10 @@ kernel namespaces tools.test math.parser sequences math.geometry.rect ;
 
     visible-children [ label? ] all?
 ] unit-test
+
+[ { { 10 30 } } ] [
+    { { 10 20 } }
+    { { 100 30 } }
+    <gadget> { 0 1 } >>orientation
+    orient
+] unit-test
index 5965e8b5682af9ebf78f6d5d16ffd5d5c8a5198f..86dc6ea354f92d384004377abb41fc4d42c5fbb1 100644 (file)
@@ -1,28 +1,30 @@
 ! Copyright (C) 2005, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: sequences ui.gadgets kernel math math.functions
-math.vectors namespaces math.order accessors math.geometry.rect ;
+math.vectors math.order math.geometry.rect namespaces accessors
+fry ;
 IN: ui.gadgets.packs
 
 TUPLE: pack < gadget
-    { align initial: 0 }
-    { fill  initial: 0 }
-    { gap   initial: { 0 0 } } ;
+{ align initial: 0 } { fill initial: 0 } { gap initial: { 0 0 } } ;
 
 : packed-dim-2 ( gadget sizes -- list )
-    [ over rect-dim over v- rot fill>> v*n v+ ] with map ;
+    swap [ dim>> ] [ fill>> ] bi '[ _ over v- _ v*n v+ ] map ;
+
+: orient ( seq1 seq2 gadget -- seq )
+    orientation>> '[ _ set-axis ] 2map ;
 
 : packed-dims ( gadget sizes -- seq )
-    2dup packed-dim-2 swap orient ;
+    [ packed-dim-2 ] [ nip ] [ drop ] 2tri orient ;
 
 : gap-locs ( gap sizes -- seq )
     { 0 0 } [ v+ over v+ ] accumulate 2nip ;
 
 : aligned-locs ( gadget sizes -- seq )
-    [ [ dup align>> swap rect-dim ] dip v- n*v ] with map ;
+    [ [ [ align>> ] [ dim>> ] bi ] dip v- n*v ] with map ;
 
 : packed-locs ( gadget sizes -- seq )
-    over gap>> over gap-locs [ dupd aligned-locs ] dip orient ;
+    [ aligned-locs ] [ [ gap>> ] dip gap-locs ] [ drop ] 2tri orient ;
 
 : round-dims ( seq -- newseq )
     { 0 0 } swap
@@ -45,12 +47,14 @@ TUPLE: pack < gadget
 
 : <shelf> ( -- pack ) { 1 0 } <pack> ;
 
-: gap-dims ( gap sizes -- seeq )
-    [ dim-sum ] keep length 1 [-] rot n*v v+ ;
+: gap-dims ( sizes gadget -- seeq )
+    [ [ dim-sum ] [ length 1 [-] ] bi ] [ gap>> ] bi* n*v v+ ;
 
 : pack-pref-dim ( gadget sizes -- dim )
-    over gap>> over gap-dims [ max-dim ] dip
-    rot orientation>> set-axis ;
+    [ nip max-dim ]
+    [ swap gap-dims ]
+    [ drop orientation>> ]
+    2tri set-axis ;
 
 M: pack pref-dim*
     dup children>> pref-dims pack-pref-dim ;
index 9a30cee77713f27588df6958e2bc9fc4b601e376..79a47380b6ccaf0e611f4802a434677523c61cf7 100644 (file)
@@ -3,10 +3,10 @@
 USING: arrays ui.gadgets ui.gadgets.borders ui.gadgets.buttons
 ui.gadgets.labels ui.gadgets.scrollers ui.gadgets.paragraphs
 ui.gadgets.incremental ui.gadgets.packs ui.gadgets.theme
-ui.clipboards ui.gestures ui.traverse ui.render hashtables io
-kernel namespaces sequences io.styles strings quotations math
-opengl combinators math.vectors sorting splitting
-io.streams.nested assocs ui.gadgets.presentations
+ui.gadgets.menus ui.clipboards ui.gestures ui.traverse ui.render
+hashtables io kernel namespaces sequences io.styles strings
+quotations math opengl combinators math.vectors sorting
+splitting io.streams.nested assocs ui.gadgets.presentations
 ui.gadgets.slots ui.gadgets.grids ui.gadgets.grid-lines
 classes.tuple models continuations destructors accessors
 math.geometry.rect fry ;
@@ -398,6 +398,8 @@ M: f sloppy-pick-up*
     dup request-focus
     com-copy-selection ;
 
+: pane-menu ( pane -- ) { com-copy } show-commands-menu ;
+
 pane H{
     { T{ button-down } [ begin-selection ] }
     { T{ button-down f { S+ } 1 } [ select-to-caret ] }
@@ -405,4 +407,5 @@ pane H{
     { T{ button-up } [ end-selection ] }
     { T{ drag } [ extend-selection ] }
     { T{ copy-action } [ com-copy ] }
+    { T{ button-down f f 3 } [ pane-menu ] }
 } set-gestures
index 216f21af27bbf4981aec5a4ba9ec57f7602e1aca..6e26a2989f0c7342ac0e6f268e6ce209d517d7bb 100644 (file)
@@ -1,7 +1,8 @@
-! Copyright (C) 2005, 2007 Slava Pestov
+! Copyright (C) 2005, 2008 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays ui.gadgets ui.gadgets.labels ui.render kernel math
-namespaces sequences math.order math.geometry.rect ;
+USING: accessors arrays ui.gadgets ui.gadgets.labels ui.render
+kernel math namespaces sequences math.order math.geometry.rect
+locals ;
 IN: ui.gadgets.paragraphs
 
 ! A word break gadget
@@ -46,12 +47,19 @@ SYMBOL: margin
     dup line-height [ max ] change
     y get + max-y [ max ] change ;
 
-: wrap-step ( quot child -- )
-    dup pref-dim [
-        over word-break-gadget? [
-            dup first overrun? [ wrap-line ] when
-        ] unless drop wrap-pos rot call
-    ] keep first2 advance-y advance-x ; inline
+:: wrap-step ( quot child -- )
+    child pref-dim
+    [
+        child
+        [
+            word-break-gadget?
+            [ drop ] [ first overrun? [ wrap-line ] when ] if
+        ]
+        [ wrap-pos quot call ] bi
+    ]
+    [ first advance-x ]
+    [ second advance-y ]
+    tri ; inline
 
 : wrap-dim ( -- dim ) max-x get max-y get 2array ;
 
index e39069ed7b105aba1de3fb1ea3ef0154b4686437..33ef3bbe3afbbc007feef35d98557987fdfe5a27 100644 (file)
@@ -36,12 +36,13 @@ M: presentation ungraft*
     call-next-method ;
 
 : <operations-menu> ( presentation -- menu )
-    dup dup hook>> curry
-    swap object>>
-    dup object-operations <commands-menu> ;
+    [ object>> ]
+    [ dup hook>> curry ]
+    [ object>> object-operations ]
+    tri <commands-menu> ;
 
 : operations-menu ( presentation -- )
-    dup <operations-menu> swap show-menu ;
+    dup <operations-menu> show-menu ;
 
 presentation H{
     { T{ button-down f f 3 } [ operations-menu ] }
index 968972a869293e49229332086b2c35bc8c663a4e..9e13e5ad7cb14378d932c9dcd7897ae60bf88952 100644 (file)
@@ -26,10 +26,11 @@ TUPLE: slider < frame elevator thumb saved line ;
 : slider-max*  ( gadget -- n ) model>> range-max-value*    ;
 
 : thumb-dim ( slider -- h )
-    dup slider-page over slider-max 1 max / 1 min
-    over elevator-length * min-thumb-dim max
-    over elevator>> rect-dim
-    rot orientation>> v. min ;
+    [
+        [ [ slider-page ] [ slider-max 1 max ] bi / 1 min ]
+        [ elevator-length ] bi * min-thumb-dim max
+    ]
+    [ [ elevator>> dim>> ] [ orientation>> ] bi v. ] bi min ;
 
 : slider-scale ( slider -- n )
     #! A scaling factor such that if x is a slider co-ordinate,
@@ -109,8 +110,8 @@ elevator H{
 : layout-thumb-dim ( slider -- )
     dup dup thumb-dim (layout-thumb)
     [
-        [ dup rect-dim ] dip
-        rot orientation>> set-axis [ ceiling ] map
+        [ [ rect-dim ] dip ] [ drop orientation>> ] 2bi set-axis
+        [ ceiling ] map
     ] dip (>>dim) ;
 
 : layout-thumb ( slider -- )
index 98c3258911a2e80d5f3d3a92b018c59c9b6ae50d..68a2a18210109adf47d1094c106f63a0188d4650 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2005, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays assocs continuations kernel math models
-namespaces opengl sequences io combinators math.vectors
+namespaces opengl sequences io combinators fry math.vectors
 ui.gadgets ui.gestures ui.render ui.backend ui.gadgets.tracks
 debugger math.geometry.rect ;
 IN: ui.gadgets.worlds
@@ -67,9 +67,7 @@ M: world children-on nip children>> ;
 : draw-world? ( world -- ? )
     #! We don't draw deactivated worlds, or those with 0 size.
     #! On Windows, the latter case results in GL errors.
-    dup active?>>
-    over handle>>
-    rot rect-dim [ 0 > ] all? and and ;
+    [ active?>> ] [ handle>> ] [ dim>> [ 0 > ] all? ] tri and and ;
 
 TUPLE: world-error error world ;
 
@@ -127,5 +125,4 @@ M: world handle-gesture ( gesture gadget -- ? )
     ] [ 2drop f ] if ;
 
 : close-global ( world global -- )
-    dup get-global find-world rot eq?
-    [ f swap set-global ] [ drop ] if ;
+    [ get-global find-world eq? ] keep '[ f _ set-global ] when ;
index ffb9795ef8584105ed313faa7de55ac8988df0f0..5faaa93292ed4a4a5b5e294fa23b4610509e0ee6 100644 (file)
@@ -205,7 +205,7 @@ SYMBOL: drag-timer
     dup hand-last-button get = ;
 
 : multi-click-position? ( -- ? )
-    hand-loc get hand-click-loc get v- norm-sq 100 <= ;
+    hand-loc get hand-click-loc get distance 10 <= ;
 
 : multi-click? ( button -- ? )
     {
index 660ae1f43da75d35ee24fa30a707a2abb5e2f5cb..bcfca946dd0ceb3cc3c2ad17d5037456107dcb35 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays definitions kernel ui.commands
 ui.gestures sequences strings math words generic namespaces make
-hashtables help.markup quotations assocs ;
+hashtables help.markup quotations assocs fry ;
 IN: ui.operations
 
 SYMBOL: +keyboard+
@@ -63,7 +63,7 @@ SYMBOL: operations
         t >>listener? ;
 
 : modify-operations ( operations hook translator -- operations )
-    rot [ modify-operation ] with with map ;
+    '[ [ _ _ ] dip modify-operation ] map ;
 
 : operations>commands ( object hook translator -- pairs )
     [ object-operations ] 2dip modify-operations
index e5b4bb8867cfc76c9734c0c69a5a936763e72f21..5cbac9798a054f096eb736b12d0eaa9619b9c38b 100755 (executable)
@@ -228,7 +228,7 @@ HOOK: free-fonts font-renderer ( world -- )
     dup string? [
         string-width
     ] [
-        0 -rot [ string-width max ] with each
+        [ 0 ] 2dip [ string-width max ] with each
     ] if ;
 
 : text-dim ( open-font text -- dim )
index 5a99d1174b00b0944d28098d4a1c07a1a4148584..127269b325ce8be2b73de65b1aae810d81d3bba0 100644 (file)
@@ -117,5 +117,7 @@ deploy-gadget "toolbar" f {
     dup com-revert ;
     
 : deploy-tool ( vocab -- )
-    vocab-name dup <deploy-gadget> 10 <border>
-    "Deploying \"" rot "\"" 3append open-window ;
+    vocab-name
+    [ <deploy-gadget> 10 <border> ]
+    [ "Deploying \"" swap "\"" 3append ] bi
+    open-window ;
index 0676619b07112f7715d5c1213db569c298969c83..51425b124d0afffb64ddc73cc9dfad41c15206f2 100644 (file)
@@ -81,14 +81,15 @@ M: interactor model-changed
 : interactor-continue ( obj interactor -- )
     mailbox>> mailbox-put ;
 
-: clear-input ( interactor -- ) model>> clear-doc ;
+: clear-input ( interactor -- )
+    #! The with-datastack is a kludge to make it infer. Stupid.
+    model>> 1array [ clear-doc ] with-datastack drop ;
 
 : interactor-finish ( interactor -- )
-    #! The spawn is a kludge to make it infer. Stupid.
     [ editor-string ] keep
     [ interactor-input. ] 2keep
     [ add-interactor-history ] keep
-    '[ _ clear-input ] "Clearing input" spawn drop ;
+    clear-input ;
 
 : interactor-eof ( interactor -- )
     dup interactor-busy? [
index 5135c3da6ec6dc1fa6ac64d12ffa2720b823bdcf..7a012aa3e001891530b7022b5ad4263443533c9f 100644 (file)
@@ -59,15 +59,15 @@ TUPLE: node value children ;
 DEFER: (gadget-subtree)
 
 : traverse-child ( frompath topath gadget -- )
-    [ -rot ] keep [
-        [ rest-slice ] 2dip traverse-step (gadget-subtree)
-    make-node ;
+    [ 2nip ] 3keep
+    [ [ rest-slice ] 2dip traverse-step (gadget-subtree) ]
+    make-node ;
 
 : (gadget-subtree) ( frompath topath gadget -- )
     {
         { [ dup not ] [ 3drop ] }
         { [ pick empty? pick empty? and ] [ 2nip , ] }
-        { [ pick empty? ] [ rot drop traverse-to-path ] }
+        { [ pick empty? ] [ traverse-to-path drop ] }
         { [ over empty? ] [ nip traverse-from-path ] }
         { [ pick first pick first = ] [ traverse-child ] }
         [ traverse-middle ]
index de2df4ee6eeeb68ec35ec8c61829ea8a5a7b262d..738d259cad5c0a3c15843887fab27eb3de9e7e2a 100644 (file)
@@ -95,6 +95,7 @@ ARTICLE: "gadgets" "Pre-made UI gadgets"
 { $subsection "ui.gadgets.sliders" }
 { $subsection "ui.gadgets.scrollers" }
 { $subsection "gadgets-editors" }
+{ $subsection "ui.gadgets.menus" }
 { $subsection "ui.gadgets.panes" }
 { $subsection "ui.gadgets.presentations" }
 { $subsection "ui.gadgets.lists" } ;
index 6e1ce8f77f57c172ff5f9a13f70f5cd1a33dd7a8..1481287e9599351dd14c4216de13a171a08d0eea 100755 (executable)
@@ -284,20 +284,18 @@ SYMBOL: nc-buttons
     message>button nc-buttons get
     swap [ push ] [ delete ] if ;
 
-: >lo-hi ( WORD -- array ) [ lo-word ] keep hi-word 2array ;
-: mouse-wheel ( wParam -- array ) >lo-hi [ sgn neg ] map ;
+: >lo-hi ( WORD -- array ) [ lo-word ] [ hi-word ] bi 2array ;
 
-: mouse-absolute>relative ( lparam handle -- array )
-    [ >lo-hi ] dip
-    "RECT" <c-object> [ GetWindowRect win32-error=0/f ] keep
-    get-RECT-top-left 2array v- ;
+: mouse-wheel ( wParam -- array ) >lo-hi [ sgn neg ] map ;
 
 : mouse-event>gesture ( uMsg -- button )
     key-modifiers swap message>button
     [ <button-down> ] [ <button-up> ] if ;
 
-: prepare-mouse ( hWnd uMsg wParam lParam -- button coordinate world )
-    [ drop mouse-event>gesture ] dip >lo-hi rot window ;
+:: prepare-mouse ( hWnd uMsg wParam lParam -- button coordinate world )
+    uMsg mouse-event>gesture
+    lParam >lo-hi
+    hWnd window ;
 
 : set-capture ( hwnd -- )
     mouse-captured get [
@@ -338,9 +336,7 @@ SYMBOL: nc-buttons
     >lo-hi swap window move-hand fire-motion ;
 
 :: handle-wm-mousewheel ( hWnd uMsg wParam lParam -- )
-    wParam mouse-wheel
-    lParam hWnd mouse-absolute>relative
-    hWnd window send-wheel ;
+    wParam mouse-wheel hand-loc get hWnd window send-wheel ;
 
 : handle-wm-cancelmode ( hWnd uMsg wParam lParam -- )
     #! message sent if windows needs application to stop dragging
@@ -435,7 +431,7 @@ M: windows-ui-backend do-events
     style 0 ex-style AdjustWindowRectEx win32-error=0/f ;
 
 : make-RECT ( world -- RECT )
-    dup window-loc>> dup rot rect-dim v+
+    [ window-loc>> dup ] [ rect-dim ] bi v+
     "RECT" <c-object>
     over first over set-RECT-right
     swap second over set-RECT-bottom
old mode 100644 (file)
new mode 100755 (executable)
index b9889c7..b65236d
@@ -95,8 +95,10 @@ M: world key-up-event
     [ key-up-event>gesture ] dip world-focus propagate-gesture ;
 
 : mouse-event>gesture ( event -- modifiers button loc )
-    dup event-modifiers over XButtonEvent-button
-    rot mouse-event-loc ;
+    [ event-modifiers ]
+    [ XButtonEvent-button ]
+    [ mouse-event-loc ]
+    tri ;
 
 M: world button-down-event
     [ mouse-event>gesture [ <button-down> ] dip ] dip
@@ -115,7 +117,7 @@ M: world button-up-event
     } at ;
 
 M: world wheel-event
-    [ dup mouse-event>scroll-direction swap mouse-event-loc ] dip
+    [ [ mouse-event>scroll-direction ] [ mouse-event-loc ] bi ] dip
     send-wheel ;
 
 M: world enter-event motion-event ;
@@ -123,7 +125,7 @@ M: world enter-event motion-event ;
 M: world leave-event 2drop forget-rollover ;
 
 M: world motion-event
-    [ dup XMotionEvent-x swap XMotionEvent-y 2array ] dip
+    [ [ XMotionEvent-x ] [ XMotionEvent-y ] bi 2array ] dip
     move-hand fire-motion ;
 
 M: world focus-in-event
@@ -144,10 +146,10 @@ M: world selection-notify-event
 
 : clipboard-for-atom ( atom -- clipboard )
     {
-        { [ dup XA_PRIMARY = ] [ drop selection get ] }
-        { [ dup XA_CLIPBOARD = ] [ drop clipboard get ] }
+        { XA_PRIMARY [ selection get ] }
+        { XA_CLIPBOARD [ clipboard get ] }
         [ drop <clipboard> ]
-    } cond ;
+    } case ;
 
 : encode-clipboard ( string type -- bytes )
     XSelectionRequestEvent-target
@@ -222,8 +224,8 @@ M: x-clipboard paste-clipboard
     utf8 encode dup length XChangeProperty drop ;
 
 M: x11-ui-backend set-title ( string world -- )
-    handle>> window>> swap dpy get -rot
-    3dup set-title-old set-title-new ;
+    handle>> window>> swap
+    [ dpy get ] 2dip [ set-title-old ] [ set-title-new ] 3bi ;
 
 M: x11-ui-backend set-fullscreen* ( ? world -- )
     handle>> window>> "XClientMessageEvent" <c-object>
index 030f0977e23ba510512015e5025239b7ad6a6926..175425f948f7298c34eec524a4ad7fa603300bd4 100644 (file)
@@ -33,7 +33,7 @@ FUNCTION: int execve ( char* path, char** argv, char** envp ) ;
     [ first ] [ ] bi exec-with-path ;
 
 : exec-args-with-env  ( seq seq -- int )
-    >r [ first ] [ ] bi r> exec-with-env ;
+    [ [ first ] [ ] bi ] dip exec-with-env ;
 
 : with-fork ( child parent -- )
     [ [ fork-process dup zero? ] dip [ drop ] prepose ] dip
index 56c632edb4b965b3faa8dda928d52fe2810db32c..d8a4bdc1380a79cfa3943584e4a936f6edc19bce 100644 (file)
@@ -31,10 +31,10 @@ C-STRUCT: statvfs
     { "uid_t"   "f_owner" }
     { { "uint32_t" 4 } "f_spare" }     
     { { "char" _VFS_NAMELEN } "f_fstypename" }
-    { { "char" _VFS_NAMELEN } "f_mntonname" }
-    { { "char" _VFS_NAMELEN } "f_mntfromname" } ;
+    { { "char" _VFS_MNAMELEN } "f_mntonname" }
+    { { "char" _VFS_MNAMELEN } "f_mntfromname" } ;
 
-FUNCTION: int statvfs ( char* path, statvfs *buf ) ;
+FUNCTION: int statvfs ( char* path, statvfsbuf ) ;
 
 TUPLE: netbsd-file-system-info < file-system-info
 flag bsize frsize io-size
index ca8a7a2e60fb9a7a125e7d8035c6e2db8c5f6106..d917425bf9cebb415042811d3e9fcc7d000e5a2b 100644 (file)
@@ -198,10 +198,10 @@ FUNCTION: ssize_t readlink ( char* path, char* buf, size_t bufsize ) ;
 : PATH_MAX 1024 ; inline
 
 : read-symbolic-link ( path -- path )
-    PATH_MAX <byte-array> dup >r
-    PATH_MAX
-    [ readlink ] unix-system-call
-    r> swap head-slice >string ;
+    PATH_MAX <byte-array> dup [
+        PATH_MAX
+        [ readlink ] unix-system-call
+    ] dip swap head-slice >string ;
 
 FUNCTION: ssize_t recv ( int s, void* buf, size_t nbytes, int flags ) ;
 FUNCTION: ssize_t recvfrom ( int s, void* buf, size_t nbytes, int flags, sockaddr-in* from, socklen_t* fromlen ) ;
index 99bae97b14090f4991072e1f01f7158dc3b5bd3d..cd4fa3395e58a58db0b84a1bcd8be6574987df2b 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 !
 ! based on glx.h from xfree86, and some of glxtokens.h
-USING: alien alien.c-types alien.syntax alien.syntax.private x11.xlib
+USING: alien alien.c-types alien.syntax x11.xlib
 namespaces make kernel sequences parser words specialized-arrays.int ;
 IN: x11.glx
 
index 953cc38c5632283fabc023c07dca72513fed58e9..a0d16084b1ba1a666f08cdb6aa2c43744509bf60 100644 (file)
@@ -110,8 +110,8 @@ M: assoc assoc-clone-like ( assoc exemplar -- newassoc )
     swap [ swapd set-at ] curry assoc-each ;
 
 : assoc-union ( assoc1 assoc2 -- union )
-    2dup [ assoc-size ] bi@ + pick new-assoc
-    [ rot update ] keep [ swap update ] keep ;
+    [ [ [ assoc-size ] bi@ + ] [ drop ] 2bi new-assoc ] 2keep
+    [ dupd update ] bi@ ;
 
 : assoc-combine ( seq -- union )
     H{ } clone [ dupd update ] reduce ;
index 55831fcdb4936e89e85e8f0b9d8a631b73b5e147..fffb172204d7057a9f5f23fdc58b2d8746f72466 100644 (file)
@@ -23,7 +23,7 @@ PREDICATE: intersection-class < class
 M: intersection-class update-class define-intersection-predicate ;
 
 : define-intersection-class ( class participants -- )
-    [ f f rot intersection-class define-class ]
+    [ [ f f ] dip intersection-class define-class ]
     [ drop update-classes ]
     2bi ;
 
index b6b277a32f41b6d3897711209be03ce58aa7dbe8..6f8021f7336a2325f2b6500a1f6611aa52b712f0 100644 (file)
@@ -248,7 +248,9 @@ M: tuple-class update-class
     3bi ;
 
 : tuple-class-unchanged? ( class superclass slots -- ? )
-    rot tuck [ superclass = ] [ "slots" word-prop = ] 2bi* and ;
+    [ over ] dip
+    [ [ superclass ] dip = ]
+    [ [ "slots" word-prop ] dip = ] 2bi* and ;
 
 : valid-superclass? ( class -- ? )
     [ tuple-class? ] [ tuple eq? ] bi or ;
index c55377e4a04ad0292ce7362afab4fe55205ddcf0..02af963e1a1d13e9b7708026132c840982fca182 100644 (file)
@@ -253,6 +253,10 @@ HELP: lines
 { $values { "stream" "an input stream" } { "seq" "a sequence of strings" } }
 { $description "Reads lines of text until the stream is exhausted, collecting them in a sequence of strings." } ;
 
+HELP: each-line
+{ $values { "quot" { $quotation "( str -- )" } } }
+{ $description "Calls the quotatin with successive lines of text, until the current " { $link input-stream } " is exhausted." } ;
+
 HELP: contents
 { $values { "stream" "an input stream" } { "str" string } }
 { $description "Reads the entire contents of a stream into a string." }
@@ -364,6 +368,8 @@ ARTICLE: "stream-utils" "Stream utilities"
 $nl
 "First, a simple composition of " { $link stream-write } " and " { $link stream-nl } ":"
 { $subsection stream-print }
+"Processing lines one by one:"
+{ $subsection each-line }
 "Sluring an entire stream into memory all at once:"
 { $subsection lines }
 { $subsection contents }
index d7d4edf49ff1656c56457069e989dd510155f2eb..c1fd69a16af006791a1e95eb07473ae0987589c2 100644 (file)
@@ -99,6 +99,9 @@ SYMBOL: error-stream
 : lines ( stream -- seq )
     [ [ readln dup ] [ ] [ drop ] produce ] with-input-stream ;
 
+: each-line ( quot -- )
+    [ [ readln dup ] ] dip [ drop ] while ; inline
+
 : contents ( stream -- str )
     [
         [ 65536 read dup ] [ ] [ drop ] produce concat f like
index bd3f951b021ece159dbbc35c621d71764379c022..dbdd5b27fea356a65686a597fca1200f7d05caf3 100644 (file)
@@ -60,3 +60,5 @@ unit-test
 [ 0 ] [ 1/0. >bignum ] unit-test
 
 [ t ] [ 64 [ 2^ 0.5 * ] map [ < ] monotonic? ] unit-test
+
+[ 5 ] [ 10.5 1.9 /i ] unit-test
index 9dcff9eb90397a34324bbf69cc29eb08a5586bc6..2a22dc4330c12ebebe3b6c5cbc040401c6d59d51 100644 (file)
@@ -24,6 +24,7 @@ M: float - float- ;
 M: float * float* ;
 M: float / float/f ;
 M: float /f float/f ;
+M: float /i float/f >integer ;
 M: float mod float-mod ;
 
 M: real abs dup 0 < [ neg ] when ;
index 8f49d882ee9826b3fb58b3035c5cbd8787711d03..bfe26823beb30a22655a094b7ab97389971247fe 100644 (file)
@@ -68,14 +68,19 @@ HELP: count-instances
 } } ;
 
 ARTICLE: "images" "Images"
-"The current image can be saved; the image contains a complete dump of all data and code in the current Factor instance:"
+"Factor has the ability to save the entire state of the system into an " { $emphasis "image file" } ". The image contains a complete dump of all data and code in the current Factor instance."
 { $subsection save }
 { $subsection save-image }
 { $subsection save-image-and-exit }
 "To start Factor with a custom image, use the " { $snippet "-i=" { $emphasis "image" } } " command line switch; see " { $link "runtime-cli-args" } "."
 $nl
+"One reason to save a custom image is if you find yourself loading the same libraries in every Factor session; some libraries take a little while to compile, so saving an image with those libraries loaded can save you a lot of time."
+$nl
+"For example, to save an image with the web framework loaded,"
+{ $code "USE: furnace" "save" }
 "New images can be created from scratch:"
 { $subsection "bootstrap.image" }
-{ $see-also "tools.memory" "tools.deploy" } ;
+"The " { $link "tools.deploy" } " tool creates stripped-down images containing just enough code to run a single application."
+{ $see-also "tools.memory" } ;
 
 ABOUT: "images"
index 42e4e7705540c1b9596bfe7c68ccc1c88072e630..49ab0eb7d488125aaa02652eaed96b22acc1e83c 100644 (file)
@@ -80,17 +80,17 @@ ERROR: no-word-error name ;
 : <no-word-error> ( name possibilities -- error restarts )
     [ drop \ no-word-error boa ] [ word-restarts ] 2bi ;
 
-SYMBOL: amended-use?
+SYMBOL: amended-use
 
 SYMBOL: auto-use?
 
 : no-word-restarted ( restart-value -- word )
     dup word? [
-        amended-use? on
         dup vocabulary>>
-        [ (use+) ] [
-            "Added ``" swap "'' vocabulary to search path" 3append note.
-        ] bi
+        [ (use+) ]
+        [ amended-use get dup [ push ] [ 2drop ] if ]
+        [ "Added ``" swap "'' vocabulary to search path" 3append note. ]
+        tri
     ] [ create-in ] if ;
 
 : no-word ( name -- newword )
@@ -232,22 +232,16 @@ SYMBOL: interactive-vocabs
 SYMBOL: print-use-hook
 
 print-use-hook global [ [ ] or ] change-at
-
+!
 : parse-fresh ( lines -- quot )
     [
-        amended-use? off
+        V{ } clone amended-use set
         parse-lines
-        amended-use? get [
-            print-use-hook get call
-        ] when
+        amended-use get empty? [ print-use-hook get call ] unless
     ] with-file-vocabs ;
 
 : parsing-file ( file -- )
-    "quiet" get [
-        drop
-    ] [
-        "Loading " write print flush
-    ] if ;
+    "quiet" get [ drop ] [ "Loading " write print flush ] if ;
 
 : filter-moved ( assoc1 assoc2 -- seq )
     swap assoc-diff [
index 832de612dd1276a323cbba53f3eeb379f5df9d8a..118969bd3c82394a8427a4d2e66b59cef69d7cdc 100644 (file)
@@ -101,14 +101,17 @@ M: integer nth-unsafe drop ;
 
 INSTANCE: integer immutable-sequence
 
+: first-unsafe
+    0 swap nth-unsafe ; inline
+
 : first2-unsafe
-    [ 0 swap nth-unsafe 1 ] [ nth-unsafe ] bi ; inline
+    [ first-unsafe ] [ 1 swap nth-unsafe ] bi ; inline
 
 : first3-unsafe
-    [ first2-unsafe 2 ] [ nth-unsafe ] bi ; inline
+    [ first2-unsafe ] [ 2 swap nth-unsafe ] bi ; inline
 
 : first4-unsafe
-    [ first3-unsafe 3 ] [ nth-unsafe ] bi ; inline
+    [ first3-unsafe ] [ 3 swap nth-unsafe ] bi ; inline
 
 : exchange-unsafe ( m n seq -- )
     [ tuck [ nth-unsafe ] 2bi@ ]
@@ -774,13 +777,13 @@ PRIVATE>
     tuck [ tail-slice ] 2bi@ ;
 
 : unclip ( seq -- rest first )
-    [ rest ] [ first ] bi ;
+    [ rest ] [ first-unsafe ] bi ;
 
 : unclip-last ( seq -- butlast last )
     [ but-last ] [ peek ] bi ;
 
 : unclip-slice ( seq -- rest-slice first )
-    [ rest-slice ] [ first ] bi ; inline
+    [ rest-slice ] [ first-unsafe ] bi ; inline
 
 : 2unclip-slice ( seq1 seq2 -- rest-slice1 rest-slice2 first1 first2 )
     [ unclip-slice ] bi@ swapd ; inline
index 89b8a0728de60454a6977ca58f3be345db700186..ce3b5ea024154940291a1fa8b636ae4731c96ec6 100644 (file)
@@ -2,6 +2,18 @@ USING: vocabs vocabs.loader.private help.markup help.syntax
 words strings io ;
 IN: vocabs.loader
 
+ARTICLE: "add-vocab-roots" "Working with code outside of the Factor source tree"
+"You can work with code outside of the Factor source tree by adding additional directories to the list of vocabulary roots."
+$nl
+"There are three ways of doing this."
+$nl
+"The first way is to use an environment variable. Factor looks at the " { $snippet "FACTOR_ROOTS" } " environment variable for a list of " { $snippet ":" } "-separated paths (on Unix) or a list of " { $snippet ";" } "-separated paths (on Windows)."
+$nl
+"The second way is to create a configuration file. You can list additional vocabulary roots in a file that Factor reads at startup:"
+{ $subsection "factor-roots" }
+"Finally, you can add vocabulary roots dynamically using a word:"
+{ $subsection add-vocab-root } ;
+
 ARTICLE: "vocabs.roots" "Vocabulary roots"
 "The vocabulary loader searches for it in one of the root directories:"
 { $subsection vocab-roots }
@@ -12,12 +24,8 @@ ARTICLE: "vocabs.roots" "Vocabulary roots"
     { { $snippet "extra" } " - additional contributed libraries." }
     { { $snippet "work" } " - a root for vocabularies which are not intended to be contributed back to Factor." }
 }
-"Your own vocabularies should go into " { $snippet "extra" } " or " { $snippet "work" } ", depending on whether or not you intend to contribute them back to the Factor project. If you wish to work on vocabularies outside of the Factor source directory, create a " { $link "factor-boot-rc" } " file like the following:"
-{ $code
-    "USING: namespaces sequences vocabs.loader ;"
-    "\"/home/jane/sources/\" vocab-roots get push"
-}
-"See " { $link "rc-files" } " for details." ;
+"You can store your own vocabularies in the " { $snippet "work" } " directory."
+{ $subsection "add-vocab-roots" } ;
 
 ARTICLE: "vocabs.loader" "Vocabulary loader"
 "The vocabulary loader is defined in the " { $vocab-link "vocabs.loader" } " vocabulary."
@@ -57,6 +65,11 @@ HELP: vocab-main
 HELP: vocab-roots
 { $var-description "A sequence of pathname strings to search for vocabularies." } ;
 
+HELP: add-vocab-root
+{ $values { "root" "a pathname string" } }
+{ $description "Adds a directory pathname to the list of vocabulary roots." }
+{ $see-also "factor-roots" } ;
+
 HELP: find-vocab-root
 { $values { "vocab" "a vocabulary specifier" } { "path/f" "a pathname string" } }
 { $description "Searches for a vocabulary in the vocabulary roots." } ;
index 49fad2626fb6f212b540fbbf55412ccff33a22b4..6fb0d088118b74fb9c388d1a9f6adcd9bc54bad3 100644 (file)
@@ -3,7 +3,7 @@
 USING: namespaces make sequences io.files kernel assocs words
 vocabs definitions parser continuations io hashtables sorting
 source-files arrays combinators strings system math.parser
-compiler.errors splitting init accessors ;
+compiler.errors splitting init accessors sets ;
 IN: vocabs.loader
 
 SYMBOL: vocab-roots
@@ -15,6 +15,9 @@ V{
     "resource:work"
 } clone vocab-roots set-global
 
+: add-vocab-root ( root -- )
+    vocab-roots get adjoin ;
+
 : vocab-dir ( vocab -- dir )
     vocab-name { { CHAR: . CHAR: / } } substitute ;
 
index 5c17d514c53922139abf4c78b141fb344e77300e..b36f8be6775c5eac3a0cfdf1e5308f103714bd5a 100644 (file)
@@ -221,7 +221,7 @@ M: word subwords drop f ;
     "( gensym )" f <word> ;
 
 : define-temp ( quot -- word )
-    gensym dup rot define ;
+    [ gensym dup ] dip define ;
 
 : reveal ( word -- )
     dup [ name>> ] [ vocabulary>> ] bi dup vocab-words
index bd1ed83baa6859e1b4b3e30e46b822adf1704823..b087d3ae2baf47636c91feeb0af739f31ba59bb5 100644 (file)
@@ -189,11 +189,11 @@ M: string >ber ( str -- byte-array )
     >byte-array append ;
 
 : >ber-application-string ( n str -- byte-array )
-    >r HEX: 40 + set-tag r> >ber ;
+    [ HEX: 40 + set-tag ] dip >ber ;
 
 GENERIC: >ber-contextspecific ( n obj -- byte-array )
 M: string >ber-contextspecific ( n str -- byte-array )
-    >r HEX: 80 + set-tag r> >ber ;
+    [ HEX: 80 + set-tag ] dip >ber ;
 
 ! =========================================================
 ! Array
index ed9b4bf0c4ef56a3687f4dae9b5f5333ce36dce3..f1b018f54eeaefa46fa5b800cdc703af46a8a8bb 100755 (executable)
@@ -10,10 +10,10 @@ IN: assocs.lib
     dupd at [ nip ] when* ;
 
 : replace-at ( assoc value key -- assoc )
-    >r >r dup r> 1vector r> rot set-at ;
+    [ dupd 1vector ] dip rot set-at ;
 
 : peek-at* ( assoc key -- obj ? )
-    swap at* dup [ >r peek r> ] when ;
+    swap at* dup [ [ peek ] dip ] when ;
 
 : peek-at ( assoc key -- obj )
     peek-at* drop ;
@@ -27,7 +27,7 @@ IN: assocs.lib
 : insert ( value variable -- ) namespace push-at ;
 
 : generate-key ( assoc -- str )
-    >r 32 random-bits >hex r>
+    [ 32 random-bits >hex ] dip
     2dup key? [ nip generate-key ] [ drop ] if ;
 
 : set-at-unique ( value assoc -- key )
diff --git a/extra/benchmark/fannkuch/fannkuch.factor b/extra/benchmark/fannkuch/fannkuch.factor
new file mode 100644 (file)
index 0000000..a69c538
--- /dev/null
@@ -0,0 +1,35 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel fry math math.combinatorics math.order sequences
+io prettyprint ;
+IN: benchmark.fannkuch
+
+: count ( quot: ( -- ? ) -- n )
+    #! Call quot until it returns false, return number of times
+    #! it was true
+    [ 0 ] dip '[ _ dip swap [ [ 1+ ] when ] keep ] loop ; inline
+
+: count-flips ( perm -- flip# )
+    '[
+        _ dup first dup 1 =
+        [ 2drop f ] [ head-slice reverse-here t ] if
+    ] count ; inline
+
+: write-permutation ( perm -- )
+    [ CHAR: 0 + write1 ] each nl ; inline
+
+: fannkuch-step ( counter max-flips perm -- counter max-flips )
+    pick 30 < [ [ 1+ ] [ ] [ dup write-permutation ] tri* ] when
+    count-flips max ; inline
+
+: fannkuch ( n -- )
+    [
+        [ 0 0 ] dip [ 1+ ] B{ } map-as
+        [ fannkuch-step ] each-permutation nip
+    ] keep
+    "Pfannkuchen(" write pprint ") = " write . ;
+
+: fannkuch-main ( -- )
+    9 fannkuch ;
+
+MAIN: fannkuch-main
diff --git a/extra/benchmark/nbody/nbody.factor b/extra/benchmark/nbody/nbody.factor
new file mode 100644 (file)
index 0000000..7b20eda
--- /dev/null
@@ -0,0 +1,105 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors float-arrays fry kernel locals make math
+math.constants math.functions math.vectors prettyprint
+sequences hints arrays ;
+IN: benchmark.nbody
+
+: solar-mass 4 pi sq * ; inline
+: days-per-year 365.24 ; inline
+
+TUPLE: body
+{ location float-array }
+{ velocity float-array }
+{ mass float read-only } ;
+
+: <body> ( location velocity mass -- body )
+    [ days-per-year v*n ] [ solar-mass * ] bi* body boa ; inline
+
+: <jupiter> ( -- body )
+    F{ 4.84143144246472090e+00 -1.16032004402742839e+00 -1.03622044471123109e-01 }
+    F{ 1.66007664274403694e-03 7.69901118419740425e-03 -6.90460016972063023e-05 }
+    9.54791938424326609e-04
+    <body> ;
+
+: <saturn> ( -- body )
+    F{ 8.34336671824457987e+00 4.12479856412430479e+00 -4.03523417114321381e-01 }
+    F{ -2.76742510726862411e-03 4.99852801234917238e-03 2.30417297573763929e-05 }
+    2.85885980666130812e-04
+    <body> ;
+
+: <uranus> ( -- body )
+    F{ 1.28943695621391310e+01 -1.51111514016986312e+01 -2.23307578892655734e-01 }
+    F{ 2.96460137564761618e-03 2.37847173959480950e-03 -2.96589568540237556e-05 }
+    4.36624404335156298e-05
+    <body> ;
+
+: <neptune> ( -- body )
+    F{ 1.53796971148509165e+01 -2.59193146099879641e+01 1.79258772950371181e-01 }
+    F{ 2.68067772490389322e-03 1.62824170038242295e-03 -9.51592254519715870e-05 }
+    5.15138902046611451e-05
+    <body> ;
+
+: <sun> ( -- body )
+    F{ 0 0 0 } F{ 0 0 0 } 1 <body> ;
+    
+: offset-momentum ( body offset -- body )
+    vneg solar-mass v/n >>velocity ; inline
+
+TUPLE: nbody-system { bodies array read-only } ;
+
+: init-bodies ( bodies -- )
+    [ first ] [ F{ 0 0 0 } [ [ velocity>> ] [ mass>> ] bi v*n v+ ] reduce ] bi
+    offset-momentum drop ; inline
+
+: <nbody-system> ( -- system )
+    [ <sun> , <jupiter> , <saturn> , <uranus> , <neptune> , ] { } make nbody-system boa
+    dup bodies>> init-bodies ; inline
+
+:: each-pair ( bodies pair-quot: ( other-body body -- ) each-quot: ( body -- ) -- )
+    bodies [| body i |
+        body each-quot call
+        bodies i 1+ tail-slice [
+            body pair-quot call
+        ] each
+    ] each-index ; inline
+
+: update-position ( body dt -- )
+    [ dup velocity>> ] dip '[ _ _ v*n v+ ] change-location drop ;
+
+: mag ( dt body other-body -- mag d )
+    [ location>> ] bi@ v- [ norm-sq dup sqrt * / ] keep ; inline
+
+:: update-velocity ( other-body body dt -- )
+    dt body other-body mag
+    [ [ body ] 2dip '[ other-body mass>> _ * _ n*v v- ] change-velocity drop ]
+    [ [ other-body ] 2dip '[ body mass>> _ * _ n*v v+ ] change-velocity drop ] 2bi ;
+
+: advance ( system dt -- )
+    [ bodies>> ] dip
+    [ '[ _ update-velocity ] [ drop ] each-pair ]
+    [ '[ _ update-position ] each ]
+    2bi ; inline
+
+: inertia ( body -- e )
+    [ mass>> ] [ velocity>> norm-sq ] bi * 0.5 * ;
+
+: newton's-law ( other-body body -- e )
+    [ [ mass>> ] bi@ * ] [ [ location>> ] bi@ distance ] 2bi / ;
+
+: energy ( system -- x )
+    [ 0.0 ] dip bodies>> [ newton's-law - ] [ inertia + ] each-pair ; inline
+
+: nbody ( n -- )
+    <nbody-system>
+    [ energy . ] [ '[ _ 0.01 advance ] times ] [ energy . ] tri ;
+
+HINTS: update-position body float ;
+HINTS: update-velocity body body float ;
+HINTS: inertia body ;
+HINTS: newton's-law body body ;
+HINTS: nbody fixnum ;
+
+: nbody-main ( -- ) 1000000 nbody ;
+
+MAIN: nbody-main
index eeebe1c12de9184d3bbe20224ffe4fc415632cbc..8319a2d8d9d824a7b54a98415fe4c065ec264ded 100644 (file)
 
-USING: kernel namespaces
+USING: kernel
+       namespaces
+       arrays
+       accessors
+       strings
+       sequences
+       locals
+       threads
        math
-       math.constants
        math.functions
+       math.trig
        math.order
+       math.ranges
        math.vectors
-       math.trig
-       math.physics.pos
-       math.physics.vel
-       combinators arrays sequences random vars
-       combinators.lib
+       random
+       calendar
+       opengl.gl
+       opengl
+       ui
+       ui.gadgets
+       ui.gadgets.tracks
+       ui.gadgets.frames
+       ui.gadgets.grids
+       ui.render
+       multi-methods
+       multi-method-syntax
        combinators.short-circuit
-       accessors ;
+       processing.shapes
+       flatland ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
 IN: boids
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-TUPLE: boid < vel ;
+: constrain ( n a b -- n ) rot min max ;
 
-C: <boid> boid
+: angle-between ( vec vec -- angle )
+  [ v. ] [ [ norm ] bi@ * ] 2bi / -1 1 constrain acos rad>deg ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-VAR: boids
-VAR: world-size
-VAR: time-slice
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+: relative-position ( self other -- v ) swap [ pos>> ] bi@ v- ;
 
-VAR: cohesion-weight
-VAR: alignment-weight
-VAR: separation-weight
+: relative-angle ( self other -- angle )
+  over vel>> -rot relative-position angle-between ;
 
-VAR: cohesion-view-angle
-VAR: alignment-view-angle
-VAR: separation-view-angle
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-VAR: cohesion-radius
-VAR: alignment-radius
-VAR: separation-radius
+: in-radius? ( self other radius -- ? ) [ distance       ] dip     <= ;
+: in-view?   ( self other angle  -- ? ) [ relative-angle ] dip 2 / <= ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: init-variables ( -- )
-  1.0 >cohesion-weight
-  1.0 >alignment-weight
-  1.0 >separation-weight
-
-  75 >cohesion-radius
-  50 >alignment-radius
-  25 >separation-radius
+: vsum ( vector-of-vectors -- vec ) { 0 0 } [ v+ ] reduce ;
 
-  180 >cohesion-view-angle
-  180 >alignment-view-angle
-  180 >separation-view-angle
+: vaverage ( seq-of-vectors -- seq ) [ vsum ] [ length ] bi v/n ;
 
-  10 >time-slice ;
+: average-position ( boids -- pos ) [ pos>> ] map vaverage ;
+: average-velocity ( boids -- vel ) [ vel>> ] map vaverage ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! random-boid and random-boids
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: random-range ( a b -- n ) 1+ over - random + ;
 
-: random-pos ( -- pos ) world-size> [ random ] map ;
+TUPLE: <boid> < <vel> ;
 
-: random-vel ( -- vel ) 2 [ drop -10 10 random-range ] map ;
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: random-boid ( -- boid ) random-pos random-vel <boid> ;
+TUPLE: <behaviour>
+  { weight     initial: 1.0 }
+  { view-angle initial: 180 }
+  { radius                  } ;
 
-: random-boids ( n -- boids ) [ drop random-boid ] map ;
+TUPLE: <cohesion>   < <behaviour> { radius initial: 75 } ;
+TUPLE: <alignment>  < <behaviour> { radius initial: 50 } ;
+TUPLE: <separation> < <behaviour> { radius initial: 25 } ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: constrain ( n a b -- n ) rot min max ;
+:: within-neighborhood? ( SELF OTHER BEHAVIOUR -- ? )
 
-: angle-between ( vec vec -- angle )
-  2dup v. -rot norm swap norm * / -1 1 constrain acos rad>deg ;
+  SELF OTHER
+    {
+      [ BEHAVIOUR radius>>     in-radius? ]
+      [ BEHAVIOUR view-angle>> in-view?   ]
+      [ eq? not                           ]
+    }
+  2&& ;
 
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+:: neighborhood ( SELF OTHERS BEHAVIOUR -- boids )
+  OTHERS [| OTHER | SELF OTHER BEHAVIOUR within-neighborhood? ] filter ;
 
-: relative-position ( self other -- v ) swap [ pos>> ] bi@ v- ;
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: relative-angle ( self other -- angle )
-  over vel>> -rot relative-position angle-between ;
+: normalize* ( u -- v ) { 0.001 0.001 } v+ normalize ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: vsum ( vector-of-vectors -- vec ) { 0 0 } [ v+ ] reduce ;
+GENERIC: force* ( sequence <boid> <behaviour> -- force )
 
-: vaverage ( seq-of-vectors -- seq ) [ vsum ] [ length ] bi v/n ;
+:: cohesion-force ( OTHERS SELF BEHAVIOUR -- force )
+  OTHERS average-position SELF pos>> v- normalize* BEHAVIOUR weight>> v*n ;
 
-: average-position ( boids -- pos ) [ pos>> ] map vaverage ;
+:: alignment-force ( OTHERS SELF BEHAVIOUR -- force )
+  OTHERS average-velocity normalize* BEHAVIOUR weight>> v*n ;
 
-: average-velocity ( boids -- vel ) [ vel>> ] map vaverage ;
+:: separation-force ( OTHERS SELF BEHAVIOUR -- force )
+  SELF pos>> OTHERS average-position v- normalize* BEHAVIOUR weight>> v*n ;
 
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+METHOD: force* ( sequence <boid> <cohesion>   -- force ) cohesion-force   ;
+METHOD: force* ( sequence <boid> <alignment>  -- force ) alignment-force  ;
+METHOD: force* ( sequence <boid> <separation> -- force ) separation-force ;
 
-: in-range? ( self other radius -- ? ) >r distance r> <= ;
+:: force ( OTHERS SELF BEHAVIOUR -- force )
+  SELF OTHERS BEHAVIOUR neighborhood
+    [ { 0 0 } ]
+    [ SELF BEHAVIOUR force* ]
+  if-empty ;
 
-: in-view? ( self other angle -- ? ) >r relative-angle r> 2 / <= ;
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: random-boids ( count -- boids )
+  [
+    drop
+    <boid> new
+      2 [ drop         1000 random ] map >>pos
+      2 [ drop -10 10 [a,b] random ] map >>vel
+  ]
+  map ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: normalize* ( u -- v ) { 0.001 0.001 } v+ normalize ;
+: draw-boid ( boid -- )
+  glPushMatrix
+    dup pos>> gl-translate-2d
+        vel>> first2 rect> arg rad>deg 0 0 1 glRotated
+    { { 0 5 } { 0 -5 } { 20 0 } } triangle
+    fill-mode
+  glPopMatrix ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-! average_position(neighbors) - self_position
+: gadget->sky ( gadget -- sky ) { 0 0 } swap dim>> <rectangle> boa ;
 
-: within-cohesion-neighborhood? ( self other -- ? )
-  { [ cohesion-radius> in-range? ]
-    [ cohesion-view-angle> in-view? ]
-    [ eq? not ] }
-  2&& ;
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: cohesion-neighborhood ( self -- boids )
-  boids> [ within-cohesion-neighborhood? ] with filter ;
+USE: syntax ! Switch back to non-multi-method 'TUPLE:' syntax
 
-: cohesion-force ( self -- force )
-  dup cohesion-neighborhood
-  dup empty?
-  [ 2drop { 0 0 } ]
-  [ average-position swap pos>> v- normalize* cohesion-weight> v*n ]
-  if ;
+TUPLE: <boids-gadget> < gadget paused boids behaviours time-slice ;
+
+M:  <boids-gadget> pref-dim*    ( <boids-gadget> -- dim ) drop { 600 400 } ;
+M:  <boids-gadget> ungraft*     ( <boids-gadget> --     ) t >>paused drop  ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-! self_position - average_position(neighbors)
+:: iterate-system ( BOIDS-GADGET -- )
 
-: within-separation-neighborhood? ( self other -- ? )
-  { [ separation-radius> in-range? ]
-    [ separation-view-angle> in-view? ]
-    [ eq? not ] }
-  2&& ;
+  [let | SKY        [ BOIDS-GADGET gadget->sky   ]
+         BOIDS      [ BOIDS-GADGET boids>>       ]
+         TIME-SLICE [ BOIDS-GADGET time-slice>>  ]
+         BEHAVIOURS [ BOIDS-GADGET behaviours>>  ] |
 
-: separation-neighborhood ( self -- boids )
-  boids> [ within-separation-neighborhood? ] with filter ;
+    BOIDS
 
-: separation-force ( self -- force )
-  dup separation-neighborhood
-  dup empty?
-  [ 2drop { 0 0 } ]
-  [ average-position swap pos>> swap v- normalize* separation-weight> v*n ]
-  if ;
+      [| SELF |
 
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+        [wlet | force-due-to [| BEHAVIOUR | BOIDS SELF BEHAVIOUR force ] |
 
-! average_velocity(neighbors)
+          ! F = m a. M is 1. So F = a.
+            
+          [let | ACCEL [ BEHAVIOURS [ force-due-to ] map vsum ] |
 
-: within-alignment-neighborhood? ( self other -- ? )
-  { [ alignment-radius> in-range? ]
-    [ alignment-view-angle> in-view? ]
-    [ eq? not ] }
-  2&& ;
+            [let | POS [ SELF pos>> SELF vel>> TIME-SLICE v*n v+ ]
+                   VEL [ SELF vel>> ACCEL      TIME-SLICE v*n v+ ] |
 
-: alignment-neighborhood ( self -- boids )
-  boids> [ within-alignment-neighborhood? ] with filter ;
+              [let | POS [ POS SKY wrap   ]
+                     VEL [ VEL normalize* ] |
+                    
+                T{ <boid> f POS VEL } ] ] ] ]
 
-: alignment-force ( self -- force )
-  alignment-neighborhood
-  dup empty?
-  [ drop { 0 0 } ]
-  [ average-velocity normalize* alignment-weight> v*n ]
-  if ;
+      ]
+      
+    map
 
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+    BOIDS-GADGET (>>boids) ] ;
 
-! F = m a
-!
-! We let m be equal to 1 so then this is simply: F = a
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: acceleration ( boid -- acceleration )
-  { separation-force alignment-force cohesion-force } map-exec-with vsum ;
+M:: <boids-gadget> draw-gadget* ( BOIDS-GADGET -- )
+  origin get
+    [ BOIDS-GADGET boids>> [ draw-boid ] each ]
+  with-translation ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! iterate-boid
+
+:: start-boids-thread ( GADGET -- )
+  GADGET f >>paused drop
+  [
+    [
+      GADGET paused>>
+        [ f ]
+        [ GADGET iterate-system GADGET relayout-1 1 milliseconds sleep t ]
+      if
+    ]
+    loop
+  ]
+  in-thread ;
+
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: world-width ( -- w ) world-size> first ;
+: default-behaviours ( -- seq )
+  { <cohesion> <alignment> <separation> } [ new ] map ;
+
+: boids-gadget ( -- gadget )
+  <boids-gadget> new-gadget
+    100 random-boids   >>boids
+    default-behaviours >>behaviours
+    10                 >>time-slice
+    t                  >>clipped? ;
 
-: world-height ( -- w ) world-size> second ;
+: run-boids ( -- ) boids-gadget dup "Boids" open-window start-boids-thread ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: below? ( n a b -- ? ) drop < ;
+USING: math.parser
+       ui.gadgets.labels
+       ui.gadgets.buttons
+       ui.gadgets.packs ;
+
+: truncate-number ( n -- n ) 10 * round 10 / ;
+
+:: make-behaviour-control ( NAME BEHAVIOUR -- gadget )
+  [let | NAME-LABEL  [ NAME           <label> reverse-video-theme ]
+         VALUE-LABEL [ 20 32 <string> <label> reverse-video-theme ] |
+
+    [wlet | update-value-label [ ! ( -- )
+              BEHAVIOUR weight>> truncate-number number>string
+              VALUE-LABEL
+              set-label-string ] |
+
+      update-value-label
+      
+    <pile> 1 >>fill
+      { 1 0 } <track>
+        NAME-LABEL  0.5 track-add
+        VALUE-LABEL 0.5 track-add
+      add-gadget
+      
+      "+0.1"
+      [
+        drop
+        BEHAVIOUR [ 0.1 + ] change-weight drop
+        update-value-label
+      ]
+      <bevel-button> add-gadget
+      
+      "-0.1"
+      [
+        drop
+        BEHAVIOUR weight>> 0.1 >
+        [
+          BEHAVIOUR [ 0.1 - ] change-weight drop
+          update-value-label
+        ]
+        when
+      ]
+      <bevel-button> add-gadget ] ] ;
 
-: above? ( n a b -- ? ) nip > ;
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: wrap ( n a b -- n )
-  {
-    { [ 3dup below? ] [ 2nip     ] }
-    { [ 3dup above? ] [ drop nip ] }
-    { [ t           ] [ 2drop    ] }
-  }
-  cond ;
+:: make-population-control ( BOIDS-GADGET -- gadget )
+  [let | VALUE-LABEL [ 20 32 <string> <label> reverse-video-theme ] |
+
+    [wlet | update-value-label [ ( -- )
+              BOIDS-GADGET boids>> length number>string
+              VALUE-LABEL
+              set-label-string ] |
+
+      update-value-label
+      
+      <pile> 1 >>fill
+    
+        { 1 0 } <track>
+          "Population: " <label> reverse-video-theme 0.5 track-add
+          VALUE-LABEL                                0.5 track-add
+        add-gadget
+
+        "Add 10"
+        [
+          drop
+          BOIDS-GADGET
+            BOIDS-GADGET boids>> 10 random-boids append
+          >>boids
+          drop
+          update-value-label
+        ]
+        <bevel-button>
+        add-gadget
+
+        "Sub 10"
+        [
+          drop
+          BOIDS-GADGET boids>> length 10 >
+          [
+            BOIDS-GADGET
+              BOIDS-GADGET boids>> 10 tail
+            >>boids
+            drop
+            update-value-label
+          ]
+          when
+        ]
+        <bevel-button>
+        add-gadget ] ] ( gadget -- gadget ) ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: wrap-x ( x -- x ) 0 world-width 1- wrap ;
+:: pause-toggle ( BOIDS-GADGET -- )
+  BOIDS-GADGET paused>>
+    [ BOIDS-GADGET start-boids-thread ]
+    [ BOIDS-GADGET t >>paused drop    ]
+  if ;
 
-: wrap-y ( y -- y ) 0 world-height 1- wrap ;
+:: randomize-boids ( BOIDS-GADGET -- )
+  BOIDS-GADGET   BOIDS-GADGET boids>> length random-boids   >>boids drop ;
 
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+: boids-app ( -- )
 
-: new-pos ( boid -- pos ) [ pos>> ] [ vel>> time-slice> v*n ] bi v+ ;
+  [let | BOIDS-GADGET [ boids-gadget ] |
 
-: new-vel ( boid -- vel )
-  [ vel>> ] [ acceleration time-slice> v*n ] bi v+ normalize* ;
+    <frame>
 
-: wrap-pos ( pos -- pos ) { [ wrap-x ] [ wrap-y ] } parallel-call ;
+      <shelf>
 
-: iterate-boid ( self -- self ) [ new-pos wrap-pos ] [ new-vel ] bi <boid> ;
+        1 >>fill
 
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+        "Pause" [ drop BOIDS-GADGET pause-toggle ] <bevel-button> add-gadget
 
-: iterate-boids ( -- ) boids> [ iterate-boid ] map >boids ;
+        "Randomize"
+        [ drop BOIDS-GADGET randomize-boids ] <bevel-button> add-gadget
 
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+        BOIDS-GADGET make-population-control add-gadget
+    
+        "Cohesion:   " BOIDS-GADGET behaviours>> first  make-behaviour-control 
+        "Alignment:  " BOIDS-GADGET behaviours>> second make-behaviour-control
+        "Separation: " BOIDS-GADGET behaviours>> third  make-behaviour-control
 
-: init-boids ( -- ) 100 random-boids >boids ;
+        [ add-gadget ] tri@
 
-: init-world-size ( -- ) { 100 100 } >world-size ;
+      @top grid-add
 
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+      BOIDS-GADGET @center grid-add
+
+    "Boids" open-window
 
-: randomize ( -- ) boids> length random-boids >boids ;
+    BOIDS-GADGET start-boids-thread ] ;
 
-: inc* ( variable -- ) dup  get 0.1 +  0 1 constrain  swap set ;
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: dec* ( variable -- ) dup  get 0.1 -  0 1 constrain  swap set ;
+: boids-main ( -- ) [ boids-app ] with-ui ;
 
+MAIN: boids-main
\ No newline at end of file
diff --git a/extra/boids/ui/authors.txt b/extra/boids/ui/authors.txt
deleted file mode 100755 (executable)
index 6cfd5da..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Eduardo Cavazos
diff --git a/extra/boids/ui/deploy.factor b/extra/boids/ui/deploy.factor
deleted file mode 100755 (executable)
index 8b3c0ba..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-USING: tools.deploy.config ;
-H{
-    { deploy-math? t }
-    { deploy-word-props? f }
-    { deploy-c-types? f }
-    { deploy-ui? t }
-    { deploy-io 2 }
-    { deploy-threads? t }
-    { deploy-word-defs? f }
-    { deploy-compiler? t }
-    { deploy-unicode? f }
-    { deploy-name "Boids" }
-    { "stop-after-last-window?" t }
-    { deploy-reflection 1 }
-}
diff --git a/extra/boids/ui/tags.txt b/extra/boids/ui/tags.txt
deleted file mode 100644 (file)
index cb5fc20..0000000
+++ /dev/null
@@ -1 +0,0 @@
-demos
diff --git a/extra/boids/ui/ui.factor b/extra/boids/ui/ui.factor
deleted file mode 100755 (executable)
index ddb25cc..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-
-USING: combinators.short-circuit kernel namespaces
-       math
-       math.trig
-       math.functions
-       math.vectors
-       math.parser
-       hashtables sequences threads
-       colors
-       opengl
-       opengl.gl
-       ui
-       ui.gadgets
-       ui.gadgets.handler
-       ui.gadgets.slate
-       ui.gadgets.theme
-       ui.gadgets.frames
-       ui.gadgets.labels
-       ui.gadgets.buttons
-       ui.gadgets.packs
-       ui.gadgets.grids
-       ui.gestures
-       assocs.lib vars rewrite-closures boids accessors
-       math.geometry.rect
-       newfx
-       processing.shapes ;
-
-IN: boids.ui
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! draw-boid
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: draw-boid ( boid -- )
-  glPushMatrix
-    dup pos>> gl-translate-2d
-        vel>> first2 rect> arg rad>deg 0 0 1 glRotated
-    { { 0 5 } { 0 -5 } { 20 0 } } triangle
-    fill-mode
-  glPopMatrix ;
-
-: draw-boids ( -- ) boids> [ draw-boid ] each ;
-
-: boid-color ( -- color ) T{ rgba f 1.0 0 0 0.3 } ;
-
-: display ( -- )
-  boid-color >fill-color
-  draw-boids ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-VAR: slate
-
-VAR: loop
-
-: run ( -- )
-  slate> rect-dim >world-size
-  iterate-boids
-  slate> relayout-1
-  yield
-  loop> [ run ] when ;
-
-: button* ( string quot -- button ) closed-quot <bevel-button> ;
-
-: toggle-loop ( -- ) loop> [ loop off ] [ loop on [ run ] in-thread ] if ;
-
-VARS: population-label cohesion-label alignment-label separation-label ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: update-population-label ( -- )
-  "Population: " boids> length number>string append
-  20 32 pad-right population-label> set-label-string ;
-
-: add-10-boids ( -- )
-  boids> 10 random-boids append >boids update-population-label ;
-
-: sub-10-boids ( -- )
-  boids> 10 tail >boids update-population-label ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: truncate-value ( n -- n ) 10 * round 10 / ;
-
-: update-cohesion-label ( -- )
-  "Cohesion: " cohesion-weight> truncate-value number>string append
-  20 32 pad-right cohesion-label> set-label-string ;
-
-: update-alignment-label ( -- )
-  "Alignment: " alignment-weight> truncate-value number>string append
-  20 32 pad-right alignment-label> set-label-string ;
-
-: update-separation-label ( -- )
-  "Separation: " separation-weight> truncate-value number>string append
-  20 32 pad-right separation-label> set-label-string ;
-
-: inc-cohesion-weight ( -- ) cohesion-weight inc* update-cohesion-label ;
-: dec-cohesion-weight ( -- ) cohesion-weight dec* update-cohesion-label ;
-
-: inc-alignment-weight ( -- ) alignment-weight inc* update-alignment-label ;
-: dec-alignment-weight ( -- ) alignment-weight dec* update-alignment-label ;
-
-: inc-separation-weight ( -- ) separation-weight inc* update-separation-label ;
-: dec-separation-weight ( -- ) separation-weight dec* update-separation-label ;
-
-: boids-window* ( -- )
-  init-variables init-world-size init-boids loop on
-
-  "" <label> reverse-video-theme >population-label update-population-label
-  "" <label> reverse-video-theme >cohesion-label   update-cohesion-label
-  "" <label> reverse-video-theme >alignment-label  update-alignment-label
-  "" <label> reverse-video-theme >separation-label update-separation-label
-
-  <frame>
-
-    <shelf>
-
-       1 >>fill
-
-      "ESC - Pause" [ drop toggle-loop ] button* add-gadget
-    
-      "1 - Randomize" [ drop randomize ] button* add-gadget
-    
-      <pile> 1 >>fill
-        population-label> add-gadget
-        "3 - Add 10" [ drop add-10-boids ] button* add-gadget
-        "2 - Sub 10" [ drop sub-10-boids ] button* add-gadget
-      add-gadget
-    
-      <pile> 1 >>fill
-        cohesion-label> add-gadget
-        "q - +0.1" [ drop inc-cohesion-weight ] button* add-gadget
-        "a - -0.1" [ drop dec-cohesion-weight ] button* add-gadget
-      add-gadget
-
-      <pile> 1 >>fill
-        alignment-label> add-gadget
-        "w - +0.1" [ drop inc-alignment-weight ] button* add-gadget
-        "s - -0.1" [ drop dec-alignment-weight ] button* add-gadget
-      add-gadget
-
-      <pile> 1 >>fill
-        separation-label> add-gadget
-        "e - +0.1" [ drop inc-separation-weight ] button* add-gadget
-        "d - -0.1" [ drop dec-separation-weight ] button* add-gadget
-      add-gadget
-
-    @top grid-add
-
-    C[ display ] <slate>
-      dup                    >slate
-      t                      >>clipped?
-      { 600 400 }            >>pdim
-      C[ [ run ] in-thread ] >>graft
-      C[ loop off ]          >>ungraft
-    @center grid-add
-
-  <handler> 
-    H{ } clone
-      T{ key-down f f "1"   } C[ drop randomize             ] is
-      T{ key-down f f "2"   } C[ drop sub-10-boids          ] is
-      T{ key-down f f "3"   } C[ drop add-10-boids          ] is
-      T{ key-down f f "q"   } C[ drop inc-cohesion-weight   ] is
-      T{ key-down f f "a"   } C[ drop dec-cohesion-weight   ] is
-      T{ key-down f f "w"   } C[ drop inc-alignment-weight  ] is
-      T{ key-down f f "s"   } C[ drop dec-alignment-weight  ] is
-      T{ key-down f f "e"   } C[ drop inc-separation-weight ] is
-      T{ key-down f f "d"   } C[ drop dec-separation-weight ] is
-      T{ key-down f f "ESC" } C[ drop toggle-loop           ] is
-    >>table
-
-  "Boids" open-window ;
-
-: boids-window ( -- ) [ [ boids-window* ] with-scope ] with-ui ;
-
-MAIN: boids-window
diff --git a/extra/combinators/cleave/enhanced/enhanced.factor b/extra/combinators/cleave/enhanced/enhanced.factor
new file mode 100644 (file)
index 0000000..b55979a
--- /dev/null
@@ -0,0 +1,31 @@
+
+USING: combinators.cleave fry kernel macros parser quotations ;
+
+IN: combinators.cleave.enhanced
+
+: \\
+  scan-word literalize parsed
+  scan-word literalize parsed ; parsing
+
+MACRO: bi ( p q -- quot )
+  [ >quot ] dip
+    >quot
+  '[ _ _ [ keep ] dip call ] ;
+
+MACRO: tri ( p q r -- quot )
+  [ >quot ] 2dip
+  [ >quot ] dip
+    >quot
+  '[ _ _ _ [ [ keep ] dip keep ] dip call ] ;
+
+MACRO: bi* ( p q -- quot )
+  [ >quot ] dip
+    >quot
+  '[ _ _ [ dip ] dip call ] ;
+
+MACRO: tri* ( p q r -- quot )
+  [ >quot ] 2dip
+  [ >quot ] dip
+    >quot
+  '[ _ _ _ [ [ 2dip ] dip dip ] dip call ] ;
+
index dd8fbd89f57b220c24930a11b501e8ae05211245..9a668b8e6e59879a57b84c6263a754ca25c5b9c1 100755 (executable)
@@ -31,7 +31,7 @@ IN: combinators.lib
 ! Generalized versions of core combinators
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: quad ( x p q r s -- ) >r >r >r keep r> keep r> keep r> call ; inline
+: quad ( x p q r s -- ) [ keep ] 3dip [ keep ] 2dip [ keep ] dip call ; inline
 
 : 4slip ( quot a b c d -- a b c d ) 4 nslip ; inline
 
@@ -123,10 +123,10 @@ MACRO: construct-slots ( assoc tuple-class -- tuple )
     >r pick >r with r> r> swapd with ;
 
 : or? ( obj quot1 quot2 -- ? )
-    >r keep r> rot [ 2nip ] [ call ] if* ; inline
+    [ keep ] dip rot [ 2nip ] [ call ] if* ; inline
 
 : and? ( obj quot1 quot2 -- ? )
-    >r keep r> rot [ call ] [ 2drop f ] if ; inline
+    [ keep ] dip rot [ call ] [ 2drop f ] if ; inline
 
 MACRO: multikeep ( word out-indexes -- ... )
     [
@@ -139,7 +139,7 @@ MACRO: multikeep ( word out-indexes -- ... )
     [ drop ] rot compose attempt-all ; inline
 
 : do-while ( pred body tail -- )
-    >r tuck 2slip r> while ; inline
+    [ tuck 2slip ] dip while ; inline
 
 : generate ( generator predicate -- obj )
     [ dup ] swap [ dup [ nip ] unless not ] 3compose
@@ -147,7 +147,7 @@ MACRO: multikeep ( word out-indexes -- ... )
 
 MACRO: predicates ( seq -- quot/f )
     dup [ 1quotation [ drop ] prepend ] map
-    >r [ [ dup ] prepend ] map r> zip [ drop f ] suffix
+    [ [ [ dup ] prepend ] map ] dip zip [ drop f ] suffix
     [ cond ] curry ;
 
 : %chance ( quot n -- ) 100 random > swap when ; inline
index f6fcac52970843105f067a39a214fb5493b51152..4d6479db915d00bb1bfb9fa31de98a05d29a5148 100755 (executable)
@@ -1,7 +1,7 @@
-! Copyright (C) 2007 Slava Pestov.
+! Copyright (C) 2007, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: io.files io.launcher io.styles io.encodings.ascii io
-hashtables kernel sequences sequences.lib assocs system sorting
+USING: io.files io.launcher io.styles io.encodings.ascii
+prettyprint io hashtables kernel sequences assocs system sorting
 math.parser sets ;
 IN: contributors
 
@@ -16,15 +16,8 @@ IN: contributors
     { } map>assoc ;
 
 : contributors ( -- )
-    changelog patch-counts sort-values <reversed>
-    standard-table-style [
-        [
-            [
-                first2 swap
-                [ write ] with-cell
-                [ number>string write ] with-cell
-            ] with-row
-        ] each
-    ] tabular-output ;
+    changelog patch-counts
+    sort-values <reversed>
+    simple-table. ;
 
 MAIN: contributors
diff --git a/extra/flatland/flatland.factor b/extra/flatland/flatland.factor
new file mode 100644 (file)
index 0000000..c98c5a6
--- /dev/null
@@ -0,0 +1,220 @@
+
+USING: accessors arrays fry kernel math math.vectors sequences
+       math.intervals
+       multi-methods
+       combinators.cleave.enhanced
+       multi-method-syntax ;
+
+IN: flatland
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! Two dimensional world protocol
+
+GENERIC: x ( obj -- x )
+GENERIC: y ( obj -- y )
+
+GENERIC: (x!) ( x obj -- )
+GENERIC: (y!) ( y obj -- )
+
+: x! ( obj x -- obj ) over (x!) ;
+: y! ( obj y -- obj ) over (y!) ;
+
+GENERIC: width  ( obj -- width  )
+GENERIC: height ( obj -- height )
+
+GENERIC: (width!)  ( width  obj -- )
+GENERIC: (height!) ( height obj -- )
+
+: width!  ( obj width  -- obj ) over (width!) ;
+: height! ( obj height -- obj ) over (width!) ;
+
+! Predicates on relative placement
+
+GENERIC: to-the-left-of?  ( obj obj -- ? )
+GENERIC: to-the-right-of? ( obj obj -- ? )
+
+GENERIC: below? ( obj obj -- ? )
+GENERIC: above? ( obj obj -- ? )
+
+GENERIC: in-between-horizontally? ( obj obj -- ? )
+
+GENERIC: horizontal-interval ( obj -- interval )
+
+GENERIC: move-to ( obj obj -- )
+
+GENERIC: move-by ( obj delta -- )
+
+GENERIC: move-left-by  ( obj obj -- )
+GENERIC: move-right-by ( obj obj -- )
+
+GENERIC: left   ( obj -- left   )
+GENERIC: right  ( obj -- right  )
+GENERIC: bottom ( obj -- bottom )
+GENERIC: top    ( obj -- top    )
+
+GENERIC: distance ( a b -- c )
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! Some of the above methods work on two element sequences.
+! A two element sequence may represent a point in space or describe
+! width and height.
+
+METHOD: x ( sequence -- x ) first  ;
+METHOD: y ( sequence -- y ) second ;
+
+METHOD: (x!) ( number sequence -- ) set-first  ;
+METHOD: (y!) ( number sequence -- ) set-second ;
+
+METHOD: width  ( sequence -- width  ) first  ;
+METHOD: height ( sequence -- height ) second ;
+
+: changed-x ( seq quot -- ) over [ [ x ] dip call ] dip (x!) ; inline
+: changed-y ( seq quot -- ) over [ [ y ] dip call ] dip (y!) ; inline
+
+METHOD: move-to ( sequence sequence -- )         [ x x! ] [ y y! ] bi drop ;
+METHOD: move-by ( sequence sequence -- ) dupd v+ [ x x! ] [ y y! ] bi drop ;
+
+METHOD: move-left-by  ( sequence number -- ) '[ _ - ] changed-x ;
+METHOD: move-right-by ( sequence number -- ) '[ _ + ] changed-x ;
+
+! METHOD: move-left-by  ( sequence number -- ) neg 0 2array move-by ;
+! METHOD: move-right-by ( sequence number -- )     0 2array move-by ;
+
+! METHOD:: move-left-by  ( SEQ:sequence X:number -- )
+!   SEQ { X 0 } { -1 0 } v* move-by ;
+
+METHOD: distance ( sequence sequence -- dist ) v- norm ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! A class for objects with a position
+
+TUPLE: <pos> pos ;
+
+METHOD: x ( <pos> -- x ) pos>> first  ;
+METHOD: y ( <pos> -- y ) pos>> second ;
+
+METHOD: (x!) ( number <pos> -- ) pos>> set-first  ;
+METHOD: (y!) ( number <pos> -- ) pos>> set-second ;
+
+METHOD: to-the-left-of?  ( <pos> number -- ? ) [ x ] dip < ;
+METHOD: to-the-right-of? ( <pos> number -- ? ) [ x ] dip > ;
+
+METHOD: move-left-by  ( <pos> number -- ) [ pos>> ] dip move-left-by  ;
+METHOD: move-right-by ( <pos> number -- ) [ pos>> ] dip move-right-by ;
+
+METHOD: above? ( <pos> number -- ? ) [ y ] dip > ;
+METHOD: below? ( <pos> number -- ? ) [ y ] dip < ;
+
+METHOD: move-by ( <pos> sequence -- ) '[ _ v+ ] change-pos drop ;
+
+METHOD: distance ( <pos> <pos> -- dist ) [ pos>> ] bi@ distance ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! A class for objects with velocity. It inherits from <pos>. Hey, if
+! it's moving it has a position right? Unless it's some alternate universe...
+
+TUPLE: <vel> < <pos> vel ;
+
+: moving-up?   ( obj -- ? ) vel>> y 0 > ;
+: moving-down? ( obj -- ? ) vel>> y 0 < ;
+
+: step-size ( vel time -- dist ) [ vel>> ] dip v*n      ;
+: move-for  ( vel time --      ) dupd step-size move-by ;
+
+: reverse-horizontal-velocity ( vel -- ) vel>> [ x neg ] [ ] bi (x!) ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! The 'pos' slot indicates the lower left hand corner of the
+! rectangle. The 'dim' is holds the width and height.
+
+TUPLE: <rectangle> < <pos> dim ;
+
+METHOD: width  ( <rectangle> -- width  ) dim>> first  ;
+METHOD: height ( <rectangle> -- height ) dim>> second ;
+
+METHOD: left   ( <rectangle> -- x )    x             ;
+METHOD: right  ( <rectangle> -- x ) \\ x width  bi + ;
+METHOD: bottom ( <rectangle> -- y )    y             ;
+METHOD: top    ( <rectangle> -- y ) \\ y height bi + ;
+
+: bottom-left ( rectangle -- pos ) pos>> ;
+
+: center-x ( rectangle -- x ) [ left   ] [ width  2 / ] bi + ;
+: center-y ( rectangle -- y ) [ bottom ] [ height 2 / ] bi + ;
+
+: center ( rectangle -- seq ) \\ center-x center-y bi 2array ;
+
+METHOD: to-the-left-of?  ( <pos> <rectangle> -- ? ) \\ x left  bi* < ;
+METHOD: to-the-right-of? ( <pos> <rectangle> -- ? ) \\ x right bi* > ;
+
+METHOD: below? ( <pos> <rectangle> -- ? ) \\ y bottom bi* < ;
+METHOD: above? ( <pos> <rectangle> -- ? ) \\ y top    bi* > ;
+
+METHOD: horizontal-interval ( <rectangle> -- interval )
+  \\ left right bi [a,b] ;
+
+METHOD: in-between-horizontally? ( <pos> <rectangle> -- ? )
+  \\ x horizontal-interval bi* interval-contains? ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+TUPLE: <extent> left right bottom top ;
+
+METHOD: left   ( <extent> -- left   ) left>>   ;
+METHOD: right  ( <extent> -- right  ) right>>  ;
+METHOD: bottom ( <extent> -- bottom ) bottom>> ;
+METHOD: top    ( <extent> -- top    ) top>>    ;
+
+METHOD: width  ( <extent> -- width  ) \\ right>> left>>   bi - ;
+METHOD: height ( <extent> -- height ) \\ top>>   bottom>> bi - ;
+
+! METHOD: to-extent ( <rectangle> -- <extent> )
+!   { [ left>> ] [ right>> ] [ bottom>> ] [ top>> ] } cleave <extent> boa ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+METHOD: to-the-left-of?  ( sequence <rectangle> -- ? ) \\ x left  bi* < ;
+METHOD: to-the-right-of? ( sequence <rectangle> -- ? ) \\ x right bi* > ;
+
+METHOD: below? ( sequence <rectangle> -- ? ) \\ y bottom bi* < ;
+METHOD: above? ( sequence <rectangle> -- ? ) \\ y top    bi* > ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! Some support for the' 'rect' class from math.geometry.rect'
+
+! METHOD: width  ( rect -- width  ) dim>> first  ;
+! METHOD: height ( rect -- height ) dim>> second ;
+
+! METHOD: left  ( rect -- left  ) loc>> x
+! METHOD: right ( rect -- right ) [ loc>> x ] [ width ] bi + ;
+
+! METHOD: to-the-left-of?  ( sequence rect -- ? ) [ x ] [ loc>> x ] bi* < ;
+! METHOD: to-the-right-of? ( sequence rect -- ? ) [ x ] [ loc>> x ] bi* > ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+USING: locals combinators ; 
+
+:: wrap ( POINT RECT -- POINT )
+    
+  {
+      { [ POINT RECT to-the-left-of?  ] [ RECT right ] }
+      { [ POINT RECT to-the-right-of? ] [ RECT left  ] }
+      { [ t                           ] [ POINT x    ] }
+  }
+  cond
+
+  {
+      { [ POINT RECT below? ] [ RECT top    ] }
+      { [ POINT RECT above? ] [ RECT bottom ] }
+      { [ t                 ] [ POINT y     ] }
+  }
+  cond
+
+  2array ;
index e084ea6806f3f8f4c48ccb0fd9f2df20239b329e..836693026a41da1152f6851da2b6f79ca5c9376d 100644 (file)
@@ -26,7 +26,7 @@ SYMBOL: tagstack
         swap >>name ;
 
 : make-tag ( string attribs -- tag )
-    >r [ closing-tag? ] keep "/" trim1 r> rot <tag> ;
+    [ [ closing-tag? ] keep "/" trim1 ] dip rot <tag> ;
 
 : make-text-tag ( string -- tag )
     tag new
index 7082acec47dd4a49f04fe4a13640b9c91f62b237..52f2d38dd1fd0744a8b53d08bb1a6fcc5c0134bd 100755 (executable)
@@ -1,7 +1,8 @@
 ! Copyright (C) 2007, 2008 Alex Chapman
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays colors combinators float-arrays kernel jamshred.oint locals math math.constants math.matrices math.order math.ranges math.vectors math.quadratic random sequences vectors ;
-USE: tools.walker
+USING: accessors arrays colors combinators float-arrays kernel
+locals math math.constants math.matrices math.order math.ranges
+math.vectors math.quadratic random sequences vectors jamshred.oint ;
 IN: jamshred.tunnel
 
 : n-segments ( -- n ) 5000 ; inline
diff --git a/extra/lisp/authors.txt b/extra/lisp/authors.txt
deleted file mode 100644 (file)
index 4b7af4a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-James Cash
diff --git a/extra/lisp/lisp-docs.factor b/extra/lisp/lisp-docs.factor
deleted file mode 100644 (file)
index c970a1e..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-IN: lisp
-USING: help.markup help.syntax ;
-HELP: <LISP
-{ $description "parsing word which converts the lisp code between <LISP and LISP> into factor quotations and calls it" }
-{ $see-also lisp-string>factor } ;
-
-HELP: lisp-string>factor
-{ $values { "str"  "a string of lisp code" } { "quot" "the quotation the lisp compiles into" } }
-{ $description "Turns a string of lisp into a factor quotation" } ;
-
-ARTICLE: "lisp" "Lisp in Factor"
-"This is a simple implementation of a Lisp dialect, which somewhat resembles Scheme." $nl
-"It works in two main stages: "
-{ $list
-  { "Parse (via "  { $vocab-link "lisp.parser" } " the Lisp code into a "
-    { $snippet "s-exp"  } " tuple." }
-  { "Transform the " { $snippet "s-exp" } " into a Factor quotation, via " { $link convert-form } }
-}
-
-{ $subsection "lisp.parser" } ;
-
-ABOUT: "lisp"
\ No newline at end of file
diff --git a/extra/lisp/lisp-tests.factor b/extra/lisp/lisp-tests.factor
deleted file mode 100644 (file)
index 5f849c4..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-! Copyright (C) 2008 James Cash
-! See http://factorcode.org/license.txt for BSD license.
-USING: lisp lisp.parser tools.test sequences math kernel parser arrays lists
-quotations ;
-
-IN: lisp.test
-
-[
-    define-lisp-builtins
-    
-    { 5 } [
-        "(+ 2 3)" lisp-eval
-    ] unit-test
-    
-    { 8.3 } [
-        "(- 10.4 2.1)" lisp-eval
-    ] unit-test
-    
-    { 3 } [
-        "((lambda (x y) (+ x y)) 1 2)" lisp-eval
-    ] unit-test
-    
-    { 42 } [
-        "((lambda (x y z) (+ x (- y z))) 40 3 1)" lisp-eval
-    ] unit-test
-    
-    { "b" } [
-        "(cond (#f \"a\") (#t \"b\"))" lisp-eval
-    ] unit-test
-    
-    { "b" } [
-        "(cond ((< 1 2) \"b\") (#t \"a\"))" lisp-eval
-    ] unit-test
-        
-    { +nil+ } [
-        "(list)" lisp-eval
-    ] unit-test
-    
-    { { 1 2 3 4 5 } } [
-        "(list 1 2 3 4 5)" lisp-eval list>seq
-    ] unit-test
-    
-    { { 1 2 { 3 { 4 } 5 } } } [
-        "(list 1 2 (list 3 (list 4) 5))" lisp-eval cons>seq
-    ] unit-test
-    
-    { 5 } [
-        "(begin (+ 1 4))" lisp-eval
-    ] unit-test
-    
-    { 5 } [
-        "(begin (+ 5 6) (+ 1 4))" lisp-eval
-    ] unit-test
-    
-    { t } [
-        T{ lisp-symbol f "if" } lisp-macro?
-    ] unit-test
-    
-    { 1 } [
-        "(if #t 1 2)" lisp-eval
-    ] unit-test
-    
-    { 3 } [
-        "((lambda (x) (if x (+ 1 2) (- 3 5))) #t)" lisp-eval
-    ] unit-test
-    
-    { { 5 4 3 } } [
-        "((lambda (x &rest xs) (cons x xs)) 5 4 3)" lisp-eval cons>seq
-    ] unit-test
-    
-    { { 5 } } [
-        "((lambda (x &rest xs) (cons x xs)) 5)" lisp-eval cons>seq
-    ] unit-test
-    
-    { { 1 2 3 4 } } [
-        "((lambda (&rest xs) xs) 1 2 3 4)" lisp-eval cons>seq
-    ] unit-test
-    
-    { 10 } [
-        <LISP (begin (+ 1 2) (+ 9 1)) LISP>
-    ] unit-test
-    
-    { 4 } [
-        <LISP ((lambda (x y) (if x (+ 1 y) (+ 2 y))) #t 3) LISP>
-    ] unit-test
-    
-    { { 3 3 4 } } [
-        <LISP (defun foo (x y &rest z)
-                  (cons (+ x y) z))
-              (foo 1 2 3 4)
-        LISP> cons>seq
-    ] unit-test
-    
-] with-interactive-vocabs
diff --git a/extra/lisp/lisp.factor b/extra/lisp/lisp.factor
deleted file mode 100644 (file)
index 4a93350..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-! Copyright (C) 2008 James Cash
-! See http://factorcode.org/license.txt for BSD license.
-USING: kernel peg sequences arrays strings 
-namespaces combinators math locals locals.private locals.backend accessors
-vectors syntax lisp.parser assocs parser words
-quotations fry lists summary combinators.short-circuit continuations multiline ;
-IN: lisp
-
-DEFER: convert-form
-DEFER: funcall
-DEFER: lookup-var
-DEFER: lookup-macro
-DEFER: lisp-macro?
-DEFER: lisp-var?
-DEFER: define-lisp-macro
-
-! Functions to convert s-exps to quotations
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-: convert-body ( cons -- quot )
-    [ ] [ convert-form compose ] foldl ; inline
-
-: convert-cond ( cons -- quot )
-    cdr [ 2car [ convert-form ] bi@ 2array ]
-    { } lmap-as '[ _ cond ] ;
-
-: convert-general-form ( cons -- quot )
-    uncons [ convert-body ] [ convert-form ] bi* '[ _ @ funcall ] ;
-
-! words for convert-lambda
-<PRIVATE
-: localize-body ( assoc body -- newbody )
-    {
-      { [ dup list? ] [ [ lisp-symbol? ] rot '[ [ name>> _ at ] [ ] bi or ] traverse ] }
-      { [ dup lisp-symbol? ] [ name>> swap at ] }
-     [ nip ]
-    } cond ;
-
-: localize-lambda ( body vars -- newvars newbody )
-    swap [ make-locals dup push-locals ] dip
-    dupd [ localize-body convert-form ] with lmap>array
-    >quotation swap pop-locals ;
-
-: split-lambda ( cons -- body-cons vars-seq )
-    cdr uncons [ name>> ] lmap>array ; inline
-
-: rest-lambda ( body vars -- quot )
-    "&rest" swap [ remove ] [ index ] 2bi
-    [ localize-lambda <lambda> lambda-rewrite call ] dip
-    swap '[ _ cut '[ @ _ seq>list ] call _ call call ] 1quotation ;
-
-: normal-lambda ( body vars -- quot )
-    localize-lambda <lambda> lambda-rewrite '[ @ compose call call ] 1quotation ;
-PRIVATE>
-
-: convert-lambda ( cons -- quot )
-    split-lambda "&rest" over member? [ rest-lambda ] [ normal-lambda ] if ;
-
-: convert-quoted ( cons -- quot )
-    cadr 1quotation ;
-
-: convert-defmacro ( cons -- quot )
-    cdr [ convert-lambda ] [ car name>> ] bi define-lisp-macro [ ] ;
-
-: macro-expand ( cons -- quot )
-    uncons [ list>seq >quotation ] [ lookup-macro ] bi* call call ;
-
-: expand-macros ( cons -- cons )
-    dup list? [ [ expand-macros ] lmap dup car lisp-macro? [ macro-expand expand-macros ] when ] when ;
-    
-: convert-begin ( cons -- quot )
-    cdr [ convert-form ] [ ] lmap-as [ 1 tail* ] [ but-last ] bi
-    [ '[ { } _ with-datastack drop ] ] map prepend '[ _ [ call ] each ] ;
-
-: form-dispatch ( cons lisp-symbol -- quot )
-    name>>
-    { { "lambda" [ convert-lambda ] }
-      { "defmacro" [ convert-defmacro ] }
-      { "quote" [ convert-quoted ] }
-      { "cond" [ convert-cond ] }
-      { "begin" [ convert-begin ] }
-     [ drop convert-general-form ]
-    } case ;
-
-: convert-list-form ( cons -- quot )
-    dup car
-    {
-      { [ dup lisp-symbol? ] [ form-dispatch ] }
-     [ drop convert-general-form ]
-    } cond ;
-
-: convert-form ( lisp-form -- quot )
-    {
-      { [ dup cons? ] [ convert-list-form ] }
-      { [ dup lisp-var? ] [ lookup-var 1quotation ] }
-      { [ dup lisp-symbol? ] [ '[ _ lookup-var ] ] }
-     [ 1quotation ]
-    } cond ;
-
-: lisp-string>factor ( str -- quot )
-    lisp-expr expand-macros convert-form ;
-
-: lisp-eval ( str -- * )
-    lisp-string>factor call ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-SYMBOL: lisp-env
-SYMBOL: macro-env
-
-ERROR: no-such-var variable-name ;
-M: no-such-var summary drop "No such variable" ;
-
-: init-env ( -- )
-    H{ } clone lisp-env set
-    H{ } clone macro-env set ;
-
-: lisp-define ( quot name -- )
-    lisp-env get set-at ;
-    
-: define-lisp-var ( lisp-symbol body --  )
-    swap name>> lisp-define ;
-
-: lisp-get ( name -- word )
-    lisp-env get at ;
-
-: lookup-var ( lisp-symbol -- quot )
-    [ name>> ] [ lisp-var? ] bi [ lisp-get ] [ no-such-var ] if ;
-
-: lisp-var? ( lisp-symbol -- ? )
-    dup lisp-symbol? [ name>> lisp-env get key? ] [ drop f ] if ;
-
-: funcall ( quot sym -- * )
-    [ 1array [ call ] with-datastack >quotation ] dip curry call ; inline
-
-: define-primitive ( name vocab word -- )
-    swap lookup 1quotation '[ _ compose call ] swap lisp-define ;
-
-: lookup-macro ( lisp-symbol -- lambda )
-    name>> macro-env get at ;
-
-: define-lisp-macro ( quot name -- )
-    macro-env get set-at ;
-
-: lisp-macro? ( car -- ? )
-    dup lisp-symbol? [ name>> macro-env get key? ] [ drop f ] if ;
-
-: define-lisp-builtins ( -- )
-   init-env
-
-   f "#f" lisp-define
-   t "#t" lisp-define
-
-   "+" "math" "+" define-primitive
-   "-" "math" "-" define-primitive
-   "<" "math" "<" define-primitive
-   ">" "math" ">" define-primitive
-
-   "cons" "lists" "cons" define-primitive
-   "car" "lists" "car" define-primitive
-   "cdr" "lists" "cdr" define-primitive
-   "append" "lists" "lappend" define-primitive
-   "nil" "lists" "nil" define-primitive
-   "nil?" "lists" "nil?" define-primitive
-
-   "set" "lisp" "define-lisp-var" define-primitive
-    
-   "(set 'list (lambda (&rest xs) xs))" lisp-eval
-   "(defmacro setq (var val) (list 'set (list 'quote var) val))" lisp-eval
-    
-   <" (defmacro defun (name vars &rest body)
-        (list 'setq name (cons 'lambda (cons vars body)))) "> lisp-eval
-    
-   "(defmacro if (pred tr fl) (list 'cond (list pred tr) (list (quote #t) fl)))" lisp-eval
-   ;
-
-: <LISP 
-    "LISP>" parse-multiline-string "(begin " prepend ")" append define-lisp-builtins
-    lisp-string>factor parsed \ call parsed ; parsing
\ No newline at end of file
diff --git a/extra/lisp/parser/authors.txt b/extra/lisp/parser/authors.txt
deleted file mode 100644 (file)
index 4b7af4a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-James Cash
diff --git a/extra/lisp/parser/parser-docs.factor b/extra/lisp/parser/parser-docs.factor
deleted file mode 100644 (file)
index fc16a0a..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-IN: lisp.parser
-USING: help.markup help.syntax ;
-
-ARTICLE: "lisp.parser" "Parsing strings of Lisp"
-"This vocab uses " { $vocab-link "peg.ebnf" } " to turn strings of Lisp into " { $snippet "s-exp" } "s, which are then used by"
-{ $vocab-link "lisp" } " to produce Factor quotations." ;
\ No newline at end of file
diff --git a/extra/lisp/parser/parser-tests.factor b/extra/lisp/parser/parser-tests.factor
deleted file mode 100644 (file)
index 911a8d3..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-! Copyright (C) 2008 James Cash
-! See http://factorcode.org/license.txt for BSD license.
-USING: lisp.parser tools.test peg peg.ebnf lists ;
-
-IN: lisp.parser.tests
-
-{ 1234  }  [
-  "1234" "atom" \ lisp-expr rule parse
-] unit-test
-
-{ -42  }  [
-    "-42" "atom" \ lisp-expr rule parse
-] unit-test
-
-{ 37/52 } [
-    "37/52" "atom" \ lisp-expr rule parse
-] unit-test
-
-{ 123.98 } [
-    "123.98" "atom" \ lisp-expr rule parse
-] unit-test
-
-{ "" } [
-    "\"\"" "atom" \ lisp-expr rule parse
-] unit-test
-
-{ "aoeu" } [
-    "\"aoeu\"" "atom" \ lisp-expr rule parse
-] unit-test
-
-{ "aoeu\"de" } [
-    "\"aoeu\\\"de\"" "atom" \ lisp-expr rule parse
-] unit-test
-
-{ T{ lisp-symbol f "foobar" } } [
-    "foobar" "atom" \ lisp-expr rule parse
-] unit-test
-
-{ T{ lisp-symbol f "+" } } [
-    "+" "atom" \ lisp-expr rule parse
-] unit-test
-
-{ +nil+ } [
-    "()" lisp-expr
-] unit-test
-
-{ T{
-    cons
-    f
-    T{ lisp-symbol f "foo" }
-    T{
-        cons
-        f
-        1
-        T{ cons f 2 T{ cons f "aoeu" +nil+ } }
-    } } } [
-    "(foo 1 2 \"aoeu\")" lisp-expr
-] unit-test
-
-{ T{ cons f
-       1
-       T{ cons f
-           T{ cons f 3 T{ cons f 4 +nil+ } }
-           T{ cons f 2 +nil+ } }
-   }
-} [
-    "(1 (3 4) 2)" lisp-expr
-] unit-test
-    
-{ { T{ lisp-symbol { name "quote" } } { 1 2 3 } } } [
-    "'(1 2 3)" lisp-expr cons>seq
-] unit-test
-    
-{ { T{ lisp-symbol f "quote" } T{ lisp-symbol f "foo" } } } [
-    "'foo" lisp-expr cons>seq
-] unit-test
-    
-{ { 1 2 { T{ lisp-symbol { name "quote" } } { 3 4 } } 5 } } [
-    "(1 2 '(3 4) 5)" lisp-expr cons>seq
-] unit-test
\ No newline at end of file
diff --git a/extra/lisp/parser/parser.factor b/extra/lisp/parser/parser.factor
deleted file mode 100644 (file)
index 50f5869..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-! Copyright (C) 2008 James Cash
-! See http://factorcode.org/license.txt for BSD license.
-USING: kernel peg peg.ebnf math.parser sequences arrays strings
-math fry accessors lists combinators.short-circuit ;
-
-IN: lisp.parser
-
-TUPLE: lisp-symbol name ;
-C: <lisp-symbol> lisp-symbol
-
-EBNF: lisp-expr
-_            = (" " | "\t" | "\n")*
-LPAREN       = "("
-RPAREN       = ")"
-dquote       = '"'
-squote       = "'"
-digit        = [0-9]
-integer      = ("-")? (digit)+                           => [[ first2 append string>number ]]
-float        = integer "." (digit)*                      => [[ first3 >string [ number>string ] 2dip 3append string>number ]]
-rational     = integer "/" (digit)+                      => [[ first3 nip string>number / ]]
-number       = float
-              | rational
-              | integer
-id-specials  = "!" | "$" | "%" | "&" | "*" | "/" | ":"
-              | "<" | "#" | " =" | ">" | "?" | "^" | "_"
-              | "~" | "+" | "-" | "." | "@"
-letters      = [a-zA-Z]                                  => [[ 1array >string ]]
-initials     = letters | id-specials
-numbers      = [0-9]                                     => [[ 1array >string ]]
-subsequents  = initials | numbers
-identifier   = initials (subsequents)*                   => [[ first2 concat append <lisp-symbol> ]]
-escaped      = "\" .                                     => [[ second ]]
-string       = dquote ( escaped | !(dquote) . )*  dquote => [[ second >string ]]
-atom         = number
-              | identifier
-              | string
-s-expression = LPAREN (list-item)* RPAREN                => [[ second seq>cons ]]
-list-item    = _ ( atom | s-expression | quoted ) _      => [[ second ]]
-quoted       = squote list-item                          => [[ second nil cons "quote" <lisp-symbol> swap cons ]]
-expr         = list-item
-;EBNF
\ No newline at end of file
diff --git a/extra/lisp/parser/summary.txt b/extra/lisp/parser/summary.txt
deleted file mode 100644 (file)
index aa407b3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-EBNF grammar for parsing Lisp
diff --git a/extra/lisp/parser/tags.txt b/extra/lisp/parser/tags.txt
deleted file mode 100644 (file)
index d1f6fa1..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-lisp
-parsing
diff --git a/extra/lisp/summary.txt b/extra/lisp/summary.txt
deleted file mode 100644 (file)
index 7277c2a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-A Lisp interpreter/compiler in Factor 
diff --git a/extra/lisp/tags.txt b/extra/lisp/tags.txt
deleted file mode 100644 (file)
index c369cca..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-lisp
-languages
index 78c168015f9e7484eb10b45eaac0d2e660d6d131..226b7126766b84bd0c11559bf80e89c66ab0d08a 100644 (file)
@@ -12,10 +12,14 @@ IN: money.tests
 [ 1/10 ] [ DECIMAL: .1 ] unit-test
 [ 1/10 ] [ DECIMAL: 0.1 ] unit-test
 [ 1/10 ] [ DECIMAL: 00.10 ] unit-test
-
-
+[ 23 ] [ DECIMAL: 23 ] unit-test
+[ -23 ] [ DECIMAL: -23 ] unit-test
+[ -23-1/100 ] [ DECIMAL: -23.01 ] unit-test
 
 [ "DECIMAL: ." eval ] must-fail
 [ "DECIMAL: f" eval ] must-fail
 [ "DECIMAL: 0.f" eval ] must-fail
 [ "DECIMAL: f.0" eval ] must-fail
+
+[ "$100.00" ] [ DECIMAL: 100.0 money>string ] unit-test
+[ "$0.00" ] [ DECIMAL: 0.0 money>string ] unit-test
index 5fa76d5f531be6676644d9f9e4e2dfc2b4368cd4..b7da97ca0676abbe5ece0e73ee9ad38ae6190836 100644 (file)
@@ -3,28 +3,31 @@ namespaces make sequences splitting grouping combinators
 continuations ;
 IN: money
 
+SYMBOL: currency-token
+CHAR: $ \ currency-token set-global
+
 : dollars/cents ( dollars -- dollars cents )
     100 * 100 /mod round ;
 
+: (money>string) ( dollars cents -- string )
+    [ number>string ] bi@
+    [ <reversed> 3 group "," join <reversed> ]
+    [ 2 CHAR: 0 pad-left ] bi* "." swap 3append ;
+
 : money>string ( object -- string )
-    dollars/cents [
-        "$" %
-        swap number>string
-        <reversed> 3 group "," join <reversed> %
-        "." % number>string 2 CHAR: 0 pad-left %
-    ] "" make ;
+    dollars/cents (money>string) currency-token get prefix ;
 
-: money. ( object -- )
-    money>string print ;
+: money. ( object -- ) money>string print ;
 
-ERROR: not-a-decimal x ;
+ERROR: not-an-integer x ;
 
 : parse-decimal ( str -- ratio )
     "." split1
-    >r dup "-" head? [ drop t "0" ] [ f swap ] if r>
+    [ "-" ?head swap ] dip
     [ [ "0" ] when-empty ] bi@
-    dup length
-    >r [ dup string>number [ nip ] [ not-a-decimal ] if* ] bi@ r>
+    [
+        [ dup string>number [ nip ] [ not-an-integer ] if* ] bi@
+    ] keep length
     10 swap ^ / + swap [ neg ] when ;
 
 : DECIMAL:
diff --git a/extra/multi-method-syntax/multi-method-syntax.factor b/extra/multi-method-syntax/multi-method-syntax.factor
new file mode 100644 (file)
index 0000000..9f05525
--- /dev/null
@@ -0,0 +1,23 @@
+
+USING: accessors effects.parser kernel lexer multi-methods
+       parser sequences words ;
+
+IN: multi-method-syntax
+
+! A nicer specializer syntax to hold us over till multi-methods go in
+! officially.
+!
+! Use both 'multi-methods' and 'multi-method-syntax' in that order.
+
+: scan-specializer ( -- specializer )
+
+  scan drop ! eat opening parenthesis
+
+  ")" parse-effect in>> [ search ] map ;
+
+: CREATE-METHOD ( -- method )
+  scan-word scan-specializer swap create-method-in ;
+
+: (METHOD:) ( -- method def ) CREATE-METHOD parse-definition ;
+
+: METHOD: (METHOD:) define ; parsing
\ No newline at end of file
diff --git a/extra/pong/pong.factor b/extra/pong/pong.factor
new file mode 100644 (file)
index 0000000..befb64a
--- /dev/null
@@ -0,0 +1,195 @@
+
+USING: kernel accessors locals math math.intervals math.order
+       namespaces sequences threads
+       ui
+       ui.gadgets
+       ui.gestures
+       ui.render
+       calendar
+       multi-methods
+       multi-method-syntax
+       combinators.short-circuit.smart
+       combinators.cleave.enhanced
+       processing.shapes
+       flatland ;
+
+IN: pong
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: clamp-to-interval ( x interval -- x )
+  [ from>> first max ] [ to>> first min ] bi ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+TUPLE: <play-field> < <rectangle>    ;
+TUPLE: <paddle>     < <rectangle>    ;
+
+TUPLE: <computer>   < <paddle> { speed initial: 10 } ;
+
+: computer-move-left  ( computer -- ) dup speed>> move-left-by  ;
+: computer-move-right ( computer -- ) dup speed>> move-right-by ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+TUPLE: <ball> < <vel>
+  { diameter   initial: 20   }
+  { bounciness initial:  1.2 }
+  { max-speed  initial: 10   } ;
+
+: above-lower-bound? ( ball field -- ? ) bottom 50 - above? ;
+: below-upper-bound? ( ball field -- ? ) top    50 + below? ;
+
+: in-bounds? ( ball field -- ? )
+  {
+    [ above-lower-bound? ]
+    [ below-upper-bound? ]
+  } && ;
+
+:: bounce-change-vertical-velocity ( BALL -- )
+
+  BALL vel>> y neg
+  BALL bounciness>> *
+
+  BALL max-speed>> min
+
+  BALL vel>> (y!) ;
+
+:: bounce-off-paddle ( BALL PADDLE -- )
+
+   BALL bounce-change-vertical-velocity
+
+   BALL x   PADDLE center x   -   0.25 *   BALL vel>> (x!)
+
+   PADDLE top   BALL pos>> (y!) ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: mouse-x ( -- x ) hand-loc get first ;
+
+:: valid-paddle-interval ( PADDLE PLAY-FIELD -- interval )
+    
+   PLAY-FIELD [ left ] [ right ] bi PADDLE width - [a,b] ;
+
+:: align-paddle-with-mouse ( PADDLE PLAY-FIELD -- )
+
+   mouse-x
+
+   PADDLE PLAY-FIELD valid-paddle-interval
+
+   clamp-to-interval
+
+   PADDLE pos>> (x!) ;
+   
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! Protocol for drawing PONG objects
+
+GENERIC: draw ( obj -- )
+
+METHOD: draw ( <paddle> -- ) [ bottom-left ] [ dim>>          ] bi rectangle ;
+METHOD: draw ( <ball>   -- ) [ pos>>       ] [ diameter>> 2 / ] bi circle    ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+USE: syntax ! Switch back to core 'TUPLE:' instead of the one provided
+            ! by multi-methods
+
+TUPLE: <pong> < gadget draw closed ;
+
+M: <pong> pref-dim*    ( <pong> -- dim ) drop { 400 400 } ;
+M: <pong> draw-gadget* ( <pong> --     ) draw>> call      ;
+M: <pong> ungraft*     ( <pong> --     ) t >>closed drop  ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: make-draw-closure ( -- closure )
+
+  ! Establish some bindings
+
+  [let | PLAY-FIELD [ T{ <play-field> { pos {  0  0 } } { dim { 400 400 } } } ]
+         BALL       [ T{ <ball>       { pos { 50 50 } } { vel {   3   4 } } } ]
+
+         PLAYER   [ T{ <paddle>   { pos { 200 396 } } { dim { 75 4 } } } ]
+         COMPUTER [ T{ <computer> { pos { 200   0 } } { dim { 75 4 } } } ] |
+
+    ! Define some internal words in terms of those bindings ...
+
+    [wlet | align-player-with-mouse [ ( -- )
+              PLAYER PLAY-FIELD align-paddle-with-mouse ]
+
+            move-ball [ ( -- ) BALL 1 move-for ]
+
+            player-blocked-ball? [ ( -- ? )
+              BALL PLAYER { [ above? ] [ in-between-horizontally? ] } && ]
+
+            computer-blocked-ball? [ ( -- ? )
+              BALL COMPUTER { [ below? ] [ in-between-horizontally? ] } && ]
+
+            bounce-off-wall? [ ( -- ? )
+              BALL PLAY-FIELD in-between-horizontally? not ] |
+
+      ! Note, we're returning a quotation.
+      ! The quotation closes over the bindings established by the 'let'.
+      ! Thus the name of the word 'make-draw-closure'.
+      ! This closure is intended to be placed in the 'draw' slot of a
+      ! <pong> gadget.
+      
+      [
+
+        BALL PLAY-FIELD in-bounds?
+          [
+            align-player-with-mouse
+              
+            move-ball
+  
+            ! computer reaction
+  
+            BALL COMPUTER to-the-left-of?  [ COMPUTER computer-move-left  ] when
+            BALL COMPUTER to-the-right-of? [ COMPUTER computer-move-right ] when
+
+            ! check if ball bounced off something
+              
+            player-blocked-ball?   [ BALL PLAYER   bounce-off-paddle  ] when
+            computer-blocked-ball? [ BALL COMPUTER bounce-off-paddle  ] when
+            bounce-off-wall?       [ BALL reverse-horizontal-velocity ] when
+
+            ! draw the objects
+              
+            COMPUTER draw
+            PLAYER   draw
+            BALL     draw
+  
+          ]
+        when
+
+      ] ] ] ( -- closure ) ; ! The trailing stack effect here is a workaround.
+                             ! The stack effects in the wlet expression throw
+                             ! off the effect for the whole word, so we reset
+                             ! it to the correct one here.
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+:: pong-loop-step ( PONG -- ? )
+  PONG closed>>
+    [ f ]
+    [ PONG relayout-1 25 milliseconds sleep t ]
+  if ;
+
+:: start-pong-thread ( PONG -- ) [ [ PONG pong-loop-step ] loop ] in-thread ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: play-pong ( -- )
+
+  <pong> new-gadget
+    make-draw-closure >>draw
+  dup "PONG" open-window
+    
+  start-pong-thread ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: play-pong-main ( -- ) [ play-pong ] with-ui ;
+
+MAIN: play-pong-main
\ No newline at end of file
index a529762c81500a2d75cbab65007d207f40c6945f..002299fef17ef281ab7be7550f0508aee4dc020e 100644 (file)
@@ -1,6 +1,6 @@
 USING: kernel money tools.test
 taxes.usa taxes.usa.federal taxes.usa.mn
-taxes.utils taxes.usa.w4 usa-cities ;
+calendar taxes.usa.w4 usa-cities ;
 IN: taxes.usa.tests
 
 [
diff --git a/extra/taxes/utils/utils.factor b/extra/taxes/utils/utils.factor
deleted file mode 100644 (file)
index a5c2240..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-! Copyright (C) 2008 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: math ;
-IN: taxes.utils
-
-: monthly ( x -- y ) 12 / ;
-: semimonthly ( x -- y ) 24 / ;
-: biweekly ( x -- y ) 26 / ;
-: weekly ( x -- y ) 52 / ;
-: daily ( x -- y ) 360 / ;
index 4e22de60bcb761233099b57827907452e849744d..c2ae0f852076ba64257254f189b3c3f20f184644 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors furnace.actions http.server
-http.server.dispatchers html.forms io.servers.connection
+http.server.dispatchers html.forms io.sockets
 namespaces prettyprint ;
 IN: webapps.ip
 
index 2ffabf7de940b5d0c6595a5b153c657c747cbaa9..5f56072c1d950dfc729afa662162df1573fc180a 100644 (file)
@@ -36,6 +36,7 @@
 (require 'font-lock)
 (require 'comint)
 (require 'view)
+(require 'ring)
 
 ;;; Customization:
 
@@ -166,6 +167,15 @@ buffer."
   "Face for headlines in help buffers."
   :group 'factor-faces)
 
+\f
+;;; Compatibility
+(when (not (fboundp 'ring-member))
+  (defun ring-member (ring item)
+    (catch 'found
+      (dotimes (ind (ring-length ring) nil)
+        (when (equal item (ring-ref ring ind))
+          (throw 'found ind))))))
+
 \f
 ;;; Factor mode font lock:
 
@@ -179,7 +189,7 @@ buffer."
     "OCT:" "POSTPONE:" "PREDICATE:" "PRIMITIVE:" "PRIVATE>" "PROVIDE:"
     "REQUIRE:"  "REQUIRES:" "SINGLETON:" "SLOT:" "SYMBOL:" "SYMBOLS:"
     "TUPLE:" "T{" "t\\??" "TYPEDEF:"
-    "UNION:" "USE:" "USING:" "V{" "VAR:" "VARS:" "W{"))
+    "UNION:" "USE:" "USING:" "V{" "VARS:" "W{"))
 
 (defconst factor--regex-parsing-words-ext
   (regexp-opt '("B" "call-next-method" "delimiter" "f" "initial:" "read-only")
@@ -194,11 +204,14 @@ buffer."
 (defsubst factor--regex-second-word (prefixes)
   (format "^%s +\\([^ \r\n]+\\)" (regexp-opt prefixes t)))
 
+(defconst factor--regex-method-definition
+  "^M: +\\([^ ]+\\) +\\([^ ]+\\)")
+
 (defconst factor--regex-word-definition
-  (factor--regex-second-word '(":" "::" "M:" "GENERIC:")))
+  (factor--regex-second-word '(":" "::" "GENERIC:")))
 
 (defconst factor--regex-type-definition
-  (factor--regex-second-word '("TUPLE:")))
+  (factor--regex-second-word '("TUPLE:" "SINGLETON:")))
 
 (defconst factor--regex-parent-type "^TUPLE: +[^ ]+ +< +\\([^ ]+\\)")
 
@@ -207,7 +220,7 @@ buffer."
 (defconst factor--regex-setter "\\W>>[^ ]+\\b")
 
 (defconst factor--regex-symbol-definition
-  (factor--regex-second-word '("SYMBOL:")))
+  (factor--regex-second-word '("SYMBOL:" "VAR:")))
 
 (defconst factor--regex-stack-effect " ( .* )")
 
@@ -225,11 +238,12 @@ buffer."
     (,factor--regex-declaration-words 1 'factor-font-lock-declaration)
     (,factor--regex-word-definition 2 'factor-font-lock-word-definition)
     (,factor--regex-type-definition 2 'factor-font-lock-type-definition)
+    (,factor--regex-method-definition (1 'factor-font-lock-type-definition)
+                                      (2 'factor-font-lock-word-definition))
     (,factor--regex-parent-type 1 'factor-font-lock-type-definition)
     (,factor--regex-constructor . 'factor-font-lock-constructor)
     (,factor--regex-setter . 'factor-font-lock-setter-word)
     (,factor--regex-symbol-definition 2 'factor-font-lock-symbol-definition)
-    (,factor--regex-using-lines 1 'factor-font-lock-vocabulary-name)
     (,factor--regex-use-line 1 'factor-font-lock-vocabulary-name))
   "Font lock keywords definition for Factor mode.")
 
@@ -237,7 +251,7 @@ buffer."
 ;;; Factor mode syntax:
 
 (defconst factor--regex-definition-starters
-  (regexp-opt '("TUPLE" "MACRO" "MACRO:" "M" ":" "")))
+  (regexp-opt '("VARS" "TUPLE" "MACRO" "MACRO:" "M" ":" "")))
 
 (defconst factor--regex-definition-start
   (format "^\\(%s:\\) " factor--regex-definition-starters))
@@ -363,7 +377,8 @@ buffer."
 
 (defconst factor--regex-single-liner
   (format "^%s" (regexp-opt '("DEFER:" "GENERIC:" "IN:"
-                              "PRIVATE>" "<PRIVATE" "SYMBOL:" "USE:"))))
+                              "PRIVATE>" "<PRIVATE"
+                              "SINGLETON:" "SYMBOL:" "USE:" "VAR:"))))
 
 (defconst factor--regex-begin-of-def
   (format "^USING: \\|\\(%s\\)\\|\\(%s .*\\)"
@@ -475,7 +490,7 @@ buffer."
 (defvar factor-mode-map (make-sparse-keymap)
   "Key map used by Factor mode.")
 
-(defsubst factor--beginning-of-defun (times)
+(defsubst factor--beginning-of-defun (&optional times)
   (re-search-backward factor--regex-begin-of-def nil t times))
 
 (defsubst factor--end-of-defun ()
@@ -625,7 +640,43 @@ buffer."
   (factor--with-vocab vocab
     (factor--listener-send-cmd cmd)))
 
-;;;;; Interface: see
+\f
+;;;;; Buffer cycling and docs
+
+
+(defconst factor--cycle-endings
+  '(".factor" "-tests.factor" "-docs.factor"))
+
+(defconst factor--regex-cycle-endings
+  (format "\\(.*?\\)\\(%s\\)$"
+          (regexp-opt factor--cycle-endings)))
+
+(defconst factor--cycle-endings-ring
+  (let ((ring (make-ring (length factor--cycle-endings))))
+    (dolist (e factor--cycle-endings ring)
+      (ring-insert ring e))))
+
+(defun factor--cycle-next (file)
+  (let* ((match (string-match factor--regex-cycle-endings file))
+         (base (and match (match-string-no-properties 1 file)))
+         (ending (and match (match-string-no-properties 2 file)))
+         (idx (and ending (ring-member factor--cycle-endings-ring ending)))
+         (gfl (lambda (i) (concat base (ring-ref factor--cycle-endings-ring i)))))
+    (if (not idx) file
+      (let ((l (length factor--cycle-endings)) (i 1) next)
+        (while (and (not next) (< i l))
+          (when (file-exists-p (funcall gfl (+ idx i)))
+            (setq next (+ idx i)))
+          (setq i (1+ i)))
+        (funcall gfl (or next idx))))))
+
+(defun factor-visit-other-file (&optional file)
+  "Cycle between code, tests and docs factor files."
+  (interactive)
+  (find-file (factor--cycle-next (or file (buffer-file-name)))))
+
+\f
+;;;;; Interface: See
 
 (defconst factor--regex-error-marker "^Type :help for debugging")
 (defconst factor--regex-data-stack "^--- Data stack:")
@@ -848,6 +899,7 @@ vocabularies which have been modified on disk."
 (factor--define-key ?s 'factor-see t)
 (factor--define-key ?e 'factor-edit)
 (factor--define-key ?z 'switch-to-factor t)
+(factor--define-key ?o 'factor-visit-other-file)
 (factor--define-key ?c 'comment-region)
 
 (factor--define-auto-indent-key ?\])
diff --git a/unmaintained/lisp/authors.txt b/unmaintained/lisp/authors.txt
new file mode 100644 (file)
index 0000000..4b7af4a
--- /dev/null
@@ -0,0 +1 @@
+James Cash
diff --git a/unmaintained/lisp/lisp-docs.factor b/unmaintained/lisp/lisp-docs.factor
new file mode 100644 (file)
index 0000000..c970a1e
--- /dev/null
@@ -0,0 +1,22 @@
+IN: lisp
+USING: help.markup help.syntax ;
+HELP: <LISP
+{ $description "parsing word which converts the lisp code between <LISP and LISP> into factor quotations and calls it" }
+{ $see-also lisp-string>factor } ;
+
+HELP: lisp-string>factor
+{ $values { "str"  "a string of lisp code" } { "quot" "the quotation the lisp compiles into" } }
+{ $description "Turns a string of lisp into a factor quotation" } ;
+
+ARTICLE: "lisp" "Lisp in Factor"
+"This is a simple implementation of a Lisp dialect, which somewhat resembles Scheme." $nl
+"It works in two main stages: "
+{ $list
+  { "Parse (via "  { $vocab-link "lisp.parser" } " the Lisp code into a "
+    { $snippet "s-exp"  } " tuple." }
+  { "Transform the " { $snippet "s-exp" } " into a Factor quotation, via " { $link convert-form } }
+}
+
+{ $subsection "lisp.parser" } ;
+
+ABOUT: "lisp"
\ No newline at end of file
diff --git a/unmaintained/lisp/lisp-tests.factor b/unmaintained/lisp/lisp-tests.factor
new file mode 100644 (file)
index 0000000..5f849c4
--- /dev/null
@@ -0,0 +1,94 @@
+! Copyright (C) 2008 James Cash
+! See http://factorcode.org/license.txt for BSD license.
+USING: lisp lisp.parser tools.test sequences math kernel parser arrays lists
+quotations ;
+
+IN: lisp.test
+
+[
+    define-lisp-builtins
+    
+    { 5 } [
+        "(+ 2 3)" lisp-eval
+    ] unit-test
+    
+    { 8.3 } [
+        "(- 10.4 2.1)" lisp-eval
+    ] unit-test
+    
+    { 3 } [
+        "((lambda (x y) (+ x y)) 1 2)" lisp-eval
+    ] unit-test
+    
+    { 42 } [
+        "((lambda (x y z) (+ x (- y z))) 40 3 1)" lisp-eval
+    ] unit-test
+    
+    { "b" } [
+        "(cond (#f \"a\") (#t \"b\"))" lisp-eval
+    ] unit-test
+    
+    { "b" } [
+        "(cond ((< 1 2) \"b\") (#t \"a\"))" lisp-eval
+    ] unit-test
+        
+    { +nil+ } [
+        "(list)" lisp-eval
+    ] unit-test
+    
+    { { 1 2 3 4 5 } } [
+        "(list 1 2 3 4 5)" lisp-eval list>seq
+    ] unit-test
+    
+    { { 1 2 { 3 { 4 } 5 } } } [
+        "(list 1 2 (list 3 (list 4) 5))" lisp-eval cons>seq
+    ] unit-test
+    
+    { 5 } [
+        "(begin (+ 1 4))" lisp-eval
+    ] unit-test
+    
+    { 5 } [
+        "(begin (+ 5 6) (+ 1 4))" lisp-eval
+    ] unit-test
+    
+    { t } [
+        T{ lisp-symbol f "if" } lisp-macro?
+    ] unit-test
+    
+    { 1 } [
+        "(if #t 1 2)" lisp-eval
+    ] unit-test
+    
+    { 3 } [
+        "((lambda (x) (if x (+ 1 2) (- 3 5))) #t)" lisp-eval
+    ] unit-test
+    
+    { { 5 4 3 } } [
+        "((lambda (x &rest xs) (cons x xs)) 5 4 3)" lisp-eval cons>seq
+    ] unit-test
+    
+    { { 5 } } [
+        "((lambda (x &rest xs) (cons x xs)) 5)" lisp-eval cons>seq
+    ] unit-test
+    
+    { { 1 2 3 4 } } [
+        "((lambda (&rest xs) xs) 1 2 3 4)" lisp-eval cons>seq
+    ] unit-test
+    
+    { 10 } [
+        <LISP (begin (+ 1 2) (+ 9 1)) LISP>
+    ] unit-test
+    
+    { 4 } [
+        <LISP ((lambda (x y) (if x (+ 1 y) (+ 2 y))) #t 3) LISP>
+    ] unit-test
+    
+    { { 3 3 4 } } [
+        <LISP (defun foo (x y &rest z)
+                  (cons (+ x y) z))
+              (foo 1 2 3 4)
+        LISP> cons>seq
+    ] unit-test
+    
+] with-interactive-vocabs
diff --git a/unmaintained/lisp/lisp.factor b/unmaintained/lisp/lisp.factor
new file mode 100644 (file)
index 0000000..4a93350
--- /dev/null
@@ -0,0 +1,178 @@
+! Copyright (C) 2008 James Cash
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel peg sequences arrays strings 
+namespaces combinators math locals locals.private locals.backend accessors
+vectors syntax lisp.parser assocs parser words
+quotations fry lists summary combinators.short-circuit continuations multiline ;
+IN: lisp
+
+DEFER: convert-form
+DEFER: funcall
+DEFER: lookup-var
+DEFER: lookup-macro
+DEFER: lisp-macro?
+DEFER: lisp-var?
+DEFER: define-lisp-macro
+
+! Functions to convert s-exps to quotations
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+: convert-body ( cons -- quot )
+    [ ] [ convert-form compose ] foldl ; inline
+
+: convert-cond ( cons -- quot )
+    cdr [ 2car [ convert-form ] bi@ 2array ]
+    { } lmap-as '[ _ cond ] ;
+
+: convert-general-form ( cons -- quot )
+    uncons [ convert-body ] [ convert-form ] bi* '[ _ @ funcall ] ;
+
+! words for convert-lambda
+<PRIVATE
+: localize-body ( assoc body -- newbody )
+    {
+      { [ dup list? ] [ [ lisp-symbol? ] rot '[ [ name>> _ at ] [ ] bi or ] traverse ] }
+      { [ dup lisp-symbol? ] [ name>> swap at ] }
+     [ nip ]
+    } cond ;
+
+: localize-lambda ( body vars -- newvars newbody )
+    swap [ make-locals dup push-locals ] dip
+    dupd [ localize-body convert-form ] with lmap>array
+    >quotation swap pop-locals ;
+
+: split-lambda ( cons -- body-cons vars-seq )
+    cdr uncons [ name>> ] lmap>array ; inline
+
+: rest-lambda ( body vars -- quot )
+    "&rest" swap [ remove ] [ index ] 2bi
+    [ localize-lambda <lambda> lambda-rewrite call ] dip
+    swap '[ _ cut '[ @ _ seq>list ] call _ call call ] 1quotation ;
+
+: normal-lambda ( body vars -- quot )
+    localize-lambda <lambda> lambda-rewrite '[ @ compose call call ] 1quotation ;
+PRIVATE>
+
+: convert-lambda ( cons -- quot )
+    split-lambda "&rest" over member? [ rest-lambda ] [ normal-lambda ] if ;
+
+: convert-quoted ( cons -- quot )
+    cadr 1quotation ;
+
+: convert-defmacro ( cons -- quot )
+    cdr [ convert-lambda ] [ car name>> ] bi define-lisp-macro [ ] ;
+
+: macro-expand ( cons -- quot )
+    uncons [ list>seq >quotation ] [ lookup-macro ] bi* call call ;
+
+: expand-macros ( cons -- cons )
+    dup list? [ [ expand-macros ] lmap dup car lisp-macro? [ macro-expand expand-macros ] when ] when ;
+    
+: convert-begin ( cons -- quot )
+    cdr [ convert-form ] [ ] lmap-as [ 1 tail* ] [ but-last ] bi
+    [ '[ { } _ with-datastack drop ] ] map prepend '[ _ [ call ] each ] ;
+
+: form-dispatch ( cons lisp-symbol -- quot )
+    name>>
+    { { "lambda" [ convert-lambda ] }
+      { "defmacro" [ convert-defmacro ] }
+      { "quote" [ convert-quoted ] }
+      { "cond" [ convert-cond ] }
+      { "begin" [ convert-begin ] }
+     [ drop convert-general-form ]
+    } case ;
+
+: convert-list-form ( cons -- quot )
+    dup car
+    {
+      { [ dup lisp-symbol? ] [ form-dispatch ] }
+     [ drop convert-general-form ]
+    } cond ;
+
+: convert-form ( lisp-form -- quot )
+    {
+      { [ dup cons? ] [ convert-list-form ] }
+      { [ dup lisp-var? ] [ lookup-var 1quotation ] }
+      { [ dup lisp-symbol? ] [ '[ _ lookup-var ] ] }
+     [ 1quotation ]
+    } cond ;
+
+: lisp-string>factor ( str -- quot )
+    lisp-expr expand-macros convert-form ;
+
+: lisp-eval ( str -- * )
+    lisp-string>factor call ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+SYMBOL: lisp-env
+SYMBOL: macro-env
+
+ERROR: no-such-var variable-name ;
+M: no-such-var summary drop "No such variable" ;
+
+: init-env ( -- )
+    H{ } clone lisp-env set
+    H{ } clone macro-env set ;
+
+: lisp-define ( quot name -- )
+    lisp-env get set-at ;
+    
+: define-lisp-var ( lisp-symbol body --  )
+    swap name>> lisp-define ;
+
+: lisp-get ( name -- word )
+    lisp-env get at ;
+
+: lookup-var ( lisp-symbol -- quot )
+    [ name>> ] [ lisp-var? ] bi [ lisp-get ] [ no-such-var ] if ;
+
+: lisp-var? ( lisp-symbol -- ? )
+    dup lisp-symbol? [ name>> lisp-env get key? ] [ drop f ] if ;
+
+: funcall ( quot sym -- * )
+    [ 1array [ call ] with-datastack >quotation ] dip curry call ; inline
+
+: define-primitive ( name vocab word -- )
+    swap lookup 1quotation '[ _ compose call ] swap lisp-define ;
+
+: lookup-macro ( lisp-symbol -- lambda )
+    name>> macro-env get at ;
+
+: define-lisp-macro ( quot name -- )
+    macro-env get set-at ;
+
+: lisp-macro? ( car -- ? )
+    dup lisp-symbol? [ name>> macro-env get key? ] [ drop f ] if ;
+
+: define-lisp-builtins ( -- )
+   init-env
+
+   f "#f" lisp-define
+   t "#t" lisp-define
+
+   "+" "math" "+" define-primitive
+   "-" "math" "-" define-primitive
+   "<" "math" "<" define-primitive
+   ">" "math" ">" define-primitive
+
+   "cons" "lists" "cons" define-primitive
+   "car" "lists" "car" define-primitive
+   "cdr" "lists" "cdr" define-primitive
+   "append" "lists" "lappend" define-primitive
+   "nil" "lists" "nil" define-primitive
+   "nil?" "lists" "nil?" define-primitive
+
+   "set" "lisp" "define-lisp-var" define-primitive
+    
+   "(set 'list (lambda (&rest xs) xs))" lisp-eval
+   "(defmacro setq (var val) (list 'set (list 'quote var) val))" lisp-eval
+    
+   <" (defmacro defun (name vars &rest body)
+        (list 'setq name (cons 'lambda (cons vars body)))) "> lisp-eval
+    
+   "(defmacro if (pred tr fl) (list 'cond (list pred tr) (list (quote #t) fl)))" lisp-eval
+   ;
+
+: <LISP 
+    "LISP>" parse-multiline-string "(begin " prepend ")" append define-lisp-builtins
+    lisp-string>factor parsed \ call parsed ; parsing
\ No newline at end of file
diff --git a/unmaintained/lisp/parser/authors.txt b/unmaintained/lisp/parser/authors.txt
new file mode 100644 (file)
index 0000000..4b7af4a
--- /dev/null
@@ -0,0 +1 @@
+James Cash
diff --git a/unmaintained/lisp/parser/parser-docs.factor b/unmaintained/lisp/parser/parser-docs.factor
new file mode 100644 (file)
index 0000000..fc16a0a
--- /dev/null
@@ -0,0 +1,6 @@
+IN: lisp.parser
+USING: help.markup help.syntax ;
+
+ARTICLE: "lisp.parser" "Parsing strings of Lisp"
+"This vocab uses " { $vocab-link "peg.ebnf" } " to turn strings of Lisp into " { $snippet "s-exp" } "s, which are then used by"
+{ $vocab-link "lisp" } " to produce Factor quotations." ;
\ No newline at end of file
diff --git a/unmaintained/lisp/parser/parser-tests.factor b/unmaintained/lisp/parser/parser-tests.factor
new file mode 100644 (file)
index 0000000..911a8d3
--- /dev/null
@@ -0,0 +1,80 @@
+! Copyright (C) 2008 James Cash
+! See http://factorcode.org/license.txt for BSD license.
+USING: lisp.parser tools.test peg peg.ebnf lists ;
+
+IN: lisp.parser.tests
+
+{ 1234  }  [
+  "1234" "atom" \ lisp-expr rule parse
+] unit-test
+
+{ -42  }  [
+    "-42" "atom" \ lisp-expr rule parse
+] unit-test
+
+{ 37/52 } [
+    "37/52" "atom" \ lisp-expr rule parse
+] unit-test
+
+{ 123.98 } [
+    "123.98" "atom" \ lisp-expr rule parse
+] unit-test
+
+{ "" } [
+    "\"\"" "atom" \ lisp-expr rule parse
+] unit-test
+
+{ "aoeu" } [
+    "\"aoeu\"" "atom" \ lisp-expr rule parse
+] unit-test
+
+{ "aoeu\"de" } [
+    "\"aoeu\\\"de\"" "atom" \ lisp-expr rule parse
+] unit-test
+
+{ T{ lisp-symbol f "foobar" } } [
+    "foobar" "atom" \ lisp-expr rule parse
+] unit-test
+
+{ T{ lisp-symbol f "+" } } [
+    "+" "atom" \ lisp-expr rule parse
+] unit-test
+
+{ +nil+ } [
+    "()" lisp-expr
+] unit-test
+
+{ T{
+    cons
+    f
+    T{ lisp-symbol f "foo" }
+    T{
+        cons
+        f
+        1
+        T{ cons f 2 T{ cons f "aoeu" +nil+ } }
+    } } } [
+    "(foo 1 2 \"aoeu\")" lisp-expr
+] unit-test
+
+{ T{ cons f
+       1
+       T{ cons f
+           T{ cons f 3 T{ cons f 4 +nil+ } }
+           T{ cons f 2 +nil+ } }
+   }
+} [
+    "(1 (3 4) 2)" lisp-expr
+] unit-test
+    
+{ { T{ lisp-symbol { name "quote" } } { 1 2 3 } } } [
+    "'(1 2 3)" lisp-expr cons>seq
+] unit-test
+    
+{ { T{ lisp-symbol f "quote" } T{ lisp-symbol f "foo" } } } [
+    "'foo" lisp-expr cons>seq
+] unit-test
+    
+{ { 1 2 { T{ lisp-symbol { name "quote" } } { 3 4 } } 5 } } [
+    "(1 2 '(3 4) 5)" lisp-expr cons>seq
+] unit-test
\ No newline at end of file
diff --git a/unmaintained/lisp/parser/parser.factor b/unmaintained/lisp/parser/parser.factor
new file mode 100644 (file)
index 0000000..50f5869
--- /dev/null
@@ -0,0 +1,41 @@
+! Copyright (C) 2008 James Cash
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel peg peg.ebnf math.parser sequences arrays strings
+math fry accessors lists combinators.short-circuit ;
+
+IN: lisp.parser
+
+TUPLE: lisp-symbol name ;
+C: <lisp-symbol> lisp-symbol
+
+EBNF: lisp-expr
+_            = (" " | "\t" | "\n")*
+LPAREN       = "("
+RPAREN       = ")"
+dquote       = '"'
+squote       = "'"
+digit        = [0-9]
+integer      = ("-")? (digit)+                           => [[ first2 append string>number ]]
+float        = integer "." (digit)*                      => [[ first3 >string [ number>string ] 2dip 3append string>number ]]
+rational     = integer "/" (digit)+                      => [[ first3 nip string>number / ]]
+number       = float
+              | rational
+              | integer
+id-specials  = "!" | "$" | "%" | "&" | "*" | "/" | ":"
+              | "<" | "#" | " =" | ">" | "?" | "^" | "_"
+              | "~" | "+" | "-" | "." | "@"
+letters      = [a-zA-Z]                                  => [[ 1array >string ]]
+initials     = letters | id-specials
+numbers      = [0-9]                                     => [[ 1array >string ]]
+subsequents  = initials | numbers
+identifier   = initials (subsequents)*                   => [[ first2 concat append <lisp-symbol> ]]
+escaped      = "\" .                                     => [[ second ]]
+string       = dquote ( escaped | !(dquote) . )*  dquote => [[ second >string ]]
+atom         = number
+              | identifier
+              | string
+s-expression = LPAREN (list-item)* RPAREN                => [[ second seq>cons ]]
+list-item    = _ ( atom | s-expression | quoted ) _      => [[ second ]]
+quoted       = squote list-item                          => [[ second nil cons "quote" <lisp-symbol> swap cons ]]
+expr         = list-item
+;EBNF
\ No newline at end of file
diff --git a/unmaintained/lisp/parser/summary.txt b/unmaintained/lisp/parser/summary.txt
new file mode 100644 (file)
index 0000000..aa407b3
--- /dev/null
@@ -0,0 +1 @@
+EBNF grammar for parsing Lisp
diff --git a/unmaintained/lisp/parser/tags.txt b/unmaintained/lisp/parser/tags.txt
new file mode 100644 (file)
index 0000000..d1f6fa1
--- /dev/null
@@ -0,0 +1,2 @@
+lisp
+parsing
diff --git a/unmaintained/lisp/summary.txt b/unmaintained/lisp/summary.txt
new file mode 100644 (file)
index 0000000..7277c2a
--- /dev/null
@@ -0,0 +1 @@
+A Lisp interpreter/compiler in Factor 
diff --git a/unmaintained/lisp/tags.txt b/unmaintained/lisp/tags.txt
new file mode 100644 (file)
index 0000000..c369cca
--- /dev/null
@@ -0,0 +1,2 @@
+lisp
+languages
index 17db7422110d60ddb4d320023b2abb7becfe5312..4cf997a51534d2652259f970ae775173889c277d 100755 (executable)
@@ -18,12 +18,12 @@ add_overflow:
        b MANGLE(overflow_fixnum_add)
 
 DEF(void,primitive_fixnum_subtract,(void)):
-    lwz r3,0(DS_REG)
-    lwz r4,-4(DS_REG)
+    lwz r3,-4(DS_REG)
+    lwz r4,0(DS_REG)
     subi DS_REG,DS_REG,4
     li r0,0
     mtxer r0
-    subfo. r5,r3,r4
+    subfo. r5,r4,r3
        bso sub_overflow
     stw r5,0(DS_REG)
     blr
index 97b1b39129e8e92b4d05762c388994c9f7c7f144..b2a1735fd798ea6dd14592de8b2fa24f44bfdccd 100755 (executable)
@@ -23,6 +23,7 @@ typedef char F_SYMBOL;
 #define STRNCMP strncmp
 #define STRDUP strdup
 
+#define FIXNUM_FORMAT "%ld"
 #define CELL_FORMAT "%lu"
 #define CELL_HEX_FORMAT "%lx"
 
index b12d677af2bd1f5ae9d0b47055ffab3bb757e6ba..af9b75bca5c931d1028c629ac666eb113c227b29 100755 (executable)
@@ -20,13 +20,13 @@ typedef wchar_t F_CHAR;
 #define STRNCMP wcsncmp
 #define STRDUP _wcsdup
 
+#define FIXNUM_FORMAT "%Id"
+#define CELL_FORMAT "%lu"
+#define CELL_HEX_FORMAT "%Ix"
+
 #ifdef WIN64
-        #define CELL_FORMAT "%Iu"
-        #define CELL_HEX_FORMAT "%Ix"
        #define CELL_HEX_PAD_FORMAT "%016Ix"
 #else
-        #define CELL_FORMAT "%lu"
-        #define CELL_HEX_FORMAT "%lx"
        #define CELL_HEX_PAD_FORMAT "%08lx"
 #endif
 
index 35fc7ad087f19f1e726e006c00bb9e336f1352c0..d97b540884b8a7e3bab9a38598d4d548151e14d5 100755 (executable)
@@ -44,7 +44,7 @@ void print_cell_hex_pad(CELL x)
 
 void print_fixnum(F_FIXNUM x)
 {
-       printf(CELL_FORMAT,x);
+       printf(FIXNUM_FORMAT,x);
 }
 
 CELL read_cell_hex(void)