Created
August 24, 2018 18:28
-
-
Save erg/2b9f655c3bbc82661573cd3fd93736bb to your computer and use it in GitHub Desktop.
factor-unmaintained
This file has been truncated, but you can view the full file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
! command | |
! ../factor-master/factor ../factor-master/basis/tools/directory-to-file/directory-to-file.factor . | |
<GIT-REPOSITORY: github.com/factor/factor-unmaintained | |
FILE: [[sudokus/summary.txt]] [[graphical sudoku solver]] | |
FILE: [[sudokus/authors.txt]] [[Sam Anklesaria | |
]] | |
FILE: [[sudokus/sudokus.factor]] [[USING: accessors arrays combinators.short-circuit grouping kernel lists | |
lists.lazy locals math math.functions math.parser math.ranges | |
models.product monads random sequences sets ui ui.gadgets.controls | |
ui.gadgets.layout models.combinators ui.gadgets.alerts vectors fry | |
ui.gadgets.labels shuffle ; | |
IN: sudokus | |
: row ( index -- row ) 1 + 9 / ceiling ; | |
: col ( index -- col ) 9 mod 1 + ; | |
: sq ( index -- square ) [ row ] [ col ] bi [ 3 / ceiling ] bi@ 2array ; | |
: near ( a pos -- ? ) { [ [ row ] same? ] [ [ col ] same? ] [ [ sq ] same? ] } 2|| ; | |
: nth-or-lower ( n seq -- elt ) [ length 1 - 2dup > [ nip ] [ drop ] if ] keep nth ; | |
:: solutions ( puzzle random? -- solutions ) | |
f puzzle random? [ indices [ f ] [ random? swap nth-or-lower ] if-empty ] [ index ] if | |
[ :> pos | |
1 9 [a,b] 80 <iota> [ pos near ] filter [ puzzle nth ] map prune diff | |
[ 1array puzzle pos cut-slice rest surround ] map >list [ random? solutions ] bind | |
] [ puzzle list-monad return ] if* ; | |
: solution ( puzzle random? -- solution ) dupd solutions dup +nil+ = [ drop "Unsolvable" alert* ] [ nip car ] if ; | |
: hint ( puzzle -- puzzle' ) [ [ f swap indices random dup ] [ f solution ] bi nth ] keep swapd >vector [ set-nth ] keep ; | |
: create ( difficulty -- puzzle ) 81 [ f ] replicate | |
40 random solution [ [ f swap [ length random ] keep set-nth ] curry times ] keep ; | |
: do-sudoku ( -- ) [ [ | |
[ | |
81 [ "" ] replicate <basic> switch-models [ [ <basic> ] map 9 group [ 3 group ] map 3 group | |
[ [ [ <spacer> [ [ <model-field> ->% 2 [ string>number ] fmap ] | |
map <spacer> ] map concat ] <hbox> , ] map concat <spacer> ] map concat <product> | |
[ "Difficulty:" <label> , "1" <basic> <model-field> -> [ string>number 1 or 1 + 10 * ] fmap | |
"Generate" <model-border-btn> -> updates [ create ] fmap <spacer> | |
"Hint" <model-border-btn> -> "Solve" <model-border-btn> -> ] <hbox> , | |
roll [ swap updates ] curry bi@ | |
[ [ hint ] fmap ] [ [ f solution ] fmap ] bi* 3array merge [ [ [ number>string ] [ "" ] if* ] map ] fmap | |
] bind | |
] with-self , ] <vbox> { 280 220 } >>pref-dim | |
"Sudoku Sleuth" open-window ] with-ui ; | |
MAIN: do-sudoku | |
]] | |
FILE: [[random-weighted/authors.txt]] [[Eduardo Cavazos | |
]] | |
FILE: [[random-weighted/random-weighted.factor]] [[ | |
USING: kernel namespaces arrays quotations sequences assocs combinators | |
mirrors math math.vectors random macros fry ; | |
IN: random-weighted | |
: probabilities ( weights -- probabilities ) dup sum v/n ; | |
: layers ( probabilities -- layers ) | |
dup length 1+ [ head ] with map rest [ sum ] map ; | |
: random-weighted ( weights -- elt ) | |
probabilities layers [ 1000 * ] map 1000 random [ > ] curry find drop ; | |
: random-weighted* ( seq -- elt ) | |
dup [ second ] map swap [ first ] map random-weighted swap nth ; | |
MACRO: call-random-weighted ( exp -- ) | |
[ keys ] [ values <enum> >alist ] bi | |
'[ _ random-weighted _ case ] ; | |
]] | |
FILE: [[ui/offscreen/offscreen-docs.factor]] [[! Copyright (C) 2008 Joe Groff. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: help.markup help.syntax kernel quotations ui.gadgets | |
images strings ui.gadgets.worlds ; | |
IN: ui.offscreen | |
HELP: <offscreen-world> | |
{ $values | |
{ "gadget" gadget } { "title" string } { "status" "a boolean" } | |
{ "world" offscreen-world } | |
} | |
{ $description "Constructs an " { $link offscreen-world } " gadget with " { $snippet "gadget" } " as its only child. Generally you should use " { $link open-offscreen } " or " { $link do-offscreen } " instead of calling this word directly." } ; | |
HELP: close-offscreen | |
{ $values | |
{ "world" offscreen-world } | |
} | |
{ $description "Releases the resources used by the rendering buffer for " { $snippet "world" } "." } ; | |
HELP: do-offscreen | |
{ $values | |
{ "gadget" gadget } { "quot" quotation } | |
} | |
{ $description "Constructs an " { $link offscreen-world } " around " { $snippet "gadget" } " with " { $link open-offscreen } ", calls " { $snippet "quotation" } " with the world on the top of the stack, and cleans up the world with " { $link close-offscreen } " at the end of " { $snippet "quotation" } "." } ; | |
HELP: gadget>bitmap | |
{ $values | |
{ "gadget" gadget } | |
{ "image" image } | |
} | |
{ $description "Renders " { $snippet "gadget" } " to an " { $link offscreen-world } " and creates an " { $link image } " from its contents." } ; | |
HELP: offscreen-world | |
{ $class-description "The class of " { $link world } " objects that render to an offscreen buffer." } ; | |
HELP: offscreen-world>bitmap | |
{ $values | |
{ "world" offscreen-world } | |
{ "image" image } | |
} | |
{ $description "Saves a copy of the contents of " { $snippet "world" } " to a " { $link image } " object." } ; | |
HELP: open-offscreen | |
{ $values | |
{ "gadget" gadget } | |
{ "world" offscreen-world } | |
} | |
{ $description "Creates and sets up an " { $link offscreen-world } " with " { $snippet "gadget" } " as its only child." } ; | |
{ offscreen-world open-offscreen close-offscreen do-offscreen } related-words | |
ARTICLE: "ui.offscreen" "Offscreen UI rendering" | |
"The " { $vocab-link "ui.offscreen" } " provides words for rendering gadgets to an offscreen buffer so that bitmaps can be made from their contents." | |
{ $subsections offscreen-world } | |
"Opening gadgets offscreen:" | |
{ $subsections | |
open-offscreen | |
close-offscreen | |
do-offscreen | |
} | |
"Creating bitmaps from offscreen buffers:" | |
{ $subsections | |
offscreen-world>bitmap | |
gadget>bitmap | |
} ; | |
ABOUT: "ui.offscreen" | |
]] | |
FILE: [[ui/offscreen/summary.txt]] [[Offscreen world gadgets for rendering UI elements to bitmaps | |
]] | |
FILE: [[ui/offscreen/offscreen.factor]] [[! (c) 2008 Joe Groff, see license for details | |
USING: accessors alien.c-types continuations images kernel math | |
sequences ui.gadgets ui.gadgets.private ui.gadgets.worlds | |
ui.private ui ui.backend destructors locals ; | |
IN: ui.offscreen | |
TUPLE: offscreen-world < world ; | |
M: offscreen-world world-pixel-format-attributes | |
{ offscreen T{ depth-bits { value 16 } } } ; | |
: <offscreen-world> ( gadget title status -- world ) | |
offscreen-world new-world ; | |
M: offscreen-world graft* | |
(open-offscreen-buffer) ; | |
M: offscreen-world ungraft* | |
[ (ungraft-world) ] | |
[ handle>> (close-offscreen-buffer) ] | |
[ reset-world ] tri ; | |
: open-offscreen ( gadget -- world ) | |
"" f <offscreen-world> | |
[ open-world-window ] [ relayout-1 ] [ ] tri | |
notify-queued ; | |
: close-offscreen ( world -- ) | |
ungraft notify-queued ; | |
:: bgrx>bitmap ( alien w h -- image ) | |
<image> | |
{ w h } >>dim | |
alien w h * 4 * memory>byte-array >>bitmap | |
BGRX >>component-order ; | |
: offscreen-world>bitmap ( world -- image ) | |
offscreen-pixels bgrx>bitmap ; | |
: do-offscreen ( gadget quot: ( offscreen-world -- ) -- ) | |
[ open-offscreen ] dip | |
over [ slip ] [ close-offscreen ] [ ] cleanup ; inline | |
: gadget>bitmap ( gadget -- image ) | |
[ offscreen-world>bitmap ] do-offscreen ; | |
]] | |
FILE: [[ui/offscreen/authors.txt]] [[Joe Groff | |
]] | |
FILE: [[ui/offscreen/tags.txt]] [[ui | |
graphics | |
]] | |
FILE: [[ui/gadgets/cartesian/cartesian.factor]] [[ | |
USING: kernel combinators sequences opengl.gl | |
ui.render ui.gadgets ui.gadgets.slate | |
accessors ; | |
IN: ui.gadgets.cartesian | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
TUPLE: cartesian < slate x-min x-max y-min y-max z-min z-max perspective ; | |
: init-cartesian ( cartesian -- cartesian ) | |
init-slate | |
-10 >>x-min | |
10 >>x-max | |
-10 >>y-min | |
10 >>y-max | |
-1 >>z-min | |
1 >>z-max ; | |
: <cartesian> ( -- cartesian ) cartesian new init-cartesian ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
M: cartesian establish-coordinate-system ( cartesian -- cartesian ) | |
dup | |
{ | |
[ x-min>> ] [ x-max>> ] | |
[ y-min>> ] [ y-max>> ] | |
[ z-min>> ] [ z-max>> ] | |
} | |
cleave | |
glOrtho ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: x-range ( cartesian range -- cartesian ) first2 [ >>x-min ] [ >>x-max ] bi* ; | |
: y-range ( cartesian range -- cartesian ) first2 [ >>y-min ] [ >>y-max ] bi* ; | |
: z-range ( cartesian range -- cartesian ) first2 [ >>z-min ] [ >>z-max ] bi* ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
]] | |
FILE: [[ui/gadgets/tabs/tabs.factor]] [[! Copyright (C) 2008 William Schlieper | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: accessors kernel fry math math.vectors sequences arrays vectors assocs | |
hashtables models models.range models.product combinators | |
ui ui.gadgets ui.gadgets.buttons ui.gadgets.frames ui.gadgets.packs | |
ui.gadgets.grids ui.gadgets.viewports ui.gadgets.books locals ; | |
IN: ui.gadgets.tabs | |
TUPLE: tabbed < frame names toggler content ; | |
DEFER: (del-page) | |
:: add-toggle ( n name model toggler -- ) | |
<frame> | |
n name toggler parent>> '[ drop _ _ _ (del-page) ] "X" swap <bevel-button> | |
@right grid-add | |
n model name <toggle-button> @center grid-add | |
toggler swap add-gadget drop ; | |
: redo-toggler ( tabbed -- ) | |
[ names>> ] [ model>> ] [ toggler>> ] tri | |
[ clear-gadget ] keep | |
[ [ length ] keep ] 2dip | |
'[ _ _ add-toggle ] 2each ; | |
: refresh-book ( tabbed -- ) | |
model>> [ ] change-model ; | |
: (del-page) ( n name tabbed -- ) | |
{ [ [ remove ] change-names redo-toggler ] | |
[ dupd [ names>> length ] [ model>> ] bi | |
[ [ = ] keep swap [ 1- ] when | |
[ < ] keep swap [ 1- ] when ] change-model ] | |
[ content>> nth-gadget unparent ] | |
[ refresh-book ] | |
} cleave ; | |
: add-page ( page name tabbed -- ) | |
[ names>> push ] 2keep | |
[ [ names>> length 1 - swap ] | |
[ model>> ] | |
[ toggler>> ] tri add-toggle ] | |
[ content>> swap add-gadget drop ] | |
[ refresh-book ] tri ; | |
: del-page ( name tabbed -- ) | |
[ names>> index ] 2keep (del-page) ; | |
: new-tabbed ( assoc class -- tabbed ) | |
new-frame | |
0 <model> >>model | |
<pile> 1 >>fill >>toggler | |
dup toggler>> @left grid-add | |
swap | |
[ keys >vector >>names ] | |
[ values over model>> <book> >>content dup content>> @center grid-add ] | |
bi | |
dup redo-toggler ; | |
: <tabbed> ( assoc -- tabbed ) tabbed new-tabbed ; | |
]] | |
FILE: [[ui/gadgets/tabs/summary.txt]] [[Tabbed windows]] | |
FILE: [[ui/gadgets/tabs/authors.txt]] [[William Schlieper | |
]] | |
FILE: [[ui/gadgets/corners/corners.factor]] [[! Copyright (C) 2009 Slava Pestov. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: accessors kernel namespaces sequences ui.gadgets.frames | |
ui.gadgets.grids ui.gadgets.icons ui.gadgets.theme ; | |
IN: ui.gadgets.corners | |
CONSTANT: @center { 1 1 } | |
CONSTANT: @left { 0 1 } | |
CONSTANT: @right { 2 1 } | |
CONSTANT: @top { 1 0 } | |
CONSTANT: @bottom { 1 2 } | |
CONSTANT: @top-left { 0 0 } | |
CONSTANT: @top-right { 2 0 } | |
CONSTANT: @bottom-left { 0 2 } | |
CONSTANT: @bottom-right { 2 2 } | |
SYMBOL: name | |
: corner-image ( name -- image ) | |
[ name get "-" ] dip 3append theme-image ; | |
: corner-icon ( name -- icon ) | |
corner-image <icon> ; | |
: /-----\ ( corner -- corner ) | |
"top-left" corner-icon @top-left grid-add | |
"top-middle" corner-icon @top grid-add | |
"top-right" corner-icon @top-right grid-add ; | |
: |-----| ( gadget corner -- corner ) | |
"left-edge" corner-icon @left grid-add | |
swap @center grid-add | |
"right-edge" corner-icon @right grid-add ; | |
: \-----/ ( corner -- corner ) | |
"bottom-left" corner-icon @bottom-left grid-add | |
"bottom-middle" corner-icon @bottom grid-add | |
"bottom-right" corner-icon @bottom-right grid-add ; | |
: make-corners ( class name quot -- corners ) | |
[ [ [ 3 3 ] dip new-frame { 1 1 } >>filled-cell ] dip name ] dip | |
with-variable ; inline | |
]] | |
FILE: [[ui/gadgets/corners/authors.txt]] [[Slava Pestov | |
]] | |
FILE: [[ui/gadgets/plot/plot.factor]] [[ | |
USING: kernel quotations arrays sequences math math.ranges fry | |
opengl opengl.gl ui.render ui.gadgets.cartesian processing.shapes | |
accessors | |
help.syntax | |
easy-help ; | |
IN: ui.gadgets.plot | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
ARTICLE: "ui.gadgets.plot" "Plot Gadget" | |
Summary: | |
A simple gadget for ploting two dimentional functions. | |
Use the arrow keys to move around. | |
Use 'a' and 'z' keys to zoom in and out. .. | |
Example: | |
<plot> [ sin ] add-function gadget. .. | |
Example: | |
<plot> | |
[ sin ] red function boa add-function | |
[ cos ] blue function boa add-function | |
gadget. .. | |
; | |
ABOUT: "ui.gadgets.plot" | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
TUPLE: plot < cartesian functions points ; | |
: init-plot ( plot -- plot ) | |
init-cartesian | |
{ } >>functions | |
100 >>points ; | |
: <plot> ( -- plot ) plot new init-plot ; | |
: step-size ( plot -- step-size ) | |
[ [ x-max>> ] [ x-min>> ] bi - ] [ points>> ] bi / ; | |
: plot-range ( plot -- range ) | |
[ x-min>> ] [ x-max>> ] [ step-size ] tri <range> ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
TUPLE: function function color ; | |
GENERIC: plot-function ( plot object -- plot ) | |
M: callable plot-function ( plot quotation -- plot ) | |
[ dup plot-range ] dip '[ dup @ 2array ] map line-strip ; | |
M: function plot-function ( plot function -- plot ) | |
dup color>> dup [ >stroke-color ] [ drop ] if | |
[ dup plot-range ] dip function>> '[ dup @ 2array ] map line-strip ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: plot-functions ( plot -- plot ) dup functions>> [ plot-function ] each ; | |
: draw-axis ( plot -- plot ) | |
dup | |
[ [ x-min>> ] [ drop 0 ] bi 2array ] | |
[ [ x-max>> ] [ drop 0 ] bi 2array ] bi line* | |
dup | |
[ [ drop 0 ] [ y-min>> ] bi 2array ] | |
[ [ drop 0 ] [ y-max>> ] bi 2array ] bi line* ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
USING: ui.gadgets.slate ; | |
M: plot draw-slate ( plot -- plot ) | |
2 glLineWidth | |
draw-axis | |
plot-functions | |
fill-mode | |
1 glLineWidth ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: add-function ( plot function -- plot ) | |
over functions>> swap suffix >>functions ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: x-span ( plot -- span ) [ x-max>> ] [ x-min>> ] bi - ; | |
: y-span ( plot -- span ) [ y-max>> ] [ y-min>> ] bi - ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
USING: ui.gestures ui.gadgets ; | |
: left ( plot -- plot ) | |
dup [ x-min>> ] [ x-span 1/10 * ] bi - >>x-min | |
dup [ x-max>> ] [ x-span 1/10 * ] bi - >>x-max | |
dup relayout-1 ; | |
: right ( plot -- plot ) | |
dup [ x-min>> ] [ x-span 1/10 * ] bi + >>x-min | |
dup [ x-max>> ] [ x-span 1/10 * ] bi + >>x-max | |
dup relayout-1 ; | |
: down ( plot -- plot ) | |
dup [ y-min>> ] [ y-span 1/10 * ] bi - >>y-min | |
dup [ y-max>> ] [ y-span 1/10 * ] bi - >>y-max | |
dup relayout-1 ; | |
: up ( plot -- plot ) | |
dup [ y-min>> ] [ y-span 1/10 * ] bi + >>y-min | |
dup [ y-max>> ] [ y-span 1/10 * ] bi + >>y-max | |
dup relayout-1 ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: zoom-in-horizontal ( plot -- plot ) | |
dup [ x-min>> ] [ x-span 1/10 * ] bi + >>x-min | |
dup [ x-max>> ] [ x-span 1/10 * ] bi - >>x-max ; | |
: zoom-in-vertical ( plot -- plot ) | |
dup [ y-min>> ] [ y-span 1/10 * ] bi + >>y-min | |
dup [ y-max>> ] [ y-span 1/10 * ] bi - >>y-max ; | |
: zoom-in ( plot -- plot ) | |
zoom-in-horizontal | |
zoom-in-vertical | |
dup relayout-1 ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: zoom-out-horizontal ( plot -- plot ) | |
dup [ x-min>> ] [ x-span 1/10 * ] bi - >>x-min | |
dup [ x-max>> ] [ x-span 1/10 * ] bi + >>x-max ; | |
: zoom-out-vertical ( plot -- plot ) | |
dup [ y-min>> ] [ y-span 1/10 * ] bi - >>y-min | |
dup [ y-max>> ] [ y-span 1/10 * ] bi + >>y-max ; | |
: zoom-out ( plot -- plot ) | |
zoom-out-horizontal | |
zoom-out-vertical | |
dup relayout-1 ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
plot | |
H{ | |
{ T{ mouse-enter } [ request-focus ] } | |
{ T{ key-down f f "LEFT" } [ left drop ] } | |
{ T{ key-down f f "RIGHT" } [ right drop ] } | |
{ T{ key-down f f "DOWN" } [ down drop ] } | |
{ T{ key-down f f "UP" } [ up drop ] } | |
{ T{ key-down f f "a" } [ zoom-in drop ] } | |
{ T{ key-down f f "z" } [ zoom-out drop ] } | |
} | |
set-gestures | |
]] | |
FILE: [[ui/gadgets/poppers/poppers.factor]] [[! Copyright (C) 2009 Sam Anklesaria | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: arrays accessors combinators kernel math | |
models models.combinators namespaces sequences | |
ui.gadgets ui.gadgets.controls ui.gadgets.layout | |
ui.gadgets.tracks ui.gestures ui.gadgets.line-support ; | |
EXCLUDE: ui.gadgets.editors => model-field ; | |
IN: ui.gadgets.poppers | |
TUPLE: popped < model-field { fatal? initial: t } ; | |
TUPLE: popped-editor < multiline-editor ; | |
: <popped> ( text -- gadget ) <basic> init-field popped-editor popped (new-field) swap >>model* ; | |
: set-expansion ( popped size -- ) over dup parent>> [ children>> index ] [ sizes>> ] bi set-nth relayout ; | |
: new-popped ( popped -- ) insertion-point "" <popped> | |
[ rot 1 + f (track-add-at) ] keep [ relayout ] [ request-focus ] bi ; | |
: focus-prev ( popped -- ) dup parent>> children>> length 1 = | |
[ drop ] [ | |
insertion-point [ 1 - dup -1 = [ drop 1 ] when ] [ children>> ] bi* nth | |
[ request-focus ] [ editor>> end-of-document ] bi | |
] if ; | |
: initial-popped ( popper -- ) "" <popped> [ f track-add drop ] keep request-focus ; | |
TUPLE: popper < track { unfocus-hook initial: [ drop ] } ; | |
! list of strings is model (make shown objects implement sequence protocol) | |
: <popper> ( model -- popper ) vertical popper new-track swap >>model ; | |
M: popped handle-gesture swap { | |
{ gain-focus [ 1 set-expansion f ] } | |
{ lose-focus [ dup parent>> | |
[ [ unfocus-hook>> call( a -- ) ] curry [ f set-expansion ] bi ] | |
[ drop ] if* f | |
] } | |
{ T{ key-up f f "RET" } [ dup editor>> delete-previous-character new-popped f ] } | |
{ T{ key-up f f "BACKSPACE" } [ dup editor>> editor-string "" = | |
[ dup fatal?>> [ [ focus-prev ] [ unparent ] bi ] [ t >>fatal? drop ] if ] | |
[ f >>fatal? drop ] if f | |
] } | |
[ swap call-next-method ] | |
} case ; | |
M: popper handle-gesture swap T{ button-down f f 1 } = | |
[ hand-click# get 2 = [ initial-popped ] [ drop ] if ] [ drop ] if f ; | |
M: popper model-changed | |
[ children>> [ unparent ] each ] | |
[ [ value>> [ <popped> ] map ] dip [ f track-add ] reduce request-focus ] bi ; | |
M: popped pref-dim* editor>> [ pref-dim* first ] [ line-height ] bi 2array ; | |
M: popper focusable-child* children>> [ t ] [ first ] if-empty ; | |
]] | |
FILE: [[ui/gadgets/poppers/authors.txt]] [[Sam Anklesaria | |
]] | |
FILE: [[ui/gadgets/layout/layout-docs.factor]] [[USING: help.markup help.syntax models ui.gadgets.tracks ; | |
IN: ui.gadgets.layout | |
HELP: , | |
{ $values { "item" "a gadget or model" } } | |
{ $description "Used in a series of gadgets created by a box, accumulating the gadget" } ; | |
HELP: ,% | |
{ $syntax "gadget ,% width" } | |
{ $description "Like ',' but stretches the gadget to always fill a percent of the parent" } ; | |
HELP: -> | |
{ $values { "uiitem" "a gadget or model" } { "model" model } } | |
{ $description "Like ',' but passes its model on for further use." } ; | |
HELP: ->% | |
{ $syntax "gadget ,% width" } | |
{ $description "Like '->' but stretches the gadget to always fill a percent of the parent" } ; | |
HELP: <spacer> | |
{ $description "Grows to fill any empty space in a box" } ; | |
HELP: <hbox> | |
{ $values { "gadgets" "a list of gadgets" } { "track" track } } | |
{ $syntax "[ gadget , gadget , ... ] <hbox>" } | |
{ $description "Creates an horizontal track containing the gadgets listed in the quotation" } ; | |
HELP: <vbox> | |
{ $values { "gadgets" "a list of gadgets" } { "track" track } } | |
{ $syntax "[ gadget , gadget , ... ] <hbox>" } | |
{ $description "Creates an vertical track containing the gadgets listed in the quotation" } ; | |
HELP: $ | |
{ $syntax "$ PLACEHOLDER-NAME $" } | |
{ $description "Defines an insertion point in a template named PLACEHOLDER-NAME which can be used by calling its name" } ; | |
HELP: with-interface | |
{ $values { "quot" "quotation that builds a template and inserts into it" } } | |
{ $description "Create templates, used with " { $link POSTPONE: $ } } ; | |
ARTICLE: "ui.gadgets.layout" "GUI Layout" | |
"Laying out GUIs works the same way as building lists with " { $vocab-link "make" } | |
". Gadgets are layed out using " { $vocab-link "ui.gadgets.tracks" } " through " { $link <hbox> } " and " { $link <vbox> } ", which allow both fixed and percentage widths. " | |
{ $link , } " and " { $link -> } " add a model or gadget to the gadget you're building. " | |
"Also, books can be made with " { $link <book> } ". " | |
{ $link <spacer> } "s add flexable space between items. " $nl | |
"Using " { $link with-interface } ", one can pre-build templates to add items to later: " | |
"Like in the StringTemplate framework for java, placeholders are defined using $ PLACERHOLDER-NAME $ " | |
"Using PLACEHOLDER-NAME again sets it as the current insertion point. " | |
"For examples using normal layout, see the " { $vocab-link "sudokus" } " demo. " | |
"For examples of templating, see the " { $vocab-link "recipes" } " demo." ; | |
ABOUT: "ui.gadgets.layout" | |
]] | |
FILE: [[ui/gadgets/layout/summary.txt]] [[Syntax for easily building GUIs and using templates]] | |
FILE: [[ui/gadgets/layout/layout.factor]] [[USING: accessors assocs arrays fry kernel lexer make math.parser | |
models monads namespaces parser sequences | |
sequences.extras models.combinators ui.gadgets | |
ui.gadgets.tracks words ui.gadgets.controls ; | |
QUALIFIED: make | |
QUALIFIED-WITH: ui.gadgets.books book | |
IN: ui.gadgets.layout | |
SYMBOL: templates | |
TUPLE: layout gadget size ; C: <layout> layout | |
TUPLE: placeholder < gadget members ; | |
: <placeholder> ( -- placeholder ) placeholder new V{ } clone >>members ; | |
: (remove-members) ( placeholder members -- ) [ [ model? ] filter swap parent>> model>> [ remove-connection ] curry each ] | |
[ nip [ gadget? ] filter [ unparent ] each ] 2bi ; | |
: remove-members ( placeholder -- ) dup members>> [ drop ] [ [ (remove-members) ] keep delete-all ] if-empty ; | |
: add-member ( obj placeholder -- ) over layout? [ [ gadget>> ] dip ] when members>> push ; | |
: , ( item -- ) make:, ; | |
: make* ( quot -- list ) { } make ; inline | |
! Just take the previous mentioned placeholder and use it | |
! If there is no previously mentioned placeholder, we're probably making a box, and will create the placeholder ourselves | |
DEFER: with-interface | |
: insertion-quot ( quot -- quot' ) | |
make:building get [ [ placeholder? ] find-last nip [ <placeholder> dup , ] unless* | |
[ templates get ] 2dip swap '[ [ _ templates set _ , @ ] with-interface ] ] when* ; | |
SYNTAX: ,% scan string>number [ <layout> , ] curry append! ; | |
SYNTAX: ->% scan string>number '[ [ _ <layout> , ] [ output-model ] bi ] append! ; | |
GENERIC: -> ( uiitem -- model ) | |
M: gadget -> dup , output-model ; | |
M: model -> dup , ; | |
: <spacer> ( -- ) <gadget> 1 <layout> , ; | |
: add-layout ( track layout -- track ) [ gadget>> ] [ size>> ] bi track-add ; | |
: layouts ( sized? gadgets -- layouts ) [ [ gadget? ] [ layout? ] bi or ] filter swap | |
[ [ dup layout? [ f <layout> ] unless ] map ] | |
[ [ dup gadget? [ gadget>> ] unless ] map ] if ; | |
: make-layout ( building sized? -- models layouts ) [ swap layouts ] curry | |
[ make* [ [ model? ] filter ] ] dip bi ; inline | |
: <box> ( gadgets type -- track ) | |
[ t make-layout ] dip <track> | |
swap [ add-layout ] each | |
swap [ <collection> >>model ] unless-empty ; inline | |
: <hbox> ( gadgets -- track ) horizontal <box> ; inline | |
: <vbox> ( gadgets -- track ) vertical <box> ; inline | |
: make-book ( models gadgets model -- book ) book:<book> swap [ "No models in books" throw ] unless-empty ; | |
: <book> ( quot: ( -- model ) -- book ) f make-layout rot 0 >>value make-book ; inline | |
: <book*> ( quot -- book ) f make-layout f make-book ; inline | |
ERROR: not-in-template word ; | |
SYNTAX: $ scan-new-word dup | |
[ [ dup templates get at [ nip , ] [ not-in-template ] if* ] curry ( -- ) define-declared "$" expect ] | |
[ [ <placeholder> [ swap templates get set-at ] keep , ] curry ] bi append! ; | |
: insert-gadget ( number parent gadget -- ) -rot [ but-last insert-nth ] change-children drop ; | |
: insert-size ( number parent size -- ) -rot [ but-last insert-nth ] change-sizes drop ; | |
: insertion-point ( placeholder -- number parent ) dup parent>> [ children>> index ] keep ; | |
GENERIC: >layout ( gadget -- layout ) | |
M: gadget >layout f <layout> ; | |
M: layout >layout ; | |
GENERIC#: (add-gadget-at) 2 ( parent item n -- ) | |
M: gadget (add-gadget-at) -rot [ add-gadget ] keep insert-gadget ; | |
M: track (add-gadget-at) -rot >layout [ add-layout ] keep [ gadget>> insert-gadget ] [ size>> insert-size ] 3bi ; | |
GENERIC#: add-gadget-at 1 ( item location -- ) | |
M: object add-gadget-at insertion-point -rot (add-gadget-at) ; | |
M: model add-gadget-at parent>> dup book:book? [ "No models in books" throw ] | |
[ dup model>> dup collection? [ nip swap add-connection ] [ drop [ 1array <collection> ] dip model<< ] if ] if ; | |
: track-add-at ( item location size -- ) swap [ <layout> ] dip add-gadget-at ; | |
: (track-add-at) ( parent item n size -- ) swap [ <layout> ] dip (add-gadget-at) ; | |
: insert-item ( item location -- ) [ dup get [ drop ] [ remove-members ] if ] [ on ] [ ] tri | |
[ add-member ] 2keep add-gadget-at ; | |
: insert-items ( makelist -- ) t swap [ dup placeholder? [ nip ] [ over insert-item ] if ] each drop ; | |
: with-interface ( quot -- ) [ make* ] curry H{ } clone templates rot with-variable [ insert-items ] with-scope ; inline | |
M: model >>= [ swap insertion-quot <action> ] curry ; | |
M: model fmap insertion-quot <mapped> ; | |
M: model $> insertion-quot side-effect-model new-mapped-model ; | |
M: model <$ insertion-quot quot-model new-mapped-model ; | |
]] | |
FILE: [[ui/gadgets/layout/authors.txt]] [[Sam Anklesaria | |
]] | |
FILE: [[ui/gadgets/alerts/alerts.factor]] [[USING: accessors models monads macros generalizations kernel | |
ui ui.gadgets.controls models.combinators ui.gadgets.layout ui.gadgets | |
ui.gadgets.labels ui.gadgets.editors ui.gadgets.buttons | |
ui.gadgets.packs locals sequences fonts io.styles | |
wrap.strings ; | |
IN: ui.gadgets.alerts | |
:: alert ( quot string -- ) <pile> { 10 10 } >>gap 1 >>align | |
string 22 wrap-lines <label> T{ font { name "sans-serif" } { size 18 } } >>font { 200 100 } >>pref-dim add-gadget | |
"okay" [ close-window ] quot append <border-button> add-gadget "" open-window ; | |
: alert* ( str -- ) [ ] swap alert ; | |
:: ask-user ( string -- model' ) | |
[ | |
string <label> T{ font { name "sans-serif" } { size 14 } } >>font dup , :> lbl | |
<model-field*> ->% 1 :> fldm | |
"okay" <model-border-btn> :> btn | |
btn -> [ fldm swap updates ] | |
[ [ drop lbl close-window ] $> , ] bi | |
] <vbox> { 161 86 } >>pref-dim "" open-window ; | |
MACRO: ask-buttons ( buttons -- quot ) dup length [ | |
[ swap | |
[ 22 wrap-lines <label> T{ font { name "sans-serif" } { size 18 } } >>font , | |
[ [ <model-border-btn> [ close-window ] >>hook -> ] map ] <hbox> , ] <vbox> | |
"" open-window | |
] dip firstn | |
] 2curry ; | |
]] | |
FILE: [[ui/gadgets/alerts/summary.txt]] [[Really simple dialog boxes]] | |
FILE: [[ui/gadgets/alerts/authors.txt]] [[Sam Anklesaria | |
]] | |
FILE: [[ui/gadgets/controls/controls.factor]] [[USING: accessors assocs arrays kernel models monads sequences | |
models.combinators ui.gadgets ui.gadgets.borders ui.gadgets.buttons | |
ui.gadgets.buttons.private ui.gadgets.editors ui.gadgets.editors.private | |
words images.loader ui.gadgets.scrollers ui.images vocabs.parser lexer | |
models.range ui.gadgets.sliders ; | |
QUALIFIED-WITH: ui.gadgets.sliders slider | |
QUALIFIED-WITH: ui.gadgets.tables tbl | |
EXCLUDE: ui.gadgets.editors => model-field ; | |
IN: ui.gadgets.controls | |
TUPLE: model-btn < button hook value ; | |
: <model-btn> ( gadget -- button ) [ | |
[ dup hook>> [ call( button -- ) ] [ drop ] if* ] | |
[ [ [ value>> ] [ ] bi or ] keep set-control-value ] | |
[ model>> f swap value<< ] tri | |
] model-btn new-button f <basic> >>model ; | |
: <model-border-btn> ( text -- button ) <model-btn> border-button-theme ; | |
TUPLE: table < tbl:table { quot initial: [ ] } { val-quot initial: [ ] } color-quot column-titles column-alignment actions ; | |
M: table tbl:column-titles column-titles>> ; | |
M: table tbl:column-alignment column-alignment>> ; | |
M: table tbl:row-columns quot>> [ call( a -- b ) ] [ drop f ] if* ; | |
M: table tbl:row-value val-quot>> [ call( a -- b ) ] [ drop f ] if* ; | |
M: table tbl:row-color color-quot>> [ call( a -- b ) ] [ drop f ] if* ; | |
: new-table ( model class -- table ) f swap tbl:new-table dup >>renderer | |
f <basic> >>actions dup actions>> [ set-model ] curry >>action ; | |
: <table> ( model -- table ) table new-table ; | |
: <table*> ( -- table ) V{ } clone <model> <table> ; | |
: <list> ( column-model -- table ) <table> [ 1array ] >>quot ; | |
: <list*> ( -- table ) V{ } clone <model> <list> ; | |
: indexed ( table -- table ) f >>val-quot ; | |
TUPLE: model-field < field model* ; | |
: init-field ( model -- model' ) [ [ ] [ "" ] if* ] change-value ; | |
: <model-field> ( model -- gadget ) model-field new-field swap init-field >>model* ; | |
M: model-field graft* | |
[ [ model*>> value>> ] [ editor>> ] bi set-editor-string ] | |
[ dup editor>> model>> add-connection ] | |
[ dup model*>> add-connection ] tri ; | |
M: model-field ungraft* | |
[ dup editor>> model>> remove-connection ] | |
[ dup model*>> remove-connection ] bi ; | |
M: model-field model-changed 2dup model*>> = | |
[ [ value>> ] [ editor>> ] bi* set-editor-string ] | |
[ nip [ editor>> editor-string ] [ model*>> ] bi set-model ] if ; | |
: (new-field) ( editor field -- gadget ) [ new-editor ] dip new-border dup gadget-child >>editor | |
field-theme { 1 0 } >>align ; inline | |
: <model-field*> ( -- field ) "" <model> <model-field> ; | |
: <empty-field> ( model -- field ) "" <model> switch-models <model-field> ; | |
: <model-editor> ( model -- gadget ) multiline-editor model-field (new-field) swap init-field >>model* ; | |
: <model-editor*> ( -- editor ) "" <model> <model-editor> ; | |
: <empty-editor> ( model -- editor ) "" <model> switch-models <model-editor> ; | |
: <model-action-field> ( -- field ) f <action-field> dup [ set-control-value ] curry >>quot | |
f <model> >>model ; | |
: <slider> ( init page min max step -- slider ) <range> horizontal slider:<slider> ; | |
: image-prep ( -- image ) scan current-vocab name>> "vocab:" "/icons/" surround ".tiff" surround <image-name> dup cached-image drop ; | |
SYNTAX: IMG-MODEL-BTN: image-prep [ <model-btn> ] curry append! ; | |
SYNTAX: IMG-BTN: image-prep [ swap <button> ] curry append! ; | |
GENERIC: output-model ( gadget -- model ) | |
M: gadget output-model model>> ; | |
M: table output-model dup val-quot>> [ selection>> ] [ selection-index>> ] if ; | |
M: model-field output-model model*>> ; | |
M: scroller output-model viewport>> children>> first output-model ; | |
M: slider output-model model>> range-model ; | |
IN: accessors | |
M: model-btn text>> children>> first text>> ; | |
IN: ui.gadgets.controls | |
SINGLETON: gadget-monad | |
INSTANCE: gadget-monad monad | |
INSTANCE: gadget monad | |
M: gadget monad-of drop gadget-monad ; | |
M: gadget-monad return drop <gadget> swap >>model ; | |
M: gadget >>= output-model [ swap call( x -- y ) ] curry ; | |
]] | |
FILE: [[ui/gadgets/controls/controls-docs.factor]] [[USING: accessors help.markup help.syntax ui.gadgets.buttons | |
ui.gadgets.editors models ui.gadgets ; | |
IN: ui.gadgets.controls | |
HELP: <model-btn> | |
{ $values { "gadget" "the button's label" } { "button" button } } | |
{ $description "Creates an button whose signal updates on clicks. " } ; | |
HELP: <model-border-btn> | |
{ $values { "text" "the button's label" } { "button" button } } | |
{ $description "Creates an button whose signal updates on clicks. " } ; | |
HELP: <table> | |
{ $values { "model" "values the table is to display" } { "table" table } } | |
{ $description "Creates an " { $link table } } ; | |
HELP: <table*> | |
{ $values { "table" table } } | |
{ $description "Creates an " { $link table } " with no initial values to display" } ; | |
HELP: <list> | |
{ $values { "column-model" "values the table is to display" } { "table" table } } | |
{ $description "Creates an " { $link table } " with a val-quot that renders each element as its own row" } ; | |
HELP: <list*> | |
{ $values { "table" table } } | |
{ $description "Creates an model-list with no initial values to display" } ; | |
HELP: indexed | |
{ $values { "table" table } } | |
{ $description "Sets the output model of an table to the selected-index, rather than the selected-value" } ; | |
HELP: <model-field> | |
{ $values { "model" model } { "gadget" model-field } } | |
{ $description "Creates a field with an initial value" } ; | |
HELP: <model-field*> | |
{ $values { "field" model-field } } | |
{ $description "Creates a field with an empty initial value" } ; | |
HELP: <empty-field> | |
{ $values { "model" model } { "field" model-field } } | |
{ $description "Creates a field with an empty initial value that switches to another signal on its update" } ; | |
HELP: <model-editor> | |
{ $values { "model" model } { "gadget" model-field } } | |
{ $description "Creates an editor with an initial value" } ; | |
HELP: <model-editor*> | |
{ $values { "editor" "an editor" } } | |
{ $description "Creates a editor with an empty initial value" } ; | |
HELP: <empty-editor> | |
{ $values { "model" model } { "editor" "an editor" } } | |
{ $description "Creates a field with an empty initial value that switches to another signal on its update" } ; | |
HELP: <model-action-field> | |
{ $values { "field" action-field } } | |
{ $description "Field that updates its model with its contents when the user hits the return key" } ; | |
HELP: IMG-MODEL-BTN: | |
{ $syntax "IMAGE-MODEL-BTN: filename" } | |
{ $description "Creates a button using a tiff image named as specified found in the icons subdirectory of the vocabulary path" } ; | |
HELP: IMG-BTN: | |
{ $syntax "[ do-something ] IMAGE-BTN: filename" } | |
{ $description "Creates a button using a tiff image named as specified found in the icons subdirectory of the vocabulary path, calling the specified quotation on click" } ; | |
HELP: output-model | |
{ $values { "gadget" gadget } { "model" model } } | |
{ $description "Returns the model a gadget uses for output. Often the same as " { $link model>> } } ; | |
]] | |
FILE: [[ui/gadgets/controls/summary.txt]] [[Gadgets with expanded model usage]] | |
FILE: [[ui/gadgets/controls/authors.txt]] [[Sam Anklesaria | |
]] | |
FILE: [[ui/gadgets/comboboxes/comboboxes.factor]] [[USING: accessors arrays kernel math.rectangles sequences | |
ui.gadgets.controls models.combinators ui.gadgets ui.gadgets.glass | |
ui.gadgets.labels ui.gestures ; | |
QUALIFIED-WITH: ui.gadgets.tables tbl | |
IN: ui.gadgets.comboboxes | |
TUPLE: combo-table < table spawner ; | |
M: combo-table handle-gesture [ call-next-method drop ] 2keep swap | |
T{ button-up } = [ | |
[ spawner>> ] | |
[ tbl:selected-row [ swap set-control-value ] [ 2drop ] if ] | |
[ hide-glass ] tri | |
] [ drop ] if t ; | |
TUPLE: combobox < label-control table ; | |
combobox H{ | |
{ T{ button-down } [ dup table>> over >>spawner <zero-rect> show-glass ] } | |
} set-gestures | |
: <combobox> ( options -- combobox ) [ first [ combobox new-label ] keep <basic> >>model ] keep | |
<basic> combo-table new-table [ 1array ] >>quot >>table ; | |
]] | |
FILE: [[ui/gadgets/comboboxes/summary.txt]] [[Combo boxes have a model choosen from a list of options]] | |
FILE: [[ui/gadgets/comboboxes/authors.txt]] [[Sam Anklesaria | |
]] | |
FILE: [[ui/gadgets/tiling/tiling.factor]] [[ | |
USING: kernel sequences math math.order | |
ui.gadgets ui.gadgets.tracks ui.gestures accessors fry | |
help.syntax | |
easy-help ; | |
IN: ui.gadgets.tiling | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
ARTICLE: "ui.gadgets.tiling" "Tiling Layout Gadgets" | |
Summary: | |
A gadget which tiles it's children. | |
A tiling gadget may contain any number of children, but only a | |
fixed number is displayed at one time. How many are displayed can | |
be controlled via Control-[ and Control-]. | |
The focus may be switched with Alt-Left and Alt-Right. | |
The focused child may be moved via Shift-Alt-Left and | |
Shift-Alt-Right. .. | |
Example: | |
<tiling-shelf> | |
"resource:" directory-files | |
[ [ drop ] <bevel-button> tiling-add ] | |
each | |
"Files" open-window .. | |
; | |
ABOUT: "ui.gadgets.tiling" | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
TUPLE: tiling < track gadgets tiles first focused ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: init-tiling ( tiling -- tiling ) | |
init-track | |
{ 1 0 } >>orientation | |
V{ } clone >>gadgets | |
2 >>tiles | |
0 >>first | |
0 >>focused ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: <tiling> ( -- gadget ) tiling new init-tiling ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: bounded-subseq ( seq a b -- seq ) | |
[ 0 max ] dip | |
pick length [ min ] curry bi@ | |
rot | |
subseq ; | |
: tiling-gadgets-to-map ( tiling -- gadgets ) | |
[ gadgets>> ] | |
[ first>> ] | |
[ [ first>> ] [ tiles>> ] bi + ] | |
tri | |
bounded-subseq ; | |
: tiling-map-gadgets ( tiling -- tiling ) | |
dup clear-track | |
dup tiling-gadgets-to-map [ 1 track-add ] each ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: tiling-add ( tiling gadget -- tiling ) | |
over gadgets>> push | |
tiling-map-gadgets ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: first-gadget ( tiling -- index ) drop 0 ; | |
: last-gadget ( tiling -- index ) gadgets>> length 1 - ; | |
: first-viewable ( tiling -- index ) first>> ; | |
: last-viewable ( tiling -- index ) [ first>> ] [ tiles>> ] bi + 1 - ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: make-focused-mapped ( tiling -- tiling ) | |
dup [ focused>> ] [ first>> ] bi < | |
[ dup first>> 1 - >>first ] | |
[ ] | |
if | |
dup [ last-viewable ] [ focused>> ] bi < | |
[ dup first>> 1 + >>first ] | |
[ ] | |
if ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: check-focused-bounds ( tiling -- tiling ) | |
dup focused>> 0 max over gadgets>> length 1 - min >>focused ; | |
: focus-prev ( tiling -- tiling ) | |
dup focused>> 1 - >>focused | |
check-focused-bounds | |
make-focused-mapped | |
tiling-map-gadgets | |
dup request-focus ; | |
: focus-next ( tiling -- tiling ) | |
dup focused>> 1 + >>focused | |
check-focused-bounds | |
make-focused-mapped | |
tiling-map-gadgets | |
dup request-focus ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: exchanged! ( seq a b -- ) | |
[ 0 max ] bi@ | |
pick length 1 - '[ _ min ] bi@ | |
rot exchange ; | |
: move-prev ( tiling -- tiling ) | |
dup [ gadgets>> ] [ focused>> 1 - ] [ focused>> ] tri exchanged! | |
focus-prev ; | |
: move-next ( tiling -- tiling ) | |
dup [ gadgets>> ] [ focused>> ] [ focused>> 1 + ] tri exchanged! | |
focus-next ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: add-tile ( tiling -- tiling ) | |
dup tiles>> 1 + >>tiles | |
tiling-map-gadgets ; | |
: del-tile ( tiling -- tiling ) | |
dup tiles>> 1 - 1 max >>tiles | |
tiling-map-gadgets ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
M: tiling focusable-child* ( tiling -- child/t ) | |
[ focused>> ] [ gadgets>> ] bi nth ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
TUPLE: tiling-shelf < tiling ; | |
TUPLE: tiling-pile < tiling ; | |
: <tiling-shelf> ( -- gadget ) | |
tiling-shelf new init-tiling { 1 0 } >>orientation ; | |
: <tiling-pile> ( -- gadget ) | |
tiling-pile new init-tiling { 0 1 } >>orientation ; | |
tiling-shelf | |
H{ | |
{ T{ key-down f { A+ } "LEFT" } [ focus-prev drop ] } | |
{ T{ key-down f { A+ } "RIGHT" } [ focus-next drop ] } | |
{ T{ key-down f { S+ A+ } "LEFT" } [ move-prev drop ] } | |
{ T{ key-down f { S+ A+ } "RIGHT" } [ move-next drop ] } | |
{ T{ key-down f { C+ } "[" } [ del-tile drop ] } | |
{ T{ key-down f { C+ } "]" } [ add-tile drop ] } | |
} | |
set-gestures | |
tiling-pile | |
H{ | |
{ T{ key-down f { A+ } "UP" } [ focus-prev drop ] } | |
{ T{ key-down f { A+ } "DOWN" } [ focus-next drop ] } | |
{ T{ key-down f { S+ A+ } "UP" } [ move-prev drop ] } | |
{ T{ key-down f { S+ A+ } "DOWN" } [ move-next drop ] } | |
{ T{ key-down f { C+ } "[" } [ del-tile drop ] } | |
{ T{ key-down f { C+ } "]" } [ add-tile drop ] } | |
} | |
set-gestures | |
]] | |
FILE: [[webapps/numbers/authors.txt]] [[Chris Double | |
]] | |
FILE: [[webapps/numbers/numbers.factor]] [[! cont-number-guess | |
! | |
! Copyright (C) 2004 Chris Double. | |
! | |
! Redistribution and use in source and binary forms, with or without | |
! modification, are permitted provided that the following conditions are met: | |
! | |
! 1. Redistributions of source code must retain the above copyright notice, | |
! this list of conditions and the following disclaimer. | |
! | |
! 2. Redistributions in binary form must reproduce the above copyright notice, | |
! this list of conditions and the following disclaimer in the documentation | |
! and/or other materials provided with the distribution. | |
! | |
! THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, | |
! INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND | |
! FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | |
! DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
! SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
! PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | |
! OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
! WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | |
! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
! | |
! This example modifies the console based 'numbers-game' example | |
! in a very minimal way to demonstrate conversion of a console | |
! program to a web based application. | |
! | |
! All that was required was changing the input and output functions | |
! to use HTML. The remaining code was untouched. | |
! | |
! The result is not that pretty but it shows the basic idea. | |
USING: kernel math parser html html.elements io namespaces | |
math.parser random webapps.continuation ; | |
IN: webapps.numbers | |
: web-print ( str -- ) | |
! Display the string in a web page. | |
[ | |
swap dup | |
"<!DOCTYPE html>" print | |
<html> | |
<head> <title> write </title> </head> | |
<body> | |
<p> write </p> | |
<p> <a =href a> "Press to continue" write </a> </p> | |
</body> | |
</html> | |
] show 2drop ; | |
: read-number ( -- ) | |
[ | |
"<!DOCTYPE html>" print | |
<html> | |
<head> <title> "Enter a number" write </title> </head> | |
<body> | |
<form =action "post" =method form> | |
<p> | |
"Enter a number:" write | |
<input "text" =type "num" =name "20" =size input/> | |
<input "submit" =type "Press to continue" =value input/> | |
</p> | |
</form> | |
</body> | |
</html> | |
] show [ "num" get ] bind string>number ; | |
: guess-banner | |
"I'm thinking of a number between 0 and 100." web-print ; | |
: guess-prompt ; | |
: too-high "Too high" web-print ; | |
: too-low "Too low" web-print ; | |
: correct "Correct - you win!" web-print ; | |
: inexact-guess ( actual guess -- ) | |
< [ too-high ] [ too-low ] if ; | |
: judge-guess ( actual guess -- ? ) | |
2dup = [ | |
2drop correct f | |
] [ | |
inexact-guess t | |
] if ; | |
: number-to-guess ( -- n ) 100 random ; | |
: numbers-game-loop ( actual -- ) | |
dup guess-prompt read-number judge-guess [ | |
numbers-game-loop | |
] [ | |
drop | |
] if ; | |
: numbers-game number-to-guess numbers-game-loop ; | |
"numbers-game" [ numbers-game ] install-cont-responder | |
]] | |
FILE: [[javascriptcore/javascriptcore.factor]] [[! Copyright (C) 2010 Doug Coleman. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: alien.c-types alien.data byte-arrays continuations fry | |
io.encodings.string io.encodings.utf8 io.files | |
javascriptcore.ffi javascriptcore.ffi.hack kernel namespaces | |
sequences ; | |
IN: javascriptcore | |
ERROR: javascriptcore-error error ; | |
SYMBOL: js-context | |
: with-global-context ( quot -- ) | |
[ | |
[ f JSGlobalContextCreate dup js-context set ] dip | |
[ nip '[ @ ] ] | |
[ drop '[ _ JSGlobalContextRelease ] ] 2bi | |
[ ] cleanup | |
] with-scope ; inline | |
: with-javascriptcore ( quot -- ) | |
set-callstack-bounds | |
with-global-context ; inline | |
: JSString>string ( JSString -- string ) | |
dup JSStringGetMaximumUTF8CStringSize [ <byte-array> ] keep | |
[ JSStringGetUTF8CString drop ] [ drop ] 2bi | |
utf8 decode [ 0 = ] trim-tail ; | |
: JSValueRef>string ( ctx JSValueRef/f -- string/f ) | |
[ | |
f JSValueToStringCopy | |
[ JSString>string ] [ JSStringRelease ] bi | |
] [ | |
drop f | |
] if* ; | |
: eval-js ( string -- result-string ) | |
[ js-context get dup ] dip | |
JSStringCreateWithUTF8CString f f 0 | |
{ { void* initial: f } } [ JSEvaluateScript ] with-out-parameters | |
dup [ nip JSValueRef>string javascriptcore-error ] [ drop JSValueRef>string ] if ; | |
: eval-js-standalone ( string -- result-string ) | |
'[ _ eval-js ] with-javascriptcore ; | |
: eval-js-path-standalone ( path -- result-string ) utf8 file-contents eval-js-standalone ; | |
]] | |
FILE: [[javascriptcore/core-foundation/platforms.txt]] [[macosx | |
]] | |
FILE: [[javascriptcore/core-foundation/authors.txt]] [[Doug Coleman | |
]] | |
FILE: [[javascriptcore/core-foundation/core-foundation.factor]] [[! Copyright (C) 2010 Doug Coleman. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: alien.syntax core-foundation core-foundation.strings | |
javascriptcore.ffi ; | |
IN: javascriptcore.core-foundation | |
FUNCTION: JSStringRef JSStringCreateWithCFString ( CFStringRef string ) ; | |
FUNCTION: CFStringRef JSStringCopyCFString ( CFAllocatorRef alloc, JSStringRef string ) ; | |
]] | |
FILE: [[javascriptcore/platforms.txt]] [[macosx | |
]] | |
FILE: [[javascriptcore/javascriptcore-tests.factor]] [[! Copyright (C) 2010 Doug Coleman. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: accessors javascriptcore kernel tools.test ; | |
IN: javascriptcore.tests | |
[ "2" ] [ "1+1" eval-js-standalone ] unit-test | |
[ "1+shoes" eval-js-standalone ] | |
[ error>> "ReferenceError: Can't find variable: shoes" = ] must-fail-with | |
]] | |
FILE: [[javascriptcore/ffi/platforms.txt]] [[macosx | |
]] | |
FILE: [[javascriptcore/ffi/hack/platforms.txt]] [[macosx | |
]] | |
FILE: [[javascriptcore/ffi/hack/hack.factor]] [[! Copyright (C) 2010 Doug Coleman. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: alien alien.accessors alien.c-types alien.syntax kernel | |
kernel.private math system ; | |
IN: javascriptcore.ffi.hack | |
HOOK: set-callstack-bounds os ( -- ) | |
HOOK: macosx-callstack-start-offset cpu ( -- address ) | |
HOOK: macosx-callstack-size-offset cpu ( -- address ) | |
M: ppc macosx-callstack-start-offset 0x188 ; | |
M: ppc macosx-callstack-size-offset 0x18c ; | |
M: x86.32 macosx-callstack-start-offset 0xc48 ; | |
M: x86.32 macosx-callstack-size-offset 0xc4c ; | |
M: x86.64 macosx-callstack-start-offset 0x1860 ; | |
M: x86.64 macosx-callstack-size-offset 0x1868 ; | |
M: object set-callstack-bounds ; | |
FUNCTION: void* pthread_self ( ) ; | |
M: macosx set-callstack-bounds | |
callstack-bounds over [ alien-address ] bi@ - | |
pthread_self | |
[ macosx-callstack-size-offset set-alien-unsigned-cell ] | |
[ macosx-callstack-start-offset set-alien-cell ] bi ; | |
]] | |
FILE: [[javascriptcore/ffi/hack/authors.txt]] [[Doug Coleman | |
]] | |
FILE: [[javascriptcore/ffi/ffi.factor]] [[! Copyright (C) 2010 Doug Coleman. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: alien alien.c-types alien.libraries alien.syntax | |
classes.struct combinators io.encodings.utf16n | |
io.encodings.utf8 kernel system ; | |
IN: javascriptcore.ffi | |
<< | |
"javascriptcore" { | |
{ [ os macosx? ] [ | |
"/System/Library/Frameworks/JavaScriptCore.framework/Versions/Current/JavaScriptCore" cdecl add-library | |
] } | |
! { [ os windows? ] [ "javascriptcore.dll" ] } | |
! { [ os unix? ] [ "libsqlite3.so" ] } | |
[ drop ] | |
} cond | |
>> | |
LIBRARY: javascriptcore | |
TYPEDEF: void* JSContextGroupRef | |
TYPEDEF: void* JSContextRef | |
TYPEDEF: void* JSGlobalContextRef | |
TYPEDEF: void* JSStringRef | |
TYPEDEF: void* JSClassRef | |
TYPEDEF: void* JSPropertyNameArrayRef | |
TYPEDEF: void* JSPropertyNameAccumulatorRef | |
TYPEDEF: void* JSValueRef | |
TYPEDEF: void* JSObjectRef | |
TYPEDEF: void* JSObjectInitializeCallback | |
TYPEDEF: void* JSObjectFinalizeCallback | |
TYPEDEF: void* JSObjectHasPropertyCallback | |
TYPEDEF: void* JSObjectGetPropertyCallback | |
TYPEDEF: void* JSObjectSetPropertyCallback | |
TYPEDEF: void* JSObjectDeletePropertyCallback | |
TYPEDEF: void* JSObjectGetPropertyNamesCallback | |
TYPEDEF: void* JSObjectCallAsFunctionCallback | |
TYPEDEF: void* JSObjectCallAsConstructorCallback | |
TYPEDEF: void* JSObjectHasInstanceCallback | |
TYPEDEF: void* JSObjectConvertToTypeCallback | |
TYPEDEF: uint unsigned | |
TYPEDEF: ushort JSChar | |
ENUM: JSPropertyAttributes | |
{ kJSPropertyAttributeNone 0 } | |
{ kJSPropertyAttributeReadOnly 2 } | |
{ kJSPropertyAttributeDontEnum 4 } | |
{ kJSPropertyAttributeDontDelete 8 } ; | |
ENUM: JSClassAttributes | |
{ kJSClassAttributeNone 0 } | |
{ kJSClassAttributeNoAutomaticPrototype 2 } ; | |
ENUM: JSType | |
kJSTypeUndefined, | |
kJSTypeNull, | |
kJSTypeBoolean, | |
kJSTypeNumber, | |
kJSTypeString, | |
kJSTypeObject ; | |
STRUCT: JSStaticValue | |
{ name c-string } | |
{ getProperty JSObjectGetPropertyCallback } | |
{ setProperty JSObjectSetPropertyCallback } | |
{ attributes JSPropertyAttributes } ; | |
STRUCT: JSStaticFunction | |
{ name c-string } | |
{ callAsFunction JSObjectCallAsFunctionCallback } ; | |
STRUCT: JSClassDefinition | |
{ version int } | |
{ attributes JSClassAttributes } | |
{ className c-string } | |
{ parentClass JSClassRef } | |
{ staticValues JSStaticValue* } | |
{ staticFunctions JSStaticFunction* } | |
{ initialize JSObjectInitializeCallback } | |
{ finalize JSObjectFinalizeCallback } | |
{ hasProperty JSObjectHasPropertyCallback } | |
{ getProperty JSObjectGetPropertyCallback } | |
{ setProperty JSObjectSetPropertyCallback } | |
{ deleteProperty JSObjectDeletePropertyCallback } | |
{ getPropertyNames JSObjectGetPropertyNamesCallback } | |
{ callAsFunction JSObjectCallAsFunctionCallback } | |
{ callAsConstructor JSObjectCallAsConstructorCallback } | |
{ hasInstance JSObjectHasInstanceCallback } | |
{ convertToType JSObjectConvertToTypeCallback } ; | |
ALIAS: kJSClassDefinitionEmpty JSClassDefinition | |
FUNCTION: JSValueRef JSEvaluateScript ( | |
JSContextRef ctx, | |
JSStringRef script, | |
JSObjectRef thisObject, | |
JSStringRef sourceURL, | |
int startingLineNumber, | |
JSValueRef* exception ) ; | |
FUNCTION: bool JSCheckScriptSyntax ( | |
JSContextRef ctx, | |
JSStringRef script, | |
JSStringRef sourceURL, | |
int startingLineNumber, | |
JSValueRef* exception ) ; | |
FUNCTION: void JSGarbageCollect | |
( JSContextRef ctx ) ; | |
FUNCTION: JSContextGroupRef JSContextGroupCreate | |
( ) ; | |
FUNCTION: JSContextGroupRef JSContextGroupRetain | |
( JSContextGroupRef group ) ; | |
FUNCTION: void JSContextGroupRelease | |
( JSContextGroupRef group ) ; | |
FUNCTION: JSGlobalContextRef JSGlobalContextCreate | |
( JSClassRef globalObjectClass ) ; | |
FUNCTION: JSGlobalContextRef JSGlobalContextCreateInGroup ( | |
JSContextGroupRef group, | |
JSClassRef globalObjectClass ) ; | |
FUNCTION: JSGlobalContextRef JSGlobalContextRetain | |
( JSGlobalContextRef ctx ) ; | |
FUNCTION: void JSGlobalContextRelease | |
( JSGlobalContextRef ctx ) ; | |
FUNCTION: JSObjectRef JSContextGetGlobalObject | |
( JSContextRef ctx ) ; | |
FUNCTION: JSContextGroupRef JSContextGetGroup | |
( JSContextRef ctx ) ; | |
FUNCTION: JSClassRef JSClassCreate | |
( JSClassDefinition* definition ) ; | |
FUNCTION: JSClassRef JSClassRetain | |
( JSClassRef jsClass ) ; | |
FUNCTION: void JSClassRelease | |
( JSClassRef jsClass ) ; | |
FUNCTION: JSObjectRef JSObjectMake | |
( JSContextRef ctx, | |
JSClassRef jsClass, void* data ) ; | |
FUNCTION: JSObjectRef JSObjectMakeFunctionWithCallback ( JSContextRef ctx, JSStringRef name, JSObjectCallAsFunctionCallback callAsFunction ) ; | |
FUNCTION: JSObjectRef JSObjectMakeConstructor ( JSContextRef ctx, JSClassRef jsClass, JSObjectCallAsConstructorCallback callAsConstructor ) ; | |
FUNCTION: JSObjectRef JSObjectMakeArray ( JSContextRef ctx, size_t argumentCount, JSValueRef arguments[], JSValueRef* exception ) ; | |
FUNCTION: JSObjectRef JSObjectMakeDate ( JSContextRef ctx, size_t argumentCount, JSValueRef arguments[], JSValueRef* exception ) ; | |
FUNCTION: JSObjectRef JSObjectMakeError ( JSContextRef ctx, size_t argumentCount, JSValueRef arguments[], JSValueRef* exception ) ; | |
FUNCTION: JSObjectRef JSObjectMakeRegExp ( JSContextRef ctx, size_t argumentCount, JSValueRef arguments[], JSValueRef* exception ) ; | |
FUNCTION: JSObjectRef JSObjectMakeFunction ( JSContextRef ctx, JSStringRef name, unsigned parameterCount, JSStringRef parameterNames[], JSStringRef body, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception ) ; | |
FUNCTION: JSValueRef JSObjectGetPrototype ( JSContextRef ctx, JSObjectRef object ) ; | |
FUNCTION: void JSObjectSetPrototype ( JSContextRef ctx, JSObjectRef object, JSValueRef value ) ; | |
FUNCTION: bool JSObjectHasProperty ( JSContextRef ctx, JSObjectRef object, JSStringRef propertyName ) ; | |
FUNCTION: JSValueRef JSObjectGetProperty ( JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception ) ; | |
FUNCTION: void JSObjectSetProperty ( JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSPropertyAttributes attributes, JSValueRef* exception ) ; | |
FUNCTION: bool JSObjectDeleteProperty ( JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception ) ; | |
FUNCTION: JSValueRef JSObjectGetPropertyAtIndex ( JSContextRef ctx, JSObjectRef object, unsigned propertyIndex, JSValueRef* exception ) ; | |
FUNCTION: void JSObjectSetPropertyAtIndex ( JSContextRef ctx, JSObjectRef object, unsigned propertyIndex, JSValueRef value, JSValueRef* exception ) ; | |
FUNCTION: void* JSObjectGetPrivate ( JSObjectRef object ) ; | |
FUNCTION: bool JSObjectSetPrivate ( JSObjectRef object, void* data ) ; | |
FUNCTION: bool JSObjectIsFunction ( JSContextRef ctx, JSObjectRef object ) ; | |
FUNCTION: JSValueRef JSObjectCallAsFunction ( JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, JSValueRef arguments[], JSValueRef* exception ) ; | |
FUNCTION: bool JSObjectIsConstructor ( JSContextRef ctx, JSObjectRef object ) ; | |
FUNCTION: JSObjectRef JSObjectCallAsConstructor ( JSContextRef ctx, JSObjectRef object, size_t argumentCount, JSValueRef arguments[], JSValueRef* exception ) ; | |
FUNCTION: JSPropertyNameArrayRef JSObjectCopyPropertyNames ( JSContextRef ctx, JSObjectRef object ) ; | |
FUNCTION: JSPropertyNameArrayRef JSPropertyNameArrayRetain ( JSPropertyNameArrayRef array ) ; | |
FUNCTION: void JSPropertyNameArrayRelease ( JSPropertyNameArrayRef array ) ; | |
FUNCTION: size_t JSPropertyNameArrayGetCount ( JSPropertyNameArrayRef array ) ; | |
FUNCTION: JSStringRef JSPropertyNameArrayGetNameAtIndex ( JSPropertyNameArrayRef array, size_t index ) ; | |
FUNCTION: void JSPropertyNameAccumulatorAddName ( JSPropertyNameAccumulatorRef accumulator, JSStringRef propertyName ) ; | |
FUNCTION: JSStringRef JSStringCreateWithCharacters ( JSChar* chars, size_t numChars ) ; | |
FUNCTION: JSStringRef JSStringCreateWithUTF8CString ( c-string string ) ; | |
FUNCTION: JSStringRef JSStringRetain ( JSStringRef string ) ; | |
FUNCTION: void JSStringRelease ( JSStringRef string ) ; | |
FUNCTION: size_t JSStringGetLength ( JSStringRef string ) ; | |
FUNCTION: JSChar* JSStringGetCharactersPtr ( JSStringRef string ) ; | |
FUNCTION: size_t JSStringGetMaximumUTF8CStringSize ( JSStringRef string ) ; | |
FUNCTION: size_t JSStringGetUTF8CString ( JSStringRef string, char* buffer, size_t bufferSize ) ; | |
FUNCTION: bool JSStringIsEqual ( JSStringRef a, JSStringRef b ) ; | |
FUNCTION: bool JSStringIsEqualToUTF8CString ( JSStringRef a, char* b ) ; | |
FUNCTION: JSType JSValueGetType ( JSContextRef ctx, JSValueRef value ) ; | |
FUNCTION: bool JSValueIsUndefined ( JSContextRef ctx, JSValueRef value ) ; | |
FUNCTION: bool JSValueIsNull ( JSContextRef ctx, JSValueRef value ) ; | |
FUNCTION: bool JSValueIsBoolean ( JSContextRef ctx, JSValueRef value ) ; | |
FUNCTION: bool JSValueIsNumber ( JSContextRef ctx, JSValueRef value ) ; | |
FUNCTION: bool JSValueIsString ( JSContextRef ctx, JSValueRef value ) ; | |
FUNCTION: bool JSValueIsObject ( JSContextRef ctx, JSValueRef value ) ; | |
FUNCTION: bool JSValueIsObjectOfClass ( JSContextRef ctx, JSValueRef value, JSClassRef jsClass ) ; | |
FUNCTION: bool JSValueIsEqual ( JSContextRef ctx, JSValueRef a, JSValueRef b, JSValueRef* exception ) ; | |
FUNCTION: bool JSValueIsStrictEqual ( JSContextRef ctx, JSValueRef a, JSValueRef b ) ; | |
FUNCTION: bool JSValueIsInstanceOfConstructor ( JSContextRef ctx, JSValueRef value, JSObjectRef constructor, JSValueRef* exception ) ; | |
FUNCTION: JSValueRef JSValueMakeUndefined ( JSContextRef ctx ) ; | |
FUNCTION: JSValueRef JSValueMakeNull ( JSContextRef ctx ) ; | |
FUNCTION: JSValueRef JSValueMakeBoolean ( JSContextRef ctx, bool boolean ) ; | |
FUNCTION: JSValueRef JSValueMakeNumber ( JSContextRef ctx, double number ) ; | |
FUNCTION: JSValueRef JSValueMakeString ( JSContextRef ctx, JSStringRef string ) ; | |
FUNCTION: bool JSValueToBoolean ( JSContextRef ctx, JSValueRef value ) ; | |
FUNCTION: double JSValueToNumber ( JSContextRef ctx, JSValueRef value, JSValueRef* exception ) ; | |
FUNCTION: JSStringRef JSValueToStringCopy ( JSContextRef ctx, JSValueRef value, JSValueRef* exception ) ; | |
FUNCTION: JSObjectRef JSValueToObject ( JSContextRef ctx, JSValueRef value, JSValueRef* exception ) ; | |
FUNCTION: void JSValueProtect ( JSContextRef ctx, JSValueRef value ) ; | |
FUNCTION: void JSValueUnprotect ( JSContextRef ctx, JSValueRef value ) ; | |
]] | |
FILE: [[javascriptcore/ffi/authors.txt]] [[Doug Coleman | |
]] | |
FILE: [[javascriptcore/authors.txt]] [[Doug Coleman | |
]] | |
FILE: [[ogg/player/player.factor]] [[! Copyright (C) 2007 Chris Double. | |
! See http://factorcode.org/license.txt for BSD license. | |
! | |
! TODO: | |
! based on number of channels in file. | |
! - End of decoding is indicated by an exception when reading the stream. | |
! How to work around this? C player example uses feof but streams don't | |
! have that in Factor. | |
! - Work out openal buffer method that plays nicely with streaming over | |
! slow connections. | |
! - Have start/stop/seek methods on the player object. | |
! | |
USING: kernel alien ogg ogg.vorbis ogg.theora io byte-arrays | |
sequences libc shuffle alien.c-types system openal math | |
namespaces threads shuffle opengl arrays ui.gadgets.worlds | |
combinators math.parser ui.gadgets ui.render opengl.gl ui | |
continuations io.files hints combinators.lib sequences.lib | |
io.encodings.binary debugger math.order accessors ; | |
IN: ogg.player | |
: audio-buffer-size ( -- number ) 128 1024 * ; inline | |
TUPLE: player stream temp-state | |
op oy og | |
vo vi vd vb vc vorbis | |
to ti tc td yuv rgb theora video-ready? video-time video-granulepos | |
source buffers buffer-indexes start-time | |
playing? audio-full? audio-index audio-buffer audio-granulepos | |
gadget ; | |
: init-vorbis ( player -- ) | |
dup oy>> ogg_sync_init drop | |
dup vi>> vorbis_info_init | |
vc>> vorbis_comment_init ; | |
: init-theora ( player -- ) | |
dup ti>> theora_info_init | |
tc>> theora_comment_init ; | |
: init-sound ( player -- ) | |
init-openal check-error | |
1 gen-buffers check-error >>buffers | |
2 uint <c-array> >>buffer-indexes | |
1 gen-sources check-error first >>source drop ; | |
: <player> ( stream -- player ) | |
player new | |
swap >>stream | |
0 >>vorbis | |
0 >>theora | |
0 >>video-time | |
0 >>video-granulepos | |
f >>video-ready? | |
f >>audio-full? | |
0 >>audio-index | |
0 >>start-time | |
audio-buffer-size "short" <c-array> >>audio-buffer | |
0 >>audio-granulepos | |
f >>playing? | |
ogg_packet malloc-struct >>op | |
ogg_sync_state malloc-struct >>oy | |
ogg_page malloc-struct >>og | |
ogg_stream_state malloc-struct >>vo | |
vorbis_info malloc-struct >>vi | |
vorbis_dsp_state malloc-struct >>vd | |
vorbis_block malloc-struct >>vb | |
vorbis_comment malloc-struct >>vc | |
ogg_stream_state malloc-struct >>to | |
theora_info malloc-struct >>ti | |
theora_comment malloc-struct >>tc | |
theora_state malloc-struct >>td | |
yuv_buffer <struct> >>yuv | |
ogg_stream_state <struct> >>temp-state | |
dup init-sound | |
dup init-vorbis | |
dup init-theora ; | |
: num-channels ( player -- channels ) | |
vi>> vorbis_info-channels ; | |
: al-channel-format ( player -- format ) | |
num-channels 1 = AL_FORMAT_MONO16 AL_FORMAT_STEREO16 ? ; | |
: get-time ( player -- time ) | |
dup start-time>> zero? [ | |
millis >>start-time | |
] when | |
start-time>> millis swap - 1000.0 /f ; | |
: clamp ( n -- n ) | |
255 min 0 max ; inline | |
: stride ( line yuv -- uvy yy ) | |
[ uv_stride>> >fixnum swap 2/ * ] 2keep | |
y_stride>> >fixnum * >fixnum ; inline | |
: each-with4 ( obj obj obj obj seq quot -- ) | |
4 each-withn ; inline | |
: compute-y ( yuv uvy yy x -- y ) | |
+ >fixnum nip swap y>> uchar-nth 16 - ; inline | |
: compute-v ( yuv uvy yy x -- v ) | |
nip 2/ + >fixnum swap u>> uchar-nth 128 - ; inline | |
: compute-u ( yuv uvy yy x -- v ) | |
nip 2/ + >fixnum swap v>> uchar-nth 128 - ; inline | |
: compute-yuv ( yuv uvy yy x -- y u v ) | |
[ compute-y ] 4keep [ compute-u ] 4keep compute-v ; inline | |
: compute-blue ( y u v -- b ) | |
drop 516 * 128 + swap 298 * + -8 shift clamp ; inline | |
: compute-green ( y u v -- g ) | |
>r >r 298 * r> 100 * - r> 208 * - 128 + -8 shift clamp ; | |
inline | |
: compute-red ( y u v -- g ) | |
nip 409 * swap 298 * + 128 + -8 shift clamp ; inline | |
: compute-rgb ( y u v -- b g r ) | |
[ compute-blue ] 3keep [ compute-green ] 3keep compute-red ; | |
inline | |
: store-rgb ( index rgb b g r -- index ) | |
>r | |
>r pick 0 + >fixnum pick set-uchar-nth | |
r> pick 1 + >fixnum pick set-uchar-nth | |
r> pick 2 + >fixnum pick set-uchar-nth | |
drop ; inline | |
: yuv>rgb-pixel ( index rgb yuv uvy yy x -- index ) | |
compute-yuv compute-rgb store-rgb 3 + >fixnum ; inline | |
: yuv>rgb-row ( index rgb yuv y -- index ) | |
over stride | |
pick y_width>> >fixnum | |
[ yuv>rgb-pixel ] each-with4 ; inline | |
: yuv>rgb ( rgb yuv -- ) | |
0 -rot | |
dup y_height>> >fixnum | |
[ yuv>rgb-row ] each-with2 | |
drop ; | |
HINTS: yuv>rgb byte-array byte-array ; | |
: process-video ( player -- player ) | |
dup gadget>> [ | |
{ | |
[ [ td>> ] [ yuv>> ] bi theora_decode_YUVout drop ] | |
[ [ rgb>> ] [ yuv>> ] bi yuv>rgb ] | |
[ gadget>> relayout-1 yield ] | |
[ ] | |
} cleave | |
] when ; | |
: num-audio-buffers-processed ( player -- player n ) | |
dup source>> AL_BUFFERS_PROCESSED 0 uint <ref> | |
[ alGetSourcei check-error ] keep uint deref ; | |
: append-new-audio-buffer ( player -- player ) | |
dup buffers>> 1 gen-buffers append >>buffers | |
[ [ buffers>> second ] keep al-channel-format ] keep | |
[ audio-buffer>> dup length ] keep | |
[ vi>> rate>> alBufferData check-error ] keep | |
[ source>> 1 ] keep | |
[ buffers>> second uint <ref> alSourceQueueBuffers check-error ] keep ; | |
: fill-processed-audio-buffer ( player n -- player ) | |
! n is the number of audio buffers processed | |
over >r >r dup source>> r> pick buffer-indexes>> | |
[ alSourceUnqueueBuffers check-error ] keep | |
uint deref dup r> swap >r al-channel-format rot | |
[ audio-buffer>> dup length ] keep | |
[ vi>> rate>> alBufferData check-error ] keep | |
[ source>> 1 ] keep | |
r> uint <ref> swap >r alSourceQueueBuffers check-error r> ; | |
: append-audio ( player -- player bool ) | |
num-audio-buffers-processed { | |
{ [ over buffers>> length 1 = over zero? and ] [ drop append-new-audio-buffer t ] } | |
{ [ over buffers>> length 2 = over zero? and ] [ yield drop f ] } | |
[ fill-processed-audio-buffer t ] | |
} cond ; | |
: start-audio ( player -- player bool ) | |
[ [ buffers>> first ] keep al-channel-format ] keep | |
[ audio-buffer>> dup length ] keep | |
[ vi>> rate>> alBufferData check-error ] keep | |
[ source>> 1 ] keep | |
[ buffers>> first uint <ref> alSourceQueueBuffers check-error ] keep | |
[ source>> alSourcePlay check-error ] keep | |
t >>playing? t ; | |
: process-audio ( player -- player bool ) | |
dup playing?>> [ append-audio ] [ start-audio ] if ; | |
: read-bytes-into ( dest size stream -- len ) | |
! Read the given number of bytes from a stream | |
! and store them in the destination byte array. | |
stream-read >byte-array dup length [ memcpy ] keep ; | |
: check-not-negative ( int -- ) | |
0 < [ "Word result was a negative number." throw ] when ; | |
: buffer-size ( -- number ) | |
4096 ; inline | |
: sync-buffer ( player -- buffer size player ) | |
[ oy>> buffer-size ogg_sync_buffer buffer-size ] keep ; | |
: stream-into-buffer ( buffer size player -- len player ) | |
[ stream>> read-bytes-into ] keep ; | |
: confirm-buffer ( len player -- player eof? ) | |
[ oy>> swap ogg_sync_wrote check-not-negative ] 2keep swap zero? ; | |
: buffer-data ( player -- player eof? ) | |
! Take some compressed bitstream data and sync it for | |
! page extraction. | |
sync-buffer stream-into-buffer confirm-buffer ; | |
: queue-page ( player -- player ) | |
! Push a page into the stream for packetization | |
[ [ vo>> ] [ og>> ] bi ogg_stream_pagein drop ] | |
[ [ to>> ] [ og>> ] bi ogg_stream_pagein drop ] | |
[ ] tri ; | |
: retrieve-page ( player -- player bool ) | |
! Sync the streams and get a page. Return true if a page was | |
! successfully retrieved. | |
dup [ oy>> ] [ og>> ] bi ogg_sync_pageout 0 > ; | |
: standard-initial-header? ( player -- player bool ) | |
dup og>> ogg_page_bos zero? not ; | |
: ogg-stream-init ( player -- state player ) | |
! Init the encode/decode logical stream state | |
[ temp-state>> ] keep | |
[ og>> ogg_page_serialno ogg_stream_init check-not-negative ] 2keep ; | |
: ogg-stream-pagein ( state player -- state player ) | |
! Add the incoming page to the stream state | |
[ og>> ogg_stream_pagein drop ] 2keep ; | |
: ogg-stream-packetout ( state player -- state player ) | |
[ op>> ogg_stream_packetout drop ] 2keep ; | |
: decode-packet ( player -- state player ) | |
ogg-stream-init ogg-stream-pagein ogg-stream-packetout ; | |
: theora-header? ( player -- player bool ) | |
! Is the current page a theora header? | |
dup [ ti>> ] [ tc>> ] [ op>> ] tri theora_decode_header 0 >= ; | |
: is-theora-packet? ( player -- player bool ) | |
dup theora>> zero? [ theora-header? ] [ f ] if ; | |
: copy-to-theora-state ( state player -- player ) | |
! Copy the state to the theora state structure in the player | |
[ to>> swap dup length memcpy ] keep ; | |
: handle-initial-theora-header ( state player -- player ) | |
copy-to-theora-state 1 >>theora ; | |
: vorbis-header? ( player -- player bool ) | |
! Is the current page a vorbis header? | |
dup [ vi>> ] [ vc>> ] [ op>> ] tri vorbis_synthesis_headerin 0 >= ; | |
: is-vorbis-packet? ( player -- player bool ) | |
dup vorbis>> zero? [ vorbis-header? ] [ f ] if ; | |
: copy-to-vorbis-state ( state player -- player ) | |
! Copy the state to the vorbis state structure in the player | |
[ vo>> swap dup length memcpy ] keep ; | |
: handle-initial-vorbis-header ( state player -- player ) | |
copy-to-vorbis-state 1 >>vorbis ; | |
: handle-initial-unknown-header ( state player -- player ) | |
swap ogg_stream_clear drop ; | |
: process-initial-header ( player -- player bool ) | |
! Is this a standard initial header? If not, stop parsing | |
standard-initial-header? [ | |
decode-packet { | |
{ [ is-vorbis-packet? ] [ handle-initial-vorbis-header ] } | |
{ [ is-theora-packet? ] [ handle-initial-theora-header ] } | |
[ handle-initial-unknown-header ] | |
} cond t | |
] [ | |
f | |
] if ; | |
: parse-initial-headers ( player -- player ) | |
! Parse Vorbis headers, ignoring any other type stored | |
! in the Ogg container. | |
retrieve-page [ | |
process-initial-header [ | |
parse-initial-headers | |
] [ | |
! Don't leak the page, get it into the appropriate stream | |
queue-page | |
] if | |
] [ | |
buffer-data not [ parse-initial-headers ] when | |
] if ; | |
: have-required-vorbis-headers? ( player -- player bool ) | |
! Return true if we need to decode vorbis due to there being | |
! vorbis headers read from the stream but we don't have them all | |
! yet. | |
dup vorbis>> 1 2 between? not ; | |
: have-required-theora-headers? ( player -- player bool ) | |
! Return true if we need to decode theora due to there being | |
! theora headers read from the stream but we don't have them all | |
! yet. | |
dup theora>> 1 2 between? not ; | |
: get-remaining-vorbis-header-packet ( player -- player bool ) | |
dup [ vo>> ] [ op>> ] bi ogg_stream_packetout { | |
{ [ dup 0 < ] [ "Error parsing vorbis stream; corrupt stream?" throw ] } | |
{ [ dup zero? ] [ drop f ] } | |
{ [ t ] [ drop t ] } | |
} cond ; | |
: get-remaining-theora-header-packet ( player -- player bool ) | |
dup [ to>> ] [ op>> ] bi ogg_stream_packetout { | |
{ [ dup 0 < ] [ "Error parsing theora stream; corrupt stream?" throw ] } | |
{ [ dup zero? ] [ drop f ] } | |
{ [ t ] [ drop t ] } | |
} cond ; | |
: decode-remaining-vorbis-header-packet ( player -- player ) | |
dup [ vi>> ] [ vc>> ] [ op>> ] tri vorbis_synthesis_headerin zero? [ | |
"Error parsing vorbis stream; corrupt stream?" throw | |
] unless ; | |
: decode-remaining-theora-header-packet ( player -- player ) | |
dup [ ti>> ] [ tc>> ] [ op>> ] tri theora_decode_header zero? [ | |
"Error parsing theora stream; corrupt stream?" throw | |
] unless ; | |
: increment-vorbis-header-count ( player -- player ) | |
[ 1+ ] change-vorbis ; | |
: increment-theora-header-count ( player -- player ) | |
[ 1+ ] change-theora ; | |
: parse-remaining-vorbis-headers ( player -- player ) | |
have-required-vorbis-headers? not [ | |
get-remaining-vorbis-header-packet [ | |
decode-remaining-vorbis-header-packet | |
increment-vorbis-header-count | |
parse-remaining-vorbis-headers | |
] when | |
] when ; | |
: parse-remaining-theora-headers ( player -- player ) | |
have-required-theora-headers? not [ | |
get-remaining-theora-header-packet [ | |
decode-remaining-theora-header-packet | |
increment-theora-header-count | |
parse-remaining-theora-headers | |
] when | |
] when ; | |
: get-more-header-data ( player -- player ) | |
buffer-data drop ; | |
: parse-remaining-headers ( player -- player ) | |
have-required-vorbis-headers? not swap have-required-theora-headers? not swapd or [ | |
parse-remaining-vorbis-headers | |
parse-remaining-theora-headers | |
retrieve-page [ queue-page ] [ get-more-header-data ] if | |
parse-remaining-headers | |
] when ; | |
: tear-down-vorbis ( player -- player ) | |
dup vi>> vorbis_info_clear | |
dup vc>> vorbis_comment_clear ; | |
: tear-down-theora ( player -- player ) | |
dup ti>> theora_info_clear | |
dup tc>> theora_comment_clear ; | |
: init-vorbis-codec ( player -- player ) | |
dup [ vd>> ] [ vi>> ] bi vorbis_synthesis_init drop | |
dup [ vd>> ] [ vb>> ] bi vorbis_block_init drop ; | |
: init-theora-codec ( player -- player ) | |
dup [ td>> ] [ ti>> ] bi theora_decode_init drop | |
dup ti>> frame_width>> over ti>> frame_height>> | |
4 * * <byte-array> >>rgb ; | |
: display-vorbis-details ( player -- player ) | |
[ | |
"Ogg logical stream " % | |
dup vo>> serialno>> # | |
" is Vorbis " % | |
dup vi>> channels>> # | |
" channel " % | |
dup vi>> rate>> # | |
" Hz audio." % | |
] "" make print ; | |
: display-theora-details ( player -- player ) | |
[ | |
"Ogg logical stream " % | |
dup to>> serialno>> # | |
" is Theora " % | |
dup ti>> width>> # | |
"x" % | |
dup ti>> height>> # | |
" " % | |
dup ti>> fps_numerator>> | |
over ti>> fps_denominator>> /f # | |
" fps video" % | |
] "" make print ; | |
: initialize-decoder ( player -- player ) | |
dup vorbis>> zero? [ tear-down-vorbis ] [ init-vorbis-codec display-vorbis-details ] if | |
dup theora>> zero? [ tear-down-theora ] [ init-theora-codec display-theora-details ] if ; | |
: sync-pages ( player -- player ) | |
retrieve-page [ | |
queue-page sync-pages | |
] when ; | |
: audio-buffer-not-ready? ( player -- player bool ) | |
dup vorbis>> zero? not over audio-full?>> not and ; | |
: pending-decoded-audio? ( player -- player pcm len bool ) | |
f <void*> 2dup >r vd>> r> vorbis_synthesis_pcmout dup 0 > ; | |
: buffer-space-available ( player -- available ) | |
audio-buffer-size swap audio-index>> - ; | |
: samples-to-read ( player available len -- numread ) | |
>r swap num-channels / r> min ; | |
: each-with3 ( obj obj obj seq quot -- ) 3 each-withn ; inline | |
: add-to-buffer ( player val -- ) | |
over audio-index>> pick audio-buffer>> set-short-nth | |
[ 1+ ] change-audio-index drop ; | |
: get-audio-value ( pcm sample channel -- value ) | |
rot *void* void*-nth float-nth ; | |
: process-channels ( player pcm sample channel -- ) | |
get-audio-value 32767.0 * >fixnum 32767 min -32768 max add-to-buffer ; | |
: (process-sample) ( player pcm sample -- ) | |
pick num-channels [ process-channels ] each-with3 ; | |
: process-samples ( player pcm numread -- ) | |
[ (process-sample) ] each-with2 ; | |
: decode-pending-audio ( player pcm result -- player ) | |
! [ "ret = " % dup # ] "" make write | |
pick [ buffer-space-available swap ] keep -rot samples-to-read | |
pick over >r >r process-samples r> r> swap | |
! numread player | |
dup audio-index>> audio-buffer-size = [ | |
t >>audio-full? | |
] when | |
dup vd>> granulepos>> dup 0 >= [ | |
! numtoread player granulepos | |
! This is wrong: fix | |
pick - >>audio-granulepos | |
] [ | |
! numtoread player granulepos | |
pick + >>audio-granulepos | |
] if | |
[ vd>> swap vorbis_synthesis_read drop ] keep ; | |
: no-pending-audio ( player -- player bool ) | |
! No pending audio. Is there a pending packet to decode. | |
dup [ vo>> ] [ op>> ] bi ogg_stream_packetout 0 > [ | |
dup [ vb>> ] [ op>> ] bi vorbis_synthesis 0 = [ | |
dup [ vd>> ] [ vb>> ] bi vorbis_synthesis_blockin drop | |
] when | |
t | |
] [ | |
! Need more data. Break out to suck in another page. | |
f | |
] if ; | |
: decode-audio ( player -- player ) | |
audio-buffer-not-ready? [ | |
! If there's pending decoded audio, grab it | |
pending-decoded-audio? [ | |
decode-pending-audio decode-audio | |
] [ | |
2drop no-pending-audio [ decode-audio ] when | |
] if | |
] when ; | |
: video-buffer-not-ready? ( player -- player bool ) | |
dup theora>> zero? not over video-ready?>> not and ; | |
: decode-video ( player -- player ) | |
video-buffer-not-ready? [ | |
dup [ to>> ] [ op>> ] bi ogg_stream_packetout 0 > [ | |
dup [ td>> ] [ op>> ] bi theora_decode_packetin drop | |
dup td>> granulepos>> >>video-granulepos | |
dup [ td>> ] [ video-granulepos>> ] bi theora_granule_time | |
>>video-time | |
t >>video-ready? | |
decode-video | |
] when | |
] when ; | |
: decode ( player -- player ) | |
get-more-header-data sync-pages | |
decode-audio | |
decode-video | |
dup audio-full?>> [ | |
process-audio [ | |
f >>audio-full? | |
0 >>audio-index | |
] when | |
] when | |
dup video-ready?>> [ | |
dup video-time>> over get-time - dup 0.0 < [ | |
-0.1 > [ process-video ] when | |
f >>video-ready? | |
] [ | |
drop | |
] if | |
] when | |
decode ; | |
: free-malloced-objects ( player -- player ) | |
{ | |
[ op>> free ] | |
[ oy>> free ] | |
[ og>> free ] | |
[ vo>> free ] | |
[ vi>> free ] | |
[ vd>> free ] | |
[ vb>> free ] | |
[ vc>> free ] | |
[ to>> free ] | |
[ ti>> free ] | |
[ tc>> free ] | |
[ td>> free ] | |
[ ] | |
} cleave ; | |
: unqueue-openal-buffers ( player -- player ) | |
[ | |
num-audio-buffers-processed over source>> rot buffer-indexes>> swapd | |
alSourceUnqueueBuffers check-error | |
] keep ; | |
: delete-openal-buffers ( player -- player ) | |
[ | |
buffers>> [ | |
1 swap uint <ref> alDeleteBuffers check-error | |
] each | |
] keep ; | |
: delete-openal-source ( player -- player ) | |
[ source>> 1 swap uint <ref> alDeleteSources check-error ] keep ; | |
: cleanup ( player -- player ) | |
free-malloced-objects | |
unqueue-openal-buffers | |
delete-openal-buffers | |
delete-openal-source ; | |
: wait-for-sound ( player -- player ) | |
! Waits for the openal to finish playing remaining sounds | |
dup source>> AL_SOURCE_STATE 0 <int> [ alGetSourcei check-error ] keep | |
*int AL_PLAYING = [ | |
100 sleep | |
wait-for-sound | |
] when ; | |
TUPLE: theora-gadget < gadget player ; | |
: <theora-gadget> ( player -- gadget ) | |
theora-gadget new-gadget | |
swap >>player ; | |
M: theora-gadget pref-dim* | |
player>> | |
ti>> dup width>> swap height>> 2array ; | |
M: theora-gadget draw-gadget* ( gadget -- ) | |
0 0 glRasterPos2i | |
1.0 -1.0 glPixelZoom | |
GL_UNPACK_ALIGNMENT 1 glPixelStorei | |
[ pref-dim* first2 GL_RGB GL_UNSIGNED_BYTE ] keep | |
player>> rgb>> glDrawPixels ; | |
: initialize-gui ( gadget -- ) | |
"Theora Player" open-window ; | |
: play-ogg ( player -- ) | |
parse-initial-headers | |
parse-remaining-headers | |
initialize-decoder | |
dup gadget>> [ initialize-gui ] when* | |
[ decode ] try | |
wait-for-sound | |
cleanup | |
drop ; | |
: play-vorbis-stream ( stream -- ) | |
<player> play-ogg ; | |
: play-vorbis-file ( filename -- ) | |
binary <file-reader> play-vorbis-stream ; | |
: play-theora-stream ( stream -- ) | |
<player> | |
dup <theora-gadget> >>gadget | |
play-ogg ; | |
: play-theora-file ( filename -- ) | |
binary <file-reader> play-theora-stream ; | |
]] | |
FILE: [[ogg/player/summary.txt]] [[Ogg vorbis and theora media player | |
]] | |
FILE: [[ogg/player/authors.txt]] [[Chris Double | |
]] | |
FILE: [[ogg/player/tags.txt]] [[audio | |
video | |
]] | |
FILE: [[furnace/callbacks/callbacks.factor]] [[! Copyright (C) 2004 Chris Double. | |
! Copyright (C) 2006, 2008 Slava Pestov. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: http http.server io kernel math namespaces | |
continuations calendar sequences assocs hashtables | |
accessors arrays alarms quotations combinators fry | |
http.server.redirection furnace assocs.lib urls ; | |
IN: furnace.callbacks | |
SYMBOL: responder | |
TUPLE: callback-responder responder callbacks ; | |
: <callback-responder> ( responder -- responder' ) | |
H{ } clone callback-responder boa ; | |
TUPLE: callback cont quot expires alarm responder ; | |
: timeout 20 minutes ; | |
: timeout-callback ( callback -- ) | |
[ alarm>> cancel-alarm ] | |
[ dup responder>> callbacks>> delete-at ] | |
bi ; | |
: touch-callback ( callback -- ) | |
dup expires>> [ | |
dup alarm>> [ cancel-alarm ] when* | |
dup '[ , timeout-callback ] timeout later >>alarm | |
] when drop ; | |
: <callback> ( cont quot expires? -- callback ) | |
f callback-responder get callback boa | |
dup touch-callback ; | |
: invoke-callback ( callback -- response ) | |
[ touch-callback ] | |
[ quot>> request get exit-continuation get 3array ] | |
[ cont>> continue-with ] | |
tri ; | |
: register-callback ( cont quot expires? -- id ) | |
<callback> callback-responder get callbacks>> set-at-unique ; | |
: forward-to-url ( url -- * ) | |
! When executed inside a 'show' call, this will force a | |
! HTTP 302 to occur to instruct the browser to forward to | |
! the request URL. | |
<temporary-redirect> exit-with ; | |
: cont-id "factorcontid" ; | |
: forward-to-id ( id -- * ) | |
! When executed inside a 'show' call, this will force a | |
! HTTP 302 to occur to instruct the browser to forward to | |
! the request URL. | |
<url> | |
swap cont-id set-query-param forward-to-url ; | |
: restore-request ( pair -- ) | |
first3 exit-continuation set request set call ; | |
SYMBOL: post-refresh-get? | |
: redirect-to-here ( -- ) | |
! Force a redirect to the client browser so that the browser | |
! goes to the current point in the code. This forces an URL | |
! change on the browser so that refreshing that URL will | |
! immediately run from this code point. This prevents the | |
! "this request will issue a POST" warning from the browser | |
! and prevents re-running the previous POST logic. This is | |
! known as the 'post-refresh-get' pattern. | |
post-refresh-get? get [ | |
[ | |
[ ] t register-callback forward-to-id | |
] callcc1 restore-request | |
] [ | |
post-refresh-get? on | |
] if ; | |
SYMBOL: current-show | |
: store-current-show ( -- ) | |
! Store the current continuation in the variable 'current-show' | |
! so it can be returned to later by 'quot-id'. Note that it | |
! recalls itself when the continuation is called to ensure that | |
! it resets its value back to the most recent show call. | |
[ current-show set f ] callcc1 | |
[ restore-request store-current-show ] when* ; | |
: show-final ( quot -- * ) | |
[ redirect-to-here store-current-show ] dip | |
call exit-with ; inline | |
: resuming-callback ( responder request -- id ) | |
url>> cont-id query-param swap callbacks>> at ; | |
M: callback-responder call-responder* ( path responder -- response ) | |
'[ | |
, , | |
[ callback-responder set ] | |
[ request get resuming-callback ] bi | |
[ | |
invoke-callback | |
] [ | |
callback-responder get responder>> call-responder | |
] ?if | |
] with-exit-continuation ; | |
: show-page ( quot -- ) | |
[ redirect-to-here store-current-show ] dip | |
[ | |
[ ] t register-callback swap call exit-with | |
] callcc1 restore-request ; inline | |
: quot-id ( quot -- id ) | |
current-show get swap t register-callback ; | |
: quot-url ( quot -- url ) | |
quot-id f swap cont-id associate derive-url ; | |
]] | |
FILE: [[furnace/callbacks/callbacks-tests.factor]] [[USING: furnace furnace.actions furnace.callbacks accessors | |
http http.server http.server.responses tools.test | |
namespaces io fry sequences | |
splitting kernel hashtables continuations ; | |
IN: furnace.callbacks.tests | |
[ 123 ] [ | |
[ | |
<request> "GET" >>method init-request | |
[ | |
exit-continuation set | |
{ } | |
<action> [ [ "hello" print 123 ] show-final ] >>display | |
<callback-responder> | |
call-responder | |
] callcc1 | |
] with-scope | |
] unit-test | |
[ | |
<action> [ | |
[ | |
"hello" print | |
<html-content> | |
] show-page | |
"byebye" print | |
[ 123 ] show-final | |
] >>display | |
<callback-responder> "r" set | |
[ 123 ] [ | |
<request> init-request | |
[ | |
exit-continuation set | |
<request> "GET" >>method init-request | |
{ } "r" get call-responder | |
] callcc1 | |
body>> first | |
<request> | |
"GET" >>method | |
dup url>> rot cont-id associate >>query drop | |
dup url>> "/" >>path drop | |
init-request | |
[ | |
exit-continuation set | |
{ } | |
"r" get call-responder | |
] callcc1 | |
! get-post-get | |
<request> | |
"GET" >>method | |
dup url>> rot "location" header query>> >>query drop | |
dup url>> "/" >>path drop | |
init-request | |
[ | |
exit-continuation set | |
{ } | |
"r" get call-responder | |
] callcc1 | |
] unit-test | |
] with-scope | |
]] | |
FILE: [[sniffer/io/bsd/bsd.factor]] [[! Copyright (C) 2007 Elie Chaftari, Doug Coleman. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: alien.c-types alien.syntax destructors hexdump io | |
io.buffers io.nonblocking io.sockets | |
io.unix.backend io.unix.files kernel libc locals math qualified | |
sequences io.sniffer.backend ; | |
QUALIFIED: unix | |
IN: io.sniffer.bsd | |
M: unix-io destruct-handle ( obj -- ) unix:close ; | |
C-UNION: ifreq_props "sockaddr-in" "short" "int" "caddr_t" ; | |
C-STRUCT: ifreq { { "char" 16 } "name" } { "ifreq_props" "props" } ; | |
TUPLE: sniffer-spec path ifname ; | |
C: <sniffer-spec> sniffer-spec | |
: IOCPARM_MASK 0x1fff ; inline | |
: IOCPARM_MAX IOCPARM_MASK 1+ ; inline | |
: IOC_VOID 0x20000000 ; inline | |
: IOC_OUT 0x40000000 ; inline | |
: IOC_IN 0x80000000 ; inline | |
: IOC_INOUT IOC_IN IOC_OUT bitor ; inline | |
: IOC_DIRMASK 0xe0000000 ; inline | |
:: ioc ( inout group num len -- n ) | |
group first 8 shift num bitor | |
len IOCPARM_MASK bitand 16 shift bitor | |
inout bitor ; | |
: io-len ( type -- n ) | |
dup zero? [ heap-size ] unless ; | |
: io ( group num -- n ) | |
IOC_VOID -rot 0 io-len ioc ; | |
: ior ( group num type -- n ) | |
IOC_OUT -roll io-len ioc ; | |
: iow ( group num type -- n ) | |
IOC_IN -roll io-len ioc ; | |
: iowr ( group num type -- n ) | |
IOC_INOUT -roll io-len ioc ; | |
: BIOCGBLEN ( -- n ) "B" 102 "uint" ior ; inline | |
: BIOCSETIF ( -- n ) "B" 108 "ifreq" iow ; inline | |
: BIOCPROMISC ( -- n ) "B" 105 io ; inline | |
: BIOCIMMEDIATE ( -- n ) "B" 112 "uint" iow ; inline | |
: make-ifreq-props ( ifname -- ifreq ) | |
"ifreq" <c-object> | |
12 <short> 16 0 pad-right over set-ifreq-props | |
swap malloc-char-string dup free-always | |
over set-ifreq-name ; | |
: make-ioctl-buffer ( fd -- buffer ) | |
BIOCGBLEN "char*" <c-object> | |
[ unix:ioctl io-error ] keep | |
*int <buffer> ; | |
: ioctl-BIOSETIF ( fd ifreq -- ) | |
>r BIOCSETIF r> unix:ioctl io-error ; | |
: ioctl-BIOPROMISC ( fd -- ) | |
BIOCPROMISC f unix:ioctl io-error ; | |
: ioctl-BIOCIMMEDIATE | |
BIOCIMMEDIATE 1 <int> unix:ioctl io-error ; | |
: ioctl-sniffer-fd ( fd ifname -- ) | |
dupd make-ifreq-props ioctl-BIOSETIF | |
dup ioctl-BIOPROMISC | |
ioctl-BIOCIMMEDIATE ; | |
M: unix-io <sniffer> ( obj -- sniffer ) | |
[ | |
[ | |
sniffer-spec-path | |
open-read | |
dup close-later | |
] keep | |
dupd sniffer-spec-ifname ioctl-sniffer-fd | |
dup make-ioctl-buffer | |
input-port <port> <line-reader> | |
\ sniffer construct-delegate | |
] with-destructors ; | |
]] | |
FILE: [[sniffer/io/bsd/authors.txt]] [[Doug Coleman | |
Elie Chaftari | |
]] | |
FILE: [[sniffer/io/backend/backend.factor]] [[USING: io.backend kernel system vocabs.loader ; | |
IN: io.sniffer.backend | |
SYMBOL: sniffer-type | |
TUPLE: sniffer ; | |
HOOK: <sniffer> io-backend ( obj -- sniffer ) | |
]] | |
FILE: [[sniffer/io/backend/authors.txt]] [[Doug Coleman | |
Elie Chaftari | |
]] | |
FILE: [[sniffer/io/filter/bsd/bsd.factor]] [[USING: alien.c-types hexdump io io.backend io.sockets.headers | |
io.sockets.headers.bsd kernel io.sniffer io.sniffer.bsd | |
io.streams.string io.unix.backend math | |
sequences system byte-arrays io.sniffer.filter.backend | |
io.sniffer.filter.backend io.sniffer.backend ; | |
IN: io.sniffer.filter.bsd | |
! http://www.iana.org/assignments/ethernet-numbers | |
: bpf-align ( n -- n' ) | |
! Align to next higher word size | |
"long" heap-size align ; | |
M: unix-io packet. ( string -- ) | |
18 cut swap >byte-array bpfh. | |
(packet.) ; | |
M: unix-io sniffer-loop ( stream -- ) | |
nl nl | |
4096 over stream-read-partial | |
dup hexdump. | |
packet. | |
sniffer-loop ; | |
! Mac | |
: sniff-wired ( -- ) | |
"/dev/bpf0" "en0" <sniffer-spec> <sniffer> sniffer-loop ; | |
! Macbook | |
: sniff-wireless ( -- ) | |
"/dev/bpf0" "en1" <sniffer-spec> <sniffer> sniffer-loop ; | |
]] | |
FILE: [[sniffer/io/filter/bsd/authors.txt]] [[Doug Coleman | |
Elie Chaftari | |
]] | |
FILE: [[sniffer/io/filter/backend/backend.factor]] [[USING: byte-arrays combinators io io.backend | |
io.sockets.headers io.sniffer.backend kernel | |
prettyprint sequences ; | |
IN: io.sniffer.filter.backend | |
HOOK: sniffer-loop io-backend ( stream -- ) | |
HOOK: packet. io-backend ( string -- ) | |
: (packet.) ( string -- ) | |
dup 14 head >byte-array | |
"--Ethernet Header--" print | |
dup etherneth. | |
dup etherneth-type { | |
! 0x800 [ ] ! IP | |
! 0x806 [ ] ! ARP | |
[ "Unknown type: " write .h ] | |
} case 2drop ; | |
]] | |
FILE: [[sniffer/io/filter/backend/authors.txt]] [[Doug Coleman | |
Elie Chaftari | |
]] | |
FILE: [[sniffer/io/filter/authors.txt]] [[Doug Coleman | |
Elie Chaftari | |
]] | |
FILE: [[sniffer/io/filter/filter.factor]] [[USING: alien.c-types byte-arrays combinators hexdump io | |
io.backend io.streams.string io.sockets.headers kernel math | |
prettyprint io.sniffer sequences system vocabs.loader | |
io.sniffer.filter.backend ; | |
IN: io.sniffer.filter | |
bsd? [ "io.sniffer.filter.bsd" require ] when | |
]] | |
FILE: [[sniffer/io/sniffer.factor]] [[USING: io.backend kernel system vocabs.loader ; | |
IN: io.sniffer | |
bsd? [ "io.sniffer.bsd" require ] when | |
]] | |
FILE: [[sniffer/io/authors.txt]] [[Doug Coleman | |
Elie Chaftari | |
]] | |
FILE: [[sniffer/channels/bsd/bsd.factor]] [[! Copyright (C) 2007 Chris Double. All Rights Reserved. | |
! See http://factorcode.org/license.txt for BSD license. | |
! | |
! Wrap a sniffer in a channel | |
USING: kernel channels channels.sniffer.backend | |
threads io io.sniffer.backend io.sniffer.bsd | |
io.unix.backend ; | |
IN: channels.sniffer.bsd | |
M: unix-io sniff-channel ( -- channel ) | |
"/dev/bpf0" "en1" <sniffer-spec> <sniffer> <channel> [ | |
[ | |
(sniff-channel) | |
] 3curry spawn drop | |
] keep ; | |
]] | |
FILE: [[sniffer/channels/backend/backend.factor]] [[USING: io.backend ; | |
HOOK: sniff-channel io-backend ( -- channel ) | |
]] | |
FILE: [[sniffer/channels/sniffer.factor]] [[! Copyright (C) 2007 Chris Double. All Rights Reserved. | |
! See http://factorcode.org/license.txt for BSD license. | |
! | |
! Wrap a sniffer in a channel | |
USING: kernel channels io io.backend io.sniffer | |
io.sniffer.backend system vocabs.loader ; | |
: (sniff-channel) ( stream channel -- ) | |
4096 pick stream-read-partial over to (sniff-channel) ; | |
bsd? [ "channels.sniffer.bsd" require ] when | |
]] | |
FILE: [[automata/ui/ui.factor]] [[ | |
USING: kernel namespaces math quotations arrays hashtables sequences threads | |
opengl | |
opengl.gl | |
colors | |
ui | |
ui.gestures | |
ui.gadgets | |
ui.gadgets.slate | |
ui.gadgets.labels | |
ui.gadgets.buttons | |
ui.gadgets.frames | |
ui.gadgets.packs | |
ui.gadgets.grids | |
ui.gadgets.theme | |
ui.gadgets.handler | |
accessors | |
vars fry | |
rewrite-closures automata math.geometry.rect newfx ; | |
IN: automata.ui | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: draw-point ( y x value -- ) 1 = [ swap glVertex2i ] [ 2drop ] if ; | |
: draw-line ( y line -- ) 0 swap [ [ 2dup ] dip draw-point 1+ ] each 2drop ; | |
: (draw-bitmap) ( bitmap -- ) 0 swap [ [ dup ] dip draw-line 1+ ] each drop ; | |
: draw-bitmap ( bitmap -- ) GL_POINTS glBegin (draw-bitmap) glEnd ; | |
: display ( -- ) black gl-color bitmap> draw-bitmap ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
VAR: slate | |
! Call a 'model' quotation with the current 'view'. | |
: with-view ( quot -- ) | |
slate> rect-dim first >width | |
slate> rect-dim second >height | |
call | |
slate> relayout-1 ; | |
! Create a quotation that is appropriate for buttons and gesture handler. | |
: view-action ( quot -- quot ) '[ drop _ with-view ] closed-quot ; | |
: view-button ( label quot -- button ) [ <label> ] dip view-action <bevel-button> ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! Helper word to make things less verbose | |
: random-rule ( -- ) set-interesting start-center ; | |
DEFER: automata-window | |
: automata-window* ( -- ) | |
init-rule | |
set-interesting | |
<frame> | |
<shelf> | |
"1 - Center" [ start-center ] view-button add-gadget | |
"2 - Random" [ start-random ] view-button add-gadget | |
"3 - Continue" [ run-rule ] view-button add-gadget | |
"5 - Random Rule" [ random-rule ] view-button add-gadget | |
"n - New" [ automata-window ] view-button add-gadget | |
@top grid-add | |
C[ display ] <slate> | |
{ 400 400 } >>pdim | |
dup >slate | |
@center grid-add | |
<handler> | |
H{ } | |
T{ key-down f f "1" } [ start-center ] view-action is | |
T{ key-down f f "2" } [ start-random ] view-action is | |
T{ key-down f f "3" } [ run-rule ] view-action is | |
T{ key-down f f "5" } [ random-rule ] view-action is | |
T{ key-down f f "n" } [ automata-window ] view-action is | |
>>table | |
"Automata" open-window ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: automata-window ( -- ) [ [ automata-window* ] with-scope ] with-ui ; | |
MAIN: automata-window | |
]] | |
FILE: [[automata/ui/deploy.factor]] [[USING: tools.deploy.config ; | |
V{ | |
{ deploy-ui? t } | |
{ deploy-io 1 } | |
{ deploy-reflection 1 } | |
{ deploy-compiler? t } | |
{ deploy-math? t } | |
{ deploy-word-props? f } | |
{ deploy-c-types? f } | |
{ "stop-after-last-window?" t } | |
{ deploy-name "Cellular Automata" } | |
} | |
]] | |
FILE: [[automata/ui/authors.txt]] [[Eduardo Cavazos | |
]] | |
FILE: [[automata/ui/tags.txt]] [[demos | |
]] | |
FILE: [[automata/automata.factor]] [[ | |
USING: kernel math math.parser random arrays hashtables assocs sequences | |
grouping vars ; | |
IN: automata | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! set-rule | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
VAR: rule VAR: rule-number | |
: init-rule ( -- ) 8 <hashtable> >rule ; | |
: rule-keys ( -- array ) | |
{ { 1 1 1 } | |
{ 1 1 0 } | |
{ 1 0 1 } | |
{ 1 0 0 } | |
{ 0 1 1 } | |
{ 0 1 0 } | |
{ 0 0 1 } | |
{ 0 0 0 } } ; | |
: rule-values ( n -- seq ) >bin 8 CHAR: 0 pad-head string>digits ; | |
: set-rule ( n -- ) | |
dup >rule-number rule-values rule-keys [ rule> set-at ] 2each ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! step-capped-line | |
! step-wrapped-line | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: pattern>state ( {_a_b_c_} -- state ) rule> at ; | |
: cap-line ( line -- 0-line-0 ) { 0 } prepend { 0 } append ; | |
: wrap-line ( a-line-z -- za-line-za ) | |
dup peek 1array swap dup first 1array append append ; | |
: step-line ( line -- new-line ) 3 <clumps> [ pattern>state ] map ; | |
: step-capped-line ( line -- new-line ) cap-line step-line ; | |
: step-wrapped-line ( line -- new-line ) wrap-line step-line ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
VARS: width height ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: random-line ( -- line ) width> [ drop 2 random ] map ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: center-i ( -- i ) width> 2 / >fixnum ; | |
: center-line ( -- line ) center-i width> [ = 1 0 ? ] with map ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: interesting ( -- seq ) | |
{ 18 22 26 30 41 45 54 60 73 75 82 86 89 90 97 101 102 105 106 107 109 | |
110 120 121 122 124 126 129 137 146 147 149 150 151 153 154 161 165 } ; | |
: mild ( -- seq ) { 6 9 11 57 62 74 118 } ; | |
: set-interesting ( -- ) interesting random set-rule ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
VAR: bitmap | |
VAR: last-line | |
: run-rule ( -- ) | |
last-line> height> [ drop step-capped-line dup ] map >bitmap >last-line ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: start-random ( -- ) random-line >last-line run-rule ; | |
: start-center ( -- ) center-line >last-line run-rule ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! VAR: loop-flag | |
! DEFER: loop | |
! : (loop) ( -- ) run-rule 3000 sleep loop ; | |
! : loop ( -- ) loop-flag> [ (loop) ] [ ] if ; | |
! : start-loop ( -- ) t >loop-flag [ loop ] in-thread ; | |
! : stop-loop ( -- ) f >loop-flag ; | |
]] | |
FILE: [[automata/summary.txt]] [[Cellular Automata Explorer (one dimensional, two state) | |
]] | |
FILE: [[automata/authors.txt]] [[Eduardo Cavazos | |
]] | |
FILE: [[LICENSE]] [[Redistribution and use in source and binary forms, with or without | |
modification, are permitted provided that the following conditions are met: | |
1. Redistributions of source code must retain the above copyright notice, | |
this list of conditions and the following disclaimer. | |
2. Redistributions in binary form must reproduce the above copyright notice, | |
this list of conditions and the following disclaimer in the documentation | |
and/or other materials provided with the distribution. | |
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, | |
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND | |
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | |
DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | |
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | |
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
]] | |
FILE: [[update/util/util.factor]] [[ | |
USING: kernel classes strings quotations words math math.parser arrays | |
combinators.smart | |
accessors | |
system prettyprint splitting | |
sequences combinators sequences.deep | |
io | |
io.launcher | |
io.encodings.utf8 | |
calendar | |
calendar.format ; | |
IN: update.util | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
DEFER: to-strings | |
: to-string ( obj -- str ) | |
dup class-of | |
{ | |
{ \ string [ ] } | |
{ \ quotation [ call( -- string ) ] } | |
{ \ word [ execute( -- string ) ] } | |
{ \ fixnum [ number>string ] } | |
{ \ array [ to-strings concat ] } | |
} | |
case ; | |
: to-strings ( seq -- str ) | |
dup [ string? ] all? | |
[ ] | |
[ [ to-string ] map flatten ] | |
if ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: cpu- ( -- cpu ) cpu unparse "." split "-" join ; | |
: platform ( -- string ) { [ os unparse ] cpu- } to-strings "-" join ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: branch-name ( -- string ) "clean-" platform append ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: gnu-make ( -- string ) | |
"make" ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: git-id ( -- id ) | |
{ "git" "show" } utf8 [ readln ] with-process-reader | |
" " split second ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: datestamp ( -- string ) | |
now | |
[ { [ year>> ] [ month>> ] [ day>> ] [ hour>> ] [ minute>> ] } cleave ] output>array | |
[ pad-00 ] map "-" join ; | |
]] | |
FILE: [[update/update.factor]] [[USING: kernel system sequences io.files io.directories | |
io.pathnames io.launcher bootstrap.image http.client update.util ; | |
IN: update | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: run-command ( cmd -- ) to-strings try-process ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: git-pull-clean ( -- ) | |
image-path parent-directory [ | |
{ "git" "pull" "git://factorcode.org/git/factor.git" branch-name } | |
run-command | |
] with-directory ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: remote-clean-image ( -- url ) | |
{ "http://factorcode.org/images/clean/" platform "/" my-boot-image-name } | |
to-string ; | |
: download-clean-image ( -- ) remote-clean-image download ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: make-clean ( -- ) { gnu-make "clean" } run-command ; | |
: make ( -- ) { gnu-make } run-command ; | |
: boot ( -- ) { "./factor" { "-i=" my-boot-image-name } } run-command ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: rebuild ( -- ) | |
image-path parent-directory [ | |
download-clean-image | |
make-clean | |
make | |
boot | |
] with-directory ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: update ( -- ) | |
image-path parent-directory [ | |
git-id | |
git-pull-clean | |
git-id | |
= not | |
[ rebuild ] | |
when | |
] with-directory ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
MAIN: update | |
]] | |
FILE: [[update/latest/latest.factor]] [[USING: kernel namespaces system io.files io.pathnames io.directories | |
bootstrap.image http.client update update.backup update.util ; | |
IN: update.latest | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: git-pull-master ( -- ) | |
image-path parent-directory | |
[ | |
{ "git" "pull" "git://factorcode.org/git/factor.git" "master" } | |
run-command | |
] | |
with-directory ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: remote-latest-image ( -- url ) | |
{ "http://factorcode.org/images/latest/" my-boot-image-name } to-string ; | |
: download-latest-image ( -- ) remote-latest-image download ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: rebuild-latest ( -- ) | |
image-path parent-directory | |
[ | |
backup | |
download-latest-image | |
make-clean | |
make | |
boot | |
] | |
with-directory ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: update-latest ( -- ) | |
image-path parent-directory | |
[ | |
git-id | |
git-pull-master | |
git-id | |
= not | |
[ rebuild-latest ] | |
when | |
] | |
with-directory ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
MAIN: update-latest | |
]] | |
FILE: [[update/backup/backup.factor]] [[USING: namespaces debugger io.files io.directories | |
bootstrap.image update.util ; | |
IN: update.backup | |
: backup-boot-image ( -- ) | |
my-boot-image-name | |
{ "boot." my-arch-name "-" [ "datestamp" get ] ".image" } to-string | |
move-file ; | |
: backup-image ( -- ) | |
"factor.image" | |
{ "factor" "-" [ "datestamp" get ] ".image" } to-string | |
move-file ; | |
: backup-vm ( -- ) | |
"factor" | |
{ "factor" "-" [ "datestamp" get ] } to-string | |
move-file ; | |
: backup ( -- ) | |
datestamp "datestamp" set | |
[ | |
backup-boot-image | |
backup-image | |
backup-vm | |
] | |
try ; | |
]] | |
FILE: [[adsoda/tools/tools.factor]] [[! Copyright (C) 2008 Jeff Bigot | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: | |
kernel | |
sequences | |
math | |
accessors | |
adsoda | |
math.vectors | |
math.matrices | |
bunny.model | |
io.encodings.ascii | |
io.files | |
sequences.deep | |
combinators | |
adsoda.combinators | |
fry | |
io.files.temp | |
grouping | |
; | |
IN: adsoda.tools | |
! --------------------------------- | |
: coord-min ( x array -- array ) swap suffix ; | |
: coord-max ( x array -- array ) swap neg suffix ; | |
: 4cube ( array name -- solid ) | |
! array : xmin xmax ymin ymax zmin zmax wmin wmax | |
<solid> | |
4 >>dimension | |
swap >>name | |
swap | |
{ | |
[ { 1 0 0 0 } coord-min ] [ { -1 0 0 0 } coord-max ] | |
[ { 0 1 0 0 } coord-min ] [ { 0 -1 0 0 } coord-max ] | |
[ { 0 0 1 0 } coord-min ] [ { 0 0 -1 0 } coord-max ] | |
[ { 0 0 0 1 } coord-min ] [ { 0 0 0 -1 } coord-max ] | |
} | |
[ curry call ] 2map | |
[ cut-solid ] each | |
ensure-adjacencies | |
; inline | |
: 3cube ( array name -- solid ) | |
! array : xmin xmax ymin ymax zmin zmax wmin wmax | |
<solid> | |
3 >>dimension | |
swap >>name | |
swap | |
{ | |
[ { 1 0 0 } coord-min ] [ { -1 0 0 } coord-max ] | |
[ { 0 1 0 } coord-min ] [ { 0 -1 0 } coord-max ] | |
[ { 0 0 1 } coord-min ] [ { 0 0 -1 } coord-max ] | |
} | |
[ curry call ] 2map | |
[ cut-solid ] each | |
ensure-adjacencies | |
; inline | |
: equation-system-for-normal ( points -- matrix ) | |
unclip [ v- 0 suffix ] curry map | |
dup first [ drop 1 ] map suffix | |
; | |
: normal-vector ( points -- v ) | |
equation-system-for-normal | |
intersect-hyperplanes ; | |
: points-to-hyperplane ( points -- hyperplane ) | |
[ normal-vector 0 suffix ] [ first ] bi | |
translate ; | |
: refs-to-points ( points faces -- faces ) | |
[ swap [ nth 10 v*n { 100 100 100 } v+ ] curry map ] | |
with map | |
; | |
! V{ { 0.1 0.2 } { 1.1 1.3 } } V{ { 1 0 } { 0 1 } } | |
! V{ { { 1.1 1.3 } { 0.1 0.2 } } { { 0.1 0.2 } { 1.1 1.3 } } } | |
: ply-model-path ( -- path ) | |
! "bun_zipper.ply" | |
"screw2.ply" | |
temp-file | |
; | |
: read-bunny-model ( -- v ) | |
ply-model-path ascii [ parse-model ] with-file-reader | |
refs-to-points | |
; | |
: 3points-to-normal ( seq -- v ) | |
unclip [ v- ] curry map first2 cross normalize | |
; | |
: 2-faces-to-prism ( seq seq -- seq ) | |
2dup | |
[ do-cycle 2 clump ] bi@ concat-nth | |
! 3 faces rectangulaires | |
swap prefix | |
swap prefix | |
; | |
: Xpoints-to-prisme ( seq height -- cube ) | |
! from 3 points gives a list of faces representing | |
! a cube of height "height" | |
! and of based on the three points | |
! a face is a group of 3 or mode points. | |
[ dup dup 3points-to-normal ] dip | |
v*n [ v+ ] curry map ! 2 eme face triangulaire | |
2-faces-to-prism | |
! [ dup number? [ 1 + ] when ] deep-map | |
! dup keep | |
; | |
: Xpoints-to-plane4D ( seq x y -- 4Dplane ) | |
! from 3 points gives a list of faces representing | |
! a cube in 4th dim | |
! from x to y (height = y-x) | |
! and of based on the X points | |
! a face is a group of 3 or mode points. | |
'[ [ [ _ suffix ] map ] [ [ _ suffix ] map ] bi ] call | |
2-faces-to-prism | |
; | |
: 3pointsfaces-to-3Dsolidfaces ( seq -- seq ) | |
[ 1 Xpoints-to-prisme [ 100 | |
110 Xpoints-to-plane4D ] map concat ] map | |
; | |
: test-figure ( -- solid ) | |
<solid> | |
2 >>dimension | |
{ 1 -1 -5 } cut-solid | |
{ -1 -1 -21 } cut-solid | |
{ -1 0 -12 } cut-solid | |
{ 1 2 16 } cut-solid | |
; | |
]] | |
FILE: [[adsoda/tools/tools-docs.factor]] [[! Copyright (C) 2008 Jeff Bigot. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: arrays help.markup help.syntax kernel sequences ; | |
IN: adsoda.tools | |
HELP: 3cube | |
{ $values | |
{ "array" "array" } { "name" "name" } | |
{ "solid" "solid" } | |
} | |
{ $description "array : xmin xmax ymin ymax zmin zmax" | |
"returns a 3D solid with given limits" | |
} ; | |
HELP: 4cube | |
{ $values | |
{ "array" "array" } { "name" "name" } | |
{ "solid" "solid" } | |
} | |
{ $description "array : xmin xmax ymin ymax zmin zmax wmin wmax" | |
"returns a 4D solid with given limits" | |
} ; | |
HELP: equation-system-for-normal | |
{ $values | |
{ "points" "a list of n points" } | |
{ "matrix" "matrix" } | |
} | |
{ $description "From a list of points, return the matrix" | |
"to solve in order to find the vector normal to the plan defined by the points" } | |
; | |
HELP: normal-vector | |
{ $values | |
{ "points" "a list of n points" } | |
{ "v" "a vector" } | |
} | |
{ $description "From a list of points, returns the vector normal to the plan defined by the points" | |
"With n points, creates n-1 vectors and then find a vector orthogonal to every others" | |
"returns { f } if a normal vector can not be found" } | |
; | |
HELP: points-to-hyperplane | |
{ $values | |
{ "points" "a list of n points" } | |
{ "hyperplane" "an hyperplane equation" } | |
} | |
{ $description "From a list of points, returns the equation of the hyperplan" | |
"Finds a normal vector and then translate it so that it includes one of the points" | |
} | |
; | |
ARTICLE: "adsoda.tools" "Tools" | |
{ $vocab-link "adsoda.tools" } | |
"Tools to help in building an " { $vocab-link "adsoda" } "-space" | |
; | |
ABOUT: "adsoda.tools" | |
]] | |
FILE: [[adsoda/tools/authors.txt]] [[Jeff Bigot | |
]] | |
FILE: [[adsoda/tools/tools-tests.factor]] [[! Copyright (C) 2008 Jeff Bigot | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: | |
adsoda.tools | |
tools.test | |
; | |
IN: adsoda.tools.tests | |
[ { 1 0 } ] [ { { 0 0 } { 0 1 } } normal-vector ] unit-test | |
[ f ] [ { { 0 0 } { 0 0 } } normal-vector ] unit-test | |
[ { 1/2 1/2 1+1/2 } ] [ { { 1 2 } { 2 1 } } points-to-hyperplane ] unit-test | |
]] | |
FILE: [[adsoda/adsoda.factor]] [[! Copyright (C) 2008 Jeff Bigot | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: accessors | |
arrays | |
assocs | |
combinators | |
kernel | |
fry | |
math | |
math.constants | |
math.functions | |
math.libm | |
math.order | |
math.vectors | |
math.matrices | |
math.parser | |
namespaces | |
prettyprint | |
sequences | |
sequences.deep | |
sets | |
slots | |
sorting | |
tools.time | |
vars | |
continuations | |
words | |
opengl | |
opengl.gl | |
colors | |
adsoda.solution2 | |
adsoda.combinators | |
opengl.demo-support | |
values | |
tools.walker | |
; | |
IN: adsoda | |
DEFER: combinations | |
VAR: pv | |
! ------------------------------------------------------------- | |
! global values | |
VALUE: remove-hidden-solids? | |
VALUE: VERY-SMALL-NUM | |
VALUE: ZERO-VALUE | |
VALUE: MAX-FACE-PER-CORNER | |
t \ remove-hidden-solids? set-value | |
0.0000001 \ VERY-SMALL-NUM set-value | |
0.0000001 \ ZERO-VALUE set-value | |
4 \ MAX-FACE-PER-CORNER set-value | |
! ------------------------------------------------------------- | |
! sequence complement | |
: with-pv ( i quot -- ) [ swap >pv call ] with-scope ; inline | |
: dimension ( array -- x ) length 1 - ; inline | |
: change-last ( seq quot -- ) | |
[ [ dimension ] keep ] dip change-nth ; inline | |
! ------------------------------------------------------------- | |
! light | |
! ------------------------------------------------------------- | |
TUPLE: light name { direction array } color ; | |
: <light> ( -- tuple ) light new ; | |
! ------------------------------------------------------------- | |
! halfspace manipulation | |
! ------------------------------------------------------------- | |
: constant+ ( v x -- w ) '[ [ _ + ] change-last ] keep ; | |
: translate ( u v -- w ) dupd v* sum constant+ ; | |
: transform ( u matrix -- w ) | |
[ swap m.v ] 2keep ! compute new normal vector | |
[ | |
[ [ abs ZERO-VALUE > ] find ] keep | |
! find a point on the frontier | |
! be sure it's not null vector | |
last ! get constant | |
swap /f neg swap ! intercept value | |
] dip | |
flip | |
nth | |
[ * ] with map ! apply intercep value | |
over v* | |
sum neg | |
suffix ! add value as constant at the end of equation | |
; | |
: position-point ( halfspace v -- x ) | |
-1 suffix v* sum ; inline | |
: point-inside-halfspace? ( halfspace v -- ? ) | |
position-point VERY-SMALL-NUM > ; | |
: point-inside-or-on-halfspace? ( halfspace v -- ? ) | |
position-point VERY-SMALL-NUM neg > ; | |
: project-vector ( seq -- seq ) | |
pv> [ head ] [ 1 + tail ] 2bi append ; | |
: get-intersection ( matrice -- seq ) | |
[ 1 tail* ] map flip first ; | |
: islenght=? ( seq n -- seq n ? ) 2dup [ length ] [ = ] bi* ; | |
: compare-nleft-to-identity-matrix ( seq n -- ? ) | |
[ [ head ] curry map ] keep identity-matrix m- | |
flatten | |
[ abs ZERO-VALUE < ] all? | |
; | |
: valid-solution? ( matrice n -- ? ) | |
islenght=? | |
[ compare-nleft-to-identity-matrix ] | |
[ 2drop f ] if ; inline | |
: intersect-hyperplanes ( matrice -- seq ) | |
[ solution dup ] [ first dimension ] bi | |
valid-solution? [ get-intersection ] [ drop f ] if ; | |
! ------------------------------------------------------------- | |
! faces | |
! ------------------------------------------------------------- | |
TUPLE: face { halfspace array } | |
touching-corners adjacent-faces ; | |
: <face> ( v -- tuple ) face new swap >>halfspace ; | |
: flip-face ( face -- face ) [ vneg ] change-halfspace ; | |
: erase-face-touching-corners ( face -- face ) | |
f >>touching-corners ; | |
: erase-face-adjacent-faces ( face -- face ) | |
f >>adjacent-faces ; | |
: faces-intersection ( faces -- v ) | |
[ halfspace>> ] map intersect-hyperplanes ; | |
: face-translate ( face v -- face ) | |
[ translate ] curry change-halfspace ; inline | |
: face-transform ( face m -- face ) | |
[ transform ] curry change-halfspace ; inline | |
: face-orientation ( face -- x ) pv> swap halfspace>> nth sgn ; | |
: backface? ( face -- face ? ) dup face-orientation 0 <= ; | |
: pv-factor ( face -- f face ) | |
halfspace>> [ pv> swap nth [ * ] curry ] keep ; inline | |
: suffix-touching-corner ( face corner -- face ) | |
[ suffix ] curry change-touching-corners ; inline | |
: real-face? ( face -- ? ) | |
[ touching-corners>> length ] | |
[ halfspace>> dimension ] bi >= ; | |
: (add-to-adjacent-faces) ( face face -- face ) | |
over adjacent-faces>> 2dup member? | |
[ 2drop ] [ swap suffix >>adjacent-faces ] if ; | |
: add-to-adjacent-faces ( face face -- face ) | |
2dup = [ drop ] [ (add-to-adjacent-faces) ] if ; | |
: update-adjacent-faces ( faces corner -- ) | |
'[ [ _ suffix-touching-corner drop ] each ] keep | |
2 among [ | |
[ first ] keep second | |
[ add-to-adjacent-faces drop ] 2keep | |
swap add-to-adjacent-faces drop | |
] each ; inline | |
: face-project-dim ( face -- x ) halfspace>> length 2 - ; | |
: apply-light ( color light normal -- u ) | |
over direction>> v. | |
neg dup 0 > | |
[ | |
[ color>> swap ] dip | |
[ * ] curry map v+ | |
[ 1 min ] map | |
] | |
[ 2drop ] | |
if | |
; | |
: enlight-projection ( array face -- color ) | |
! array = lights + ambient color | |
[ [ third ] [ second ] [ first ] tri ] | |
[ halfspace>> project-vector normalize ] bi* | |
[ apply-light ] curry each | |
v* | |
; | |
: (intersection-into-face) ( face-init face-adja quot -- face ) | |
[ | |
[ [ pv-factor ] bi@ | |
roll | |
[ map ] 2bi@ | |
v- | |
] 2keep | |
[ touching-corners>> ] bi@ | |
[ swap [ = ] curry find nip f = ] curry find nip | |
] dip over | |
[ | |
call | |
dupd | |
point-inside-halfspace? [ vneg ] unless | |
<face> | |
] [ 3drop f ] if | |
; inline | |
: intersection-into-face ( face-init face-adja -- face ) | |
[ [ project-vector ] bi@ ] (intersection-into-face) ; | |
: intersection-into-silhouette-face ( face-init face-adja -- face ) | |
[ ] (intersection-into-face) ; | |
: intersections-into-faces ( face -- faces ) | |
clone dup | |
adjacent-faces>> [ intersection-into-face ] with map | |
sift ; | |
: (face-silhouette) ( face -- faces ) | |
clone dup adjacent-faces>> | |
[ backface? | |
[ intersection-into-silhouette-face ] [ 2drop f ] if | |
] with map | |
sift | |
; inline | |
: face-silhouette ( face -- faces ) | |
backface? [ drop f ] [ (face-silhouette) ] if ; | |
! -------------------------------- | |
! solid | |
! ------------------------------------------------------------- | |
TUPLE: solid dimension silhouettes | |
faces corners adjacencies-valid color name ; | |
: <solid> ( -- tuple ) solid new ; | |
: suffix-silhouettes ( solid silhouette -- solid ) | |
[ suffix ] curry change-silhouettes ; | |
: suffix-face ( solid face -- solid ) | |
[ suffix ] curry change-faces ; | |
: suffix-corner ( solid corner -- solid ) | |
[ suffix ] curry change-corners ; | |
: erase-solid-corners ( solid -- solid ) f >>corners ; | |
: erase-silhouettes ( solid -- solid ) | |
dup dimension>> f <array> >>silhouettes ; | |
: filter-real-faces ( solid -- solid ) | |
[ [ real-face? ] filter ] change-faces ; | |
: initiate-solid-from-face ( face -- solid ) | |
face-project-dim <solid> swap >>dimension ; | |
: erase-old-adjacencies ( solid -- solid ) | |
erase-solid-corners | |
[ dup [ erase-face-touching-corners | |
erase-face-adjacent-faces drop ] each ] | |
change-faces ; | |
: point-inside-or-on-face? ( face v -- ? ) | |
[ halfspace>> ] dip point-inside-or-on-halfspace? ; | |
: point-inside-face? ( face v -- ? ) | |
[ halfspace>> ] dip point-inside-halfspace? ; | |
: point-inside-solid? ( solid point -- ? ) | |
[ faces>> ] dip [ point-inside-face? ] curry all? ; inline | |
: point-inside-or-on-solid? ( solid point -- ? ) | |
[ faces>> ] dip | |
[ point-inside-or-on-face? ] curry all? ; inline | |
: unvalid-adjacencies ( solid -- solid ) | |
erase-old-adjacencies f >>adjacencies-valid | |
erase-silhouettes ; | |
: add-face ( solid face -- solid ) | |
suffix-face unvalid-adjacencies ; | |
: cut-solid ( solid halfspace -- solid ) <face> add-face ; | |
: slice-solid ( solid face -- solid1 solid2 ) | |
[ [ clone ] bi@ flip-face add-face | |
[ "/outer/" append ] change-name ] 2keep | |
add-face [ "/inner/" append ] change-name ; | |
! ------------- | |
: add-silhouette ( solid -- solid ) | |
dup | |
! find-adjacencies | |
faces>> { } | |
[ face-silhouette append ] reduce | |
sift | |
<solid> | |
swap >>faces | |
over dimension>> >>dimension | |
over name>> " silhouette " append | |
pv> number>string append | |
>>name | |
! ensure-adjacencies | |
suffix-silhouettes ; inline | |
: find-silhouettes ( solid -- solid ) | |
{ } >>silhouettes | |
dup dimension>> [ [ add-silhouette ] with-pv ] each ; | |
: ensure-silhouettes ( solid -- solid ) | |
dup silhouettes>> [ f = ] all? | |
[ find-silhouettes ] when ; | |
! ------------ | |
: corner-added? ( solid corner -- ? ) | |
! add corner to solid if it is inside solid | |
[ ] | |
[ point-inside-or-on-solid? ] | |
[ swap corners>> member? not ] | |
2tri and | |
[ suffix-corner drop t ] [ 2drop f ] if ; | |
: process-corner ( solid faces corner -- ) | |
swapd | |
[ corner-added? ] keep swap ! test if corner is inside solid | |
[ update-adjacent-faces ] | |
[ 2drop ] | |
if ; | |
: compute-intersection ( solid faces -- ) | |
dup faces-intersection | |
dup f = [ 3drop ] [ process-corner ] if ; | |
: test-faces-combinaisons ( solid n -- ) | |
[ dup faces>> ] dip among | |
[ compute-intersection ] with each ; | |
: compute-adjacencies ( solid -- solid ) | |
dup dimension>> [ >= ] curry | |
[ keep swap ] curry MAX-FACE-PER-CORNER swap | |
[ [ test-faces-combinaisons ] 2keep 1 - ] while drop ; | |
: find-adjacencies ( solid -- solid ) | |
erase-old-adjacencies | |
compute-adjacencies | |
filter-real-faces | |
t >>adjacencies-valid ; | |
: ensure-adjacencies ( solid -- solid ) | |
dup adjacencies-valid>> | |
[ find-adjacencies ] unless | |
ensure-silhouettes | |
; | |
: (non-empty-solid?) ( solid -- ? ) | |
[ dimension>> ] [ corners>> length ] bi < ; | |
: non-empty-solid? ( solid -- ? ) | |
ensure-adjacencies (non-empty-solid?) ; | |
: compare-corners-roughly ( corner corner -- ? ) | |
2drop t ; | |
! : remove-inner-faces ( -- ) ; | |
: face-project ( array face -- seq ) | |
backface? | |
[ 2drop f ] | |
[ [ enlight-projection ] | |
[ initiate-solid-from-face ] | |
[ intersections-into-faces ] tri | |
>>faces | |
swap >>color | |
] if ; | |
: solid-project ( lights ambient solid -- solids ) | |
ensure-adjacencies | |
[ color>> ] [ faces>> ] bi [ 3array ] dip | |
[ face-project ] with map | |
sift | |
[ ensure-adjacencies ] map | |
; | |
: (solid-move) ( solid v move -- solid ) | |
curry [ map ] curry | |
[ dup faces>> ] dip call drop | |
unvalid-adjacencies ; inline | |
: solid-translate ( solid v -- solid ) | |
[ face-translate ] (solid-move) ; | |
: solid-transform ( solid m -- solid ) | |
[ face-transform ] (solid-move) ; | |
: find-corner-in-silhouette ( s1 s2 -- elt bool ) | |
pv> swap silhouettes>> nth | |
swap corners>> | |
[ point-inside-solid? ] with find swap ; | |
: valid-face-for-order ( solid point -- face ) | |
[ point-inside-face? not ] | |
[ drop face-orientation 0 = not ] 2bi and ; | |
: check-orientation ( s1 s2 pt -- int ) | |
[ nip faces>> ] dip | |
[ valid-face-for-order ] curry find swap | |
[ face-orientation ] [ drop f ] if ; | |
: (order-solid) ( s1 s2 -- int ) | |
2dup find-corner-in-silhouette | |
[ check-orientation ] [ 3drop f ] if ; | |
: order-solid ( solid solid -- i ) | |
2dup (order-solid) | |
[ 2nip ] | |
[ swap (order-solid) | |
[ neg ] [ f ] if* | |
] if* ; | |
: subtract ( solid1 solid2 -- solids ) | |
faces>> swap clone ensure-adjacencies ensure-silhouettes | |
[ swap slice-solid drop ] curry map | |
[ non-empty-solid? ] filter | |
[ ensure-adjacencies ] map | |
; inline | |
! ------------------------------------------------------------- | |
! space | |
! ------------------------------------------------------------- | |
TUPLE: space name dimension solids ambient-color lights ; | |
: <space> ( -- space ) space new ; | |
: suffix-solids ( space solid -- space ) | |
[ suffix ] curry change-solids ; inline | |
: suffix-lights ( space light -- space ) | |
[ suffix ] curry change-lights ; inline | |
: clear-space-solids ( space -- space ) f >>solids ; | |
: space-ensure-solids ( space -- space ) | |
[ [ ensure-adjacencies ] map ] change-solids ; | |
: eliminate-empty-solids ( space -- space ) | |
[ [ non-empty-solid? ] filter ] change-solids ; | |
: projected-space ( space solids -- space ) | |
swap dimension>> 1 - <space> | |
swap >>dimension swap >>solids ; | |
: get-silhouette ( solid -- silhouette ) | |
silhouettes>> pv> swap nth ; | |
: solid= ( solid solid -- ? ) [ corners>> ] same? ; | |
: space-apply ( space m quot -- space ) | |
curry [ map ] curry [ dup solids>> ] dip | |
[ call ] [ 2drop ] recover drop ; inline | |
: space-transform ( space m -- space ) | |
[ solid-transform ] space-apply ; | |
: space-translate ( space v -- space ) | |
[ solid-translate ] space-apply ; | |
: describe-space ( space -- ) | |
solids>> | |
[ [ corners>> [ pprint ] each ] [ name>> . ] bi ] each ; | |
: clip-solid ( solid solid -- solids ) | |
[ ] | |
[ solid= not ] | |
[ order-solid -1 = ] 2tri | |
and | |
[ get-silhouette subtract ] | |
[ drop 1array ] | |
if | |
; | |
: (solids-silhouette-subtract) ( solids solid -- solids ) | |
[ clip-solid append ] curry { } -rot each ; inline | |
: solids-silhouette-subtract ( solids i solid -- solids ) | |
! solids is an array of 1 solid arrays | |
[ (solids-silhouette-subtract) ] curry map-but | |
; inline | |
: remove-hidden-solids ( space -- space ) | |
! We must include each solid in a sequence because | |
! during substration | |
! a solid can be divided in more than on solid | |
[ | |
[ [ 1array ] map ] | |
[ length ] | |
[ ] | |
tri | |
[ solids-silhouette-subtract ] 2each | |
{ } [ append ] reduce | |
] change-solids | |
eliminate-empty-solids ! TODO include into change-solids | |
; | |
: space-project ( space i -- space ) | |
[ | |
[ clone | |
remove-hidden-solids? [ remove-hidden-solids ] when | |
dup | |
[ solids>> ] | |
[ lights>> ] | |
[ ambient-color>> ] tri | |
[ rot solid-project ] 2curry | |
map | |
[ append ] { } -rot each | |
! TODO project lights | |
projected-space | |
! remove-inner-faces | |
! | |
eliminate-empty-solids | |
] with-pv | |
] [ 3drop <space> ] recover | |
; inline | |
: middle-of-space ( space -- point ) | |
solids>> [ corners>> ] map concat | |
[ [ ] [ v+ ] map-reduce ] [ length ] bi v/n | |
; | |
! ------------------------------------------------------------- | |
! 3D rendering | |
! ------------------------------------------------------------- | |
: face-reference ( face -- halfspace point vect ) | |
[ halfspace>> ] | |
[ touching-corners>> first ] | |
[ touching-corners>> second ] tri | |
over v- | |
; | |
: theta ( v halfspace point vect -- v x ) | |
[ [ over ] dip v- ] dip | |
[ cross dup norm >float ] | |
[ v. >float ] | |
2bi | |
fatan2 | |
-rot v. | |
0 < [ neg ] when | |
; | |
: ordered-face-points ( face -- corners ) | |
[ touching-corners>> 1 head ] | |
[ touching-corners>> 1 tail ] | |
[ face-reference [ theta ] 3curry ] tri | |
{ } map>assoc sort-values keys | |
append | |
; inline | |
: point->GL ( point -- ) gl-vertex ; | |
: points->GL ( array -- ) do-cycle [ point->GL ] each ; | |
: face->GL ( face color -- ) | |
[ ordered-face-points ] dip | |
[ first3 1.0 glColor4d GL_POLYGON | |
[ [ point->GL ] each ] do-state ] curry | |
[ 0 0 0 1 glColor4d GL_LINE_LOOP | |
[ [ point->GL ] each ] do-state ] | |
bi | |
; inline | |
: solid->GL ( solid -- ) | |
[ faces>> ] | |
[ color>> ] bi | |
[ face->GL ] curry each ; inline | |
: space->GL ( space -- ) | |
solids>> | |
[ solid->GL ] each ; | |
]] | |
FILE: [[adsoda/combinators/combinators.factor]] [[! Copyright (C) 2008 Jeff Bigot | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: kernel arrays sequences fry math combinators ; | |
IN: adsoda.combinators | |
! : (combinations) ( seq -- seq ) [ 1 tail ] dip combinations ; | |
! : prefix-each [ prefix ] curry map ; inline | |
! : combinations ( seq n -- seqs ) | |
! { | |
! { [ dup 0 = ] [ 2drop { { } } ] } | |
! { [ over empty? ] [ 2drop { } ] } | |
! { [ t ] [ | |
! [ [ 1 - (combinations) ] [ drop first ] 2bi prefix-each ] | |
! [ (combinations) ] 2bi append | |
! ] } | |
! } cond ; | |
: columnize ( array -- array ) [ 1array ] map ; inline | |
: among ( array n -- array ) | |
2dup swap length | |
{ | |
{ [ over 1 = ] [ 3drop columnize ] } | |
{ [ over 0 = ] [ 4drop { } ] } | |
{ [ 2dup < ] [ 2drop [ 1 cut ] dip | |
[ 1 - among [ append ] with map ] | |
[ among append ] 2bi | |
] } | |
{ [ 2dup = ] [ 3drop 1array ] } | |
{ [ 2dup > ] [ 4drop { } ] } | |
} cond | |
; | |
: concat-nth ( seq1 seq2 -- seq ) | |
[ nth append ] curry map-index ; | |
: do-cycle ( array -- array ) dup first suffix ; | |
: map-but ( seq i quot -- seq ) | |
! quot : ( seq x -- seq ) | |
'[ _ = [ @ ] unless ] map-index ; inline | |
]] | |
FILE: [[adsoda/combinators/combinators-tests.factor]] [[USING: adsoda.combinators | |
sequences | |
tools.test | |
; | |
IN: adsoda.combinators.tests | |
[ { "atoto" "b" "ctoto" } ] [ { "a" "b" "c" } 1 [ "toto" append ] map-but ] | |
unit-test | |
]] | |
FILE: [[adsoda/combinators/authors.txt]] [[JF Bigot, after Greg Ferrar]] | |
FILE: [[adsoda/combinators/combinators-docs.factor]] [[! Copyright (C) 2008 Jeff Bigot. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: arrays help.markup help.syntax kernel sequences ; | |
IN: adsoda.combinators | |
HELP: among | |
{ $values | |
{ "array" array } { "n" "number of value to select" } | |
{ "array" array } | |
} | |
{ $description "returns an array containings every possibilities of n choices among a given sequence" } ; | |
HELP: columnize | |
{ $values | |
{ "array" array } | |
{ "array" array } | |
} | |
{ $description "flip a sequence into a sequence of 1 element sequences" } ; | |
HELP: concat-nth | |
{ $values | |
{ "seq1" sequence } { "seq2" sequence } | |
{ "seq" sequence } | |
} | |
{ $description "merges 2 sequences of sequences appending corresponding elements" } ; | |
HELP: do-cycle | |
{ $values | |
{ "array" array } | |
{ "array" array } | |
} | |
{ $description "Copy the first element at the end of the sequence in order to close the cycle." } ; | |
ARTICLE: "adsoda.combinators" "Combinators" | |
{ $vocab-link "adsoda.combinators" } | |
; | |
ABOUT: "adsoda.combinators" | |
]] | |
FILE: [[adsoda/adsoda-docs.factor]] [[! Copyright (C) 2008 Jeff Bigot | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: help.markup help.syntax ; | |
IN: adsoda | |
! -------------------------------------------------------------- | |
! faces | |
! -------------------------------------------------------------- | |
ARTICLE: "face-page" "Face in ADSODA" | |
"explanation of faces" | |
$nl | |
"link to functions" $nl | |
"what is an halfspace" $nl | |
"halfspace touching-corners adjacent-faces" $nl | |
"touching-corners list of pointers to the corners which touch this face" $nl | |
"adjacent-faces list of pointers to the faces which touch this face" | |
{ $subsections | |
face | |
<face> | |
} | |
"test relative position" | |
{ $subsections | |
point-inside-or-on-face? | |
point-inside-face? | |
} | |
"handling face" | |
{ $subsections | |
flip-face | |
face-translate | |
face-transform | |
} | |
; | |
HELP: face | |
{ $class-description "a face is defined by" | |
{ $list "halfspace equation" } | |
{ $list "list of touching corners" } | |
{ $list "list of adjacent faces" } | |
$nl | |
"Touching corners and adjacent faces are defined by algorithm thanks to other faces of the solid" | |
} | |
; | |
HELP: <face> | |
{ $values { "v" "an halfspace equation" } { "tuple" "a face" } } ; | |
HELP: flip-face | |
{ $values { "face" "a face" } { "face" "flipped face" } } | |
{ $description "change the orientation of a face" } | |
; | |
HELP: face-translate | |
{ $values { "face" "a face" } { "v" "a vector" } } | |
{ $description | |
"translate a face following a vector" | |
$nl | |
"a translation of an halfspace doesn't change the normal vector. this word just compute the new constant term" } | |
; | |
HELP: face-transform | |
{ $values { "face" "a face" } { "m" "a transformation matrix" } } | |
{ $description "compute the transformation of a face using a transformation matrix" } | |
; | |
! -------------------------------- | |
! solid | |
! -------------------------------------------------------------- | |
ARTICLE: "solid-page" "Solid in ADSODA" | |
"explanation of solids" | |
$nl | |
"link to functions" | |
{ $subsections | |
solid | |
<solid> | |
} | |
"test relative position" | |
{ $subsections | |
point-inside-solid? | |
point-inside-or-on-solid? | |
} | |
"playing with faces and solids" | |
{ $subsections | |
add-face | |
cut-solid | |
slice-solid | |
} | |
"solid handling" | |
{ $subsections | |
solid-project | |
solid-translate | |
solid-transform | |
subtract | |
get-silhouette | |
solid= | |
} | |
; | |
HELP: solid | |
{ $class-description "dimension" $nl "silhouettes" $nl "faces" $nl "corners" $nl "adjacencies-valid" $nl "color" $nl "name" | |
} | |
; | |
HELP: add-face | |
{ $values { "solid" "a solid" } { "face" "a face" } } | |
{ $description "reshape a solid with a face. The face truncate the solid." } ; | |
HELP: cut-solid | |
{ $values { "solid" "a solid" } { "halfspace" "an halfspace" } } | |
{ $description "like add-face but just with halfspace equation" } ; | |
HELP: slice-solid | |
{ $values { "solid" "a solid" } { "face" "a face" } { "solid1" "the outer part of the former solid" } { "solid2" "the inner part of the former solid" } } | |
{ $description "cut a solid into two parts. The face acts like a knife" | |
} ; | |
HELP: solid-project | |
{ $values { "lights" "lights" } { "ambient" "ambient" } { "solid" "solid" } { "solids" "projection of solid" } } | |
{ $description "Project the solid using pv vector" | |
$nl | |
"TODO: explain how to use lights" | |
} ; | |
HELP: solid-translate | |
{ $values { "solid" "a solid" } { "v" "translating vector" } } | |
{ $description "Translate a solid using a vector" | |
$nl | |
"v and solid must have the same dimension " | |
} ; | |
HELP: solid-transform | |
{ $values { "solid" "a solid" } { "m" "transformation matrix" } } | |
{ $description "Transform a solid using a matrix" | |
$nl | |
"v and solid must have the same dimension " | |
} ; | |
HELP: subtract | |
{ $values { "solid1" "initial shape" } { "solid2" "shape to remove" } { "solids" "resulting shape" } } | |
{ $description "Substract solid2 from solid1" } ; | |
! -------------------------------------------------------------- | |
! space | |
! -------------------------------------------------------------- | |
ARTICLE: "space-page" "Space in ADSODA" | |
"A space is a collection of solids and lights." | |
$nl | |
"link to functions" | |
$nl | |
"Defining words" | |
{ $subsections | |
space | |
<space> | |
suffix-solids | |
suffix-lights | |
clear-space-solids | |
describe-space | |
} | |
"Handling space" | |
{ $subsections | |
space-ensure-solids | |
eliminate-empty-solids | |
space-transform | |
space-translate | |
remove-hidden-solids | |
space-project | |
} | |
; | |
HELP: space | |
{ $class-description | |
"dimension" $nl " solids" $nl " ambient-color" $nl "lights" | |
} | |
; | |
HELP: suffix-solids | |
"( space solid -- space )" | |
{ $values { "space" "a space" } { "solid" "a solid to add" } } | |
{ $description "Add solid to space definition" } ; | |
HELP: suffix-lights | |
"( space light -- space ) " | |
{ $values { "space" "a space" } { "light" "a light to add" } } | |
{ $description "Add a light to space definition" } ; | |
HELP: clear-space-solids | |
"( space -- space )" | |
{ $values { "space" "a space" } } | |
{ $description "remove all solids in space" } ; | |
HELP: space-ensure-solids | |
{ $values { "space" "a space" } } | |
{ $description "rebuild corners of all solids in space" } ; | |
HELP: space-transform | |
{ $values { "space" "a space" } { "m" "a matrix" } } | |
{ $description "Transform a space using a matrix" } ; | |
HELP: space-translate | |
{ $values { "space" "a space" } { "v" "a vector" } } | |
{ $description "Translate a space following a vector" } ; | |
HELP: describe-space | |
{ $values { "space" "a space" } } | |
{ $description "return a description of space" } ; | |
HELP: space-project | |
{ $values { "space" "a space" } { "i" "an integer" } } | |
{ $description "Project a space along ith coordinate" } ; | |
! -------------------------------------------------------------- | |
! 3D rendering | |
! -------------------------------------------------------------- | |
ARTICLE: "3D-rendering-page" "The 3D rendering in ADSODA" | |
"explanation of 3D rendering" | |
$nl | |
"link to functions" | |
{ $subsections | |
face->GL | |
solid->GL | |
space->GL | |
} | |
; | |
HELP: face->GL | |
{ $values { "face" "a face" } { "color" "3 3 values array" } } | |
{ $description "display a face" } ; | |
HELP: solid->GL | |
{ $values { "solid" "a solid" } } | |
{ $description "display a solid" } ; | |
HELP: space->GL | |
{ $values { "space" "a space" } } | |
{ $description "display a space" } ; | |
! -------------------------------------------------------------- | |
! light | |
! -------------------------------------------------------------- | |
ARTICLE: "light-page" "Light in ADSODA" | |
"explanation of light" | |
$nl | |
"link to functions" | |
; | |
ARTICLE: { "adsoda" "light" } "ADSODA : lights" | |
{ $code """ | |
! HELP: light position color | |
! <light> ( -- tuple ) light new ; | |
! light est un vecteur avec 3 variables pour les couleurs\n | |
void Light::Apply(Vector& normal, double &cRed, double &cGreen, double &cBlue)\n | |
{ \n | |
// Dot the light direction with the normalized normal of Face. | |
register double intensity = -(normal * (*this)); | |
// Face is a backface, from light's perspective | |
if (intensity < 0) | |
return; | |
// Add the intensity componentwise | |
cRed += red * intensity; | |
cGreen += green * intensity; | |
cBlue += blue * intensity; | |
// Clip to unit range | |
if (cRed > 1.0) cRed = 1.0; | |
if (cGreen > 1.0) cGreen = 1.0; | |
if (cBlue > 1.0) cBlue = 1.0; | |
""" } | |
; | |
ARTICLE: { "adsoda" "halfspace" } "ADSODA : halfspace" | |
" defined by the concatenation of the normal vector and a constant" | |
; | |
ARTICLE: "adsoda-main-page" "ADSODA : Arbitrary-Dimensional Solid Object Display Algorithm" | |
"multidimensional handler :" | |
$nl | |
"design a solid using face delimitations. Only works on convex shapes" | |
$nl | |
{ $emphasis "written in C++ by Greg Ferrar" } | |
$nl | |
"full explanation on adsoda page at " { $url "http://www.flowerfire.com/ADSODA/" } | |
$nl | |
"Useful words are describe on the following pages: " | |
{ $subsections | |
"face-page" | |
"solid-page" | |
"space-page" | |
"light-page" | |
"3D-rendering-page" | |
} ; | |
ABOUT: "adsoda-main-page" | |
]] | |
FILE: [[adsoda/summary.txt]] [[ADSODA : Arbitrary-Dimensional Solid Object Display Algorithm]] | |
FILE: [[adsoda/adsoda-tests.factor]] [[USING: adsoda | |
kernel | |
math | |
accessors | |
sequences | |
adsoda.solution2 | |
fry | |
tools.test | |
arrays ; | |
IN: adsoda.tests | |
: s1 ( -- solid ) | |
<solid> | |
2 >>dimension | |
"s1" >>name | |
{ 1 1 1 } >>color | |
{ 1 -1 -5 } cut-solid | |
{ -1 -1 -21 } cut-solid | |
{ -1 0 -12 } cut-solid | |
{ 1 2 16 } cut-solid | |
; | |
: solid1 ( -- solid ) | |
<solid> | |
2 >>dimension | |
"solid1" >>name | |
{ 1 -1 -5 } cut-solid | |
{ -1 -1 -21 } cut-solid | |
{ -1 0 -12 } cut-solid | |
{ 1 2 16 } cut-solid | |
ensure-adjacencies | |
; | |
: solid2 ( -- solid ) | |
<solid> | |
2 >>dimension | |
"solid2" >>name | |
{ -1 1 -10 } cut-solid | |
{ -1 -1 -28 } cut-solid | |
{ 1 0 13 } cut-solid | |
! { 1 2 16 } cut-solid | |
ensure-adjacencies | |
; | |
: solid3 ( -- solid ) | |
<solid> | |
2 >>dimension | |
"solid3" >>name | |
{ 1 1 1 } >>color | |
{ 1 0 16 } cut-solid | |
{ -1 0 -36 } cut-solid | |
{ 0 1 1 } cut-solid | |
{ 0 -1 -17 } cut-solid | |
! { 1 2 16 } cut-solid | |
ensure-adjacencies | |
; | |
: solid4 ( -- solid ) | |
<solid> | |
2 >>dimension | |
"solid4" >>name | |
{ 1 1 1 } >>color | |
{ 1 0 21 } cut-solid | |
{ -1 0 -36 } cut-solid | |
{ 0 1 1 } cut-solid | |
{ 0 -1 -17 } cut-solid | |
ensure-adjacencies | |
; | |
: solid5 ( -- solid ) | |
<solid> | |
2 >>dimension | |
"solid5" >>name | |
{ 1 1 1 } >>color | |
{ 1 0 6 } cut-solid | |
{ -1 0 -17 } cut-solid | |
{ 0 1 17 } cut-solid | |
{ 0 -1 -19 } cut-solid | |
ensure-adjacencies | |
; | |
: solid7 ( -- solid ) | |
<solid> | |
2 >>dimension | |
"solid7" >>name | |
{ 1 1 1 } >>color | |
{ 1 0 38 } cut-solid | |
{ 1 -5 -66 } cut-solid | |
{ -2 1 -75 } cut-solid | |
ensure-adjacencies | |
; | |
: solid6s ( -- seq ) | |
solid3 clone solid2 clone subtract | |
; | |
: space1 ( -- space ) | |
<space> | |
2 >>dimension | |
! solid3 suffix-solids | |
solid1 suffix-solids | |
solid2 suffix-solids | |
! solid6s [ suffix-solids ] each | |
solid4 suffix-solids | |
! solid5 suffix-solids | |
solid7 suffix-solids | |
{ 1 1 1 } >>ambient-color | |
<light> | |
{ -100 -100 } >>position | |
{ 0.2 0.7 0.1 } >>color | |
suffix-lights | |
; | |
: space2 ( -- space ) | |
<space> | |
4 >>dimension | |
! 4cube suffix-solids | |
{ 1 1 1 } >>ambient-color | |
<light> | |
{ -100 -100 } >>position | |
{ 0.2 0.7 0.1 } >>color | |
suffix-lights | |
; | |
! { | |
! { 1 0 0 0 } | |
! { 0 1 0 0 } | |
! { 0 0 0.984807753012208 -0.1736481776669303 } | |
! { 0 0 0.1736481776669303 0.984807753012208 } | |
! } | |
! ------------------------------------------------------------ | |
! constant+ | |
[ { 1 2 5 } ] [ { 1 2 3 } 2 constant+ ] unit-test | |
! ------------------------------------------------------------ | |
! translate | |
[ { 1 -1 0 } ] [ { 1 -1 -5 } { 3 -2 } translate ] unit-test | |
! ------------------------------------------------------------ | |
! transform | |
[ { -1 -1 -5 21.0 } ] [ { -1 -1 -5 21 } | |
{ { 1 0 0 } | |
{ 0 1 0 } | |
{ 0 0 1 } | |
} transform | |
] unit-test | |
! ------------------------------------------------------------ | |
! compare-nleft-to-identity-matrix | |
[ t ] [ | |
{ | |
{ 1 0 0 1232 } | |
{ 0 1 0 0 321 } | |
{ 0 0 1 0 } } | |
3 compare-nleft-to-identity-matrix | |
] unit-test | |
[ f ] [ | |
{ { 1 0 0 } { 0 1 0 } { 0 0 0 } } | |
3 compare-nleft-to-identity-matrix | |
] unit-test | |
[ f ] [ | |
{ { 2 0 0 } { 0 1 0 } { 0 0 1 } } | |
3 compare-nleft-to-identity-matrix | |
] unit-test | |
! ------------------------------------------------------------ | |
[ t ] [ | |
{ { 1 0 0 } | |
{ 0 1 0 } | |
{ 0 0 1 } } 3 valid-solution? | |
] unit-test | |
[ f ] [ | |
{ { 1 0 0 1 } | |
{ 0 0 0 1 } | |
{ 0 0 1 0 } } 3 valid-solution? | |
] unit-test | |
[ f ] [ | |
{ { 1 0 0 1 } | |
{ 0 0 0 1 } } 3 valid-solution? | |
] unit-test | |
[ f ] [ | |
{ { 1 0 0 1 } | |
{ 0 0 0 1 } | |
{ 0 0 1 0 } } 2 valid-solution? | |
] unit-test | |
! ------------------------------------------------------------ | |
[ 3 ] [ { 1 2 3 } last ] unit-test | |
[ { 1 2 5 } ] [ { 1 2 3 } dup [ 2 + ] change-last ] unit-test | |
! ------------------------------------------------------------ | |
! position-point | |
[ 0 ] [ | |
{ 1 -1 -5 } { 2 7 } position-point | |
] unit-test | |
! ------------------------------------------------------------ | |
! transform | |
! TODO construire un exemple | |
! ------------------------------------------------------------ | |
! slice-solid | |
! ------------------------------------------------------------ | |
! solve-equation | |
! deux cas de tests, avec solution et sans solution | |
[ { 2 7 } ] | |
[ { { 1 -1 -5 } { 1 2 16 } } intersect-hyperplanes ] | |
unit-test | |
[ f ] | |
[ { { 1 -1 -5 } { 1 2 16 } { -1 -1 -21 } } intersect-hyperplanes ] | |
unit-test | |
[ f ] | |
[ { { 1 0 -5 } { 1 0 16 } } intersect-hyperplanes ] | |
unit-test | |
! ------------------------------------------------------------ | |
! point-inside-halfspace | |
[ t ] [ { 1 -1 -5 } { 0 0 } point-inside-halfspace? ] | |
unit-test | |
[ f ] [ { 1 -1 -5 } { 8 13 } point-inside-halfspace? ] | |
unit-test | |
[ t ] [ { 1 -1 -5 } { 8 13 } point-inside-or-on-halfspace? ] | |
unit-test | |
! ------------------------------ | |
! order solid | |
[ 1 ] [ 0 >pv solid1 solid2 order-solid ] unit-test | |
[ -1 ] [ 0 >pv solid2 solid1 order-solid ] unit-test | |
[ f ] [ 1 >pv solid1 solid2 order-solid ] unit-test | |
[ f ] [ 1 >pv solid2 solid1 order-solid ] unit-test | |
! clip-solid | |
[ { { 13 15 } { 15 13 } { 13 13 } } ] | |
[ 0 >pv solid2 solid1 clip-solid first corners>> ] unit-test | |
solid1 corners>> '[ _ ] | |
[ 0 >pv solid1 solid1 clip-solid first corners>> ] unit-test | |
solid1 corners>> '[ _ ] | |
[ 0 >pv solid1 solid2 clip-solid first corners>> ] unit-test | |
solid1 corners>> '[ _ ] | |
[ 1 >pv solid1 solid2 clip-solid first corners>> ] unit-test | |
solid2 corners>> '[ _ ] | |
[ 1 >pv solid2 solid1 clip-solid first corners>> ] unit-test | |
! | |
[ | |
{ | |
{ { 13 15 } { 15 13 } { 13 13 } } | |
{ { 16 17 } { 16 13 } { 36 17 } { 36 13 } } | |
{ { 16 1 } { 16 2 } { 36 1 } { 36 2 } } | |
} | |
] [ 0 >pv solid2 solid3 2array | |
solid1 (solids-silhouette-subtract) | |
[ corners>> ] map | |
] unit-test | |
[ | |
{ | |
{ { 8 13 } { 2 7 } { 12 9 } { 12 2 } } | |
{ { 13 15 } { 15 13 } { 13 13 } } | |
{ { 16 17 } { 16 15 } { 36 17 } { 36 15 } } | |
{ { 16 1 } { 16 2 } { 36 1 } { 36 2 } } | |
} | |
] [ | |
0 >pv <space> solid1 suffix-solids | |
solid2 suffix-solids | |
solid3 suffix-solids | |
remove-hidden-solids | |
solids>> [ corners>> ] map | |
] unit-test | |
! { } | |
! { } | |
! <light> { 0.2 0.3 0.4 } >>color { 1 -1 1 } >>direction suffix | |
! <light> { 0.4 0.3 0.1 } >>color { -1 -1 -1 } >>direction suffix | |
! suffix | |
! { 0.1 0.1 0.1 } suffix ! ambient color | |
! { 0.23 0.32 0.17 } suffix ! solid color | |
! solid3 faces>> first | |
! enlight-projection | |
]] | |
FILE: [[adsoda/adsoda.tests]] [[! : init-4D-demo ( -- space ) | |
! OK | |
! espace de dimension 4 et de couleur 0,3 0.3 0.3 | |
<space> | |
4 >>dimension | |
{ 0.3 0.3 0.3 } >>ambient-color | |
{ 100 150 100 150 100 150 100 150 } "4cube1" 4cube suffix-solids | |
{ 160 180 160 180 160 180 160 180 } "4cube2" 4cube suffix-solids | |
<light> | |
{ -100 -100 -100 -100 } >>position | |
{ 0.2 0.7 0.1 } >>color | |
suffix-lights | |
! ; | |
! : init-3D-demo ( -- space ) | |
! OK | |
! espace de dimension 4 et de couleur 0,3 0.3 0.3 | |
<space> | |
3 >>dimension | |
{ 0.3 0.3 0.3 } >>ambient-color | |
{ 100 150 100 150 100 150 } "3cube1" 3cube suffix-solids | |
! { -150 -10 -150 -10 -150 -10 -150 -10 } "4cube2" 4cube suffix-solids | |
<light> | |
{ -100 -100 -100 -100 } >>position | |
{ 0.2 0.7 0.1 } >>color | |
suffix-lights | |
! ; | |
: s1 ( -- solid ) | |
<solid> | |
2 >>dimension | |
"s1" >>name | |
{ 1 1 1 } >>color | |
{ 1 -1 -5 } cut-solid | |
{ -1 -1 -21 } cut-solid | |
{ -1 0 -12 } cut-solid | |
{ 1 2 16 } cut-solid | |
; | |
: solid1 ( -- solid ) | |
<solid> | |
2 >>dimension | |
"solid1" >>name | |
{ 1 -1 -5 } cut-solid | |
{ -1 -1 -21 } cut-solid | |
{ -1 0 -12 } cut-solid | |
{ 1 2 16 } cut-solid | |
ensure-adjacencies | |
; | |
: solid2 ( -- solid ) | |
<solid> | |
2 >>dimension | |
"solid2" >>name | |
{ -1 1 -10 } cut-solid | |
{ -1 -1 -28 } cut-solid | |
{ 1 0 13 } cut-solid | |
! { 1 2 16 } cut-solid | |
ensure-adjacencies | |
; | |
: solid3 ( -- solid ) | |
<solid> | |
2 >>dimension | |
"solid3" >>name | |
{ 1 1 1 } >>color | |
{ 1 0 16 } cut-solid | |
{ -1 0 -36 } cut-solid | |
{ 0 1 1 } cut-solid | |
{ 0 -1 -17 } cut-solid | |
! { 1 2 16 } cut-solid | |
ensure-adjacencies | |
; | |
: solid4 ( -- solid ) | |
<solid> | |
2 >>dimension | |
"solid4" >>name | |
{ 1 1 1 } >>color | |
{ 1 0 21 } cut-solid | |
{ -1 0 -36 } cut-solid | |
{ 0 1 1 } cut-solid | |
{ 0 -1 -17 } cut-solid | |
ensure-adjacencies | |
; | |
: solid5 ( -- solid ) | |
<solid> | |
2 >>dimension | |
"solid5" >>name | |
{ 1 1 1 } >>color | |
{ 1 0 6 } cut-solid | |
{ -1 0 -17 } cut-solid | |
{ 0 1 17 } cut-solid | |
{ 0 -1 -19 } cut-solid | |
ensure-adjacencies | |
; | |
: solid7 ( -- solid ) | |
<solid> | |
2 >>dimension | |
"solid7" >>name | |
{ 1 1 1 } >>color | |
{ 1 0 38 } cut-solid | |
{ 1 -5 -66 } cut-solid | |
{ -2 1 -75 } cut-solid | |
ensure-adjacencies | |
; | |
: solid6s ( -- seq ) | |
solid3 clone solid2 clone subtract | |
; | |
: space1 ( -- space ) | |
<space> | |
2 >>dimension | |
! solid3 suffix-solids | |
solid1 suffix-solids | |
solid2 suffix-solids | |
! solid6s [ suffix-solids ] each | |
solid4 suffix-solids | |
! solid5 suffix-solids | |
solid7 suffix-solids | |
{ 1 1 1 } >>ambient-color | |
<light> | |
{ -100 -100 } >>position | |
{ 0.2 0.7 0.1 } >>color | |
suffix-lights | |
; | |
: space2 ( -- space ) | |
<space> | |
4 >>dimension | |
! 4cube suffix-solids | |
{ 1 1 1 } >>ambient-color | |
<light> | |
{ -100 -100 } >>position | |
{ 0.2 0.7 0.1 } >>color | |
suffix-lights | |
; | |
]] | |
FILE: [[adsoda/authors.txt]] [[Jeff Bigot | |
Greg Ferrar]] | |
FILE: [[adsoda/tags.txt]] [[adsoda 4D viewer]] | |
FILE: [[adsoda/solution2/solution2.factor]] [[USING: kernel | |
sequences | |
namespaces | |
math | |
math.vectors | |
math.matrices | |
; | |
IN: adsoda.solution2 | |
! ------------------- | |
! correctif solution | |
! --------------- | |
SYMBOL: matrix | |
: MIN-VAL-adsoda ( -- x ) 0.00000001 | |
! 0.000000000001 | |
; | |
: zero? ( x -- ? ) | |
abs MIN-VAL-adsoda < | |
; | |
! [ number>string string>number ] map | |
: with-matrix ( matrix quot -- ) | |
[ swap matrix set call matrix get ] with-scope ; inline | |
: nth-row ( row# -- seq ) matrix get nth ; | |
: change-row ( row# quot -- seq ) ! row# quot -- | quot: seq -- seq ) | |
matrix get swap change-nth ; inline | |
: exchange-rows ( row# row# -- ) matrix get exchange ; | |
: rows ( -- n ) matrix get length ; | |
: cols ( -- n ) 0 nth-row length ; | |
: skip ( i seq quot -- n ) | |
over [ find-from drop ] dip length or ; inline | |
: first-col ( row# -- n ) | |
! First non-zero column | |
0 swap nth-row [ zero? not ] skip ; | |
: clear-scale ( col# pivot-row i-row -- n ) | |
[ over ] dip nth dup zero? [ | |
3drop 0 | |
] [ | |
[ nth dup zero? ] dip swap [ | |
2drop 0 | |
] [ | |
swap / neg | |
] if | |
] if ; | |
: (clear-col) ( col# pivot-row i -- ) | |
[ [ clear-scale ] 2keep [ n*v ] dip v+ ] change-row ; | |
: rows-from ( row# -- slice ) | |
rows dup <slice> ; | |
: clear-col ( col# row# rows -- ) | |
[ nth-row ] dip [ [ 2dup ] dip (clear-col) ] each 2drop ; | |
: do-row ( exchange-with row# -- ) | |
[ exchange-rows ] keep | |
[ first-col ] keep | |
dup 1 + rows-from clear-col ; | |
: find-row ( row# quot -- i elt ) | |
[ rows-from ] dip find ; inline | |
: pivot-row ( col# row# -- n ) | |
[ dupd nth-row nth zero? not ] find-row 2nip ; | |
: (echelon) ( col# row# -- ) | |
over cols < over rows < and [ | |
2dup pivot-row [ over do-row 1 + ] when* | |
[ 1 + ] dip (echelon) | |
] [ | |
2drop | |
] if ; | |
: echelon ( matrix -- matrix' ) | |
[ 0 0 (echelon) ] with-matrix ; | |
: nonzero-rows ( matrix -- matrix' ) | |
[ [ zero? ] all? ] reject ; | |
: null/rank ( matrix -- null rank ) | |
echelon dup length swap nonzero-rows length [ - ] keep ; | |
: leading ( seq -- n elt ) [ zero? not ] find ; | |
: reduced ( matrix' -- matrix'' ) | |
[ | |
rows <reversed> [ | |
dup nth-row leading drop | |
dup [ swap dup clear-col ] [ 2drop ] if | |
] each | |
] with-matrix ; | |
: basis-vector ( row col# -- ) | |
[ clone ] dip | |
[ swap nth neg recip ] 2keep | |
[ 0 spin set-nth ] 2keep | |
[ n*v ] dip | |
matrix get set-nth ; | |
: nullspace ( matrix -- seq ) | |
echelon reduced dup empty? [ | |
dup first length identity-matrix [ | |
[ | |
dup leading drop | |
dup [ basis-vector ] [ 2drop ] if | |
] each | |
] with-matrix flip nonzero-rows | |
] unless ; | |
: 1-pivots ( matrix -- matrix ) | |
[ dup leading nip [ recip v*n ] when* ] map ; | |
: solution ( matrix -- matrix ) | |
echelon nonzero-rows reduced 1-pivots ; | |
]] | |
FILE: [[adsoda/solution2/summary.txt]] [[A modification of solution to approximate solutions]] | |
FILE: [[cpu/arm/bootstrap.factor]] [[! Copyright (C) 2007 Slava Pestov. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: bootstrap.image.private kernel namespaces system | |
cpu.arm.assembler math layouts words compiler.units ; | |
IN: bootstrap.arm | |
! We generate ARM3 code | |
f have-BX? set | |
4 \ cell set | |
big-endian off | |
4 jit-code-format set | |
: ds-reg R5 ; | |
: word-reg R0 ; | |
: quot-reg R0 ; | |
: scan-reg R2 ; | |
: temp-reg R3 ; | |
: xt-reg R12 ; | |
: stack-frame 16 bootstrap-cells ; | |
: next-save stack-frame 2 bootstrap-cells - ; | |
: xt-save stack-frame 3 bootstrap-cells - ; | |
: array-save stack-frame 4 bootstrap-cells - ; | |
: scan-save stack-frame 5 bootstrap-cells - ; | |
[ | |
temp-reg quot-reg quot-array@ <+> LDR ! load array | |
scan-reg temp-reg scan@ ADD ! initialize scan pointer | |
] { } make jit-setup set | |
[ | |
LR SP 4 <-> STR ! save return address | |
SP SP stack-frame SUB | |
xt-reg SP xt-save <+> STR ! save XT | |
xt-reg stack-frame MOV | |
xt-reg SP next-save <+> STR ! save frame size | |
temp-reg SP array-save <+> STR ! save array | |
] { } make jit-prolog set | |
[ | |
temp-reg scan-reg 4 <!+> LDR ! load literal and advance | |
temp-reg ds-reg 4 <!+> STR ! push literal | |
] { } make jit-push-literal set | |
[ | |
temp-reg scan-reg 4 <!+> LDR ! load wrapper and advance | |
temp-reg dup wrapper@ <+> LDR ! load wrapped object | |
temp-reg ds-reg 4 <!+> STR ! push wrapped object | |
] { } make jit-push-wrapper set | |
[ | |
R1 SP 4 SUB ! pass stack pointer to primitive | |
] { } make jit-word-primitive-jump set | |
[ | |
R1 SP 4 SUB ! pass stack pointer to primitive | |
] { } make jit-word-primitive-call set | |
: load-word-xt ( -- ) | |
word-reg scan-reg 4 <!+> LDR ! load word and advance | |
xt-reg word-reg word-xt@ <+> LDR ; | |
: jit-call | |
scan-reg SP scan-save <+> STR ! save scan pointer | |
LR PC MOV ! save return address | |
xt-reg BX ! call | |
scan-reg SP scan-save <+> LDR ! restore scan pointer | |
; | |
: jit-jump | |
xt-reg BX ; | |
[ load-word-xt jit-call ] { } make jit-word-call set | |
[ load-word-xt jit-jump ] { } make jit-word-jump set | |
: load-quot-xt | |
xt-reg quot-reg quot-xt@ <+> LDR ; | |
: load-branch | |
temp-reg ds-reg 4 <-!> LDR ! pop boolean | |
temp-reg \ f tag-number CMP ! compare it with f | |
quot-reg scan-reg MOV ! point quot-reg at false branch | |
quot-reg dup 4 EQ ADD ! point quot-reg at true branch | |
quot-reg dup 4 <+> LDR ! load the branch | |
scan-reg dup 12 ADD ! advance scan pointer | |
load-quot-xt | |
; | |
[ | |
load-branch jit-jump | |
] { } make jit-if-jump set | |
[ | |
load-branch jit-call | |
] { } make jit-if-call set | |
[ | |
temp-reg ds-reg 4 <-!> LDR ! pop index | |
temp-reg dup 1 <LSR> MOV ! turn it into an array offset | |
scan-reg dup 4 <+> LDR ! load array | |
temp-reg dup scan-reg ADD ! compute quotation location | |
quot-reg temp-reg array-start <+> LDR ! load quotation | |
load-quot-xt | |
jit-jump | |
] { } make jit-dispatch set | |
[ | |
SP SP stack-frame ADD ! pop stack frame | |
LR SP 4 <-> LDR ! load return address | |
] { } make jit-epilog set | |
[ LR BX ] { } make jit-return set | |
[ "bootstrap.arm" forget-vocab ] with-compilation-unit | |
]] | |
FILE: [[cpu/arm/arm.factor]] [[! Copyright (C) 2007 Slava Pestov. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: alien alien.c-types kernel math namespaces | |
cpu.architecture cpu.arm.architecture cpu.arm.assembler | |
cpu.arm.intrinsics generator generator.registers continuations | |
compiler io vocabs sequences system ; | |
! EABI passes floats in integer registers. | |
[ alien-float ] | |
[ >r >r >float r> r> set-alien-float ] | |
4 | |
"box_float" | |
"to_float" <primitive-type> | |
"float" define-primitive-type | |
[ >float ] "float" c-type set-c-type-prep | |
[ alien-double ] | |
[ >r >r >float r> r> set-alien-double ] | |
8 | |
"box_double" | |
"to_double" <primitive-type> <long-long-type> | |
"double" define-primitive-type | |
[ >float ] "double" c-type set-c-type-prep | |
T{ arm-backend } compiler-backend set-global | |
! We don't auto-detect since that would require us to support | |
! illegal instruction traps. This works on Linux but not on | |
! Windows CE. | |
"arm-variant" get [ | |
"ARM variant: " write "arm-variant" get print | |
] [ | |
"You should specify the -arm-variant=<variant> switch." print | |
"<variant> can be one of arm3, arm4, arm4t, or arm5." print | |
"Assuming arm3." print | |
"arm3" "arm-variant" set-global | |
] if | |
"arm-variant" get { "arm4" "arm4t" "arm5" } member? [ | |
"cpu.arm.4" require | |
] when | |
"arm-variant" get { "arm4t" "arm5" } member? [ | |
t have-BX? set-global | |
] when | |
"arm-variant" get "arm5" = [ | |
t have-BLX? set-global | |
] when | |
7 cells profiler-prologues set-global | |
]] | |
FILE: [[cpu/arm/architecture/architecture.factor]] [[! Copyright (C) 2007 Slava Pestov. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: alien alien.c-types arrays cpu.arm.assembler compiler | |
kernel kernel.private math namespaces words words.private | |
generator.registers generator.fixup generator cpu.architecture | |
system layouts ; | |
IN: cpu.arm.architecture | |
TUPLE: arm-backend ; | |
! ARM register assignments: | |
! R0-R4, R7-R10 integer vregs | |
! R11, R12 temporary | |
! R5 data stack | |
! R6 retain stack | |
! R7 primitives | |
: ds-reg R5 ; inline | |
: rs-reg R6 ; inline | |
M: temp-reg v>operand drop R12 ; | |
M: int-regs return-reg drop R0 ; | |
M: int-regs param-regs drop { R0 R1 R2 R3 } ; | |
M: int-regs vregs drop { R0 R1 R2 R3 R4 R7 R8 R9 R10 } ; | |
! No FPU support yet | |
M: float-regs param-regs drop { } ; | |
M: float-regs vregs drop { } ; | |
: <+/-> dup 0 < [ neg <-> ] [ <+> ] if ; | |
GENERIC: loc>operand ( loc -- reg addressing ) | |
M: ds-loc loc>operand ds-loc-n cells neg ds-reg swap <+/-> ; | |
M: rs-loc loc>operand rs-loc-n cells neg rs-reg swap <+/-> ; | |
: load-cell ( reg -- ) | |
[ | |
"end" define-label | |
! Load target address | |
PC 0 <+> LDR | |
! Skip an instruction | |
"end" get B | |
! The target address | |
0 , | |
! Continue here | |
"end" resolve-label | |
] with-scope ; | |
: call-cell ( -- ) | |
! Compute return address; we skip 3 instructions | |
LR PC 8 ADD | |
! Load target address | |
R12 PC 0 <+> LDR | |
! Jump to target address | |
R12 BX | |
! The target address | |
0 , ; | |
M: arm-backend load-indirect ( obj reg -- ) | |
tuck load-cell rc-absolute-cell rel-literal | |
dup 0 <+> LDR ; | |
M: immediate load-literal | |
over v>operand small-enough? [ | |
[ v>operand ] bi@ swap MOV | |
] [ | |
v>operand load-indirect | |
] if ; | |
: lr-save ( n -- i ) cell - ; | |
: next-save ( n -- i ) 2 cells - ; | |
: xt-save ( n -- i ) 3 cells - ; | |
: factor-area-size 5 cells ; | |
M: arm-backend stack-frame ( n -- i ) | |
factor-area-size + 8 align ; | |
M: arm-backend %save-word-xt ( -- ) | |
R12 PC 9 cells SUB ; | |
M: arm-backend %save-dispatch-xt ( -- ) | |
R12 PC 2 cells SUB ; | |
M: arm-backend %prologue ( n -- ) | |
SP SP pick SUB | |
R11 over MOV | |
R11 SP pick next-save <+> STR | |
R12 SP pick xt-save <+> STR | |
LR SP rot lr-save <+> STR ; | |
M: arm-backend %epilogue ( n -- ) | |
LR SP pick lr-save <+> LDR | |
SP SP rot ADD ; | |
: compile-dlsym ( symbol dll reg -- ) | |
load-cell rc-absolute rel-dlsym ; | |
: %alien-global ( symbol dll reg -- ) | |
[ compile-dlsym ] keep dup 0 <+> LDR ; | |
M: arm-backend %profiler-prologue ( -- ) | |
! We can clobber R0 here since it is undefined at the start | |
! of a word. | |
R12 load-indirect | |
R0 R12 profile-count-offset <+> LDR | |
R0 R0 1 v>operand ADD | |
R0 R12 profile-count-offset <+> STR ; | |
M: arm-backend %call-label ( label -- ) BL ; | |
M: arm-backend %jump-label ( label -- ) B ; | |
: %prepare-primitive ( -- ) | |
! Save stack pointer to stack_chain->callstack_top, load XT | |
R1 SP 4 SUB ; | |
M: arm-backend %call-primitive ( word -- ) | |
%prepare-primitive | |
call-cell rc-absolute-cell rel-word ; | |
M: arm-backend %jump-primitive ( word -- ) | |
%prepare-primitive | |
! Load target address | |
R12 PC 0 <+> LDR | |
! Jump to target address | |
R12 BX | |
! The target address | |
0 , rc-absolute-cell rel-word ; | |
M: arm-backend %jump-t ( label -- ) | |
"flag" operand f v>operand CMP NE B ; | |
: (%dispatch) ( word-table# -- ) | |
! Load jump table target address into reg. | |
"scratch" operand PC "n" operand 1 <LSR> ADD | |
"scratch" operand dup 0 <+> LDR | |
rc-indirect-arm rel-dispatch | |
"scratch" operand dup compiled-header-size ADD ; | |
M: arm-backend %call-dispatch ( word-table# -- ) | |
[ | |
(%dispatch) | |
"scratch" operand BLX | |
] H{ | |
{ +input+ { { f "n" } } } | |
{ +scratch+ { { f "scratch" } } } | |
} with-template ; | |
M: arm-backend %jump-dispatch ( word-table# -- ) | |
[ | |
%epilogue-later | |
(%dispatch) | |
"scratch" operand BX | |
] H{ | |
{ +input+ { { f "n" } } } | |
{ +scratch+ { { f "scratch" } } } | |
} with-template ; | |
M: arm-backend %return ( -- ) %epilogue-later PC LR MOV ; | |
M: arm-backend %unwind drop %return ; | |
M: arm-backend %peek >r v>operand r> loc>operand LDR ; | |
M: arm-backend %replace >r v>operand r> loc>operand STR ; | |
: (%inc) ( n reg -- ) | |
dup rot cells dup 0 < [ neg SUB ] [ ADD ] if ; | |
M: arm-backend %inc-d ( n -- ) ds-reg (%inc) ; | |
M: arm-backend %inc-r ( n -- ) rs-reg (%inc) ; | |
: stack@ SP swap <+> ; | |
M: int-regs %save-param-reg drop swap stack@ STR ; | |
M: int-regs %load-param-reg drop swap stack@ LDR ; | |
M: stack-params %save-param-reg | |
drop | |
R12 swap stack-frame* + stack@ LDR | |
R12 swap stack@ STR ; | |
M: stack-params %load-param-reg | |
drop | |
R12 rot stack@ LDR | |
R12 swap stack@ STR ; | |
M: arm-backend %prepare-unbox ( -- ) | |
! First parameter is top of stack | |
R0 R5 4 <-!> LDR ; | |
M: arm-backend %unbox ( n reg-class func -- ) | |
! Value must be in R0. | |
! Call the unboxer | |
f %alien-invoke | |
! Store the return value on the C stack | |
over [ [ return-reg ] keep %save-param-reg ] [ 2drop ] if ; | |
M: arm-backend %unbox-long-long ( n func -- ) | |
! Value must be in R0:R1. | |
! Call the unboxer | |
f %alien-invoke | |
! Store the return value on the C stack | |
[ | |
R0 over stack@ STR | |
R1 swap cell + stack@ STR | |
] when* ; | |
M: arm-backend %unbox-small-struct ( size -- ) | |
! Alien must be in R0. | |
drop | |
"alien_offset" f %alien-invoke | |
! Load first cell | |
R0 R0 0 <+> LDR ; | |
M: arm-backend %unbox-large-struct ( n size -- ) | |
! Alien must be in R0. | |
! Compute destination address | |
R1 SP roll ADD | |
R2 swap MOV | |
! Copy the struct to the stack | |
"to_value_struct" f %alien-invoke ; | |
M: arm-backend %box ( n reg-class func -- ) | |
! If the source is a stack location, load it into freg #0. | |
! If the source is f, then we assume the value is already in | |
! freg #0. | |
>r | |
over [ 0 over param-reg swap %load-param-reg ] [ 2drop ] if | |
r> f %alien-invoke ; | |
M: arm-backend %box-long-long ( n func -- ) | |
>r [ | |
R0 over stack@ LDR | |
R1 swap cell + stack@ LDR | |
] when* r> f %alien-invoke ; | |
M: arm-backend %box-small-struct ( size -- ) | |
! Box a 4-byte struct returned in R0. | |
R2 swap MOV | |
"box_small_struct" f %alien-invoke ; | |
: temp@ stack-frame* factor-area-size - swap - ; | |
: struct-return@ ( size n -- n ) | |
[ | |
stack-frame* + | |
] [ | |
stack-frame* factor-area-size - swap - | |
] ?if ; | |
M: arm-backend %prepare-box-struct ( size -- ) | |
! Compute target address for value struct return | |
R0 SP rot f struct-return@ ADD | |
! Store it as the first parameter | |
R0 0 stack@ STR ; | |
M: arm-backend %box-large-struct ( n size -- ) | |
! Compute destination address | |
[ swap struct-return@ ] keep | |
R0 SP roll ADD | |
R1 swap MOV | |
! Copy the struct from the C stack | |
"box_value_struct" f %alien-invoke ; | |
M: arm-backend struct-small-enough? ( size -- ? ) | |
4 <= ; | |
M: arm-backend %prepare-alien-invoke | |
! Save Factor stack pointers in case the C code calls a | |
! callback which does a GC, which must reliably trace | |
! all roots. | |
"stack_chain" f R12 %alien-global | |
SP R12 0 <+> STR | |
ds-reg R12 8 <+> STR | |
rs-reg R12 12 <+> STR ; | |
M: arm-backend %alien-invoke ( symbol dll -- ) | |
call-cell rc-absolute-cell rel-dlsym ; | |
M: arm-backend %prepare-alien-indirect ( -- ) | |
"unbox_alien" f %alien-invoke | |
R0 SP cell temp@ <+> STR ; | |
M: arm-backend %alien-indirect ( -- ) | |
R12 SP cell temp@ <+> LDR | |
R12 BLX ; | |
M: arm-backend %alien-callback ( quot -- ) | |
R0 load-indirect | |
"c_to_factor" f %alien-invoke ; | |
M: arm-backend %callback-value ( ctype -- ) | |
! Save top of data stack | |
%prepare-unbox | |
R0 SP cell temp@ <+> STR | |
! Restore data/call/retain stacks | |
"unnest_stacks" f %alien-invoke | |
! Place former top of data stack in R0 | |
R0 SP cell temp@ <+> LDR | |
! Unbox R0 | |
unbox-return ; | |
M: arm-backend %cleanup ( alien-node -- ) drop ; | |
: %untag ( dest src -- ) 0b111 BIC ; | |
: %untag-fixnum ( dest src -- ) tag-bits get <ASR> MOV ; | |
: %tag-fixnum ( dest src -- ) tag-bits get <LSL> MOV ; | |
M: arm-backend value-structs? t ; | |
M: arm-backend small-enough? ( n -- ? ) 0 255 between? ; | |
M: long-long-type c-type-stack-align? drop t ; | |
M: arm-backend fp-shadows-int? ( -- ? ) f ; | |
! Alien intrinsics | |
M: arm-backend %unbox-byte-array ( dst src -- ) | |
[ v>operand ] bi@ byte-array-offset ADD ; | |
M: arm-backend %unbox-alien ( dst src -- ) | |
[ v>operand ] bi@ alien-offset <+> LDR ; | |
M: arm-backend %unbox-f ( dst src -- ) | |
drop v>operand 0 MOV ; | |
M: arm-backend %unbox-any-c-ptr ( dst src -- ) | |
! We need three registers here. R11 and R12 are reserved | |
! temporary registers. The third one is R14, which we have | |
! to save/restore. | |
"end" define-label | |
"start" define-label | |
! Save R14. | |
R14 SP 4 <-> STR | |
! Address is computed in R11 | |
R11 0 MOV | |
! Load object into R12 | |
R12 swap v>operand MOV | |
! We come back here with displaced aliens | |
"start" resolve-label | |
! Is the object f? | |
R12 f v>operand CMP | |
! If so, done | |
"end" get EQ B | |
! Is the object an alien? | |
R14 R12 header-offset <+/-> LDR | |
R14 alien type-number tag-fixnum CMP | |
! Add byte array address to address being computed | |
R11 R11 R12 NE ADD | |
! Add an offset to start of byte array's data area | |
R11 R11 byte-array-offset NE ADD | |
"end" get NE B | |
! If alien, load the offset | |
R14 R12 alien-offset <+/-> LDR | |
! Add it to address being computed | |
R11 R11 R14 ADD | |
! Now recurse on the underlying alien | |
R12 R12 underlying-alien-offset <+/-> LDR | |
"start" get B | |
"end" resolve-label | |
! Done, store address in destination register | |
v>operand R11 MOV | |
! Restore R14. | |
R14 SP 4 <-> LDR ; | |
]] | |
FILE: [[cpu/arm/architecture/authors.txt]] [[Slava Pestov | |
]] | |
FILE: [[cpu/arm/summary.txt]] [[ARM3 compiler backend | |
]] | |
FILE: [[cpu/arm/allot/allot.factor]] [[! Copyright (C) 2006, 2007 Slava Pestov. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: kernel cpu.architecture cpu.arm.assembler | |
cpu.arm.architecture namespaces math sequences | |
generator generator.registers generator.fixup system layouts | |
alien ; | |
IN: cpu.arm.allot | |
: load-zone-ptr ( reg -- ) "nursery" f rot %alien-global ; | |
: %allot ( header size -- ) | |
! Store a pointer to 'size' bytes allocated from the | |
! nursery in R11 | |
8 align ! align the size | |
R12 load-zone-ptr ! nusery -> r12 | |
R11 R12 cell <+> LDR ! nursery.here -> r11 | |
R11 R11 pick ADD ! increment r11 | |
R11 R12 cell <+> STR ! r11 -> nursery.here | |
R11 R11 rot SUB ! old value | |
R12 swap type-number tag-fixnum MOV ! compute header | |
R12 R11 0 <+> STR ! store header | |
; | |
: %store-tagged ( reg tag -- ) | |
>r dup fresh-object v>operand R11 r> tag-number ORR ; | |
: %allot-bignum ( #digits -- ) | |
! 1 cell header, 1 cell length, 1 cell sign, + digits | |
! length is the # of digits + sign | |
bignum over 3 + cells %allot | |
R12 swap 1+ v>operand MOV ! compute the length | |
R12 R11 cell <+> STR ! store the length | |
; | |
: %allot-bignum-signed-1 ( dst src -- ) | |
! on entry, reg is a 30-bit quantity sign-extended to | |
! 32-bits. | |
! exits with tagged ptr to bignum in reg. | |
[ | |
"end" define-label | |
! is it zero? | |
dup v>operand 0 CMP | |
0 >bignum pick EQ load-literal | |
"end" get EQ B | |
! ! it is non-zero | |
1 %allot-bignum | |
! is the fixnum negative? | |
dup v>operand 0 CMP | |
! negative sign | |
R12 1 LT MOV | |
! negate fixnum | |
dup v>operand dup 0 LT RSB | |
! positive sign | |
R12 0 GE MOV | |
! store sign | |
R12 R11 2 cells <+> STR | |
! store the number | |
v>operand R11 3 cells <+> STR | |
! tag the bignum, store it in reg | |
bignum %store-tagged | |
"end" resolve-label | |
] with-scope ; | |
M: arm-backend %box-alien ( dst src -- ) | |
"end" define-label | |
dup v>operand 0 CMP | |
over v>operand f v>operand EQ MOV | |
"end" get EQ B | |
alien 4 cells %allot | |
! Store offset | |
v>operand R11 3 cells <+> STR | |
R12 f v>operand MOV | |
! Store expired slot | |
R12 R11 1 cells <+> STR | |
! Store underlying-alien slot | |
R12 R11 2 cells <+> STR | |
! Store tagged ptr in reg | |
object %store-tagged | |
"end" resolve-label ; | |
]] | |
FILE: [[cpu/arm/allot/authors.txt]] [[Slava Pestov | |
]] | |
FILE: [[cpu/arm/intrinsics/intrinsics.factor]] [[! Copyright (C) 2007 Slava Pestov. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: alien arrays cpu.architecture cpu.arm.assembler | |
cpu.arm.architecture cpu.arm.allot kernel kernel.private math | |
math.private namespaces sequences words | |
quotations byte-arrays hashtables.private hashtables generator | |
generator.registers generator.fixup sequences.private sbufs | |
sbufs.private vectors vectors.private system | |
classes.tuple.private layouts strings.private slots.private ; | |
IN: cpu.arm.intrinsics | |
: %slot-literal-known-tag | |
"val" operand | |
"obj" operand | |
"n" get cells | |
"obj" get operand-tag - <+/-> ; | |
: %slot-literal-any-tag | |
"scratch" operand "obj" operand %untag | |
"val" operand "scratch" operand "n" get cells <+> ; | |
: %slot-any | |
"scratch" operand "obj" operand %untag | |
"n" operand dup 1 <LSR> MOV | |
"val" operand "scratch" operand "n" operand <+> ; | |
\ slot { | |
! Slot number is literal and the tag is known | |
{ | |
[ %slot-literal-known-tag LDR ] H{ | |
{ +input+ { { f "obj" known-tag } { [ small-slot? ] "n" } } } | |
{ +scratch+ { { f "val" } } } | |
{ +output+ { "val" } } | |
} | |
} | |
! Slot number is literal | |
{ | |
[ %slot-literal-any-tag LDR ] H{ | |
{ +input+ { { f "obj" } { [ small-slot? ] "n" } } } | |
{ +scratch+ { { f "scratch" } { f "val" } } } | |
{ +output+ { "val" } } | |
} | |
} | |
! Slot number in a register | |
{ | |
[ %slot-any LDR ] H{ | |
{ +input+ { { f "obj" } { f "n" } } } | |
{ +scratch+ { { f "val" } { f "scratch" } } } | |
{ +output+ { "val" } } | |
{ +clobber+ { "n" } } | |
} | |
} | |
} define-intrinsics | |
: %write-barrier ( -- ) | |
"val" get operand-immediate? "obj" get fresh-object? or [ | |
"cards_offset" f R12 %alien-global | |
"scratch" operand R12 "obj" operand card-bits <LSR> ADD | |
"val" operand "scratch" operand 0 <+> LDRB | |
"val" operand dup card-mark ORR | |
"val" operand "scratch" operand 0 <+> STRB | |
] unless ; | |
\ set-slot { | |
! Slot number is literal and tag is known | |
{ | |
[ %slot-literal-known-tag STR %write-barrier ] H{ | |
{ +input+ { { f "val" } { f "obj" known-tag } { [ small-slot? ] "n" } } } | |
{ +scratch+ { { f "scratch" } } } | |
{ +clobber+ { "val" } } | |
} | |
} | |
! Slot number is literal | |
{ | |
[ %slot-literal-any-tag STR %write-barrier ] H{ | |
{ +input+ { { f "val" } { f "obj" } { [ small-slot? ] "n" } } } | |
{ +scratch+ { { f "scratch" } } } | |
{ +clobber+ { "val" } } | |
} | |
} | |
! Slot number is in a register | |
{ | |
[ %slot-any STR %write-barrier ] H{ | |
{ +input+ { { f "val" } { f "obj" } { f "n" } } } | |
{ +scratch+ { { f "scratch" } } } | |
{ +clobber+ { "val" "n" } } | |
} | |
} | |
} define-intrinsics | |
: fixnum-op ( op -- quot ) | |
[ "out" operand "x" operand "y" operand ] swap add ; | |
: fixnum-register-op ( op -- pair ) | |
fixnum-op H{ | |
{ +input+ { { f "x" } { f "y" } } } | |
{ +scratch+ { { f "out" } } } | |
{ +output+ { "out" } } | |
} 2array ; | |
: fixnum-value-op ( op -- pair ) | |
fixnum-op H{ | |
{ +input+ { { f "x" } { [ small-tagged? ] "y" } } } | |
{ +scratch+ { { f "out" } } } | |
{ +output+ { "out" } } | |
} 2array ; | |
: define-fixnum-op ( word op -- ) | |
[ fixnum-value-op ] keep fixnum-register-op 2array | |
define-intrinsics ; | |
{ | |
{ fixnum+fast ADD } | |
{ fixnum-fast SUB } | |
{ fixnum-bitand AND } | |
{ fixnum-bitor ORR } | |
{ fixnum-bitxor EOR } | |
} [ | |
first2 define-fixnum-op | |
] each | |
\ fixnum-bitnot [ | |
"x" operand dup MVN | |
"x" operand dup %untag | |
] H{ | |
{ +input+ { { f "x" } } } | |
{ +output+ { "x" } } | |
} define-intrinsic | |
\ fixnum*fast [ | |
"out" operand "y" operand %untag-fixnum | |
"out" operand "x" operand "out" operand MUL | |
] H{ | |
{ +input+ { { f "x" } { f "y" } } } | |
{ +scratch+ { { f "out" } } } | |
{ +output+ { "out" } } | |
} define-intrinsic | |
\ fixnum-shift [ | |
"out" operand "x" operand "y" get neg <ASR> MOV | |
! Mask off low bits | |
"out" operand dup %untag | |
] H{ | |
{ +input+ { { f "x" } { [ -31 0 between? ] "y" } } } | |
{ +scratch+ { { f "out" } } } | |
{ +output+ { "out" } } | |
} define-intrinsic | |
: %untag-fixnums ( seq -- ) | |
[ dup %untag-fixnum ] unique-operands ; | |
: overflow-check ( insn -- ) | |
[ | |
"end" define-label | |
[ "out" operand "x" operand "y" operand roll S execute ] keep | |
"end" get VC B | |
{ "x" "y" } %untag-fixnums | |
"x" operand "x" operand "y" operand roll execute | |
"out" get "x" get %allot-bignum-signed-1 | |
"end" resolve-label | |
] with-scope ; inline | |
: overflow-template ( word insn -- ) | |
[ overflow-check ] curry H{ | |
{ +input+ { { f "x" } { f "y" } } } | |
{ +scratch+ { { f "out" } } } | |
{ +output+ { "out" } } | |
{ +clobber+ { "x" "y" } } | |
} define-intrinsic ; | |
\ fixnum+ \ ADD overflow-template | |
\ fixnum- \ SUB overflow-template | |
\ fixnum>bignum [ | |
"x" operand dup %untag-fixnum | |
"out" get "x" get %allot-bignum-signed-1 | |
] H{ | |
{ +input+ { { f "x" } } } | |
{ +scratch+ { { f "out" } } } | |
{ +clobber+ { "x" } } | |
{ +output+ { "out" } } | |
} define-intrinsic | |
\ bignum>fixnum [ | |
"end" define-label | |
"x" operand dup %untag | |
"y" operand "x" operand cell <+> LDR | |
! if the length is 1, its just the sign and nothing else, | |
! so output 0 | |
"y" operand 1 v>operand CMP | |
"y" operand 0 EQ MOV | |
"end" get EQ B | |
! load the value | |
"y" operand "x" operand 3 cells <+> LDR | |
! load the sign | |
"x" operand "x" operand 2 cells <+> LDR | |
! is the sign negative? | |
"x" operand 0 CMP | |
! Negate the value | |
"y" operand "y" operand 0 NE RSB | |
"y" operand dup %tag-fixnum | |
"end" resolve-label | |
] H{ | |
{ +input+ { { f "x" } } } | |
{ +scratch+ { { f "y" } } } | |
{ +clobber+ { "x" } } | |
{ +output+ { "y" } } | |
} define-intrinsic | |
: fixnum-jump ( op -- quo ) | |
[ "x" operand "y" operand CMP ] swap | |
1quotation [ B ] 3append ; | |
: fixnum-register-jump ( op -- pair ) | |
fixnum-jump { { f "x" } { f "y" } } 2array ; | |
: fixnum-value-jump ( op -- pair ) | |
fixnum-jump { { f "x" } { [ small-tagged? ] "y" } } 2array ; | |
: define-fixnum-jump ( word op -- ) | |
[ fixnum-value-jump ] keep fixnum-register-jump | |
2array define-if-intrinsics ; | |
{ | |
{ fixnum< LT } | |
{ fixnum<= LE } | |
{ fixnum> GT } | |
{ fixnum>= GE } | |
{ eq? EQ } | |
} [ | |
first2 define-fixnum-jump | |
] each | |
\ tag [ | |
"out" operand "in" operand tag-mask get AND | |
"out" operand dup %tag-fixnum | |
] H{ | |
{ +input+ { { f "in" } } } | |
{ +scratch+ { { f "out" } } } | |
{ +output+ { "out" } } | |
} define-intrinsic | |
\ type [ | |
! Get the tag | |
"out" operand "obj" operand tag-mask get AND | |
! Compare with object tag number (3). | |
"out" operand object tag-number CMP | |
! Tag the tag if it is not equal to 3 | |
"out" operand dup NE %tag-fixnum | |
! Load the object header if tag is equal to 3 | |
"out" operand "obj" operand object tag-number <-> EQ LDR | |
] H{ | |
{ +input+ { { f "obj" } } } | |
{ +scratch+ { { f "out" } } } | |
{ +output+ { "out" } } | |
} define-intrinsic | |
\ class-hash [ | |
"end" define-label | |
! Get the tag | |
"out" operand "obj" operand tag-mask get AND | |
! Compare with tuple tag number (2). | |
"out" operand tuple tag-number CMP | |
"out" operand "obj" operand tuple-class-offset <+/-> EQ LDR | |
"out" operand dup class-hash-offset <+/-> EQ LDR | |
"end" get EQ B | |
! Compare with object tag number (3). | |
"out" operand object tag-number CMP | |
"out" operand "obj" operand object tag-number <-> EQ LDR | |
! Tag the tag | |
"out" operand dup NE %tag-fixnum | |
"end" resolve-label | |
] H{ | |
{ +input+ { { f "obj" } } } | |
{ +scratch+ { { f "out" } } } | |
{ +output+ { "out" } } | |
} define-intrinsic | |
: userenv ( reg -- ) | |
! Load the userenv pointer in a register. | |
"userenv" f rot compile-dlsym ; | |
\ getenv [ | |
"n" operand dup 1 <ASR> MOV | |
"x" operand userenv | |
"x" operand "x" operand "n" operand <+> LDR | |
] H{ | |
{ +input+ { { f "n" } } } | |
{ +scratch+ { { f "x" } } } | |
{ +output+ { "x" } } | |
{ +clobber+ { "n" } } | |
} define-intrinsic | |
\ setenv [ | |
"n" operand dup 1 <ASR> MOV | |
"x" operand userenv | |
"val" operand "x" operand "n" operand <+> STR | |
] H{ | |
{ +input+ { { f "val" } { f "n" } } } | |
{ +scratch+ { { f "x" } } } | |
{ +clobber+ { "n" } } | |
} define-intrinsic | |
: %set-slot R11 swap cells <+> STR ; | |
: %store-length | |
R12 "n" operand MOV | |
R12 1 %set-slot ; | |
: %fill-array swap 2 + %set-slot ; | |
\ <tuple> [ | |
tuple "n" get 2 + cells %allot | |
%store-length | |
! Store class | |
"class" operand 2 %set-slot | |
! Zero out the rest of the tuple | |
"initial" operand f v>operand MOV | |
"n" get 1- [ 1+ "initial" operand %fill-array ] each | |
"out" get tuple %store-tagged | |
] H{ | |
{ +input+ { { f "class" } { [ inline-array? ] "n" } } } | |
{ +scratch+ { { f "out" } { f "initial" } } } | |
{ +output+ { "out" } } | |
} define-intrinsic | |
\ <array> [ | |
array "n" get 2 + cells %allot | |
%store-length | |
! Store initial element | |
"n" get [ "initial" operand %fill-array ] each | |
"out" get object %store-tagged | |
] H{ | |
{ +input+ { { [ inline-array? ] "n" } { f "initial" } } } | |
{ +scratch+ { { f "out" } } } | |
{ +output+ { "out" } } | |
} define-intrinsic | |
\ <byte-array> [ | |
byte-array "n" get 2 cells + %allot | |
%store-length | |
! Store initial element | |
R12 0 MOV | |
"n" get cell align cell /i [ R12 %fill-array ] each | |
"out" get object %store-tagged | |
] H{ | |
{ +input+ { { [ inline-array? ] "n" } } } | |
{ +scratch+ { { f "out" } } } | |
{ +output+ { "out" } } | |
} define-intrinsic | |
\ <ratio> [ | |
ratio 3 cells %allot | |
"numerator" operand 1 %set-slot | |
"denominator" operand 2 %set-slot | |
"out" get ratio %store-tagged | |
] H{ | |
{ +input+ { { f "numerator" } { f "denominator" } } } | |
{ +scratch+ { { f "out" } } } | |
{ +output+ { "out" } } | |
} define-intrinsic | |
\ <complex> [ | |
complex 3 cells %allot | |
"real" operand 1 %set-slot | |
"imaginary" operand 2 %set-slot | |
! Store tagged ptr in reg | |
"out" get complex %store-tagged | |
] H{ | |
{ +input+ { { f "real" } { f "imaginary" } } } | |
{ +scratch+ { { f "out" } } } | |
{ +output+ { "out" } } | |
} define-intrinsic | |
\ <wrapper> [ | |
wrapper 2 cells %allot | |
"obj" operand 1 %set-slot | |
! Store tagged ptr in reg | |
"out" get object %store-tagged | |
] H{ | |
{ +input+ { { f "obj" } } } | |
{ +scratch+ { { f "out" } } } | |
{ +output+ { "out" } } | |
} define-intrinsic | |
! Alien intrinsics | |
: %alien-accessor ( quot -- ) | |
"offset" operand dup %untag-fixnum | |
"offset" operand dup "alien" operand ADD | |
"value" operand "offset" operand 0 <+> roll call ; inline | |
: alien-integer-get-template | |
H{ | |
{ +input+ { | |
{ unboxed-c-ptr "alien" c-ptr } | |
{ f "offset" fixnum } | |
} } | |
{ +scratch+ { { f "value" } } } | |
{ +output+ { "value" } } | |
{ +clobber+ { "offset" } } | |
} ; | |
: %alien-integer-get ( quot -- ) | |
%alien-accessor | |
"value" operand dup %tag-fixnum ; inline | |
: alien-integer-set-template | |
H{ | |
{ +input+ { | |
{ f "value" fixnum } | |
{ unboxed-c-ptr "alien" c-ptr } | |
{ f "offset" fixnum } | |
} } | |
{ +clobber+ { "value" "offset" } } | |
} ; | |
: %alien-integer-set ( quot -- ) | |
"offset" get "value" get = [ | |
"value" operand dup %untag-fixnum | |
] unless | |
%alien-accessor ; inline | |
: define-alien-integer-intrinsics ( word get-quot word set-quot -- ) | |
[ %alien-integer-set ] curry | |
alien-integer-set-template | |
define-intrinsic | |
[ %alien-integer-get ] curry | |
alien-integer-get-template | |
define-intrinsic ; | |
\ alien-unsigned-1 [ LDRB ] | |
\ set-alien-unsigned-1 [ STRB ] | |
define-alien-integer-intrinsics | |
: alien-cell-template | |
H{ | |
{ +input+ { | |
{ unboxed-c-ptr "alien" c-ptr } | |
{ f "offset" fixnum } | |
} } | |
{ +scratch+ { { unboxed-alien "value" } } } | |
{ +output+ { "value" } } | |
{ +clobber+ { "offset" } } | |
} ; | |
\ alien-cell | |
[ [ LDR ] %alien-accessor ] | |
alien-cell-template define-intrinsic | |
: set-alien-cell-template | |
H{ | |
{ +input+ { | |
{ unboxed-c-ptr "value" pinned-c-ptr } | |
{ unboxed-c-ptr "alien" c-ptr } | |
{ f "offset" fixnum } | |
} } | |
{ +clobber+ { "offset" } } | |
} ; | |
\ set-alien-cell | |
[ [ STR ] %alien-accessor ] | |
set-alien-cell-template define-intrinsic | |
]] | |
FILE: [[cpu/arm/intrinsics/authors.txt]] [[Slava Pestov | |
]] | |
FILE: [[cpu/arm/authors.txt]] [[Slava Pestov | |
]] | |
FILE: [[cpu/arm/tags.txt]] [[compiler | |
]] | |
FILE: [[cpu/arm/4/4.factor]] [[! Copyright (C) 2007 Slava Pestov. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: alien arrays cpu.architecture cpu.arm.assembler | |
cpu.arm.architecture cpu.arm5.assembler kernel kernel.private | |
math math.private namespaces sequences words quotations | |
byte-arrays hashtables.private hashtables generator | |
generator.registers generator.fixup sequences.private | |
strings.private ; | |
IN: cpu.arm4 | |
: (%char-slot) | |
"out" operand string-offset MOV | |
"out" operand dup "n" operand 2 <LSR> ADD ; | |
\ char-slot [ | |
(%char-slot) | |
"out" operand "obj" operand "out" operand <+> LDRH | |
"out" operand dup %tag-fixnum | |
] H{ | |
{ +input+ { { f "n" } { f "obj" } } } | |
{ +scratch+ { { f "out" } } } | |
{ +output+ { "out" } } | |
} define-intrinsic | |
\ set-char-slot [ | |
"val" operand dup %untag-fixnum | |
(%char-slot) | |
"val" operand "obj" operand "out" operand <+> STRH | |
] H{ | |
{ +input+ { { f "val" } { f "n" } { f "obj" } } } | |
{ +scratch+ { { f "out" } } } | |
{ +clobber+ { "val" } } | |
} define-intrinsic | |
\ alien-signed-1 [ LDRSB ] | |
\ set-alien-signed-1 [ STRB ] | |
define-alien-integer-intrinsics | |
\ alien-unsigned-2 [ LDRH ] | |
\ set-alien-unsigned-2 [ STRH ] | |
define-alien-integer-intrinsics | |
\ alien-signed-2 [ LDRSH ] | |
\ set-alien-signed-2 [ STRH ] | |
define-alien-integer-intrinsics | |
]] | |
FILE: [[cpu/arm/4/summary.txt]] [[Additional compiler intrinsics for ARM4 | |
]] | |
FILE: [[cpu/arm/4/authors.txt]] [[Slava Pestov | |
]] | |
FILE: [[images/processing/rotation/rotation.factor]] [[! Copyright (C) 2009 Kobi Lurie. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: accessors arrays colors combinators | |
combinators.short-circuit fry grouping images images.bitmap | |
images.loader images.normalization kernel locals math sequences ; | |
IN: images.processing.rotation | |
ERROR: unsupported-rotation degrees ; | |
<PRIVATE | |
: rotate-90 ( seq^3 -- seq^3 ) flip [ reverse ] map ; | |
: rotate-180 ( seq^3 -- seq^3 ) reverse [ reverse ] map ; | |
: rotate-270 ( seq^3 -- seq^3 ) flip reverse ; | |
: (rotate) ( seq n -- seq' ) | |
{ | |
{ 0 [ ] } | |
{ 90 [ rotate-90 ] } | |
{ 180 [ rotate-180 ] } | |
{ 270 [ rotate-270 ] } | |
[ unsupported-rotation ] | |
} case ; | |
: rows-remove-pad ( byte-rows -- pixels' ) | |
[ dup length 4 mod head* ] map ; | |
: row-length ( image -- n ) | |
[ bitmap>> length ] [ dim>> second ] bi /i ; | |
: image>byte-rows ( image -- byte-rows ) | |
[ bitmap>> ] [ row-length ] bi group rows-remove-pad ; | |
: (seperate-to-pixels) ( byte-rows image -- pixel-rows ) | |
component-order>> bytes-per-pixel '[ _ group ] map ; | |
: image>pixel-rows ( image -- pixel-rows ) | |
[ image>byte-rows ] keep (seperate-to-pixels) ; | |
: flatten-table ( seq^3 -- seq ) | |
[ concat ] map concat ; | |
: ?reverse-dimensions ( image n -- ) | |
{ 270 90 } member? [ [ reverse ] change-dim ] when drop ; | |
: normalize-degree ( n -- n' ) 360 rem ; | |
: processing-effect ( image quot -- image' ) | |
'[ image>pixel-rows @ flatten-table ] [ bitmap<< ] [ ] tri ; inline | |
:: rotate' ( image n -- image ) | |
n normalize-degree :> n' | |
image image>pixel-rows :> pixel-table | |
image n' ?reverse-dimensions | |
pixel-table n' (rotate) :> table-rotated | |
image table-rotated flatten-table >>bitmap ; | |
PRIVATE> | |
: rotate ( image n -- image' ) | |
normalize-degree | |
[ '[ _ (rotate) ] processing-effect ] [ ?reverse-dimensions ] 2bi ; | |
: reflect-y-axis ( image -- image ) | |
[ [ reverse ] map ] processing-effect ; | |
: reflect-x-axis ( image -- image ) | |
[ reverse ] processing-effect ; | |
]] | |
FILE: [[images/processing/rotation/test-bitmaps/lake.bmp]] base64[[Qk3lAQAAAAAAADYAAAAoAAAADQAAAAoAAAABABgAAAAAAK8BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQID/QID/QID/QID///+A//+A//+AAAAAAAAAAECA/0CA/0CA/0CA////gP//gP//gAAAAAAAAAAAAAAAAAAAAABAgP9AgP9AgP9AgP///4D//4D//4AAAAAAAAAAAAAAAAAAAAAAAAAAQID/QID/QID///+A//+A//+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAgIAAAIAAAIAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAECA/wCAAACAAACAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAICAAIAAgAAAgAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgACAgACAgACAAEBAAEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAgIAAgIAAgIAAAABAQAAAAACAAP+AAP+AAP8A/wAA/wAA/wD/gID/gID/gIBAQABAQAAAAAAAgAD/gAD/gAD/AP8AAP8AAP8A/4CA/4CA/4CAQEAAQEAAQEAAAIAA/4AA/4AA/wD/AAD/AAD/AP+AgP+AgP+AgEBAAEBAAEBAAEBAAAA=]] | |
FILE: [[images/processing/rotation/test-bitmaps/small-rotated.bmp]] base64[[Qk3GAQAAAAAAADYAAAAoAAAADQAAAAoAAAABABgAAAAAAAAAAACAAP8AgAD/AAAAAAAAAAAAgAD/gAD/gAD/AP8AAP8AAP8A/4CA/4CA/4CAQEAAQEAAQEAAQEAAAIAA/4AA/4AA/wD/AAD/AAD/AP+AgP+AgP+AgEBAAEBAAEBAAEBAAACAAP+AAP+AAP8A/wAA/wAA/wD/gID/gID/gIBAQABAQABAQABAQAAAAAAAAAAAAAAAAAAAAAAAAAAAgACAgACAgACAgAAAgAAAgAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAgIAAgIAAgIAAAIAAAIAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAICAAICAAICAAACAAACAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQID/QID/QID/QID///+A//+A//+AAAAAAAAAAAAAAAAAAAAAAAAAAECA/0CA/0CA/0CA////gP//gP//gAAAAAAAAAAAAAAAAAAAAAAAAABAgP9AgP9AgP9AgP///4D//4D//4AAAAAAAAAAAAAAAAAAAAAAAAAAQID/QID/QID/QID///+A//+A//+AAA==]] | |
FILE: [[images/processing/rotation/test-bitmaps/small.bmp]] base64[[Qk3WAQAAAAAAADYAAAAoAAAACgAAAA0AAAABABgAAAAAAKABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAD/gAD/gAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAP+AAP+AAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAA/4AA/4AA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAP8AAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAA/wAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAD/AAD/AAAAQID/QID/QID/QID/gACAgACAgACA/4CA/4CA/4CAAABAgP9AgP9AgP9AgP+AAICAAICAAID/gID/gID/gIAAAECA/0CA/0CA/0CA/4AAgIAAgIAAgP+AgP+AgP+AgAAAQID/QID/QID/QID/gAAAgAAAgAAAQEAAQEAAQEAAAAD//4D//4D//4D//4CAAACAAACAAABAQABAQABAQAAAAP//gP//gP//gP//gIAAAIAAAIAAAEBAAEBAAEBAAAAA//+A//+A//+A//+AgAAAgAAAgAAAQEAAQEAAQEAAAAA=]] | |
FILE: [[images/processing/rotation/test-bitmaps/PastedImage.bmp]] base64[[Qk22qgAAAAAAADYAAAAoAAAAdQAAAHwAAAABABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApmYoqGcqpWUoomImomMnpGUppGQno2MjpWUlpmYmomIioWEhoV8hnlodn1oepl0hpV0hqmQosW4ztnQ6tXU7u3tD0JJc1JhjxYpXu4FPtntJr3NBqGs5rGw6o2AunVknoVwrpl8tqmQwpGAroV4npF4noVkjoFgioFggoFkgnVcdolwhp2ElqmUoqmUmp2IkpF4ipF4jpmAkp2ElpmAko10hnlgcnFYbm1Ual1IWmlkcnV0fn10gn10gnVodoFwgpmAlp2Amq2MqrmYtq2UpqGIjqmMlo1sfpVwipl4kq2QrqmMtqWMurGcyrGgzo2ErpmQvs3I9uXhHxIVVzIxhzY1kyYthxIZdx4lgvoBXuntSvoBXvoFWvoFVuHxQt3tPw4dayY1gzJBhvYFQrnA/qGc1oF0po10nqWAprGIqrWMrp10lplwkqGAnqmMpqmQpqmQorWcssWkxq2Itq2AsAKJhIJ5eHpxcHZ1eIZ5fIpxdIZdXGpNTE5NSEZZWFppZGptaHJtYG5xXG51XG51XG51VGaJcIqxoMapoMKdlLrh4QsWGULd5Q6RnMZhcJpFWHpxdJaFfJ6FeJp9aJJ9ZI5xWIZhSHZdRHJNOGZdTHptWIJlSGpxWHqFbIqReJaZgJ6FcIaRfJKZgJKNdH6NdIaJcIqJcIaReI6BbHqFcHZ5ZG5xWGp1XG55XHZ9ZH6BfIqBhJJ9fIqJhJKViJadkJ6xoLK5qL7BrMa9qMLZwNbRuMrFpLK5mKrBnLbRsMrt0PLlzPbVvO7RvPbJvPLd1Q79+TMqKWNSVZNaXadCRZ8uMZMaHX8WGXMiKXcOEV8aGW86PY9OUZs+QY9CSZM6RY9GUZsiLXMOGVrR3RapqN6poNaRgK6diLKpjK6xjK65lLa5mLrBoL61lLLBpL69pLa9pLatlKqpiKqhdKKdcJwCfXBucWxqeXBydXB2cXB6YVhqXVBiYVRaaWBifXR6iYCKeXSCdWh6fWx+hXSGhXB+kXSKvajK/fEa7ekSvbzq6e0a1d0KoajWjZi+bXyeVWSCYWSGaWR+aWB+dWiKgXSaeXCWeWSOhXCegWyakXyqpZC2nYymmYimmYimkXyanYyqoZSupZSqnYiaoYiWnYSSnYCakXiOhWyCgWx6hXB2fWhuaVRicVhqdVxyiXCOmZCmfXyOfXiKhXSGgXB+gXCCkYCSlYSWkYCWhXSOkXySkXSKuZiqzay+zajC2bjWxajKrZTCqZTKvajm2c0LCgVHTlGLTlWPLjl3FiVrGiF7Fh1y+f1TEhVjHh1fIh1fLiVnWlGXXlWfXlWfcnG7bm2zUlGW8fU25eUi8fUm2dUC0cjyzcDm0bjaxajG4bze0bTSxazKzbDOvaC+sZiyqZCmmYCSjXSGkWyKlWiSkWCQAoVwbn1oZoVwbo14fpGEjo18iqWQmrmkps24usm0vqWUppGElol4jol4jqGUprmsusGswt3U+yYlTwYJNu3xJx4lWsnVCrHA8u39KsXQ9nmEqomQutHZAxIZQvH9IsHM8snM8t3Y/v3xFunU/s204sGw0rmswrGswrWsxpmQrpWMqo2AnpmInqGMnpV8jo10ipl8mpmAlo10ipF8iol0eoFscnlgboFoeo10iqGIprGguo18koFofpV8jpF4ho1wfoVsfoFofnVgdnVkepV4kpl0jpVwio1ogpV0ipl8lpF0lnlgjp2IwsW08tHJDv4BQmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AAKhhH6hhHqtkIatlJKZgIKVeIadgI6dgIaZfIKNdH6ReIqRgJahkKa1pLq9rMK1rL6VjKKprM7x/ScCET8WIVbyATahsOrh8SseKWMSIVceKV8WIVM+UYL2DTqduN6dsNapuOKxtNrNwObVvObNsNbFrMa5rMKZlKqBhJptbIZtbIZxbIaBcIqFcIqBaH6FbIKVeJaljKKVfJKJcH6JdH6VgIahjJqdhJaReI6NcI59YH5lTGZtUGaJbH59ZG6JZHKVeIapjJ6xlKa5mLLBnLqxkKqtiKaZdJKVfJJ5YHqJbI7BqNcWATcWBUbl3SLFyQphOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAACsZSSqZCGnYh2iXRmfWxmhXB6iXCCjWx+kXCChWR6iWSCpYSiuaS+saS+nZSupaS+mZi2rbDWydD+tbjulZjSpajm4eEfJiVm+fk6/f0/BgFC+gUy+g0uzeD+eYyqVWCCcXiWeXyWnZSywbDSwajKsZi2rZSytaTCqZy6cWiGZVx+eWyOfXCWdWSGeWB+cVhyaVRycVx2gWyGmYianYSWqZCitZiqtZSqoYCapYCaqYymqZCipZSmnZimkYyanZSipZCmvZiyxZiyzZy2wZzGsZjCoYiyoYSqrZi2uaDC3cjzFgE3OiVnKhVfBfVDBglKYTgCYTgD///+YTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgD///+YTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgAAs24uq2ckol8aol8apWMhpGEjol8jol0ipF0jqWMorGYsq2QqqmMpqmYsq2gvsXA3tXQ8sXE7qWo0rGw4sW89unhIzYtawX5OsG08sW8+sW49tnZBu3xEuXtCq200rG00rGwzrGszr2w0sm83sGw0qmUtp2Eop2Ipq2YtqmYtpWEpqGQsqWUtqGMrqmMqqGEopmIppmIorWkur2ovsm4xtW8zsmsvrWUqrWQqrWQqrWcqrGYpp2Qmo2IloGAjpGMnpmInp14krGAnrWEoqmAqq2Mur2gztnE5tnE5tnI6tHI8tHFAvn1Oy4te1JVq15xwmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AAK1pLKZjIqRiH6lnJKtqKahmKaVjKaRkKqppMKhmLaZjKKlmKqxmK6xmLK5pL7FsM7VvOrd1QLJyPK9vObBvPK9tO7FuPa5qOahlMqpnNaxoNq1rNrNyO7t6RLp6Q7Z1PqtqM6poMq5sNqpnMqNfKqRfKaNeJqRgKK1pMLdzOrJuNa9qMbFsMrFqL7NsMbVuNLVxN7ZyOK1pLqhlKallKKlkKKZhJaVeI6FZH6JaIKVeIaJcHaNdH6VgI6FcIKVgJKNdIqBZHqhfJq5lLLBnMbFoM7NsNbdyOrRyObd3P7V2QbV5R8CGV8mRZNOcc9+pg5hOAJhOAJhOAP///5hOAJhOAP///////////5hOAJhOAJhOAJhOAP///5hOAJhOAJhOAP///5hOAJhOAJhOAP///5hOAJhOAP///////5hOAP///5hOAJhOAP///5hOAJhOAP///5hOAP///5hOAACcWR+dWh2lYyOpaSiwbzGubjKzczqpazWiZC6iYyqzcjewbjKwbS+uaS2sZiuoYSmqYi6qaDKlZS+mZS+oZjGoZjGsaDWsaDOqZTCuaDOvaTSqZi+raDGvbTemZC6lYi2jYSypZzKzcT21c0CubDiqZzOnZTCpZzGraDKoZS2gWyOgXCGrZSqtZiurYyepYyeiXiOnZSqpZyuiYCOfXB+cWRyhXiOkXySpYyiuZy2pYyasZCexaiyxai2waC2yajCxazG1bza3cjuxbTWsZjCwajSwazSybzeycjyxcz2zeUS+h1bPm23bqH7grojksZCYTgCYTgCYTgD///+YTgD///+YTgCYTgCYTgD///+YTgCYTgCYTgD///+YTgCYTgCYTgD///+YTgCYTgCYTgD///+YTgD///+YTgCYTgCYTgD///+YTgCYTgD///+YTgCYTgD///+YTgD///+YTgAAqWgusm81wYBCu3w+snI2tHM6yopU2Jhl1JVfvX9GsXE2rWsvsW8wtnM1s280r2oytG85snA5sHA3rGozrGkyrms1s245smw2sGkyr2cwqWIqqGMpq2YuqWYuqmcwsW83tXI8uHZBvXtGu3pGuHdDtHNAq2s5pWQyn10pmFYfmlcgoF0kp2MoqWQpqGInqGInq2gtsnA1sG4zrmwxp2UqpGInpmQqqWUssWwzs241rWgusGowtG0ztGsytm00t283uHI8u3hCtnVBsnI+sG87s3A7snA8s3I+uXtHyI1Z1Zxr2qV33ql+6baN9MGb876bmE4AmE4AmE4A////mE4A////mE4AmE4AmE4A////mE4AmE4A////mE4A////mE4AmE4A////mE4AmE4AmE4A////mE4A////mE4AmE4AmE4A////mE4AmE4A////mE4AmE4A////mE4A////mE4AALh2P7d2PbR1ObFyNqprMadnLrRzPs2LWdKQXMB/SLNyOK1rL7BvMK9uMKxrL6ZlLKxqM6tpMKxqMKpnLq9qMrFsNK5oMK1nLrBpL69mLKlhJ6tlKa1nLapkKqllK6toL6toL6tpMaZlLqVlLrJyPLt8ScyPYN+ic9ucarRzP6lnMqpoMa9sNLNwNrp2PLRxNrNxNqhmK6dlKqtpLqxpL6pnLqJfJ6NgKKdjLKhlLalmL65rNLRvOLNtNrJrNbJsOLRxPcSFU8KFVMuRYNyhcOOlc+Chb9SVY8SHVdqdbeuxgu20ieathOGogt6kfdabcphOAJhOAJhOAP///5hOAP///5hOAJhOAJhOAP///5hOAJhOAP///5hOAP///5hOAJhOAP///5hOAJhOAJhOAP///5hOAP///5hOAJhOAJhOAP///5hOAJhOAP///5hOAJhOAP///5hOAP///5hOAACoZi+gXiWjYiepaS2mZyykZCukYi2ybjq1cDusZzCiXiWaWBudXB6kZSepai6maC2pazCraS+qaCyqZiqrZSupZCqnYSisZiuwai+uZyuqYyesZiqqZCmjXyOmYialYSaiXyWiYCehYCahYSimZi6rbTnEiVrSl2jXmGfBgU60cz2ycDm0cTmubDOvbjSwbTSxbzStai+wbDKwbTSybzevbDSsaDKrZzGuazSoZS+saTasaTawbDmqZjKmYi6lYS+3dkTYm2rboHDlq33vuInssIDQk2SvcUKlZje5ekzPkGPSk2nMjWXBgVuyckeraTiYTgCYTgCYTgD///+YTgD///+YTgCYTgCYTgD///+YTgD///+YTgCYTgCYTgD///+YTgD///+YTgCYTgCYTgD///+YTgD///+YTgCYTgCYTgD///+YTgCYTgD///+YTgCYTgD///+YTgD///+YTgAApGEqnFkgpWInqGcroWAlomAopmMtsW02qmUunlkgm1YdoV0ipGImq2wvrG0xqWwvqGsuqGgqpmIlpmEkpmAlp2EmpmAlolwhn1keoFoeoFoepF4ip2InqGQop2MopGAlo18lol8lomAlpGIprWwztnZB05dn05Zmx4dVu3hEsm84rmszr2sxqWcts3I4tHI4tHA1tXA1tXA3tnE6tHA7tXE8sm47tnE/sGw5q2g1rmo6sGw7qWY1tXJAwoBNw4FPxYRSy41dy45fxopdxIhay49gxYZYqGk6o2EzsG0+tHBCr2w/qWU5ol4yoFsqpV4omE4AmE4A////////mE4AmE4A////////////mE4AmE4A////mE4AmE4AmE4A////mE4A////////////////mE4AmE4A////////////mE4A////////////mE4A////////mE4AmE4A////mE4AAKlmLbFsM7h0ObNwNaxqL6lmLqZjK6xpL6xqL6pmLK1oL7RvNrRxN7RxN6xrMKlrLKVmJ6ViI6NeH6JdH6NdIadhJqljKKZgJaZhJqhiJ6diJ6pmLK5qMa1oL7BqMrBrM7BrMrBrMrNuNbx3PsiDSsuJU8uLWbd2Q61qNKtmLqhhJ6hiJqdhJKNfI6ViJqRhJqJcIaNcIqljK61mMbRtO7hzQrRvPrhyQrx3Rrl0Q8N8TcB6S8eDUdKPXM2LV8aFUsqKV86OW8yLW7t7S61tPrRzQ7VzQ715Sbl1RK1nNaVfLKFbKKFbKKZgLKxkMKlgKJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAP///5hOAJhOAJhOAJhOAJhOAP///5hOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAP///5hOAAC1cTi3cTi3cjezbzSsaS2taS+tajGsbC6ubzGubjKxbjSwazOrZi6pZSujYCShYCGfXh6fWxuhWxymYCKsZSmuaC6wajCzbjS4dDm0cDarZy2taTGvazWybji6dT+3cjy1bzm0bji4czy+d0C0bTepZS+hYCqdWyWjXyaqYyirYyaqYSOmXyCjXiCdWRudWR2jXSOqYiyxaTSyaze1bz2+eEe8dUazbT2sZjaoYjKrYzSyazurZTOkYCyfXSeaWCOhXyqwbjmwbDqnYzKraDeuajmlYC+mYC6jXSihWSOjWyWiWiOhWiKhWyKhWSGfVyCYTgCYTgCYTgD///+YTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgD///+YTgCYTgCYTgCYTgCYTgD///+YTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgD///+YTgAAs284tXI6tHE5s283sGsxrGctqmUqq2ctr20zsnI3rm40pWUro2EmpWAlpF4jpmAko2AjpF8mpmAorWgxt3I7s3A7r2w3vXpFw4JMtnVAtXQ/vHpFq2k0snA7v31HsW84rGgxrmkytnE5rGUtpV4mp2MqpGQpp2Uqq2cusWwytG4zsWwvrGcqqGQqp2UrqGQtsmo4tGw7rmo3tXE/tXJArmo5tnFAu3VFsGg2pl4qo1wooFkmo1wqpV4qpl4pqmMsp2AopmEoqWQsqGMuol8qmVchlFAbl1EbmlMdolkjpl0mpVsjoVkgnFQam1UbnVogmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AAK9tNbJwObh3QLRxOqxmLa5nLatjKKxjK6tmL6pqMaZoLqRmKqhmK65nLbBoLrFrMbVwN7p1QLhzQLFsOrJvPbNwPrFvPbRzQbt7SLFxP6xsOrNzPrRyPaxqNbFwOrJxO7FvOK5rNbJvN7FsNbZvN7VyObN0OLR0OrNxOrJwOrNxOrVzOrNxObRzPbh4Q8B9S8uEVsuEVcSATsKATseFU8SBUK5qOKZhLqVeJ6NcIqBbI6JdJ6ZfK6deKqdcKKdcJKddI6VdI6BaIJ1YIZdWHpdWHpdWHZxXIaBYIqRaJKZbJaNYI6NZIqNaIqZhJ6dmK5hOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAACsajCrbDGubjStazGqZSytZi2qYSimXSWhXCSgYCakZyyoaC2raS60bjS4cTe2bze+eULBe0azbDqhWymYVCGjXy2pZTOeWyidWyehXyykYi+qaDSqaDOpZzKmZC+kYy6nZjCoZzOubDexbjm0bzuxbzmucDqzc0C7eki6eEe5eEa/fkrAgEzQkF7ammrLiVvBfE7Efk6+ekiycD2ycT6vbTugXCqcVyOhWyOlXyWhXSSgWyWhWiWiWSWjWCKkWSGjWh+lXSGdVxyZVR2ZWCGYWCGcWSKgWiSiWiSiWiOlXCWoXiisYy2qYyypZCyqZi2YTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgAApWQpnF0gnl8jo2Imp2MppmEoqGEpqGIpp2IpomIoomMpqGgusm82uHM6smsyp18ppV8ppV8roVoonlcln1gmpl8trWYyqWQvq2YxrWk0rWg2r2w4rGo1pGItpGQupmYyrGw5rG05sXE+uHhFtnRDr249t3lIuXpLwYFUzo1gzYxfvn9OuHhHunpKs3VHpWQ3oVwunVkpnVsoo2EuomEun10rnVknoFwnoVwkn1kfnlogm1Yfn1gjolklo1kipVsjpVwhqWImqGInqGMqqmcxqWcyqWQvpmAqp2AoqGEopV4lo1slpl8qo10poVomqWIsqmMsqGIsqWMtpF8po10nn1smnVkknVkkoFwooFsqn1opoFoon1cknlUhnFMgmlIdnVQfmVAcmlEdmU8YnVMan1ccn1cbnlUcnFIbmk8bnFIdn1QdoVceoVkenlYcn1YcoVgeolgeoVcdo1kfo1ogAKVkJ6BgIZ9fIKJhI6ViKKdhKapiLKxmLahjKqZkK6ZnLaNjKaBeJqNeJ6JaJKhfKqlhLaxkMbFoNrFpN7NqN7NqNrZsOLRrN7ZuOblyPbt1Qrp3Q7V0P7NzP6trOKxtOrR3Rbp8Sr1/TsiKWcyMXMeJWM2OX8SEVsOCVsOBVbt5S6xqOp9eLZpaKJ5eL51cLphVJJxZKKZkMaZkL6VkL6RiMKllM6tmMaZhKaRgJqZhJ6hjLKxlL65lMKxiK6hfJqxkKaxmKqtmK61nL6hkL6djMKhjLqpkLqpkK6NcIqNbI6BZI6ReKqhiMKhfLaxiLqpgLKhgKqNcJp9YIp9ZI55YI5lVIJRQG5hUH5tUI5hRIZVOHJVOG5xTHp1VH55XIKJaI55WH6RcJaZcI6BXHZ1VGp1UGZxTGZtRGZxSHKFXIZ5THJ5TG51TGptSGJtSGJpRF5pRF5tSGJtSGJxTGQCjYiSiYiKfXx6hYCOoZCqmXymjXCejXSajXiWgXSWgXiaeXSShXiipZS+waza1bDiyaTWxaTaxaTayaTa0aTW0aTS1ajW3bTm2bTm3bju0bTqpZjOlZDGYWSaWVyWtcD7Ag1HGiVjGiFnNj2DEhle7fEyxcUCubD2nZDaYVSaaViWdWiafXSekYy2nZjKmYzKrZzWtazemZC+jYSyhXyqjXy2mYi+oYy2oYyqqZSqpZSqsZzCvaDKuZDCqYiupYSiqYyinYialYSajXiWdWCOhWyifWiWhWyWkXiWhWyGmXyeoYi2rZDGrZDOpXy+rXy2nXCieVR+ZURubUx2ZUh2ZUx2WURyVUBuXUR2XTx6UTBuVTRyYUB2dVCCgWCKgWSCdVRyZURegWB6jWh+fVhycUxmbUhmfVRyhVh6fVR6eVB2cUhqZTxiYThWaUBeXThSYTxWdVBqfVhyjWiCkWyEArWwur24tsXAxr20wrGgvqWUuqGItpmEqqWQrp2Mrp2QtqGYvrWs2sW45sm04smw3sWg0r2c0rWYyrmYys2k0tWw2tWs2tWw3sWg0q2Mxo1wsnVopnV0sqms5wYRS3aBu251s36Fx2ZtryopcsXFCrGo5pmQxo2Ato10sqWMwqWMurGcvrmkwrmowrmkxqGMupF8toF0om1kjllQemFQgm1Yjn1omn1oknlkfnFYbnFccolwlqGErpVwooFgin1kgol0ioVwgn1ohoFojn1kkolwnpF0opl8pqGEppl8npF0mpF0poFkmnlclolgnoVUjn1QgoVchn1Ygn1cholskolsloVsmolwnn1gjn1UjoFYkoFcknlUinlUhoFgim1MdmE8XnVQaoFcdnlUanVUaoVgfo1kipVojplsko1ggnlQcnVMcn1Ufn1UeoFYeoFceoVgepFwipFwiqF8lrWQqALh1Ord0Nrh1ObZzOLRxOLNwObBsN6xpMrBrNa9pNK1oNK1qNa9tOK1sNq5rNrNrN7JoNKxmMahjLqdhLKtkLq9oMq9nMq5nNK5nNrBqOq9rPLh3ScSGV9iaa9mbbNmbbNqcbMqLW7Z2RapoOKBdLaVhLqllMKtlMKpiL6tiLqhfKKVdJKNbIKNbIKNcIaJdJZ9aJZpWIJhVHplWHZlVHpxWIZtVH5hRG5tUGpxVGp1WHKRcJaNaJZ1UIJ1VIJtVHptWHJtWHJtWHp1XIZ5YIqBaI6NcJaRcJqFZI55WIKFYI6RbJ6FYJKBXI6BWI6BUI6FXI6FXIqFYIaJbIqReJKNcI6BaI6JcJqBYI59UIKFWIqNZJaFYJKJZJaNaJqFZJKNaI6JYIKFYHqJZHqFXHqNZI6VaJadbJqpfJ6pgJ6phKKZdJ6pfLKddJ6RaIqRbI6FaIaRdJKZeJKdeJKJZHwCxbTS1cTa4czqwbTStajOvbTatajWsaDOvaDOtZTKrZDKqZzStazitbDetajWxajWyaDOsZzGlYi2jXimpYy2sZjCrZTCqZjOwbTy4dUe9fFDKi1/Rk2fXmW3en3LPkWO2d0iiYjGjYS+lYjCkXy2qYzCrZTCsZDCkWymhVySkWSOhVh2fVRuhVx6hVx+fVyGbViGZVB6aVR2YUxqXUBmZUBubUh6XTxmcVhueVhuaUxmYUBmXTxuZUR6XURyUTheVUBiYUxueWCKdViKaVBydVxycVhybUx2cUx6eVSGfViKkWiaiWCKgViCgVyKjWieiWSWjWiWlXiajXCKiXCGjXSKkXSSgWSGgWCOdVCCdViKjWSalXCimXiqqYS2sYi2oXSimWyWlWiOkXSKgWSChVyKiVyOlWiWlWySqYCepYCinXiqpXy2nXCimXCajWySkXCWlXSWiWiGhVx+bURgAo14on1kip2EqpGApol8oo2EqoV8pol0ppV0qplwqqV8uqWMyq2k2qmo1q2k0sGo1tGo1rmk0qWcyp2Quq2cwrGgxp2Qwqmc2uXhIwYFUuXpQwIJZxIZex4pfwIJWpmc6oWAyoV8upWEvqGIvqmIuqmMvqmMvqmIwp14tql8vqFwpplwmpFkjo1kioVcinVQgmlUgnlkipF4lqGEopFwko1okpVsmpl4nn1cdoFgcn1gen1YgoFgknlcln1gkoVslpF4opF4ooVsmnFYinFYdnlkcnlgdnVYeoFgkpVooolcko1gjoFYfpFkhqF4oqGEtqGEspF0opF0lpV8kpmAlqGInqWIppV0lolslkk8fgkkeiE0ikVIkl1UnnVgopl4trGIuqF0pp1wno1wioVsipFwopFoopFkmoVchnFQanlYdm1MemlEgoVYkpVsno1ololokn1chm1MbmlEZmk8XAJ9ZJKBbJKJdJaJeJZ5aIpxZIJtXIJtTH55VIqFYJqRdKqVfLaZjMKVlL6ZkL6lkLqtjLqlkL6hmMKlmMK1pNK9sOK5rOa9tPb5/Uc2QZMuNYsyPZ8+RaLt+U6psP6FiM6loN6dlMqRhLqVgK6dhLKtlL6hhLqphL6pfL6xhMK1hL65jL6pgKqZcKKVdKadeLKNeKqVfKq9pM61lL6piLKpiLKxjLqdgKqliKa5nLq1mLqpiLKdhK6RfKqhjLatmL6pkLaRdJ5tVIJtWIqFbI6JdIqFbIaBaIqBYI6JaJqZcKKJYI6JYIKpfJ6phKqZfK6NcJ6FaJaFZIqRcI6NbIp1VHJtRGZxSGYNZME9aTUcxG0coEVMvFGE2GHM/HYNIIo9PJJdTJZxWJZ5aJKVdKKdeK6VbKaJXI59UH5pPGJdNFp1UH6BXI6NZJKNZI6FZI59WIJxTHZVMFpdPF5tQGACuaTKsZy6pZCumYSemYCalXyWgWSCfVCCiWCSjWyaiXSelYSuhXyifXiefXSejXimhXCedWSSdWSSfWyemYS+xbjy9e0rMilvOkGPKjmK4fVCqbkSqbUOkaDqqbDurajeqaTasajeraDWqZzKqaDCsaDKqYi6tYi+vZDGtYi+vZDCvZTGuZTGrYy+mYSyiXSmiXCujXSuiXCigWiWeWCOlXymoYiypZC6qZTCqZDCpYSyoYiumYiqhXSWiXyejXyajXCWjWyWkXimmYi2nYi2pYiymYCmgWiSgWSOjXSelXyikXCSmXCSmXCSlWyWhWiWdVCCbUh6fVSChVyGeVB6aTxmZThebURlda14urtkgqNkIgKcTaYMiTFQ0MCZFJxJQLBRcMhVtPRl7RB2JTCGRUCKXUSSbUyKfVCGkWSSpXimpXyeqYCimXCOhVx+fVR2bURudUx6iVyOkWSShVyEArmkxqWQrp2IpqmUrs200sm00s2w1s2k1q2ItqWEsqGMspGEpomEopWUrp2YupmMspWErpWEspWEsol4ppF8ts249v3xM0pBiyIhbvoJVtntOtnlOu31StHVGs3RBsnE9r245sG07rmo3q2gyqWYtpmIqo1snolklo1gkoFUhpFklqF4qp10polwnpV8qpF4po1wqoVoopV8rrWYxq2MurGQuqmQurWgyrGgzqWQvq2QwrGYwo2EqmlghoF0mpF8pqGErqGAqpmArpF8sp2AsqWEsqGArp18pqmIsrWUvqmErqF4nqV4npVoin1Ufm1IemlEdmlEdnFMfn1Uhn1UfnVMdoVYgo1kjTXh3XMPmf9n/bdL/U8XyOLbmJKzcDY23D3ORH1ViMDk0QSUQSCgSVC0TZTYWd0AahkgekE4hmFMjmVIdm1IbnFManVQaolgfo1kjplsnp1wop1wnqF4oAKxnLq9qMbJtNLNuN7VxOrZzPLFrNa1nMqljLadhKqVhKKViKaFfJp9dJKBeJZ9cJKNgKKhlL6pmMatnM61oNrdyQbVwQbJuQLFuQbZ0SL5+Ub1+Url5S7BwP7R0P7Z1P7BtN6pmMqReKZ5ZI5lVHZNPF5VOGZhRHJdPGpxTHqFYIp1THZtTHaZeKKhhK65mMa1lMahgLKlhLaZeKKRcJqVdJ6ZgKqpkLqVgKqJeKaNfKqJfKqFgKqFgKqZkLahjLaxlMKtiLqpjMKpkMqlhLq1iMKthLqZdKqdeKqdeKaBXIZ1THaJWIKVZIqdcJqNaJqFYJKBXI59WIp9WIqFYI59VIZ1UIJ9WIkx4eFO+4oPc/3LX/3LX/3LX/3LX/3LX/13L9UjA7Cyx3w+h0gx5mxpbbSs/PkAkEUkqFFUvFWQ3F3I+Fn9FGY5QHp1ZI6piKqxiKqthK6lfK6lgK6xkLgCvbDOwbDWuajKwazWqZzGeWyWZViGZUyCaVSKgWyajXyehXSaaVx+iXyioZS2qZy+tajOvazarZzKqZTGqZTOxbDuuajqwaz27dknFgVTIhFi3dEeqaDmmZDGjYSujYCmlYCugWyaaVB+ZUx2aVh6aVh6gXCWnYSugWSOgWCKiWiSjWiSmXSelXCaoXymnXimkWyahWSOiWSSiWSOdVB6eViCbVB6bVR+aVR+gXCaiYCqcWiWfXymkZC6nZS+rZTGsYzCvZTOtZTOlXy2kWyqkWSmeVCOYUB6UTBmRShaZURugVyGgVSCfVB2kWiWoXyyrYi+rYi6qYS2qYS2pYSynXyunYCulXypMeXkxrtmV4/922/922/922/922/922/922/922/922/922/9o0/lSx+81t+IYptYJgagYY3opSEw5NSpJKxRXMhZzQBeaVSCqYSmrYSqqYSupYCumXykAunhBtHE7t3M/u3hDr2w4qGYyn10qpGAuqWUzsGs5rmk1q2Yxrmo1rWk0s3A7sm86r2s4sm05rGg0q2czr2s5vnlIuXNEsWs9unNGuXJFsGo8rGc4pWExoF4pm1chllEal1EamlMenlcioFokoFoin1sjmlcgmFMdlU8ZmFIcm1QenlYgnlQfnFIcnVMdnVMenlUfpV0nqmAqpVsloFYgnFQenFQeolslo14no2Apo2EsoF4po2MtpGMuoF0polwpqF4tqV4tpV0rolwqoFkon1cmm1MjmlQinVclnlgkoFoloFginlYgnVQdnlUfo1kmpFsoo1ompFsnq2IusGg0rmgzqmMvp2EtSnh6Mq/Znuf/e+D/e+D/e+D/e+D/e+D/e+D/e+D/e+D/e+D/e+D/e+D/e+D/e+D/e+D/Xc7yP73mIKvZBom0G1xtVzETk1MhqmEpq2EqqmErqWErp2AqALVzQK9tOrFvPbt5SLl3RbZ0Q7h2Rbh1RbNwP7JuPbVvPrRtO7RsO7BqOrBtPK9tPKZkNJ1aKJ5ZJ6hkM6hlNMB9Tr15SqpmN7BqO6piM6JZKZxVJJ5YJpxXIZxXH59YH55WHqNbJaphLatjLaVfKKFdJZpXIJZTHJRPGJ9ZI6NdJ6NaJZ5VIZxRHZ5SH6VaJqVdJ6lgKqpgKqheKKVbJaNbJqJaJJ5YIplVH5pXIZpXIplYIpNTHo1LGJVQHp1VI55TIZlOHZxVI6VeLK1oN6xnNqpkNKxnNqpnNadjL6dkLqZjLKhjLKVfKJtTHpxRHaNYJKdeKqZdKaZdKahfK6ZfK6JbKKNdKyWIojOv2aLq/37j/37j/37j/37j/37j/37j/37j/37j/37j/37j/37j/37j/37j/37j/37j/37j/37j/3PY/wmAqE0tFJJTI6tiKqxiK6lgKqdfKaRcJQC9fU2/fk7CgVHJiFe6eEi0ckK3dUS2dES0cUGqZTa1bz+0bDywaTmvaTqwbD6ycEO4dki4dUW4dETBfU7Bf0+8eUy6eEmjYTCYVCOYUSCdVCKaUiCeVySgWiOfWR+fWB+iWiOoYCqsYy+uZzKsZjCpYy2pZS6raDGtajOuaTOuaDOpYi2qYS2sYS+sYC6xZTKrYy6mXiimXCaqYCupYCynXiqmYCumYCubWCKXVR6aWCKYViGSUByUUB6cViSiWCajVyakWCeoYC6qYzGkXy2fWSihXCqnZTKqaDWqZzOpZjGnZC+oZS6fXCWbVB+nXCipXiqiWCSgVyOfViKhWCSmXSmqYi6oYy8niaQnqtan7f+D6f+D6f+D6f+D6f+D6f+D6f+D6f+D6f+D6f+D6f+D6f+D6f+D6f+D6f+D6f+D6f+D6f912v8bptlJKxWOUiatYyytYyuqYSmlXCSiWSEA1pds3p5zz5BjxoZYt3ZItnVFt3dGuXdFsG08r2s6qWIypV0tqWIysWs9rmo+tnVJunpOxoNVv3xNxYJU4Z9xzIxftndIpmU0oV4snlomn1kkn1kloVompl4no10jolwiqGApqWArqF8sqWIvqWMup2ErqGItpmErqGQvq2cxp2IuqWIvrGQxrmQysGU0r2Qypl0poFgipVwnolklo1onpF0qolwpoV0pnVoloWAqomApp2Quq2cyqmUyq2Mwplspplkoq18tq2Mwo10pnlgloVooqGEtp2Itn1ommlUhol0op2Esq2YvqWQtrGQurWMtpVolnFEcnFIdoFYipFklplwop14qpl8qSpiuCp3PvPD/huz/huz/huz/huz/huz/huz/huz/huz/huz/huz/huz/huz/huz/huz/huz/huz/huz/d9z/G6bZOyoaeUEZmlEdnlMbo1ggplsjplwjANKUbMmLYrV2Ta1uQrR0Rrh4SbNzQbZ2QrBuOqpmMqFaKJ1UJJxVJbBqPL57TcWFWcGDWLd1SLJuQMJ/Ut2ecc6QYsWIWKdoN6JhLqViLKhjLalkLqtkL65nL7BpL69oL69nMKtiLqZdLKNcKqJbJ6VeKahgLKhiLadiLaplMaJdKaBaKKFaKaRbKqlfLqddK6NbJqJaJKVdKKphLa1lM6pjMaZhL6RgLaNhLJ1bJpVSHJVRG5pWIZ1XI51TIaBUI6dZKKZaKKZeKqNdKKhfLKhfK6VbJ6JZJaJbJqFaJqpjL6ZfKqdeKqRbJaNaJKVbJKVbJKZcJqheKKhdKKNYI59UIKNYJKdeKk2ZsCiq2cHy/4vx/4vx/4vx/4vx/4vx/4vx/4vx/4vx/4vx/4vx/4vx/4vx/4vx/4vx/4vx/4vx/4vx/3ne/0W/5iw+PGw3E5JKGJtPGKBVHZ5SGp5SGgDIi2O3elGsbUOqaj67ek2zcUKqaTiycj6ycDysaTSrZjKpYTCxajq8d0jDgVK8fU+0d0mpZzirZzi1ckO2dEeucEGrbT2hYjCgXyylZC6pZi+nYy2pYy6uZjCybDOxajOwaDOuZTKtZTKrZDGnYSyqYy6pYCyqYy6lXyqlYCyfWSiaVCOdVyalXS2nXy+kXCqmXiioYCmnXyqoXyypYS+mXy2lXiyjXSuZVCKZVSGbViCZUx2aVB6YTxugVSOvYzGtYC6nWymkWieiWyelWiajVyOjWSSkWiWhVyKgVSGiVyOlWSWpXSmnWiarXymrYSmqYCipXyqnXSeiWCKgViCiVyKlWyWnXSdDnrkqq9nF9P+P9f+P9f+P9f+P9f+P9f+P9f+P9f+P9f+P9f+P9f+P9f+P9f+P9f+P9f+P9f+P9f+P9f984f9Iv+YnRUdkNRKTTRqiVx6iVx2hVh2iVhwAv4JXuHxOuHpLuXhJt3VEsW49rGo4rWw4rGo2rGk2rWg2rGY1sGs6rmo6qmg5pWY3oGIypGEwqWQxqWYzp2MxpGExo2EwpmQzpmQypGIvol8ro18qpmAsqWIvq2Uyp2EupV8tpV8to1woo10npV8oo1skpl0oqmEtpl8sqmIxqGExqWQyp2Ixol4sn1wpmFQfmFIan1gfpFwlolkknFMfmVAem1EfoVYlqV4uql8vplwopVwmoVkjoVcipFklo1gkpVklo1ckoVUjolglo1gjpFkio1cgoFQdnVIboFQdolUgqVklp1ckqVomqlwoqF4nqGApqmEtqGAsqGArp14pqF4nqF8mpFsiLKzZLKzZu/D8lPr/lPr/lPr/lPr/lPr/lPr/lPr/lPr/lPr/lPr/lPr/lPr/lPr/lPr/lPr/lPr/lPr/fuP/eNnyGlprXDAQkkwZoVYcn1UYnFMWm1IVANSWadWXZ9CRYMKBULl2RbNvPa5rOKppNqlnNKpmNKtmNKxlNatmNahkNKdkNKNiM6BfL6NfLatlMqlkMqhjMallNKhlNKZjMqNgLqJgLadjL6hjMKRfLaJcKqNeLJ9aKJxXJZ9bKKNcJ6NcJqNcJKRcJahfKqxjL6hgLKVdK6RdK55ZJ5lVJJpXJZRRIJNPG5lTHZ9ZI55XIZ1VH5xTH6BXJKVcKqpgLqxgL6tfLqpgLKlgKqhfKaNaJKJYJKJYJKNaJqJYJKBXI6FXJJ1THZlPF5VLE5ZME5xSGKFWHaFWHaZYIaZYI6haJaldJqthKahhKadfKK5mMK9nMKxkLKtiKadfJKJaH0S13zix3Kff8pj+/5j+/5j+/5j+/5j+/5j+/5j+/5j+/5j+/5j+/5j+/5j+/5j+/5j+/5j+/5j+/5j+/4Dl/33Z8hNqhFYuEI5MGaBVGp9UGJ1SFppREwDDhFTBg1G1dUKoZzSrZzSoZDCqZjKpaDWpZzSpZTOpYzGoYDCpYzKrZjWqZzaoZjatazqwazmwajerZjSnYjGoZTSnZTOlYjCdWiecWSSeWyWjXyypZDKpZjOkXy2gWymkXyykXimkXSejWiSgVx+hWCGiWSWgVyOfVyGdViGeWCSiXCilYC6mYTCmYTGiXSyiXSmhXCagWyaiWyerYzCwZzWvZjStZDKrYS+tYTCvZjKvZzGvZzGuZjC1bDi1bDivZjKyaTWwZzOnXiqlXCaoXyekXCOjWyKlXCOlWyGlXCKoXiSoXSWoXCWqXyeqYSioXyarZCqxajCuaC2qYymoYSalXSGjWyBeweZewear4PKe//+e//+e//+e//+e//+e//+e//+e//+e//+e//+e//+e//+e//+e//+e//+e//+e//+C5v+y8v8MepxPKxCNSxqjWB2iVhuhVRqiVxsApWUznl0qlVQgl1UgmVYhnVkkoFwnoV0qoV4sol4solwqn1gmpV0sqGExp2IwpGAvpGAvp2Evpl8tpl8upmEwp2IxpGEvl1QhlVIem1cin1wmqGMwqGQyp2UyqWUzq2Y0sGs4rmcyqGArp10mpVsjpFkko1onolklpV0npV4npmApqGMtqmUyq2U1qWM1q2Q2r2o4sW47rms2rGczqGEvpV0ro1spoVgmoFYlpFknqWAsrmYwtGw3tGw2sWg0rmUxrGMvsGcytm04uXA7t286s2s1rWUuq2QrqmEpp14koVgenFMZolgeolgfo1khpFojplwkqWEnqmMoqWMmp2Akp18jqGAlqGEnYcHmYcHmreDyrP//rP//rP//rP//rP//rP//rP//rP//rP//rP//rP//rP//rP//rP//rP//rP//rP//ieb/uPL/FJC3RycOh0gXnFAWnFAVpFcdrWEmAKNhLaJgK6NhLJ5bJZtWIZ1XIppVIZtXJJxYJp9ZJ6JbKaFaKKdfLaxlMqtkMq5nNatmNKpjMadgL6ZfLqplNK1oN6ZhL6ZhLqpmMa1qM65pMqlkMKZiMadkMqZjMKVhLqplMqtkL6hgKqpgKq5jLKtgK6phLqhfKqZeJ6ZgJqZiKKlkLaljL61nNqtlN6liNqtnN69sO69sOaxoNatmNK1mNKxjMalgLqheLKxgL61kMK5lMaphLaRbJ6ZdKalhK6tjLa1lL6hgKqZeJ6RbJ6hfK6tiLqNbJaNbJKZfJqZfJKVdI6lfJ6ZcJKddJ6hdKKdcJqddJKZdIqVeIKdfIadfI6lfJo1iOGXD5mjH6XbJ5uH6/9H8/8v9/8X+/7z//7r//7r//7r//7r//7r//7r//7r//7r//7r//7r//7r//7r//5Dm/73y/zez2UUmD4VJG6RaIKdaIaxfJq9iKQCoZTCkYSqkYSqlYiulYCumYCujXSmjXiyiXSuiXCqmXy2mXy2nXy2qYy+sZjGuaDOpYy6mXy2lXiyhWymjXiyjXiyeWSehXCimYSupYy2oYSqjXSmgWymeWSefWiidWSWbVyKdVyGjWyWqYSuvZC+uZC+rYjCmXSiiWiSmYCamYSekXiecViGXUSCZUiWgWi2lYTGoZTStajiwbTmybjqybDexaTa0azmzajixaDapYC2jWiaiWSWgVyOiWSSjWyWiWiSfVyGiWiSnYCiqYi2wZzWyaTaqYS2waDGzbDOzbDKyazKyaDCvZS2sYSyqXimpXSilWiKjWR6kWx+lXSGpXyWlWiJyYkhoxOaP5/w0ud8nqtY8sdl4yeaV1eyz4vLr+v/g/P/H///F///F///F///F///F///F///F///F///F//+V5v/D8v9Iudw7NSiCSR+nXSapXCOoWyKlWB8Ao18ppF8pq2YwsGw2rmo2rWg1qmQyqmUzqWIwqWMxqWMwpmArpV8qolwnnlgjnVcimVMdmVMemFEel1AellAemVQinlgmnlgkoVolpFwmpV0mo1smo1wqnlklm1Uhm1YhnFcim1Qfo1smq2Iur2Uxr2YzsGg2s2w3sWo1rmgxrGYvp2QtpmAsp2Iwq2U2smw+rms6rms5tXE+sGw4rWgzqGItpF0ppFwppFsqplwrqWAtq2IuqmEtq2MuqmIsp18ppV4mpV4mp2AoqWIprWQvr2QxrWIuq2Arq2IsqmAorGMrqWAoqmAorGIqp1wmp1wmp1wmqV0lqFwjpVkgpFkgpVoipVoieGhPoNvyofT/j/X/j/X/f+r5bd/yScjmOLzfHavWa8Ti7fz/1f//0///0///0///0///0///0///0///0///neb/yvL/dszmMENAd0QdoFgjpVgfplkgqVwjAKplL7VvObVvOrJtObFsOqtnNadiMapjMaVdK51WJJtUIpZQG5hTHpVQG5NOGJFMFpNOGJhSHZpUIJ5YJKFaKKVeLKVeLKFbJ6NdKKZeKalhK61jLqxiL6piLqZfKaljLbNtOKxlMKpiLa5lMrFoNrFqOLJtObRvOrNuObJtN7JtN7JuOLBsN7FuOrJvPbRwP7BsOqdjMaRfK6FcJ6RfKaljLaReKalhLrFoN7NpObRqOLFoNLBnM7VsOLhvOrRsNrBpMatkKqpjKadgJqZdJaheJ6JYIKNZIKZdI6RbIaVcIaZdIqdeI6ZdJKlgJq5jKq1iKaxgKKteJaZZIKdbIqleJaheJXxsUKbd8qj6/5b8/5b8/5b8/5b8/5b8/5b8/5b8/zC53HzL5vP9/+z+/+v+/+b//+P//+H//+H//+H//+H//6Pm/8/y/4nS6SdRWG0/GqBaJrJnLrZqMbltMwCrZjGtZzKoYi2gWymjXi2gXCufWimiWiiiWSegWCagWSajXSikYCunYy2gXSahXieiYCikXymlXyqkXimmYCuiWymeVyWgWSWkXSilXCilWyaoXSijVyOdUh6eVR+fWCKeVyKdVyKkXyusZjOuZzasZTSrZzKrZzKpZjGnZC+lYS2pZTCrZzKtajWoZjGkYS2jXiueWCWhWiapYy2rZS6uaDKvaTSyaze0azqyaDiwZzatZTKrYi6jWyajWyWkXCanYCinYCerZSqqZSmnXyOnXSKnXSGkWh2hWBmmXR+nXyCmXR+hWBqeVRecUxWeVRaiVxukWB6qXSSrXiSpXSSnXSKhWBt0ZUWq3vKs/f+Z//+Z//+Z//+Z//+Z//+Z//+Z//+P+fw6v98krNZAstlfv99+zOas3u+85fL4/v/4/v/0///A7P/e9f+75fIjYXByQh6jXyuzaTCwZiytYykAnVcioVsmpV0rp2EvqmQ0q2Y2rWc2tGw6t248rGQyrGYzr2k0qWQwp2QuqGYvqGYvpWMrpmEqo10noVslo1wnoFglnVUinlUhm1IdmE8ZmU4amU4ZnVEcnlMeoFYgoVgjpFwnqWMvrGc1qmUzqWQzqGIwqWQvqWQvqGQxq2c1r2w5q2g1pmMuoF8pnl0momEqqWUxq2YxpmArpF0npl8nqWMrrGQvqmMvq2MwrmQzqGAupFwpqGAsq2Qvr2kzrmkwrmgurGctq2YqqmUprmUnsmgprmQkqV8fpVwbpVsao1oZolgYoFYXoVgYoFcWo1wYrGIhrmMlr2MnrmInqV8jqWAirGMlmGw8dsnmzPv/mf//mf//mf//mf//mf//mf//nv//0vv/1/v/w/z/vfz/ker1fuXyTszmOr/fJ7PZGqbSQLLZcMXigMzmj9LpLXmMklYprGUvsWgurmUqqV8kAKNbJqdeKaheKahfLKhfLatjMKtiMK1kMK1kMahfLKtjMaxlM6pjMa1mNKtnM6VhLKRgK6ReKaJaJp1VIZ5VH55UH5tRGp1TG59UHJ9VHZ1THJxSGqNYIKZcJaddJ6xjMLBoNrJrOa5pN6llMqdkMKZhLKZdKqddK6ZdKaZeKqZgLKlkL6xnMqxpMrFuN7BvOK5sOK5pNrBpNK9lMa5kL7BkMLFmMK9mMK5mMbFpNK9lMLBlMbVqNrNpNLBnMbBnL65lLK9nLK1lKK1lJ7FnKbJnKK9kJrBmKKxkJalhIqtjJK5mJqxjJLFoKbRrKrNpJ7NpJ7BnKK5mJq5kJ7JpK7BnK7NoLbVpLlGNlOP0/KT//5n//5n//5n//5n//5n//9f8/5fW7FaZq1ilunrK5ojQ6bXi8sTo9dz8/9f8/8b9/7b+/1XF4jBpdkZ3fIZrTadfKqZdJKZeIqVdIJ5WGQCvZzGvZjCrYSypXiqgViKfViKcUh+eVSGhWSahWSekXSujWyqiWiqfWCafWSedWCabViOgWiihWSegWSWlXiipYSqsYyqvZi6sZCyoYCmqYiqsYyqwZy6rYiupYCusYzGpYjClXy2kYC2mYi2lYiumYCumXCmmWyimWiemXCepYCquZjCuaDGtZy+wbDSvazSuazW0bzq2bzm4bjmyZjGzZjCzZzCxZzCuZi6uZi+xZS6xZS+xZS+yaDCyaDGxaC+yaS6wZyqtZCatZCSsYiSvZCawZSe0ay21bS+3cDG6czS2bzCtZCaqYSOoXyCqYCCsYyKrYyOtZiapYiOtZiewZyuzaC2yZiycbUJevt/s/f/h/f/K/v/K/v+x///J/v/J6vVBb3eUVietZiyqYiSSZTd7a0xceG5TfnxJmKtcp7xdvt9OuNx6Y0egWCajVyKiVx+lWyGqYSaqYiWqYyUArmYwrWUvrGMtq2Esp10qpFwpp18sp18sqGEupF0rpF0rpV0tpFwsoFgnoVopoFoonVgmoV0roFoooVsoqGItrWcxsGo0tG44t3A6tHA6s245tG42t3A3sms0rmYyqWEvo1wqo1wqpGAspmItqWUuq2UvqWArq2AssGYxsGYwrmQtrGMrrGQrqmMpqmQpqWMqqmUsr2kwsWkwt241t2w0tmsztmsztGoxrmUsrmQrtmowtmgvsGUrsmgusmgvsGcsrGMnqF8hqWAirGQkrWMkqF4fqmAhrmUntGwtunIztGwtrGQmpVwfo1oco1obplwcqWAgqWEhrWUlsGkqsmsstWwvtmwxtGkvtGcuWoJ+W6CvSrDPccbigczmn9nsv+bySJ21hFInpVwkqmEkq2IkqmEkrGMnrWMorWMor2YssGcurWUtqWEpqV8nql4mrWEqs2gwuG40unE3unI3vXU5AKNbJaVeKKRdJ6phLa1kMqxlM65oNq5nNaxlM6hgL6ZeLq1lNa9nN69nN7NsOrRtO7FsOrVxPrBsOq9qOLFsOrJtOa5qNa5pNa5pNbBtOrRxPrRxOrVwOLdxO7dxPLRtObJrObZwPLVxO7JvOLRxObVuOLFoMq9lL6thKqlfJ6lgJ6ZdIqhfJKhgJKZeIaZfIaZfIalhJKtjJ6xlKK5mKbBnK7VrMLNpLrVqL7ptM7hrLbZpK7FlKLFmKa1jJ6xjJqlgIqxjJbNrK7ZuLrVsK7JoKLJoKLVrK7NqKrJpKrBnKa1kJqdeIqVcIKFZG6lhIbVtLbdvL7p0M7lyMrhxMbtyNLpxNLlwNLZrMbZoL7FlKq9lKqxjJphsPYR0VH9xUaBmMa1jJq5kKKxjJa9nKbFoKq9lKLFlKrJmK7FmK69lKrBnLLJpLrluM7xwNbxvN7htNbVqMrVqM7ZsNLlwNgCgWCKhWSOgWiSnYCunYC2mXy2oYzGuZzWwaTesZTOzbDq1bT23bz67dEK3cT6ybDewazWuaTSxbDiybTuvajixbDmwazixbDqzbjyxbjusaTWpZy+raC+raDCvaTOtZzGpYy+sZjCtZzGsZy+sZy6tZy6pXyemXSSpYSavZiuuZSmtZCerYiSnXR+jWhulWxuhWBeiWRigWBiiWhqlXh6mXyCrYySxZimzZimxYiawYSCwYyKxZia0aimxZyizaiu3by+6cjK9dTW+djS9dDS+dDS5by+3bS2zaiqzayu0ayy5cDK8cze/dTq+djm3cDGuZyisZSWwaiirZSOvaCi1bS2wZymwZymrYietYCesYCWrYSWvZim2bi+3cDG0bCy0bCy1bCyyaSuuZiivZymxaCqxaCqzaCu1aiyyZymuZCevZiixaCu1ay24bC+1aTCzaDC1aTO2azW0ajO2bTMAqWErq2UtrGYwrGYwqmQwrWYzp2EuqGAtq2MvqmIurWUxrmUyrmUzsGc0rmYxq2Mtp2ApqmMsr2cxsWo2rmYzrWYzsGg2s2s4sGg2q2QwqGItqWQrp2MopmIoq2UtqGMqoVsjolsjoFohol0ipmAlqGEmrGMorWUpqGAjpVwfoFYYpFkao1kaolgXplwaq2EerGEeqmEepl4bp2AesmsptG0qtWwrsWYmsWMlsmQksmQhtmoluW4quW8tvXMywno6wXk5uXExsmoqs2wqsWgnq2Ehplwco1kYqmAetGsruHAxuXAztm0xr2UrrWQpolodmFETpl8frWYltm8tuHAut28usmkrsmkrsmksr2Yqq2ImrmUptGwvtm4vs20tsW0stW4tt3EuuHEwunM0uHEytW4vtWwusWYorGEjql8hplwerGMlsWgqtWsrtWwttWwwuW42vHA7vXE8uW03tWsyAK5nMK5oL6xnL6xmMKtlL6xlMKtjL6piLKlhK6hgK6hfKqddKKhfKatiLK1kLapiKa1lK7ZsM7JoL6xjK6lgKqheKaddKaRZJKJXIadcJKphJ6liJqhjJrFrMLNtMrRuM7hxNrZvM65oK65nKqxlKKpjJqdeIKJaHKJZGqVcHa1kI7NpKLRqKK5kIbNqJ7NqJrJoJLFnI69mIq9nI7NrKK9nI7BnJLRpKLZpKbptK7xvLLVpJLJnI69mIrBnJalhIaNbG6NbG6dfH6tjIqxjI61kJLFoKLdvLLx0Mbx0MrdvLrVsLrVsL7lwNL51OrpyNrFpLLNrK7hwLr10MblxLrlwL7dtLrBmJ7ZsL7ZtMLxyNcB4O794Or12N715OLl1M7x3Nb95NrdxLrdwMLVuL7lxM7hvMbRqLLVrLbhuMLRrLb11N8B4Ob1zNbtyNblwNbtxOLhtNrVpM7VqMrZrMgCwaTGtZy6taC+sZi+pYiunXiirYi2uZi2uZi2waDCsZCupXyenXSWqYCemXCKpYCSoYCOrYiStZCixZy2tYyqlXCSkWiKlWiGjWR6mWx6pXx+qYSGpYiKrYiOoYSGrYyStZCWsZCSsZCWwaCmvaCmtZiauZSWtZSWwaSi4cS+5cS6zaSeqYR+pYR2sZCCwZyOvZyOwZyOuZSGuZCGtYyCxZiKxZyW5biu2aym0aieyZyKuZB+tZSCsZSGoYR+qYyKvZyezayuyaiq1bS25cTG8dDS8dDS+dzS/eDW8dTK4cS+6czO6czS+djm7cze5cDa+djm+dTa+dDK5biy1bCiwZiSuYyKuZCSzaCq5bjC6cDG6cjO4cDG1bS6xayurZiOrZSKmYB2pYx6rZCSuZyi5cTO9dDa+dTfAeDm+dji8dDa9dji9djm+djq+dTq9czjAdjy/dTy/dDu8cji+czkAs2ozsGkxr2gvq2Qrpl0lplwkrmQts2svtGwwvXQ5u3I4tGswtGsvsWgrrGMmq2MkrGQjq2QirWYksGgprWUosGgst24zt24ws2kpsmYjsGQfqV8apV0Ypl4apVwZpl0aqmEdsGYksWgnrmYlrmYlsmoptW0rtm8stW4rtW4rsmsorWYjsmsos2wps2wpsWonqWIfqV8dsWYksWUitWcks2UirmMfr2UhqmIeqGAcr2citW4ptW4rt3AuuHExvnc3wHk5wno6vnY2wXk5vnc3tm8wr2gpsmops2wptW4rtW4runM0v3g5vHc5unI3vnQ7v3Y7t20utmspsGUhrWIerWIesWUjs2gnvXAxu2wttmkprWEhqFwdpVsboFYWnFMRn1cUpVwZq2Mfs2sruHExvXU2vnU3vXQ2vXU2vHU2uHI0tnE1tHA0uXI4vXQ7vHM5vHM5vHM4vnM4vnI3vXA1ALJpM7BoMq9oL69mLaxjK61jK7FnLrFqLbNqLbFoK6xjJqpiJLBnKbFnKLNpKbFnJq5kI6xlIatlIaVfHaNcHahgIqlgIqphIa5kIa5kHq1iGaheFqZcFaheF6heGatgG6leGqleGqZdGqZdGqJZFqJaFqNcGKZfG6xlIbNsKLlyL7pzML12M711M7hwLbVtK7VuK7FqJ7RpJ7VpJ7BhH6xeG69jIKxiH61nI7FsJ7ZvK7lyLr13M754NcB5OcV+P8F4OsJ5Or92N710NLhwMbRtMLNsLbVuLbdwLrVvK7NtKa9qJ69qKKpmJ6lhJq9mLLBnLK5kJrRqJ7NoJLJlIbRnJLhsKrpvLrdqK7JjIrVmJLhqKrhpKrNmJ7FlJrpuLbtwLrpvLLpwLLlxMLx1Nb94OL12N7t0NbZvMLJsL7RuMrd0N7d0OLlyObtyOrhvN7dtM7RrL7dsMLltMLlrMACyazOzbDSzbDOzbDK3cDW5cji2bTK0ay2uZyerYySpYiGoYR+pYiCrZCGrYx+pYR6tYyGtZSSvZyWtZCGsYR+tYiGsYiGrYiGpYR2rZB2sZRuvZh2tYxyuZR+qYRukWxakWhemXBmsYh6vZSGtYx6vZSGwaSW0bSm4cS28dTG6czC2biq1bCi2ayi4bCm9ci6/djS/dzW8dDO+dDPBdTXCdze+dDO9dTTEfju3dDC2ciy8djC+dzO4cS60bS24bjC1ay24bi+4bi7AdTXGfT7CeTzAeDq8dDWzayuwaiewaCetZSWnYCCiXB2nYCOtZCi0ay67cjO+djS9dDG6cC66cS+9dDS7cjO5by++cjDDdzTIfDrIejrIejvHejvIfT3DeTjAdzbAdje+dje9dzjBejrBejq/eTm+dze4cjS3cjW0cTWxbTKqYiirYSiqYCeuYymvZCmwZCmyZiqzZisAsmswtG4ytm8zuXI1tG0wt3E0tm4xtWwttG0ttG4rsmwpr2olrWgjrGYhsWomuHAtunAuuG8wt20utmootGcktGcltmsquXAvs20ot3EqvncuvXQsvXMtwHgywng0vHMwt20ruW8tuG8ruW4qv3MtvXMtuHAsuXIut3AstW4qtm4qvXMvvHIuvXAtvnAtuGsounEvvXU0wHc4xn0+x30/w3k7uXAxt28ws2wrsGwotXEqr2oip2EcoVoXo1sbqV8gsWYntWort20tvHEwvHIzuW8yunEzuXEyuHAxunIxvXY1v3c3v3c3wno7w3o8x35Axn0/xXw9x4A/wns5wno5xHw8w3s8vnY3wHc3vXYyv3czv3Uyv3QyvXEyvXEyv3Q0vXM0vnU3wHk6v3g8wHo8v3g4v3g4unMyu3Q0vHY2uHM1tXA2unM6uW82uGwzum41um00tmovsmYrsGQpsGQpALhwMLRsLLRsKrNsKbpxMLlwLrpxMLdvLrt0MrZwLLVwK714M7l0L7VuKrFqJq9nJK5lI6tkI6xjI69kIq9iH65iILVqKrlxMLp0L7ZwKbhxKLRsJbRtKLhvK7txL7dvLrRsK7dtK7ZsKbRpJLdrJbdtJ7ZtKbBpJaliHrNrJ8F4NcJ5NbpvK7RnJLNlIrRnJLFoJrNrKrlvL7JnJ6xgIqtgIqtiIqhgIKNcG6JdGaRfGKRfGKtlILdvLb11NbpwMbRqKq9lJaxhIK5jIbBmJa9mKLJpK7lxMb93NsB4Nr53NLx0NLx1NL52Nr52N7xzNb11Nr52Nrx0NLt0M7x1Mr92NsJ6OsJ6OsJ5Obx1M7t0Mr10M8J4Nr1zM7txMblvL7pwMbtyNLpzNb12Obt0NrZvL6xlJaZfH65nJ7JrK7JrLbJrMLVsM7ZtNLJoLq5kKrJmLbVqLrVqLrZqL7FlKgCsZB+uZiGwZyKuZh+vZR6uZB6sYh2mXhujXBmjXBmlXhqpZB+pZB6lXhqgWRWhWBSiWhahWRmkXBuuYyGxZiKxZiOvZSWpYiCmYRynYRuqYhqjXRakXRmoYR6sZSKlXRyiWxmlXhuoXxutYh21aSOzZyK0aSe1aym0aii0aiiuZCKtYyGxZSOyZiSxZSOyZiSuZCKuZCKwZCStYCGrXh+rXyCrYSGmXRymXxyrZCGuaCK7dS7Ffzm7dDCzaSevZSSvZSS0aii4bCm7cCzAdTXCeTrAeDi7czK6cjC6cjC6czC8dTK+dzS+dza7czS8czW4bzG2bi+4cDCzayq6cC6/djS+dDS+dDS8dDS5cTG1bS2waCivZiaxZyewZiavZyewaCmyaSusYyWrZCWtZiewaSmvaCitZSWuZiavZietZCerYiitYyutYyqnXiSmXSOrYSevZiqxaCyrYiWqYSMAp18Yp18XqF8Wpl0Tp14To1sQoFcNoloVqF8cr2cjsGols20nsWslsGgjsGgirmUgr2UhrmYlrWQisWcksmcjsGcjsGclsGonsGsmsGoksWkhsWoktG0qs2wprWYlpFwcqGAfrGQhr2Yit2wnvnIsvXEsvnIwwHUzwHQyum8ts2knt2spvHAuvXEvvHAutmsotGonsWYksGQjvHAvwHQywXQzwnY1wHY0wng2v3YyunMut3Eqt3ErtG0pt24runAvw3k3xnw4xHk1w3gzvHIwt20tuG4uuG4stGsosGcksWglsmomsmkntWwqt24ut24wuG8xunIyvXQ0wXg3v3UzvnIwv3Qyv3MyunAvs2wtsGkqs2sss2srtW0ttW0tsmoqsmortGsts2ostW4vtm8wt28wt28wuG0vs2krr2QnsGQqtWkvtmsxsmkusWktsmkusGctrmUqpV0ho1seo1oeALNsJLBpIbJpILNqIbNqH7NrH7hvJbhwKsB4Mr53McR9N8R8NsJ7NcJ6NMd+OMl/Osd9OMF6N8F5NsJ4NcN4NMF3M711MrhyL7x1Mb52MMB3L8F5NMJ7N8N8OsF6OL12NMB4Nr52M792MrxyLcB0L8N2M8F1M8N3Ncd7Ob90MrhtK7ltK7hsKrltK8B0Msd7Ocd+OsJ4NLxwLbxwLbdqJ7JlI7NmI7VqJ7NpJbJoJLBpJK5oI7RtKb11Mb1zMbdtK7ZtKbdtKbhtKbdsKLJoJrNpKLdtLLdtK7ZtKbRrJ69mIrBnI7FoJLVrKL10M752N8J6O8R7PMF3N8V7Or5zMbpuLL9yML5xLr1yMLtyM7x0Nb52N793NsR8O8J6OrpyMrhwMblwMrxzNbt0NbdwMbNqLLNpK7ZrLbZrLbZpLbVoLbBjKqxgJqlgJKtjJ6pjJ6liJ6hhJqFZHqNaH6lfJAC5cyu3cSm3bye5cSi2biS2bSO4byW5cCm4bymxaSKwaCKwaCKyaiS2bSe0aiS2ayW2ayW3byq5cCy3bSi7cCq7cSy5cS23cC27cy+/di+9cyq4bii2byy8dTK7dDG2byu3byy4cCzAdzO/dDC+cS29by24bCq2aiizZyWqXhyqXhy1aCa6bSu+cjC/czG8cC6yaSWqYByhVhKfUw+iVRGqXRmsXxuxZCG2aye0aia2biq3cCywaCSrYh6uZCKzaia2bCi4bSm5biq2aye2aym9czK7cS+7cS+9dDC9dDC+dTHBeDTBeDS+dDLAdjW8dDO8czK7cTC3bSy9cjC6biy4aym6bCq3aSa6bSy8cjO5cDC1bSyzayqvaCWuZiWuZiauZSavZiivZimtZCatZCasYiSuYyWtYSSqXSCoWh6lWB6kVx6jWB6gVxqfWBmmXiKqYyisZCqsZCqwZiywZSwAqGEbpl4Yp14WqV8WrmUbt20juW8lt24ksGYer2YermYer2chrGQeqF4YrGEbsmYer2Mcr2Ufs2kis2ggs2gfuG4mvHMutW4qtm4ptWsjtmoguW0lvHItu3Ittm0pt24quG8ruXAsvHIuuW4qt2snt2sot20rtWsptmootGgluWwqvW8tuGontGgmsWUjrmMgqF8bplwXql8aqF0XqFsWr2IdsmUfs2Yhs2gjt20ptm0qsmoosWkmtWsquG4st20quG4quW4qtmsntmsnuG4runAwu3Ewv3UzxHs3yH87vnUxs2omsWckrmQir2UjsWgktGkmtWkns2cltGclsWQisWMhsmQitmgltWclsWUksWUksmglsmklrmYirGUir2cmrmUms2kss2gtrmUnrWQmrmQmrmIlrGAkplofplofrmIorGAnp14jq2MlrmUmrGIlqWAmqmAopVskpFojolcgAKtiGqxiGq1iGq1hGK1iGK5iGLRpH7NrHrFoHrFoH7BmHq1kHK1iHLFnILBlHbBkHKxgGK9kHLRpIbRpH7ZrH7NpILBnILRsJrZtJrFnHbVpHbdrIrdrJLNnIbJmIbRpJLRqJLRsJrZrJ65jH7JmIrhuKrpyL7lwLLNoJLFlIrttKrttKrdpJrhqJ7lsKbpvKrlxLLlxK7lwKbZsJLVpIrdrI7ZqIrdsJbhtKLdtKbhuLbhvL791NcB2NrxyMLpvLbNnJLJnI7JnI7VqJrpwLr91NcF3N750MrVsKbNpJq5kIaheHKddG6pgHrBmI7RoI7NlIbVnJLdpJ7VnJbBiILBiILFjIa1fHahaGK1fHK1gHaleGalgGq1lIK1mIqxkI6tjJKheIatfJKphI69lJ6xiJK1hJrJmK7drMLxvNbZqMLJoLrNqL7VrLa1iJK1jJqpgJqRaI6FXIp5UH5xPGwCvYxu0aB+0Zx6yZBuyZBqxYhexYxmuYxiuZRqxaB+2bCS7cCjAdS/Cdi/AdS2/cyrBdSy9cyq2ayG5bSK1ah2vZBmyaSC2bSW1ayO0aR63ah2xZBmuYhmvZBuvYhuwZR65byi5byq+cy++cy+/dDHAdzS9djK9dTG/dDC9cS26bCm4aSa6bCm6bCm2aCW4bSi0bCevZyG0bCS3bia6cCe6bybAdS3Adi+/dC++dDC9dDO9cjS+dDW5by+0aii3aymzZySwZSGxZSG3aie5bS20aSqpXx6nXRymXBqiWBWgVxSmXBqwZiS5by27byy8bym6bSm5bCm3aii2aCa0Zia2aCi4aSi0ZiS0ZiS5aia2aCStYButZBytZR6tZiGrYyGlXR6pYCKrXySrYSOoXR+oXCCsYCWsYCWvYyitYSirYSetZCqwZyyuYyWuYSKvZCexZy2wZi+tYi2uYi+yZTMAtWkftmofum0jum0it2ket2keuWsftWsgtmwitm0jrmMbr2Qbs2cdtWoftmofu24juGwftGgdtWoetWkctGkbuG0ium8ltGohuXAmvXInuGsfr2IYq2AWqF0UqFwVrGIbsGYet2slum8os2gisWYhr2UgqmMfqmIesGYjs2gltGclt2kotWgmrmAerF8csmcksGklsmsot28rvHItwngzyH84xnw2wngywXcxu3Itt3Att24uuG4utWsrtmwsvHAvtmoos2cktGkltWgkrmEgqF4cqF4bq2Eeq2Ifq2IgsGcltWwqtm0st20st20qt2wot2wpt2wptmsquW0tvnEzum4vuWwtwHIxwHMxvnAsuWwntGgjsmcgsWchsmgksmgltm0sunEytm0wt20xtGkttGgusmcstmowuW40uW40tWsysmgvs2kws2Yqs2YpsWUqsmgurWMrql8pq2ArsGQvALtuI7drH7puI7drH7ZqHrpuIbpvI7xyKLtxJ7ZrIa5jF69jF69hFa5iE7BjFK9jEq1hELBiFq9iFq5gFKxfE65hGLFmG6pgFaxiGLBlHa1jGqxiGK5kGrFnH7VqJLZrJbRqIbJmHKtgFaRZD6FVDaJXEaheGa5kILFmJLRpJ7htLbluLrVqKbRpJ8N4NsV8OsR9PMR8PL11Nb50M8F2NbpwLrJpJbRrJq9mIK9oILBpJbBnJK5kI7NpKbZrLbhsLLpuLbpuLLZrJ7hrJrVpJbRpJbZrJrRsJbZvKbhxLr10NLxzNbpxMbhvLbdtK7ZsK7NqKrBnJ7BoKLJoKrNqLLNoKrVqLLZpKrhrK7hsKrZsKbRqJrZsKLdrJ7lsKb1wLbtxLrhwL7dvMLduMLNpLrRqL7RqL7JoLbNpLq1iKatgJ65iKrBkLbNlK7JkKq9iKa9kKqxhKKpfJ6pfJ6xhJwCvYhmuYhiwYxq2ah+6biG5biC7cSS4byS1ah+1ah+vZBepXRCrXRCuYRKtYRKoXQ6qYBCuYBOuYBSvYRWwYhauYhauYhasYBWvYxmuYxmtYhixZhu0aR64bCO4bCW0aCCoXROgVAmmWg6rXhStXxexZB21aSS7bim8byu/cS6/cTC9cDDAdDK+cjC5bSu0aCavZSKoXx2rYB+sYB6tYB6tYB2zZyOyZyGxZx+xaCCxaSWzaii1ayqyaCiuZCSzZyi2aSm4bCq9ci7BdjG9ci66byq7cSu8dCy9dS+7czC8czO8cTO6bzC8cjG7cS+4biy2bSuzaiqxaSq2bS+1bC61aiyxZyeyZie3aiuzZie1aii4biy4bSu7bSu+by68bCu6bSy2bC2waCmuYyWpXiGqYCKpXiCqXyGrYCKsYCSvYyixZCuuYimtXyWsXSOtYCerXiWqXSWpXCSnWiKhVBsAsmYetWkgtGkfs2gcs2kcsGYYsGcZrmYYpl4Qq2IUr2UXsWYYsmYYr2MVq18Rql8RrGETs2UZtmgcumwgtWcbsWMXsWMXtWkdtmoft2sfsWUZqV0RqV4SqFsSqVwVsGMbsGQZr2MWr2QXr2IXr2AYsGAatGUft2gktWUismMgtGUjr2Afr2Efq14cpVcVql4brWIerGEdqVsZp1kXrF4bsGIetGYhrmIcql4XqmAYq2Ier2cksmoosWcnuW8vwHY2xns6yH06yH06yH05wnczu3AsunAqu3MrvHQuunEuvHExv3I0wHQ1vXExuGsqt2wpt20ruG4uuXAwtW0usWgpsmkqsmgptmwruGwrsGIjsGMktmkqtWcot2gpuWgpt2Qmr18hplkboVYYolcYoVcWplwbpFoZpFkYpVsaqF4eql8hrGAkrGAlqVwhqFkfq1wjplceplcfpVYepFUdn08YALpuJ7RoIbJmHbJnHbJoG65kFqphE61lF65mGLBnGbRqHLVqHLVqHLVqHbVqHrVqHbNoG7FjGbBiGLFjGKtdEadZDahaDqZYDKZZDaZZDKJVCKJXCahcEK1gF7FjHLRnH7VpHrpuIbhsHrVoHLhpILpqI7ZmH69eGqpZFaRVEaJUEahaGLRmI7drKLpuKrtwLLpvK7htKLVoJbdpJrlrKLZoJK9hHa1fHLBkH7ZrJrpxLb53NMJ6OMd9PcV7O8F3N8F2Nr9zMbhtKq9kIK1iHq9kILFnIbBoILFpI7FnJLRpKrNmKbBiJbBiI69iIKxhHq1jIaxiIaRbG6FZGZ5WFqZeHa9nJbBnJbFmJLRlJK9jIrFlJLRnJrFhIa9dHalWFqJREqBRE6BTFKJWF6dbGqZaGadbGaZbGaZbGatfH6peIKtfIa1gJK1fJalbIqdZIKZYH6ZYIKdZIaNVHqVWIACyZCCuYRuyZh61aiC2ayCzaRuxaBqzax23byG4byG2bB64bR+3bB+3bB+vZBitYhesYRatYBesXRSqXBKqXBGpXBGmWQ6lVwyqXBCtXxOwZBe7byK9cie9cCe9byi5ayO2ah+4ax+4ah61aB22aCC2ZyCyZB2wYRyuXhqxYx6zZiK3aie9cy++dDC4byu5cC29dDDDeDbHeznGejjDdzXAczHEeDbGeTjFejjHfTvBeTa8dTK3by2zaiq0aiqvZSWvZCSvYyOqXhymWxioXRqsYR2pXhmlXBarYh2sYyGuYySuYSSvXyOvYCGvYiCvZCKsYiCrYR+rYiGrYyOqYiGtZSOpYR+oYB2pXhypWxmkWBamWhikVxWgUQ+iUA+kUhCiUhCjVBOoWhqpXB2rXh+uYiGvYyKwYyKsYB+vYiOrXiGrXSCuYCWuYiiqXyaoXiSqYCamWiGmWiKpXiaxZC4Aum0puWwntWkhsGQbrmQZrmMXrGMWqmMVrGQWrmUXs2kcsmcbr2QYrWIWq2AVq2EXs2ogtWghsWQcs2YdsWUcsWQbsWQcsGQasWQasWUatWofuW4ium8ktmkhs2YftmkiuGwjtmoetWkes2YdsWQdtmkjvnItw3cyxXk0wHYwv3UwvnUxvXYyt28ssmsou3Uzv3c3wHc3wnk5xXs7wXc3vnQ0wHY2v3U2vHM1tWwtrmYkq2QhrmclsWkpmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AALNnIrJnIrFmIK9lHa9lHLNqILRrILNsILFpHLNrHbRsH7VqILNoHrRpH7JnHrRqIbZsJLVoIrNlILRnIbJmHrNnH7VpIbVpIrFlHa9lHapgF6RaEaddFKRYEqldGK1gHK9jHLZqIbxxJ71wKL5yLMJ1McR6NcJ5M8N6NcB5M794MsJ7N8N9OcB6NsR+PMiBQL53OLx1NbtzNbpxMbhwMLhwMLZuL7NsLbBpK61mKKxkI7BpJrVuK7JrKJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAAC1aiO5bie6byq8cSy9cyu+dCy6cSe5cSezayCuZhutZBmxZR2zZx61aiG1ayO4bie2bSa7birBcy+8byu2aiW1aiW2aya4bim4bym2bimwZyKrYhywZyG0aya2aym6bizDeDTIfDXFezPDdzLCdjO/dDHEezbCejXCeTXDezfCezfCezfDfDnEfTu/eDe/dze7cjS+dji7czS5cTG3by64cS61bi21bi+6czS9eDnDfDvBeje+dzS4cS+YTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgAAt20ku3Epu3ArvXItvHIsu3EquXAotGwkr2Ydq2EYq2EYrWIar2MbsWYftWwktWwmt28ouW4ptmomtGklunAsvHIvwHc0w3s4xH05xH06wns5v3k0w3s3xn46w3o5x349xnw5w3o1vHIst20pvnMxwng2xXw5wnk1w3o2w3o2wHg0wHc0uXEutGwru3Iyv3Y3vnU2vXM0u3Iyv3Y1vXUyuXIvuXIutW4ttW8uuHIxtW8su3QxvXYzunMxmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AALdtJbdtJrRqJLluKb1yLbtxLLZtJ7FpIq1lH6RcFaNaE6pfGbBlILtwK7VrJbJqJLhwK7lvKrdsKLtwLLtyLrtyL8F5NsJ7OcB5OMF7OsF9O796N7hyL7hxMLtzNMB3ObtzNL11NLxyML10MsN5OcR6OcF4NsF4Nb94NbdwLblwLcF3NcJ3NrtxMb1zNL11NbtyMb50NL91NcB2NcF3NbxzMLpyLrdwLbx0NLt0NLt1M712M753Nb11M5hOAJhOAJhOAJhOAP///////////////5hOAJhOAP///////////5hOAJhOAP///5hOAJhOAJhOAP///5hOAJhOAP///////5hOAP///5hOAJhOAJhOAJhOAP///////////5hOAJhOAP///5hOAJhOAJhOAJhOAJhOAJhOAP///////////////5hOAJhOAP///////////5hOAJhOAP///5hOAAC8dCy4cCi2bia4bym1bSe4byq3byu5cy66dTC2cCu1byq4cCu9dTHCeTW9dDC7ci68cy+1aya1aia4biq6cS26cS26ci+5ci+7dTPAezrBfTy9eTe4czG7dTXEfD7GfkPEe0DFfEHEez7DejzEfD3FfDzEezvCezq+ejm5dDO9dDPDdzjHeTrEeTnFfT2/eDa8dTG6cC+3bC24bi++dDS7cTC8czC9dDO9dDa9dDa6czO6cjK2bi62bi6YTgCYTgCYTgD///+YTgCYTgCYTgCYTgCYTgD///+YTgCYTgCYTgD///+YTgD///+YTgCYTgCYTgD///+YTgD///+YTgCYTgCYTgD///+YTgCYTgCYTgD///+YTgCYTgCYTgD///+YTgD///+YTgCYTgCYTgCYTgCYTgD///+YTgCYTgCYTgCYTgCYTgD///+YTgCYTgCYTgD///+YTgD///+YTgAAwHcvu3EpuW4nt20ns2kluW8qvXQwu3Uwu3YxvHcyvngzu3QwvHUxvHQwvnUxvnUxvnUxvHIuwHYywnk1v3czvnYzv3g1v3g2wXo5xX8+xYBAwn08xH09xn9Ax4BBx39Cw3w/xHxAxn1Bx35Axn0/x34/yH4+xX8/wH08unU0u3Mzv3Q0wXM0wHQ1u3MzunMwt3AstWsps2kptWsruG4us2kormYjr2clrWUlrGUmqWIiq2QksGgotGwsmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4A////mE4A////mE4AmE4AmE4A////mE4A////mE4AmE4AmE4A////mE4AmE4AmE4A////mE4AmE4AmE4A////mE4A////mE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4A////mE4AALNoH7JnILZsJbtwK8B1McN4NMN6Nr12M7VvK7p0MLVvK7hxLr12Mrt0ML10McN5NsV8OcJ5NcJ6NsN7OMF6NsB5NsJ7OMR9PMiBQceAQMR+PsF6OsF6OsR9PsR8PcR8PcN7PMF5O8J5PL10N7ZtML50N8Z+P8J7PL57O714OMB4OMB1NcB0Nb91Nbx0M712M753Mr1zMLxyMb1zMrdtK7ZuK7dwLLRuKrFrKbBqKbVuLrhwMLZuLrNrK5hOAJhOAP///5hOAJhOAJhOAJhOAJhOAJhOAP///5hOAJhOAJhOAP///5hOAP///5hOAJhOAJhOAP///5hOAP///5hOAJhOAJhOAP///5hOAJhOAJhOAP///5hOAJhOAJhOAP///5hOAP///5hOAJhOAJhOAJhOAP///5hOAJhOAJhOAJhOAJhOAJhOAP///////////////////5hOAP///5hOAAC6bye8cSq9ci2/dTHBdjK8ci61bCi2byy4ci+9dzS8djO9djO+dzS/eDXCeTfEejjFeznBeTXBeja/eDS6czC6czC8dTK+dzW/eDe8dTW8dDS/dzi/eDnAeDm+dja+djbCejnCejrCeTvAdzq9czjEfD/HgEHDfT7AezzBezvEfT3DeTnCdzjAdTXBeDa6ci+6cS23bSu3bS22bCy4bi23byy4ci65cy+5dDK3cjK7dDW4cDGxaSmrYyOYTgCYTgD///+YTgCYTgCYTgCYTgCYTgCYTgD///+YTgCYTgCYTgD///+YTgD///+YTgCYTgCYTgD///+YTgD///+YTgCYTgCYTgD///////+YTgCYTgD///+YTgCYTgCYTgD///+YTgD///+YTgCYTgCYTgCYTgD///+YTgCYTgCYTgCYTgCYTgCYTgD///+YTgCYTgCYTgD///+YTgD///+YTgAAv3Yvw3k0v3cxvnYyv3cyvHUwvXYywHo3wnw5wHk2wHk2wHg1v3g1v3c0wXk2u3EvuG4stm8rtW8rtm8rtG0qt3AtuXIvu3QxvHUyvHMzvnY2wHc4wXg6vHQ0t3Auu3QxvHUyuXEvvXQ1wHg6v3U7wHg7wHk6vnk6vHY3uXMzu3Q0unIxt24ttm0rsmgmsGYksGYksGYmqV8gql4hsWcotGwqsWsns24rtXEvs28vuHEyuHAytm0uuXExmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4AmE4A////////////mE4AmE4A////////////////mE4AmE4A////////////mE4A////mE4A////mE4AmE4A////////////mE4AmE4A////mE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4AmE4A////////////mE4AmE4A////////AL12MMF7Nb12Mr13M8B7Nbt2ML54M8F6N8J7OMF6N7tzMLxyML10Mr91M8F3NbxyMLhuLLlxLbdwLLdwLLdwLLhxLr53NMJ7OMB5Nr50M710Mr50NcJ3OL1zMrtyL711MLxzL7duK7pvL7ZrLbBlKLJpLLdwMbdwMLZvL7lxMblxMbVtLLVtK7tyMLluLLVqKLJoKLZrLbluMb1xNsF2Ob10NbpzMLx2NLx4OLhzNbdvMbVtLbdvL7txMZhOAJhOAJhOAP///5hOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAP///5hOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAP///5hOAJhOAJhOAJhOAJhOAP///5hOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAAC/eTS7dDC+dzPAeTTEfTjFgDnCfDXBeDW+dDK4biy3bCq7by2+cjC/czG9cjC8cS+6by27cS68cy+5cCy3byu3biq3byu6cS26cS28cy+9dDC9ci/AdDK/dTHBdzPDeDPCeTXBeDS8ci+0aimzaSm0ayu4cjC7czG5by67cC+5cC65ci+8dTK6cS+5biy4bSu3bS27bzG/cja9bzS5bTC4bi+5cS+9dzW6czSzay2xaCqsYyOtYiOqXR6YTgCYTgCYTgCYTgD///////////////+YTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgD///+YTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgD///+YTgCYTgCYTgCYTgCYTgCYTgD///////////////+YTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgAAuXEtuXAtwnk1v3YxunErunIqvHMrvHEtv3IvvnEuum0rum0rum0qu24suWwqum0qum4rum8ru3Ett20puG4pt20puW8qu3EtvHItvXMvu3ItuW8rvHErum8qvHEtv3Qvv3UxvHIuu3Etu3Iuu3IuunItt28rs2cksGMgtmkmtmsosmonrmckqWAdqFwaql0bq2Efr2IjsmQnsGMmsmUnsWYlrWQhrWQhpV0coVgZoFYWnFEQmU0NnU8PmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AALtxLrpvLLpvK7tvKrtvKLtvJrpuJrhsJ7hqJ7dpJrJkIbZoJbZoJbdpJrVnJLZoJbZpJbptKbpvKrdsJ7luKbdsJ7htKLluKbdsJrZrJbRrJLFmHrBkHK1iG7BlILJnI7NoJLJnI7RqJbFpI7JqI7dvKbRsJrJlILRlIbZnJLJnI6tjH6tlIrFoJrFmJLFkIq1jH69jIbNmJ7NmJq5iIKxgHKZeGKJZE6RcF6ZdGqZbGaRXFaVYFqZYFphOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAAC2aie3aSe5bCi8byq3aSO0Zx60Zx+yZSC1ZySzZiK1aCW4bCi6biu3aye3aiW3aia2aSW3aiW1aCO1aCO4ayazaCOuYx6vZR+xZh+wZh6sYhqrYBetYhiuYhqyZiCxZSCxZiK0aSW0aSSzaSO1bia4cCmyaSGuYRquXxqpWxamWxapXxutZyS0aymzZyWxZCKuYx6uYx+tYh+vYyCrYBynXReqYRm0aiKxaSKvZiGyZyO3aie5bCq7bi2YTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgAAtWomtmomtWomtmolsmYfs2cfsGQcrGEcsGUht2wouHAqtm4otG0mt28ouW8ouW4nuG0muGwluGojtmkit2oluW0ou3Arum4pt2sluW0luGwkunAnv3UtuG0ltWoit2sku24pu28rtWsltG0mt3Ert3Aqt20ot2wntmsms2oksWgjr2chs2omsmglrmEfsmQitGgkt2wot20puG4qtWwot28qvXQvunEsuW8quG4qvHMwvHIxuG4utmwsmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AALtwLLtwLLluKrluKbtxKr91Lb1zK8B1ML1zLrlxK7hwKq9pI69pIbRtJbhwKLlwKLVrI7RoILVpIbVpIrhrJrpvKrdsKLdrJrZpJLhrJblrJbhtJrlxKbdtJbdrI7tuJ7lsJ7VqJbRrJbNtJ7NuKLdwKrtwLb10MLxzL753Mr94NMB3M8N5NsB1Mr1wML5wLsJ1MsJ2M75zMbtxL7tyMbxzM7txMLZsKrdtK7htK7ZtLLRsLLZuLrhwMJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAAC/dTHBdzO/dTG+dC+9cyy9dCy+dS29cy26cSu7cy24cSq1byixbCOzbCO0bCS3bia4bye4bSS3bCS2aiO4bSi7cCu4bSm3aye3aye5aye3aSS0aCOzaSKuZB2xZR6zZiCvYx6yZyK2bii0biiybSi3byy5biy1aymtYyGtZCGtZSGsYyCxZya6bi68bzDCczXDdjW/cjK/czS6bjG0aSy3bTC4bTC5bTCzaCqwZCarYiStZSWwZyi0bCyYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgD///+YTgCYTgCYTgCYTgD///+YTgCYTgCYTgD///+YTgCYTgCYTgD///+YTgD///+YTgCYTgCYTgCYTgD///////////////+YTgCYTgCYTgCYTgD///+YTgCYTgCYTgCYTgD///+YTgD///+YTgCYTgCYTgD///+YTgCYTgD///////+YTgD///+YTgAAvHMvu3Iuu3Iut28ps2sjtGwktW0lsmsitG0ksmoisGkgrmggqWMbsmsjuXEpuXEpt28nuXEnuG8muG4ntmwnt2wot2woum8rum8ru20qv3Atv3MvunArum8qum8qvXEsum4pwXYyvXUvuHErtW8rtm4stWsqs2kor2UksmgmtGonuW8tunAvum4vvnEzvXAyuWwutWgqsWQoq14kql0ktmowvnE4uWwytWkusmYrrmQosWgrtGsuuG8xmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4A////mE4AmE4AmE4A////mE4AmE4AmE4A////mE4A////mE4AmE4AmE4A////mE4AmE4AmE4A////mE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4A////mE4A////mE4AmE4AmE4A////mE4A////mE4AmE4AmE4A////mE4AALVsKLlwLLhvK7ZuKLBoIbNrI7NrI65nHrJrIbJrIrBoIK5mHrRsJrpyLLlxK7ZuKLNrI7NsI7BoH7NrI7FpI7RrJ7htKrxwLr5yML5wLrttKrluKrhuKrxxLL1yLcB1ML90L7ZrJ69mIq1mIaliHq5lI7BmJrNpJ7FnJa9mIq9mIrJpJrdsKbdrKrlsLbdqK7ZpK7ZpK7JkKLFkKbVoL7VoL7RnLrVoL7dqMbdqMbdtM7ZuMrhvM7lwMphOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAP///////////////////////5hOAJhOAP///5hOAP///5hOAJhOAP///5hOAP///5hOAJhOAJhOAP///5hOAJhOAJhOAP///5hOAJhOAJhOAJhOAP///////////////////////5hOAP///5hOAJhOAJhOAP///5hOAP///5hOAJhOAJhOAP///5hOAACyaSWyaSWyaSWxaSSzayS2bia3bya2bySzbCGuZx6nXxeoYBqtZR+sZB6pYRuzayS3bye7dCu3cCe4cCi5cSu5byq9cS+9cS+6biy8by27by25byu4biq5biq4bSm2aye1aiWxZyKvZiKwZiSuZiSxaSazaiazaiasYx+kXBeoXxqrYButYh6vZCCzZySxZSOwYyKvYiOvYiSxYye5azC2ai+0aC23azC0aC25bTK7cTe7cTa3bjKzai2YTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgD///+YTgCYTgD///+YTgCYTgCYTgD///+YTgD///+YTgCYTgD///+YTgD///+YTgCYTgCYTgCYTgD///////////////+YTgCYTgCYTgCYTgCYTgD///+YTgCYTgD///+YTgCYTgD///+YTgCYTgCYTgD///+YTgD///+YTgCYTgCYTgD///+YTgAAt24quXAstWworGQfqWEaqGAYqmEZp18Vo1oRoFcPp14Ytm0ovHEtuXArv3UvvnQuvXQsvnYsuXAntmwlu3ErvHEsu24ruW0quW4ruW4rum4rtmsptGsovHIvunAss2kksmgjtWsns2ontWsqunEwuHAtuHAstm4ptW0nvXQtvHMsuW4ouG0muW4pt20osmgjsWYjsWUisGMjtmkqum0wtmots2grsmYqrmMmsGUpsWcttGsvtm0xvXM3mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4A////mE4AmE4A////mE4AmE4AmE4A////mE4A////mE4A////////mE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4A////mE4AmE4A////mE4AmE4A////mE4AmE4AmE4A////mE4A////mE4AmE4AmE4A////mE4AALduKrRqJq9mIq9mIapiG6lhGaxjGrFoHrZsJLtvKr5yLsJ0McR2M8J1Mb9zL75yLblvJ7ZtI7NpILhtJrxvK7ttKbpsKbhrJ7htKbhtKLdtKLZrKbNpJ7VrKbJpJbFnIrJoJK9mIrJoJrZsLLlvL7lwL7VuKrVsJ7RsJrdtKLhuJ7dsJbZrJLpwKrlvKrRrJ7FoJLVqJrhsKrtuLr1wMrxvMbhsLrdsLrdtL7NqLLRqL7dtMrdtMbpvM5hOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAP///5hOAJhOAP///5hOAJhOAP///5hOAJhOAJhOAP///5hOAP///5hOAP///5hOAP///5hOAJhOAP///////////5hOAJhOAJhOAJhOAJhOAJhOAP///5hOAJhOAP///5hOAJhOAP///////////////5hOAJhOAP///////////5hOAP///5hOAAC5biq3bCi5biq6byu4bSa8ciq7cSm5bye6bSi+cCy5aiizYyKuXx2qXBmwYh6xZB+vZR2xZh62aSK4bCW7bim5aya3aSW1ZyO0ZyK1aiW2bii0aieyaCeyaCa0aii3biq2bSm0aye0aii0aiqyZyiyaCmxaie0aye1bCi1aya4bSi4bSizaCOwaCKvZiKxaCS0aye5cC26cC26biy3aiu2aCu3ay62ay20aiyzai22ajC1aS+xZSqxZCmYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgD///////+YTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgD///////+YTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgD///+YTgCYTgCYTgCYTgCYTgAAt2wotGkltGklt2woum8pvHEqu3Aqum4oumwpumspuGgotGQksGAfs2QitGcis2chsmcetmoivW8puWwmuGoltWcismQgsGMerWEbsGcgs2sjr2Yiq2Egq2Efsmgms2omsGYisWcjr2QirWEhr2IksGQmsWgnt20st24suG4qvHEtu3Arum8rtWomsmcltGootm0qtmwqt2srtWgpsWQmr2ImsGQosmYqs2gstGsvt2wwtGgutWkstWgrmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4A////mE4AALRpJ7ZrKLhtKblvK7txLr1zMLlvLrhvK7puK7tuLL9xL8BxMLxtK7psKbtvKrdtJrVrIrZtJrVqJrRpJbBjH69iHbBiHa5hGrFnHrdvJLVvJLRsJbFnI7JnI7VpJrdqJ7ZoJbVoJbdpKLVnJ7ZmJ7prLLptLrtvL7twL7pvLbdsKLVqJrJnI69kILRpJbZrJ7VqKbNpJ7NoJ7BlJK1iIqthIq1jJbJoKrZsL7hvMrZtMbZsMLlvMrhtLphOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAJhOAAC5bSvAdTG/dC+8cy6+dDG2bSysZCSoXxytYyGxZSOxZCKwYiCyZCGwYx+vZB6vZR2tZRypYh2iWRalWxiqXxusXxqvYhy0ZiC3ayO0bCStZh6vZiCwZSGwZB+1aCS6bCm5aie3ZyW4ZyW3Zya4aCe4aSi2Zye1ZiayZSOtYR6qXxyqXxutYh6xZCC1aCO3aye4bSu5biy5biyzaCawZyWzaim2bS2zaiqtZCStZCWqYyakWx6oYCGtZSWYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgCYTgAAuG0pum8quG4mt20ltGskrWUhp18drGIesWUisWUir2MhsmQis2Uis2Yhs2chtGois2ohs2wmuHAruXArtWomt2onuWsoumwpum0rsmYkqV8cqmAcr2MetGcht2kktWYismIesmEetGMgt2cmtmYlsmMhsGIgr2EfqFsZqFwZql8arGEcsGUhtWkkuGsmuWwntmsotWkntWgmtGkmt20runAttGoos2kosmcnrmQksWgptWwus2ortm4umE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AALJnI7JnI7FnILRqIrJpIq5mIbBmJLVqJrVnJLJkIbFjIbRmI7lrKLtuKb9zLbtxKbZtJLZuKLlyLLduKbdrJ7psKrpsKrhrKbFkJa5hIqxhIa5iHrFlHbRoILVnIbRjH7RjH7RjH7VkIbZlIrJjILFiH7FjIbBiH65iHq1hHqxhHLFmIbVqJbBjHrFkH7RnIrNlIrVnJLVnJLdrJ7ZrJ7dsKLhsKrVpJ7drKbpvLb52Nbx0NLdvL7lxMbpwMLhuLrZsLLNpKrhvMbRsLrNnLbJmLLNnLbNqLrJqLrFqLLJqK7VsLrdvL7ZtLrVtLrNsLbNqLLJqLLVqLrhsMbZqL7RmK7dqL7ZqL7RpK69oJ7NrKrRqLbptM7lqMbtsMr1uNLptMbluL7huLrtxMbpxM7ZtMLpxNrtxN710Or51O7ZuMrdwMrlxM7pwNbpwNrdtM7xvNrtuNLlsM7dqMblsMwCxZiK0aSS3bSa3bSa1ayW0aia4bCq9by24aie1ZyS1ZyS0ZiO4aia2aSS1aSO2ayO3bCS1bCayaiSwZyKyZiO1aSa3aii2aietYR+rXx2tYCCxZCC0aCC0Zx+0ZiC1ZSC0Yx+1ZCC1ZCCyYR2yYyC0ZSKzZSK0aCS0aSWyZyO3bCe2ayawZSCsYRyuYh2xZB+yZSGyZSCxZCCvYh6rXRqzZSK5aym6bSrBdDG9cC21bCqwaSeuZiSqYB+rYSCuZCSzaiq0bCy3by+4cDK2azC4ajC8cDW8cTa3bjG3bjC4cDG1bS2vZyepYSGoYCCrYyOuZiexaSmzaSuzaCu1aS20ZyuzZSqyZCmwZSayayiwaSexZym3azC2aTG3ajG4azK+cja8cjO/dTS9dDS3bi+4bjG5bzS5bzS3bTO3bTO2bTK2bjKzay6yaC60aTG0aDC7bjW+cTi7bjW5bDO7bjUAt2sru28su3Ast2wotGklum4ru20stWYlsmQhtWYjtmgltWgktGcjsWQfr2Idr2Icr2MdsWYisGcisWgksGYisWYjsWckrWMerWMdr2UesWcftWkhtmois2UetGYft2YitWQgtmUhtmUhtGQhs2QhtGUis2UismcjsmcjtWomtGols2okt2wns2gjtGkkt2oluGwlt2sls2Uhs2UitGYkvnAtwHIvvnAtu20qtWglsmgmsGclr2YksmgntWsrunAwu3Iyu3MzunIyu3Q0um8zuWwxtGgssmcqsmgqrmUnrGQlqWEhpV0dpl0drGQirmYlsmoqtW0ttGssuG0vt2suuGsvuGovs2UquG0vvHQwuXIwtmwuuGwxvG82vXA4vnE4vHA1t2wutmwrr2UlrGAir2QnsmcqtWktuGwyvHE2v3M5tGovsWYrsmgus2kwtWoxu241vG82t2oxt2oxtWkvALlsLrlsLLZrKLNoJbVpJrVoJ7ZnJ7FhILJiILdoJbttKrhrKLJmIbJlILJmIbBjHrBjHrRoJLNpJbJpJbFoJK9mIqtjHqZdF6ddFKlfFKxiFa9kGrNmHrVoIbNlH7JiHrNjHrNjH7RkILVmI7BhHq9hHrBiH65jH61iHaxiHahfGqpiHK9kH7FmIbRoI7hsJrltJrpuKLptKblsKrtuLb5wL71vLbttKrhqJ7psKbpvLbluLbtwML1yMr1yMrtwMblvMLhvMLVtLbNsLLNoK69hJqpdIa1iJLBmKK5mJq1lJa5lJa5lJbVrKrtyMLlxL7lwMLpyMrpxMrxxM7tvMrpsMb1vNLxuM7tuMLlxL7hxL7ZsLbVpLrZpMLdqMLJlK7RoLLJnKa9lJbJmJ7ZpK7ptL7ptMLlrMLZqLrZpLrhsMbltMr5yN75zOLtxNrpuNLdrMbZqMLhrMrlsMrhrMQCxYyWxZCWyZiSwZCG1aCWzZSOzZCS0ZCO0ZSK1ZiO1aCSwZSCwZSCzaSS2bCe2aya1aiW2ayeyZyOwZSGvZiKuZSGuZSGsZB6xZx2yaBu2bB+5biS3ayS1aCGxZB60ZiG6bCe6aye3aCW1ZiOuYB6wYyCwZCCqXxuoXRmqYByqYR2wZyO2aye4bSi6byq5bim3bCe4bSq6byy8cC+6bS65bC25ayu6bCy7bSu8biu9cS+8by+7bi+7bi+6bC64ay22ay22ay20ayy1bS21ayy0aCq1aSuzaCqwZiaxaCi1bS23bS21aiu6cDC9cjO5by+5by+1bCyyaCqxZigIAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd67bzQAr2EirmEhrGAerF8brWAcrV8crl4dsGAfsmMhs2YitGcjtGoktGsluXArt24ptGkktmsntmols2cis2klsmklsmonsWomsGokuG8ouW0lt2sitWois2citGcis2Yhs2UhtmckvG0qumsptmgmsmUjsWUis2gktGkltWsnt24quXAsu3Iuu3Iuum8ruW4quG0ptm0pum8tvHIxvXIyvHEzvHAzt2osum0uvXExuGwqu20ruWsrt2gqtWUotGQns2QpsmUpsGUnrGMlr2YosWcotGgptmssuW8vuW8vt24uuW8vuG4uuGwtum0uvG8wtmwttGkrs2gqrWQmr2UoCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeuGwvAK9hIK1iH69kILFlH7FkHrBiHbFiHrVmJLhqJ7puKrdrJrhvKbx0LrlxK7duKLVrJ7JoJLRpIrZqJbVqJrVrKLRsKrRrKrFpKLVqJ7ZoJrhqJrptKLltKLhsJ7hqJ7ZoJbZoJbtuK7tuK7tuLLtvLbtvLLtwLLtwLLxyL750Mb1zMLhvLLZsKrhtK7tvLLluK7duK7lwLrlxMbZsLrlvMrluM7RoLLBlJ7BlJrFlJbVmJrJjI7BgIrJhJLRjJ7RlKrFkKK5iJqthIqphI61jJLRqKLlvLbpwL7xyMrhuLrRqKrZpKrVmKbJjJrFkJqxhI6xhI7BlKbFnK7JnLAgB3ggB3ggB3ggB3jcx5Dcx5AgB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3kZB5ich4ggB3ggB3ggB3ggB3rpuMACtYx2rYRutZByxZx2uYhitXxevYRm0ZSC1ZyO4aiezZyOyZyO1aiWxaCKuZB+tZCCtYx+vYx2xYx6uYR6xZyOyaSawZSSxZiW3aim4aSi5aii4bCi1aia2ayi3bCm2aym3bCu6by24bCu5bSu6byy6biy3aim3aiq6bS26by63bCy2ayq2bSu1bSq5cS20ayaxaSWyaiayaii0aym0ayquZCSoXh2pXx6uZSOwZiOzZSS1ZSa3Zyi2Zii3Zym6aiy1ZyiyZiexaCiyaiq2ayy4ayu4bCu3bCu1aiq1aCm2aCm3aCq0ZCewYSWtYCOuYyWxZSeyZSm2ai24ay8IAd4IAd4IAd4YEeDg3/vw7/03MeQIAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4YEeCin/P////////////g3/s3MeQIAd4IAd63aiwArGIarWUdrGUcrGQZrWIXsGMZtmgftGcftGYgr2EermAer2EfrWAdq18arGAbrGEcql8cqlwZrF0arl8crWAdrWIeq2AdsWUhtmkmuGkmuGkms2cjsWcks2knr2cmrmUns2srsmkptmwrtmoos2cjuGspuWoquGkruWsuum0wum0vt20ttm8stW8qsm0ntW8ntW4otW0otW0otW0os2olsWgkrmUhtGsns2sms2gltmgmumort2cou2ssvGwttmgotGcmtWknt28stW0rtWcntWYnsWIjrmIhsGQktWcmtmYntmYnt2cptWcqrWEjrGEirmEjr2Ijs2YosmUnCAHeCAHeCAHeg4Hv////////////ZWHqCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeGBHg0c/5////////////////////8O/9NzHkCAHeu24wALZrJrhwKrNrJK5lHrFlHrRnILZpIrRpIa9lH69jH7JlI7JkIrFjIbFkIK5hHKtdGKxdGq5fHK5gHbNlIrRnJLRoJLdsKLltKbhqJ7lrKLRmI65iH7FoJLNpJ7JqKrVtLbhvL7huLrdtLLZqKLhrKLttK7lsKrdqKrdqK7dqLLZpKrRqKbRtKrBpJK1nILRuJ7hwK7VrKLRrJ7NpJrZsKblvLbpxLrlvLblvLb5yMb9xMbprLLlqK75vMLdoKa9gIbJkJLRpJ7duK7NrKLFlI7BiILJmIrFmI7JnI7VnJLFhH7BfHa1dHatdHahbG6teHq9iIqteHqlcHKtdHggB3ggB3hgR4PDv/f///////////////2Vh6ggB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3sG/9////////////////////////////8G/9wgB3sF2OQC2aie1aye0ayezaSSzaCO0aCS2aia0bCWzbCa1aymxZia2aCe5ayi2ZyO1ZSG3ZSG3ZSKyYyCvYx+1aSW3bCi3ayi4bSm5biq6biq3bCi2aSa2aia7cy26cS23bSu3bS2zaSm3bCy4bCu4aii6bCm2aSayZySyZiWvYyKsYB+qXh2lXBqoXxysZB+uZh+yaSO0aSaxZiSyZyS1aSi3ayu5bC22aiq2aSq7bjC5bC61aCmyZSa0Zyi1Zie2ZyizZSa0Zyi2aiu0aiqzaSe0aCazZSOwZCGsYx6mXBenWhWpWherWheqWxmtXhurXRuvYh+2aCa4aiixYyKtXx4IAd4IAd51cez///////////////////////9lYeoIAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd6in/P////////////Rz/lGQeain/P///////////8nIeK/djkAr2Igr2QgsmcjtGkltGkls2kltm0os2slsmomtmwruW0uum4tu20rvm8rvW0pumgktmUitmckuW0qu3EtuG4qt20ptmwos2omt24quW4qt2wot24otGwms2ont20ruG0ttGgpsWUlsGMhsmMis2QhsWQgq18bqV4bqV4bqmAdqmAdpFsXp10ZsWcis2kjtmolt2omuGootGcltGclsGIisWMjs2UnuGkrtWUosmQnsGQmr2Qlr2Mks2UmtGcos2YntWgptWgpsWUmr2MjsmQksGMhr2Qhq2MeqmAbrF8brFwZrVwZqFgVp1kWrF4bsWQgtmgltGYjr2EfsmQiCAHeCAHe4N/7////////op/z8O/9////////////ZWHqCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeg4Hv////////////0c/5GBHgCAHeCAHe////////////RkHmv3Y7AK1gHLFlIbNnI7RpJK5kH65lIa1jHqxgG69jH7BjI7VnKLZpKLdpJ7lsKLtuKblrJ7prKL1xLb1yL7xyLrxyLrlwLLVsKLVrJ7ZtKbZsKLVrJrZtJ7BoIrFoJLZsKbdqK7ptLrhrK7doJ7ZnJrVmJLRmIrFlIK5jHrFmIrVrJ7RrJrNoJLZrJrVpJbdrJrVoI7RnIrJkIbFjIK5gHrJkIrZoJ7VnJ7FhI69fIbBiJK5iI65kJK9kJbFlJbNnKLRoKbZqK7RoKbFkJaxfIKtdHq1hIrFnJrVtKrZsKbdqKLNlIrVkJLdnJrdoJ7ZpJrJlIbFjIbFkIbFkIrZpJwgB3ich4v///////////xgR4Dcx5PDv/f///////////2Vh6ggB3ggB3ggB3ggB3ggB3ggB3ggB3mVh6v////////////Dv/Tcx5AgB3ggB3mVh6v///////////ych4rtxOAC0ZyKyZB+sXxqnXBekWxWkXBWjWRKqXRawYh2vYB6uXyCxYyKzZSKwZCCyZyK0aSS2aye2bCmzaieyaCWzaSWzaCS1aia4biq1bSi0aya0bCazayWyaSO2aia4bSq2aCi1Zie3aCi5aSi1ZSS0ZSO0ZiKvYh2qXxqwZSCwZyGyaSO0aSSyZyOwYyCsXRuoWheoXBanWhSrXRmxZCCzZSKzZSOwYiCwYSGzZSW2aCi4ayy4bi6/dTW8cjK4by+4bi61ayu4bi68bzC6bS64ay27bzK+dDa8czS6cTG8cDC6bCy6ai28bS+7bjC3ayuzaCazZyW2aiq3ayu7by8IAd5lYer///////+yr/UIAd4IAd43MeTw7/3///////////+in/MIAd4IAd4IAd4IAd4IAd5GQeb////////////w7/03MeQIAd4IAd4IAd6yr/X////////g3/sIAd62bDQAsWQfrF8Zp1wUqF0WrWQcrWYcrmUctGYes2QesGEer2AesWMhsmYisGQgrmMesGcjsmglr2UjsGYksWYksWYir2Qgsmcjs2gksWYhsGgisWkjsGcgsGYesWQfrF4brV0csmIirFwdq1sarl4drF4bqFkWqVsXrF4asGQfsWgismkksGUgr2QgrmAfq1wcrl4ermEcsGMetWgktmgkt2kmtWcktWcltWcluGoouWwqtmoqtmwsu3Iyt28vtGwss2oqtWwtu3AxvXI0wHQ2v3M2vXE2vHM3u3M2u3I0vnI1vXAzvm80vW4zvG81u28zvHEyvHEzvHEzu3Azv3Q3CAHeg4Hv////////g4HvCAHeCAHeCAHeNzHk8O/9////////////op/zCAHeCAHeCAHeNzHk8O/9////////////ZWHqCAHeCAHeCAHeCAHeVlHo////8O/9RkHmCAHermUqALxuKrVoI7ZpIrVpIbBmHbBoHrNrILVqH7JlHbNmIbVnJLVnJLVoJLJmIbRnIrJmIq5hH6tgHq9kIrFlI69kIa1fHLBiH7FlIa9kH65jHq5mILFmH65hGqlbFqVXFKtaGbBfH6xcHa1eHK1fHa9hHrBhHrRkIrZnJLptKbpvKrVqJbVpJbhsKrpsLbxrL75tMLlqKLpsKb9wLrlqKLhqKLlrKblrKrprLLpsLLpsLLhrLLdsLbVsLLZuLrlxMbpxMrhuMLlwMrxxM7htL7NoKrVrLblxM7pzNbt0Nb1zNrxwNb5xN7xwOL1yOsB1PMJ3Pr90O791O750Or91OwgB3qKf8////////0ZB5ggB3ggB3ggB3ggB3hgR4NHP+f///////////6Kf8wgB3ich4vDv/f///////////2Vh6ggB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3rBmKAC4aie3aCW2aCO1aCO2ayO4bya1byK3cCK1bSK0aiO3aye2aSWwYx+vYRyuYButXRqrWxqqXhyqXx2pXRuqXRqrXRqtXxysXxurYBusYRyqYRuoXRauYBmuXxqvXxy1YyK0YiKyYSKzYyKyZCK2aSa3aSa8aim9biy3aSWvYh61aia4bSu4ayy6ay63ZSy7aS+9bi+9bi+5aSq4aSm5ayu8bC68bC67bC69bjDCczXAczS7cDC6cTG6cjK6cTK6cjO4bzG7cjS8cjS/dDbDeTvCeTq/dzjAezvBfDzBeTrAdTm+czm7cTi5cDe5bzi7cTq7cDq/dT6/dkC9dD0IAd7Bv/f///////9GQeYIAd4IAd4IAd4IAd4IAd4YEeDRz/n///////////+in/PRz/n///////////+in/MIAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd6oXRoAumsrtmkmtWgkt2smunAqtm4ntG0jtG0is2wjsmgitWoltGgjr2IdrmAbrF4asWEer14cqlwapVgWoVMRo1UTo1USp1kWp1oXqF0Yq2AbqWAbql0YqlsWr18btWQgtWQitWQjtmUltmYltGUjumsqumsquWkquGkouWspu24rvXIvwHQzvG8wu20xv283v282vGwwuGgrumotu2wvu2wvvW0xvW4xvW8xvG0wuGostWsrr2YmqmIir2cnsWgpr2cosGgruG80unE2v3Y6w3k9wHg6u3Q2vXg4wHs7v3c5u3I2uW81t242tGw0tm04vnM/v3M/v3RAvXM9unA6CAHewb/3////////RkHmCAHeCAHeCAHeCAHeCAHeCAHeGBHg0c/5////////////////////////op/zCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeu3EwALNnJrFmJLRpJbRrJrNrJa5nIq5kIaxgH6pdG7FkIbZoJbZpJLRnIrRmIrVnJLVnJrNkJbBhIKtcGaxeG7NlIrRmI7BkIK1hHq1iH61jILFnJbJlIq9gHa1eG7BiH7RlIrVmI7hoJrlpKLppKr5tLr5uL7tsL7hqLLttLb5wLrxuLb1wML1xM7luMrhtNLpuNLttMLxsL71tMb9wNb9xNr9xNr9zNr1yM7luL7huLrRtLbJsK7dwMLpyMrlwMr51Ob92O7xyOrpwObpwOrpyObx2Orx2O752Or52OrtxNrpwNr50PMJ5Qr51QcF3Q8J3Qr9zPr5yO7ltNLRoLwgB3oOB7////////1ZR6AgB3ggB3ggB3ggB3ggB3ggB3ggB3hgR4NHP+f///////////////9HP+QgB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3r92OwCyZSOzZiS0aCSzaCS0aiW0aie4biy4aiu7bCy9by24aii4aya3aia2aCW6bCq6bCq5aiu5ayq5aym8biy9by24bCq2aiiyZiOwZCKuZCKwZSOwYyGuYB6wYh+zZCK1ZyS2aCW1ZyS3aSi8bCy8ayy7ayy4aiq2aCe6bCq9byy6bSq4bCq5bC2/cjW8bzW5bDG/cTLCczTBczXBczfCdDnDdzzDdzrDeDnFezy/dji8dTXDfDvAeDi+dja/dDbBdjq/dDm8cjq8cjy6cDq4bze7czm5cDa3bjK4bzO3bTK4bjS4bTa6cDq4bjm2bDe2bDWzaDGxZy+xZiyvZCsIAd6Dge////////+Dge8IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4YEeDRz/n////////////Rz/kYEeAIAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd7CeD8AsWMgr2EesWIftGYkuWwpuWwsvG8vvG0vuWsruWspt2knt2onuWspumwpuWopuGkpuGkrt2coumsrt2gotmcnsWUltGcntWkptmkpsWcns2kos2gotWopuWwsum0suWwqtWkmsGMhsmUkt2kquWorumsrumspvG4rvXEtum4qsmgksWcksmYltWcpumouv28zxXc3xXg3wXQ0w3Y4wXU4v3M4wnc7v3Q3vHI2t24xtWwuu3M0u3EzvHIzum8xum4yum40v3Q7u3A4tGkxsmgvsWgtqmEmqV4jrWInrWIorWEop1wkpVojpFoiplwlqF4mpVsjp10ksGYsrWQpCAHeRkHm////////0c/5CAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeop/z////////////0c/5GBHgCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHesGYwAK5gHLBhHrFjILRlJbRlJa5hIq1fIq1dIKxdH7FhI7VmJbJkI7NlJLRmJbRlJrZnKblpLLdoKrdoKrdpKrZoKrZpKrdqK7hsLbtwMLlvL7txMbpwMblvMLlvMbpwMLluLbZrKbNoJrdsK7tvL7puL7tuLr1uK7ptKrVrJ7BoI6tkH6lhHrFnJr1vMsFwNMNzNsB0MbxyLrtvLr5yM7ltMLltMb1xNrpwNLVsMLJpLLNpK7NpK7ZsLrhsLrhsLrZpLrZpL7JlK7FlK7JnLbBlK65kKapfJKZaH6RXHKdaIK1fJq5hKKxgKKhcJKlfJq5kK7JpLrBnLKlgJaNaHggB3ggB3v///////////ych4ggB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3qKf8////////////9HP+RgR4AgB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3ggB3rNpNACvYh2tYB21aCa4aiu3aiyxZSiwYyi2Zyy3Zyu4aCu7bC25aiu5aSu2Zim5aS26ai65aS62aCu4ay24ay25bC65bC67bi+7bzC7cTK8cjK9czO8czW6cTS5cDK6cTO6cDG6cTC7cTC8cjK9czO7cTG8bzC8bi22aym1bSu5czC5dDG9dzW9dTa9cTPAcDW+bzK4biq2bSm6cC25by63bC+2ay+wZCmpXiOmXCGtZCi1ai25bjC4bS+6bS+8bzK4ai62aC2yZCmuYieuYiavYievYyiwYyiwZCm2aS64ai+zZSutYCetXyauYiiwZCmwZiquZCitYiatYyesYSUIAd4IAd6yr/X///////+Tj/EIAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd6in/P////////////Rz/kYEeAIAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd4IAd6+cz8AuW8qtmwpuG0su28xvHI1vXQ5vXI3vW80u2swvW0xvGwvvG0vvG0vu2suu2svuWkuuWkuumswvnA1vnE1um0vum0vvnEzv3I0vHEyvHIyvHIyvHM1uXA0uG8yunEzu3MzvnY2v3U1v3U1vnQ0u3Exu3ExvnEzu3MzunQ0vXk5u3g3vHg5v3k7wXc8v3E4vHAzt28stm8rtWwptGkpsWYosGUnrGElsWUqt2wwum4zu20yumwxtGYrtWcsuWwwuWswtmgtsmQpsmUnsGMlsGImsGInr2Emr2EmrmAlrmAlqFofp1ker2EmtGYruGsutGgqr2IksGQms2cpr2MlCAHeCAHeVlHo////////////JyHiCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeop/z////////////8O/9NzHkCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHesWUwAA==]] | |
FILE: [[images/processing/rotation/test-bitmaps/PastedImage90.bmp]] base64[[Qk06qgAAAAAAADYAAAAoAAAAfAAAAHUAAAABABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAq2Asp1wnpFgkmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4Ao1ognFMZpFshrWQqolkfm1EYmk8Xm1AYoVchqF4orGQupl8pp2AqpFwlolkhplwjnlIaolYcm1IVmlETolcbrWEmr2IppVgfqVwjuW0zrWMpqV8knlYZqmMlvXU5uXA2tm0ztWsytmsyvnM5vXA1uWsws2YrsGQpsWUqqmEjo1oeqV8ksGUsolcgnE8bsmUzsGQvrGEnoVQbn08YpVYgsWQumE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AuWwzu241tWkvuGsxu280uGwvum4wt2osu24wwXY5v3Y5v3Y7u3E4tmw0rmUqsGYoqF0au3Ewv3Y7wng/sGYws2k0vnM/sWUwq2ItqF0opVokmE4AmE4AmE4AmE4A////////////////////////////////////mE4AmE4Ao1kfm1IYo1ogqF8lp14koVcfmlEZl08XpFkkp1wnqWArqWArqWErp18ppVwkplsjnlIaoVYdnFMWnVIWoVUapFcdrF8mqFsiplkgtmoxsGYsrmUqpV0gqmIlunI3tmw0tGozuW03tWoyvHI4vnI3uW0wsmYqsGQptmovq2Ilo1seo1ofsGYspFojnlQfrmIvq2Arql8np1oipFUdo1UeqV4mmE4AmE4AmE4AmE4A////////////////////////mE4AmE4AmE4AmE4AmE4AmE4AmE4A////////////////////////mE4A////mE4AmE4AmE4At2oxuWwzt2oxuWwyCAHeCAHeCAHeCAHeCAHeCAHeJyHiRkHmJyHiCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHesWkxqmIqpFsimE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AoVcdm1IYn1YcpFwipl4kolohm1MblUwWolcjp1woqV8rqmErqmErqWAqqmEpo1ggoFUdolcdn1UYn1QYolYbnFAVp1ohqVwjpVgfsmcus2kwsWgupl4iqmEmunE3tWoztms1vXE8tWkzv3Q7vnM4t2wwsGQpsmYrtWousWgspV0hoVkerGQqpVskoVcirWItql8pql8nqVwkpVYep1khploimE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AuWwzu241t2oxuGsyCAHeCAHeCAHeCAHeNzHkwb/3////////////4N/7RkHmCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHerWcsq2Uqo10hmE4AmE4AmE4AmE4A////////////////////mE4AmE4AmE4AmE4AmE4AmE4AolgemlEXnVQapFwipF0kpV0ln1chnFMdnVMeplsnq2Erq2Eqq2EqrGIrrWMrnlMbm08YolceoVYcoFUao1gdnFAWpFogp10moFgjoFomo18rrGUvpl0kpVshuG40tWoytWkzvHA7uG02v3U8vHM4tGsvr2QptmovtWour2YqrmUqqGEmrGQqqmAopFojsGYvrWMrrGEoql0lplcfplggplohmE4AmE4AmE4AmE4AmE4A////mE4A////////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4Au240vnE4vG82tmowCAHeCAHeCAHeNzHk8O/9////////////////////8O/9CAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeqmQor2ktpmAkmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AoVgemlEXmE8VoVgeoVohpFwlolokn1Ygm1Ebo1kjrGIqqmEpqmEpq2IqrWMsmlEdkkoYk00akkwZjkwZjUsah0gXhUkbgkkfd0QdbT8ackIeklYpp18qolcfs2gwuG01s2gwuW42u3E4wHY8vHM5t20zrmMpum00smYtq2EnsGctqWInqmMoqWAmqmAmsWctsmgur2Qqq14lplceplgfqmAmmE4AmE4AmE4AmE4A////mE4AmE4A////mE4A////mE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AvG82u241u241t2sxCAHeCAHeCAHe4N/7////////////////////////////CAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeqmQpr2ktqmQpmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4An1Ycm1IYl04UoFcepFsjo1sko1oloVkjn1UdolgfqmIqmlUgk1MhklMjjlImeUEZbDcTZDUSXDAQVi4QTysQRycORSYPOzUoMENAJ1FYI2FwLXmMhmtNo1cirWEqvG83tWkwtWwwuXA1vXM4vHM5uG83qmAnum41rmQqpl0jsmkuqmMnpl4irGIlrWMmr2QnsWUqr2IprWAnq1wjp1kgqF4kmE4AmE4AmE4AmE4A////mE4AmE4A////mE4A////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////////////////////////////mE4AmE4AmE4At20ztGgwtWoxum40CAHeCAHeJyHi////////////op/zCAHeZWHqsq/1VlHoCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeqmMpsGkvrGYsmE4AmE4AmE4AmE4A////////////////////mE4AmE4AmE4AmE4AmE4AmE4AnlYcm1IYmlAXoFYepFoiplwmpVsno1kjoVcfnVQanVkjc0AXVzETTS0USSsVOyoaLD48J0VHGlprE2qEDHqcFJC3N7PZSLncdszmidLpu+Xyj9LpRnd8oFgmql4mvHA1uGwvtWwtu3I1vnU6vXQ7u3I6q2EouGwzsmgup14ksWktq2Mnn1gZrmUmrWIkrmEis2YpsmQqrF0jqFkfqVsiql8mmE4AmE4AmE4AmE4A////mE4AmE4A////mE4A////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AunA2tGkxs2kwu3E2CAHeCAHeRkHm////////////RkHmCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeqGAnrWUsr2gvmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AoVkenVMamE4Vn1Uep10np1wooVYko1kkplwjnFMajlAeVzIWG1xtCYCoG6bZG6bZRb/mSL/meNnyfdnysvL/uPL/vfL/w/L/yvL/z/L/3vX/gMzmMGl2emNHqV8nuW4ztWsttWsrvXM1vnY6uXI4uXI5qmIouW82tm00rWMqsmkuqWAkoFcaq2MltWstrmMls2Yqs2UrrV8lqVwhrV8lrmIomE4AmE4AmE4AmE4AmE4A////////////////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////////////////////mE4AmE4AmE4AmE4AmE4AmE4AunA1smgusmguvnM4CAHeCAHeCAHe////////////0c/5GBHgCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeplwksGgvs2wzmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AoVcenlMbmU8Yn1Ufql8sqV8tmlEgoFcjqmAom1Ibf0UZSSsUBom0c9j/ddr/d9z/ed7/fOH/fuP/gOX/gub/ieb/kOb/leb/neb/o+b/wOz/cMXiVcXiTrjcqWEpsmkusWgrsWgqwHg5vXY5tHA0t3Q4sW0yunM6tWwzrWMrtmsxrGAmo1gep14js2ovsGcss2kwsGQtrmIprGAlrWAkrmAlmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AuXEzs2susWYrvnI3CAHeCAHeCAHeop/z////////////0c/5NzHkCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHep10lrmYusWsymE4AmE4AmE4AmE4A////////////////////////mE4AmE4AmE4AmE4AmE4An1QdnlMcnFIanVMcpl0np14qm1MenVQfqV8nmVIdcj4WOTUqIKvZfuP/g+n/huz/i/H/j/X/lPr/mP7/nv//rP//uv//xf//0///4f//9P//QLLZtv7/Xb7frWUtsGcsr2YorGMlvXU3vXY4tnE1t3Q3tHE1tXA2smswq2IotWkvsGMqpFcerGAnsmgurWQqsmgvrmIqsWQrrGAkq18hq10gmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4At3Aytm4ytGovuW0yCAHeCAHeCAHeGBHg0c/5////////////8O/9NzHkCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeNzHkrWMrrmUttG00mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AnFIdoVchnlQdnlQcqmEoqWAonlYdl00WqV4pmFMjZDcXKUhMP73mfuP/g+n/huz/i/H/j/X/lPr/mP7/nv//rP//uv//xf//0///4f//+P7/GqbSxv3/XKe8sGcur2UqrmQnplwetGstvHQ2uHI0tG4yt3I1uHM1smstrWQnsGQqtWgtpVgermIotmowq2EntWsyq2Anr2Moql8hql4gq14hmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4Atm4ytm0yv3M5uGwxCAHeCAHeCAHeCAHeGBHgwb/3////////////8O/9ZWHqCAHeCAHeCAHeCAHeCAHeCAHeCAHeGBHg8O/9rGIqrGMruG83mE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4Amk8bnFIcn1Ueo1ggqmAnqmAnnFQamk8YpFkkkE4hVS8VGGN6Xc7yfuP/g+n/huz/i/H/j/X/lPr/mP7/nv//rP//uv//xf//0///4f//+P7/J7PZ1/z/SZirr2YssWYrsmcpql8huG4wvnY4vHU2smwvuHI0vHY2smsrr2Ynr2QntmktqFoeplofvG81rWEouW40rWIprGAkqF4eq18fr2IjmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4A////////////////////////mE4AmE4AmE4AmE4AmE4AvnU7t20zvHE2tmkuCAHeCAHeCAHeCAHeCAHeCAHeop/z////////////////ZWHqCAHeCAHeCAHeCAHeCAHeGBHg0c/5////qWApqmMrsWoxmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AnFIbm1EZoVYeplskql8npVskoVchn1Qfn1QhhkgeSSoUCYGoe+D/fuP/g+n/huz/i/H/j/X/lPr/mP7/nv//rP//uv//xf//0///4f//vOXyOr/f3Pz/U358rWMosmYrtWosrGEjtWstwHg5vXU2tm8wvnc3u3Q0rmcnrmYms2krtmstql0gploft2swr2MouW40s2kuq2AipVsaplsZrGAfmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AvXQ6t20zuGwytmouCAHeCAHeCAHeCAHeCAHeCAHeCAHeg4Hv////////////////op/zCAHeCAHeCAHeGBHg0c/5////////o10np2IstG42mE4AmE4AmE4AmE4AmE4A////////////////////////////mE4AmE4AmE4AnlUcnFMZn1UcpVojp1smpVolpFkmolcjm1Mid0AaQCQRGKbWe+D/fuP/g+n/huz/i/H/j/X/lPr/mP7/nv//rP//uv//xf//0///4///rN7vTszmxOj1XHhurWMosWUqs2grsWYotGosvnU3vXQ2u3Q1v3k5unMypl8frWUluG0vtmstrWEkrGAksmYrrGAltmowsmgtql8hpFkYplsZsGMimE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4A////////////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4Au3E3uW80tWktuWswCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeZWHq////////////////op/zCAHeGBHg0c/5////////////oF0ppGArs3A5mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4An1cbnVQZm1IZo1kipVololcjpFoopVspl1EkZTYWKz8+Nbfie+D/fuP/g+n/huz/i/H/j/X/lPr/mP7/nv//rP//uv//xf//0///5v//fszmfuXyteLye2tMrGMnr2UosWgqtWwuuG8xvXQ2vnU3vXY3wXo6v3g4rGUlr2got28ws2krrmMlrmIlrWEmrGAlsmcstGovqV4gpFoZp1sZr2MimE4AmE4AmE4AmE4AmE4AmE4A////////////////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////////////////mE4AmE4AmE4AmE4AmE4AunE2uW80smcqum0wCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeRkHm8O/9////////////0c/50c/5////////////op/zqGc1qmg1tHI8mE4AmE4AmE4AmE4A////////////////////mE4AmE4AmE4AmE4AmE4AmE4An1ccnVUanFMZoVgfo1kjoVcipFwop14rkVAiVC0TGlttUsfve+D/fuP/g+n/huz/i/H/j/X/lPr/mP7/nv//rP//uv//xf//0///6/7/X7/fker1iNDpkmU3qmEksWgqsWgqtW4vuXEzuXEzvXU2v3g4wXo6v3g4tm8vsGkpt28ws2osrGIkrmQmrGIkqFwgtGgutGovqmAiplwbploZrmIhmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4A////////mE4AmE4AmE4Atm0wuG4xr2Qnum0vCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeNzHk8O/9////////////////////////op/zCAHernA/qmo3tnVAmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AnVMaoFcdn1YcnVUaoVceoFkgoVsipV0oiUwhSCgSDHmbaNP5e+D/fuP/g+n/huz/i/H/j/X/lPr/mP7/nv//rP//uv//xf//0///7P7/QLLZvfz/esrmqmIkq2Ikr2cpr2cpuHEytW4vrmcouHExvHU1vXc4wHo8u3Q2rWYntm8wt3AxrWQmrWQmr2UnqF0ftGkts2kuqV4hoVcWp1saq14fmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4A////////mE4AmE4AmE4AunEzt24vrGAitmkrCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeJyHi0c/5////////////////op/zCAHeCAHevYFQtHdFvH1JmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmU8Yplwjo1ofnlUaolkepF0io1winloke0QdQSUQD6HSdtv/e+D/fuP/g+n/huz/i/H/j/X/lPr/mP7/nv//rP//uv//xf//1f//8/3/JKzWw/z/WKW6rWYsqmEkrGMlrmYounM0t3Awq2Qks2sruXEwvnY3v3g8vXY5q2QltW4vu3Q1rWQmrmUnqmEjq2Ejt20xt24wrmMlolcYolYXqVwdmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////////////////mE4AmE4AmE4AmE4AmE4Au3ExvXQ0r2UlsmYnCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeop/z////////////op/zCAHeCAHeCAHezJBhw4ZWuXlImE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmlEdpFwloFgeoFcdoVgepVojp1wnnFYlbT0ZMDk0LLHfdtv/e+D/fuP/g+n/huz/i/H/j/X/lPr/mP7/nv//rP//uv//x///7fz/fMvmOr/f1/v/VpmrlFYnpVwkrmQosmkruHEwt3EuqWMeq2MfunAswHY3wHk6unM1rGMls2osvHM1r2Yps2gtq18kq18ktm0wt28wsGgpoVYYoFMUqFoamE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////////////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AuG4uv3U0tmwrr2UlCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeop/z////////////0c/5CAHeCAHeCAHeCAHeyY1gyItcvH1NmE4AmE4AmE4AmE4A////////////////////////////////////mE4AmE4AmVAcnlYfmVEXnVQaolggplslqF0pl1MlXDIVH1ViSMDsdtv/e+D/fuP/g+n/huz/i/H/j/X/lPr/mP7/nv//rP//uv//4Pz/a8TiMLncj/n80vv/l9bsQW93hFInrWMmtWwst3Euv3k2pmAdpVwZum8swHc2vnU3u3I0smkrtGstuXAyr2Yos2ksqF4hqWAiunEyuHAvtmwtplkboFETo1QTmE4AmE4AmE4AmE4A////////////////////////////////////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AuW4vvHIzt2wusmcpCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeop/z////////////0c/5GBHgCAHeCAHeCAHeCAHew4da0ZRm1JRlmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AnVQfolojnVUcmE8Xo1ojqF0orGIuj08kUCwUD3ORXcv1dtv/e+D/fuP/g+n/huz/i/H/j/X/lPr/mP7/nv//rP//uv//6/r/HavWlvz/mf//nv//1/z/yer1SJ21oGYxtGwstW4tvHc1q2Uin1cUu3Auw3k4vXM0unAxsGgpsmoruHAxrmUmrmUmq2MkpV0etm0su3Euum0sr18holESolIQmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4Aum0xvnI2vHA1tGgsCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeop/z////////////0c/5GBHgCAHeCAHeCAHeCAHeCAHet3tPzpFj25tsmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////////mE4AmE4AmE4AmE4AmE4AmlIdnlcgoFkgm1MdoVkkrGItpl4tg0giRScSDY23ctf/dtv/e+D/fuP/g+n/huz/i/H/j/X/lPr/mP7/nv//rP//vP//s+LyOLzflvz/mf//mf//mf//yf7/v+byf3FRtGwssW0suXUzq2YjnFMRum4tyH09v3Q0uW8vr2cnsmoqunIyrmYmr2cmrGQjq2MhsmglvXAtvGwrt2QmqVYWpFIQmE4AmE4AmE4AmE4AmE4A////////////////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AvW40uGsyvnE4smUrCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeZWHq////////////0c/5GBHgCAHeCAHeCAHeCAHeCAHeCAHeuHxQ0JJk3JxumE4AmE4AmE4AmE4AmE4AmE4A////////mE4AmE4AmE4AmE4AmE4AmE4AmE4AnFMgnVUfoFgioFgio1omqmEtnVgocz8dNDAmJKzcctf/dtv/e+D/fuP/g+n/huz/i/H/j/X/lPr/mP7/nv//rP//xf7/ldXsScjmlvz/mf//mf//mf//sf//n9nshHRUt3Axs20tvXk4sWsroFYWsWUmx3o7vXEyu3ExsGYmtW0twno6rmYlrGUirWYirWYhsmgkuWwpvm8uuWgpr10dolAPmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4Au2wyt2oxvXA4t2owCAHeCAHeCAHeCAHeCAHeCAHeCAHeZWHq////////////0c/5GBHgCAHeCAHeCAHeCAHeCAHeCAHeCAHevoFVz5Bj15VnmE4AmE4AmE4AmE4A////////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AnlUhnFMenVQgnlUholklpl4ql1UnYTYYIkxUOLbmctf/dtv/e+D/fuP/g+n/huz/i/H/j/X/lPr/mP7/nv//rP//y/3/eMnmbd/ylvz/mf//mf//mf//yv7/gczmmGw9tm4vtm4vvXY3tW0upVsbs2YnyHo7vXEyvXMzsWcntW0txHw7r2glrmYirWUgrWUesWcht2snu20rt2gpsWEhoFEPmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4AmE4A////////////////////mE4AmE4AmE4AmE4AmE4AmE4AuWoxtmkxvG82tmkwCAHeCAHeCAHeCAHeCAHeCAHeZWHq////////////8O/9GBHgCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHevoFW05Rm15VnmE4AmE4A////////mE4AmE4A////////mE4AmE4AmE4AmE4AmE4AmE4AmE4An1cklU4bmFAdnlUioVgkpVwokVIkUy8UE2mDU8Xyctf/dtv/e+D/fuP/g+n/huz/i/H/j/X/lPr/mP7/nv//rP//0fz/PLHZf+r5lvz/mf//mf//mf//yv7/ccbirGMmr2YptGwvv3g6uHAxqFwduGkqyHo6v3Qywng2r2Yms2srv3c2s2sqsmklqWAarWQcsmcgtmwouG0rtWcotGcmpFcVmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4A////mE4A////mE4AmE4AmE4AmE4AmE4Aum0zt2swuGwxtWkuCAHeCAHeCAHeCAHeCAHeZWHq////////////8O/9NzHkCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHevoBXzo9j1pRlmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////////mE4AmE4AmE4AmE4AmE4AoFoolU4clU0coFcko1klo1kmiE0iRygRCICnbdL/ctf/dtv/e+D/fuP/g+n/huz/i/H/j/X/lPr/mP7/nv//rP//4fr/J6rWj/X/lvz/mf//mf//mf//4f3/SrDPr2Uqq2ElrmUpwHg7unIzrWEhuGoqyHw6v3UyvXQzsGgos2ssvnY3tW0ssmglqV4ZrWAbtGgjtGomuG4stmkqsWUkploYmE4AmE4AmE4AmE4AmE4A////////////////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4A////mE4A////mE4AmE4AmE4AmE4AmE4AtGotsWcptmwutmwtCAHeCAHeCAHeCAHeZWHq////////////8O/9NzHkCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeuntSxoZby4lZmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4An1opmFEhlEwboFYkoVYinVYigkkeRzEbIKjZf9n/g9z/leP/nuf/our/p+3/vPD/wfL/xfT/u/D8p9/yq+DyreDydsnmNLnfj/X/lvz/mf//mf//pP//7P3/W6CvsWUqrGAlq2ImvHI1unAxtmkptWYkw3c0v3czu3QytW0tsGkqvHQ1uXAwsWUkrWAdtmgkuWwntmwptWoosGMkr2MipFgWmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4A////mE4A////mE4AmE4AmE4AmE4AmE4As2sqsGknuXIwuHEvCAHeCAHeCAHeNzHk////////////8O/9NzHkCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeJyHivoBXw4RXyIdXmE4AmE4AmE4AmE4AmE4A////////////////mE4AmE4AmE4AmE4AmE4AmE4AoFsqm1Qjl08en1Ujn1QgnVQgkk8fT1pNLq7ZXMPmU77iMa7ZMq/ZM6/ZJ6rWCp3PKKrZKqvZLKzZOLHcXsHmYcHmaMfpj+f8ofT/qPr/rP3/zPv/4/T8Xr7fWoJ+tmgvrWAnr2Yqtm0wuW4wu2wtsmMivnIwvXYyvHUzuXExs2wtu3IzvHIzsWUkrV8cuWomvnAsuGwqs2YnsGIjtGUkqVsZmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4Ar2gnsmsovHQwuXEvCAHeCAHeNzHk8O/9////////////op/zGBHgCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeJyHik4/x////x4lgyIpdx4dXmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AoFwomFQfl1Edn1gjoFgjoFgjolslg1kwXWteTXh3THh4THl5Snh6JYiiJ4mkSpiuTZmwQ565LKzZRLXfXsHmYcHmZcPmaMTmoNvypt3yqt7ydsnmUY2UnG1CtGcutmsxq2Insmkstmwvs2gqvXAxt2oruW8vwHc3wnk5vHQ0unAvvXIwum0stWclqFoYtGYkwHMxuGsrt2oruGwrsWYkqV4cmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AtGkrsGUmuG0vu24wCAHeCAHeNzHk4N/7////////////////////sq/1g4HvRkHmRkHmRkHmVlHog4Hv0c/5////////////xIZdxYZcxIVYmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AnVkklFAblVAbolwnolwmoFkhpV0lnFIZm1EZo1kjn1YipV8qp2Eto10rqGMvpl8qp14qp10npFsiolofo1sgqGEnjWI4cmJIeGhPfGxQdGVFmGw8tWkusmYstGkvuXA0sGcpsmkrsGYnrmQks2gnum8uu3IzvnY3wno6vnQ0v3MyvnEut2kmtmglrV8dtGYkwHIxtmkqsmYntmwrsGclqGAdmE4AmE4AmE4AmE4A////////////////////////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AtmovsmQps2UqvG4zCAHeCAHeCAHeGBHgg4Hv8O/9////////////////////////////////////////////////////////yYthxodfvn9UmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AnVkkmVUgllEcoVsmoFojpF0kqWIpm1EZmU4XoVYgnVQgp2ArqmMvolsoqmIup14qo1gkpVslqF8mp18kpV0hqGAlqV8mpVoipVoiqF4loVgbrGMls2gts2gttmwxunE0sGcpsmkrt20urmMisWUjuGwqvXQ0w3s8wno6vnQ0v3Qyv3IwumwqsmQisWMhuGkouWwttWossWcnsmgpr2clqWEfmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4At2ovs2UquGovvW80CAHeCAHeCAHeCAHeCAHeGBHgdXHs4N/7////////////////////////////////////////sq/1VlHozY1ky4xkxYdcmE4AmE4AmE4AmE4AmE4A////////////////mE4AmE4AmE4AmE4AmE4AmE4An1smnlgjmVMdolslo1wjo10iqGInnVUcmk8ZnVMdn1Uhp18rrmgzpl8rpl0pplwon1QgolciqF4nq2IpqGEmp18jp18jqV8lpVoiqV4lp10iqWAisGcrsGcrtWwvu3I0tW0tt28uuXAvsGYkrWIetGckunEvxHw8v3Y2v3Y0vnIwum4suGspsWMhsGIgtmgoum4vs2gqtWossmkqpl4drWUjmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4AmE4A////////////////////////mE4AmE4AmE4AmE4AmE4AtGYrtGcruGsvumwxCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeJyHiZWHqg4Hvop/zwb/3wb/3g4Hvg4HvRkHmCAHeCAHeCAHezIxh0JFnxohemE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4Ao10nn1kjmVIdolskpF4kolwhpmAlo1sinlQen1UfoVgjqWEssGg0qF8roVgkpFklo1gjoFYgp14prGQsqmMpp2Akp18hpV0hpFkgp1siqV0kqV8jsmkrrWYnsmssuHExr2gouHAuuXEutWworWIesmUhunAuwno5vHUyunAuv3UzvnMxum4ssWQisGIgtGYmvnEzs2ostWwusWgpnlYWqmIhmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AtmovtWktt2suu28yCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHeCAHexIVV1pdpxYlamE4AmE4AmE4A////////////////////////////mE4A////mE4AmE4AmE4ApF8pn1gim1Mdn1cholsio1wipV8kpFwjoVchn1Uhn1YiqmEtq2Iupl0pn1YioFYiqF0oolgiqGArr2cwrmgtqWMmpV4gpFsfpVkgplkgq14krmInrmQnqWIjsGkquXIyq2Ujtm8tvXQxuW4ssGUhs2gkvXQxwns5u3Qzs2sqwXg3xXs6vXIwtGcltWcltmgmuW0tsmgqtm0vtW0uoVkZq2MjmE4AmE4AmE4AmE4AmE4A////////////////////////////mE4AmE4AmE4AmE4AmE4A////////////////////////mE4A////mE4AmE4AmE4AuGwxs2gruG0vvHEzsWYor2UosmcsuGsvsmUnq10erV8esmQitmknu28vv3Q3v3U7vXQ9unA6tGgvr2QrrWQpo1oerGElr2MluXhH1JVky45dmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AqWMto1wmmVEbn1YgoVghpV4mpF0loVkin1UgnFMfn1YiqmEtpFsnpl0poFcjnFIdqF4op10nqGAsrmYwsWowqmMopl0io1keqFwjq14lql0kr2MnrmYmrWYmrWUlunQzsGoorWYluHAuvnQytmsptGonvnY0x4A/vHQ0uHAwvXQ0wXc3t20ss2clt2knt2ootmsqsGgosWkquXAwpFsbq2IhmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AtWous2krtGssunEysmgqrWQmsWcrtmots2YoqVwcsWMir2EfsWQit2sru3AzvnQ6v3ZAvXM9uW00sWYssGYsqWAlrWMns2cps3I9yopY05VjmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AqGIsqGAqnlUfoVchoVcio1olpF0ooVolm1IemlEdoFcjq2Iuo1omp14qolgknFEcplwmqV8qqmEtp18oq2QqqWEnp10kpVoiqV0lrGAopFgermMlsGcoq2MjqWEht28vrGUlpl8fs2srvnU2t20urmQmu3IzxXw9vnY2tm4vunIyxHs8u3EwtWkntWckuWwpt2wpsGcns2oquG4urGIhq2EfmE4AmE4AmE4AmE4A////////////////////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////////mE4AmE4AmE4AmE4AmE4AsmossWkptW0tunIytWwss2gqsGUpsmUpr2Ijq14euGootGYjsWQhtmoqvHEzv3U7v3U+v3RAvnI7sWcvp10ksGcsrWImsGQmpmQvv35M05RimE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AqmMsqmAsp1won1QgoVcjolklqGEso1wnnVQgmlEdoVgkq2IvpFsoo1gkqV4qpVolpVskqmAoqGApqGEpqF8mplwkp1wmqV0op1wmrWIpolcbrGIhs2knrGMiqWAgtW0trmcomFETsWksvnY5v3Y7sGcstGsuxn0/vXU2uG8xuG8xwno7vHMytGkms2Uhum0pt2wps2oqtm0rt20rrWMhrGIgmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////////mE4AmE4AmE4AmE4AmE4AmE4AmE4As2osrmYnsmoquXAwuW8vtGkrrGEjsWUnrmEjr2IitmgmtmglsWMhs2clvHEzv3Q7u3A6v3M/v3M+s2gxpVsjsmkurmQor2Iko2Ert3VDwoFRv4BQsXJCwYJS15xw36mD5LGQ876b1ptyq2k4pV4oqWAon1cgnVogp2YrqmYtqWIsrGIuq18toVUjoFQjo1onqGEtpl8roVolm1Ieo1omqF8so1kmnFEdp1worWMtpVskq2EpqF4nq2EpqmEopFojqF0oql4pp1wmrmMqnlUWo1wYs2knqmAgplwcqWEht3AxolodunI2uXA2vnQ7r2YsrWQox35AvHM1vHM1t24wvnY3vHQzsWgktGgjvG8pt2wotmwruG4st2wprGEer2QimE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4AmE4A////////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4As2wtq2MjrmYluXEvuW8vtmwtrGEjrmMlrGEiq14er2IfsWQgsmUhs2gmvHEywnc+u3E6vnM/wndCtmw1qF4mrmQrsGYqtGgqrGgzsm88tnNCtHJDuXdIwX1Q1JVq05xz4K6I9MGb3qR9snJHoFsqrGQwoVkhm1UbpmEnqWQsoVomqF8tqV8volgnoFYjoFciqF4oqmEqpVsln1Ufp1wmpFolnlUfm1Mem1QfrGQuo1okq18pqlwoqV0mql8no1khp10nrGEsp1wmqWAmnFMVoFcWtGsqqF8go1oboVkbvnY5rWQpvnU6u3M3unI3qWEmp2Ajw3o8vnY3u3M0t24uvXQzwHY1r2UjsGYju28st20qt20ru3EvuGsqr2Igr2IgmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////////mE4AmE4AmE4AmE4AmE4AmE4AmE4AtW0uqGAgrGQiu3IwvXIzvG8wsWQmrWAjrWEjqFsbq10brF4btmkmt2sru28zwHU8uW84tm04wXdDtmw3plwlqV8msGQpuGsurGcytG89r2o5sW08xYFRyoVXy4teyZFk26h+6baN4aiCwYFbol4ypmAsoVsinFQao1oiqmMso10pqGIwq2QznlcloFcjoFYgpFkhql8nplwkpVoipVkin1QdnVQdpV8on1wlqWQtpFslp1omqVomqFolqFwlolgfplwkr2UtrGIqpl0knlUXoVgYsWgpqmEjo1ocpVwgv3U6r2UruXA0vnY5vHc5qmYnolwdwno7vnY2vnc2tWwqtWsovnQyrmQiqmAeuW8tt20suG8tvHIxvXExsGIjr2AhmE4AmE4AmE4AmE4A////////////////////////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////////mE4AmE4AmE4AmE4AmE4Atm0uqWEhpl0dtWsqunAwum0usmMmsGEltWcqq10drV4bp1kWt2gnu24wvG81vXI6uXA3tGw0vnVBuG45pFoiqFwkrmIotGYrqWMutW87qmUyp2IwxYBNzolZvn1OwIZXz5tt3ql+5q2EzI1lqWU5oVsooVoioVkgo1kirGMtpl8qpF4qq2QxoFkmoVgkolgioFYfolggplwkqV4nolYgoFUgnlYgqGMsqGUuq2Yvp14qqV0pp1ckplgjqF0lolgeqV8nsmgwqmAop14joVgaoFYXrGMkrWQmpVwfp14ivHM3tm0xtWwvunM0v3g5r2oop2Agv3c3vHU0vnc0smknsWgkwXg0sWckp10bsGYktm0sunExum8wwHQ1sGIlr18jmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4At28vr2cnpV0drmUltWoruGwttWYptGQnt2cprV0dqlsZqFgVt2cmvG0vvW4zvHA4u3E4t242wnlCunA6pVojrGAorV8mr2EmqmMtuXM9q2UwnlgjsGo1xYBNtHFAtXlHvodW2qV37bSJ0pNpr2w/oVsoolojpVsjo1gjqF4oo1sloFkjqGItpF0ppFsnpFomo1gjolgjpFwkqF4nnVMdoFchoFgipmMsp2Qvp2Espl8qpVklqVklplghqF4knFMZpV0jsmsyqWAopl0ipl0folgYrmYmtm8wrGQmrWQmuXAyuXAztWwuunMzunM0r2onrWUlv3c3vHQ0vHUysmomsGcjwXg0s2omqF4cplwatWwqvHM1vHEzv3I0s2YprmEkmE4AmE4AmE4AmE4AmE4A////////////////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////////////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AtWwutW0tqWEhrmUlt20tuG4utmkqt2gqtmYnsF8dq1oXrVwZtWQkumotvm80vnE3vnM5uW81vnQ8uG02p1wkrmEorWAnp1keq2Qru3Q8sWoypF0lolsjt3I8tHI8tXZBs3lE1Zxr67GCz5BjtHBCpV8so1slpl0mplslpVwlpV4lo1sjpl8npF0moVgjn1YiolckplwopV8oqmEroFchmVEboFolp2QuqWYxol0oqmMvolcjolUgoVYdpVwioVgepl8ks2wyrGMrpVwhp18go1oZq2MkunM0tGwtsGcptGssuHAxt28uuHEvtW4rs20psGgnvXY1vnc0unMwsWglr2YivnUxvnUxrmQhoFcUsGclvXQ0vHMzvHExtGkqrmMkmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////////////////mE4AmE4AmE4AmE4AmE4AsmoruHAxrGQlrWUltW0tuW8vtGoqtmgptmYnsWEfqVoXrFwZs2UiumwsvXAzvHA1wHU5u3I2unA2uG40rWEorV8ms2UrqFofpl4ktGwytm41pl8lnlgermgwtnI6t3c/sXM9yI1Z2p1tuXpMsG0+rWc1oVkjolkjpFokolojqGEoo1wioVshpl8nnlYgnlUhpVooolomo10nrWUvp14pkUoWnlgkp2MvqmczmlUhoVomoFUhoFQdoVYdpVshp14kpl8ms2wzqmAopFshpl0fpVsaqWEit3AxunIzsmkqs2srtGsrvHQyvHUytW4rtW8rsGonunIxwHg2unIwsGcktGsnvXQwyH87s2kmolgVq2IguHEuu3MwunEusWckrGMhmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4A////////mE4AmE4AmE4AsWost24wrmUnrmYmsWgot24uuG4utWgptWcmtWckp1oVrF8bt2oovHAwvnI1vXM2wXk6v3c5u3E2t20yrWIop1oguGovrmAlpVwisGcts2owpV0ipV8kq2YttnE5tHI5snI8uXtHxIdVpWY3o2EzuXVEo10omlMdoFgiolokp2AoqmQrpF4lqGEpoVkjnFMeoFgkoFgjoFkjqmIsp14qlEwZnVclqmc1qmg1n1omolsmoVcinVIbnFIYpVwjqmEpo1sksGgxq2Ispl0joVgZpVwbrGQltW0vtGwts2oqs2oqqmAevHQxv3g1s2wpt3Aus2sruHAxv3c2unIwtGsotm0pvXQwxHs3tWwpplwaq2Iftm8pvXUvvHQusWkjq2IdmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4A////////mE4AmE4AmE4Asmout24xsmgqsGYosGYmuW8vvHIytWoqsGQksmcjplwXqmAbtmwpunExu3I0u3Q1wXw8wHs7vnY6uG8zrWInpFcctmkurmAlo1sfrmYqs2svo1ogpl0kqGEqtnE5t3I6sm83s3I+1JVjr3FCqGk6vXlJpmAul1EbnFchoFokpmAqqmQuoVslpl8ppFwmm1MdnVYeoFoioFokp18ppl0qmFAemlQirGc2p2Uyp2ItolklpFoloFQdlkwTo1siq2Qro1slqmEtq2Aro1kgpFodqV8fsGYotGstrmUntWsrt20to1kYt28svnc0smoptW4tvHQ1uXEyuXExu3MyuG4st20ru3Evv3UzvnQyp10cq2EetGwlvHQsu3MrsGggpVwWmE4AmE4AmE4AmE4AmE4A////////////////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////////////////mE4AmE4AmE4AmE4AmE4As2ouvHE2smcqrWIks2gquW8vunAvt2wrrmIhsWYjrGMeq2MetW0qvHM0u3M2unM1wHs7vXg4vnY6t24yqV4jplofsGQpr2EmqmMlsWksrmYqpVwiq2IpqGIsr2gzs2w1sGs0snA84KFv0JNkxYZYtXNDpWAvlFAbl1YdnFkiqWQvqGMun1olpF0oo1wlnFYcnlgdoVshpmApqGArq2EunlQjm1MjqmQ0oVwqqGEtpVsno1kko1cglUsTpFwjrWUuq2Iusmk2rWIuolggp10hrmQkr2QmsGUnqmAhsmgouW8vplwcsWgovHQ0r2gps2wtwHg6unEzsmkrwHg4uG4ut20su3Evu3EwwXc3qV8eqF4btmsmu3ErunAqsWchqV4ZmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4A////////////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4As2ctvHA1tGgsql0htWkrtmssuW8tuGwrsWIjsmYisGQhr2QhsWcmvnQ2vHM3uXEzv3c4u3Q2vHY7uXA2qmEmql8ksGMor2EmqGIjtG4ypF0ipl0jrGQqrGYwq2MusWgzsGo0s3A746Vz7LCAy49gtHNDrmo5mVchl1YemFghqWcyp2MwoVsoolwnoFojnVccnlkcol0iqWIsqWEsrWIwpFkpn1cmrGc2n1kooVooqF8ro1cjpFkimU8XqF8ns2s1qF8rsGc1r2QxqF4np10ismgpsmcor2QmqF4fsmgovnQ0q2EhrWQkvHQ0tm8wtG0wwnk8uW8yr2Yownk6t20ts2kovXMyunAwv3U1tGkqqF4ctGklum8qu3Asr2QgrGEdmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AsmYsuGowuWwxr2EmtGgqtGgptGoouGsrtWYnsGIgs2UjsGMhrWEiu28yvXE2tWstwnk6wHg6vHY6u3M5sWgtrmQpr2MosGInq2UptnA1pF8kpV4ksGcusGcxqmAqsGcxrGYwsG873KFw77iJxIharW0+q2g3ol8ql1YemVghqmcxqGQvnVgjn1kknlgimlQcnFYdoVsjp2Itp2AsqWEupFsqoFkorWg3pF8tnlglqF8spVomo1gjnVMdpVwmt286pFsnqmItrWQvpl0lp18jrmUnsWcprGIkrWMktWwrvXQ0sWgnrGMjuXExvnc3uHAxxn0+vHIzsGYlwHU1vHIwsmgmtmspuG4runAuuW0trmEgtWklvXIuwnczrWIeqF0amE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4As2cttmswum8zs2grtWsssWcorWMktmsstWcnsWUjtGgmsmQkq10euGstv3M2s2gqw3k7w3k9unI5uG83smgvsGUrr2InsGImrmYtr2owoV0jnVkermYss2ctrWEormUssW01snI+y5Fg5at9xopdu3tLp2MyqGMunVghmVUdqGMqrWcvo14loFojnVchnVYinFYim1YipmItpF8sqmQypV8tolwqpV4sqmMxo10po10oolsnolgloVckp14quXA7pl4np2AoqWIpp2AmqmUpqmUprWUnrWQkrGQktm4uvnY0s2wqq2MitW0twXk5vXQ0wHU1vHEwrmMhu3Asw3gzt2wotmsntmsntWomt2ontWgkuGsmwXYxyH05r2QgplsYmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AtGwuuHAyu3Q0s2wstW0tr2YoqmEjsmoqtW0rs2sos2knr2MjrF8gum0uwHQ2uG0vv3Q2v3Y6unA6unA6tGkxsmctrmImsGMlq2MqsGsxpGAlnVgdrGUpsWYsrGAnqF8mt3I7tnVBwoVU26Bwy45fzItbsGw6qWQsoFognVccqGInq2YrpWEmn1ohm1YenlgioVsmm1UgpF4ppmArqmMwrWUzpV0rnFUjqGAuq2Mwpl4qpFonoVUjoFcjsGcztm04qGAqolokp2AoqmMpq2Uqq2YqrWUorWQmqWAis2srvXU1smoqp18fsmoqvnY2v3Y3uG4ut20trGEguGwpxHk1uG0puW4qtmsnsmcjsWUhtGkltmsnvXIuyH06uG0qql4cmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AuG8xt28vunIytW0ttGssrGMlq2EisWgot28st24rtGoqsWUmsWQlvG8wvXI0vHEzvHI0unE2unA5vHI8u3A4sWUrrmInsmUnp2AmrmovpWEloFofqmMnr2Ysp14koFketW82u3hCxIVT2Jtqy41dzo5bsG45pmEopV0jpV0hqWImrGYqp2ImoVwgm1YcmFMbpF4opF0no1slqGAqq2Iur2UzqV4tmU4dpFgnq18tploop1spo1ckolgksmk1sGcyrWUvn1chpV4mq2Qqp2AnrGctr2cssGcqqF8hrGMlunIyuXExo1sbs2srwno6wnk6uG4vtWorr2UltGooxnw4t20puG0puW4qsmcjsGUhs2ckum4suGwqyH06v3Mxr2MjmE4AmE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4A////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4As2kqtGwsu3MzuG8wtmstsGUnrmImsmYntWkntGkntmortWgptGgpuG4uu3AxuXAyu3I0uG80vHI6vHI6v3Q7smUrsmQpsmQppmAlrGgspGAkoVsfpV4hqWQppmIno10isWsxuHI8tHE9t3ZExYRSyopXoV8qp2Aop10jo1ofpVwhrGQpqmMool0im1YclVAYpF4oqmQto1wlqGErrGUwrGMwqF4tnlMho1cmplkop1korWAupVklo1omr2YyrGMvq2MtolokpV4msGkxp2AormgurmUssmkurGMnqWAit28vwXk5o1sbr2cnwHk5wXg6tWstsWYntGoqr2Ukw3k3tm0ptmwouG4qs2cks2cktmooum4ttmkpxns6wXY2r2QkmE4AmE4AmE4AmE4AmE4AmE4A////////////////mE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4Atmwss2oqu3IyuW8wtmstsmUpsWQotWcotGcmsmQktGcotWgptmortWsrtWwtuG4wuG8xsGgrv3Y7v3Q5um40tmkvtmgttmgtoFwgp2QnoFwgo1wfolkcp2UopGMnpWAksmowt283smw4pWEvw4FPxoVSmlgjqmMsp1wkpFkhpVsjqF8mqWEon1kgm1UelE4XoVslq2Yvo18mpF8pqGMtq2UxolwpnVUjolgmplspoFQjr2Mxo1gkolgktWw4rmUxqWEro1slp18ptGw2pFwmrmkwsGcvsWgvsGcsrGMms2orwno6qWEhqmMivnc3xX4/uG4wqV8gunAxr2UkunAvt20rs2omt20qum8tt2spvHAvuGwss2cowHY2wXc3r2UlmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AuG4urmQkunAwu3AxuGsts2QptGUqumostmgor2Ahs2Ums2YntGgpuG4us2oqunEyunIzr2covnU5wXY6um4ytmkuuGouuWswnVodpWIloFwfpF4hn1kbpGMmoGAjoVwgsGgttm00sms1pmIuwoBNzYtXn10npl4pp1woo1gio1kirGIrqmIroFginVUgl1Ecn1gkqGMtol8noF0mpmQtp2UvoF0plVAenFYkq2MwnVMhoFUjpFklolgktWw4sWg0pl0polkkqmIsuG86o1slr2kzsGcxsmgxsmgvrWMnsWcovXMysGclqGEfuHExwHk5tG0to1sbvXU1s2knt24rvXMxrmQiuG4svHIwtGootmwstmstrmQkuW8vxXs7tGoqmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AmE4AunAwq2EgtWsrvXIyumwutGQntGMnt2cpvGwtt2gptmcotGcos2couG8vtGwsuXExunEysWgpuXAyv3Q2um8xuGwuvG8yuWwwn10gomEkoV0hpV8jolsfp2Ypo2IlpWAjsWottGsys202qmYytXJA0o9cpGAspV4qp14qolklolklrmUwrmQwpVwonVQgmVEenlclpF8qoV0lmlghoWAqpGQupGMujUsYlFAeqmUynVcjmE8boVcio1okrmYwtGw2pFsnoFcjq2MutWw4o1smq2Qvs2k0smgwsmgusWYptGopuW8tr2YirGUht3Auvng1uHEuoVoXt28tu3QwtG0pvXUxq2IetWsqwHY2uW8vtWsrs2kpsmgosWcnx309s2oqsWkpsmsouHEvunMxvXUztm4utGwss2srq2MjuXExu3Exql0enU8PplgWu24ttmwsuHAwtGwsuG8xuXAys2otvXM3um8zsWQptWgruG0urWUltm4uuXExqmAfsmgnvXIyu24vtWUosmEktmYou2ssvm8wtWYns2UmsWUlvHIyt28vtm4uunIyr2cnunIyvnY2vHIzuGwuum0vtWcsn10gn18in14ioFofm1QZqWUpp2Qmo10fsWostG0ztG84sGw5qWY1x4NRq2Uzo1wqpl8roVoln1gjrGUvr2gyqGEro1oll08boFgkp2ErpmIqo2EqoWAqn18po2Mtk1MeklAcq2cymlYhmlQeoVkjqF8pr2cxtGw3qmEtolklqmEtsGczq2IuqGAstWo2sWUvsGUrsWUosWYmuW4qsmcjrWUgtW4rvXczvnczp2Ecq2UgxX85t3ErtG0psGgksWkmv3U1vnQ1uG4urmQjtWsqsmoowno4t28trmcltW4rvnc0vXYzvnc1tm4usGgotm4usWkptm0ut28vrWIjmU0NpVgWuWwquG4utm4usGcotGsuuG8zt24ytm0xt20xsWUqtWksuW8yqGAhs2ort28vrmYkr2Yku3Awu24vt2gqsGAit2cot2couWortGcor2Mkr2Qlv3U1u3IytWwsunExqmIit3AwwHg4u3EztmwuuG0vtGYrnV0foGEkn18jo18kmVMZqmQorGYpolwdrGQnsGowrms0rGk2sGw7wHpLsms7oFkmol0noFslm1YfqGMsrGcwolwlpFwlmFAZn1YgqmIsqGIrrGYwol8qnFoloF4pmVgimFYhp2QulVEbmVMdpVwmqWAqr2cxrmYwrmUxo1omq2IusWg0rWUypFwpsGUxsWUvtmgvtmkrsGMitmoltWkkrmQftW4puXIuvHYwr2oipF8Yu3Uut3Eqrmgjt3AssmoouG8vvXI0t24usGcks2oor2ckvnc0vHUyq2QhsGkmwXo3u3QxvXYzunIyq2QkuHAwuHAxuHAytW0trGMjnFEQpFcVt2onvHIxtGwsrWUlsWgrtm4yu3E2tGsvt20ytWkvtGgutmwwpFsetWwuvHQ0sGknsGcluW4tvG8vuWsrsmMjtWUmumorumsssmUmr2QlrmQkuG4utmwst2wtu3Awr2Ymsmwrw3w7u3M0s2kruW4wumwxmlkcoF8ipmQprGgun1gfqmMprWcqpV4hqWMmrWguqWYvrGk2rmo6w3xNq2M0o1wooFsjoV0knlogpmEnqWUqnFccnVYcmlMZn1gerWYuqWEsq2Qwo18qomAqo2EsmlcimlgiomAplVIcm1YgplwoqmAsr2YyqWAsrWQwqWAtqWAttGo4sGc2qGAur2UwsWUutmowuGstsGEgsmQhvG8ssmcir2citm8rtnIstXEqpF8YrmgiunMusGkktm4qtm0quG4tvXQzt3AtsGklsWklq2IeunEtwXk2rmYkrGQjw3w7tW8su3UzunMzqWIitW4uu3Q1uHEyt28xsWgqoFYWplsZsmcjvHMwtm0sq2IkrmQot20zu3E3sWcttGovtmowt2wwtm0xqmMmsWgpvnY1tWwqsmgmum8tvXEvu20rtWYms2Uktmgmv3ExtWgpsGQmrmIjuGsstmoquGsswHM0tWsrtG0tvHU1tWwus2krtWotu20yl1IWn1kfolwjqGIpo1wjqWAmrWQqologrmcts241qGUtqGUvq2g1uXRDqGIypl4qo1wipV8ln1kfpGAmqmUqnFYbnFUanlYboFgcrmcuqmQwqWQvol4poFwmo2Apmlchl1UeoWAqnVsmmVUhql8vq18urWEwpFknrGAvsWg2plwrs2k5smg4rmQzsWk0rmYvrmQrum0zsWImsmQkum0rtGonqGAcsWwnt3QwsGwool0Zq2Qhv3YysmgktGomt20pt20pvnQwu3Itr2ggsWggqmAYtmsmx307tWwtrWYovXg5uHIxu3Q0vXQ2rGUmsGopt3Iys28vuHM1s2stoVgZpl0ar2YhuG4quG0rsGQmsmYrt2oxuW0ysGUps2oss2ottGsvuG8yrWQlrmQkum8tvXAttWglumwpvG4ruGwqsWUlsGYjs2glvnIxuWwusmQnsGIktmgouWwqumwswnM1uGosuG4uv3Y4t24xsmksrWQoum4zm1UanlcdnVcco10ipF4jqGAmrWQqoVkfqWMosWwzp2Msrms0sGw5vHdGrGY2sGg2pV4noVsjoVwkpmEpqGMqnlkfm1QanFYbn1cdqWIpqmUwrGgzpWAqmlUfo14nmVUfm1ginVolo2EsmVQiqV4urGAvq2EvoFYlqF4ss2o4pFsqsWg3tGs6q2MwrmYxrmYurmUstWovs2YpsWMltmkptmspqmIerWcjxH47s2wro1wbpl8cwng2s2kltmsns2gjuG0ov3QvwXcxr2YgsWcfql4XsGQfxXo4vHM1sGkrunM0tW8uvHQ0vXQ2rWUlsWspuXQytXEvvHg4unM0pV0cpFwXsWkiuW8qt20rs2gqtWkut2oxtGgtrmMmt20vtGoss2gstmwvrWQksmcnt2spwXQxu20quGonu20rvXExsGUmrmUjs2smuW8tu24wtWUor18hs2UluGooumwsvW4wvG0wuW4vxXs8vHI2tWwwplwht2wwnFYbnVcbnFYaoFoep2ElrWUqrWUqpV4jpF8kqWUso2Aoq2cxtnE/uHJCs209u3VFpmEunFcjoFwnq2YxqGMtn1okmFEbl08Zpl4np2AqqWQurWgyqmQum1UfolslnlgipmAroV0ppGAto10roVYlqmAurWQyoVgmqWAutGs5pFwpqWEusms3qmMvr2YwsWcwtGoxs2kusWYpsWYmtGkouW4rr2UhrGIfvXU0t28wqGAgpl0cwHY0tWonsWQhs2Yht2wlwHYvwngytGsmsmchrmIcrV8cxnk4v3U2s2wttW4vtW4tt3AtvXQzr2cltG4quXMvs24rvHY0vXc1rWQholkTtGoiunEstmwquW0wuWwytWgvt2swsmYqt2wutmstsmYqsmgqs2oqs2kotWknum0qvnAtu20qumwsum0usGUnqV8etGsnuW8ttmkquGkrsWEjsGEhtWclumssu2wuvW8xvXIzw3g5v3Q3unA0qV4jsWUqnlgcnFYamlUYnlgbqGMmrWYqsmsvpmEloV4jpmQqol8nrGgysm47tG8+vHVGtnFArmo4oFwqnVknqWUzpmIvn1omm1Ufm1IepVsmrGMuqGIsqmQupmAqm1QenFQeolokpmArolwppmEvpV4sm1EfpVwqr2Y0o1sprGMxsWk2pF0ppF4pr2k0rGQvsWYws2cwtmsztWswq2MktWwrsGcksWclrmMfr2MgvnQzuXAxq2Iiq2EhwnY1s2YjrF8bsmUftmoiwHUtxnw2smkls2cjtGYhr2EdxHg2wHY2tm4vtW4tuXIuunIuvHMwrmYjt3AsuHIusWsnunMwuXEvrWQhpl4YqmEZvXQvu3EwuG0wvnE4tGcutGgts2gruGwut2susGQorWMltm0ttGoouGwquWspwHIvvW8tuWsrt2ostGgsqF4drmUhunEutmoqs2UntWcnsGIgtWcluWsqvGwuvW4xv3M2w3c6wnc7vXE2sGQprGElo10hnlkbn1oboFscpWAhqmQotW8zqWQonFkcpGInqmcur2w0tXE8uHNCvnhHrmo5xIFQr207n10rpGIwo18tm1YjnFYhmVAbo1okqmIspV8prGQupV0nnlYgnFQeo1smp14qpF0qqmMxpl8tmVAeoFcksGc1pV0rrWY0smw3qGItqWMtrmgyqWMrsGQws2YwtmszsGcrpl8gtG0qr2cjsWYis2UirF4bwnc3w3k7q2Aiq18gwXQzsmUjql0Zr2Idt2sjum8myH84unAurWAdsGIetmgkwHMxvnQ0uHAwuHEuuXIvvHMwu3Ews2kotm4rt28stGwqvXQ1uG4vsWYlrGAcp10Xt28qvHMzt20wtmowtWgvtmovtmotvG8xtmgrr2Imq2Eis2opunAtt2wos2UivnAtvnAvuWwtvHAzuW4zrmQksWgkuW8tuWwtsWMjtmgns2UjtWckuWspvGwuvW0xv3E2w3c8v3M4uW0xtmsvsGUnpmAkoVwdoVwdol0eol0fp2Elsm4xqWUon1wfp2UqrGkvsm83tHA7tG07tW89tXJAx4VTsnE+omEupWQvoV8qmFQgmVUel1AZpFwkqmIsnlgjq2MupFwmnVQeoFYgpVslqWAso1onrWUzqWEvnFMfnFMfq2MwqGEvq2Y0sm46rWgzpF8pq2Uupl8nrmQvsmYxt2w0rmYppV4esmsps2sorWMgtWcksGEfwXU1x30/rGAiq14fwHQyt2onolURqFsWtWkiunAnwngzwXY1rWAerF4buWsow3c1wXc3uHAwt28uvXUywXc1vnQ0uG4ut20ruG4tsWcowXY5uW0wsmUnrmIgq2ActWwou3IxtGksql0ktWgvuWswum0wvXAyt2orsWQmrWIisGclt20rtmsnq10atGYku24tum0uvHEzuW8ytGsqs2oltmwpt2srsGIismQis2Uit2kmuGoouWsru2wvv3E2wnQ5wXU4uW0wt2wvsWYop2EloFseoFsepF8iolwfpmImr2ovqGUpomAjrmwxq2kusG00tnE6rWYxsms3tXE/woBOsnA9o2EupmQvo2EsllQemVYdmFMaqGEorWUvoFolrWYxpl4oolkjpVslqF4oqmArolklqmEtqF8solkknVUfolsnrGczrGg1sG05sGw4oVwnqWMtpF0nr2UxuG45t241rGUooloap2Aer2cjrmQhsWUitWknvnQzxn0+smcnrWAhvHAvvHAtn1MPqF0Xtmwkt24mvHItvnQzrGAep1kXt2kmxno4xXs7unExuXExv3Y1wHY1uG4vtWsrvXMytmwsql4hvXE2vW80sGMms2Ymr2MguG4qu3Evum4xq14ksWQpsWMntmkqu24uum4stWgpsGUks2gmtGkmt2snr2Ies2UiuWwqvHAvvXIytmwutGsptW0os2kmtWkotGclrmAesWQgtmgkuWoouGkpu2wvv3A1wXM3w3Y4vnIzuW8utGkppmAkpF4joVsgo10ipV8koFshrWkurWkuqWcrsG4zp2UqsGwytXA3qWMrsWk0rmo3xIBOvnpInVsopmQxpmQvm1kjmFUemlUdpF4lr2kzolwopV8rqWEtolkkqmAqqmAqplwmpVwnpV0op18qpFwlnlchoFsmrms2r2w5rWo4tXE+pF8roVompmArsGk0tm85sWkwq2MnoFgYpl4br2YirmUhsWYktGknvHQzwHc4uW8vsGQksGQjvHAtoVYSql8auXAptGwkt28rvXU1q2AfqVsZtWglx3s5wnk5u3M1u3M0u3Iyv3U1t2wts2kpvHIxt20tqV8guW4xv3I2smQns2YnrWIft20pvnMxv3M0sWQosmQor2IksGMjuGwqunAtt2srs2gnuW4stWgmtWcksWQgs2Uhum0pum8svHIxuXExsmootW0otGsnsmcktGclsWMgq10ZtWgkv3AuuWkqumotvW0xwXM1wXQ0u28uunAttWwppF4jolwhpF4jpmAlqWMonFcdpmIotnI4p2UqsnA1qGYrrWovtXA1o1wiqmIstGw7y4RVxH5OnVkpnFkorWs3oF0omlYgmVQenlkipV8qo10roVooqGAsoVkjpV0nqWAqpl4ooFgiolokqGApn1gfn1kjoVwmsW47r2w7qGU0rms5p2Mxnlglq2Yxrmk2tG86r2kwqWEkolkYqmEesWcjsGcjqV8dsWonv3c1vXU0s2sqrmQisWYkwng0qmAcplwXuXErr2chsmsoxHw8qF8drGEduG0ow3g2wHc3vHU1vnY4vXM0vnQ0unAvtWspvXMwt20rsGYmtmstu28xr2Ijr2MhrmMft2wownYzv3IytWgqtmkrr2IjsWUitWomuXAttmwqs2knuW4stWkntWcksmUgt2slum4ouG0qum8tuXAusmomtW0otWsosWYkuGoosmQhp1oUsGMeumwpvW4vuGgrvGwvwnM0xXg3vHIutm0ptm8rpF4iolwip2Ampl8mpV4lmlUcpmIptXE3ol4jq2gts3E2sW80tHA1olwho10jsmo4y4RWwXxOoVwumFUkq2c1pF8tn1olm1YhmlUgo14qolwro1wqrWUxpFsmnlUfpV0nq2Mupl0po1smpl4omFIamVMdol0pr2o4q2c3pWExrms6sGw6o14rqWUxrmw4rms1qmUspl8hoVgXrGEesmgkr2cjqWIftW4rv3Y0unEvsWgmrmQitGonx346smklqF8buXEstGwnsGklxH08r2UirWIeum8rvXQwv3c3vnc4u3I0vnU2u3IxvHUxt3AsvncyunEtsGYksmgot20tq2EfrWMfrmMetGgkwnUyw3Y1uWwutmkrsGMisWYjsWgktGsntm0qtWopuG0rtmsos2UismUhuGwluW0mt2wntm0pt24rsWkltW4ouHArtGkmt2omtGciqFwWrmEcuWoovW4vvGwwu20wv3EyxXc3wHQxuG4qt28sp2Iko10hp2Eko10ioVsgnFYcqGEotW40qWMnqGIntHE2sG00tHI4pGEmnVkdqGQtwH1Ly4lbpWQ3nVwupmMyqGMuol0ln1chnVQgp14sol0ppF4prmYxp14pnVMepVomsWUyr2Qyp10rpFwqmFQfk08bol0sq2Q2qWI2oFotsmw+tHA/pGEtomEqsG84r2s0qWMqpl8hpVsbq2Ees2omsGcjsWontW0rvXIuuGsotGcksmYktmsox3s5vHAurmMgum8quG0osmckxXw6tGgmql4bu3AsuXAtu3UzyIFAv3c3v3Y3vXU1v3g2unMwvXYzunIvsGYktWoouG0rql0bsWQisWQismQivnAuwnM1vXAyt2orsWUjsmgjtGsnsWgktGootmsnt2snuWwntGcisWQft2oluGwmuW4puG0puW4rtGsmtW8ntG4nsmkjtmoltWgjqFoXrl4evm0wu2kvv282um40uWwxv28zw3M2vm8yvHAzqmUmo10fqGIlpV8joFofnlgfqmMqs2wxq2MnqGInunY8r240s3I4pWImnVkbp2UruHhD2ppqs3VHnl4vp2Yyrmkxo1whoVcfoVcipV0ppmEspV8qqGErqF8pnVMdnlIfrGAusGU0qV8up18vn1wplFEgpmExqWM1q2U3mVIlq2U2sm89qGYxnl0msW43sGw0qmQppl4ho1obplwas2onrGQgs2wpuHAtuGwpvnAts2UisWUjvHAuwHQyv3MxsWUjuWwptmglrF8cw3g2uW0rpVcVum4quG8rsmsoxH48v3g3u3IyvXM0xX09u3MzvHQzwXg2smgmuW4suW4sqFwasWYks2clrmEfvXAwvG8wvnEzuWwts2ckt20ouW8qr2YismcltGkltWgjuGsmsWQfrmIdtGkktGgjum8quW4qu28suXEtsm0nrWcgrmYfs2kjt2smrF0bq1wcvGsvt2Usv283uG00vG81umouwXA0wHA1v3E4qmUopmAkp2ImqGMnoVwinVkhqGMrsWovrWYrqWQps3A2rmwzqWcto18jo14gqGQqtHM90JBeunpKmloopGMtrmowo1sgoVceo1kiplwoq2Mvolwnpl4opVwmnFIcnFEdrGEvrmQypFsqpV0tol4smlclpmEwq2U1rWc2l1Egp2IwsW46rWo1oF8prGkyrWcvqmMpqGAkp10folgXrmQhqWEds2wpvXUztmsovXAttGcksmYkvXEvuW0rvnIwtGgmuGonumwprmAetGknvnIwq14ct2sovnQwt28swHo2xH07tGwru3ExxHk5wHQ1v3U1wHU1tm0ru3IwunEvqWAdsWgmtGspsmglwHUyum4uum4vt2sqr2QguW4punAqsGgitWomr2QgsWQgtWkksGMerGEcs2gjsWYhuG0oum8ruG0rtW0qtW8qsGkkrGQfsWcitWklsGMgrmAfumwtumsuu20xuW4yv3I1tWcpvW8yvXEzwXc8p2ElpF8kqWUqpmInoFwin1wlqWUtsWwyq2Uqp2Mor2w0tHE5r2sxp2Ekpl8grGcqs3E5wIBMuHhHn14tn10nrmkwo1sgn1UbpFkjqmAqrmUxp10pm1Mdpl0nnlQfnlUhqmEtrGQxoVopnVcmp2IxmVUkpWAuqmUyqWMvnFYhpmAssGw3q2cypmMurGcyrmgxrGQrqF8kq2Iko1katGooqmEfsmsovXYztWwovHIuum8rsWUjvHAuuGwqum0ruGont2kmumwptWgmtWopwHQyr2EftGYjvXMvvXYyw305w3w5uXEuwnc2x3k6wXM0wHQ1wnc4t24ttW0rvHUyrmckq2UirWcks2omw3k2sWcmunAvt2wprWIeuG0mtmsks2gjum8rsmcjrWIesGUhtWolsGUgt2wnr2Qftmsnu3Iutmwqtm0rtm8stG0qqF8cp10Ztmsmsmcjr2QguGwquGssvG8wvXEzuWwtsmYlsWcmvXU2v3k7olwhoVwhqGUro2AnnFshnlsjqGQsr2oxoFwhoF0kqmgxsnA5rmszqGImqmEjsWwvtXM6v35Kvn9OrGo6nVomrGcvpV0koVYdplwmrmMvr2UxqF4qnVMdo1oknlYgo1olqWItqWIvoFoomlQjqWQynlknolwoqGMtqWQtpF4np2Qtsm44qWUwq2g1qWQvrmYwrGMrpl0irWQnpFkas2kos2knrWYjunMwtm4qvXMvwnk1rWMht2spuW0rtWgmvW8tu20quGkmt2kouW4uvXAwr2AfqFoYt2onvnUxwns3wns3wHc0wXc1w3c4v3Q0wHU1w3k5unIxtW0suXIvsmonq2MfqV8br2chwHczrGMguW8tsmkmq2AbuW4ot2wluG0ou3ArtWomql8brGEcsWYhtmsms2okqmIcsGcju3IuuG8stmsqt20ttGoppVwapFsXs2gktGkksGUgtWkluG0rwHQzvXAwuGwqsWckqWEevXc1vHg5nVcdpmAnp2MqpWMqm1shmVcfpWEpsm41oFsjmlcgqWcytHM9sm84qGEnq2MmtG4zs3E6uXhGzYxfu3lLmlYlqWMuqF8opFkjqFwprWEvr2QwpFkloVgiolokm1Qeo10nrmgzp2Iuol0pn1koqGExpF0rnlgkpmAppmIopmEnrGYvsm03pWEtr2w5pmAsqWAqrmQtqWAnrmUpoFYYrWQjuXEusmsouXIvunMwtm4qwXg1rmQis2knuG0rql4cuWwqu20qumwptGcluG0tv3EwtGUjolQRs2Yiv3Uwv3gywns3wHg0uXAtvXQzu3MzwHg4xH09u3Q0uXExuXAutmsosmcjplsWsWgjv3g0rWUhtGonr2YiqF8avHMsuG4nuG0ovHEtt2woql8cql8arGEct2wntGolqF8aqmEduXAsvXMwt2wsum0vtmkqql4dqmAdtGsmsmkjsmkktWoltWomvXIvvG4tum0qsmgkq2QfuXQxu3g3oFkgpF4lpF8mpmQrm1shnFohqmYtt3M6qGUtmFYftHM/wYFOu3hEq2YuqmMosWwysnA6unhHzo1gw4FVmFUmqWMwq2IuoVckql8vrGEwrWIvoFUhnFMeoFgimFIcn1kjrmkzq2cxqmUxpWAsqmIxpV0rnVYhpV4npmAmpmAmrmgxsm03p2Qvq2c1pl4qplwnsGYwqV8nr2YrpVwfpVwduHEvtW4rs2wovHUxtW4qs2sntGooum8tv3Qyql4ctGglsWUivXEts2gltGknv3EusmMgpFURsWMewHYwwHkzw3s3w3o2t3AtuXQzunU0vXg4wXs7uXMzuXExu3AvtmkmtmckqVsWs2okvncyrWQhsmgmr2YipFwXvXQtt20otWsmuG4qum8trWEeqFwZrWEesmcjtWomrGIdqmAct24qvnQxum8uum0wt2osrGAfqmAdtWsnsGchsWgium8qr2Ieu24rvnAuvW8sum4qsGgjuXMwvXk5oFggoVsipmIprWsxoGEmqmcuq2YtrWkwq2gyn10p25xq15hnx4dVrWo0o18mq2cus3E6u3pIwYFUw4JWp2Q2o10sqmIvpFspp14tql8vr2Qxo1gkl08aoFkjlU8ZlE8YrWozqGQvp2ItpV8qpl8sqGAsn1chpV0npl4noloksWo1s245qWYxqGQxpl0pplonsGYxq2EqqWEmqGAjolkasGkotW4rrGUhuHEtt3AsqWIetGoowHQyx3s5s2cltmoos2gkv3QwsGYjsWYkvG8rtWUiqlkVrl4axXk0w3o1wnk1w3o2v3g1vno5wH08vns7wHs8vHY3tm8vuW8usGMgtGUhrl8atmsmvHMvrWMhr2UksWclrGMftW0ntGwmtWwot24su3AvsmUjqFsZrmIetGklsmcjrWIdqF0ZtWsnvHIvum0tuWsut2orr2MiqV4bsWYisGUgsGQfum0pt2kluWspu20tumwqvXEttWsntW0runQ0oFginFYepmIprGswpmUqrWkwp2IppGAoqWcxpWQy36Jz0pdo05Zmt3ZDnVslp2UqtHQ6s3NAuXpLxIRWrmw9o2Atq2UwrGQwqmIwqmEvrWIvolklmFEcp2ErmFMdllMcq2gxpmErqGItqmMuqmEtrGMvoFcjolklqF8qpl0os2w3tG86q2cyqWQvp10rplsoq2Asr2Uvpl0krWUpolocrWUltm8spl8btG0puXIusGkltWspwHUzw3c1tmootWspuXAsvXUxqmIermQgu24pt2gkr14asGEcw3cywnkzwno1wnk1wXg1wns6xX8/wns8w30+vnk6t3Awu3Mxs2cksmUgrmEat2wnvXQwtWsps2kos2kns2omtm4ptWwntGsnt20su28vtWYmr2EfsGIftGgksmcjrmMfql8btGklu3Ast2oquGkrt2oqsmYlqV4brmMeql8arF4atmckvW4suGkouGostmgnvG4rum0qtmspu3MzoVkjmVIap2Mprmswrmswq2Usp2Eoo14mp2Uwq2s5zI9gxIla05dny4tZoWAqpGQps3Q4rnA6t3lIzY5fsXFApmQxqWUwq2UwqmMvqGEuqmIuo1snlU4ZoFwlmlcgmlcgqWUuqGItqGAsqWAspl0oqF8qolklo1onqmEuq2IwsGg2sm05q2cyqWQvpl0qplwpqWArsWgyqV8nrGMop14grmUltW0ro1wYsGkluHAstm0ptGknvnIwwXUzuGwqt20runIvvXYyqmMfqF4ZtWkktGUftmYfsmQdvnItxHo1xHs2xXw5wXg2xHs7yH4+xn4/x4BBwHk6t3AxuHIwt28rtGwmsmkht20ou3AtuW4stWsqsGYms2omuHAstW4qsWonsWgnum0utmcnsGIgsWMhs2Uis2UisGIfsGQgs2gku3Ast2opuWoquWwqsmckq18bsWUgr2IdqVsXtGQivGopuWkqu2wvuGoqumspvW4rvG4tvnEzpF4nm1YgqWQtsGw0sWsxrGYtqmUtpF8pqmcztHNAu3xJq205tnZBy4lTqWUvp2MqtXI5sW85r249x4lYu3xMrGo5pWEuqmMwqmMvq2UvrGgypmIqk08XmlYen1sjoV0lqWMtp2ErpV4pqmMuo1skpFwloVghpFkkq2ArrmQvr2YzsWo4rGU0qGIwpmEspmArq2UvtW44rWcuqGEmqmMmrWYmsmopoloWr2UhvXMtt20ns2civXEsw3YzvW8tt2souG4qwHc0r2UgolcRsWQdsGAaumojtmcgtmkjwnUxv3Qxwng2xHo5xXw8x34/vnQ3xHw/wHg7smkstGsrunItt28puHApt3Aqt3Aqt28stm4srmUjsWkmuHAtuXAvsmgpsGQmumssuGkosmMhsWIftGUitGUir2EesGMgsWUiu28sum4suGspu20rtmkmsWQgtGYitGYiqFkWsGEet2kmumsqvm4vu2ssumsru24uvG8wu3ExoV4nl1MepF8qs204s2w1sGoysGw0o18qrmw4uHdDsnI8pmYurWwzyINKtG03pV4mtm83tG87tnRDzIxcxIZXsXFCoF0tpF8tqmIup2EsqmgwqWYtmVUdmlYeoFoipV8orGYwqWMuolsnp2EspV8oo1wkoFcfpVsjrmMsr2Qvr2UxsWg2rmc2qWQzp2QwpWIrqWUutHE5rGcupmAlrGUor2gprmYlolkWrWMev3Mtt2sltWkjvnIswHQvvnEtt2snsmYiv3QxsWYhoVUNrV8Xr2AYuGkgtmggsWQdvnIswnYzvnMxw3k5xHw9xn0/tm0wvXM4v3U7sGUos2kpu3IusmojtW4mt3Ers24osm0otW8rqWIermYkunEwuW8vsmcor2IktmYnuGgntmYlsmMgsmMgs2QhsGEermAesmUju28tum8ss2cjuGsoumwps2QhtWYktGUjrF4br2Eetmkmumsqvm0uvGssuWorum4vu3Exu3ExpGArk04ZoFsmunU/tW85sGw0sm83qmcytXNAu3pGpWUuoWEopGIpvHc+vndArGUtsWw1sW45uHhFyIpZzY9gyopcqmg4pWIwqGIvpWArqmcyq2gynlkjmVMdoFokq2MtrmcyqWIvo1wqq2Qxo10no1wmo1okp10mqmAqqmErq2IurmUyrGYzqmUzqWUypmItpmItsm84rGcvol0irmcqsGgprmYlpl0ar2UhuW4qtGkkrWIdt2wnvHItv3QwuW4qrmMfvnMvs2gipFkPq14Ur2IXtWgctWgds2YdvXAow3cyt20pvXQyw3o8x35AvXQ3wHc6wHg6tmsttGopu3IusWkjs2kjtG0ms20ntG4ouHErrWYhsGYktWsqtmwstGoqrWEhtWcnt2cmt2cmtmUismEdtGQhtWYjtWYjtmgmu24suW0rtmootmoouGoosmMitmcmtWUkrl4drV8dsmQitGUjumkqvGwst2kqu28vvXMzvnQ0qmQwl1EcoVwnv3xFs3A5p2Usr2w0rmw2s3E9vXtGpmUuoWAmomAls241uHM8tnE5sm83rmw3sXE+vX9OxohZ2ZtrtnZFo2EvpWEvpGEuq2g1rmo3pF4pmlQfnlciqmEtrGMvqF8spl0srWUyo1woo1wnpF0nqGArqGAqo1slo1smqmItpF8rrGc1rmk3pGAtpGAstXE7rWcxoFohrmgrrGQlsWgnpl0arGIeuG8rtmwpqF8br2Yiv3YywHczvHIutmsnvnMvum8oq2AVploOr2QXuGweuGoetWkevHEnxXszvHIsvHIwxHs+xn1Bwnk8wnk7vXQ1um8vvHIvu3EttGoltGkktWsltGsltm4ovXUvr2Yir2Yis2onsmgmtGoor2Qit2kouGcltGMgtWQhtWQgtmUhtGQgt2glumspu24ruGwrtmwrt20suGwrsGMht2gnuWkoq1sarV4cs2MitmYluWkot2kosmUkt2wrvHIyv3U1pl8tmFIdnlkjt3Y/rG02nl8lrGszqmgyqWcyuHZBq2kxomAnol8lsGsytG44rmkyrms1qGczrG05unxKxolY36FxyotbomIxoV8up2UyrGo3sG07qmYyoFsmmlMeo1slqGAqqWArq2IurmUypV8tn1sopF4prmcyq2QvnVchm1QfrGUwnVciqWMvsms5pV8to1wqtnA8rGYwolsjtm8zrGQksGYkqV4aplwZuW8tt20rpV4brGQhvnYzuHAsuXAstGwmuW8qt2slsmYcoFQJr2MWum4huGsftmoetmohyHw1w3o1vXU0xXxBxHxAwXk7wno6uXEvt24rwXg0vHIusmcjtGklu28rtWolsmciwXYytmsnsWcitWsnr2YitGsnsWcjtWglt2clsmEetGMftWQgtmUhs2MfumsnvG0qu24rum8tsmkpuG4ut2wssWUluGsrt2gorFwdrFwdsmEitmUluGgmtWcksGMhs2gmu3Ewv3U1oVwrnFYhnlwlsnM8qm44nF4lrGwzq2ozo2EstXI8q2gvol8lo18lsGsytW85rGgxsW84p2YwrGw5tHdFwINR251s2pxstndIoWAyqWg3qmk2r245sG03pWArl1EanlYeolojqGApr2cwsGgzpV8tnFclpF8ssGs4qmUym1cinFcis204nlcipFwnsGg2qWIwo1wqsms5qWMvoVsjuHE2rWQlqmEdqV4apFoXt20rtGwrolsZqGAfwHg2t28suG8rtGokuW8osGYetGohqF0TsGQZtWketmofuGwjr2Mcw3g0xnw5u3M0xHtAw3w/w3s8wno5vHUyvHMvwnk1v3Uxs2gksWYiu24puWwnr2Meum4pv3QvtWolsmgjsmgktm0psGYitmgluWonsmIetGMftGMftWQgs2Meumwntmcktmglt2wrs2sruG8vs2kptGgpum0utWYnsmIisF8ftGIitWQjtWYjtmgltWkmtmspunEwvnY2nVknn1kjoF0msHM8p2w1lVggrG00tnU+pWItsW83q2gvpWEmpGAlsGszt3I8sW84snE7pGMupmYyrG06rXA+3aBu2Ztsz5Fjpmc6oWIzq2o3snE9tnU/o2ApllEan1gfn1gfolwir2gvsWozp2Eun1oooFspq2Y0pWEunVklm1YhqWMtn1gioVgjrGMwrGMxqWEvtG05rWcxqGMqtG4zq2Mkpl0aq2AbpFsWvHMwt28upV0cpFwcvXY0tm8rt24qtGkksGUerGIbtmsltGggsGMbtGcfuWsjtmkirWAcum4sx349wHc5xn5Dx39CxHw9vnY2u3QxvXUww3gzv3QvsmcjsWUgt2sku24ns2YgvXEswHUwtmsns2kksWcit24qs2omt2onumwptWYitGMftWUgt2YismIetGYhs2UhtmgltmsprmUntW0tt20tuG0tt2ortmgorV0cq1oZtWMitWQitGUitWckuWwquW4tunAxu3Mzo2Aun1oknVoivH9Ip243nmMqq200unpDpmQuqmcwqWUrpmImp2MosGoyunU/v31HsXA6pmQvpGQuq2s4llclwYRS2Zts3p9ywIJWqmw/qmw7s3RBtHQ/o2Erm1chnFcfn1kfo10jsGkvsmwzq2Uyo14spF8tqWUzpmMwn1oom1Uhpl8pnlUfoFYgp10nqWArrmYyt3E8r2kzq2Uts20yqGEhpVwZqF4ZqmEbwng0u3EvrGUirWYlwXo4u3Qxtm0psmYhr2IbqFwVtWokuGwlqVwVsWMcvW8os2YfqV0Ytmspw3o5u3M0xHw+x4BBxHw9vnY2t3Auu3IvwXczvHEtsGUgsmYgtWoit2sjsWUeum8qvXItuG0punAssmkltGoosmgmtWkmtWgkt2kktWchtGYgtGYfs2UfsWQes2YhuGont2wpr2cmsmoqt20rt20rtmwpuG0qrF4bpVcUr18ctWQgsGIfs2Qium0sunAwunEzunEzrGw6oV4mmlgfxIZQvYNOs3g/uXtCu3pEr203qWYuqmQqo18jqGQorWgvsm44snA7rGo1qWcypGIts3M/mFkmqms52Jpr15ltx4pfu35TpGg6tHVGsHA/pmQxoF4pnFchoFojpl4nrmcvrmYwqWIvolwqqWYzp2Uyp2QynlknnlklqmIunVIenlMeplwlq2Irsms0t3E7q2gwpmIosWswq2Ijpl4aqF4XrmUfwHgyuG8rqGEes2wpw3w6vHUyu3Its2chr2QbqF0UsWcfuGwjqFsSrWAXvXAntmkhpFgStGsmxn46uHEwu3U1xn9AxH0+wHg5vHQ0vXMyv3Uxum8qrWIbrmIauG0lt20lrmQdum8qvHEsuW4qvHIvtWspsmgmq2EfsmcjsGQftGchtGggtGcfs2UetWghtWghtGciuGwntmsos2kns2knunEts2onsWgktmomsWQfqVsWrl8ar18brV4bsGIfuWwsuW8xuXAyuG8yqGs5oV8nmlkftHZAz5RgvoNLu3xEs3I7q2gxq2YurWctqmQpp2Inrmoxr2s1q2k0tHI9qmgzrGo1tXQ/pWQxnV0sxIZX0ZNnxIZez5Foqm1Du31SuXlLqmg5pWExnlgmnlckoVomq2QvqWMupmAspF8tqWQyqGQypmIxoFspo1wqrGIvo1cjnVEco1ggsGcut3A3tXA4q2gvp2MoqGMmqWIipV0YplwVrWMcvXMttG0opF0ZtG0qwns3tm8svHItt2skrmIZq2AWrmQatGkeqV4SqFwQvXInum8kp10UsGchw3s3uHIvuHMxxH09wXo6v3g5wXg6wnc4wHQyvHErsGQcrWIYv3UtuXEps2kiunAruG4quG4qtGsos2knsmgnq2EgsWcjsGUhr2MesWUdtGggtmois2Yet2sks2ciuW0otWomsWcksWgku3MttGwmsGgismkjsGYermEarmAZqlsWr2AdrmAetWopuW8wunE0uXA0r3NBnF0lmFkhomQuxYhUvoFMtnZBrWs2qmYvqGMpq2UprGYqpF4iqmYsrWkxvHpFs3M+qmg0r2w4undDqWYznVopuHdJyotfwIJZzI9nqm5EtnlOvX5St3RHrGc4nFUkmlIgn1klqWQup2Mto18qqGMwo18sqGMwqWQwo10po1smrWMuqF0omU4ZnFIarGMqtG42tHE6qWcvqWQrqWImqmEhqV8aqF4Wr2YdvXQstGwlo10WsWokwXk0uG4ouW0lt2sisWQZr2IYrGIYsWYbqV0RolcJu28iuW4ipFoRq2Icv3k0v3o3vXk3wn08wXo6v3c4wHc4vnQ1vXIvuW8rsWYeq2AXunAnuG0mtGgjv3MvuW4quW8rtmsptmsptGonr2YitGwlr2YgqmAcrmIesWQgtWkhr2QauW4ktWoium0ouGwos2cjrmIftmomt24otm0ns2slsGcgsWYfqF0Wql0YsmUisGMhs2gounAxvHM1vHM1tntJkVYelVkgnmEqx4pXwYBQsW49rGg2r2k0qWIqqWEnqmMnoFoep2Inq2cttXQ/rGw6pGIvrWg2u3VCtG06o1wsr2s8vXxQuXpQy41iuH1QtntOvn5RyIRYsGo8olkpnVQin1kkqGMtqWYvol8rp2Mvnlsln1wmrmkyqGEqpV0mqWErpVsmmU4anVMcqmIqs245tHE+rGk1qGItqmEnqV8fsGQfrWIZrGUbvncuuHEoqmIasWkhwHcvvXMqtmogtWkdt2oduGsfrWMarWIYsWUZolUIsGQXtWofqmAXsGciwns5wX07wX08xYBAxH4+vHQ0vnY2vXQyvXQwu3IttGskrGIauGwkuWslt2kkv3Atu20qu28tum4rt20otm4os2sjtW8krWYeqV8crGEhrWAgsWcfrGIVtmwft2siuGomuWoouGkmtGYjtmkmt2wotWsmtGwmsWkjrmYgqmEbqWAbsWclsGUjs2kou3ExvXMzvHIyu4FPmFwmm18nsXQ9xIhVv39PsW8+qmc1rmgzr2cwr2YsrmcroFoeqGIntHA2tnVAsXE/oV8srWk0uXI9t247q2MxsGo6uHVHwYFUzZBkyo5ivoJVtnRIxYFUuXJFqmIzmFEgnlompWIspWQupGIvomAtnFkkm1cirWozqWMtpFwmpl4ppVwomE8Zn1UdqGAptHA6sG06sW47q2Qwp1wkplsesmYjrmQeq2Qdt3EqtnApp2EbsGokvnYwv3YvtWsjsWcdtGkevXInsGUdrmMZt2sfplkMrV8TsWUar2Udtm4pxH06wXs6wHs6xX8+x4BAvHU1vHMzvnQzvHMvvXMvtmslsGYeuW0luGsluWsnu20qvnAuvG8tuW4ruG0otWolsGcgt28ktGwksmYkrmEiq18dr2UeqV8UsmgbuW0ltmgmuGkouGkmuWsot2wouW4qtmwotGsmsGgirmMerGEcq2AbrWMgrmQisWcnuW8vvHIyvHIyxYpXpGcxo2Yvu39Kx4pYvn5OsG08qGUyqmUwsGkysGkvsGovn1kepmEmuHQ5w4JMu3tInVsnq2Yxtm45tm05sWg0rmc2sG08uXhIvn9RzpBjyIhbsW5Bu3ZJunNGsGo7mFQjoV4somEuoF8spmQyo2AunVonlVIeqmYxpmEroVolo10opF0om1Idn1QcrGQst3A6rmk1s248sGg2olcho1kes2kprmQhqWEds20ounQvpmEcsGsmvHUxu3Mvtm4ptm0mtWsjuXAmrGIYr2MZtmofplkNqlwQsWQasWUduG8pxH05wHk4u3UzwXo5yIFBv3g3vHUywHk2unEtvHItt2wmsWYft2sltmkkt2snum8rvnIwum4suW4ruG0ptGcirWEbsWcet2sjum0rsWQlrWEfrWMdp10UsWcduG8otWont2optmkmuGonum4qt24qtm0ptW0osWYhr2Qfq2AbqF0YrWIfsGQitmkpu3Awu3EyvHEy1Jhjt3lDqGo1rHA8uHxKyYlZwX5Ormo5rGgzsmw2rWcurGYrolwhpmAls240vXpFtHNBnlsoqWQvtGs3t205tWw3rmc0qmYzqmc2r209zIpb0pBism5AsGs9sWs9qmY3o2EwpmU0p2g3oWIwpmQzpmMypWIwl1QhpmEuoVwonlgkoVsnoFklnlUhnVMbr2YutG44rmk1sWw6s2s4pFkkpVoht24wqmEhq2IhuXAvuXEwqWIgsGonuHIvt3AttW4qtGwmtm0ltGohqmAVrGAVtWkdplgMpVcMsGQatWkiuG4pw3s4wns5uXIvv3g2xH08vnc1u3Qxwns4unEtu3EtuW4pr2Ufum4pt2smt2snum8rvHAuvXEvuW0quGsntWcjsGMermEatGYgumwpuGsptmonrWMepl0XrGQesGoksWkosWYlsWUhuW0puW4qs2omtWsnuG4qs2gksWUhrF8bp1oXrWEesmYjtWkpuGwtu28wv3I00JJcxYZQtXdCsnVCqGw6uHhHzYtasW49rGg1s245rmgwp2EopmAlqWMosGowr2w3sW89qWUzrWYytmw4tWo1tWs2r2cyq2Uwp2Qwrms5vXtKv3xMtXBBrmo6uXNEvXlKunhJtndIxYhYq209o2EwqGU0p2UzpGEvpmEvnlknnlgmpV4snlclnVUim1EarGMqsGo0rmo1sGs4sGg2p10ppFoit24zqWAirGIhtmsqtWoqr2UlsGclvXUyuXEtvHMusGcgsmkgum8lsWYbrmIWsWMXqFoOplkOsWQctWkhtmsmwHc0wXk2unIvv3g1wns4vHUyuXIvvnc0t28ruW8quG0ormMeu3Art2wouG0pt2wouG0qvXEvu24rumwpt2klsmQgsGIdr2IcuWsoumwqt2oosWckq2MermUhsWomtGsqsGUkq2Adt2wouG0ptmwotWwotWomsmcjsGIfrV8cp1kWsGQgtmootGcnt2oru24vvnEzu3tDuHhCuntGx4lWvIBNqWo5unhIr207qGYxrms1sWw0qWQqp2Emp2Emrmgus3A7s3A+o18tpl8ts2o2tGk0tWw2r2gyrGYwrGgxr2w4sW48s249t3JBsWw7vnlIwH1OvHlMzIxfzpBirnBBpGExqWU0qGU0p2IxrWg3o14smVQipV4solspoFglnlQfqWEqrWcxsm05sWw5rWYzqF4ppVwksGgsqGAirWIhtGclrmIgsWYjsGcjwXczu3EsuG4ms2kgr2QZuG0irmEYrmIWsWMXp1kNqVwRsWQbs2cftWolvHIvu3IvunEtvnYzwHk2unMwt3AtuHEut24qt20pt2wns2gjuW0oum8qu3Art2wotGsnuW8qvHEsu20puWsmtWcir2IdrF8at2onumwqtWkmsWYjr2YirmUhsmontGwqsmkmrWIetGgkt2sot20puXAss2gkr2QgrV8cq10ao1UStGYjuGwqsWUltmkquWwuum0vtXU7p2Uur286u3xJxYhVpWY0sW89sG88qGYxrGkyr2oyq2UrpmAlo10hrGUpt3I7sm89mFQhn1gms2o3tGk1s2k0q2QuqWMtq2cwrWk0pmEvpF8trWg2qmUzr2s5qGU0wX9P4Z9x3Z5xtnRHp2MxqGMxp2IxpmEwqmU0o14sllAeoVoopmAro1wnnlUfpV4oqGItsWw6r2o4rmYzqWAqrWMqrWUoo1wdrGEftGckr2IfsWYismcjw3g0u3Aqs2gftmsftWodtGkbrF8TsGIWtWcbq10RqlwRsWUcsmYetmolunAsu3IuunEtv3czwXo2unMwtG0qt3Ast28ruG4puW4puGsmt2oluGsmuG0otmwnsWkjuXEru3ErvG8ru24puGolsGMfql8btWomt2snsmYjsGYisWgkr2YismkltWsosWcjrWAdtGckt2wouG4qvHIus2klsWYir2Qhql0ao1UTs2UivW8ttmcntmgquWwuum0vtnQ6qmgwu3pEwYJNwIRPrW47rGw4r285pmUvrGozqmcuqmYqpmEkol0fpmAirWgxsWw6oVspnlclsWk3smk2rmYyp2Eso14pp2QuqWYwn1snol4pq2czqmUxq2czqGQzwX1OxYJUwn9StXJDqWYzqWQyq2Y0pl8upl8uoVspl1AenlgkpF4poVslnVUhoFkloVsor2o4sm07sWo2rGMrsWctsGgppV8drWQhtmoor2QirmMhsWckwng1t20os2ggtGkfuW0itWkcrmAUr2EVumwgsWMYqlwSs2YdtGchvG8rtGklu3AsuG4qwnk1w3s4v3g0tm8rt3AsuXAst20pt2wntWgjtmkitWkitmojuG4ns2sjuHAotmwluG0muGwluWwmtGklpVsYuXArt24psGcisWgksmklsGUhs2kltWomrmEerl8cs2UitWklu3EtvHIusmglsWYksWUjqV0boVMRrF4bvG4st2got2kquGstvnE1sW4zrGgxv3xGyYlTvH9JsnQ/qWo0snI8pWUvsHA3rGowqmgspmIlo14foVscpmAouHNAs2w6oVoosWg2sWk2rWYyqGMupWItqWcyqGYwnVkkpWEsqmYxq2cyrGg0nlknuHREv3xNsm5Aq2c4qWQxq2UysGo3pl8tp2AvpV4smFEemlQgpV8qo10nolomoVknoFoosGw6sWw4r2cxsmgvrWQorWYkq2Uhr2clt20urGMjpFwbrWQiwXk2uXAss2kitGkhtmshtWoer2IWrmAUtmgcsGIYrF0UsWQcs2UgwXMvtmomt2wotWomwHYywno2wXo2tW8rt3AsvHMvu3Etum8qtWgjuGojtWkht2wkuG8msGgft3AnuXAns2kgtmkivW8ptWomolkWuHAruXIssmoksGcis2klsmcjs2citmolsWMerF0armAdr2MfuW0qvXIvs2onsGYkr2Qiql8dpVgWq1wZuWspumsrt2gquGstvnA1qmQoolwir2oyt3U+qmszq2w1sXE7t3VAqmgysnA5q2kwq2kvqGgqpWIjn1sbpF8munVAwXtGpV8rrGQxsWk2r2c0rGYxrGcxrmk0qWQvnVkkpWEsqGUvr2s2sm05nVoouHVFxoNVt3VIqWc4pGEwo18tsGs5p2EvqmMxpl8tmVMemFIdpF8ppmEqpF4poFoooV0rtXE+rmk0qmMstmwzq2Ikq2QirGUhrWUkuG8wq2QjoVkZrmYlwXo3t28qr2Ufr2QcvXMqtGgdsGIWrmATs2UZsWMZrWAXtWghtWgiu24quW4puW8qtWsmvHIuwnk1wXk1tm8ruXEtu3Euum8rum0pt2oluGwltGgguG0kuXEns2wju3QrvnYstm0jsWYetmoitm0mqWIds2wmtm4otWwmsWYitGgktmsntmoltGkir2MdqlwZrl8csmMgtmckvXEttmwpr2Ujq2Aeql4cqlwasGEguWsqt2cot2gqtmgrumswpV0hnVUZpF0isGswpWMopmYttXQ8tW86qmIutG85rGozqWswqGsupWYnn14eo2AjtXA3vnlCpV8pqWEtsmk1sWg0smg0smgztGo1q2MuoVwnpWEro2AorWozr2s4pmQ0uHZIunpOwYNYtHdJoGIyoF8vrWs6pGAvq2Y0qWMumVMdk04YomAopWMrpGArm1YjnVgmsWw6sGs1p2AprWUrqGAjrGQjrmQjrWMhunAurmUjoloWr2Uhx304tmslr2McrGAYwXUsuGwfrWEQqmAQrGETs2gbrGEWs2ogtmwktm0mt28ouHArvHMvvnUxxXw5xXs5uG4suG4sum8tum4rtmkltmkluG0mtWsjuG8nt28ns2sjt28nvXQsuW8nr2UdsmcetWsirWUcs2ohtm0kt2wkr2MdsGMetWoltmsnsmgkrWMfql8crF0at2UitmUiumsotmsnsmglrmEfq1sar14cs2QluWoruGkruWksuWkuuWkupl0hnVcboVwfrmsurWsvqWkvsXA3sWwzqGEpr2oypmUspmgtqWwvqWssoWAhpmAksWsxtm83p18pqF8qtWw4smw3s2s3sWo1sGo1qWQuo14ppmMsn1wkqmcvsm86r208snBDtnVJxYVZvH1PpWY3o2IzqGY2pGAvrmc1rmgznVcikUwWoV4nqGYvpWEsnVgmoFootG07smw3q2MtqmIpqWAkq2MksWcmqWEeuHAtr2ckoVgUrmUgyX86tmslsmYesGQcv3Mqu24jr2MSqF0Oql8RtWodrWIXq2EXtGohuG4ntWwmsmoku3IuvnUxw3k2xHo4u3EvvHIwvHEvum0qtmglt2omuW4nuXAot24muXEptm4os2skvnQuvnItsWQfs2cht20mr2UdtGoiu3Eptmsjr2IcsGMetmsmtGkktWsnrWQgrGEcq10Yt2UhumgkuWsntGkksGcjsmYirV0asWEetWcmumwquGkptmcpumouuWkun1oenVcboV0hqGUpr2swp2Urq2gvrmkvrGYrs280rGsvqWourG0xrGswo2AkpF4jsGguuHE3smsyoloksGs2sm04rms2rWo1q2k0pmQvn10np2YuoF4lqGUts3A7sG08sGw+rmo+vntNw4FSqmg5p2Q0qmc2p2Iwq2QyrGYxnlgjk04YoF0mqGYvq2czn1knoVops2w6t3E+rmYxrWQtplwirGMms2kpq2MfsWomsWomoFkVsGgix344tGokrGEbsGUdwHUttmofsGMUrWESq18RtWoer2QYq2AVsmcetWsjtWwktWslvXQwvnUxvXQxwnk3wXk2wXc1vXIwuWwqtWckt2oluW8ouHAotGwkuXEpuXErqWEbv3Uvv3MvsGIetGciu28qr2Qes2chv3MttWkjr2IdsmYhtmwnt24pt24ormQfrGAbrmEctWUhvW0pu24psmcirmMetGcirmAbrF4atWckumwquWoptGUmuWktu2svnlodnFcbn1sfol4jrWkurGkvqmYsrGYsrmkttnM1r24wpGUnq2wvtHE3qWUrpWAlrmcttG40uHM6o14nqWUvsW45rWw2rWw3qmo1pWUvn14npWUrn10kol8orWk0sGo6r2k6sWs9sGo8vHdIrmo6qGQ0q2Y1qGExrGUyqmMvolwnlVAbp2Mtp2QurWY0n1gmoFgnr2c3u3RCsGc0q2IsqmAnsWgrsWcoq2QhrGYhtW4qpV4asGgjwno0tm0nqF4YsWcgwnYvtWofrmITrmESr2MVtWodt2wfrWIWtGkftWohsWYfu3Arwnk1vHQwu3Qwv3g1v3c0v3Uzv3Mxu24st2kmt2snt28otG0ls2wjsmsjunIsrGQeuXArwnUxqlwZs2QiumwpsGMfs2Yhu24ptmkksWQfsmUgs2kkuXAruXErsWgiq18asWQgtmcjvm8ruWwosGQgsGQgsmYhr2EcrmAbtGYitmglumwptGYltmYpu2suoV8hm1gbnVoeol4jqGQprmkvqmMprGYrsG0vsW8wsG8wnVwepGImtHE3q2Yuo2EmqGYrq2kusm82oF4moV4orWs2r204rWs4q2k2pmMwoV8oomEooV8mmlcfrmo1tGw7sGk5qWIynFUlsWo6sGs6q2Y1qWMypV0sp18tp18tpV8qmFMepGArqWQwqmMxoloqpFwsr2c3t28+rmUzqF8pp10ltGsvsGcpqWIgrWgjuXQvqWQesWslwns1smokrGQerWIcwHUvs2cdr2EVq10QsmYYtWoct2wfr2QYs2ges2cer2MbsGUgvXUxvHUxvXYyvnc0v3g1vXQyvnIwum0qtmglum4rtG0mr2khsWwjqWMbtGwmrWUfvHEtxHYzrl8dsGAfvG0rsmQhs2UiuWsouGomtGcjsmYhsGUgtGslvHQutWolrWAdsWMhuWsou20rt2kns2UismYitWgksGMfr2IdtGcit2omuWsps2UkuWkrvG0voWEhm1ocnl0gpGElpGAlqWEoq2QqqWYqsG4yrWsvrWsvmlgboV0itG82sGszpWUrpGYqqGgtqGguo2Mpnl0kqGYvrWo1qmc0qWMypV8tpWErpGEppWIpoV0mq2YxtG07tGw8pV0tnVQkqWEwrGY1rGU1qGAwn1gmoVoopl8tpmArllAbo10or2k0rGUzo1sqpV0trWU1tW09rmUyp10oqV8ntGswqmIkqGEfr2olvXgzqWQfs20nxHw2sGgir2chrWQcu3Aor2Qbr2MXqV0QsWYYtWocuG0fsmcbtWogsWUdrWIaql8ZuHAru3QwuHEuvXYzwHg1vHIwu28tum0rtmgluGwotm4or2kjtW8ormggrmYeqGAatm0ownQxs2MitGQkwHEwsGIgsmQitGYjtGYjtWgkuGsosGUgtGokuG8psmcjr2EfsmQitmgnum4ttmkosWMisWMhtWcktmkltGgjtmkkuGsmt2onsmQjuWorvG0vomIimlkaomAiqWUppF4iolkgrGYspmMos3I3sXE2s3I4ol4lm1YdrWgvsW40rm40pmgupGcsomMppmctoF4mp2QtrWg0q2QyqV8upF0qol0nqGMspWEoo18nrmk1tW8+tW8/qWIyoVooq2YyrWg2q2Y0qWMxolwqolsppl8tqWMwm1QioFkmrGYzq2MxpF0rpF0rpl4us2w6rWUxqF8qrGQru3I4rGMmqWIhsmwptXArpV4asGolxH03sGgirmYesGYetmwkrmMbrmMXr2QXr2UXtGoctmwes2kctGwfrWQZq2EYo1oTtW8qvngztW8rvHYzwHk2u3Mwt2wqum0rsmQhtWgluHAquHAquHEqsGkgsGggp18Xp14YvnIuuWoouGgov3EvsWQir2MhsWMhtWcktmglu20qtWgktGcjt2sms2cjrmAesmUjsWYmuW0utWcorl8gr2AetWckt2sntWoltmgluGoot2kntWYlu2wtvGwvpmYmllYWn10esm0vo10foVkeqWMoqGYtomMqvX9GwH9IrGcwnlkgqmYsrm4ysnI3qmoxoGAmomIopmQroF0lp2Mrr2k0rWUyplwqoVgmo1smqWEsp2EqoFsmsGs5sm49qmU2r2s6qmYyrGk0rGk2qmY0qWUzol4sn1knolwqqWMxnVYkoFgmrGQyqF8soVknpF0rqGAvrGUzqmIuqGArsGgwvXQ5sWgrq2MktG4rtnAso1wZr2cjvncxsWkir2YesWgfsWgftm0jtmshtWofq2IUsGcZuG8hrmUXs2sdrmYbq2EYpFwVtnArvHcyunQwvXc0wHk2wXo3uG4svnEut2kms2Yit2wouXEru3MtsmoismsirmceoFcPu28qvnAsumspu24ssWUjsWUismQhtWcktWYjt2gltWYjs2Yium4quGonr2Eer2MftWsptmwrsGMjr2AesGEes2YhtGojsmgisWQhvW8tuWspsWEjuGgrvW0xpWUlk1IRmlgYs24upl8gpFwgpF0jqmkwomQu1JVf0pBctXA7qmUurGovrm8xr20zq2YvoVwkp2IpqGMqo14lqWQrsGs1r2gzpV0qnlUiolgkq2ItqWMtmlUiqWUzs3A/tHFBsG08sG46snA8rGo2qWc0qWc0oV4snFgmol0rqWIwpV0rolknt248rWQxoVkmqGEurGUzsGk3q2MvqWErrmYttGwws2otrmcntG0tu3Qyo1wZqF8cwHgyuG8psGYesWgermUatmwiu3EntWofpl4QrmYYt28hrGQWsWkcs2sgr2YdrWUfunUwu3YxtW8ruHIvwnw5wns4vnQyv3IvuGontWcksGUhvXMuunErtG0ksmshs2who1oRtmwkum0oumwpum4rrWMhsWUitWckuGonsmQhsmIgtGUismMhuGontWcjtGYgr2Ufs2wmsmomr2MfsGIds2QesmUdtW0is2wjql0bu2wsuWsrrF0ft2cru2swo2Mjk1MTmFUWrmkpp2Aho1sfol0ipGQqqWs12JhlzYtZsm46sW02rGkvrGwuq2ctrGMrpl0lqGIprGYto10mpmEqrGkyrGgzol0pm1Mfn1Qgs2k1rWcymVMgpGAuuHVFtnREuXdFtnZCsnI+rWw4qmk2qWg1oV0qm1cko14sqmUzqmMxolootGw6rWQwnlUhp18srmc1rmc1qGAtqmIsrmYts2svsWottGsttWwtt28upl4boloVuHAquXApt24ks2sermMYtWsgvHIouG8krmYYrWUXs2sdqmMVs2wguXEntGwksWkiuXMuu3UwvXYztm8swHo3wXo3wXg1vHEtuGwnsmUgrGEcwHUwvXMtsmsirmcetm8kp18VsWgeuW8num4ouG8rqF8crGIetWomvW8ttWYlsWEgtGQjsGAftWYktGUgtGcftGkhtGwls2slrGAbql0WtGYetWoft3AitG0irGAfuGorvG0vrV0gtmcsvW80pGQnl1cal1QYqWQmp2Ajolwgol8jpWMps3M6yopUtHM+pGItpmMtpmMrrWoxqmUqq2MoqmEoqGEpqmIso1wnqGItsGw3rWo1oV8pm1cgoFkgs2w1sWs1mVYhn10quHZFt3VEt3dGs3NBqmk4rGo4rms4qmYyoFwnmlUho10pqmQyp2Ixn1oprWc2q2IwnFIfp18srmg2qGMxp2Euq2Mvq2ItrmQtsWcutm0ytm4xunEwrGIdoFcNuG8luG8luW8ltGkfsWMZuWsfum8ju3EksGcZqmETsWgarGMWtGsgunEnuXAotm0nt28rvXQww3o2tWwovXYyvngzwnw1vHMrum4mtGcfsGQcvXMrvnUttW0ls2sjt28mqmEZrGMau3Epu3AquW8urGQkp18dsGYkuGwqu20stmcns2Qkrl4dsWIer2EZtmgftmkitmomtm0orWMeo1kSrmUcs2sgtW8itG0jrmQhuG4svG8vrV8isGMovXI3pGUpnF0hmFYao18ipV4hoVwepGEjqGYprm4ytHM6p2cupGQromAoqWYurWkvrGctrmctrWYtpmEop2Eppl8pqWUus3A5r202o2EqnFkgpV8lsm00tnM8nlslqGYytnRDtHJCtnVFuHhJs3FCsW49s289qGQwnVkknVcipmArrWg1q2c1oFwrq2Y2q2Mwn1YipFwprGUzpl8trWYzrGUwp14oplwkrWMruXI4t3E0uXAurmQeo1sQs2sftm0jt20jrmIYsWIXt2keum4huW4gsGYYrmQWs2kbrmMXs2ogvnQsu3Equ3EsuG8quW8qw3g0vHIuvHUwu3YwxYA5unIqu28mtGces2cfv3UtvXQstGwks2sjtm4mqGAYqWEZvHIqvHEqvXMwtm0srWUhrmYhtGomum4rtWgns2UjrV8csGIdrV8XsGMZtGcgtGgks2klrmUhpFwVrWYcsGgeuG8mtm4nrmcitGonuWwsrmEisWUovXQ5omMnnl8inFwepGEjpmAgn1sZpWMhq2opsG8xsnI2qmsxpmcsoWAlrGovrGktsGsxrGYtqmUsp2MppWIoqGQqrGgvtHE4rWozol8onloipmAms200tXE6qmcxr2w4uXdFunhIt3ZItHRGu3pNt3VEuXZFq2c0mVYhm1YhpWArrmo2sWw6o14tqmQ0qF8toFYip10qrWQyp2AtqmQwq2UvqWIrpl0lrGMrt3A1tG0wunEwr2Uep14Ts2oftm4krmUbrWIYsmQat2ketmoeum4hs2kcsmgbtmsgrmQZr2UcvXMrvHIsvXIttW0ns2klwHUxwXYyv3cywHs1xH04unEru28ot2kjsmYfu3EqvXMss2sjsGghs2skqWEaqmIbuG0mum8pu3EuvnQxtGsksmkitWsltGkltWkmtWglrWAcsWQermIYrWIXsWUes2gjtGklrmQfpFsVrWQcsGYdtmsjunAqs2sltGoluWwptGUlt2osvHI1omImnV4hnVwdo14fq2Ukol0Zol8aqWckqWkou3w+sXI2qWktqGcrs3A1s280s283tHE6rWsxo2ImomEjoWAjr20wtnM4sG00pGApol4lpmEnqmUrs243sGs1u3hDu3lIyYhXxoZYrW5Cqmo+uXhJwoFQqGc0l1UgnlslpWIrsGw2sm05oFspp2EvqF8sqV4qq2EsqmEtp2ArrGYwrGYwrGYvq2Qrr2Yts2wyuXI1s2wprmYfpl0Ts2ohuXEoqV8WrWEYsmQbum0it2sftmofs2gcsmcdtWogsGQbr2UdvHEsvXItuW4puG8pt20nu3Arv3UxvnYyvXczwHk0v3Yxu28qvG8qtmoluW4pvnQvt28ptm4osWkkrGQfr2Yhum8rt2wouW8rvHMut20ltGoit20mt2wos2glsGQhrF8bsWUfsWcdrGQZrmUes2kktGkltGkkp1wXqF0WtWkhtWgjt2smtGsms2gktGYktGUluGoru28xpWUonFwdnlwcoVwbq2Qhp2Idol8apGIfpWMjwYBCtHU5o2InpWInuHQ5t3I3tHE5uHdArm40nl8jn18gn18esXAxuHU5uHM6p2Eqol0lqWQrp2Ipsm00rmoyt3M/sW89woFRz5BjtXZNrG1DuHpL0JFgtXVClVQgo2EspGEqq2YwtW86qGItpV0rqF4pq2EsrGMtpF0noFokrGYwrGcvrWgvr2gvr2gvs2wztm8ztGwqsGciqF8Wsmkgt28np14WrWIatGceum0jum4jsGMatGkfsmYdsmYetWkhsWYgum8qu3ArtGoktm4muW4ntmwlvXItv3cxvXYyvnczwnk1um8ruWwotWomuW4qv3Uxu3IuuG8rsmkltWwor2YiuW4qtGkluG0pv3QvuG4msWcgt20mu3AstmsosmYkrGAer2QgrWQcrGUcs2sktGsnsmcjs2cjrF8ap1wUtmkitmgjtWgktGkltGgksWIfsWMgtWgmuG0sqGcqnl4enFsan1oZqGEeqmQhq2ckpmMinVodsm81t3Y9oF4lnFkgsWwzt3E4tXI6snA5q2wxnF0goGAhomIir24tt3Q2tXE2n1kioFskrGcuqWQrr2oxsGw1tHE7r206v35O3p5zyYtit3pRuHxO1ZdnwYNRnl0qomArpGEqpF8ptW85rWcyoVsmp14pr2YwrWUvpV4ooVkjq2UtrmgvrWcusGkxsGgys2w0tG4ytGwsrmYhp18XsGkht3Eppl4YrGIatGgftmoft2sfrmIYtWkgtGghrmEbuWwnsmciuW4nu3Ept20muHAou3EpsmcgvHEqw3k0wXs1u3QwuXAtum8st2kntmomu3AswXczu3IuuXAssmkluXAstGomt2wotGkltmsowHUxum8qsmcjtGkku28suWwssWQlrmEhrWIfq2EbrWUduHAqtWsnr2QgsWUhsmQfrF8ZtWgjt2gltmkmsWYks2Ykr2EesGEerWAdtmwppmYoomEgn1wboVwbqGEfrGUks24urWksnFkfqWguuHY/qGYvpGEqqWYttXE4s284r201rGowpWQppWQno2IkrWwuuHU6sW00o14on1kkrmkyrmkxrGcur2wzunhBtXNAvX1N1pds0pRsyItjv4JX1JZpw4RUpWUzo2EtqGUwo18pqmUvq2YxnVcio1smr2cxrmYwo1sloFgiqWErrmcwsGkxs2ozsmkzsmszsmswuHAwrGQfp18Ys2wkuXMrqGEbq2Iar2MbtWkfu24jr2IZsmYeum4nsmQgum0ps2citWojt20kt20lvHQswHcvs2gfum8nv3YvvXYwv3k0uXEtu3EutmontWomu3Asv3UxvHMvtWwosmklt24qt24quW4qt2wotGknuW0ruG0psmcjsWYit2sruWwusWMlr2Eir2EgrWMdrGIatmsmtmonr2IgrWActGcisWQfvG4quGonumsrs2cmsmUjsWMgrmAcr2IduW8q]] | |
FILE: [[images/processing/rotation/rotation-tests.factor]] [[! Copyright (C) 2009 Kobi Lurie, Doug Coleman. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: accessors fry images.loader | |
images.processing.rotation kernel literals math sequences | |
tools.test images.processing.rotation.private ; | |
IN: images.processing.rotation.tests | |
: first-row ( seq^2 -- seq ) first ; | |
: first-col ( seq^2 -- item ) harvest [ first ] map ; | |
: last-row ( seq^2 -- item ) last ; | |
: last-col ( seq^2 -- item ) harvest [ last ] map ; | |
: end-of-first-row ( seq^2 -- item ) first-row last ; | |
: first-of-first-row ( seq^2 -- item ) first-row first ; | |
: end-of-last-row ( seq^2 -- item ) last-row last ; | |
: first-of-last-row ( seq^2 -- item ) last-row first ; | |
<< | |
: clone-image ( image -- new-image ) | |
clone [ clone ] change-bitmap ; | |
>> | |
: pasted-image ( -- image ) | |
"vocab:images/processing/rotation/test-bitmaps/PastedImage.bmp" | |
load-image clone-image ; | |
: pasted-image90 ( -- image ) | |
"vocab:images/processing/rotation/test-bitmaps/PastedImage90.bmp" | |
load-image clone-image ; | |
: lake-image ( -- image ) | |
"vocab:images/processing/rotation/test-bitmaps/lake.bmp" | |
load-image clone-image image>pixel-rows ; | |
[ t ] [ pasted-image dup clone-image 4 [ 90 rotate ] times = ] unit-test | |
[ t ] [ pasted-image dup clone-image 2 [ 180 rotate ] times = ] unit-test | |
[ t ] [ pasted-image dup clone-image 270 rotate 90 rotate = ] unit-test | |
[ t ] [ | |
pasted-image dup clone-image dup { 90 180 90 } [ rotate drop ] with each = | |
] unit-test | |
[ t ] [ | |
pasted-image 90 rotate | |
pasted-image90 = | |
] unit-test | |
[ t ] [ | |
"vocab:images/processing/rotation/test-bitmaps/small.bmp" | |
load-image 90 rotate | |
"vocab:images/processing/rotation/test-bitmaps/small-rotated.bmp" | |
load-image = | |
] unit-test | |
[ t ] [ | |
lake-image | |
[ first-of-first-row ] | |
[ 90 (rotate) end-of-first-row ] bi = | |
] unit-test | |
[ t ] | |
[ lake-image [ first-row ] [ 90 (rotate) last-col ] bi = ] unit-test | |
[ t ] | |
[ lake-image [ last-col ] [ 90 (rotate) last-row reverse ] bi = ] unit-test | |
[ t ] | |
[ lake-image [ last-row ] [ 90 (rotate) first-col ] bi = ] unit-test | |
[ t ] | |
[ lake-image [ first-col ] [ 90 (rotate) first-row reverse ] bi = ] unit-test | |
]] | |
FILE: [[images/processing/rotation/authors.txt]] [[Kobi Lurie | |
Doug Coleman | |
]] | |
FILE: [[images/jpeg/jpeg.factor]] [[! Copyright (C) 2009 Marc Fauconneau. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: accessors arrays byte-arrays combinators | |
compression.huffman fry grouping images images.loader | |
images.processing io io.binary io.encodings.binary | |
io.streams.byte-array io.streams.limited io.streams.throwing | |
kernel locals math math.bitwise math.blas.matrices | |
math.blas.vectors math.constants math.functions math.matrices | |
math.order math.vectors memoize namespaces sequences | |
sequences.deep ; | |
QUALIFIED-WITH: bitstreams bs | |
IN: images.jpeg | |
SINGLETON: jpeg-image | |
TUPLE: loading-jpeg < image | |
{ headers } | |
{ bitstream } | |
{ color-info initial: { f f f f } } | |
{ quant-tables initial: { f f } } | |
{ huff-tables initial: { f f f f } } | |
{ components } ; | |
{ "jpg" "jpeg" } [ jpeg-image ?register-image-class ] each | |
<PRIVATE | |
: <loading-jpeg> ( headers bitstream -- image ) | |
loading-jpeg new swap >>bitstream swap >>headers ; | |
SINGLETONS: SOF DHT DAC RST SOI EOI SOS DQT DNL DRI DHP EXP | |
APP JPG COM TEM RES ; | |
! ISO/IEC 10918-1 Table B.1 | |
:: >marker ( byte -- marker ) | |
byte | |
{ | |
{ [ dup 0xCC = ] [ { DAC } ] } | |
{ [ dup 0xC4 = ] [ { DHT } ] } | |
{ [ dup 0xC9 = ] [ { JPG } ] } | |
{ [ dup -4 shift 0xC = ] [ SOF byte 4 bits 2array ] } | |
{ [ dup 0xD8 = ] [ { SOI } ] } | |
{ [ dup 0xD9 = ] [ { EOI } ] } | |
{ [ dup 0xDA = ] [ { SOS } ] } | |
{ [ dup 0xDB = ] [ { DQT } ] } | |
{ [ dup 0xDC = ] [ { DNL } ] } | |
{ [ dup 0xDD = ] [ { DRI } ] } | |
{ [ dup 0xDE = ] [ { DHP } ] } | |
{ [ dup 0xDF = ] [ { EXP } ] } | |
{ [ dup -4 shift 0xD = ] [ RST byte 4 bits 2array ] } | |
{ [ dup -4 shift 0xE = ] [ APP byte 4 bits 2array ] } | |
{ [ dup 0xFE = ] [ { COM } ] } | |
{ [ dup -4 shift 0xF = ] [ JPG byte 4 bits 2array ] } | |
{ [ dup 0x01 = ] [ { TEM } ] } | |
[ { RES } ] | |
} | |
cond nip ; | |
TUPLE: jpeg-chunk length type data ; | |
: <jpeg-chunk> ( type length data -- jpeg-chunk ) | |
jpeg-chunk new | |
swap >>data | |
swap >>length | |
swap >>type ; | |
TUPLE: jpeg-color-info | |
h v quant-table dc-huff-table ac-huff-table { diff initial: 0 } id ; | |
: <jpeg-color-info> ( h v quant-table -- jpeg-color-info ) | |
jpeg-color-info new | |
swap >>quant-table | |
swap >>v | |
swap >>h ; | |
: jpeg> ( -- jpeg-image ) jpeg-image get ; | |
: apply-diff ( dc color -- dc' ) | |
[ diff>> + dup ] [ diff<< ] bi ; | |
: fetch-tables ( component -- ) | |
[ [ jpeg> quant-tables>> nth ] change-quant-table drop ] | |
[ [ jpeg> huff-tables>> nth ] change-dc-huff-table drop ] | |
[ [ 2 + jpeg> huff-tables>> nth ] change-ac-huff-table drop ] tri ; | |
: read4/4 ( -- a b ) read1 16 /mod ; | |
! headers | |
: decode-frame ( header -- ) | |
data>> | |
binary | |
[ | |
read1 8 assert= | |
2 read be> | |
2 read be> | |
swap 2array jpeg> dim<< | |
read1 | |
[ | |
read1 read4/4 read1 <jpeg-color-info> | |
swap [ >>id ] keep jpeg> color-info>> set-nth | |
] times | |
] with-byte-reader ; | |
: decode-quant-table ( chunk -- ) | |
dup data>> | |
binary | |
[ | |
length>> | |
2 - 65 / | |
[ | |
read4/4 [ 0 assert= ] dip | |
64 read | |
swap jpeg> quant-tables>> set-nth | |
] times | |
] with-byte-reader ; | |
: decode-huff-table ( chunk -- ) | |
data>> [ binary <byte-reader> ] [ length ] bi limit-stream [ | |
[ input-stream get stream>> [ count>> ] [ limit>> ] bi < ] | |
[ | |
read4/4 swap 2 * + | |
16 read | |
dup [ ] [ + ] map-reduce read | |
binary [ [ read [ B{ } ] unless* ] { } map-as ] with-byte-reader | |
swap jpeg> huff-tables>> set-nth | |
] while | |
] stream-throw-on-eof ; | |
: decode-scan ( chunk -- ) | |
data>> | |
binary | |
[ | |
read1 <iota> | |
[ drop | |
read1 jpeg> color-info>> nth clone | |
read1 16 /mod [ >>dc-huff-table ] [ >>ac-huff-table ] bi* | |
] map jpeg> components<< | |
read1 0 assert= | |
read1 63 assert= | |
read1 16 /mod [ 0 assert= ] bi@ | |
] with-byte-reader ; | |
: singleton-first ( seq -- elt ) | |
[ length 1 assert= ] [ first ] bi ; | |
ERROR: not-a-baseline-jpeg-image ; | |
: baseline-parse ( -- ) | |
jpeg> headers>> [ type>> { SOF 0 } = ] any? [ not-a-baseline-jpeg-image ] unless | |
jpeg> headers>> | |
{ | |
[ [ type>> { SOF 0 } = ] filter singleton-first decode-frame ] | |
[ [ type>> { DQT } = ] filter [ decode-quant-table ] each ] | |
[ [ type>> { DHT } = ] filter [ decode-huff-table ] each ] | |
[ [ type>> { SOS } = ] filter singleton-first decode-scan ] | |
} cleave ; | |
: parse-marker ( -- marker ) | |
read1 0xFF assert= | |
read1 >marker ; | |
: parse-headers ( -- chunks ) | |
[ parse-marker dup { SOS } = not ] | |
[ | |
2 read be> | |
dup 2 - read <jpeg-chunk> | |
] [ produce ] keep dip swap suffix ; | |
MEMO: zig-zag ( -- zz ) | |
{ | |
{ 0 1 5 6 14 15 27 28 } | |
{ 2 4 7 13 16 26 29 42 } | |
{ 3 8 12 17 25 30 41 43 } | |
{ 9 11 18 24 31 40 44 53 } | |
{ 10 19 23 32 39 45 52 54 } | |
{ 20 22 33 38 46 51 55 60 } | |
{ 21 34 37 47 50 56 59 61 } | |
{ 35 36 48 49 57 58 62 63 } | |
} flatten ; | |
MEMO: yuv>bgr-matrix ( -- m ) | |
{ | |
{ 1 2.03211 0 } | |
{ 1 -0.39465 -0.58060 } | |
{ 1 0 1.13983 } | |
} ; | |
: wave ( x u -- n ) swap 2 * 1 + * pi * 16 / cos ; | |
:: dct-vect ( u v -- basis ) | |
{ 8 8 } coord-matrix [ { u v } [ wave ] 2map product ] map^2 | |
1 u v [ 0 = [ 2 sqrt / ] when ] bi@ 4 / m*n ; | |
MEMO: dct-matrix ( -- m ) 64 <iota> [ 8 /mod dct-vect flatten ] map ; | |
: mb-dim ( component -- dim ) [ h>> ] [ v>> ] bi 2array ; | |
! : blocks ( component -- seq ) | |
! mb-dim ! coord-matrix flip concat [ [ { 2 2 } v* ] [ v+ ] bi* ] with map ; | |
: all-macroblocks ( quot: ( mb -- ) -- ) | |
[ | |
jpeg> | |
[ dim>> 8 v/n ] | |
[ color-info>> sift { 0 0 } [ mb-dim vmax ] reduce v/ ] bi | |
[ ceiling ] map | |
coord-matrix flip concat | |
] | |
[ each ] bi* ; inline | |
: reverse-zigzag ( b -- b' ) zig-zag swap [ nth ] curry map ; | |
: idct-factor ( b -- b' ) dct-matrix v.m ; | |
MEMO: dct-matrix-blas ( -- m ) dct-matrix >float-blas-matrix ; | |
: V.M ( x A -- x.A ) Mtranspose swap M.V ; | |
: idct-blas ( b -- b' ) >float-blas-vector dct-matrix-blas V.M ; | |
: idct ( b -- b' ) idct-factor ; | |
:: draw-block ( block x,y color-id jpeg-image -- ) | |
block dup length>> sqrt >fixnum group flip | |
dup matrix-dim coord-matrix flip | |
[ | |
[ '[ _ [ second ] [ first ] bi ] dip nth nth ] | |
[ x,y v+ color-id jpeg-image draw-color ] bi | |
] with each^2 ; | |
: sign-extend ( bits v -- v' ) | |
swap [ ] [ 1 - 2^ < ] 2bi | |
[ -1 swap shift 1 + + ] [ drop ] if ; | |
: read1-jpeg-dc ( decoder -- dc ) | |
[ read1-huff dup ] [ bs>> bs:read ] bi sign-extend ; | |
: read1-jpeg-ac ( decoder -- run/ac ) | |
[ read1-huff 16 /mod dup ] [ bs>> bs:read ] bi sign-extend 2array ; | |
:: decode-block ( color -- pixels ) | |
color dc-huff-table>> read1-jpeg-dc color apply-diff | |
64 0 <array> :> coefs | |
0 coefs set-nth | |
0 :> k! | |
[ | |
color ac-huff-table>> read1-jpeg-ac | |
[ first 1 + k + k! ] [ second k coefs set-nth ] [ ] tri | |
{ 0 0 } = not | |
k 63 < and | |
] loop | |
coefs color quant-table>> v* | |
reverse-zigzag idct ; | |
:: draw-macroblock-yuv420 ( mb blocks -- ) | |
mb { 16 16 } v* :> pos | |
0 blocks nth pos { 0 0 } v+ 0 jpeg> draw-block | |
1 blocks nth pos { 8 0 } v+ 0 jpeg> draw-block | |
2 blocks nth pos { 0 8 } v+ 0 jpeg> draw-block | |
3 blocks nth pos { 8 8 } v+ 0 jpeg> draw-block | |
4 blocks nth 8 group 2 matrix-zoom concat pos 1 jpeg> draw-block | |
5 blocks nth 8 group 2 matrix-zoom concat pos 2 jpeg> draw-block ; | |
:: draw-macroblock-yuv444 ( mb blocks -- ) | |
mb { 8 8 } v* :> pos | |
3 <iota> [ [ blocks nth pos ] [ jpeg> draw-block ] bi ] each ; | |
:: draw-macroblock-y ( mb blocks -- ) | |
mb { 8 8 } v* :> pos | |
0 blocks nth pos 0 jpeg> draw-block | |
64 0 <array> pos 1 jpeg> draw-block | |
64 0 <array> pos 2 jpeg> draw-block ; | |
! %fixme: color hack | |
! color h>> 2 = | |
! [ 8 group 2 matrix-zoom concat ] unless | |
! pos { 8 8 } v* color jpeg> draw-block ; | |
: decode-macroblock ( -- blocks ) | |
jpeg> components>> | |
[ | |
[ mb-dim first2 * ] | |
[ [ decode-block ] curry replicate ] bi | |
] map concat ; | |
: cleanup-bitstream ( bytes -- bytes' ) | |
binary [ | |
[ | |
{ 0xFF } read-until | |
read1 [ 0x00 = and ] keep swap | |
] | |
[ drop ] produce | |
swap >marker { EOI } assert= | |
swap suffix | |
{ 0xFF } join | |
] with-byte-reader ; | |
: setup-bitmap ( image -- ) | |
dup dim>> 16 v/n [ ceiling ] map 16 v*n >>dim | |
BGR >>component-order | |
ubyte-components >>component-type | |
f >>upside-down? | |
dup dim>> first2 * 3 * 0 <array> >>bitmap | |
drop ; | |
ERROR: unsupported-colorspace ; | |
SINGLETONS: YUV420 YUV444 Y MAGIC! ; | |
:: detect-colorspace ( jpeg-image -- csp ) | |
jpeg-image color-info>> sift :> colors | |
MAGIC! | |
colors length 1 = [ drop Y ] when | |
colors length 3 = | |
[ | |
colors [ mb-dim { 1 1 } = ] all? | |
[ drop YUV444 ] when | |
colors unclip | |
[ [ mb-dim { 1 1 } = ] all? ] | |
[ mb-dim { 2 2 } = ] bi* and | |
[ drop YUV420 ] when | |
] when ; | |
! this eats ~50% cpu time | |
: draw-macroblocks ( mbs -- ) | |
jpeg> detect-colorspace | |
{ | |
{ YUV420 [ [ first2 draw-macroblock-yuv420 ] each ] } | |
{ YUV444 [ [ first2 draw-macroblock-yuv444 ] each ] } | |
{ Y [ [ first2 draw-macroblock-y ] each ] } | |
[ unsupported-colorspace ] | |
} case ; | |
! this eats ~25% cpu time | |
: color-transform ( yuv -- rgb ) | |
{ 128 0 0 } v+ yuv>bgr-matrix swap m.v | |
[ 0 max 255 min >fixnum ] map ; | |
: baseline-decompress ( -- ) | |
jpeg> bitstream>> cleanup-bitstream { 255 255 255 255 } append | |
>byte-array bs:<msb0-bit-reader> jpeg> bitstream<< | |
jpeg> | |
[ bitstream>> ] | |
[ [ [ <huffman-decoder> ] with map ] change-huff-tables drop ] bi | |
jpeg> components>> [ fetch-tables ] each | |
[ decode-macroblock 2array ] collector | |
[ all-macroblocks ] dip | |
jpeg> setup-bitmap draw-macroblocks | |
jpeg> bitmap>> 3 <groups> [ color-transform ] map! drop | |
jpeg> [ >byte-array ] change-bitmap drop ; | |
ERROR: not-a-jpeg-image ; | |
: loading-jpeg>image ( loading-jpeg -- image ) | |
dup jpeg-image [ | |
baseline-parse | |
baseline-decompress | |
] with-variable ; | |
: load-jpeg ( stream -- loading-jpeg ) | |
[ | |
parse-marker { SOI } = [ not-a-jpeg-image ] unless | |
parse-headers | |
contents <loading-jpeg> | |
] with-input-stream ; | |
PRIVATE> | |
M: jpeg-image stream>image ( stream jpeg-image -- bitmap ) | |
drop load-jpeg loading-jpeg>image ; | |
]] | |
FILE: [[ori/ori-tests.factor]] [[IN: ori.tests | |
USING: ori tools.test ; | |
\ pitch-up must-infer | |
\ pitch-down must-infer | |
\ turn-left must-infer | |
\ turn-right must-infer | |
\ roll-left must-infer | |
\ roll-right must-infer | |
]] | |
FILE: [[ori/authors.txt]] [[Eduardo Cavazos | |
]] | |
FILE: [[ori/ori.factor]] [[ | |
USING: kernel namespaces make accessors | |
math math.constants math.functions math.matrices math.vectors | |
sequences splitting grouping self math.trig ; | |
IN: ori | |
TUPLE: ori val ; | |
C: <ori> ori | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: ori> ( -- val ) self> val>> ; | |
: >ori ( val -- ) self> val<< ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: make-matrix ( quot width -- matrix ) [ { } make ] dip group ; inline | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! These rotation matrices are from | |
! `Computer Graphics: Principles and Practice' | |
: Rz ( angle -- Rx ) deg>rad | |
[ dup cos , dup sin neg , 0 , | |
dup sin , dup cos , 0 , | |
0 , 0 , 1 , ] 3 make-matrix nip ; | |
: Ry ( angle -- Ry ) deg>rad | |
[ dup cos , 0 , dup sin , | |
0 , 1 , 0 , | |
dup sin neg , 0 , dup cos , ] 3 make-matrix nip ; | |
: Rx ( angle -- Rz ) deg>rad | |
[ 1 , 0 , 0 , | |
0 , dup cos , dup sin neg , | |
0 , dup sin , dup cos , ] 3 make-matrix nip ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: apply-rotation ( rotation -- ) ori> swap m. >ori ; | |
: rotate-x ( angle -- ) Rx apply-rotation ; | |
: rotate-y ( angle -- ) Ry apply-rotation ; | |
: rotate-z ( angle -- ) Rz apply-rotation ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: pitch-up ( angle -- ) neg rotate-x ; | |
: pitch-down ( angle -- ) rotate-x ; | |
: turn-left ( angle -- ) rotate-y ; | |
: turn-right ( angle -- ) neg rotate-y ; | |
: roll-left ( angle -- ) neg rotate-z ; | |
: roll-right ( angle -- ) rotate-z ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! roll-until-horizontal | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: V ( -- V ) { 0 1 0 } ; | |
: X ( -- 3array ) ori> [ first ] map ; | |
: Y ( -- 3array ) ori> [ second ] map ; | |
: Z ( -- 3array ) ori> [ third ] map ; | |
: set-X ( seq -- ) ori> [ set-first ] 2each ; | |
: set-Y ( seq -- ) ori> [ set-second ] 2each ; | |
: set-Z ( seq -- ) ori> [ set-third ] 2each ; | |
: roll-until-horizontal ( -- ) | |
V Z cross normalize set-X | |
Z X cross normalize set-Y ; | |
]] | |
FILE: [[triggers/triggers.factor]] [[! Copyright (C) 2008 Alex Chapman | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: assocs digraphs kernel namespaces sequences ; | |
IN: triggers | |
: triggers ( -- triggers ) | |
\ triggers global [ drop H{ } clone ] cache ; | |
: trigger-graph ( trigger -- graph ) | |
triggers [ drop <digraph> ] cache ; | |
: reset-trigger ( trigger -- ) | |
<digraph> swap triggers set-at ; | |
: add-trigger ( key quot trigger -- ) | |
! trigger should be a symbol. Note that symbols with the same name but | |
! different vocab are not equal | |
trigger-graph add-vertex ; | |
: before ( key1 key2 trigger -- ) | |
trigger-graph add-edge ; | |
: after ( key1 key2 trigger -- ) | |
swapd before ; | |
: call-trigger ( trigger -- ) | |
trigger-graph topological-sorted-values [ call ] each ; | |
]] | |
FILE: [[triggers/summary.txt]] [[triggers allow you to register code to be 'triggered' | |
]] | |
FILE: [[triggers/authors.txt]] [[Alex Chapman | |
]] | |
FILE: [[triggers/triggers-tests.factor]] [[USING: triggers kernel tools.test ; | |
IN: triggers.tests | |
SYMBOL: test-trigger | |
test-trigger reset-trigger | |
: add-test-trigger test-trigger add-trigger ; | |
[ ] [ test-trigger call-trigger ] unit-test | |
[ "op called" ] [ "op" [ "op called" ] add-test-trigger test-trigger call-trigger ] unit-test | |
[ "first called" "second called" ] [ | |
test-trigger reset-trigger | |
"second op" [ "second called" ] add-test-trigger | |
"first op" [ "first called" ] add-test-trigger | |
test-trigger call-trigger | |
] unit-test | |
]] | |
FILE: [[ldap/ldap.factor]] [[! Copyright (C) 2007 Elie CHAFTARI | |
! See http://factorcode.org/license.txt for BSD license. | |
! | |
! Tested with OpenLDAP 2.2.7.0.21 on Mac OS X 10.4.9 PowerPC | |
USING: alien alien.c-types assocs continuations hashtables io kernel | |
ldap.libldap math namespaces sequences ; | |
IN: ldap | |
SYMBOL: message | |
SYMBOL: ldp | |
! ========================================================= | |
! Error interpretation routines | |
! ========================================================= | |
: result-to-error ( ld res freeit -- num ) | |
ldap_result2error ; | |
: err-to-string ( err -- str ) | |
ldap_err2string ; | |
: check-result ( result -- ) | |
dup zero? [ drop ] [ | |
err-to-string throw | |
] if ; | |
: result-type ( result -- ) | |
result-types >hashtable at print ; | |
! ========================================================= | |
! Initialization routines | |
! ========================================================= | |
! deprecated in favor of ldap_initialize | |
: open ( host port -- ld ) | |
ldap_open ; | |
! deprecated in favor of ldap_initialize | |
: init ( host port -- ld ) | |
ldap_init ; | |
: initialize ( ld url -- ) | |
dupd ldap_initialize swap *void* ldp set check-result ; | |
: get-option ( ld option outvalue -- ) | |
ldap_get_option check-result ; | |
: set-option ( ld option invalue -- ) | |
ldap_set_option check-result ; | |
! ========================================================= | |
! Bind operations | |
! ========================================================= | |
: simple-bind ( ld who passwd -- id ) | |
ldap_simple_bind ; | |
: simple-bind-s ( ld who passwd -- ) | |
ldap_simple_bind_s check-result ; | |
: unbind-s ( ld -- ) | |
ldap_unbind_s check-result ; | |
: with-bind ( ld who passwd quot -- ) | |
-roll [ simple-bind-s [ ldp get unbind-s ] [ ] cleanup ] with-scope ; inline | |
! ========================================================= | |
! Search operations | |
! ========================================================= | |
: search ( ld base scope filter attrs attrsonly -- id ) | |
ldap_search ; | |
: search-s ( ld base scope filter attrs attrsonly res -- ) | |
ldap_search_s check-result ; | |
! ========================================================= | |
! Return results of asynchronous operation routines | |
! ========================================================= | |
: result ( ld msgid all timeout result -- ) | |
[ ldap_result ] keep *void* message set result-type ; | |
: parse-result ( ld result errcodep matcheddnp errmsgp referralsp serverctrlsp freeit -- ) | |
ldap_parse_result check-result ; | |
: count-messages ( ld result -- count ) | |
ldap_count_messages ; | |
: first-message ( ld result -- message ) | |
ldap_first_message ; | |
: next-message ( ld message -- message ) | |
ldap_next_message ; | |
: msgtype ( msg -- num ) | |
ldap_msgtype ; | |
: msgid ( msg -- num ) | |
ldap_msgid ; | |
: count-entries ( ld result -- count ) | |
ldap_count_entries ; | |
: first-entry ( ld result -- entry ) | |
ldap_first_entry ; | |
: next-entry ( ld entry -- entry ) | |
ldap_next_entry ; | |
: first-attribute ( ld entry berptr -- str ) | |
ldap_first_attribute ; | |
: next-attribute ( ld entry ber -- str ) | |
ldap_next_attribute ; | |
: get-values ( ld entry attr -- values ) | |
ldap_get_values ; | |
: get-dn ( ld entry -- str ) | |
ldap_get_dn ; | |
! ========================================================= | |
! Public routines | |
! ========================================================= | |
: get-message ( -- message ) | |
message get ; | |
: get-ldp ( -- ldp ) | |
ldp get ; | |
]] | |
FILE: [[ldap/ldap-tests.factor]] [[USING: alien alien.c-types io kernel ldap ldap.libldap | |
namespaces prettyprint tools.test ; | |
IN: ldap.tests | |
"void*" <c-object> "ldap://localhost:389" initialize | |
get-ldp LDAP_OPT_PROTOCOL_VERSION LDAP_VERSION3 <int> set-option | |
[ 3 ] [ | |
get-ldp LDAP_OPT_PROTOCOL_VERSION "int*" <c-object> [ get-option ] keep | |
*int | |
] unit-test | |
[ | |
get-ldp "cn=jimbob,dc=example,dc=com" "secret" [ | |
! get-ldp "dc=example,dc=com" LDAP_SCOPE_ONELEVEL "(objectclass=*)" f 0 | |
! "void*" <c-object> [ search-s ] keep *int . | |
[ 2 ] [ | |
get-ldp "dc=example,dc=com" LDAP_SCOPE_SUBTREE "(objectclass=*)" f 0 | |
search | |
] unit-test | |
! get-ldp LDAP_RES_ANY 0 f "void*" <c-object> result . | |
get-ldp LDAP_RES_ANY LDAP_MSG_ALL f "void*" <c-object> result | |
! get-message *int . | |
"Message ID: " write | |
get-message msgid . | |
get-ldp get-message get-dn . | |
"Entries count: " write | |
get-ldp get-message count-entries . | |
SYMBOL: entry | |
SYMBOL: attr | |
"Attribute: " write | |
get-ldp get-message first-entry entry set get-ldp entry get | |
"void*" <c-object> first-attribute dup . attr set | |
"Value: " write | |
get-ldp entry get attr get get-values *char* . | |
get-ldp get-message first-message msgtype result-type | |
get-ldp get-message next-message msgtype result-type | |
] with-bind | |
] drop | |
]] | |
FILE: [[ldap/summary.txt]] [[OpenLDAP binding | |
]] | |
FILE: [[ldap/libldap/libldap.factor]] [[! Copyright (C) 2007 Elie CHAFTARI | |
! See http://factorcode.org/license.txt for BSD license. | |
! | |
! Tested with OpenLDAP 2.2.7.0.21 on Mac OS X 10.4.9 PowerPC | |
! | |
! export LD_LIBRARY_PATH=/opt/local/lib | |
USING: alien alien.syntax combinators kernel system ; | |
IN: ldap.libldap | |
<< "libldap" { | |
{ [ win32? ] [ "libldap.dll" stdcall ] } | |
{ [ macosx? ] [ "libldap.dylib" cdecl ] } | |
{ [ unix? ] [ "libldap.so" cdecl ] } | |
} cond add-library >> | |
: LDAP_VERSION1 1 ; inline | |
: LDAP_VERSION2 2 ; inline | |
: LDAP_VERSION3 3 ; inline | |
: LDAP_VERSION_MIN LDAP_VERSION2 ; inline | |
: LDAP_VERSION LDAP_VERSION2 ; inline | |
: LDAP_VERSION_MAX LDAP_VERSION3 ; inline | |
: LDAP_PORT 389 ; inline ! ldap:/// default LDAP port | |
: LDAPS_PORT 636 ; inline ! ldaps:/// default LDAP over TLS port | |
: LDAP_SCOPE_BASE 0x0000 ; inline | |
: LDAP_SCOPE_BASEOBJECT LDAP_SCOPE_BASE ; inline | |
: LDAP_SCOPE_ONELEVEL 0x0001 ; inline | |
: LDAP_SCOPE_ONE LDAP_SCOPE_ONELEVEL ; inline | |
: LDAP_SCOPE_SUBTREE 0x0002 ; inline | |
: LDAP_SCOPE_SUB LDAP_SCOPE_SUBTREE ; inline | |
: LDAP_SCOPE_SUBORDINATE 0x0003 ; inline ! OpenLDAP extension | |
: LDAP_SCOPE_CHILDREN LDAP_SCOPE_SUBORDINATE ; inline | |
: LDAP_SCOPE_DEFAULT -1 ; inline ! OpenLDAP extension | |
: LDAP_RES_ANY -1 ; inline | |
: LDAP_RES_UNSOLICITED 0 ; inline | |
! how many messages to retrieve results for | |
: LDAP_MSG_ONE 0x00 ; inline | |
: LDAP_MSG_ALL 0x01 ; inline | |
: LDAP_MSG_RECEIVED 0x02 ; inline | |
! the possible result types returned | |
: LDAP_RES_BIND 0x61 ; inline | |
: LDAP_RES_SEARCH_ENTRY 0x64 ; inline | |
: LDAP_RES_SEARCH_REFERENCE 0x73 ; inline | |
: LDAP_RES_SEARCH_RESULT 0x65 ; inline | |
: LDAP_RES_MODIFY 0x67 ; inline | |
: LDAP_RES_ADD 0x69 ; inline | |
: LDAP_RES_DELETE 0x6b ; inline | |
: LDAP_RES_MODDN 0x6d ; inline | |
: LDAP_RES_COMPARE 0x6f ; inline | |
: LDAP_RES_EXTENDED 0x78 ; inline | |
: LDAP_RES_EXTENDED_PARTIAL 0x79 ; inline | |
: result-types ( -- seq ) { | |
{ 0x61 "LDAP_RES_BIND" } | |
{ 0x64 "LDAP_RES_SEARCH_ENTRY" } | |
{ 0x73 "LDAP_RES_SEARCH_REFERENCE" } | |
{ 0x65 "LDAP_RES_SEARCH_RESULT" } | |
{ 0x67 "LDAP_RES_MODIFY" } | |
{ 0x69 "LDAP_RES_ADD" } | |
{ 0x6b "LDAP_RES_DELETE" } | |
{ 0x6d "LDAP_RES_MODDN" } | |
{ 0x6f "LDAP_RES_COMPARE" } | |
{ 0x78 "LDAP_RES_EXTENDED" } | |
{ 0x79 "LDAP_RES_EXTENDED_PARTIAL" } | |
} ; | |
: LDAP_OPT_PROTOCOL_VERSION 0x0011 ; inline | |
C-STRUCT: ldap | |
{ "char" "ld_lberoptions" } | |
{ "int" "ld_deref" } | |
{ "int" "ld_timelimit" } | |
{ "int" "ld_sizelimit" } | |
{ "int" "ld_errno" } | |
{ "char*" "ld_error" } | |
{ "char*" "ld_matched" } | |
{ "int" "ld_refhoplimit" } | |
{ "ulong" "ld_options" } ; | |
LIBRARY: libldap | |
! =============================================== | |
! ldap.h | |
! =============================================== | |
! Will be depreciated in a later release (ldap_init() is preferred) | |
FUNCTION: void* ldap_open ( char* host, int port ) ; | |
FUNCTION: void* ldap_init ( char* host, int port ) ; | |
FUNCTION: int ldap_initialize ( ldap* ld, char* url ) ; | |
FUNCTION: int ldap_get_option ( void* ld, int option, void* outvalue ) ; | |
FUNCTION: int ldap_set_option ( void* ld, int option, void* invalue ) ; | |
FUNCTION: int ldap_simple_bind ( void* ld, char* who, char* passwd ) ; | |
FUNCTION: int ldap_simple_bind_s ( void* ld, char* who, char* passwd ) ; | |
FUNCTION: int ldap_unbind_s ( void* ld ) ; | |
FUNCTION: int ldap_result2error ( void* ld, void* res, int freeit ) ; | |
FUNCTION: char* ldap_err2string ( int err ) ; | |
FUNCTION: int ldap_search ( void* ld, char* base, int scope, char* filter, | |
char* attrs, int attrsonly ) ; | |
FUNCTION: int ldap_search_s ( void* ld, char* base, int scope, char* filter, | |
char* attrs, int attrsonly, void* res ) ; | |
FUNCTION: int ldap_result ( void* ld, int msgid, int all, void* timeout, | |
void* result ) ; | |
FUNCTION: int ldap_parse_result ( void* ld, void* result, int* errcodep, | |
char* matcheddnp, char* errmsgp, | |
char* referralsp, void* serverctrlsp, | |
int freeit ) ; | |
FUNCTION: int ldap_count_messages ( void* ld, void* result ) ; | |
FUNCTION: void* ldap_first_message ( void* ld, void* result ) ; | |
FUNCTION: void* ldap_next_message ( void* ld, void* message ) ; | |
FUNCTION: int ldap_msgtype ( void* msg ) ; | |
FUNCTION: int ldap_msgid ( void* msg ) ; | |
FUNCTION: int ldap_count_entries ( void* ld, void* result ) ; | |
FUNCTION: void* ldap_first_entry ( void* ld, void* result ) ; | |
FUNCTION: void* ldap_next_entry ( void* ld, void* entry ) ; | |
FUNCTION: char* ldap_first_attribute ( void* ld, void* entry, void* berptr ) ; | |
FUNCTION: char* ldap_next_attribute ( void* ld, void* entry, void* ber ) ; | |
FUNCTION: char** ldap_get_values ( void* ld, void* entry, char* attr ) ; | |
FUNCTION: char* ldap_get_dn ( void* ld, void* entry ) ; | |
]] | |
FILE: [[ldap/libldap/authors.txt]] [[Elie Chaftari | |
]] | |
FILE: [[ldap/libldap/tags.txt]] [[bindings | |
]] | |
FILE: [[ldap/authors.txt]] [[Elie Chaftari | |
]] | |
FILE: [[ldap/conf/createdit.ldif]] [[# this is a comment # MUST be in FIRST column - very picky | |
## DEFINE DIT ROOT/BASE/SUFFIX #### | |
## uses RFC 2377 format | |
## replace example and com as necessary below | |
## or for experimentation leave as is | |
## dcObject is an AUXILLIARY objectclass and MUST | |
## have a STRUCTURAL objectclass (organization in this case) | |
# this is an ENTRY sequence and is preceded by a BLANK line | |
dn: dc=example,dc=com | |
dc: example | |
description: My wonderful company as much text as you want to place in this line up to 32K | |
continuation data for the line above must have <CR> or <CR><LF> i.e. ENTER works | |
on both Windows and *nix system - new line MUST begin with ONE SPACE | |
objectClass: dcObject | |
objectClass: organization | |
o: Example, Inc. | |
## FIRST Level hierarchy - people | |
## uses mixed upper and lower case for objectclass | |
# this is an ENTRY sequence and is preceded by a BLANK line | |
dn: ou=people, dc=example,dc=com | |
ou: people | |
description: All people in organisation | |
objectclass: organizationalunit | |
## SECOND Level hierarchy | |
## ADD a single entry under FIRST (people) level | |
# this is an ENTRY sequence and is preceded by a BLANK line | |
# the ou: Human Resources is the department name | |
dn: cn=Robert Forest,ou=people,dc=example,dc=com | |
objectclass: inetOrgPerson | |
cn: Robert Forest | |
sn: Forest | |
uid: 0 | |
userpassword: rForest | |
carlicense: HISCAR 123 | |
homephone: 555-111-2222 | |
mail: r.forest@example.com | |
description: swell guy | |
# ou: Human Resources]] | |
FILE: [[ldap/conf/slapd.conf]] [[# | |
###### SAMPLE 1 - SIMPLE DIRECTORY ############ | |
# | |
# NOTES: inetorgperson picks up attributes and objectclasses | |
# from all three schemas | |
# | |
# NB: RH Linux schemas in /etc/openldap | |
# | |
include /opt/local/etc/openldap/schema/core.schema | |
include /opt/local/etc/openldap/schema/cosine.schema | |
include /opt/local/etc/openldap/schema/inetorgperson.schema | |
# NO SECURITY - no access clause | |
# defaults to anonymous access for read | |
# only rootdn can write | |
# NO REFERRALS | |
# DON'T bother with ARGS file unless you feel strongly | |
# slapd scripts stop scripts need this to work | |
pidfile /opt/local/var/run/run/slapd.pid | |
# enable a lot of logging - we might need it | |
# but generates huge logs | |
loglevel -1 | |
# NO dynamic backend modules | |
# NO TLS-enabled connections | |
# backend definition not required | |
####################################################################### | |
# bdb database definitions | |
# | |
# replace example and com below with a suitable domain | |
# | |
# If you don't have a domain you can leave it since example.com | |
# is reserved for experimentation or change them to my and inc | |
# | |
####################################################################### | |
database bdb | |
suffix "dc=example, dc=com" | |
# root or superuser | |
rootdn "cn=jimbob, dc=example, dc=com" | |
rootpw secret | |
# The database directory MUST exist prior to running slapd AND | |
# change path as necessary | |
directory /opt/local/var/run/openldap-data | |
# Indices to maintain for this directory | |
# unique id so equality match only | |
index uid eq | |
# allows general searching on commonname, givenname and email | |
index cn,gn,mail eq,sub | |
# allows multiple variants on surname searching | |
index sn eq,sub,subany,subfinal | |
# optimise department searches | |
index ou eq | |
# shows use of default index parameter | |
index default eq,sub | |
# indices missing - uses default eq,sub | |
index telephonenumber | |
]] | |
FILE: [[ldap/conf/addentry.ldif]] [[## ADD a single entry to people level | |
dn: cn=John Spider,ou=people,dc=example,dc=com | |
objectclass: inetOrgPerson | |
cn: John Spider | |
sn: Spider | |
uid: 1 | |
userpassword: jSpider | |
carlicense: HISCAR 124 | |
homephone: 555-111-2223 | |
mail: j.spider@example.com | |
# ou: Sales | |
## ADD another single entry to people level | |
dn: cn=Sheri Matsumo,ou=people,dc=example,dc=com | |
objectclass: inetOrgPerson | |
cn: Sheri Matsumo | |
sn: Matsumo | |
uid: 2 | |
userpassword: sMatsumo | |
carlicense: HERCAR 125 | |
homephone: 555-111-2225 | |
mail: s.matsumo@example.com | |
# ou: IT]] | |
FILE: [[ldap/tags.txt]] [[enterprise | |
network | |
]] | |
FILE: [[4DNav/4DNav-docs.factor]] base64[[ISBDb3B5cmlnaHQgKEMpIDIwMDggSmVhbi1GcmFu529pcyBCaWdvdC4KISBTZWUgaHR0cDovL2ZhY3RvcmNvZGUub3JnL2xpY2Vuc2UudHh0IGZvciBCU0QgbGljZW5zZS4KVVNJTkc6IGhlbHAubWFya3VwIGhlbHAuc3ludGF4IGtlcm5lbCBxdW90YXRpb25zIHN0cmluZ3MgOwpJTjogNEROYXYKCgpIRUxQOiBtZW51LTNECnsgJHZhbHVlcwogICAgIHsgImdhZGdldCIgImdhZGdldCIgfQp9CnsgJGRlc2NyaXB0aW9uICJUaGUgbWVudSBkZWRpY2F0ZWQgdG8gM0QgbW92ZW1lbnRzIG9mIHRoZSBjYW1lcmEiIH0gOwoKSEVMUDogbWVudS00RAp7ICR2YWx1ZXMKICAgIAogICAgIHsgImdhZGdldCIgImdhZGdldCIgfQp9CnsgJGRlc2NyaXB0aW9uICJUaGUgbWVudSBkZWRpY2F0ZWQgdG8gNEQgbW92ZW1lbnRzIG9mIHNwYWNlIiB9IDsKCkhFTFA6IG1lbnUtYmFyCnsgJHZhbHVlcwogICAgCiAgICAgeyAiZ2FkZ2V0IiAiZ2FkZ2V0IiB9Cn0KeyAkZGVzY3JpcHRpb24gInJldHVybiBnYWRnZXQgY29udGFpbmluZyBtZW51IGJ1dHRvbnMiIH0gOwoKSEVMUDogbW9kZWwtcHJvamVjdGlvbgp7ICR2YWx1ZXMKICAgICB7ICJ4IiAiaW50ZXJnZXIiIH0KICAgICB7ICJzcGFjZSIgInNwYWNlIiB9Cn0KeyAkZGVzY3JpcHRpb24gIlByb2plY3Qgc3BhY2UgZm9sbG93aW5nIGNvb3JkaW5hdGUgeCIgfSA7CgpIRUxQOiBtdnQtM0QtMQp7ICR2YWx1ZXMKICAgIAogICAgIHsgInF1b3QiICJxdW90YXRpb24iIH0KfQp7ICRkZXNjcmlwdGlvbiAicmV0dXJuIGEgcXVvdGF0aW9uIHRvIG9yaWVudGF0ZSBzcGFjZSB0byBzZWUgaXQgZnJvbSBmaXJzdCBwb2ludCBvZiB2aWV3IiB9IDsKCkhFTFA6IG12dC0zRC0yCnsgJHZhbHVlcwogICAgCiAgICAgeyAicXVvdCIgInF1b3RhdGlvbiIgfQp9CnsgJGRlc2NyaXB0aW9uICJyZXR1cm4gYSBxdW90YXRpb24gdG8gb3JpZW50YXRlIHNwYWNlIHRvIHNlZSBpdCBmcm9tIHNlY29uZCBwb2ludCBvZiB2aWV3IiB9IDsKCkhFTFA6IG12dC0zRC0zCnsgJHZhbHVlcwogICAgCiAgICAgeyAicXVvdCIgInF1b3RhdGlvbiIgfQp9CnsgJGRlc2NyaXB0aW9uICJyZXR1cm4gYSBxdW90YXRpb24gdG8gb3JpZW50YXRlIHNwYWNlIHRvIHNlZSBpdCBmcm9tIHRoaXJkIHBvaW50IG9mIHZpZXciIH0gOwoKSEVMUDogbXZ0LTNELTQKeyAkdmFsdWVzCiAgICAKICAgICB7ICJxdW90IiAicXVvdGF0aW9uIiB9Cn0KeyAkZGVzY3JpcHRpb24gInJldHVybiBhIHF1b3RhdGlvbiB0byBvcmllbnRhdGUgc3BhY2UgdG8gc2VlIGl0IGZyb20gZmlyc3QgcG9pbnQgb2YgdmlldyIgfSA7CgpIRUxQOiBsb2FkLW1vZGVsLWZpbGUKeyAkZGVzY3JpcHRpb24gImxvYWQgc3BhY2UgZnJvbSBmaWxlIiB9IDsKCkhFTFA6IHJvdGF0aW9uLTRECnsgJHZhbHVlcwogICAgIHsgIm0iICJhIHJvdGF0aW9uIG1hdHJpeCIgfQp9CnsgJGRlc2NyaXB0aW9uICJBcHBseSBhIDREIHJvdGF0aW9uIG1hdHJpeCIgfSA7CgpIRUxQOiB0cmFuc2xhdGlvbi00RAp7ICR2YWx1ZXMKICAgICB7ICJ2IiAidmVjdG9yIiB9Cn0KeyAkZGVzY3JpcHRpb24gIkFwcGx5IGEgNEQgdHJhbnNsYXRpb24iIH0gOwoKCkFSVElDTEU6ICJpbXBsZW1lbnRhdGlvbiBkZXRhaWxzIiAiSG93IDRETmF2IGlzIGRvbmUiCiI0RE5hdiBpcyBidWlsZCB1c2luZyA6IgoKeyAkc3Vic2VjdGlvbnMKICAgICI0RE5hdi5jYW1lcmEiCiAgICAiYWRzb2RhLW1haW4tcGFnZSIKfQo7CgpBUlRJQ0xFOiAiU3BhY2UgZmlsZSIgIkNyZWF0ZSBhIG5ldyBzcGFjZSBmaWxlIgoiVG8gYnVpbGQgYSBuZXcgc3BhY2UsIGNyZWF0ZSBhbiBYTUwgZmlsZSB1c2luZyAiIHsgJHZvY2FiLWxpbmsgImFkc29kYSIgfSAiIG1vZGVsIGRlc2NyaXB0aW9uLiBBIHNvbGlkIGlzIG5vdCBjYXJhY3Rlcml6ZWQgYnkgaXRzIGNvcm5lcnMgYnV0IGlzIGRlZmluZWQgYXMgdGhlIGludGVyc2VjdGlvbiBvZiBoeXBlcnBsYW5lcy4iCgokbmwKIkFuIGV4YW1wbGUgaXM6Igp7ICRjb2RlICIiIgo8bW9kZWw+CjxzcGFjZT4KIDxkaW1lbnNpb24+NDwvZGltZW5zaW9uPgogPHNvbGlkPgogICAgIDxuYW1lPjRjdWJlMTwvbmFtZT4KICAgICA8ZGltZW5zaW9uPjQ8L2RpbWVuc2lvbj4KICAgICA8ZmFjZT4xLDAsMCwwLDEwMDwvZmFjZT4KICAgICA8ZmFjZT4tMSwwLDAsMCwtMTUwPC9mYWNlPgogICAgIDxmYWNlPjAsMSwwLDAsMTAwPC9mYWNlPgogICAgIDxmYWNlPjAsLTEsMCwwLC0xNTA8L2ZhY2U+CiAgICAgPGZhY2U+MCwwLDEsMCwxMDA8L2ZhY2U+CiAgICAgPGZhY2U+MCwwLC0xLDAsLTE1MDwvZmFjZT4KICAgICA8ZmFjZT4wLDAsMCwxLDEwMDwvZmFjZT4KICAgICA8ZmFjZT4wLDAsMCwtMSwtMTUwPC9mYWNlPgogICAgIDxjb2xvcj4xLDAsMDwvY29sb3I+CiA8L3NvbGlkPgogPHNvbGlkPgogICAgIDxuYW1lPjR0cmlhbmN1YmU8L25hbWU+CiAgICAgPGRpbWVuc2lvbj40PC9kaW1lbnNpb24+CiAgICAgPGZhY2U+MSwwLDAsMCwxNjA8L2ZhY2U+CiAgICAgPGZhY2U+LTAuNDk5OTk5OTk5OTk5OTk5OCwtMC44NjYwMjU0MDM3ODQ0Mzg3LDAsMCwtMTMwPC9mYWNlPgogICAgIDxmYWNlPi0wLjUwMDAwMDAwMDAwMDAwMDQsMC44NjYwMjU0MDM3ODQ0Mzg0LDAsMCwtMTMwPC9mYWNlPgogICAgIDxmYWNlPjAsMCwxLDAsMTQwPC9mYWNlPgogICAgIDxmYWNlPjAsMCwtMSwwLC0xODA8L2ZhY2U+CiAgICAgPGZhY2U+MCwwLDAsMSwxMTA8L2ZhY2U+CiAgICAgPGZhY2U+MCwwLDAsLTEsLTE4MDwvZmFjZT4KICAgICA8Y29sb3I+MCwxLDA8L2NvbG9yPgogPC9zb2xpZD4KIDxzb2xpZD4KICAgICA8bmFtZT50cmlhbmdvbmU8L25hbWU+CiAgICAgPGRpbWVuc2lvbj40PC9kaW1lbnNpb24+CiAgICAgPGZhY2U+MSwwLDAsMCw2MDwvZmFjZT4KICAgICA8ZmFjZT4wLjUsMC44NjYwMjU0MDM3ODQ0Mzg2LDAsMCw2MDwvZmFjZT4KICAgICA8ZmFjZT4tMC41LDAuODY2MDI1NDAzNzg0NDM4NywwLDAsLTIwPC9mYWNlPgogICAgIDxmYWNlPi0xLjAsMCwwLDAsLTEwMDwvZmFjZT4KICAgICA8ZmFjZT4tMC41LC0wLjg2NjAyNTQwMzc4NDQzODQsMCwwLC0xMDA8L2ZhY2U+CiAgICAgPGZhY2U+MC41LC0wLjg2NjAyNTQwMzc4NDQzODcsMCwwLC0yMDwvZmFjZT4KICAgICA8ZmFjZT4wLDAsMSwwLDEyMDwvZmFjZT4KICAgICA8ZmFjZT4wLDAsLTAuNDk5OTk5OTk5OTk5OTk5OCwtMC44NjYwMjU0MDM3ODQ0Mzg3LC0xMjA8L2ZhY2U+CiAgICAgPGZhY2U+MCwwLC0wLjUwMDAwMDAwMDAwMDAwMDQsMC44NjYwMjU0MDM3ODQ0Mzg0LC0xMjA8L2ZhY2U+CiAgICAgPGNvbG9yPjAsMSwxPC9jb2xvcj4KIDwvc29saWQ+CiA8bGlnaHQ+CiAgICAgPGRpcmVjdGlvbj4xLDEsMSwxPC9kaXJlY3Rpb24+CiAgICAgPGNvbG9yPjAuMiwwLjIsMC42PC9jb2xvcj4KIDwvbGlnaHQ+CiA8Y29sb3I+MC44LDAuOSwwLjk8L2NvbG9yPgo8L3NwYWNlPgo8L21vZGVsPiIiIiB9IDsKCkFSVElDTEU6ICJUT0RPIiAiVG9kbyIKeyAkbGlzdCAKICAgICJBIHZvY2FiIHRvIGluaXRpYWxpemUgcGFyYW1ldGVycyIKICAgICJhbiBlZGl0b3IgbW9kZSIgCiAgICAgICAgeyAkbGlzdCAiYWRkIGEgZmFjZSB0byBhIHNvbGlkIgogICAgICAgICAgICAgICAgImFkZCBhIHNvbGlkIHRvIHRoZSBzcGFjZSIKICAgICAgICAgICAgICAgICJtb3ZlIGEgZmFjZSIKICAgICAgICAgICAgICAgICJtb3ZlIGEgc29saWQiCiAgICAgICAgICAgICAgICAic2VsZWN0IGEgc29saWQgaW4gYSBsaXN0IgogICAgICAgICAgICAgICAgInNlbGVjdCBhIGZhY2UiCiAgICAgICAgICAgICAgICAiZGlzcGxheSBzZWxlY3RlZCBmYWNlIgogICAgICAgICAgICAgICAgImVkaXQgYSBzb2xpZCBjb2xvciIKICAgICAgICAgICAgICAgICJhZGQgYSBsaWdodCIKICAgICAgICAgICAgICAgICJlZGl0IGEgbGlnaHQgY29sb3IiCiAgICAgICAgICAgICAgICAibW92ZSBhIGxpZ2h0IgogICAgICAgICAgICAgICAgfQogICAgImFkZCBhIHRvb2wgd2ljaCBnaXZlIGFuIGh5cGVycGxhbmUgbm9ybWFsIHZlY3RvciB3aXRoIGVub3VnaHQgcG9pbnRzLiBXaWxsIHVzZSBhZHNvZGEuaW50ZXJzZWN0LWh5cGVycGxhbmVzIHdpdGggeyB7IDAgfSB7IDAgfSB7IDEgfSB9ICIKICAgICJkZWNvcnJlbGF0ZSAzRCBjYW1lcmEgYW5kIGFjdGl2YXRlIHRoZW0gd2l0aCBzZWxlY3QgYnV0dG9ucyIKCn0gOwoKCkFSVElDTEU6ICI0RE5hdiIgIlRoZSA0RE5hdiBhcHAiCnsgJHZvY2FiLWxpbmsgIjRETmF2IiB9CiRubAp7ICRoZWFkaW5nICI0RCBOYXZpZ2F0b3IiIH0KIjRETmF2IGlzIGEgc2ltcGxlIHRvb2wgdG8gdmlzdWFsaXplIDQgZGltZW5zaW9ubmFsIG9iamVjdHMuIgokbmwKIkl0IHVzZXMgIiB7ICR2b2NhYi1saW5rICJhZHNvZGEiIH0gIiBsaWJyYXJ5IHRvIGRpc3BsYXkgYSA0RCBzcGFjZSBhbmQgbmF2aWdhdGUgdGhydSBpdC4iCiRubAoiSXQgd2lsbCBkaXNwbGF5OiIKeyAkbGlzdAogICAgeyAiYSBtZW51IHdpbmRvdyIgfQogICAgeyAgIjQgdmlzdWFsaXphdGlvbiB3aW5kb3dzIiB9Cn0KIkVhY2ggdmlzdWFsaXphdGlvbiB3aW5kb3cgcmVwcmVzZW50cyB0aGUgcHJvamVjdGlvbiBvZiB0aGUgNEQgc3BhY2Ugb24gYSBwYXJ0aWN1bGFyIDNEIHNwYWNlLiIKCnsgJGhlYWRpbmcgIlN0YXJ0IiB9CiJ0eXBlOiIgeyAkY29kZSAiXCI0RE5hdlwiIHJ1biIgfSAKCnsgJGhlYWRpbmcgIk5hdmlnYXRpb24iIH0KIk1lbnUgd2luZG93IGlzIGRpdmlkZWQgaW4gNCBhcmVhcyIKeyAkbGlzdAogICAgeyAiYSBzcGFjZS1maWxlIGNob29zZXIgdG8gc2VsZWN0IHRoZSBmaWxlIHRvIGRpc3BsYXkiIH0KICAgIHsgImEgcGFyYW1ldHJpemF0aW9uIGFyZWEgdG8gc2VsZWN0IHRoZSBwcm9qZWN0aW9uIG1vZGUiIH0KICAgIHsgIjREIHN1Ym1lbnUgdG8gdHJhbnNsYXRlIGFuZCByb3RhdGUgdGhlIDREIHNwYWNlIiB9CiAgICB7ICIzRCBzdWJtZW51IHRvIG1vdmUgdGhlIGNhbWVyYSBpbiAzRCBzcGFjZS4gQ2FtZXJhcyBpbiBldmVyeSAzRCBzcGFjZXMgYXJlIG1hbmlwdWxhdGVkIGFzIGEgc2luZ2xlIG9uZSIgfQogICAgfQoKeyAkaGVhZGluZyAiTGlua3MiIH0KeyAkc3Vic2VjdGlvbnMKICAgICJTcGFjZSBmaWxlIgogICAgIlRPRE8iCiAgICAiaW1wbGVtZW50YXRpb24gZGV0YWlscyIKfQoKOwoKQUJPVVQ6ICI0RE5hdiIK]] | |
FILE: [[4DNav/turtle/turtle.factor]] [[USING: kernel math arrays math.vectors math.matrices namespaces make | |
math.constants math.functions splitting grouping math.trig sequences | |
accessors 4DNav.deep models vars ; | |
IN: 4DNav.turtle | |
! replacement of self | |
VAR: self | |
: with-self ( quot obj -- ) [ >self call ] with-scope ; inline | |
: save-self ( quot -- ) self> [ self> clone >self call ] dip >self ; inline | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
TUPLE: turtle pos ori ; | |
: <turtle> ( -- turtle ) | |
turtle new | |
{ 0 0 0 } clone >>pos | |
3 identity-matrix >>ori | |
; | |
TUPLE: observer < turtle projection-mode collision-mode ; | |
: <observer> ( -- object ) | |
observer new | |
0 <model> >>projection-mode | |
f <model> >>collision-mode | |
; | |
: turtle-pos> ( -- val ) self> pos>> ; | |
: >turtle-pos ( val -- ) self> pos<< ; | |
: turtle-ori> ( -- val ) self> ori>> ; | |
: >turtle-ori ( val -- ) self> ori<< ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! These rotation matrices are from | |
! `Computer Graphics: Principles and Practice' | |
! waiting for deep-cleave-quots | |
! : Rz ( angle -- Rx ) deg>rad | |
! { { [ cos ] [ sin neg ] 0 } | |
! { [ sin ] [ cos ] 0 } | |
! { 0 0 1 } | |
! } deep-cleave-quots ; | |
! : Ry ( angle -- Ry ) deg>rad | |
! { { [ cos ] 0 [ sin ] } | |
! { 0 1 0 } | |
! { [ sin neg ] 0 [ cos ] } | |
! } deep-cleave-quots ; | |
! : Rx ( angle -- Rz ) deg>rad | |
! { { 1 0 0 } | |
! { 0 [ cos ] [ sin neg ] } | |
! { 0 [ sin ] [ cos ] } | |
! } deep-cleave-quots ; | |
: Rz ( angle -- Rx ) deg>rad | |
[ dup cos , dup sin neg , 0 , | |
dup sin , dup cos , 0 , | |
0 , 0 , 1 , ] 3 make-matrix nip ; | |
: Ry ( angle -- Ry ) deg>rad | |
[ dup cos , 0 , dup sin , | |
0 , 1 , 0 , | |
dup sin neg , 0 , dup cos , ] 3 make-matrix nip ; | |
: Rx ( angle -- Rz ) deg>rad | |
[ 1 , 0 , 0 , | |
0 , dup cos , dup sin neg , | |
0 , dup sin , dup cos , ] 3 make-matrix nip ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: apply-rotation ( rotation -- ) | |
turtle-ori> swap m. >turtle-ori ; | |
: rotate-x ( angle -- ) Rx apply-rotation ; | |
: rotate-y ( angle -- ) Ry apply-rotation ; | |
: rotate-z ( angle -- ) Rz apply-rotation ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: pitch-up ( angle -- ) neg rotate-x ; | |
: pitch-down ( angle -- ) rotate-x ; | |
: turn-left ( angle -- ) rotate-y ; | |
: turn-right ( angle -- ) neg rotate-y ; | |
: roll-left ( angle -- ) neg rotate-z ; | |
: roll-right ( angle -- ) rotate-z ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! roll-until-horizontal | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: V ( -- V ) { 0 1 0 } ; | |
: X ( -- 3array ) turtle-ori> [ first ] map ; | |
: Y ( -- 3array ) turtle-ori> [ second ] map ; | |
: Z ( -- 3array ) turtle-ori> [ third ] map ; | |
: set-X ( seq -- ) turtle-ori> [ set-first ] 2each ; | |
: set-Y ( seq -- ) turtle-ori> [ set-second ] 2each ; | |
: set-Z ( seq -- ) turtle-ori> [ set-third ] 2each ; | |
: roll-until-horizontal ( -- ) | |
V Z cross normalize set-X | |
Z X cross normalize set-Y ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: distance ( turtle turtle -- n ) | |
pos>> swap pos>> v- [ sq ] map-sum sqrt ; | |
: move-by ( point -- ) turtle-pos> v+ >turtle-pos ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: reset-turtle ( -- ) | |
{ 0 0 0 } clone >turtle-pos 3 identity-matrix >turtle-ori ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: step-vector ( length -- array ) { 0 0 1 } n*v ; | |
: step-turtle ( length -- ) | |
step-vector turtle-ori> swap m.v | |
turtle-pos> v+ >turtle-pos ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: strafe-up ( length -- ) | |
90 pitch-up | |
step-turtle | |
90 pitch-down ; | |
: strafe-down ( length -- ) | |
90 pitch-down | |
step-turtle | |
90 pitch-up ; | |
: strafe-left ( length -- ) | |
90 turn-left | |
step-turtle | |
90 turn-right ; | |
: strafe-right ( length -- ) | |
90 turn-right | |
step-turtle | |
90 turn-left ; | |
]] | |
FILE: [[4DNav/turtle/authors.txt]] [[Eduardo Cavazos | |
]] | |
FILE: [[4DNav/turtle/turtle-docs.factor]] base64[[ISBDb3B5cmlnaHQgKEMpIDIwMDggSmVhbi1GcmFuw6dvaXMgQmlnb3QuCiEgU2VlIGh0dHA6Ly9mYWN0b3Jjb2RlLm9yZy9saWNlbnNlLnR4dCBmb3IgQlNEIGxpY2Vuc2UuClVTSU5HOiBhcnJheXMgaGVscC5tYXJrdXAgaGVscC5zeW50YXgga2VybmVsIHNlcXVlbmNlcyA7CklOOiA0RE5hdi50dXJ0bGUKCgpBUlRJQ0xFOiAiNEROYXYudHVydGxlIiAiVHVydGxlIgp7ICR2b2NhYi1saW5rICI0RE5hdi50dXJ0bGUiIH0KOwoKQUJPVVQ6ICI0RE5hdi50dXJ0bGUiCg==]] | |
FILE: [[4DNav/4DNav.factor]] [[! Copyright (C) 2008 Jeff Bigot | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: kernel | |
namespaces | |
accessors | |
assocs | |
make | |
math | |
math.functions | |
math.trig | |
math.parser | |
hashtables | |
sequences | |
combinators | |
continuations | |
colors | |
colors.constants | |
prettyprint | |
vars | |
quotations | |
io | |
io.directories | |
io.pathnames | |
help.markup | |
io.files | |
ui.gadgets.panes | |
ui | |
ui.gadgets | |
ui.traverse | |
ui.gadgets.borders | |
ui.gadgets.frames | |
ui.gadgets.tracks | |
ui.gadgets.labels | |
ui.gadgets.labeled | |
ui.gadgets.lists | |
ui.gadgets.buttons | |
ui.gadgets.packs | |
ui.gadgets.grids | |
ui.gadgets.corners | |
ui.gestures | |
ui.gadgets.scrollers | |
splitting | |
vectors | |
math.vectors | |
values | |
4DNav.turtle | |
4DNav.window3D | |
4DNav.deep | |
4DNav.space-file-decoder | |
models | |
fry | |
adsoda | |
adsoda.tools | |
; | |
QUALIFIED-WITH: ui.pens.solid s | |
QUALIFIED-WITH: ui.gadgets.wrappers w | |
IN: 4DNav | |
VALUE: selected-file | |
VALUE: translation-step | |
VALUE: rotation-step | |
3 \ translation-step set-value | |
5 \ rotation-step set-value | |
VAR: selected-file-model | |
VAR: observer3d | |
VAR: view1 | |
VAR: view2 | |
VAR: view3 | |
VAR: view4 | |
VAR: present-space | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! namespace utilities | |
: closed-quot ( quot -- quot ) | |
namestack swap '[ namestack [ _ set-namestack @ ] dip set-namestack ] ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! waiting for deep-cleave-quots | |
: 4D-Rxy ( angle -- Rx ) deg>rad | |
[ 1.0 , 0.0 , 0.0 , 0.0 , | |
0.0 , 1.0 , 0.0 , 0.0 , | |
0.0 , 0.0 , dup cos , dup sin neg , | |
0.0 , 0.0 , dup sin , dup cos , ] 4 make-matrix nip ; | |
: 4D-Rxz ( angle -- Ry ) deg>rad | |
[ 1.0 , 0.0 , 0.0 , 0.0 , | |
0.0 , dup cos , 0.0 , dup sin neg , | |
0.0 , 0.0 , 1.0 , 0.0 , | |
0.0 , dup sin , 0.0 , dup cos , ] 4 make-matrix nip ; | |
: 4D-Rxw ( angle -- Rz ) deg>rad | |
[ 1.0 , 0.0 , 0.0 , 0.0 , | |
0.0 , dup cos , dup sin neg , 0.0 , | |
0.0 , dup sin , dup cos , 0.0 , | |
0.0 , 0.0 , 0.0 , 1.0 , ] 4 make-matrix nip ; | |
: 4D-Ryz ( angle -- Rx ) deg>rad | |
[ dup cos , 0.0 , 0.0 , dup sin neg , | |
0.0 , 1.0 , 0.0 , 0.0 , | |
0.0 , 0.0 , 1.0 , 0.0 , | |
dup sin , 0.0 , 0.0 , dup cos , ] 4 make-matrix nip ; | |
: 4D-Ryw ( angle -- Ry ) deg>rad | |
[ dup cos , 0.0 , dup sin neg , 0.0 , | |
0.0 , 1.0 , 0.0 , 0.0 , | |
dup sin , 0.0 , dup cos , 0.0 , | |
0.0 , 0.0 , 0.0 , 1.0 , ] 4 make-matrix nip ; | |
: 4D-Rzw ( angle -- Rz ) deg>rad | |
[ dup cos , dup sin neg , 0.0 , 0.0 , | |
dup sin , dup cos , 0.0 , 0.0 , | |
0.0 , 0.0 , 1.0 , 0.0 , | |
0.0 , 0.0 , 0.0 , 1.0 , ] 4 make-matrix nip ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! UI | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: button* ( string quot -- button ) | |
closed-quot <repeat-button> ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: model-projection-chooser ( -- gadget ) | |
observer3d> projection-mode>> | |
{ { 1 "perspective" } { 0 "orthogonal" } } | |
<radio-buttons> ; | |
: collision-detection-chooser ( -- gadget ) | |
observer3d> collision-mode>> | |
{ { t "on" } { f "off" } } <radio-buttons> ; | |
: model-projection ( x -- space ) | |
present-space> swap space-project ; | |
: update-observer-projections ( -- ) | |
view1> relayout-1 | |
view2> relayout-1 | |
view3> relayout-1 | |
view4> relayout-1 ; | |
: update-model-projections ( -- ) | |
0 model-projection <model> view1> model<< | |
1 model-projection <model> view2> model<< | |
2 model-projection <model> view3> model<< | |
3 model-projection <model> view4> model<< ; | |
: camera-action ( quot -- quot ) | |
'[ drop _ observer3d> | |
with-self update-observer-projections ] | |
closed-quot ; | |
: win3D ( text gadget -- ) | |
"navigateur 4D : " rot append open-window ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! 4D object manipulation | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: (mvt-4D) ( quot -- ) | |
present-space> | |
swap call space-ensure-solids | |
>present-space | |
update-model-projections | |
update-observer-projections ; inline | |
: rotation-4D ( m -- ) | |
'[ _ [ [ middle-of-space dup vneg ] keep | |
swap space-translate ] dip | |
space-transform | |
swap space-translate | |
] (mvt-4D) ; | |
: translation-4D ( v -- ) '[ _ space-translate ] (mvt-4D) ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! menu | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: menu-rotations-4D ( -- gadget ) | |
3 3 <frame> | |
{ 1 1 } >>filled-cell | |
<pile> 1 >>fill | |
"XY +" [ drop rotation-step 4D-Rxy rotation-4D ] | |
button* add-gadget | |
"XY -" [ drop rotation-step neg 4D-Rxy rotation-4D ] | |
button* add-gadget | |
@top-left grid-add | |
<pile> 1 >>fill | |
"XZ +" [ drop rotation-step 4D-Rxz rotation-4D ] | |
button* add-gadget | |
"XZ -" [ drop rotation-step neg 4D-Rxz rotation-4D ] | |
button* add-gadget | |
@top grid-add | |
<pile> 1 >>fill | |
"YZ +" [ drop rotation-step 4D-Ryz rotation-4D ] | |
button* add-gadget | |
"YZ -" [ drop rotation-step neg 4D-Ryz rotation-4D ] | |
button* add-gadget | |
@center grid-add | |
<pile> 1 >>fill | |
"XW +" [ drop rotation-step 4D-Rxw rotation-4D ] | |
button* add-gadget | |
"XW -" [ drop rotation-step neg 4D-Rxw rotation-4D ] | |
button* add-gadget | |
@top-right grid-add | |
<pile> 1 >>fill | |
"YW +" [ drop rotation-step 4D-Ryw rotation-4D ] | |
button* add-gadget | |
"YW -" [ drop rotation-step neg 4D-Ryw rotation-4D ] | |
button* add-gadget | |
@right grid-add | |
<pile> 1 >>fill | |
"ZW +" [ drop rotation-step 4D-Rzw rotation-4D ] | |
button* add-gadget | |
"ZW -" [ drop rotation-step neg 4D-Rzw rotation-4D ] | |
button* add-gadget | |
@bottom-right grid-add | |
; | |
: menu-translations-4D ( -- gadget ) | |
3 3 <frame> | |
{ 1 1 } >>filled-cell | |
<pile> 1 >>fill | |
<shelf> 1 >>fill | |
"X+" [ drop { 1 0 0 0 } translation-step v*n | |
translation-4D ] | |
button* add-gadget | |
"X-" [ drop { -1 0 0 0 } translation-step v*n | |
translation-4D ] | |
button* add-gadget | |
add-gadget | |
"YZW" <label> add-gadget | |
@bottom-right grid-add | |
<pile> 1 >>fill | |
"XZW" <label> add-gadget | |
<shelf> 1 >>fill | |
"Y+" [ drop { 0 1 0 0 } translation-step v*n | |
translation-4D ] | |
button* add-gadget | |
"Y-" [ drop { 0 -1 0 0 } translation-step v*n | |
translation-4D ] | |
button* add-gadget | |
add-gadget | |
@top-right grid-add | |
<pile> 1 >>fill | |
"XYW" <label> add-gadget | |
<shelf> 1 >>fill | |
"Z+" [ drop { 0 0 1 0 } translation-step v*n | |
translation-4D ] | |
button* add-gadget | |
"Z-" [ drop { 0 0 -1 0 } translation-step v*n | |
translation-4D ] | |
button* add-gadget | |
add-gadget | |
@top-left grid-add | |
<pile> 1 >>fill | |
<shelf> 1 >>fill | |
"W+" [ drop { 0 0 0 1 } translation-step v*n | |
translation-4D ] | |
button* add-gadget | |
"W-" [ drop { 0 0 0 -1 } translation-step v*n | |
translation-4D ] | |
button* add-gadget | |
add-gadget | |
"XYZ" <label> add-gadget | |
@bottom-left grid-add | |
"X" <label> @center grid-add | |
; | |
: menu-4D ( -- gadget ) | |
<shelf> | |
"rotations" <label> add-gadget | |
menu-rotations-4D add-gadget | |
"translations" <label> add-gadget | |
menu-translations-4D add-gadget | |
0.5 >>align | |
{ 0 10 } >>gap | |
; | |
! ------------------------------------------------------ | |
: redraw-model ( space -- ) | |
>present-space | |
update-model-projections | |
update-observer-projections ; | |
: load-model-file ( -- ) | |
selected-file dup selected-file-model> set-model | |
read-model-file | |
redraw-model ; | |
: mvt-3D-X ( turn pitch -- quot ) | |
'[ turtle-pos> norm neg reset-turtle | |
_ turn-left | |
_ pitch-up | |
step-turtle ] ; | |
: mvt-3D-1 ( -- quot ) 90 0 mvt-3D-X ; inline | |
: mvt-3D-2 ( -- quot ) 0 90 mvt-3D-X ; inline | |
: mvt-3D-3 ( -- quot ) 0 0 mvt-3D-X ; inline | |
: mvt-3D-4 ( -- quot ) 45 45 mvt-3D-X ; inline | |
: camera-button ( string quot -- button ) | |
[ <label> ] dip camera-action <repeat-button> ; | |
! ---------------------------------------------------------- | |
! file chooser | |
! ---------------------------------------------------------- | |
: <run-file-button> ( file-name -- button ) | |
dup '[ drop _ \ selected-file set-value load-model-file | |
] | |
closed-quot <roll-button> { 0 0 } >>align ; | |
: <list-runner> ( -- gadget ) | |
"resource:extra/4DNav" | |
<pile> 1 >>fill | |
over dup directory-files | |
[ ".xml" tail? ] filter | |
[ append-path ] with map | |
[ <run-file-button> add-gadget ] each | |
swap <labeled-gadget> ; | |
! ----------------------------------------------------- | |
: menu-rotations-3D ( -- gadget ) | |
3 3 <frame> | |
{ 1 1 } >>filled-cell | |
"Turn\n left" [ rotation-step turn-left ] | |
camera-button @left grid-add | |
"Turn\n right" [ rotation-step turn-right ] | |
camera-button @right grid-add | |
"Pitch down" [ rotation-step pitch-down ] | |
camera-button @bottom grid-add | |
"Pitch up" [ rotation-step pitch-up ] | |
camera-button @top grid-add | |
<shelf> 1 >>fill | |
"Roll left\n (ctl)" [ rotation-step roll-left ] | |
camera-button add-gadget | |
"Roll right\n(ctl)" [ rotation-step roll-right ] | |
camera-button add-gadget | |
@center grid-add | |
; | |
: menu-translations-3D ( -- gadget ) | |
3 3 <frame> | |
{ 1 1 } >>filled-cell | |
"left\n(alt)" [ translation-step strafe-left ] | |
camera-button @left grid-add | |
"right\n(alt)" [ translation-step strafe-right ] | |
camera-button @right grid-add | |
"Strafe up \n (alt)" [ translation-step strafe-up ] | |
camera-button @top grid-add | |
"Strafe down\n (alt)" [ translation-step strafe-down ] | |
camera-button @bottom grid-add | |
<pile> 1 >>fill | |
"Forward (ctl)" [ translation-step step-turtle ] | |
camera-button add-gadget | |
"Backward (ctl)" | |
[ translation-step neg step-turtle ] | |
camera-button add-gadget | |
@center grid-add | |
; | |
: menu-quick-views ( -- gadget ) | |
<shelf> | |
"View 1 (1)" mvt-3D-1 camera-button add-gadget | |
"View 2 (2)" mvt-3D-2 camera-button add-gadget | |
"View 3 (3)" mvt-3D-3 camera-button add-gadget | |
"View 4 (4)" mvt-3D-4 camera-button add-gadget | |
; | |
: menu-3D ( -- gadget ) | |
<pile> | |
<shelf> | |
menu-rotations-3D add-gadget | |
menu-translations-3D add-gadget | |
0.5 >>align | |
{ 0 10 } >>gap | |
add-gadget | |
menu-quick-views add-gadget ; | |
TUPLE: handler < w:wrapper table ; | |
: <handler> ( child -- handler ) handler w:new-wrapper ; | |
M: handler handle-gesture ( gesture gadget -- ? ) | |
tuck table>> at dup [ call( gadget -- ) f ] [ 2drop t ] if ; | |
: add-keyboard-delegate ( obj -- obj ) | |
<handler> | |
H{ | |
{ T{ key-down f f "LEFT" } | |
[ [ rotation-step turn-left ] camera-action ] } | |
{ T{ key-down f f "RIGHT" } | |
[ [ rotation-step turn-right ] camera-action ] } | |
{ T{ key-down f f "UP" } | |
[ [ rotation-step pitch-down ] camera-action ] } | |
{ T{ key-down f f "DOWN" } | |
[ [ rotation-step pitch-up ] camera-action ] } | |
{ T{ key-down f { C+ } "UP" } | |
[ [ translation-step step-turtle ] camera-action ] } | |
{ T{ key-down f { C+ } "DOWN" } | |
[ [ translation-step neg step-turtle ] | |
camera-action ] } | |
{ T{ key-down f { C+ } "LEFT" } | |
[ [ rotation-step roll-left ] camera-action ] } | |
{ T{ key-down f { C+ } "RIGHT" } | |
[ [ rotation-step roll-right ] camera-action ] } | |
{ T{ key-down f { A+ } "LEFT" } | |
[ [ translation-step strafe-left ] camera-action ] } | |
{ T{ key-down f { A+ } "RIGHT" } | |
[ [ translation-step strafe-right ] camera-action ] } | |
{ T{ key-down f { A+ } "UP" } | |
[ [ translation-step strafe-up ] camera-action ] } | |
{ T{ key-down f { A+ } "DOWN" } | |
[ [ translation-step strafe-down ] camera-action ] } | |
{ T{ key-down f f "1" } [ mvt-3D-1 camera-action ] } | |
{ T{ key-down f f "2" } [ mvt-3D-2 camera-action ] } | |
{ T{ key-down f f "3" } [ mvt-3D-3 camera-action ] } | |
{ T{ key-down f f "4" } [ mvt-3D-4 camera-action ] } | |
} >>table | |
; | |
! -------------------------------------------- | |
! print elements | |
! -------------------------------------------- | |
! print-content | |
GENERIC: adsoda-display-model ( x -- ) | |
M: light adsoda-display-model | |
"\n light : " . | |
{ | |
[ direction>> "direction : " pprint . ] | |
[ color>> "color : " pprint . ] | |
} cleave | |
; | |
M: face adsoda-display-model | |
{ | |
[ halfspace>> "halfspace : " pprint . ] | |
[ touching-corners>> "touching corners : " pprint . ] | |
} cleave | |
; | |
M: solid adsoda-display-model | |
{ | |
[ name>> "solid called : " pprint . ] | |
[ color>> "color : " pprint . ] | |
[ dimension>> "dimension : " pprint . ] | |
[ faces>> "composed of faces : " pprint | |
[ adsoda-display-model ] each ] | |
} cleave | |
; | |
M: space adsoda-display-model | |
{ | |
[ dimension>> "dimension : " pprint . ] | |
[ ambient-color>> "ambient-color : " pprint . ] | |
[ solids>> "composed of solids : " pprint | |
[ adsoda-display-model ] each ] | |
[ lights>> "composed of lights : " pprint | |
[ adsoda-display-model ] each ] | |
} cleave | |
; | |
! ---------------------------------------------- | |
: menu-bar ( -- gadget ) | |
<shelf> | |
"reinit" [ drop load-model-file ] button* add-gadget | |
selected-file-model> <label-control> add-gadget | |
; | |
: controller-window* ( -- gadget ) | |
{ 0 1 } <track> | |
menu-bar f track-add | |
<list-runner> | |
<scroller> | |
f track-add | |
<shelf> | |
"Projection mode : " <label> add-gadget | |
model-projection-chooser add-gadget | |
f track-add | |
<shelf> | |
"Collision detection (slow and buggy ) : " | |
<label> add-gadget | |
collision-detection-chooser add-gadget | |
f track-add | |
<pile> | |
0.5 >>align | |
menu-4D add-gadget | |
COLOR: purple s:<solid> >>interior | |
"4D movements" <labeled-gadget> | |
f track-add | |
<pile> | |
0.5 >>align | |
{ 2 2 } >>gap | |
menu-3D add-gadget | |
COLOR: purple s:<solid> >>interior | |
"Camera 3D" <labeled-gadget> | |
f track-add | |
COLOR: gray s:<solid> >>interior | |
; | |
: viewer-windows* ( -- ) | |
"YZW" view1> win3D | |
"XZW" view2> win3D | |
"XYW" view3> win3D | |
"XYZ" view4> win3D | |
; | |
: navigator-window* ( -- ) | |
controller-window* | |
viewer-windows* | |
add-keyboard-delegate | |
"navigateur 4D" open-window | |
; | |
: windows ( -- ) [ [ navigator-window* ] with-scope ] with-ui ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: init-variables ( -- ) | |
"choose a file" <model> >selected-file-model | |
<observer> >observer3d | |
[ observer3d> >self | |
reset-turtle | |
45 turn-left | |
45 pitch-up | |
-300 step-turtle | |
] with-scope | |
; | |
: init-models ( -- ) | |
0 model-projection observer3d> <window3D> >view1 | |
1 model-projection observer3d> <window3D> >view2 | |
2 model-projection observer3d> <window3D> >view3 | |
3 model-projection observer3d> <window3D> >view4 | |
; | |
: 4DNav ( -- ) | |
init-variables | |
selected-file read-model-file >present-space | |
init-models | |
windows | |
; | |
MAIN: 4DNav | |
]] | |
FILE: [[4DNav/window3D/window3D-docs.factor]] base64[[ISBDb3B5cmlnaHQgKEMpIDIwMDggSmVhbi1GcmFuw6dvaXMgQmlnb3QuCiEgU2VlIGh0dHA6Ly9mYWN0b3Jjb2RlLm9yZy9saWNlbnNlLnR4dCBmb3IgQlNEIGxpY2Vuc2UuClVTSU5HOiBoZWxwLm1hcmt1cCBoZWxwLnN5bnRheCBrZXJuZWwgOwpJTjogNEROYXYud2luZG93M0QKCgoKQVJUSUNMRTogIjRETmF2LndpbmRvdzNEIiAiV2luZG93M0QiCnsgJHZvY2FiLWxpbmsgIjRETmF2LndpbmRvdzNEIiB9CjsKCkFCT1VUOiAiNEROYXYud2luZG93M0QiCg==]] | |
FILE: [[4DNav/window3D/window3D.factor]] [[! Copyright (C) 2008 Jeff Bigot | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: kernel | |
ui.gadgets | |
ui.render | |
opengl | |
opengl.gl | |
opengl.glu | |
4DNav.camera | |
4DNav.turtle | |
math | |
values | |
alien.c-types | |
accessors | |
namespaces | |
adsoda | |
models | |
prettyprint | |
; | |
IN: 4DNav.window3D | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! drawing functions | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
TUPLE: window3D < gadget observer ; | |
: <window3D> ( model observer -- gadget ) | |
window3D new | |
swap 2dup | |
projection-mode>> add-connection | |
2dup | |
collision-mode>> add-connection | |
>>observer | |
swap <model> >>model | |
t >>root? | |
; | |
M: window3D pref-dim* ( gadget -- dim ) drop { 300 300 } ; | |
M: window3D draw-gadget* ( gadget -- ) | |
GL_PROJECTION glMatrixMode | |
glLoadIdentity | |
0.6 0.6 0.6 .9 glClearColor | |
dup observer>> projection-mode>> value>> 1 = | |
[ 60.0 1.0 0.1 3000.0 gluPerspective ] | |
[ -400.0 400.0 -400.0 400.0 0.0 4000.0 glOrtho ] if | |
dup observer>> collision-mode>> value>> | |
\ remove-hidden-solids? | |
set-value | |
dup observer>> do-look-at | |
GL_MODELVIEW glMatrixMode | |
glLoadIdentity | |
0.9 0.9 0.9 1.0 glClearColor | |
1.0 glClearDepth | |
GL_LINE_SMOOTH glEnable | |
GL_BLEND glEnable | |
GL_DEPTH_TEST glEnable | |
GL_LEQUAL glDepthFunc | |
GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA glBlendFunc | |
GL_LINE_SMOOTH_HINT GL_NICEST glHint | |
1.25 glLineWidth | |
GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT bitor | |
glClear | |
glLoadIdentity | |
GL_LIGHTING glEnable | |
GL_LIGHT0 glEnable | |
GL_COLOR_MATERIAL glEnable | |
GL_FRONT GL_AMBIENT_AND_DIFFUSE glColorMaterial | |
! ************************* | |
control-value | |
[ space->GL ] when* | |
! ************************* | |
; | |
M: window3D graft* drop ; | |
M: window3D model-changed nip relayout ; | |
]] | |
FILE: [[4DNav/window3D/authors.txt]] [[Jeff Bigot | |
]] | |
FILE: [[4DNav/camera/camera-docs.factor]] base64[[ISBDb3B5cmlnaHQgKEMpIDIwMDggSmVhbi1GcmFuw6dvaXMgQmlnb3QuCiEgU2VlIGh0dHA6Ly9mYWN0b3Jjb2RlLm9yZy9saWNlbnNlLnR4dCBmb3IgQlNEIGxpY2Vuc2UuClVTSU5HOiBoZWxwLm1hcmt1cCBoZWxwLnN5bnRheCBrZXJuZWwgOwpJTjogNEROYXYuY2FtZXJhCgpIRUxQOiBjYW1lcmEtZXllCnsgJHZhbHVlcwogICAgCiAgICAgeyAicG9pbnQiICJwb3NpdGlvbiIgfQp9CnsgJGRlc2NyaXB0aW9uICJyZXR1cm4gdGhlIHBvc2l0aW9uIG9mIHRoZSBjYW1lcmEiIH0gOwoKSEVMUDogY2FtZXJhLWZvY3VzCnsgJHZhbHVlcwogICAgCiAgICAgeyAicG9pbnQiICJwb3NpdGlvbiIgfQp9CnsgJGRlc2NyaXB0aW9uICJyZXR1cm4gdGhlIHBvaW50IHRoZSBjYW1lcmEgbG9va3MgYXQiIH0gOwoKSEVMUDogY2FtZXJhLXVwCnsgJHZhbHVlcwogICAgCiAgICAgeyAiZGlydmVjIiAidXBzaWRlIGRpcmVjdGlvbiIgfQp9CnsgJGRlc2NyaXB0aW9uICJJbiBvcmRlciB0byBwcmVjaXNlIHRoZSByb2xpbmcgcG9zaXRpb24gb2YgY2FtZXJhIGdpdmUgYW4gdXB3YXJkIHZlY3RvciIgfSA7CgpIRUxQOiBkby1sb29rLWF0CnsgJHZhbHVlcwogICAgIHsgImNhbWVyYSIgImRpcmVjdGlvbiIgfQp9CnsgJGRlc2NyaXB0aW9uICJXb3JkIHRvIHVzZSBpbiByZXBsYWNlbWVudCBvZiBnbC1sb29rLWF0IHdoZW4gdXNpbmcgYSBjYW1lcmEiIH0gOwoKQVJUSUNMRTogIjRETmF2LmNhbWVyYSIgIkNhbWVyYSIKeyAkdm9jYWItbGluayAiNEROYXYuY2FtZXJhIiB9CiRubAoiQSBjYW1lcmEgaXMgZGVmaW5lZCBieToiCnsgJGxpc3QKeyAiYSBwb3NpdGlvbiAoIiB7ICRsaW5rIGNhbWVyYS1leWUgfSAiKSIgfQp7ICJhIGZvY3VzIGRpcmVjdGlvbiAoIiB7ICRsaW5rIGNhbWVyYS1mb2N1cyB9ICIpIiB9CnsgImFuIGF0dGl0dWRlIGluZm9ybWF0aW9uICgiIHsgJGxpbmsgY2FtZXJhLXVwIH0gIikiIH0KfQoiVXNlICIgeyAkbGluayBkby1sb29rLWF0IH0gIiBpbiBvcGVuZ2wgc3RhdGVtZW50IGluIHBsYWNlbWVudCBvZiBnbC1sb29rLWF0IgokbmwKIkEgY2FtZXJhIGlzIGEgIiB7ICR2b2NhYi1saW5rICI0RE5hdi50dXJ0bGUiIH0gIiBvYmplY3QuIEl0cyBhIHNwZWNpYWwgdm9jYWIgdG8gaGFuZGxlIG1vdXZlbWVudHMgb2YgYSAzRCBvYmplY3Q6Igp7ICRsaXN0CnsgIlRvIGRlZmluZSBhIGNhbWVyYSIKewogICAgJHVuY2hlY2tlZC1leGFtcGxlCiAgICAKIlZBUjogbXktY2FtZXJhIgoiOiBpbml0LW15LWNhbWVyYSAoIC0tICkiCiIgICAgPHR1cnRsZT4gPm15LWNhbWVyYSIKIiAgICBbIG15LWNhbWVyYT4gPnNlbGYiCiIgICAgICByZXNldC10dXJ0bGUgIgoiICAgIF0gd2l0aC1zY29wZSA7Igp9IH0KeyAiVG8gbW92ZSBpdCIKewogICAgJHVuY2hlY2tlZC1leGFtcGxlCgoiICAgIFsgbXktY2FtZXJhPiA+c2VsZiIKIiAgICAgIDQ1IHBpdGNoLXVwICIKIiAgICAgIDUgc3RlcC10dXJ0bGUiIAoiICAgIF0gd2l0aC1zY29wZSAiCn0gfQp7ICJvciIKewogICAgJHVuY2hlY2tlZC1leGFtcGxlCgoiICAgIFsgbXktY2FtZXJhPiA+c2VsZiIKIiAgICAgIDUgc3RyYWZlLWxlZnQiCiIgICAgXSB3aXRoLXNjb3BlICIKfQp9CnsKInRvIHVzZSBpdCBpbiBhbiBvcGVuZ2wgc3RhdGVtZW50Igp7CiAgICAkdW5jaGVja2VkLWV4YW1wbGUKICAibXktY2FtZXJhPiBkby1sb29rLWF0IgoKfQp9Cn0KCgo7CgpBQk9VVDogIjRETmF2LmNhbWVyYSIK]] | |
FILE: [[4DNav/camera/authors.txt]] [[Adam Wendt | |
]] | |
FILE: [[4DNav/camera/camera.factor]] [[USING: kernel namespaces math.vectors opengl opengl.glu 4DNav.turtle ; | |
IN: 4DNav.camera | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: camera-eye ( -- point ) turtle-pos> ; | |
: camera-focus ( -- point ) | |
[ 1 step-turtle turtle-pos> ] save-self ; | |
: camera-up ( -- dirvec ) | |
[ 90 pitch-up turtle-pos> 1 step-turtle turtle-pos> swap v- ] | |
save-self ; | |
: do-look-at ( camera -- ) | |
[ >self camera-eye camera-focus camera-up gl-look-at ] | |
with-scope ; | |
]] | |
FILE: [[4DNav/prismetriagone.xml]] [[<model> | |
<space> | |
<name>Prismetragone</name> | |
<dimension>4</dimension> | |
<solid> | |
<name>triangone</name> | |
<dimension>4</dimension> | |
<face>1,0,0,0,60</face> | |
<face>0.5,0.8660254037844386,0,0,60</face> | |
<face>-0.5,0.8660254037844387,0,0,-20</face> | |
<face>-1.0,0,0,0,-100</face> | |
<face>-0.5,-0.8660254037844384,0,0,-100</face> | |
<face>0.5,-0.8660254037844387,0,0,-20</face> | |
<face>0,0,1,0,120</face> | |
<face>0,0,-0.4999999999999998,-0.8660254037844387,-120</face> | |
<face>0,0,-0.5000000000000004,0.8660254037844384,-120</face> | |
<color>0,1,1</color> | |
</solid> | |
<light> | |
<direction>1,1,1,1</direction> | |
<color>0.2,0.2,0.6</color> | |
</light> | |
<color>0.8,0.9,0.9</color> | |
</space> | |
</model> | |
]] | |
FILE: [[4DNav/deep/deep.factor]] [[USING: macros quotations math math.functions math.trig | |
sequences.deep kernel make fry combinators grouping ; | |
IN: 4DNav.deep | |
! USING: bake ; | |
! MACRO: deep-cleave-quots ( seq -- quot ) | |
! [ [ quotation? ] deep-filter ] | |
! [ [ dup quotation? [ drop , ] when ] deep-map ] | |
! bi '[ _ cleave _ bake ] ; | |
: make-matrix ( quot width -- matrix ) | |
[ { } make ] dip group ; inline | |
]] | |
FILE: [[4DNav/deep/deep-docs.factor]] base64[[ISBDb3B5cmlnaHQgKEMpIDIwMDggSmVhbi1GcmFu529pcyBCaWdvdC4KISBTZWUgaHR0cDovL2ZhY3RvcmNvZGUub3JnL2xpY2Vuc2UudHh0IGZvciBCU0QgbGljZW5zZS4KVVNJTkc6IGhlbHAubWFya3VwIGhlbHAuc3ludGF4IGtlcm5lbCBxdW90YXRpb25zIHNlcXVlbmNlcyA7CklOOiA0RE5hdi5kZWVwCgohIEhFTFA6IGRlZXAtY2xlYXZlLXF1b3RzCiEgeyAkdmFsdWVzCiEgICAgIHsgInNlcSIgc2VxdWVuY2UgfQohICAgICB7ICJxdW90IiBxdW90YXRpb24gfQohIH0KISB7ICRkZXNjcmlwdGlvbiAiQSB3b3JkIHRvIGJ1aWxkIGEgc29xdWVuY2UgZnJvbSBhIHNlcXVlbmNlIG9mIHF1b3RhdGlvbiIgfQohIAohIHsgJGV4YW1wbGVzCiEgIkl0IGlzIHVzZWZ1bCB0byBidWlsZCBtYXRyaXgiCiEgeyAkZXhhbXBsZSAiVVNJTkc6IG1hdGggbWF0aC50cmlnIDsgIgohICAgICAiIDMwIGRlZz5yYWQgIgohICAgICIgIHsgIHsgWyBjb3MgXSBbIHNpbiBuZWcgXSAgIDAgfSAiCiEgICAgIiAgICAgeyBbIHNpbiBdIFsgY29zIF0gICAgICAgMCB9ICIKISAgICAiICAgICB7ICAgMCAgICAgICAwICAgICAgICAgICAxIH0gIgohICAgICIgIH0gZGVlcC1jbGVhdmUtcXVvdHMgIiAKISAgICAgIiAiCiEgCiEgCiEgfSB9CiEgOwoKQVJUSUNMRTogIjRETmF2LmRlZXAiICJEZWVwIgp7ICR2b2NhYi1saW5rICI0RE5hdi5kZWVwIiB9CjsKCkFCT1VUOiAiNEROYXYuZGVlcCIK]] | |
FILE: [[4DNav/file-chooser/authors.txt]] [[Jeff Bigot | |
]] | |
FILE: [[4DNav/file-chooser/file-chooser.factor]] [[! Copyright (C) 2008 Jeff Bigot | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: | |
kernel | |
io.files | |
io.backend | |
io.directories | |
io.files.info | |
io.pathnames | |
sequences | |
models | |
strings | |
ui | |
ui.operations | |
ui.commands | |
ui.gestures | |
ui.gadgets | |
ui.gadgets.buttons | |
ui.gadgets.lists | |
ui.gadgets.labels | |
ui.gadgets.tracks | |
ui.gadgets.packs | |
ui.gadgets.panes | |
ui.gadgets.scrollers | |
prettyprint | |
combinators | |
accessors | |
values | |
tools.walker | |
fry | |
; | |
IN: 4DNav.file-chooser | |
TUPLE: file-chooser < track | |
path | |
extension | |
selected-file | |
presenter | |
hook | |
list | |
; | |
: find-file-list ( gadget -- list ) | |
[ file-chooser? ] find-parent list>> ; | |
file-chooser H{ | |
{ T{ key-down f f "UP" } | |
[ find-file-list select-previous ] } | |
{ T{ key-down f f "DOWN" } | |
[ find-file-list select-next ] } | |
{ T{ key-down f f "PAGE_UP" } | |
[ find-file-list list-page-up ] } | |
{ T{ key-down f f "PAGE_DOWN" } | |
[ find-file-list list-page-down ] } | |
{ T{ key-down f f "RET" } | |
[ find-file-list invoke-value-action ] } | |
{ T{ button-down } | |
request-focus } | |
{ T{ button-down f 1 } | |
[ find-file-list invoke-value-action ] } | |
} set-gestures | |
: list-of-files ( file-chooser -- seq ) | |
[ path>> value>> directory-entries ] [ extension>> ] bi | |
'[ [ name>> _ [ tail? ] with any? ] | |
[ directory? ] bi or ] filter | |
; | |
: update-filelist-model ( file-chooser -- ) | |
[ list-of-files ] [ model>> ] bi set-model ; | |
: init-filelist-model ( file-chooser -- file-chooser ) | |
dup list-of-files <model> >>model ; | |
: (fc-go) ( file-chooser button quot -- ) | |
[ [ file-chooser? ] find-parent dup path>> ] dip | |
call | |
normalize-path swap set-model | |
update-filelist-model | |
drop ; inline | |
: fc-go-parent ( file-chooser button -- ) | |
[ dup value>> parent-directory ] (fc-go) ; | |
: fc-go-home ( file-chooser button -- ) | |
[ home ] (fc-go) ; | |
: fc-change-directory ( file-chooser file -- ) | |
dupd [ path>> value>> normalize-path ] [ name>> ] bi* | |
append-path over path>> set-model | |
update-filelist-model | |
; | |
: fc-load-file ( file-chooser file -- ) | |
over [ name>> ] [ selected-file>> ] bi* set-model | |
[ [ path>> value>> ] [ selected-file>> value>> ] bi append ] [ hook>> ] bi | |
call( path -- ) | |
; inline | |
! : fc-ok-action ( file-chooser -- quot ) | |
! dup selected-file>> value>> "" = | |
! [ drop [ drop ] ] [ | |
! [ path>> value>> ] | |
! [ selected-file>> value>> append ] | |
! [ hook>> prefix ] tri | |
! [ drop ] prepend | |
! ] if ; | |
: line-selected-action ( file-chooser -- ) | |
dup list>> list-value | |
dup directory? | |
[ fc-change-directory ] [ fc-load-file ] if ; | |
: present-dir-element ( element -- string ) | |
[ name>> ] [ directory? ] bi [ "-> " prepend ] when ; | |
: <file-list> ( file-chooser -- list ) | |
dup [ nip line-selected-action ] curry | |
[ present-dir-element ] rot model>> <list> ; | |
: <file-chooser> ( hook path extension -- gadget ) | |
{ 0 1 } file-chooser new-track | |
swap >>extension | |
swap <model> >>path | |
"" <model> >>selected-file | |
swap >>hook | |
init-filelist-model | |
dup <file-list> >>list | |
"choose a file in directory " <label> f track-add | |
dup path>> <label-control> f track-add | |
dup extension>> ", " join "limited to : " prepend | |
<label> f track-add | |
<shelf> | |
"selected file : " <label> add-gadget | |
over selected-file>> <label-control> add-gadget | |
f track-add | |
<shelf> | |
over [ swap fc-go-parent ] curry "go up" | |
swap <border-button> add-gadget | |
over [ swap fc-go-home ] curry "go home" | |
swap <border-button> add-gadget | |
! over [ swap fc-ok-action ] curry "OK" | |
! swap <bevel-button> add-gadget | |
! [ drop ] "Cancel" swap <bevel-button> add-gadget | |
f track-add | |
dup list>> <scroller> 1 track-add | |
; | |
M: file-chooser pref-dim* drop { 400 200 } ; | |
: file-chooser-window ( -- ) | |
[ . ] home { "xml" "txt" } <file-chooser> | |
"Choose a file" open-window ; | |
]] | |
FILE: [[4DNav/multi solids.xml]] [[<model> | |
<space> | |
<name>multi solids</name> | |
<dimension>4</dimension> | |
<solid> | |
<name>4cube1</name> | |
<dimension>4</dimension> | |
<face>1,0,0,0,100</face> | |
<face>-1,0,0,0,-150</face> | |
<face>0,1,0,0,100</face> | |
<face>0,-1,0,0,-150</face> | |
<face>0,0,1,0,100</face> | |
<face>0,0,-1,0,-150</face> | |
<face>0,0,0,1,100</face> | |
<face>0,0,0,-1,-150</face> | |
<color>1,0,0</color> | |
</solid> | |
<solid> | |
<name>4triancube</name> | |
<dimension>4</dimension> | |
<face>1,0,0,0,160</face> | |
<face>-0.4999999999999998,-0.8660254037844387,0,0,-130</face> | |
<face>-0.5000000000000004,0.8660254037844384,0,0,-130</face> | |
<face>0,0,1,0,140</face> | |
<face>0,0,-1,0,-180</face> | |
<face>0,0,0,1,110</face> | |
<face>0,0,0,-1,-180</face> | |
<color>0,1,0</color> | |
</solid> | |
<solid> | |
<name>triangone</name> | |
<dimension>4</dimension> | |
<face>1,0,0,0,60</face> | |
<face>0.5,0.8660254037844386,0,0,60</face> | |
<face>-0.5,0.8660254037844387,0,0,-20</face> | |
<face>-1.0,0,0,0,-100</face> | |
<face>-0.5,-0.8660254037844384,0,0,-100</face> | |
<face>0.5,-0.8660254037844387,0,0,-20</face> | |
<face>0,0,1,0,120</face> | |
<face>0,0,-0.4999999999999998,-0.8660254037844387,-120</face> | |
<face>0,0,-0.5000000000000004,0.8660254037844384,-120</face> | |
<color>0,1,1</color> | |
</solid> | |
<light> | |
<direction>1,1,1,1</direction> | |
<color>0.2,0.2,0.6</color> | |
</light> | |
<color>0.8,0.9,0.9</color> | |
</space> | |
</model> | |
]] | |
FILE: [[4DNav/triancube.xml]] [[<model> | |
<space> | |
<name>triancube</name> | |
<dimension>4</dimension> | |
<solid> | |
<name>triancube</name> | |
<dimension>4</dimension> | |
<face>1,0,0,0,160</face> | |
<face>-0.4999999999999998,-0.8660254037844387,0,0,-130</face> | |
<face>-0.5000000000000004,0.8660254037844384,0,0,-130</face> | |
<face>0,0,1,0,140</face> | |
<face>0,0,-1,0,-180</face> | |
<face>0,0,0,1,110</face> | |
<face>0,0,0,-1,-180</face> | |
<color>0,1,0</color> | |
</solid> | |
<light> | |
<direction>1,1,1,1</direction> | |
<color>0.2,0.2,0.6</color> | |
</light> | |
<color>0.8,0.9,0.9</color> | |
</space> | |
</model> | |
]] | |
FILE: [[4DNav/summary.txt]] [[Simple tool to navigate through a 4D space with projections on 4 3D spaces | |
]] | |
FILE: [[4DNav/hypercube.xml]] [[<model> | |
<space> | |
<name>hypercube</name> | |
<dimension>4</dimension> | |
<solid> | |
<name>4cube1</name> | |
<dimension>4</dimension> | |
<face>1,0,0,0,100</face> | |
<face>-1,0,0,0,-150</face> | |
<face>0,1,0,0,100</face> | |
<face>0,-1,0,0,-150</face> | |
<face>0,0,1,0,100</face> | |
<face>0,0,-1,0,-150</face> | |
<face>0,0,0,1,100</face> | |
<face>0,0,0,-1,-150</face> | |
<color>1,0,0</color> | |
</solid> | |
<solid> | |
<name>4cube1</name> | |
<dimension>4</dimension> | |
<face>1,0,0,0,100</face> | |
<face>-1,0,0,0,-150</face> | |
<face>0,1,0,0,100</face> | |
<face>0,-1,0,0,-150</face> | |
<face>0,0,1,0,100</face> | |
<face>0,0,-1,0,-150</face> | |
<face>0,0,0,1,100</face> | |
<face>0,0,0,-1,-150</face> | |
<color>1,0,0</color> | |
</solid> | |
<light> | |
<direction>1,1,1,1</direction> | |
<color>0.2,0.2,0.6</color> | |
</light> | |
<color>0.8,0.9,0.9</color> | |
</space> | |
</model> | |
]] | |
FILE: [[4DNav/deploy.factor]] [[USING: tools.deploy.config ; | |
H{ | |
{ deploy-c-types? t } | |
{ deploy-word-props? t } | |
{ deploy-name "4DNav" } | |
{ deploy-ui? t } | |
{ deploy-math? t } | |
{ deploy-threads? t } | |
{ deploy-reflection 3 } | |
{ deploy-unicode? t } | |
{ deploy-io 3 } | |
{ "stop-after-last-window?" t } | |
{ deploy-word-defs? t } | |
} | |
]] | |
FILE: [[4DNav/space-file-decoder/space-file-decoder.factor]] [[! Copyright (C) 2008 Jeff Bigot | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: adsoda xml xml.traversal xml.syntax accessors | |
combinators sequences math.parser kernel splitting values | |
continuations ; | |
IN: 4DNav.space-file-decoder | |
: decode-number-array ( x -- y ) | |
"," split [ string>number ] map ; | |
TAGS: adsoda-read-model ( tag -- model ) | |
TAG: dimension adsoda-read-model | |
children>> first string>number ; | |
TAG: direction adsoda-read-model | |
children>> first decode-number-array ; | |
TAG: color adsoda-read-model | |
children>> first decode-number-array ; | |
TAG: name adsoda-read-model | |
children>> first ; | |
TAG: face adsoda-read-model | |
children>> first decode-number-array ; | |
TAG: solid adsoda-read-model | |
<solid> swap | |
{ | |
[ "dimension" tag-named adsoda-read-model >>dimension ] | |
[ "name" tag-named adsoda-read-model >>name ] | |
[ "color" tag-named adsoda-read-model >>color ] | |
[ "face" | |
tags-named [ adsoda-read-model cut-solid ] each ] | |
} cleave | |
ensure-adjacencies | |
; | |
TAG: light adsoda-read-model | |
<light> swap | |
{ | |
[ "direction" tag-named adsoda-read-model >>direction ] | |
[ "color" tag-named adsoda-read-model >>color ] | |
} cleave | |
; | |
TAG: space adsoda-read-model | |
<space> swap | |
{ | |
[ "dimension" tag-named adsoda-read-model >>dimension ] | |
[ "name" tag-named adsoda-read-model >>name ] | |
[ "color" tag-named | |
adsoda-read-model >>ambient-color ] | |
[ "solid" tags-named | |
[ adsoda-read-model suffix-solids ] each ] | |
[ "light" tags-named | |
[ adsoda-read-model suffix-lights ] each ] | |
} cleave | |
; | |
: read-model-file ( path -- x ) | |
[ | |
[ file>xml "space" tag-named adsoda-read-model ] | |
[ 2drop <space> ] recover | |
] [ <space> ] if* | |
; | |
]] | |
FILE: [[4DNav/space-file-decoder/space-file-decoder-docs.factor]] base64[[ISBDb3B5cmlnaHQgKEMpIDIwMDggSmVhbi1GcmFuw6dvaXMgQmlnb3QuCiEgU2VlIGh0dHA6Ly9mYWN0b3Jjb2RlLm9yZy9saWNlbnNlLnR4dCBmb3IgQlNEIGxpY2Vuc2UuClVTSU5HOiBoZWxwLm1hcmt1cCBoZWxwLnN5bnRheCBrZXJuZWwgOwpJTjogNEROYXYuc3BhY2UtZmlsZS1kZWNvZGVyCgoKCkhFTFA6IHJlYWQtbW9kZWwtZmlsZQp7ICR2YWx1ZXMKICAgIAogICAgIHsgInBhdGgiICJwYXRoIHRvIHRoZSBmaWxlIHRvIHJlYWQiIH0KICAgICB7ICJ4IiAidmFsdWUiIH0KfQp7ICRkZXNjcmlwdGlvbiAiUmVhZCBhIGZpbGUgY29udGFpbmluZyB0aGUgeG1sIGRlc2NyaXB0aW9uIG9mIHRoZSBtb2RlbCIgfSA7CgpBUlRJQ0xFOiAiNEROYXYuc3BhY2UtZmlsZS1kZWNvZGVyIiAiU3BhY2UgWE1MZmlsZSBkZWNvZGVyIgp7ICR2b2NhYi1saW5rICI0RE5hdi5zcGFjZS1maWxlLWRlY29kZXIiIH0KOwoKQUJPVVQ6ICI0RE5hdi5zcGFjZS1maWxlLWRlY29kZXIiCg==]] | |
FILE: [[4DNav/space-file-decoder/authors.txt]] [[Jeff Bigot | |
]] | |
FILE: [[4DNav/light_test.xml]] [[<model> | |
<space> | |
<name>multi solids</name> | |
<dimension>4</dimension> | |
<solid> | |
<name>4cube1</name> | |
<dimension>4</dimension> | |
<face>1,0,0,0,100</face> | |
<face>-1,0,0,0,-150</face> | |
<face>0,1,0,0,100</face> | |
<face>0,-1,0,0,-150</face> | |
<face>0,0,1,0,100</face> | |
<face>0,0,-1,0,-150</face> | |
<face>0,0,0,1,100</face> | |
<face>0,0,0,-1,-150</face> | |
<color>1,1,1</color> | |
</solid> | |
<solid> | |
<name>4triancube</name> | |
<dimension>4</dimension> | |
<face>1,0,0,0,160</face> | |
<face>-0.4999999999999998,-0.8660254037844387,0,0,-130</face> | |
<face>-0.5000000000000004,0.8660254037844384,0,0,-130</face> | |
<face>0,0,1,0,140</face> | |
<face>0,0,-1,0,-180</face> | |
<face>0,0,0,1,110</face> | |
<face>0,0,0,-1,-180</face> | |
<color>1,1,1</color> | |
</solid> | |
<solid> | |
<name>triangone</name> | |
<dimension>4</dimension> | |
<face>1,0,0,0,60</face> | |
<face>0.5,0.8660254037844386,0,0,60</face> | |
<face>-0.5,0.8660254037844387,0,0,-20</face> | |
<face>-1.0,0,0,0,-100</face> | |
<face>-0.5,-0.8660254037844384,0,0,-100</face> | |
<face>0.5,-0.8660254037844387,0,0,-20</face> | |
<face>0,0,1,0,120</face> | |
<face>0,0,-0.4999999999999998,-0.8660254037844387,-120</face> | |
<face>0,0,-0.5000000000000004,0.8660254037844384,-120</face> | |
<color>1,1,1</color> | |
</solid> | |
<light> | |
<direction>1,0,0,0</direction> | |
<color>0,0,0,0.6</color> | |
</light> | |
<light> | |
<direction>0,1,0,0</direction> | |
<color>0,0.6,0,0</color> | |
</light> | |
<light> | |
<direction>0,0,1,0</direction> | |
<color>0,0,0.6,0</color> | |
</light> | |
<light> | |
<direction>0,0,0,1</direction> | |
<color>0.6,0.6,0.6</color> | |
</light> | |
<color>0.99,0.99,0.99</color> | |
</space> | |
</model> | |
]] | |
FILE: [[4DNav/authors.txt]] [[Jeff Bigot | |
]] | |
FILE: [[4DNav/tags.txt]] [[4D viewer]] | |
FILE: [[oracle/liboci/liboci.factor]] [[! Copyright (C) 2007 Elie CHAFTARI | |
! See http://factorcode.org/license.txt for BSD license. | |
! | |
! Adapted from oci.h and ociap.h | |
! Tested with Oracle version - 10.1.0.3 Instant Client | |
! | |
! DYLD_LIBRARY_PATH="/usr/local/oracle/instantclient10_1" | |
! export DYLD_LIBRARY_PATH | |
USING: alien alien.syntax combinators kernel system ; | |
IN: oracle.liboci | |
"oci" { | |
{ [ os winnt? ] [ "oci.dll" stdcall ] } | |
{ [ os macosx? ] [ "$DYLD_LIBRARY_PATH/libclntsh.dylib" cdecl ] } | |
{ [ os unix? ] [ "$DYLD_LIBRARY_PATH/libclntsh.so.10.1" cdecl ] } | |
} cond add-library | |
! =============================================== | |
! Attribute Types | |
! =============================================== | |
: OCI_ATTR_USERNAME 22 ; inline ! username attribute | |
: OCI_ATTR_PASSWORD 23 ; inline ! password attribute | |
! =============================================== | |
! Various Modes | |
! =============================================== | |
: OCI_DEFAULT 0x00 ; inline ! default value for parameters and attributes | |
: OCI_THREADED 0x01 ; inline ! appl. in threaded environment | |
: OCI_OBJECT 0x02 ; inline ! application in object environment | |
! =============================================== | |
! Execution Modes | |
! =============================================== | |
: OCI_DESCRIBE_ONLY 0x10 ; inline ! only describe the statement | |
! =============================================== | |
! Credential Types | |
! =============================================== | |
: OCI_CRED_RDBMS 1 ; inline ! database username/password | |
: OCI_CRED_EXT 2 ; inline ! externally provided credentials | |
: OCI_CRED_PROXY 3 ; inline ! proxy authentication | |
! =============================================== | |
! Error Return Values | |
! =============================================== | |
: OCI_SUCCESS 0 ; inline ! maps to SQL_SUCCESS of SAG CLI | |
: OCI_SUCCESS_WITH_INFO 1 ; inline ! maps to SQL_SUCCESS_WITH_INFO | |
: OCI_RESERVED_FOR_INT_USE 200 ; inline ! reserved | |
: OCI_NO_DATA 100 ; inline ! maps to SQL_NO_DATA | |
: OCI_ERROR -1 ; inline ! maps to SQL_ERROR | |
: OCI_INVALID_HANDLE -2 ; inline ! maps to SQL_INVALID_HANDLE | |
: OCI_NEED_DATA 99 ; inline ! maps to SQL_NEED_DATA | |
: OCI_STILL_EXECUTING -3123 ; inline ! OCI would block error | |
! =============================================== | |
! Parsing Syntax Types | |
! =============================================== | |
: OCI_V7_SYNTAX 2 ; inline ! V815 language - for backwards compatibility | |
: OCI_V8_SYNTAX 3 ; inline ! V815 language - for backwards compatibility | |
: OCI_NTV_SYNTAX 1 ; inline ! Use what so ever is the native lang of server | |
! =============================================== | |
! Scrollable Cursor Fetch Options | |
! For non-scrollable cursor, the only valid | |
! (and default) orientation is OCI_FETCH_NEXT | |
! =============================================== | |
: OCI_FETCH_CURRENT 0x01 ; inline ! refetching current position | |
: OCI_FETCH_NEXT 0x02 ; inline ! next row | |
: OCI_FETCH_FIRST 0x04 ; inline ! first row of the result set | |
: OCI_FETCH_LAST 0x08 ; inline ! the last row of the result set | |
: OCI_FETCH_PRIOR 0x10 ; inline ! the previous row relative to current | |
: OCI_FETCH_ABSOLUTE 0x20 ; inline ! absolute offset from first | |
: OCI_FETCH_RELATIVE 0x40 ; inline ! offset relative to current | |
: OCI_FETCH_RESERVED_1 0x80 ; inline ! reserved | |
! =============================================== | |
! Handle Types | |
! =============================================== | |
: OCI_HTYPE_ENV 1 ; inline ! environment handle | |
: OCI_HTYPE_ERROR 2 ; inline ! error handle | |
: OCI_HTYPE_SVCCTX 3 ; inline ! service handle | |
: OCI_HTYPE_STMT 4 ; inline ! statement handle | |
: OCI_HTYPE_BIND 5 ; inline ! bind handle | |
: OCI_HTYPE_DEFINE 6 ; inline ! define handle | |
: OCI_HTYPE_DESCRIBE 7 ; inline ! describe handle | |
: OCI_HTYPE_SERVER 8 ; inline ! server handle | |
: OCI_HTYPE_SESSION 9 ; inline ! authentication handle | |
! =============================================== | |
! Attribute Types | |
! =============================================== | |
: OCI_ATTR_FNCODE 1 ; inline ! the OCI function code | |
: OCI_ATTR_OBJECT 2 ; inline ! is the environment initialized in object mode | |
: OCI_ATTR_NONBLOCKING_MODE 3 ; inline ! non blocking mode | |
: OCI_ATTR_SQLCODE 4 ; inline ! the SQL verb | |
: OCI_ATTR_ENV 5 ; inline ! the environment handle | |
: OCI_ATTR_SERVER 6 ; inline ! the server handle | |
: OCI_ATTR_SESSION 7 ; inline ! the user session handle | |
: OCI_ATTR_TRANS 8 ; inline ! the transaction handle | |
: OCI_ATTR_ROW_COUNT 9 ; inline ! the rows processed so far | |
: OCI_ATTR_SQLFNCODE 10 ; inline ! the SQL verb of the statement | |
: OCI_ATTR_PREFETCH_ROWS 11 ; inline ! sets the number of rows to prefetch | |
: OCI_ATTR_NESTED_PREFETCH_ROWS 12 ; inline ! the prefetch rows of nested table | |
: OCI_ATTR_PREFETCH_MEMORY 13 ; inline ! memory limit for rows fetched | |
: OCI_ATTR_NESTED_PREFETCH_MEMORY 14 ; inline ! memory limit for nested rows | |
: OCI_ATTR_CHAR_COUNT 15 ; inline ! this specifies the bind and define size in characters | |
! =============================================== | |
! OCI integer types | |
! =============================================== | |
TYPEDEF: ushort ub2 | |
TYPEDEF: short sb2 | |
TYPEDEF: uint ub4 | |
TYPEDEF: int sb4 | |
! =============================================== | |
! Input data types (ocidfn.h) | |
! =============================================== | |
: SQLT_CHR 1 ; inline ! (ORANET TYPE) character string | |
: SQLT_NUM 2 ; inline ! (ORANET TYPE) oracle numeric | |
: SQLT_INT 3 ; inline ! (ORANET TYPE) integer | |
: SQLT_FLT 4 ; inline ! (ORANET TYPE) Floating point number | |
: SQLT_STR 5 ; inline ! zero terminated string | |
: SQLT_ODT 156 ; inline ! OCIDate type | |
! =============================================== | |
! Input datetimes and intervals (ocidfn.h) | |
! =============================================== | |
: SQLT_DATE 184 ; inline ! ANSI Date | |
: SQLT_TIME 185 ; inline ! TIME | |
: SQLT_TIME_TZ 186 ; inline ! TIME WITH TIME ZONE | |
: SQLT_TIMESTAMP 187 ; inline ! TIMESTAMP | |
: SQLT_TIMESTAMP_TZ 188 ; inline ! TIMESTAMP WITH TIME ZONE | |
: SQLT_INTERVAL_YM 189 ; inline ! INTERVAL YEAR TO MONTH | |
: SQLT_INTERVAL_DS 190 ; inline ! INTERVAL DAY TO SECOND | |
: SQLT_TIMESTAMP_LTZ 232 ; inline ! TIMESTAMP WITH LOCAL TZ | |
! =============================================== | |
! Opaque pointer types | |
! =============================================== | |
TYPEDEF: void dvoid | |
TYPEDEF: void oci_env | |
TYPEDEF: void oci_server | |
TYPEDEF: void oci_error | |
TYPEDEF: void oci_svc_ctx | |
TYPEDEF: void oci_session | |
TYPEDEF: void oci_stmt | |
LIBRARY: oci | |
! =============================================== | |
! ociap.h | |
! =============================================== | |
FUNCTION: int OCIInitialize ( ub4 mode, void* ctxp, void* malocfp, void* ralocfp, dvoid* mfreefp ) ; | |
FUNCTION: int OCITerminate ( ub4 mode ) ; | |
FUNCTION: int OCIEnvInit ( void* envhpp, ub4 mode, size_t xtramem_sz, dvoid* usrmempp ) ; | |
FUNCTION: int OCIEnvCreate ( dvoid* envhpp, ub4 mode, void* ctxp, void* malocfp, void* ralocfp, void* mfreefp, size_t xtramemz, dvoid* usrmempp ) ; | |
FUNCTION: int OCIHandleAlloc ( void* parenth, dvoid* hndlpp, ub4 type, size_t xtramem_sz, dvoid* usrmempp ) ; | |
FUNCTION: int OCIServerAttach ( void* srvhp, void* errhp, char* dblink, sb4 dblink_len, ub4 mode ) ; | |
FUNCTION: int OCIServerDetach ( void* srvhp, void* errhp, ub4 mode ) ; | |
FUNCTION: int OCIHandleFree ( dvoid* p0, ub4 p1 ) ; | |
FUNCTION: int OCILogon ( void* envhp, void* errhp, dvoid* svchpp, uchar* username, ub4 uname_len, uchar* passwd, ub4 password_len, uchar* dsn, ub4 dsn_len ) ; | |
FUNCTION: int OCILogoff ( void* p0, void* p1 ) ; | |
FUNCTION: void OCIErrorGet ( void* handlp, ub4 recordno, char* sqlstate, sb4* errcodep, uchar* bufp, ub4 bufsize, ub4 type ) ; | |
FUNCTION: int OCIStmtPrepare ( void* stmtp, void* errhp, uchar* stmt, ub4 stmt_len, ub4 language, ub4 mode ) ; | |
FUNCTION: int OCIStmtExecute ( void* svchp, void* stmtp1, void* errhp, ub4 iters, ub4 rowoff, void* snap_in, void* snap_out, ub4 mode ) ; | |
FUNCTION: int OCIParamGet ( void* hndlp, ub4 htype, void* errhp, dvoid* parmdpp, ub4 pos ) ; | |
FUNCTION: int OCIAttrGet ( void* trgthndlp, ub4 trghndltyp, void* attributep, ub4* sizep, ub4 attrtype, void* errhp ) ; | |
FUNCTION: int OCIAttrSet ( dvoid* trgthndlp, ub4 trgthndltyp, dvoid* attributep, ub4 size, ub4 attrtype, oci_error* errhp ) ; | |
FUNCTION: int OCIDefineByPos ( void* stmtp, dvoid* defnpp, void* errhp, ub4 position, void* valuep, sb4 value_sz, ub2 dty, sb2* indp, ub2* rlenp, ub2* rcodep, ub4 mode ) ; | |
FUNCTION: int OCIStmtFetch ( void* stmthp, void* errhp, ub4 p2, ub2 p3, ub4 p4 ) ; | |
FUNCTION: int OCITransStart ( void* svchp, void* errhp, ushort p2, ushort p3 ) ; | |
FUNCTION: int OCITransCommit ( void* svchp, void* errhp, ushort p2 ) ; | |
FUNCTION: int OCITransRollback ( void* svchp, void* errhp, ushort p2 ) ; | |
FUNCTION: int OCISessionBegin ( oci_svc_ctx* svchp, oci_error* errhp, oci_session* usrhp, ub4 credt, ub4 mode ) ; | |
FUNCTION: int OCISessionEnd ( oci_svc_ctx* svchp, oci_error* errhp, oci_session* usrhp, ub4 mode ) ; | |
FUNCTION: int OCIServerVersion ( void* handlp, void* errhp, uchar* bufsz, int bufsz, short hndltype ) ; | |
]] | |
FILE: [[oracle/liboci/authors.txt]] [[Elie Chaftari | |
]] | |
FILE: [[oracle/summary.txt]] [[Oracle database bindings | |
]] | |
FILE: [[oracle/oracle-tests.factor]] [[USING: oracle oracle.liboci prettyprint tools.test | |
kernel ; | |
[ | |
"testuser" "testpassword" "//localhost/test1" log-on . | |
allocate-statement-handle | |
"CREATE TABLE TESTTABLE ( COL1 VARCHAR(40), COL2 NUMBER)" prepare-statement | |
[ t ] [ execute-statement ] unit-test | |
"INSERT INTO TESTTABLE (COL1, COL2) VALUES('hello', 50)" prepare-statement | |
[ t ] [ execute-statement ] unit-test | |
"INSERT INTO TESTTABLE (COL1, COL2) VALUES('hi', 60)" prepare-statement | |
[ t ] [ execute-statement ] unit-test | |
"INSERT INTO TESTTABLE (COL1, COL2) VALUES('bye', 70)" prepare-statement | |
[ t ] [ execute-statement ] unit-test | |
"COMMIT" prepare-statement | |
[ t ] [ execute-statement ] unit-test | |
"SELECT * FROM TESTTABLE" prepare-statement | |
1 SQLT_STR define-by-position run-query | |
[ V{ "hello" "hi" "bye" "50" "60" "70" } ] [ | |
2 SQLT_STR define-by-position run-query gather-results | |
] unit-test | |
clear-result | |
"UPDATE TESTTABLE SET COL2 = 10 WHERE COL1='hi'" prepare-statement | |
[ t ] [ execute-statement ] unit-test | |
"COMMIT" prepare-statement | |
[ t ] [ execute-statement ] unit-test | |
"SELECT * FROM TESTTABLE WHERE COL1 = 'hi'" prepare-statement | |
[ V{ "10" } ] [ | |
2 SQLT_STR define-by-position run-query gather-results | |
] unit-test | |
clear-result | |
"DROP TABLE TESTTABLE" prepare-statement | |
execute-statement | |
free-statement-handle log-off clean-up terminate | |
] drop | |
]] | |
FILE: [[oracle/oracle.factor]] [[! Copyright (C) 2007 Elie CHAFTARI | |
! See http://factorcode.org/license.txt for BSD license. | |
! | |
! Adapted from oci.h and ociap.h | |
! Tested with Oracle version - 10.1.0.3 Instant Client | |
USING: alien alien.c-types alien.strings combinators kernel math | |
namespaces oracle.liboci prettyprint sequences | |
io.encodings.ascii accessors ; | |
IN: oracle | |
SYMBOL: env | |
SYMBOL: err | |
SYMBOL: srv | |
SYMBOL: svc | |
SYMBOL: ses | |
SYMBOL: stm | |
SYMBOL: buf | |
SYMBOL: res | |
SYMBOL: con | |
TUPLE: connection username password db ; | |
C: <connection> connection | |
! ========================================================= | |
! Error-handling routines | |
! ========================================================= | |
: get-oci-error ( object -- * ) | |
1 f "uint*" <c-object> dup >r 512 "uchar" <c-array> dup >r | |
512 OCI_HTYPE_ERROR OCIErrorGet r> r> *uint drop | |
ascii alien>string throw ; | |
: check-result ( result -- ) | |
{ | |
{ OCI_SUCCESS [ ] } | |
{ OCI_ERROR [ err get get-oci-error ] } | |
{ OCI_INVALID_HANDLE [ "invalid handle" throw ] } | |
[ "operation failed" throw ] | |
} case ; | |
: check-status ( status -- bool ) | |
{ | |
{ OCI_SUCCESS [ t ] } | |
{ OCI_ERROR [ err get get-oci-error ] } | |
{ OCI_INVALID_HANDLE [ "invalid handle" throw ] } | |
{ OCI_NO_DATA [ f ] } | |
[ "operation failed" throw ] | |
} case ; | |
! ========================================================= | |
! Initialization and handle-allocation routines | |
! ========================================================= | |
! Legacy initialization routine | |
: oci-initialize ( -- ) | |
OCI_DEFAULT f f f f OCIInitialize check-result ; | |
! Legacy initialization routine | |
: oci-env-init ( -- ) | |
"void*" <c-object> dup OCI_DEFAULT 0 f OCIEnvInit | |
check-result *void* env set ; | |
: create-environment ( -- ) | |
"void*" <c-object> dup OCI_DEFAULT f f f f 0 f OCIEnvCreate | |
check-result *void* env set ; | |
: allocate-error-handle ( -- ) | |
env get | |
"void*" <c-object> tuck OCI_HTYPE_ERROR 0 f OCIHandleAlloc | |
check-result *void* err set ; | |
: allocate-service-handle ( -- ) | |
env get | |
"void*" <c-object> tuck OCI_HTYPE_SVCCTX 0 f OCIHandleAlloc | |
check-result *void* svc set ; | |
: allocate-session-handle ( -- ) | |
env get | |
"void*" <c-object> tuck OCI_HTYPE_SESSION 0 f OCIHandleAlloc | |
check-result *void* ses set ; | |
: allocate-server-handle ( -- ) | |
env get | |
"void*" <c-object> tuck OCI_HTYPE_SERVER 0 f OCIHandleAlloc | |
check-result *void* srv set ; | |
: init ( -- ) | |
oci-initialize | |
oci-env-init | |
allocate-error-handle | |
allocate-service-handle | |
allocate-session-handle | |
allocate-server-handle ; | |
! ========================================================= | |
! Single user session logon routine | |
! ========================================================= | |
: oci-log-on ( -- ) | |
env get err get svc get | |
con get username>> dup length swap ascii malloc-string swap | |
con get password>> dup length swap ascii malloc-string swap | |
con get db>> dup length swap ascii malloc-string swap | |
OCILogon check-result ; | |
! ========================================================= | |
! Attach to server and attribute-setting routines | |
! ========================================================= | |
: attach-to-server ( -- ) | |
srv get err get con get db>> dup length OCI_DEFAULT | |
OCIServerAttach check-result ; | |
: set-service-attribute ( -- ) | |
svc get OCI_HTYPE_SVCCTX srv get 0 OCI_ATTR_SERVER err get OCIAttrSet check-result ; | |
: set-username-attribute ( -- ) | |
ses get OCI_HTYPE_SESSION con get username>> dup length swap ascii malloc-string swap | |
OCI_ATTR_USERNAME err get OCIAttrSet check-result ; | |
: set-password-attribute ( -- ) | |
ses get OCI_HTYPE_SESSION con get password>> dup length swap ascii malloc-string swap | |
OCI_ATTR_PASSWORD err get OCIAttrSet check-result ; | |
: set-attributes ( -- ) | |
set-service-attribute | |
set-username-attribute | |
set-password-attribute ; | |
! ========================================================= | |
! Session startup routines | |
! ========================================================= | |
: begin-session ( -- ) | |
svc get err get ses get OCI_CRED_RDBMS OCI_DEFAULT OCISessionBegin check-result ; | |
: set-authentication-handle ( -- ) | |
svc get OCI_HTYPE_SVCCTX ses get 0 OCI_ATTR_SESSION err get OCIAttrSet check-result ; | |
! ========================================================= | |
! Statement preparation and execution routines | |
! ========================================================= | |
: allocate-statement-handle ( -- ) | |
env get | |
"void*" <c-object> tuck OCI_HTYPE_STMT 0 f OCIHandleAlloc | |
check-result *void* stm set ; | |
: prepare-statement ( statement -- ) | |
>r stm get err get r> dup length swap ascii malloc-string swap | |
OCI_NTV_SYNTAX OCI_DEFAULT OCIStmtPrepare check-result ; | |
: calculate-size ( type -- size ) | |
{ | |
{ SQLT_INT [ "int" heap-size ] } | |
{ SQLT_FLT [ "float" heap-size ] } | |
{ SQLT_CHR [ "char" heap-size ] } | |
{ SQLT_NUM [ "int" heap-size 10 * ] } | |
{ SQLT_STR [ 64 ] } | |
{ SQLT_ODT [ 256 ] } | |
} case ; | |
: define-by-position ( position type -- ) | |
>r >r stm get f <void*> err get | |
r> r> dup calculate-size >r [ "char" malloc-array dup buf set ] keep 1+ | |
r> f f f OCI_DEFAULT OCIDefineByPos check-result ; | |
: execute-statement ( -- bool ) | |
svc get stm get err get 1 0 f f OCI_DEFAULT OCIStmtExecute check-status ; | |
: fetch-statement ( -- bool ) | |
stm get err get 1 OCI_FETCH_NEXT OCI_DEFAULT OCIStmtFetch check-status ; | |
: free-statement-handle ( -- ) | |
stm get OCI_HTYPE_STMT OCIHandleFree check-result ; | |
! ========================================================= | |
! Log off and detach from server routines | |
! ========================================================= | |
: end-session ( -- ) | |
svc get err get ses get OCI_DEFAULT OCISessionEnd check-result ; | |
: detach-from-server ( -- ) | |
srv get err get OCI_DEFAULT OCIServerDetach check-result ; | |
: log-off ( -- ) | |
end-session | |
detach-from-server ; | |
! ========================================================= | |
! Clean-up and termination routines | |
! ========================================================= | |
: free-service-handle ( -- ) | |
svc get OCI_HTYPE_SVCCTX OCIHandleFree check-result ; | |
: free-server-handle ( -- ) | |
srv get OCI_HTYPE_SERVER OCIHandleFree check-result ; | |
: free-error-handle ( -- ) | |
err get OCI_HTYPE_ERROR OCIHandleFree check-result ; | |
: free-environment-handle ( -- ) | |
env get OCI_HTYPE_ENV OCIHandleFree check-result ; | |
: clean-up ( -- ) | |
free-service-handle | |
free-server-handle | |
free-error-handle | |
free-environment-handle ; | |
: terminate ( -- ) | |
OCI_DEFAULT OCITerminate check-result ; | |
! ========================================================= | |
! Utility routines | |
! ========================================================= | |
: server-version ( -- ) | |
srv get err get 512 "uchar" malloc-array dup >r 512 OCI_HTYPE_SERVER | |
OCIServerVersion check-result r> ascii alien>string . ; | |
! ========================================================= | |
! Public routines | |
! ========================================================= | |
: log-on ( username password db -- ) | |
<connection> con set | |
init attach-to-server set-attributes | |
begin-session set-authentication-handle | |
V{ } clone res set ; | |
: fetch-each ( object -- object ) | |
fetch-statement [ | |
buf get ascii alien>string res get swap suffix res set | |
fetch-each | |
] [ ] if ; | |
: run-query ( object -- object ) | |
execute-statement [ | |
buf get ascii alien>string res get swap suffix res set | |
fetch-each | |
] [ ] if ; | |
: gather-results ( -- seq ) | |
res get ; | |
: show-result ( -- ) | |
res get [ . ] each ; | |
: clear-result ( -- ) | |
V{ } clone res set ; | |
]] | |
FILE: [[oracle/authors.txt]] [[Elie Chaftari | |
]] | |
FILE: [[oracle/tags.txt]] [[database | |
]] | |
FILE: [[irc/ui/ircui-rc]] [[! Default system ircui-rc file | |
! Copy into .ircui-rc in your home directory and then change username and such | |
! To find your home directory, type "home ." into a Factor listener | |
USING: irc.client irc.ui ; | |
"irc.freenode.org" 8001 "factor-irc" f ! server port nick password | |
{ "#concatenative" "#terrorisland" } ! all the channels you want to autojoin | |
server-open | |
]] | |
FILE: [[irc/ui/ui.factor]] [[! Copyright (C) 2008 William Schlieper | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: accessors kernel threads combinators concurrency.mailboxes | |
sequences strings hashtables splitting fry assocs hashtables colors | |
sorting unicode math.order | |
ui ui.gadgets ui.gadgets.panes ui.gadgets.editors | |
ui.gadgets.scrollers ui.commands ui.gadgets.frames ui.gestures | |
ui.gadgets.tabs ui.gadgets.grids ui.gadgets.packs ui.gadgets.labels | |
io io.styles namespaces calendar calendar.format models continuations | |
irc.client irc.client.private irc.messages | |
irc.ui.commandparser irc.ui.load vocabs.loader classes prettyprint ; | |
RENAME: join sequences => sjoin | |
IN: irc.ui | |
SYMBOL: chat | |
SYMBOL: client | |
TUPLE: ui-window < tabbed client ; | |
M: ui-window ungraft* | |
client>> terminate-irc ; | |
TUPLE: irc-tab < frame chat client window ; | |
: write-color ( str color -- ) | |
foreground associate format ; | |
CONSTANT: dark-red T{ rgba f 0.5 0.0 0.0 1 } | |
CONSTANT: dark-green T{ rgba f 0.0 0.5 0.0 1 } | |
CONSTANT: dark-blue T{ rgba f 0.0 0.0 0.5 1 } | |
: dot-or-parens ( string -- string ) | |
[ "." ] | |
[ "(" prepend ")" append ] if-empty ; | |
GENERIC: write-irc ( irc-message -- ) | |
M: ping write-irc | |
drop "* Ping" blue write-color ; | |
M: privmsg write-irc | |
"<" dark-blue write-color | |
[ irc-message-sender write ] keep | |
"> " dark-blue write-color | |
trailing>> write ; | |
M: notice write-irc | |
[ type>> dark-blue write-color ] keep | |
": " dark-blue write-color | |
trailing>> write ; | |
TUPLE: own-message message nick timestamp ; | |
: <own-message> ( message nick -- own-message ) | |
now own-message boa ; | |
M: own-message write-irc | |
"<" dark-blue write-color | |
[ nick>> bold font-style associate format ] keep | |
"> " dark-blue write-color | |
message>> write ; | |
M: join write-irc | |
"* " dark-green write-color | |
irc-message-sender write | |
" has entered the channel." dark-green write-color ; | |
M: part write-irc | |
"* " dark-red write-color | |
[ irc-message-sender write ] keep | |
" has left the channel" dark-red write-color | |
trailing>> dot-or-parens dark-red write-color ; | |
M: quit write-irc | |
"* " dark-red write-color | |
[ irc-message-sender write ] keep | |
" has left IRC" dark-red write-color | |
trailing>> dot-or-parens dark-red write-color ; | |
M: kick write-irc | |
"* " dark-red write-color | |
[ irc-message-sender write ] keep | |
" has kicked " dark-red write-color | |
[ who>> write ] keep | |
" from the channel" dark-red write-color | |
trailing>> dot-or-parens dark-red write-color ; | |
M: mode write-irc | |
"* " dark-blue write-color | |
[ name>> write ] keep | |
" has applied mode " dark-blue write-color | |
[ mode>> write ] keep | |
" to " dark-blue write-color | |
parameter>> write ; | |
M: nick write-irc | |
"* " dark-blue write-color | |
[ irc-message-sender write ] keep | |
" is now known as " blue write-color | |
trailing>> write ; | |
M: unhandled write-irc | |
"UNHANDLED: " write | |
line>> dark-blue write-color ; | |
M: irc-end write-irc | |
drop "* You have left IRC" dark-red write-color ; | |
M: irc-disconnected write-irc | |
drop "* Disconnected" dark-red write-color ; | |
M: irc-connected write-irc | |
drop "* Connected" dark-green write-color ; | |
M: irc-chat-end write-irc | |
drop ; | |
M: irc-message write-irc | |
"UNIMPLEMENTED" write | |
[ class pprint ] keep | |
": " write | |
line>> dark-blue write-color ; | |
GENERIC: time-happened ( message -- timestamp ) | |
M: irc-message time-happened timestamp>> ; | |
M: object time-happened drop now ; | |
: print-irc ( irc-message -- ) | |
[ time-happened timestamp>hms write " " write ] | |
[ write-irc nl ] bi ; | |
: send-message ( message -- ) | |
[ print-irc ] | |
[ chat get speak ] bi ; | |
GENERIC: handle-inbox ( tab message -- ) | |
: value-labels ( assoc val -- seq ) | |
'[ nip _ = ] assoc-filter keys sort-strings [ <label> ] map ; | |
: add-gadget-color ( pack seq color -- pack ) | |
'[ _ >>color add-gadget ] each ; | |
M: object handle-inbox | |
nip print-irc ; | |
: display ( stream tab -- ) | |
'[ _ [ [ t ] | |
[ _ dup chat>> hear handle-inbox ] | |
while ] with-output-stream ] "ircv" spawn drop ; | |
: <irc-pane> ( tab -- tab pane ) | |
<scrolling-pane> | |
[ <pane-stream> swap display ] 2keep ; | |
TUPLE: irc-editor < editor outstream tab ; | |
: <irc-editor> ( tab pane -- tab editor ) | |
irc-editor new-editor | |
swap <pane-stream> >>outstream ; | |
: editor-send ( irc-editor -- ) | |
{ [ outstream>> ] | |
[ [ irc-tab? ] find-parent ] | |
[ editor-string ] | |
[ "" swap set-editor-string ] } cleave | |
'[ _ irc-tab set _ parse-message ] with-output-stream ; | |
irc-editor "general" f { | |
{ T{ key-down f f "RET" } editor-send } | |
{ T{ key-down f f "ENTER" } editor-send } | |
} define-command-map | |
: new-irc-tab ( chat ui-window class -- irc-tab ) | |
new-frame | |
swap >>window | |
swap >>chat | |
<irc-pane> [ <scroller> @center grid-add ] keep | |
<irc-editor> <scroller> @bottom grid-add ; | |
M: irc-tab graft* | |
[ chat>> ] [ window>> client>> ] bi attach-chat ; | |
M: irc-tab ungraft* | |
chat>> detach-chat ; | |
TUPLE: irc-channel-tab < irc-tab userlist ; | |
: <irc-channel-tab> ( chat ui-window -- irc-tab ) | |
irc-channel-tab new-irc-tab | |
<pile> [ <scroller> @right grid-add ] keep >>userlist ; | |
: update-participants ( tab -- ) | |
[ userlist>> [ clear-gadget ] keep ] | |
[ chat>> participants>> ] bi | |
[ +operator+ value-labels dark-green add-gadget-color ] | |
[ +voice+ value-labels blue add-gadget-color ] | |
[ +normal+ value-labels black add-gadget-color ] tri drop ; | |
M: participant-changed handle-inbox | |
drop update-participants ; | |
TUPLE: irc-server-tab < irc-tab ; | |
: <irc-server-tab> ( chat -- irc-tab ) | |
f irc-server-tab new-irc-tab ; | |
: <irc-nick-tab> ( chat ui-window -- irc-tab ) | |
irc-tab new-irc-tab ; | |
M: irc-tab pref-dim* | |
drop { 480 480 } ; | |
: join-channel ( name ui-window -- ) | |
[ dup <irc-channel-chat> ] dip | |
[ <irc-channel-tab> swap ] keep | |
add-page ; | |
: query-nick ( nick ui-window -- ) | |
[ dup <irc-nick-chat> ] dip | |
[ <irc-nick-tab> swap ] keep | |
add-page ; | |
: irc-window ( ui-window -- ) | |
[ ] | |
[ client>> profile>> server>> ] bi | |
open-window ; | |
: ui-connect ( profile -- ui-window ) | |
<irc-client> | |
{ [ [ <irc-server-chat> ] dip attach-chat ] | |
[ chats>> +server-chat+ swap at <irc-server-tab> dup | |
"Server" associate ui-window new-tabbed [ swap window<< ] keep ] | |
[ >>client ] | |
[ connect-irc ] } cleave ; | |
: server-open ( server port nick password channels -- ) | |
[ <irc-profile> ui-connect [ irc-window ] keep ] dip | |
[ over join-channel ] each drop ; | |
: main-run ( -- ) run-ircui ; | |
MAIN: main-run | |
"irc.ui.commands" require | |
]] | |
FILE: [[irc/ui/commandparser/commandparser.factor]] [[! Copyright (C) 2008 William Schlieper | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: kernel vocabs.loader sequences strings splitting words irc.messages ; | |
IN: irc.ui.commandparser | |
: command ( string string -- string command ) | |
[ "say" ] when-empty | |
dup "irc.ui.commands" lookup | |
[ nip ] | |
[ " " append prepend "quote" "irc.ui.commands" lookup ] if* ; | |
: parse-message ( string -- ) | |
"/" ?head [ " " split1 swap command ] [ "say" command ] if execute ; | |
]] | |
FILE: [[irc/ui/load/load.factor]] [[! Copyright (C) 2008 William Schlieper | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: kernel io.files io.pathnames parser editors sequences ; | |
IN: irc.ui.load | |
: file-or ( path path -- path ) [ [ exists? ] keep ] dip ? ; | |
: personal-ui-rc ( -- path ) home ".ircui-rc" append-path ; | |
: system-ui-rc ( -- path ) "extra/irc/ui/ircui-rc" resource-path ; | |
: ircui-rc ( -- path ) personal-ui-rc system-ui-rc file-or ; | |
: run-ircui ( -- ) ircui-rc run-file ; | |
]] | |
FILE: [[irc/ui/summary.txt]] [[A simple IRC client]] | |
FILE: [[irc/ui/commands/commands.factor]] [[! Copyright (C) 2008 William Schlieper | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: accessors kernel sequences arrays irc.client | |
irc.messages irc.ui namespaces ; | |
IN: irc.ui.commands | |
: say ( string -- ) | |
irc-tab get | |
[ window>> client>> profile>> nickname>> <own-message> print-irc ] | |
[ chat>> speak ] 2bi ; | |
: me ( string -- ) ! Placeholder until I make /me look different | |
"ACTION " 1 prefix prepend 1 suffix say ; | |
: join ( string -- ) | |
irc-tab get window>> join-channel ; | |
: query ( string -- ) | |
irc-tab get window>> query-nick ; | |
: whois ( string -- ) | |
"WHOIS" swap { } clone swap <irc-client-message> | |
irc-tab get listener>> speak ; | |
: quote ( string -- ) | |
drop ; ! THIS WILL CHANGE | |
]] | |
FILE: [[irc/ui/authors.txt]] [[William Schlieper | |
]] | |
FILE: [[io/sockets/headers/headers.factor]] [[! Copyright (C) 2007 Doug Coleman. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: alien alien.c-types alien.syntax byte-arrays io | |
io.sockets kernel structs math math.parser | |
prettyprint sequences ; | |
IN: io.sockets.headers | |
C-STRUCT: etherneth | |
{ { "char" 6 } "dmac" } | |
{ { "char" 6 } "smac" } | |
{ "ushort" "type" } ; | |
: >mac-address ( byte-array -- string ) | |
6 memory>byte-array | |
[ >hex 2 48 pad-left ] { } map-as ":" join ; | |
: etherneth. ( etherneth -- ) | |
[ etherneth-dmac "Dest MAC: " write >mac-address . ] keep | |
[ etherneth-smac "Source MAC: " write >mac-address . ] keep | |
[ etherneth-type "Type : " write .h ] keep | |
drop ; | |
C-STRUCT: iph | |
{ "uchar" "hl|v" } ! hl is 4 bits, v is 4 bits | |
{ "uchar" "tos" } | |
{ "short" "len" } | |
{ "short" "id" } | |
{ "short" "off" } | |
{ "uchar" "ttl" } | |
{ "uchar" "p" } | |
{ "ushort" "ip_sum" } | |
{ "uint" "ip_src" } | |
{ "uint" "ip_dst" } ; | |
: iph-hl ( iph -- n ) | |
iph-hl|v -4 shift ; | |
: iph-v ( iph -- n ) | |
iph-hl|v 0x0f bitand ; | |
: set-iph-hl ( n iph -- ) | |
[ iph-hl|v 0x0f bitand >r 4 shift r> bitor ] keep | |
set-iph-hl|v ; | |
: set-iph-v ( n iph -- ) | |
[ iph-hl|v 0xf0 bitand bitor ] keep | |
set-iph-hl|v ; | |
C-STRUCT: icmph | |
{ "uchar" "type" } | |
{ "uchar" "code" } | |
{ "short" "chksum" } | |
{ "ushort" "id" } | |
{ "ushort" "seq" } ; | |
C-STRUCT: udph | |
{ "ushort" "sport" } | |
{ "ushort" "dport" } | |
{ "ushort" "len" } | |
{ "ushort" "check" } ; | |
C-STRUCT: tcph | |
{ "ushort" "sport" } | |
{ "ushort" "dport" } | |
{ "uint" "seq" } | |
{ "uint" "ack" } | |
{ "uchar" "x2|off" } | |
{ "uchar" "flags" } | |
{ "ushort" "win" } | |
{ "ushort" "sum" } | |
{ "ushort" "urp" } ; | |
: tcph-x2 ( iph -- n ) | |
tcph-x2|off -4 shift ; | |
: tcph-off ( iph -- n ) | |
tcph-x2|off 0x0f bitand ; | |
: set-tcph-x2 ( n iph -- ) | |
[ tcph-x2|off 0x0f bitand >r 4 shift r> bitor ] keep | |
set-tcph-x2|off ; | |
: set-tcph-off ( n iph -- ) | |
[ tcph-x2|off 0x0f bitand bitor ] keep | |
set-tcph-x2|off ; | |
]] | |
FILE: [[io/sockets/headers/bsd/bsd.factor]] [[! Copyright (C) 2007 Doug Coleman. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: alien alien.c-types alien.syntax byte-arrays io | |
kernel math prettyprint ; | |
IN: io.sockets.headers.bsd | |
C-STRUCT: bpfh | |
{ "timeval" "timestamp" } | |
{ "ulong" "caplen" } | |
{ "ulong" "datalen" } | |
{ "ushort" "hdrlen" } ; | |
: bpfh. ( bpfh -- ) | |
[ | |
bpfh-timestamp "Timestamp: " write | |
"timeval" heap-size memory>byte-array . | |
] keep | |
[ bpfh-caplen "caplen: " write . ] keep | |
[ bpfh-datalen "datalen: " write . ] keep | |
[ bpfh-hdrlen "hdrlen: " write . ] keep | |
drop ; | |
]] | |
FILE: [[io/sockets/headers/bsd/authors.txt]] [[Doug Coleman | |
]] | |
FILE: [[io/sockets/headers/authors.txt]] [[Doug Coleman | |
]] | |
FILE: [[run-desc/run-desc.factor]] [[USING: io io.encodings.utf8 io.launcher kernel sequences ; | |
IN: run-desc | |
: run-desc ( desc -- result ) utf8 [ contents [ but-last ] [ f ] if* ] with-process-reader ; | |
]] | |
FILE: [[llvm/reader/add.bc]] base64[[QkPA3iEMAAAwAAAAARAAABAAAAAHgSORQcgESQYQMjmSAYQMJQUIGR4Ei2KADEUCQpILQmQQMhQ4CBhJCjJEJEgKkCEjRHKAjAwhhgqKCmQMHwAAUSAAAAkAAAAyIsgIIGWChAAmQ0gFCSZDxgVCMiYIiDkCMCCVAcAIAAAAAABDkgAAAAAAACAMBAAKAAAAEwRBBQLgEA4EAAAABQAAADYwSBRjAcFlAgF2AAXRTBEGAAAAAAAAAHEgAAACAAAABjAAwwAAAAAAAAAA]] | |
FILE: [[llvm/reader/reader.factor]] [[! Copyright (C) 2009 Matthew Willis. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: accessors alien.c-types alien.data alien.syntax | |
destructors kernel llvm.core llvm.engine llvm.jit llvm.wrappers | |
; | |
IN: llvm.reader | |
: buffer>module ( buffer -- module ) | |
[ | |
value>> f void* <ref> f void* <ref> | |
[ LLVMParseBitcode drop ] 2keep | |
void* deref [ llvm-throw ] when* void* deref | |
module new swap >>value | |
] with-disposal ; | |
: load-module ( path -- module ) | |
<buffer> buffer>module ; | |
: load-into-jit ( path name -- ) | |
[ load-module ] dip add-module ; | |
]] | |
FILE: [[llvm/reader/add.ll]] [[define i32 @add(i32 %x, i32 %y) { | |
entry: | |
%sum = add i32 %x, %y | |
ret i32 %sum | |
} | |
]] | |
FILE: [[llvm/reader/tags.txt]] [[not tested | |
]] | |
FILE: [[llvm/wrappers/wrappers.factor]] [[! Copyright (C) 2009 Matthew Willis. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: accessors alien.c-types alien.data alien.strings | |
io.encodings.utf8 destructors kernel | |
llvm.core llvm.engine ; | |
IN: llvm.wrappers | |
: llvm-throw ( c-string -- ) | |
[ utf8 alien>string ] [ LLVMDisposeMessage ] bi throw ; | |
: <dispose> ( alien class -- disposable ) new swap >>value ; | |
TUPLE: module value disposed ; | |
M: module dispose* value>> LLVMDisposeModule ; | |
: <module> ( name -- module ) | |
LLVMModuleCreateWithName module <dispose> ; | |
TUPLE: provider value module disposed ; | |
M: provider dispose* value>> LLVMDisposeModuleProvider ; | |
: (provider) ( module -- provider ) | |
[ value>> LLVMCreateModuleProviderForExistingModule provider <dispose> ] | |
[ t >>disposed value>> ] bi | |
>>module ; | |
: <provider> ( module -- provider ) | |
[ (provider) ] with-disposal ; | |
TUPLE: engine value disposed ; | |
M: engine dispose* value>> LLVMDisposeExecutionEngine ; | |
: (engine) ( provider -- engine ) | |
[ | |
value>> f void* <ref> f void* <ref> | |
[ swapd 0 swap LLVMCreateJITCompiler drop ] 2keep | |
void* deref [ llvm-throw ] when* void* deref | |
] | |
[ t >>disposed drop ] bi | |
engine <dispose> ; | |
: <engine> ( provider -- engine ) | |
[ (engine) ] with-disposal ; | |
: (add-block) ( name -- basic-block ) | |
"function" swap LLVMAppendBasicBlock ; | |
TUPLE: builder value disposed ; | |
M: builder dispose* value>> LLVMDisposeBuilder ; | |
: <builder> ( name -- builder ) | |
(add-block) LLVMCreateBuilder [ swap LLVMPositionBuilderAtEnd ] keep | |
builder <dispose> ; | |
TUPLE: buffer value disposed ; | |
M: buffer dispose* value>> LLVMDisposeMemoryBuffer ; | |
: <buffer> ( path -- module ) | |
f void* <ref> f void* <ref> | |
[ LLVMCreateMemoryBufferWithContentsOfFile drop ] 2keep | |
void* deref [ llvm-throw ] when* void* deref buffer <dispose> ; | |
]] | |
FILE: [[llvm/wrappers/wrappers-tests.factor]] [[! Copyright (C) 2009 Matthew Willis. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: destructors kernel llvm.wrappers sequences tools.test vocabs ; | |
{ } [ "test" <module> dispose ] unit-test | |
{ } [ "test" <module> <provider> dispose ] unit-test | |
{ } [ "llvm.jit" vocabs member? [ "test" <module> <provider> <engine> dispose ] unless ] unit-test | |
]] | |
FILE: [[llvm/wrappers/tags.txt]] [[not tested | |
]] | |
FILE: [[llvm/clang/ffi/platforms.txt]] [[unix]] | |
FILE: [[llvm/clang/ffi/ffi.factor]] [[USING: alien alien.c-types alien.libraries alien.syntax | |
classes.struct combinators system unix.types ; | |
IN: llvm.clang.ffi | |
<< | |
"libclang" { | |
{ [ os macosx? ] [ "libclang.dylib" ] } | |
{ [ os windows? ] [ "clang.dll" ] } | |
{ [ os unix? ] [ "/usrlibclang.so" ] } | |
} cond cdecl add-library | |
>> | |
LIBRARY: libclang | |
C-TYPE: CXTranslationUnitImpl | |
TYPEDEF: void* CXIndex | |
TYPEDEF: CXTranslationUnitImpl* CXTranslationUnit | |
TYPEDEF: void* CXClientData | |
STRUCT: CXUnsavedFile | |
{ Filename c-string } | |
{ Contents c-string } | |
{ Length ulong } ; | |
ENUM: CXAvailabilityKind | |
CXAvailability_Available | |
CXAvailability_Deprecated | |
CXAvailability_NotAvailable ; | |
STRUCT: CXString | |
{ data void* } | |
{ private_flags uint } ; | |
FUNCTION: c-string clang_getCString ( CXString string ) ; | |
FUNCTION: void clang_disposeString ( CXString string ) ; | |
FUNCTION: CXIndex clang_createIndex ( int excludeDeclarationsFromPCH, | |
int displayDiagnostics ) ; | |
FUNCTION: void clang_disposeIndex ( CXIndex index ) ; | |
TYPEDEF: void* CXFile | |
FUNCTION: CXString clang_getFileName ( CXFile SFile ) ; | |
FUNCTION: time_t clang_getFileTime ( CXFile SFile ) ; | |
FUNCTION: uint clang_isFileMultipleIncludeGuarded ( CXTranslationUnit tu, CXFile file ) ; | |
FUNCTION: CXFile clang_getFile ( CXTranslationUnit tu, c-string file_name ) ; | |
STRUCT: CXSourceLocation | |
{ ptr_data void*[2] } | |
{ int_data uint } ; | |
STRUCT: CXSourceRange | |
{ ptr_data void*[2] } | |
{ begin_int_data uint } | |
{ end_int_data uint } ; | |
FUNCTION: CXSourceLocation clang_getNullLocation ( ) ; | |
FUNCTION: uint clang_equalLocations ( CXSourceLocation loc1, CXSourceLocation loc2 ) ; | |
FUNCTION: CXSourceLocation clang_getLocation ( CXTranslationUnit tu, CXFile file, uint line, uint column ) ; | |
FUNCTION: CXSourceLocation clang_getLocationForOffset ( CXTranslationUnit tu, | |
CXFile file, | |
uint offset ) ; | |
FUNCTION: CXSourceRange clang_getNullRange ( ) ; | |
FUNCTION: CXSourceRange clang_getRange ( CXSourceLocation begin, | |
CXSourceLocation end ) ; | |
FUNCTION: void clang_getInstantiationLocation ( CXSourceLocation location, | |
CXFile* file, | |
uint* line, | |
uint* column, | |
uint* offset ) ; | |
FUNCTION: void clang_getSpellingLocation ( CXSourceLocation location, | |
CXFile* file, | |
uint* line, | |
uint* column, | |
uint* offset ) ; | |
FUNCTION: CXSourceLocation clang_getRangeStart ( CXSourceRange range ) ; | |
FUNCTION: CXSourceLocation clang_getRangeEnd ( CXSourceRange range ) ; | |
ENUM: CXDiagnosticSeverity | |
CXDiagnostic_Ignored | |
CXDiagnostic_Note | |
CXDiagnostic_Warning | |
CXDiagnostic_Error | |
CXDiagnostic_Fatal ; | |
TYPEDEF: void* CXDiagnostic | |
FUNCTION: uint clang_getNumDiagnostics ( CXTranslationUnit Unit ) ; | |
FUNCTION: CXDiagnostic clang_getDiagnostic ( CXTranslationUnit Unit, | |
uint Index ) ; | |
FUNCTION: void clang_disposeDiagnostic ( CXDiagnostic Diagnostic ) ; | |
ENUM: CXDiagnosticDisplayOptions | |
{ CXDiagnostic_DisplaySourceLocation 0x01 } | |
{ CXDiagnostic_DisplayColumn 0x02 } | |
{ CXDiagnostic_DisplaySourceRanges 0x04 } | |
{ CXDiagnostic_DisplayOption 0x08 } | |
{ CXDiagnostic_DisplayCategoryId 0x10 } | |
{ CXDiagnostic_DisplayCategoryName 0x20 } ; | |
FUNCTION: CXString clang_formatDiagnostic ( CXDiagnostic Diagnostic, | |
uint Options ) ; | |
FUNCTION: uint clang_defaultDiagnosticDisplayOptions ( ) ; | |
FUNCTION: CXDiagnosticSeverity clang_getDiagnosticSeverity ( CXDiagnostic ) ; | |
FUNCTION: CXSourceLocation clang_getDiagnosticLocation ( CXDiagnostic ) ; | |
FUNCTION: CXString clang_getDiagnosticSpelling ( CXDiagnostic ) ; | |
FUNCTION: CXString clang_getDiagnosticOption ( CXDiagnostic Diag, CXString* Disable ) ; | |
FUNCTION: uint clang_getDiagnosticCategory ( CXDiagnostic ) ; | |
FUNCTION: CXString clang_getDiagnosticCategoryName ( uint Category ) ; | |
FUNCTION: uint clang_getDiagnosticNumRanges ( CXDiagnostic ) ; | |
FUNCTION: CXSourceRange clang_getDiagnosticRange ( CXDiagnostic Diagnostic, uint Range ) ; | |
FUNCTION: uint clang_getDiagnosticNumFixIts ( CXDiagnostic Diagnostic ) ; | |
FUNCTION: CXString clang_getDiagnosticFixIt ( CXDiagnostic Diagnostic, | |
uint FixIt, | |
CXSourceRange* ReplacementRange ) ; | |
FUNCTION: CXString clang_getTranslationUnitSpelling ( CXTranslationUnit CTUnit ) ; | |
FUNCTION: CXTranslationUnit clang_createTranslationUnitFromSourceFile ( CXIndex CIdx, | |
c-string source_filename, | |
int num_clang_command_line_args, | |
char** clang_command_line_args, | |
uint num_unsaved_files, | |
CXUnsavedFile* unsaved_files ) ; | |
FUNCTION: CXTranslationUnit clang_createTranslationUnit ( CXIndex CIdx, c-string ast_filename ) ; | |
ENUM: CXTranslationUnit_Flags | |
{ CXTranslationUnit_None 0x00 } | |
{ CXTranslationUnit_DetailedPreprocessingRecord 0x01 } | |
{ CXTranslationUnit_Incomplete 0x02 } | |
{ CXTranslationUnit_PrecompiledPreamble 0x04 } | |
{ CXTranslationUnit_CacheCompletionResults 0x08 } | |
{ CXTranslationUnit_CXXPrecompiledPreamble 0x10 } | |
{ CXTranslationUnit_CXXChainedPCH 0x20 } | |
{ CXTranslationUnit_NestedMacroInstantiations 0x40 } ; | |
FUNCTION: uint clang_defaultEditingTranslationUnitOptions ( ) ; | |
FUNCTION: CXTranslationUnit clang_parseTranslationUnit ( CXIndex CIdx, | |
c-string source_filename, | |
char** command_line_args, | |
int num_command_line_args, | |
CXUnsavedFile* unsaved_files, | |
uint num_unsaved_files, | |
uint options ) ; | |
ENUM: CXSaveTranslationUnit_Flags CXSaveTranslationUnit_None ; | |
FUNCTION: uint clang_defaultSaveOptions ( CXTranslationUnit TU ) ; | |
FUNCTION: int clang_saveTranslationUnit ( CXTranslationUnit TU, | |
c-string FileName, | |
uint options ) ; | |
FUNCTION: void clang_disposeTranslationUnit ( CXTranslationUnit ) ; | |
ENUM: CXReparse_Flags CXReparse_None ; | |
FUNCTION: uint clang_defaultReparseOptions ( CXTranslationUnit TU ) ; | |
FUNCTION: int clang_reparseTranslationUnit ( CXTranslationUnit TU, | |
uint num_unsaved_files, | |
CXUnsavedFile* unsaved_files, | |
uint options ) ; | |
ENUM: CXTUResourceUsageKind | |
{ CXTUResourceUsage_AST 1 } | |
{ CXTUResourceUsage_Identifiers 2 } | |
{ CXTUResourceUsage_Selectors 3 } | |
{ CXTUResourceUsage_GlobalCompletionResults 4 } | |
{ CXTUResourceUsage_SourceManagerContentCache 5 } | |
{ CXTUResourceUsage_AST_SideTables 6 } | |
{ CXTUResourceUsage_SourceManager_Membuffer_Malloc 7 } | |
{ CXTUResourceUsage_SourceManager_Membuffer_MMap 8 } | |
{ CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc 9 } | |
{ CXTUResourceUsage_ExternalASTSource_Membuffer_MMap 10 } | |
{ CXTUResourceUsage_Preprocessor 11 } | |
{ CXTUResourceUsage_PreprocessingRecord 12 } | |
{ CXTUResourceUsage_MEMORY_IN_BYTES_BEGIN 1 } | |
{ CXTUResourceUsage_MEMORY_IN_BYTES_END 12 } | |
{ CXTUResourceUsage_First 1 } | |
{ CXTUResourceUsage_Last 12 } ; | |
FUNCTION: c-string clang_getTUResourceUsageName ( CXTUResourceUsageKind kind ) ; | |
STRUCT: CXTUResourceUsageEntry | |
{ kind CXTUResourceUsageKind } | |
{ amount ulong } ; | |
STRUCT: CXTUResourceUsage | |
{ data void* } | |
{ numEntries uint } | |
{ entries CXTUResourceUsageEntry* } ; | |
FUNCTION: CXTUResourceUsage clang_getCXTUResourceUsage ( CXTranslationUnit TU ) ; | |
FUNCTION: void clang_disposeCXTUResourceUsage ( CXTUResourceUsage usage ) ; | |
ENUM: CXCursorKind | |
{ CXCursor_UnexposedDecl 1 } | |
{ CXCursor_StructDecl 2 } | |
{ CXCursor_UnionDecl 3 } | |
{ CXCursor_ClassDecl 4 } | |
{ CXCursor_EnumDecl 5 } | |
{ CXCursor_FieldDecl 6 } | |
{ CXCursor_EnumConstantDecl 7 } | |
{ CXCursor_FunctionDecl 8 } | |
{ CXCursor_VarDecl 9 } | |
{ CXCursor_ParmDecl 10 } | |
{ CXCursor_ObjCInterfaceDecl 11 } | |
{ CXCursor_ObjCCategoryDecl 12 } | |
{ CXCursor_ObjCProtocolDecl 13 } | |
{ CXCursor_ObjCPropertyDecl 14 } | |
{ CXCursor_ObjCIvarDecl 15 } | |
{ CXCursor_ObjCInstanceMethodDecl 16 } | |
{ CXCursor_ObjCClassMethodDecl 17 } | |
{ CXCursor_ObjCImplementationDecl 18 } | |
{ CXCursor_ObjCCategoryImplDecl 19 } | |
{ CXCursor_TypedefDecl 20 } | |
{ CXCursor_CXXMethod 21 } | |
{ CXCursor_Namespace 22 } | |
{ CXCursor_LinkageSpec 23 } | |
{ CXCursor_Constructor 24 } | |
{ CXCursor_Destructor 25 } | |
{ CXCursor_ConversionFunction 26 } | |
{ CXCursor_TemplateTypeParameter 27 } | |
{ CXCursor_NonTypeTemplateParameter 28 } | |
{ CXCursor_TemplateTemplateParameter 29 } | |
{ CXCursor_FunctionTemplate 30 } | |
{ CXCursor_ClassTemplate 31 } | |
{ CXCursor_ClassTemplatePartialSpecialization 32 } | |
{ CXCursor_NamespaceAlias 33 } | |
{ CXCursor_UsingDirective 34 } | |
{ CXCursor_UsingDeclaration 35 } | |
{ CXCursor_TypeAliasDecl 36 } | |
{ CXCursor_FirstDecl 1 } | |
{ CXCursor_LastDecl 36 } | |
{ CXCursor_FirstRef 40 } | |
{ CXCursor_ObjCSuperClassRef 40 } | |
{ CXCursor_ObjCProtocolRef 41 } | |
{ CXCursor_ObjCClassRef 42 } | |
{ CXCursor_TypeRef 43 } | |
{ CXCursor_CXXBaseSpecifier 44 } | |
{ CXCursor_TemplateRef 45 } | |
{ CXCursor_NamespaceRef 46 } | |
{ CXCursor_MemberRef 47 } | |
{ CXCursor_LabelRef 48 } | |
{ CXCursor_OverloadedDeclRef 49 } | |
{ CXCursor_LastRef 49 } | |
{ CXCursor_FirstInvalid 70 } | |
{ CXCursor_InvalidFile 70 } | |
{ CXCursor_NoDeclFound 71 } | |
{ CXCursor_NotImplemented 72 } | |
{ CXCursor_InvalidCode 73 } | |
{ CXCursor_LastInvalid 73 } | |
{ CXCursor_FirstExpr 100 } | |
{ CXCursor_UnexposedExpr 100 } | |
{ CXCursor_DeclRefExpr 101 } | |
{ CXCursor_MemberRefExpr 102 } | |
{ CXCursor_CallExpr 103 } | |
{ CXCursor_ObjCMessageExpr 104 } | |
{ CXCursor_BlockExpr 105 } | |
{ CXCursor_LastExpr 105 } | |
{ CXCursor_FirstStmt 200 } | |
{ CXCursor_UnexposedStmt 200 } | |
{ CXCursor_LabelStmt 201 } | |
{ CXCursor_LastStmt 201 } | |
{ CXCursor_TranslationUnit 300 } | |
{ CXCursor_FirstAttr 400 } | |
{ CXCursor_UnexposedAttr 400 } | |
{ CXCursor_IBActionAttr 401 } | |
{ CXCursor_IBOutletAttr 402 } | |
{ CXCursor_IBOutletCollectionAttr 403 } | |
{ CXCursor_LastAttr 403 } | |
{ CXCursor_PreprocessingDirective 500 } | |
{ CXCursor_MacroDefinition 501 } | |
{ CXCursor_MacroInstantiation 502 } | |
{ CXCursor_InclusionDirective 503 } | |
{ CXCursor_FirstPreprocessing 500 } | |
{ CXCursor_LastPreprocessing 503 } ; | |
STRUCT: CXCursor | |
{ kind CXCursorKind } | |
{ data void*[3] } ; | |
FUNCTION: CXCursor clang_getNullCursor ( ) ; | |
FUNCTION: CXCursor clang_getTranslationUnitCursor ( CXTranslationUnit ) ; | |
FUNCTION: uint clang_equalCursors ( CXCursor c1, CXCursor c2 ) ; | |
FUNCTION: uint clang_hashCursor ( CXCursor ) ; | |
FUNCTION: CXCursorKind clang_getCursorKind ( CXCursor ) ; | |
FUNCTION: uint clang_isDeclaration ( CXCursorKind ) ; | |
FUNCTION: uint clang_isReference ( CXCursorKind ) ; | |
FUNCTION: uint clang_isExpression ( CXCursorKind ) ; | |
FUNCTION: uint clang_isStatement ( CXCursorKind ) ; | |
FUNCTION: uint clang_isInvalid ( CXCursorKind ) ; | |
FUNCTION: uint clang_isTranslationUnit ( CXCursorKind ) ; | |
FUNCTION: uint clang_isPreprocessing ( CXCursorKind ) ; | |
FUNCTION: uint clang_isUnexposed ( CXCursorKind ) ; | |
ENUM: CXLinkageKind | |
CXLinkage_Invalid | |
CXLinkage_NoLinkage | |
CXLinkage_Internal | |
CXLinkage_UniqueExternal | |
CXLinkage_External ; | |
ENUM: CXLanguageKind | |
CXLanguage_Invalid | |
CXLanguage_C | |
CXLanguage_ObjC | |
CXLanguage_CPlusPlus ; | |
FUNCTION: CXLinkageKind clang_getCursorLinkage ( CXCursor cursor ) ; | |
FUNCTION: CXAvailabilityKind clang_getCursorAvailability ( CXCursor cursor ) ; | |
FUNCTION: CXLanguageKind clang_getCursorLanguage ( CXCursor cursor ) ; | |
C-TYPE: CXCursorSetImpl | |
TYPEDEF: CXCursorSetImpl* CXCursorSet | |
FUNCTION: CXCursorSet clang_createCXCursorSet ( ) ; | |
FUNCTION: void clang_disposeCXCursorSet ( CXCursorSet cset ) ; | |
FUNCTION: uint clang_CXCursorSet_contains ( CXCursorSet cset, CXCursor cursor ) ; | |
FUNCTION: uint clang_CXCursorSet_insert ( CXCursorSet cset, CXCursor cursor ) ; | |
FUNCTION: CXCursor clang_getCursorSemanticParent ( CXCursor cursor ) ; | |
FUNCTION: CXCursor clang_getCursorLexicalParent ( CXCursor cursor ) ; | |
FUNCTION: void clang_getOverriddenCursors ( CXCursor cursor, CXCursor** overridden, uint* num_overridden ) ; | |
FUNCTION: void clang_disposeOverriddenCursors ( CXCursor* overridden ) ; | |
FUNCTION: CXFile clang_getIncludedFile ( CXCursor cursor ) ; | |
FUNCTION: CXCursor clang_getCursor ( CXTranslationUnit TU, | |
CXSourceLocation location ) ; | |
FUNCTION: CXSourceLocation clang_getCursorLocation ( CXCursor ) ; | |
FUNCTION: CXSourceRange clang_getCursorExtent ( CXCursor ) ; | |
ENUM: CXTypeKind | |
{ CXType_Invalid 0 } | |
{ CXType_Unexposed 1 } | |
{ CXType_Void 2 } | |
{ CXType_Bool 3 } | |
{ CXType_Char_U 4 } | |
{ CXType_UChar 5 } | |
{ CXType_Char16 6 } | |
{ CXType_Char32 7 } | |
{ CXType_UShort 8 } | |
{ CXType_UInt 9 } | |
{ CXType_ULong 10 } | |
{ CXType_ULongLong 11 } | |
{ CXType_UInt128 12 } | |
{ CXType_Char_S 13 } | |
{ CXType_SChar 14 } | |
{ CXType_WChar 15 } | |
{ CXType_Short 16 } | |
{ CXType_Int 17 } | |
{ CXType_Long 18 } | |
{ CXType_LongLong 19 } | |
{ CXType_Int128 20 } | |
{ CXType_Float 21 } | |
{ CXType_Double 22 } | |
{ CXType_LongDouble 23 } | |
{ CXType_NullPtr 24 } | |
{ CXType_Overload 25 } | |
{ CXType_Dependent 26 } | |
{ CXType_ObjCId 27 } | |
{ CXType_ObjCClass 28 } | |
{ CXType_ObjCSel 29 } | |
{ CXType_FirstBuiltin 2 } | |
{ CXType_LastBuiltin 29 } | |
{ CXType_Complex 100 } | |
{ CXType_Pointer 101 } | |
{ CXType_BlockPointer 102 } | |
{ CXType_LValueReference 103 } | |
{ CXType_RValueReference 104 } | |
{ CXType_Record 105 } | |
{ CXType_Enum 106 } | |
{ CXType_Typedef 107 } | |
{ CXType_ObjCInterface 108 } | |
{ CXType_ObjCObjectPointer 109 } | |
{ CXType_FunctionNoProto 110 } | |
{ CXType_FunctionProto 111 } ; | |
STRUCT: CXType | |
{ kind CXTypeKind } | |
{ data void*[2] } ; | |
FUNCTION: CXType clang_getCursorType ( CXCursor C ) ; | |
FUNCTION: uint clang_equalTypes ( CXType A, CXType B ) ; | |
FUNCTION: CXType clang_getCanonicalType ( CXType T ) ; | |
FUNCTION: uint clang_isConstQualifiedType ( CXType T ) ; | |
FUNCTION: uint clang_isVolatileQualifiedType ( CXType T ) ; | |
FUNCTION: uint clang_isRestrictQualifiedType ( CXType T ) ; | |
FUNCTION: CXType clang_getPointeeType ( CXType T ) ; | |
FUNCTION: CXCursor clang_getTypeDeclaration ( CXType T ) ; | |
FUNCTION: CXString clang_getDeclObjCTypeEncoding ( CXCursor C ) ; | |
FUNCTION: CXString clang_getTypeKindSpelling ( CXTypeKind K ) ; | |
FUNCTION: CXType clang_getResultType ( CXType T ) ; | |
FUNCTION: CXType clang_getCursorResultType ( CXCursor C ) ; | |
FUNCTION: uint clang_isPODType ( CXType T ) ; | |
FUNCTION: uint clang_isVirtualBase ( CXCursor ) ; | |
ENUM: CX_CXXAccessSpecifier | |
CX_CXXInvalidAccessSpecifier | |
CX_CXXPublic | |
CX_CXXProtected | |
CX_CXXPrivate ; | |
FUNCTION: CX_CXXAccessSpecifier clang_getCXXAccessSpecifier ( CXCursor ) ; | |
FUNCTION: uint clang_getNumOverloadedDecls ( CXCursor cursor ) ; | |
FUNCTION: CXCursor clang_getOverloadedDecl ( CXCursor cursor, uint index ) ; | |
FUNCTION: CXType clang_getIBOutletCollectionType ( CXCursor ) ; | |
ENUM: CXChildVisitResult | |
CXChildVisit_Break | |
CXChildVisit_Continue | |
CXChildVisit_Recurse ; | |
CALLBACK: CXChildVisitResult CXCursorVisitor ( CXCursor cursor, | |
CXCursor parent, | |
CXClientData client_data ) ; | |
FUNCTION: uint clang_visitChildren ( CXCursor parent, | |
CXCursorVisitor visitor, | |
CXClientData client_data ) ; | |
FUNCTION: CXString clang_getCursorUSR ( CXCursor ) ; | |
FUNCTION: CXString clang_constructUSR_ObjCClass ( c-string class_name ) ; | |
FUNCTION: CXString clang_constructUSR_ObjCCategory ( c-string class_name, | |
c-string category_name ) ; | |
FUNCTION: CXString clang_constructUSR_ObjCProtocol ( c-string protocol_name ) ; | |
FUNCTION: CXString clang_constructUSR_ObjCIvar ( c-string name, | |
CXString classUSR ) ; | |
FUNCTION: CXString clang_constructUSR_ObjCMethod ( c-string name, | |
uint isInstanceMethod, | |
CXString classUSR ) ; | |
FUNCTION: CXString clang_constructUSR_ObjCProperty ( c-string property, | |
CXString classUSR ) ; | |
FUNCTION: CXString clang_getCursorSpelling ( CXCursor ) ; | |
FUNCTION: CXString clang_getCursorDisplayName ( CXCursor ) ; | |
FUNCTION: CXCursor clang_getCursorReferenced ( CXCursor ) ; | |
FUNCTION: CXCursor clang_getCursorDefinition ( CXCursor ) ; | |
FUNCTION: uint clang_isCursorDefinition ( CXCursor ) ; | |
FUNCTION: CXCursor clang_getCanonicalCursor ( CXCursor ) ; | |
FUNCTION: uint clang_CXXMethod_isStatic ( CXCursor C ) ; | |
FUNCTION: uint clang_CXXMethod_isVirtual ( CXCursor C ) ; | |
FUNCTION: CXCursorKind clang_getTemplateCursorKind ( CXCursor C ) ; | |
FUNCTION: CXCursor clang_getSpecializedCursorTemplate ( CXCursor C ) ; | |
ENUM: CXTokenKind | |
CXToken_Punctuation | |
CXToken_Keyword | |
CXToken_Identifier | |
CXToken_Literal | |
CXToken_Comment ; | |
STRUCT: CXToken | |
{ int_data uint[4] } | |
{ ptr_data void* } ; | |
FUNCTION: CXTokenKind clang_getTokenKind ( CXToken ) ; | |
FUNCTION: CXString clang_getTokenSpelling ( CXTranslationUnit TU, | |
CXToken Token ) ; | |
FUNCTION: CXSourceLocation clang_getTokenLocation ( CXTranslationUnit TU, | |
CXToken Token ) ; | |
FUNCTION: CXSourceRange clang_getTokenExtent ( CXTranslationUnit TU, | |
CXToken Token ) ; | |
FUNCTION: void clang_tokenize ( CXTranslationUnit TU, | |
CXSourceRange Range, | |
CXToken** Tokens, | |
uint* NumTokens ) ; | |
FUNCTION: void clang_annotateTokens ( CXTranslationUnit TU, | |
CXToken* Tokens, | |
uint NumTokens, | |
CXCursor* Cursors ) ; | |
FUNCTION: void clang_disposeTokens ( CXTranslationUnit TU, | |
CXToken* Tokens, | |
uint NumTokens ) ; | |
FUNCTION: CXString clang_getCursorKindSpelling ( CXCursorKind Kind ) ; | |
FUNCTION: void clang_getDefinitionSpellingAndExtent ( CXCursor cursor, | |
char** startBuf, | |
char** endBuf, | |
uint* startLine, | |
uint* startColumn, | |
uint* endLine, | |
uint* endColumn ) ; | |
FUNCTION: void clang_enableStackTraces ( ) ; | |
CALLBACK: void executeOnThreadCallback ( void* ) ; | |
FUNCTION: void clang_executeOnThread ( executeOnThreadCallback* callback, | |
void* user_data, | |
uint stack_size ) ; | |
TYPEDEF: void* CXCompletionString | |
STRUCT: CXCompletionResult | |
{ CursorKind CXCursorKind } | |
{ CompletionString CXCompletionString } ; | |
ENUM: CXCompletionChunkKind | |
CXCompletionChunk_Optional | |
CXCompletionChunk_TypedText | |
CXCompletionChunk_Text | |
CXCompletionChunk_Placeholder | |
CXCompletionChunk_Informative | |
CXCompletionChunk_CurrentParameter | |
CXCompletionChunk_LeftParen | |
CXCompletionChunk_RightParen | |
CXCompletionChunk_LeftBracket | |
CXCompletionChunk_RightBracket | |
CXCompletionChunk_LeftBrace | |
CXCompletionChunk_RightBrace | |
CXCompletionChunk_LeftAngle | |
CXCompletionChunk_RightAngle | |
CXCompletionChunk_Comma | |
CXCompletionChunk_ResultType | |
CXCompletionChunk_Colon | |
CXCompletionChunk_SemiColon | |
CXCompletionChunk_Equal | |
CXCompletionChunk_HorizontalSpace | |
CXCompletionChunk_VerticalSpace ; | |
FUNCTION: CXCompletionChunkKind clang_getCompletionChunkKind ( CXCompletionString completion_string, | |
uint chunk_number ) ; | |
FUNCTION: CXString clang_getCompletionChunkText ( CXCompletionString completion_string, | |
uint chunk_number ) ; | |
FUNCTION: CXCompletionString clang_getCompletionChunkCompletionString ( CXCompletionString completion_string, | |
uint chunk_number ) ; | |
FUNCTION: uint clang_getNumCompletionChunks ( CXCompletionString completion_string ) ; | |
FUNCTION: uint clang_getCompletionPriority ( CXCompletionString completion_string ) ; | |
FUNCTION: CXAvailabilityKind clang_getCompletionAvailability ( CXCompletionString completion_string ) ; | |
STRUCT: CXCodeCompleteResults | |
{ Results CXCompletionResult* } | |
{ NumResults uint } ; | |
ENUM: CXCodeComplete_Flags | |
{ CXCodeComplete_IncludeMacros 1 } | |
{ CXCodeComplete_IncludeCodePatterns 2 } ; | |
FUNCTION: uint clang_defaultCodeCompleteOptions ( ) ; | |
FUNCTION: CXCodeCompleteResults* clang_codeCompleteAt ( CXTranslationUnit TU, | |
c-string complete_filename, | |
uint complete_line, | |
uint complete_column, | |
CXUnsavedFile* unsaved_files, | |
uint num_unsaved_files, | |
uint options ) ; | |
FUNCTION: void clang_sortCodeCompletionResults ( CXCompletionResult* Results, uint NumResults ) ; | |
FUNCTION: void clang_disposeCodeCompleteResults ( CXCodeCompleteResults* Results ) ; | |
FUNCTION: uint clang_codeCompleteGetNumDiagnostics ( CXCodeCompleteResults* Results ) ; | |
FUNCTION: CXDiagnostic clang_codeCompleteGetDiagnostic ( CXCodeCompleteResults* Results, | |
uint Index ) ; | |
FUNCTION: CXString clang_getClangVersion ( ) ; | |
FUNCTION: void clang_toggleCrashRecovery ( uint isEnabled ) ; | |
CALLBACK: void CXInclusionVisitor ( CXFile included_file, | |
CXSourceLocation* inclusion_stack, | |
uint include_len, | |
CXClientData client_data ) ; | |
FUNCTION: void clang_getInclusions ( CXTranslationUnit tu, | |
CXInclusionVisitor visitor, | |
CXClientData client_data ) ; | |
]] | |
FILE: [[llvm/types/types-tests.factor]] [[! Copyright (C) 2009 Matthew Willis. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: kernel llvm.types sequences tools.test ; | |
{ T{ integer f 32 } } [ " i32 " parse-type ] unit-test | |
{ float } [ " float " parse-type ] unit-test | |
{ T{ pointer f f x86_fp80 } } [ " x86_fp80 * " parse-type ] unit-test | |
{ T{ vector f f 4 T{ integer f 32 } } } [ " < 4 x i32 > " parse-type ] unit-test | |
{ T{ struct f f { float double } f } } [ TYPE: { float , double } ; ] unit-test | |
{ T{ array f f 0 float } } [ TYPE: [ 0 x float ] ; ] unit-test | |
{ label void metadata } | |
[ [ " label " " void " " metadata " ] [ parse-type ] each ] unit-test | |
{ T{ function f f float { float float } t } } | |
[ TYPE: float ( float , float , ... ) ; ] unit-test | |
{ T{ struct f f { float TYPE: i32 (i32)* ; } t } } | |
[ TYPE: < { float, i32 (i32)* } > ; ] unit-test | |
{ t } [ TYPE: i32 ; TYPE: i32 ; [ >tref ] same? ] unit-test | |
{ t } [ TYPE: i32 * ; TYPE: i32 * ; [ >tref ] same? ] unit-test | |
{ TYPE: i32 ; } [ TYPE: i32 ; >tref tref> ] unit-test | |
{ TYPE: float ; } [ TYPE: float ; >tref tref> ] unit-test | |
{ TYPE: double ; } [ TYPE: double ; >tref tref> ] unit-test | |
{ TYPE: x86_fp80 ; } [ TYPE: x86_fp80 ; >tref tref> ] unit-test | |
{ TYPE: fp128 ; } [ TYPE: fp128 ; >tref tref> ] unit-test | |
{ TYPE: ppc_fp128 ; } [ TYPE: ppc_fp128 ; >tref tref> ] unit-test | |
{ TYPE: opaque ; } [ TYPE: opaque ; >tref tref> ] unit-test | |
{ TYPE: label ; } [ TYPE: label ; >tref tref> ] unit-test | |
{ TYPE: void ; } [ TYPE: void ; >tref tref> ] unit-test | |
{ TYPE: i32* ; } [ TYPE: i32* ; >tref tref> ] unit-test | |
{ TYPE: < 2 x i32 > ; } [ TYPE: < 2 x i32 > ; >tref tref> ] unit-test | |
{ TYPE: [ 0 x i32 ] ; } [ TYPE: [ 0 x i32 ] ; >tref tref> ] unit-test | |
{ TYPE: { i32, i32 } ; } [ TYPE: { i32, i32 } ; >tref tref> ] unit-test | |
{ TYPE: < { i32, i32 } > ; } [ TYPE: < { i32, i32 } > ; >tref tref> ] unit-test | |
{ TYPE: i32 ( i32 ) ; } [ TYPE: i32 ( i32 ) ; >tref tref> ] unit-test | |
{ TYPE: \1* ; } [ TYPE: \1* ; >tref tref> ] unit-test | |
{ TYPE: { i32, \2* } ; } [ TYPE: { i32, \2* } ; >tref tref> ] unit-test | |
]] | |
FILE: [[llvm/types/types.factor]] [=[! Copyright (C) 2009 Matthew Willis. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: accessors alien.c-types alien.data arrays combinators | |
kernel llvm.core locals math.parser math multiline namespaces | |
parser peg.ebnf sequences sequences.deep specialized-arrays | |
strings vocabs words ; | |
SPECIALIZED-ARRAY: void* | |
IN: llvm.types | |
! Type resolution strategy: | |
! pass 1: | |
! create the type with uprefs mapped to opaque types | |
! cache typerefs in enclosing types for pass 2 | |
! if our type is concrete, then we are done | |
! | |
! pass 2: | |
! wrap our abstract type in a type handle | |
! create a second type, using the cached enclosing type info | |
! resolve the first type to the second | |
! | |
GENERIC: (>tref) ( type -- LLVMTypeRef ) | |
GENERIC: ((tref>)) ( LLVMTypeRef type -- type ) | |
GENERIC: c-type ( type -- str ) | |
! default implementation for simple types | |
M: object ((tref>)) nip ; | |
: unsupported-type ( -- ) | |
"cannot generate c-type: unsupported llvm type" throw ; | |
M: object c-type unsupported-type ; | |
TUPLE: integer size ; | |
C: <integer> integer | |
M: integer (>tref) size>> LLVMIntType ; | |
M: integer ((tref>)) swap LLVMGetIntTypeWidth >>size ; | |
M: integer c-type size>> { | |
{ 64 [ "longlong" ] } | |
{ 32 [ "int" ] } | |
{ 16 [ "short" ] } | |
{ 8 [ "char" ] } | |
[ unsupported-type ] | |
} case ; | |
SINGLETONS: float double x86_fp80 fp128 ppc_fp128 ; | |
M: float (>tref) drop LLVMFloatType ; | |
M: double (>tref) drop LLVMDoubleType ; | |
M: double c-type drop "double" ; | |
M: x86_fp80 (>tref) drop LLVMX86FP80Type ; | |
M: fp128 (>tref) drop LLVMFP128Type ; | |
M: ppc_fp128 (>tref) drop LLVMPPCFP128Type ; | |
SINGLETONS: opaque label void metadata ; | |
M: opaque (>tref) drop LLVMOpaqueType ; | |
M: label (>tref) drop LLVMLabelType ; | |
M: void (>tref) drop LLVMVoidType ; | |
M: void c-type drop "void" ; | |
M: metadata (>tref) drop | |
"metadata types unsupported by llvm c bindings" throw ; | |
! enclosing types cache their llvm refs during | |
! the first pass, used in the second pass to | |
! resolve uprefs | |
TUPLE: enclosing cached ; | |
GENERIC: clean ( type -- ) | |
GENERIC: clean* ( type -- ) | |
M: object clean drop ; | |
M: enclosing clean f >>cached clean* ; | |
! builds the stack of types that uprefs need to refer to | |
SYMBOL: types | |
:: push-type ( type quot: ( type -- LLVMTypeRef ) -- LLVMTypeRef ) | |
type types get push | |
type quot call( type -- LLVMTypeRef ) | |
types get pop over >>cached drop ; | |
DEFER: <up-ref> | |
:: push-ref ( ref quot: ( LLVMTypeRef -- type ) -- type ) | |
ref types get index | |
[ types get length swap - <up-ref> ] [ | |
ref types get push | |
ref quot call( LLVMTypeRef -- type ) | |
types get pop drop | |
] if* ; | |
GENERIC: (>tref)* ( type -- LLVMTypeRef ) | |
M: enclosing (>tref) [ (>tref)* ] push-type ; | |
DEFER: type-kind | |
GENERIC: (tref>)* ( LLVMTypeRef type -- type ) | |
M: enclosing ((tref>)) [ (tref>)* ] curry push-ref ; | |
: (tref>) ( LLVMTypeRef -- type ) dup type-kind ((tref>)) ; | |
TUPLE: pointer < enclosing type ; | |
: <pointer> ( t -- o ) pointer new swap >>type ; | |
M: pointer (>tref)* type>> (>tref) 0 LLVMPointerType ; | |
M: pointer clean* type>> clean ; | |
M: pointer (tref>)* swap LLVMGetElementType (tref>) >>type ; | |
M: pointer c-type type>> 8 <integer> = "c-string" "void*" ? ; | |
TUPLE: vector < enclosing size type ; | |
: <vector> ( s t -- o ) | |
vector new | |
swap >>type swap >>size ; | |
M: vector (>tref)* [ type>> (>tref) ] [ size>> ] bi LLVMVectorType ; | |
M: vector clean* type>> clean ; | |
M: vector (tref>)* | |
over LLVMGetElementType (tref>) >>type | |
swap LLVMGetVectorSize >>size ; | |
TUPLE: struct < enclosing types packed? ; | |
: <struct> ( ts p? -- o ) | |
struct new | |
swap >>packed? swap >>types ; | |
M: struct (>tref)* | |
[ types>> [ (>tref) ] map void* >c-array ] | |
[ types>> length ] | |
[ packed?>> 1 0 ? ] tri LLVMStructType ; | |
M: struct clean* types>> [ clean ] each ; | |
M: struct (tref>)* | |
over LLVMIsPackedStruct 0 = not >>packed? | |
swap dup LLVMCountStructElementTypes void* <c-array> | |
[ LLVMGetStructElementTypes ] keep >array | |
[ (tref>) ] map >>types ; | |
TUPLE: array < enclosing size type ; | |
: <array> ( s t -- o ) | |
array new | |
swap >>type swap >>size ; | |
M: array (>tref)* [ type>> (>tref) ] [ size>> ] bi LLVMArrayType ; | |
M: array clean* type>> clean ; | |
M: array (tref>)* | |
over LLVMGetElementType (tref>) >>type | |
swap LLVMGetArrayLength >>size ; | |
SYMBOL: ... | |
TUPLE: function < enclosing return params vararg? ; | |
: <function> ( ret params var? -- o ) | |
function new | |
swap >>vararg? swap >>params swap >>return ; | |
M: function (>tref)* { | |
[ return>> (>tref) ] | |
[ params>> [ (>tref) ] map void* >c-array ] | |
[ params>> length ] | |
[ vararg?>> 1 0 ? ] | |
} cleave LLVMFunctionType ; | |
M: function clean* [ return>> clean ] [ params>> [ clean ] each ] bi ; | |
M: function (tref>)* | |
over LLVMIsFunctionVarArg 0 = not >>vararg? | |
over LLVMGetReturnType (tref>) >>return | |
swap dup LLVMCountParamTypes void* <c-array> | |
[ LLVMGetParamTypes ] keep >array | |
[ (tref>) ] map >>params ; | |
: type-kind ( LLVMTypeRef -- class ) | |
LLVMGetTypeKind { | |
{ LLVMVoidTypeKind [ void ] } | |
{ LLVMFloatTypeKind [ float ] } | |
{ LLVMDoubleTypeKind [ double ] } | |
{ LLVMX86_FP80TypeKind [ x86_fp80 ] } | |
{ LLVMFP128TypeKind [ fp128 ] } | |
{ LLVMPPC_FP128TypeKind [ ppc_fp128 ] } | |
{ LLVMLabelTypeKind [ label ] } | |
{ LLVMIntegerTypeKind [ integer new ] } | |
{ LLVMFunctionTypeKind [ function new ] } | |
{ LLVMStructTypeKind [ struct new ] } | |
{ LLVMArrayTypeKind [ array new ] } | |
{ LLVMPointerTypeKind [ pointer new ] } | |
{ LLVMOpaqueTypeKind [ opaque ] } | |
{ LLVMVectorTypeKind [ vector new ] } | |
} case ; | |
TUPLE: up-ref height ; | |
C: <up-ref> up-ref | |
M: up-ref (>tref) | |
types get length swap height>> - types get nth | |
cached>> [ LLVMOpaqueType ] unless* ; | |
: resolve-types ( typeref typeref -- typeref ) | |
over LLVMCreateTypeHandle [ LLVMRefineType ] dip | |
[ LLVMResolveTypeHandle ] keep LLVMDisposeTypeHandle ; | |
: >tref-caching ( type -- LLVMTypeRef ) | |
V{ } clone types [ (>tref) ] with-variable ; | |
: >tref ( type -- LLVMTypeRef ) | |
[ >tref-caching ] [ >tref-caching ] [ clean ] tri | |
2dup = [ drop ] [ resolve-types ] if ; | |
: tref> ( LLVMTypeRef -- type ) | |
V{ } clone types [ (tref>) ] with-variable ; | |
: t. ( type -- ) | |
>tref | |
"type-info" LLVMModuleCreateWithName | |
[ "t" rot LLVMAddTypeName drop ] | |
[ LLVMDumpModule ] | |
[ LLVMDisposeModule ] tri ; | |
EBNF: parse-type | |
WhiteSpace = " "* | |
Zero = "0" => [[ drop 0 ]] | |
LeadingDigit = [1-9] | |
DecimalDigit = [0-9] | |
Number = LeadingDigit:d (DecimalDigit)*:ds => [[ ds d prefix string>number ]] | |
WhiteNumberSpace = WhiteSpace Number:n WhiteSpace => [[ n ]] | |
WhiteZeroSpace = WhiteSpace (Zero | Number):n WhiteSpace => [[ n ]] | |
Integer = "i" Number:n => [[ n <integer> ]] | |
FloatingPoint = ( "float" | "double" | "x86_fp80" | "fp128" | "ppc_fp128" ) => [[ "llvm.types" vocab lookup-word ]] | |
LabelVoidMetadata = ( "label" | "void" | "metadata" | "opaque" ) => [[ "llvm.types" vocab lookup-word ]] | |
Primitive = LabelVoidMetadata | FloatingPoint | |
Pointer = T:t WhiteSpace "*" => [[ t <pointer> ]] | |
Vector = "<" WhiteNumberSpace:n "x" Type:t ">" => [[ n t <vector> ]] | |
StructureTypesList = "," Type:t => [[ t ]] | |
Structure = "{" Type:t (StructureTypesList)*:ts "}" => [[ ts t prefix >array f <struct> ]] | |
Array = "[" WhiteZeroSpace:n "x" Type:t "]" => [[ n t <array> ]] | |
NoFunctionParams = "(" WhiteSpace ")" => [[ drop { } ]] | |
VarArgs = WhiteSpace "..." WhiteSpace => [[ drop ... ]] | |
ParamListContinued = "," (Type | VarArgs):t => [[ t ]] | |
ParamList = "(" Type:t (ParamListContinued*):ts ")" => [[ ts t prefix ]] | |
Function = T:t WhiteSpace ( ParamList | NoFunctionParams ):ts => [[ ... ts member? dup [ ... ts remove! drop ] when t ts >array rot <function> ]] | |
PackedStructure = "<" WhiteSpace "{" Type:ty (StructureTypesList)*:ts "}" WhiteSpace ">" => [[ ts ty prefix >array t <struct> ]] | |
UpReference = "\\" Number:n => [[ n <up-ref> ]] | |
Name = '%' ([a-zA-Z][a-zA-Z0-9]*):id => [[ id flatten >string ]] | |
T = Pointer | Function | Primitive | Integer | Vector | Structure | PackedStructure | Array | UpReference | Name | |
Type = WhiteSpace T:t WhiteSpace => [[ t ]] | |
Program = Type | |
;EBNF | |
SYNTAX: TYPE: ";" parse-multiline-string parse-type suffix! ; | |
]=] | |
FILE: [[llvm/types/tags.txt]] [[not tested | |
]] | |
FILE: [[llvm/core/core.factor]] [[! Copyright (C) 2009 Matthew Willis. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: alien alien.c-types alien.libraries alien.syntax | |
combinators kernel sequences system ; | |
IN: llvm.core | |
<< | |
: add-llvm-library ( name -- ) | |
dup { | |
{ [ os macosx? ] [ "lib" ".dylib" surround ] } | |
{ [ os unix? ] [ "lib" ".so" surround ] } | |
{ [ os windows? ] [ ".dll" append ] } | |
} cond cdecl add-library ; | |
{ "LLVMSystem" "LLVMSupport" "LLVMCore" "LLVMBitReader" } | |
[ add-llvm-library ] each | |
>> | |
! llvm-c/Core.h | |
LIBRARY: LLVMCore | |
TYPEDEF: uint unsigned | |
TYPEDEF: unsigned enum | |
ENUM: LLVMAttribute | |
{ LLVMZExtAttribute 0b1 } | |
{ LLVMSExtAttribute 0b10 } | |
{ LLVMNoReturnAttribute 0b100 } | |
{ LLVMInRegAttribute 0b1000 } | |
{ LLVMStructRetAttribute 0b10000 } | |
{ LLVMNoUnwindAttribute 0b100000 } | |
{ LLVMNoAliasAttribute 0b1000000 } | |
{ LLVMByValAttribute 0b10000000 } | |
{ LLVMNestAttribute 0b100000000 } | |
{ LLVMReadNoneAttribute 0b1000000000 } | |
{ LLVMReadOnlyAttribute 0b10000000000 } ; | |
ENUM: LLVMTypeKind | |
LLVMVoidTypeKind | |
LLVMFloatTypeKind | |
LLVMDoubleTypeKind | |
LLVMX86_FP80TypeKind | |
LLVMFP128TypeKind | |
LLVMPPC_FP128TypeKind | |
LLVMLabelTypeKind | |
LLVMMetadataTypeKind | |
LLVMIntegerTypeKind | |
LLVMFunctionTypeKind | |
LLVMStructTypeKind | |
LLVMArrayTypeKind | |
LLVMPointerTypeKind | |
LLVMOpaqueTypeKind | |
LLVMVectorTypeKind ; | |
ENUM: LLVMLinkage | |
LLVMExternalLinkage | |
LLVMLinkOnceLinkage | |
LLVMWeakLinkage | |
LLVMAppendingLinkage | |
LLVMInternalLinkage | |
LLVMDLLImportLinkage | |
LLVMDLLExportLinkage | |
LLVMExternalWeakLinkage | |
LLVMGhostLinkage ; | |
ENUM: LLVMVisibility | |
LLVMDefaultVisibility | |
LLVMHiddenVisibility | |
LLVMProtectedVisibility ; | |
ENUM: LLVMCallConv | |
{ LLVMCCallConv 0 } | |
{ LLVMFastCallConv 8 } | |
{ LLVMColdCallConv 9 } | |
{ LLVMX86StdcallCallConv 64 } | |
{ LLVMX86FastcallCallConv 65 } ; | |
ENUM: LLVMIntPredicate | |
{ LLVMIntEQ 32 } | |
{ LLVMIntNE 33 } | |
{ LLVMIntUGT 34 } | |
{ LLVMIntUGE 35 } | |
{ LLVMIntULT 36 } | |
{ LLVMIntULE 37 } | |
{ LLVMIntSGT 38 } | |
{ LLVMIntSGE 39 } | |
{ LLVMIntSLT 40 } | |
{ LLVMIntSLE 41 } ; | |
ENUM: LLVMRealPredicate | |
LLVMRealPredicateFalse | |
LLVMRealOEQ | |
LLVMRealOGT | |
LLVMRealOGE | |
LLVMRealOLT | |
LLVMRealOLE | |
LLVMRealONE | |
LLVMRealORD | |
LLVMRealUNO | |
LLVMRealUEQ | |
LLVMRealUGT | |
LLVMRealUGE | |
LLVMRealULT | |
LLVMRealULE | |
LLVMRealUNE | |
LLVMRealPredicateTrue ; | |
! Opaque Types | |
TYPEDEF: void* LLVMModuleRef | |
TYPEDEF: void* LLVMPassManagerRef | |
TYPEDEF: void* LLVMModuleProviderRef | |
TYPEDEF: void* LLVMTypeRef | |
TYPEDEF: void* LLVMTypeHandleRef | |
TYPEDEF: void* LLVMValueRef | |
TYPEDEF: void* LLVMBasicBlockRef | |
TYPEDEF: void* LLVMBuilderRef | |
TYPEDEF: void* LLVMMemoryBufferRef | |
! Functions | |
FUNCTION: void LLVMDisposeMessage ( c-string Message ) ; | |
FUNCTION: LLVMModuleRef LLVMModuleCreateWithName ( c-string ModuleID ) ; | |
FUNCTION: int LLVMAddTypeName ( LLVMModuleRef M, c-string Name, LLVMTypeRef Ty ) ; | |
FUNCTION: void LLVMDisposeModule ( LLVMModuleRef M ) ; | |
FUNCTION: void LLVMDumpModule ( LLVMModuleRef M ) ; | |
FUNCTION: LLVMModuleProviderRef | |
LLVMCreateModuleProviderForExistingModule ( LLVMModuleRef M ) ; | |
FUNCTION: void LLVMDisposeModuleProvider ( LLVMModuleProviderRef MP ) ; | |
! Types | |
! LLVM types conform to the following hierarchy: | |
! | |
! types: | |
! integer type | |
! real type | |
! function type | |
! sequence types: | |
! array type | |
! pointer type | |
! vector type | |
! void type | |
! label type | |
! opaque type | |
! See llvm::LLVMTypeKind::getTypeID. | |
FUNCTION: LLVMTypeKind LLVMGetTypeKind ( LLVMTypeRef Ty ) ; | |
! Operations on integer types | |
FUNCTION: LLVMTypeRef LLVMInt1Type ( ) ; | |
FUNCTION: LLVMTypeRef LLVMInt8Type ( ) ; | |
FUNCTION: LLVMTypeRef LLVMInt16Type ( ) ; | |
FUNCTION: LLVMTypeRef LLVMInt32Type ( ) ; | |
FUNCTION: LLVMTypeRef LLVMInt64Type ( ) ; | |
FUNCTION: LLVMTypeRef LLVMIntType ( unsigned NumBits ) ; | |
FUNCTION: unsigned LLVMGetIntTypeWidth ( LLVMTypeRef IntegerTy ) ; | |
! Operations on real types | |
FUNCTION: LLVMTypeRef LLVMFloatType ( ) ; | |
FUNCTION: LLVMTypeRef LLVMDoubleType ( ) ; | |
FUNCTION: LLVMTypeRef LLVMX86FP80Type ( ) ; | |
FUNCTION: LLVMTypeRef LLVMFP128Type ( ) ; | |
FUNCTION: LLVMTypeRef LLVMPPCFP128Type ( ) ; | |
! Operations on function types | |
FUNCTION: LLVMTypeRef | |
LLVMFunctionType ( LLVMTypeRef ReturnType, LLVMTypeRef* ParamTypes, unsigned ParamCount, int IsVarArg ) ; | |
FUNCTION: int LLVMIsFunctionVarArg ( LLVMTypeRef FunctionTy ) ; | |
FUNCTION: LLVMTypeRef LLVMGetReturnType ( LLVMTypeRef FunctionTy ) ; | |
FUNCTION: unsigned LLVMCountParamTypes ( LLVMTypeRef FunctionTy ) ; | |
FUNCTION: void LLVMGetParamTypes ( LLVMTypeRef FunctionTy, LLVMTypeRef* Dest ) ; | |
! Operations on struct types | |
FUNCTION: LLVMTypeRef | |
LLVMStructType ( LLVMTypeRef* ElementTypes, unsigned ElementCount, int Packed ) ; | |
FUNCTION: unsigned LLVMCountStructElementTypes ( LLVMTypeRef StructTy ) ; | |
FUNCTION: void LLVMGetStructElementTypes ( LLVMTypeRef StructTy, LLVMTypeRef* Dest ) ; | |
FUNCTION: int LLVMIsPackedStruct ( LLVMTypeRef StructTy ) ; | |
! Operations on array, pointer, and vector types (sequence types) | |
FUNCTION: LLVMTypeRef LLVMArrayType ( LLVMTypeRef ElementType, unsigned ElementCount ) ; | |
FUNCTION: LLVMTypeRef LLVMPointerType ( LLVMTypeRef ElementType, unsigned AddressSpace ) ; | |
FUNCTION: LLVMTypeRef LLVMVectorType ( LLVMTypeRef ElementType, unsigned ElementCount ) ; | |
FUNCTION: LLVMTypeRef LLVMGetElementType ( LLVMTypeRef Ty ) ; | |
FUNCTION: unsigned LLVMGetArrayLength ( LLVMTypeRef ArrayTy ) ; | |
FUNCTION: unsigned LLVMGetPointerAddressSpace ( LLVMTypeRef PointerTy ) ; | |
FUNCTION: unsigned LLVMGetVectorSize ( LLVMTypeRef VectorTy ) ; | |
! Operations on other types | |
FUNCTION: LLVMTypeRef LLVMVoidType ( ) ; | |
FUNCTION: LLVMTypeRef LLVMLabelType ( ) ; | |
FUNCTION: LLVMTypeRef LLVMOpaqueType ( ) ; | |
! Operations on type handles | |
FUNCTION: LLVMTypeHandleRef LLVMCreateTypeHandle ( LLVMTypeRef PotentiallyAbstractTy ) ; | |
FUNCTION: void LLVMRefineType ( LLVMTypeRef AbstractTy, LLVMTypeRef ConcreteTy ) ; | |
FUNCTION: LLVMTypeRef LLVMResolveTypeHandle ( LLVMTypeHandleRef TypeHandle ) ; | |
FUNCTION: void LLVMDisposeTypeHandle ( LLVMTypeHandleRef TypeHandle ) ; | |
! Types end | |
FUNCTION: unsigned LLVMCountParams ( LLVMValueRef Fn ) ; | |
FUNCTION: void LLVMGetParams ( LLVMValueRef Fn, LLVMValueRef* Params ) ; | |
FUNCTION: LLVMValueRef | |
LLVMAddFunction ( LLVMModuleRef M, c-string Name, LLVMTypeRef FunctionTy ) ; | |
FUNCTION: LLVMValueRef LLVMGetFirstFunction ( LLVMModuleRef M ) ; | |
FUNCTION: LLVMValueRef LLVMGetNextFunction ( LLVMValueRef Fn ) ; | |
FUNCTION: unsigned LLVMGetFunctionCallConv ( LLVMValueRef Fn ) ; | |
FUNCTION: void LLVMSetFunctionCallConv ( LLVMValueRef Fn, unsigned CC ) ; | |
FUNCTION: LLVMBasicBlockRef | |
LLVMAppendBasicBlock ( LLVMValueRef Fn, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMGetBasicBlockParent ( LLVMBasicBlockRef BB ) ; | |
! Values | |
FUNCTION: LLVMTypeRef LLVMTypeOf ( LLVMValueRef Val ) ; | |
FUNCTION: c-string LLVMGetValueName ( LLVMValueRef Val ) ; | |
FUNCTION: void LLVMSetValueName ( LLVMValueRef Val, c-string Name ) ; | |
FUNCTION: void LLVMDumpValue ( LLVMValueRef Val ) ; | |
! Instruction Builders | |
FUNCTION: LLVMBuilderRef LLVMCreateBuilder ( ) ; | |
FUNCTION: void LLVMPositionBuilder | |
( LLVMBuilderRef Builder, LLVMBasicBlockRef Block, LLVMValueRef Instr ) ; | |
FUNCTION: void LLVMPositionBuilderBefore | |
( LLVMBuilderRef Builder, LLVMValueRef Instr ) ; | |
FUNCTION: void LLVMPositionBuilderAtEnd | |
( LLVMBuilderRef Builder, LLVMBasicBlockRef Block ) ; | |
FUNCTION: LLVMBasicBlockRef LLVMGetInsertBlock | |
( LLVMBuilderRef Builder ) ; | |
FUNCTION: void LLVMClearInsertionPosition | |
( LLVMBuilderRef Builder ) ; | |
FUNCTION: void LLVMInsertIntoBuilder | |
( LLVMBuilderRef Builder, LLVMValueRef Instr ) ; | |
FUNCTION: void LLVMDisposeBuilder | |
( LLVMBuilderRef Builder ) ; | |
! IB Terminators | |
FUNCTION: LLVMValueRef LLVMBuildRetVoid | |
( LLVMBuilderRef Builder ) ; | |
FUNCTION: LLVMValueRef LLVMBuildRet | |
( LLVMBuilderRef Builder, LLVMValueRef V ) ; | |
FUNCTION: LLVMValueRef LLVMBuildBr | |
( LLVMBuilderRef Builder, LLVMBasicBlockRef Dest ) ; | |
FUNCTION: LLVMValueRef LLVMBuildCondBr | |
( LLVMBuilderRef Builder, LLVMValueRef If, LLVMBasicBlockRef Then, LLVMBasicBlockRef Else ) ; | |
FUNCTION: LLVMValueRef LLVMBuildSwitch | |
( LLVMBuilderRef Builder, LLVMValueRef V, LLVMBasicBlockRef Else, unsigned NumCases ) ; | |
FUNCTION: LLVMValueRef LLVMBuildInvoke | |
( LLVMBuilderRef Builder, LLVMValueRef Fn, LLVMValueRef* Args, unsigned NumArgs, | |
LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildUnwind | |
( LLVMBuilderRef Builder ) ; | |
FUNCTION: LLVMValueRef LLVMBuildUnreachable | |
( LLVMBuilderRef Builder ) ; | |
! IB Add Case to Switch | |
FUNCTION: void LLVMAddCase | |
( LLVMValueRef Switch, LLVMValueRef OnVal, LLVMBasicBlockRef Dest ) ; | |
! IB Arithmetic | |
FUNCTION: LLVMValueRef LLVMBuildAdd | |
( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildSub | |
( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildMul | |
( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildUDiv | |
( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildSDiv | |
( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildFDiv | |
( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildURem | |
( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildSRem | |
( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildFRem | |
( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildShl | |
( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildLShr | |
( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildAShr | |
( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildAnd | |
( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildOr | |
( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildXor | |
( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildNeg | |
( LLVMBuilderRef Builder, LLVMValueRef V, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildNot | |
( LLVMBuilderRef Builder, LLVMValueRef V, c-string Name ) ; | |
! IB Memory | |
FUNCTION: LLVMValueRef LLVMBuildMalloc | |
( LLVMBuilderRef Builder, LLVMTypeRef Ty, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildArrayMalloc | |
( LLVMBuilderRef Builder, LLVMTypeRef Ty, LLVMValueRef Val, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildAlloca | |
( LLVMBuilderRef Builder, LLVMTypeRef Ty, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildArrayAlloca | |
( LLVMBuilderRef Builder, LLVMTypeRef Ty, LLVMValueRef Val, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildFree | |
( LLVMBuilderRef Builder, LLVMValueRef PointerVal ) ; | |
FUNCTION: LLVMValueRef LLVMBuildLoad | |
( LLVMBuilderRef Builder, LLVMValueRef PointerVal, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildStore | |
( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMValueRef Ptr ) ; | |
FUNCTION: LLVMValueRef LLVMBuildGEP | |
( LLVMBuilderRef B, LLVMValueRef Pointer, LLVMValueRef* Indices, | |
unsigned NumIndices, c-string Name ) ; | |
! IB Casts | |
FUNCTION: LLVMValueRef LLVMBuildTrunc | |
( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildZExt | |
( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildSExt | |
( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildFPToUI | |
( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildFPToSI | |
( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildUIToFP | |
( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildSIToFP | |
( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildFPTrunc | |
( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildFPExt | |
( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildPtrToInt | |
( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildIntToPtr | |
( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildBitCast | |
( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, c-string Name ) ; | |
! IB Comparisons | |
FUNCTION: LLVMValueRef LLVMBuildICmp | |
( LLVMBuilderRef Builder, LLVMIntPredicate Op, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildFCmp | |
( LLVMBuilderRef Builder, LLVMRealPredicate Op, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ; | |
! IB Misc Instructions | |
FUNCTION: LLVMValueRef LLVMBuildPhi | |
( LLVMBuilderRef Builder, LLVMTypeRef Ty, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildCall | |
( LLVMBuilderRef Builder, LLVMValueRef Fn, LLVMValueRef* Args, unsigned NumArgs, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildSelect | |
( LLVMBuilderRef Builder, LLVMValueRef If, LLVMValueRef Then, LLVMValueRef Else, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildVAArg | |
( LLVMBuilderRef Builder, LLVMValueRef List, LLVMTypeRef Ty, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildExtractElement | |
( LLVMBuilderRef Builder, LLVMValueRef VecVal, LLVMValueRef Index, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildInsertElement | |
( LLVMBuilderRef Builder, LLVMValueRef VecVal, LLVMValueRef EltVal, LLVMValueRef Index, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildShuffleVector | |
( LLVMBuilderRef Builder, LLVMValueRef V1, LLVMValueRef V2, LLVMValueRef Mask, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildExtractValue | |
( LLVMBuilderRef Builder, LLVMValueRef AggVal, unsigned Index, c-string Name ) ; | |
FUNCTION: LLVMValueRef LLVMBuildInsertValue | |
( LLVMBuilderRef Builder, LLVMValueRef AggVal, LLVMValueRef EltVal, unsigned Index, c-string Name ) ; | |
! Memory Buffers/Bit Reader | |
FUNCTION: int LLVMCreateMemoryBufferWithContentsOfFile | |
( c-string Path, LLVMMemoryBufferRef* OutMemBuf, c-string* OutMessage ) ; | |
FUNCTION: void LLVMDisposeMemoryBuffer ( LLVMMemoryBufferRef MemBuf ) ; | |
LIBRARY: LLVMBitReader | |
FUNCTION: int LLVMParseBitcode | |
( LLVMMemoryBufferRef MemBuf, LLVMModuleRef* OutModule, c-string* OutMessage ) ; | |
FUNCTION: int LLVMGetBitcodeModuleProvider | |
( LLVMMemoryBufferRef MemBuf, LLVMModuleProviderRef* OutMP, c-string* OutMessage ) ; | |
]] | |
FILE: [[llvm/core/tags.txt]] [[not tested | |
]] | |
FILE: [[llvm/invoker/invoker-tests.factor]] [[! Copyright (C) 2009 Matthew Willis. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: alien.llvm io.pathnames llvm.invoker llvm.reader tools.test ; | |
{ 3 } [ | |
<< "resource:extra/llvm/reader/add.bc" install-bc >> 1 2 add | |
] unit-test | |
]] | |
FILE: [[llvm/invoker/invoker.factor]] [[! Copyright (C) 2009 Matthew Willis. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: accessors alien alien.data arrays assocs compiler.units | |
effects io.backend io.pathnames kernel llvm.core llvm.jit | |
llvm.reader llvm.types make namespaces sequences | |
specialized-arrays vocabs words ; | |
QUALIFIED-WITH: alien.c-types c | |
SPECIALIZED-ARRAY: c:void* | |
IN: llvm.invoker | |
! get function name, ret type, param types and names | |
! load module | |
! iterate through functions in a module | |
TUPLE: function name alien return params ; | |
: params ( llvm-function -- param-list ) | |
dup LLVMCountParams c:void* <c-array> | |
[ LLVMGetParams ] keep >array | |
[ [ LLVMGetValueName ] [ LLVMTypeOf tref> ] bi 2array ] map ; | |
: <function> ( LLVMValueRef -- function ) | |
function new | |
over LLVMGetValueName >>name | |
over LLVMTypeOf tref> type>> return>> >>return | |
swap params >>params ; | |
: (functions) ( llvm-function -- ) | |
[ dup , LLVMGetNextFunction (functions) ] when* ; | |
: functions ( llvm-module -- functions ) | |
LLVMGetFirstFunction [ (functions) ] { } make [ <function> ] map ; | |
: function-effect ( function -- effect ) | |
[ params>> keys ] [ return>> void? 0 1 ? ] bi <effect> ; | |
: install-function ( function -- ) | |
dup name>> "alien.llvm" create-vocab drop | |
"alien.llvm" create-word swap | |
[ | |
dup name>> function-pointer , | |
dup return>> c:lookup-c-type , | |
dup params>> [ second c:lookup-c-type ] map , | |
cdecl , \ alien-indirect , | |
] [ ] make swap function-effect [ define-declared ] with-compilation-unit ; | |
: install-module ( name -- ) | |
current-jit mps>> at [ | |
module>> functions [ install-function ] each | |
] [ "no such module" throw ] if* ; | |
: install-bc ( path -- ) | |
[ normalize-path ] [ file-name ] bi | |
[ load-into-jit ] keep install-module ; | |
<< "alien.llvm" create-vocab drop >> | |
]] | |
FILE: [[llvm/invoker/tags.txt]] [[not tested | |
]] | |
FILE: [[llvm/jit/jit.factor]] [[! Copyright (C) 2009 Matthew Willis. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: accessors alien.c-types alien.data alien.syntax assocs | |
destructors kernel llvm.core llvm.engine llvm.wrappers | |
namespaces ; | |
IN: llvm.jit | |
TUPLE: jit ee mps ; | |
: empty-engine ( -- engine ) | |
"initial-module" <module> <provider> <engine> ; | |
: <jit> ( -- jit ) | |
jit new empty-engine >>ee H{ } clone >>mps ; | |
: current-jit ( -- jit ) | |
\ current-jit global [ drop <jit> ] cache ; | |
: (remove-functions) ( function -- ) | |
current-jit ee>> value>> over LLVMFreeMachineCodeForFunction | |
LLVMGetNextFunction dup ALIEN: 0 = [ drop ] [ (remove-functions) ] if ; | |
: remove-functions ( module -- ) | |
! free machine code for each function in module | |
LLVMGetFirstFunction dup ALIEN: 0 = [ drop ] [ (remove-functions) ] if ; | |
: remove-provider ( provider -- ) | |
current-jit ee>> value>> swap value>> f void* <ref> f void* <ref> | |
[ LLVMRemoveModuleProvider drop ] 2keep void* deref [ llvm-throw ] when* | |
void* deref module new swap >>value | |
[ value>> remove-functions ] with-disposal ; | |
: remove-module ( name -- ) | |
dup current-jit mps>> at [ | |
remove-provider | |
current-jit mps>> delete-at | |
] [ drop ] if* ; | |
: add-module ( module name -- ) | |
[ <provider> ] dip [ remove-module ] keep | |
current-jit ee>> value>> pick | |
[ [ value>> LLVMAddModuleProvider ] [ t >>disposed drop ] bi ] with-disposal | |
current-jit mps>> set-at ; | |
: function-pointer ( name -- alien ) | |
current-jit ee>> value>> dup | |
rot f void* <ref> [ LLVMFindFunction drop ] keep | |
void* deref LLVMGetPointerToGlobal ; | |
]] | |
FILE: [[llvm/jit/tags.txt]] [[not tested | |
]] | |
FILE: [[llvm/jit/jit-tests.factor]] [[! Copyright (C) 2009 Matthew Willis. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: destructors llvm.jit llvm.wrappers tools.test ; | |
{ } [ "test" <module> "test" add-module "test" remove-module ] unit-test | |
]] | |
FILE: [[llvm/authors.txt]] [[Matthew Willis | |
]] | |
FILE: [[llvm/engine/engine.factor]] [[! Copyright (C) 2009 Matthew Willis. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: alien alien.c-types alien.libraries alien.syntax kernel | |
llvm.core sequences ; | |
IN: llvm.engine | |
<< | |
{ | |
"LLVMExecutionEngine" "LLVMTarget" "LLVMAnalysis" "LLVMipa" | |
"LLVMTransformUtils" "LLVMScalarOpts" "LLVMCodeGen" | |
"LLVMAsmPrinter" "LLVMSelectionDAG" "LLVMX86CodeGen" | |
"LLVMJIT" "LLVMInterpreter" | |
} [ add-llvm-library ] each | |
>> | |
! llvm-c/ExecutionEngine.h | |
LIBRARY: LLVMExecutionEngine | |
TYPEDEF: void* LLVMGenericValueRef | |
TYPEDEF: void* LLVMExecutionEngineRef | |
FUNCTION: LLVMGenericValueRef LLVMCreateGenericValueOfInt | |
( LLVMTypeRef Ty, ulonglong N, int IsSigned ) ; | |
FUNCTION: ulonglong LLVMGenericValueToInt | |
( LLVMGenericValueRef GenVal, int IsSigned ) ; | |
FUNCTION: int LLVMCreateExecutionEngine | |
( LLVMExecutionEngineRef *OutEE, LLVMModuleProviderRef MP, c-string* OutError ) ; | |
FUNCTION: int LLVMCreateJITCompiler | |
( LLVMExecutionEngineRef* OutJIT, LLVMModuleProviderRef MP, unsigned OptLevel, c-string* OutError ) ; | |
FUNCTION: void LLVMDisposeExecutionEngine ( LLVMExecutionEngineRef EE ) ; | |
FUNCTION: void LLVMFreeMachineCodeForFunction ( LLVMExecutionEngineRef EE, LLVMValueRef F ) ; | |
FUNCTION: void LLVMAddModuleProvider ( LLVMExecutionEngineRef EE, LLVMModuleProviderRef MP ) ; | |
FUNCTION: int LLVMRemoveModuleProvider | |
( LLVMExecutionEngineRef EE, LLVMModuleProviderRef MP, LLVMModuleRef* OutMod, c-string* OutError ) ; | |
FUNCTION: int LLVMFindFunction | |
( LLVMExecutionEngineRef EE, c-string Name, LLVMValueRef* OutFn ) ; | |
FUNCTION: void* LLVMGetPointerToGlobal ( LLVMExecutionEngineRef EE, LLVMValueRef Global ) ; | |
FUNCTION: LLVMGenericValueRef LLVMRunFunction | |
( LLVMExecutionEngineRef EE, LLVMValueRef F, unsigned NumArgs, LLVMGenericValueRef* Args ) ; | |
]] | |
FILE: [[llvm/engine/tags.txt]] [[not tested | |
]] | |
FILE: [[llvm/tags.txt]] [[bindings | |
not tested | |
]] | |
FILE: [[pdf/pdf-tests.factor]] [[USING: io.files kernel math namespaces pdf pdf.libhpdf prettyprint sequences ; | |
IN: pdf.tests | |
SYMBOL: font | |
SYMBOL: width | |
SYMBOL: height | |
SYMBOL: twidth | |
: font-list ( -- seq ) { | |
"Courier" | |
"Courier-Bold" | |
"Courier-Oblique" | |
"Courier-BoldOblique" | |
"Helvetica" | |
"Helvetica-Bold" | |
"Helvetica-Oblique" | |
"Helvetica-BoldOblique" | |
"Times-Roman" | |
"Times-Bold" | |
"Times-Italic" | |
"Times-BoldItalic" | |
"Symbol" | |
"ZapfDingbats" | |
} ; | |
[ | |
! HPDF_COMP_ALL set-compression-mode | |
! HPDF_PAGE_MODE_USE_OUTLINE set-page-mode | |
! Add a new page object | |
add-page | |
get-page-height height set | |
get-page-width width set | |
! Print the lines of the page | |
1 set-page-line-width | |
50 50 width get 100 - height get 110 - page-rectangle | |
page-stroke | |
! Print the title of the page (with positioning center) | |
"Helvetica" f get-font font set | |
font get 24 set-page-font-and-size | |
"Font Demo" page-text-width twidth set | |
[ | |
width get twidth get - 2 / height get 50 - "Font Demo" page-text-out | |
] with-text | |
! Print subtitle | |
[ | |
font get 16 set-page-font-and-size | |
60 height get 80 - "<Standard Type1 font samples>" page-text-out | |
] with-text | |
! Print font list | |
[ | |
60 height get 105 - page-move-text-pos | |
SYMBOL: fontname | |
font-list [ | |
fontname set | |
fontname get f get-font font set | |
! print a label of text | |
font get 9 set-page-font-and-size | |
fontname get page-show-text | |
0 -18 page-move-text-pos | |
! print a sample text | |
font get 20 set-page-font-and-size | |
"abcdefgABCDEFG12345!#$%&+-@?" page-show-text | |
0 -20 page-move-text-pos | |
] each | |
] with-text | |
"font_test.pdf" temp-file save-to-file | |
] with-pdf | |
]] | |
FILE: [[pdf/libhpdf/libhpdf.factor]] [[! Copyright (C) 2007 Elie CHAFTARI | |
! See http://factorcode.org/license.txt for BSD license. | |
! | |
! Tested with libharu2 2.0.8 on Mac OS X 10.4.9 PowerPC | |
! | |
! export LD_LIBRARY_PATH=/opt/local/lib | |
USING: alien alien.syntax combinators system ; | |
IN: pdf.libhpdf | |
<< "libhpdf" { | |
{ [ win32? ] [ "libhpdf.dll" stdcall ] } | |
{ [ macosx? ] [ "libhpdf.dylib" cdecl ] } | |
{ [ unix? ] [ "$LD_LIBRARY_PATH/libhpdf.so" cdecl ] } | |
} cond add-library >> | |
! compression mode | |
: HPDF_COMP_NONE 0x00 ; inline ! No contents are compressed | |
: HPDF_COMP_TEXT 0x01 ; inline ! Compress contents stream of page | |
: HPDF_COMP_IMAGE 0x02 ; inline ! Compress streams of image objects | |
: HPDF_COMP_METADATA 0x04 ; inline ! Compress other data (fonts, cmaps...) | |
: HPDF_COMP_ALL 0x0F ; inline ! All stream data are compressed | |
: HPDF_COMP_MASK 0xFF ; inline | |
! page mode | |
CONSTANT: HPDF_PAGE_MODE_USE_NONE 0 | |
CONSTANT: HPDF_PAGE_MODE_USE_OUTLINE 1 | |
CONSTANT: HPDF_PAGE_MODE_USE_THUMBS 2 | |
CONSTANT: HPDF_PAGE_MODE_FULL_SCREEN 3 | |
CONSTANT: HPDF_PAGE_MODE_EOF 4 | |
: error-code ( -- seq ) { | |
{ 0x1001 "HPDF_ARRAY_COUNT_ERR\nInternal error. The consistency of the data was lost." } | |
{ 0x1002 "HPDF_ARRAY_ITEM_NOT_FOUND\nInternal error. The consistency of the data was lost." } | |
{ 0x1003 "HPDF_ARRAY_ITEM_UNEXPECTED_TYPE\nInternal error. The consistency of the data was lost." } | |
{ 0x1004 "HPDF_BINARY_LENGTH_ERR\nThe length of the data exceeds HPDF_LIMIT_MAX_STRING_LEN." } | |
{ 0x1005 "HPDF_CANNOT_GET_PALLET\nCannot get a pallet data from PNG image." } | |
{ 0x1007 "HPDF_DICT_COUNT_ERR\nThe count of elements of a dictionary exceeds HPDF_LIMIT_MAX_DICT_ELEMENT" } | |
{ 0x1008 "HPDF_DICT_ITEM_NOT_FOUND\nInternal error. The consistency of the data was lost." } | |
{ 0x1009 "HPDF_DICT_ITEM_UNEXPECTED_TYPE\nInternal error. The consistency of the data was lost." } | |
{ 0x100A "HPDF_DICT_STREAM_LENGTH_NOT_FOUND\nInternal error. The consistency of the data was lost." } | |
{ 0x100B "HPDF_DOC_ENCRYPTDICT_NOT_FOUND\nHPDF_SetPermission() OR HPDF_SetEncryptMode() was called before a password is set." } | |
{ 0x100C "HPDF_DOC_INVALID_OBJECT\nInternal error. The consistency of the data was lost." } | |
{ 0x100E "HPDF_DUPLICATE_REGISTRATION\nTried to register a font that has been registered." } | |
{ 0x100F "HPDF_EXCEED_JWW_CODE_NUM_LIMIT\nCannot register a character to the japanese word wrap characters list." } | |
{ 0x1011 "HPDF_ENCRYPT_INVALID_PASSWORD\nTried to set the owner password to NULL. owner password and user password is the same." } | |
{ 0x1013 "HPDF_ERR_UNKNOWN_CLASS\nInternal error. The consistency of the data was lost." } | |
{ 0x1014 "HPDF_EXCEED_GSTATE_LIMIT\nThe depth of the stack exceeded HPDF_LIMIT_MAX_GSTATE." } | |
{ 0x1015 "HPDF_FAILED_TO_ALLOC_MEM\nMemory allocation failed." } | |
{ 0x1016 "HPDF_FILE_IO_ERROR\nFile processing failed. (A detailed code is set.)" } | |
{ 0x1017 "HPDF_FILE_OPEN_ERROR\nCannot open a file. (A detailed code is set.)" } | |
{ 0x1019 "HPDF_FONT_EXISTS\nTried to load a font that has already been registered." } | |
{ 0x101A "HPDF_FONT_INVALID_WIDTHS_TABLE\nThe format of a font-file is invalid . Internal error. The consistency of the data was lost." } | |
{ 0x101B "HPDF_INVALID_AFM_HEADER\nCannot recognize a header of an afm file." } | |
{ 0x101C "HPDF_INVALID_ANNOTATION\nThe specified annotation handle is invalid." } | |
{ 0x101E "HPDF_INVALID_BIT_PER_COMPONENT\nBit-per-component of a image which was set as mask-image is invalid." } | |
{ 0x101F "HPDF_INVALID_CHAR_MATRICS_DATA\nCannot recognize char-matrics-data of an afm file." } | |
{ 0x1020 "HPDF_INVALID_COLOR_SPACE\n1. The color_space parameter of HPDF_LoadRawImage is invalid.\n2. Color-space of a image which was set as mask-image is invalid.\n3. The function which is invalid in the present color-space was invoked." } | |
{ 0x1021 "HPDF_INVALID_COMPRESSION_MODE\nInvalid value was set when invoking HPDF_SetCommpressionMode()." } | |
{ 0x1022 "HPDF_INVALID_DATE_TIME\nAn invalid date-time value was set." } | |
{ 0x1023 "HPDF_INVALID_DESTINATION\nAn invalid destination handle was set." } | |
{ 0x1025 "HPDF_INVALID_DOCUMENT\nAn invalid document handle is set." } | |
{ 0x1026 "HPDF_INVALID_DOCUMENT_STATE\nThe function which is invalid in the present state was invoked." } | |
{ 0x1027 "HPDF_INVALID_ENCODER\nAn invalid encoder handle was set." } | |
{ 0x1028 "HPDF_INVALID_ENCODER_TYPE\nA combination between font and encoder is wrong." } | |
{ 0x102B "HPDF_INVALID_ENCODING_NAME\nAn Invalid encoding name is specified." } | |
{ 0x102C "HPDF_INVALID_ENCRYPT_KEY_LEN\nThe lengh of the key of encryption is invalid." } | |
{ 0x102D "HPDF_INVALID_FONTDEF_DATA\n1. An invalid font handle was set.\n2. Unsupported font format." } | |
{ 0x102E "HPDF_INVALID_FONTDEF_TYPE\nInternal error. The consistency of the data was lost." } | |
{ 0x102F "HPDF_INVALID_FONT_NAME\nA font which has the specified name is not found." } | |
{ 0x1030 "HPDF_INVALID_IMAGE\nUnsupported image format." } | |
{ 0x1031 "HPDF_INVALID_JPEG_DATA\nUnsupported image format." } | |
{ 0x1032 "HPDF_INVALID_N_DATA\nCannot read a postscript-name from an afm file." } | |
{ 0x1033 "HPDF_INVALID_OBJECT\n1. An invalid object is set.\n2. Internal error. The consistency of the data was lost." } | |
{ 0x1034 "HPDF_INVALID_OBJ_ID\nInternal error. The consistency of the data was lost." } | |
{ 0x1035 "HPDF_INVALID_OPERATION\nInvoked HPDF_Image_SetColorMask() against the image-object which was set a mask-image." } | |
{ 0x1036 "HPDF_INVALID_OUTLINE\nAn invalid outline-handle was specified." } | |
{ 0x1037 "HPDF_INVALID_PAGE\nAn invalid page-handle was specified." } | |
{ 0x1038 "HPDF_INVALID_PAGES\nAn invalid pages-handle was specified. (internal error)" } | |
{ 0x1039 "HPDF_INVALID_PARAMETER\nAn invalid value is set." } | |
{ 0x103B "HPDF_INVALID_PNG_IMAGE\nInvalid PNG image format." } | |
{ 0x103C "HPDF_INVALID_STREAM\nInternal error. The consistency of the data was lost." } | |
{ 0x103D "HPDF_MISSING_FILE_NAME_ENTRY\nInternal error. The \"_FILE_NAME\" entry for delayed loading is missing." } | |
{ 0x103F "HPDF_INVALID_TTC_FILE\nInvalid .TTC file format." } | |
{ 0x1040 "HPDF_INVALID_TTC_INDEX\nThe index parameter was exceed the number of included fonts" } | |
{ 0x1041 "HPDF_INVALID_WX_DATA\nCannot read a width-data from an afm file." } | |
{ 0x1042 "HPDF_ITEM_NOT_FOUND\nInternal error. The consistency of the data was lost." } | |
{ 0x1043 "HPDF_LIBPNG_ERROR\nAn error has returned from PNGLIB while loading an image." } | |
{ 0x1044 "HPDF_NAME_INVALID_VALUE\nInternal error. The consistency of the data was lost." } | |
{ 0x1045 "HPDF_NAME_OUT_OF_RANGE\nInternal error. The consistency of the data was lost." } | |
{ 0x1049 "HPDF_PAGES_MISSING_KIDS_ENTRY\nInternal error. The consistency of the data was lost." } | |
{ 0x104A "HPDF_PAGE_CANNOT_FIND_OBJECT\nInternal error. The consistency of the data was lost." } | |
{ 0x104B "HPDF_PAGE_CANNOT_GET_ROOT_PAGES\nInternal error. The consistency of the data was lost." } | |
{ 0x104C "HPDF_PAGE_CANNOT_RESTORE_GSTATE\nThere are no graphics-states to be restored." } | |
{ 0x104D "HPDF_PAGE_CANNOT_SET_PARENT\nInternal error. The consistency of the data was lost." } | |
{ 0x104E "HPDF_PAGE_FONT_NOT_FOUND\nThe current font is not set." } | |
{ 0x104F "HPDF_PAGE_INVALID_FONT\nAn invalid font-handle was specified." } | |
{ 0x1050 "HPDF_PAGE_INVALID_FONT_SIZE\nAn invalid font-size was set." } | |
{ 0x1051 "HPDF_PAGE_INVALID_GMODE\nSee Graphics mode." } | |
{ 0x1052 "HPDF_PAGE_INVALID_INDEX\nInternal error. The consistency of the data was lost." } | |
{ 0x1053 "HPDF_PAGE_INVALID_ROTATE_VALUE\nThe specified value is not a multiple of 90." } | |
{ 0x1054 "HPDF_PAGE_INVALID_SIZE\nAn invalid page-size was set." } | |
{ 0x1055 "HPDF_PAGE_INVALID_XOBJECT\nAn invalid image-handle was set." } | |
{ 0x1056 "HPDF_PAGE_OUT_OF_RANGE\nThe specified value is out of range." } | |
{ 0x1057 "HPDF_REAL_OUT_OF_RANGE\nThe specified value is out of range." } | |
{ 0x1058 "HPDF_STREAM_EOF\nUnexpected EOF marker was detected." } | |
{ 0x1059 "HPDF_STREAM_READLN_CONTINUE\nInternal error. The consistency of the data was lost." } | |
{ 0x105B "HPDF_STRING_OUT_OF_RANGE\nThe length of the specified text is too long." } | |
{ 0x105C "HPDF_THIS_FUNC_WAS_SKIPPED\nThe execution of a function was skipped because of other errors." } | |
{ 0x105D "HPDF_TTF_CANNOT_EMBEDDING_FONT\nThis font cannot be embedded. (restricted by license.)" } | |
{ 0x105E "HPDF_TTF_INVALID_CMAP\nUnsupported ttf format. (cannot find unicode cmap.)" } | |
{ 0x105F "HPDF_TTF_INVALID_FOMAT\nUnsupported ttf format." } | |
{ 0x1060 "HPDF_TTF_MISSING_TABLE\nUnsupported ttf format. (cannot find a necessary table.)" } | |
{ 0x1061 "HPDF_UNSUPPORTED_FONT_TYPE\nInternal error. The consistency of the data was lost." } | |
{ 0x1062 "HPDF_UNSUPPORTED_FUNC\n1. The library is not configured to use PNGLIB.\n2. Internal error. The consistency of the data was lost." } | |
{ 0x1063 "HPDF_UNSUPPORTED_JPEG_FORMAT\nUnsupported Jpeg format." } | |
{ 0x1064 "HPDF_UNSUPPORTED_TYPE1_FONT\nFailed to parse .PFB file." } | |
{ 0x1065 "HPDF_XREF_COUNT_ERR\nInternal error. The consistency of the data was lost." } | |
{ 0x1066 "HPDF_ZLIB_ERROR\nAn error has occurred while executing a function of Zlib." } | |
{ 0x1067 "HPDF_INVALID_PAGE_INDEX\nAn error returned from Zlib." } | |
{ 0x1068 "HPDF_INVALID_URI\nAn invalid URI was set." } | |
{ 0x1069 "HPDF_PAGELAYOUT_OUT_OF_RANGE\nAn invalid page-layout was set." } | |
{ 0x1070 "HPDF_PAGEMODE_OUT_OF_RANGE\nAn invalid page-mode was set." } | |
{ 0x1071 "HPDF_PAGENUM_STYLE_OUT_OF_RANGE\nAn invalid page-num-style was set." } | |
{ 0x1072 "HPDF_ANNOT_INVALID_ICON\nAn invalid icon was set." } | |
{ 0x1073 "HPDF_ANNOT_INVALID_BORDER_STYLE\nAn invalid border-style was set." } | |
{ 0x1074 "HPDF_PAGE_INVALID_DIRECTION\nAn invalid page-direction was set." } | |
{ 0x1075 "HPDF_INVALID_FONT\nAn invalid font-handle was specified." } | |
} ; | |
LIBRARY: libhpdf | |
! =============================================== | |
! hpdf.h | |
! =============================================== | |
FUNCTION: void* HPDF_New ( void* user_error_fn, void* user_data ) ; | |
FUNCTION: void* HPDF_Free ( void* pdf ) ; | |
FUNCTION: ulong HPDF_SetCompressionMode ( void* pdf, uint mode ) ; | |
FUNCTION: ulong HPDF_SetPageMode ( void* pdf, uint mode ) ; | |
FUNCTION: void* HPDF_AddPage ( void* pdf ) ; | |
FUNCTION: ulong HPDF_SaveToFile ( void* pdf, char* file_name ) ; | |
FUNCTION: float HPDF_Page_GetHeight ( void* page ) ; | |
FUNCTION: float HPDF_Page_GetWidth ( void* page ) ; | |
FUNCTION: ulong HPDF_Page_SetLineWidth ( void* page, float line_width ) ; | |
FUNCTION: ulong HPDF_Page_Rectangle ( void* page, float x, float y, | |
float width, float height ) ; | |
FUNCTION: ulong HPDF_Page_Stroke ( void* page ) ; | |
FUNCTION: void* HPDF_GetFont ( void* pdf, char* font_name, | |
char* encoding_name ) ; | |
FUNCTION: ulong HPDF_Page_SetFontAndSize ( void* page, void* font, | |
float size ) ; | |
FUNCTION: float HPDF_Page_TextWidth ( void* page, char* text ) ; | |
FUNCTION: ulong HPDF_Page_BeginText ( void* page ) ; | |
FUNCTION: ulong HPDF_Page_TextOut ( void* page, float xpos, float ypos, | |
char* text ) ; | |
FUNCTION: ulong HPDF_Page_EndText ( void* page ) ; | |
FUNCTION: ulong HPDF_Page_MoveTextPos ( void* page, float x, float y ) ; | |
FUNCTION: ulong HPDF_Page_ShowText ( void* page, char* text ) ; | |
]] | |
FILE: [[pdf/pdf.factor]] [[! Copyright (C) 2007 Elie CHAFTARI | |
! See http://factorcode.org/license.txt for BSD license. | |
! | |
! Tested with libharu2 2.0.8 on Mac OS X 10.4.9 PowerPC | |
USING: assocs continuations hashtables kernel math namespaces pdf.libhpdf ; | |
IN: pdf | |
SYMBOL: pdf | |
SYMBOL: page | |
! ========================================================= | |
! Error handling routines | |
! ========================================================= | |
: check-status ( status -- ) | |
dup zero? [ | |
drop | |
] [ | |
error-code >hashtable at throw | |
] if ; | |
! ========================================================= | |
! Document handling routines | |
! ========================================================= | |
: new-pdf ( error-handler user-data -- ) | |
HPDF_New pdf set ; | |
: free-pdf ( -- ) | |
pdf get HPDF_Free drop ; | |
: with-pdf ( quot -- ) | |
[ f f new-pdf [ free-pdf ] [ ] cleanup ] with-scope ; inline | |
: set-compression-mode ( mode -- ) | |
pdf get swap HPDF_SetCompressionMode check-status ; | |
: set-page-mode ( mode -- ) | |
pdf get swap HPDF_SetPageMode check-status ; | |
: add-page ( -- ) | |
pdf get HPDF_AddPage page set ; | |
: save-to-file ( filename -- ) | |
pdf get swap HPDF_SaveToFile check-status ; | |
: get-font ( fontname encoding -- font ) | |
pdf get -rot HPDF_GetFont ; | |
! ========================================================= | |
! Page Handling routines | |
! ========================================================= | |
: get-page-height ( -- height ) | |
page get HPDF_Page_GetHeight ; | |
: get-page-width ( -- width ) | |
page get HPDF_Page_GetWidth ; | |
: page-text-width ( text -- width ) | |
page get swap HPDF_Page_TextWidth ; | |
! ========================================================= | |
! Graphics routines | |
! ========================================================= | |
: set-page-line-width ( linewidth -- ) | |
page get swap HPDF_Page_SetLineWidth check-status ; | |
: page-rectangle ( x y width height -- ) | |
>r >r >r >r page get r> r> r> r> HPDF_Page_Rectangle check-status ; | |
: page-stroke ( -- ) | |
page get HPDF_Page_Stroke check-status ; | |
: set-page-font-and-size ( font size -- ) | |
page get -rot HPDF_Page_SetFontAndSize check-status ; | |
: page-begin-text ( -- ) | |
page get HPDF_Page_BeginText check-status ; | |
: page-text-out ( xpos ypos text -- ) | |
page get -roll HPDF_Page_TextOut check-status ; | |
: page-end-text ( -- ) | |
page get HPDF_Page_EndText check-status ; | |
: with-text ( -- ) | |
[ page-begin-text [ page-end-text ] [ ] cleanup ] with-scope ; inline | |
: page-move-text-pos ( x y -- ) | |
page get -rot HPDF_Page_MoveTextPos check-status ; | |
: page-show-text ( text -- ) | |
page get swap HPDF_Page_ShowText check-status ; | |
]] | |
ln -sf $(SONAME)$(SOVER1) $(SONAME)$(SONAME)$(SOVER1)JS) $(LDFLAGS) -Wl X, modify the Makefile after calling ./configure --shared | |
Now you can build and install: | |
make clean | |
make | |
make install | |
Test PDF files from pdf-tests.factor are generated in the test folder.]] | |
FILE: [[pdf/authors.txt]] [[Elie Chaftari | |
]] | |
FILE: [[advice/advice.factor]] [[! Copyright (C) 2008 James Cash | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: kernel sequences fry words assocs linked-assocs tools.annotations | |
coroutines lexer parser quotations arrays namespaces continuations | |
summary ; | |
IN: advice | |
SYMBOLS: before after around advised in-advice? ; | |
: advised? ( word -- ? ) | |
advised word-prop ; | |
DEFER: make-advised | |
<PRIVATE | |
: init-around-co ( quot -- coroutine ) | |
\ coreset suffix cocreate ; | |
PRIVATE> | |
: advise ( quot name word loc -- ) | |
dup around eq? [ [ init-around-co ] 3dip ] when | |
over advised? [ over make-advised ] unless | |
word-prop set-at ; | |
: advise-before ( quot name word -- ) before advise ; | |
: advise-after ( quot name word -- ) after advise ; | |
: advise-around ( quot name word -- ) around advise ; | |
: get-advice ( word type -- seq ) | |
word-prop values ; | |
: call-before ( word -- ) | |
before get-advice [ call ] each ; | |
: call-after ( word -- ) | |
after get-advice [ call ] each ; | |
: call-around ( main word -- ) | |
t in-advice? [ | |
around get-advice tuck | |
[ [ coresume ] each ] [ call ] [ <reversed> [ coresume ] each ] tri* | |
] with-variable ; | |
: remove-advice ( name word loc -- ) | |
word-prop delete-at ; | |
ERROR: ad-do-it-error ; | |
M: ad-do-it-error summary | |
drop "ad-do-it should only be called inside 'around' advice" ; | |
: ad-do-it ( input -- result ) | |
in-advice? get [ ad-do-it-error ] unless coyield ; | |
: make-advised ( word -- ) | |
[ dup '[ [ _ ] dip over dup '[ _ call-before _ _ call-around _ call-after ] ] annotate ] | |
[ { before after around } [ <linked-hash> swap set-word-prop ] with each ] | |
[ t advised set-word-prop ] tri ; | |
: unadvise ( word -- ) | |
[ reset ] [ { before after around advised } [ f swap set-word-prop ] with each ] bi ; | |
SYNTAX: ADVISE: ! word adname location => word adname quot loc | |
scan-word scan scan-word parse-definition swap [ spin ] dip advise ; | |
SYNTAX: UNADVISE: | |
scan-word suffix! \ unadvise suffix! ; | |
]] | |
FILE: [[advice/advice-docs.factor]] [[IN: advice | |
USING: help.markup help.syntax tools.annotations words coroutines ; | |
HELP: make-advised | |
{ $values { "word" "a word to annotate in preparation of advising" } } | |
{ $description "Prepares a word for being advised. This is done by: " | |
{ $list | |
{ "Annotating it to call the appropriate words before, around, and after the original body " } | |
{ "Adding " { $snippet "before" } ", " { $snippet "around" } ", and " { $snippet "after" } " properties, which will contain the advice" } | |
{ "Adding an " { $snippet "advised" } "property, which can later be used to determine if a given word is defined (see " { $link advised? } ")" } | |
} | |
} | |
{ $see-also advised? annotate } ; | |
HELP: advised? | |
{ $values { "word" "a word" } { "?" "t or f, indicating if " { $snippet "word" } " is advised" } } | |
{ $description "Determines whether or not the given word has any advice on it." } ; | |
HELP: ad-do-it | |
{ $values { "input" "an object" } { "result" "an object" } } | |
{ $description "Calls either the next applicable around advice or the main body, returning back to the point it was called from when finished. This word should only be called from inside advice." } | |
{ $see-also coyield } ; | |
ARTICLE: "advice" "Advice" | |
"Advice is a simple way of adding additition functionality to words by adding 'hooks' to a word, which can act before, after, or around the calling of the word." ; | |
ABOUT: "advice" | |
]] | |
FILE: [[advice/advice-tests.factor]] [[! Copyright (C) 2008 James Cash | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: kernel sequences io io.streams.string math tools.test advice math.parser | |
parser namespaces multiline eval words assocs ; | |
IN: advice.tests | |
[ | |
[ ad-do-it ] must-fail | |
: foo ( -- str ) "foo" ; | |
\ foo make-advised | |
{ "bar" "foo" } [ | |
[ "bar" ] "barify" \ foo advise-before | |
foo | |
] unit-test | |
{ "bar" "foo" "baz" } [ | |
[ "baz" ] "bazify" \ foo advise-after | |
foo | |
] unit-test | |
{ "foo" "baz" } [ | |
"barify" \ foo before remove-advice | |
foo | |
] unit-test | |
: bar ( a -- b ) 1 + ; | |
\ bar make-advised | |
{ 11 } [ | |
[ 2 * ] "double" \ bar advise-before | |
5 bar | |
] unit-test | |
{ 11/3 } [ | |
[ 3 / ] "third" \ bar advise-after | |
5 bar | |
] unit-test | |
{ -2 } [ | |
[ -1 * ad-do-it 3 + ] "frobnobicate" \ bar advise-around | |
5 bar | |
] unit-test | |
: add ( a b -- c ) + ; | |
\ add make-advised | |
{ 10 } [ | |
[ [ 2 * ] bi@ ] "double-args" \ add advise-before | |
2 3 add | |
] unit-test | |
{ 21 } [ | |
[ 3 * ad-do-it 1- ] "around1" \ add advise-around | |
2 3 add | |
] unit-test | |
! { 9 } [ | |
! [ [ 1- ] bi@ ad-do-it 2 / ] "around2" \ add advise-around | |
! 2 3 add | |
! ] unit-test | |
! { { "around1" "around2" } } [ | |
! \ add around word-prop keys | |
! ] unit-test | |
{ 5 f } [ | |
\ add unadvise | |
2 3 add \ add advised? | |
] unit-test | |
! : quux ( a b -- c ) * ; | |
! { f t 3+3/4 } [ | |
! <" USING: advice kernel math ; | |
! IN: advice.tests | |
! \ quux advised? | |
! ADVISE: quux halve before [ 2 / ] bi@ ; | |
! \ quux advised? | |
! 3 5 quux"> eval | |
! ] unit-test | |
! { 3+3/4 "1+1/2 2+1/2 3+3/4" } [ | |
! <" USING: advice kernel math math.parser io io.streams.string ; | |
! IN: advice.tests | |
! ADVISE: quux log around | |
! 2dup [ number>string write " " write ] bi@ | |
! ad-do-it | |
! dup number>string write ; | |
! [ 3 5 quux ] with-string-writer"> eval | |
! ] unit-test | |
] with-scope | |
]] | |
FILE: [[advice/summary.txt]] [[Implmentation of advice/aspects | |
]] | |
FILE: [[advice/authors.txt]] [[James Cash | |
]] | |
FILE: [[advice/tags.txt]] [[extensions | |
]] | |
FILE: [[peg-lexer/peg-lexer.factor]] [=[USING: hashtables assocs sequences locals math accessors multiline delegate strings | |
delegate.protocols kernel peg peg.ebnf peg.private lexer namespaces combinators parser | |
words ; | |
IN: peg-lexer | |
TUPLE: lex-hash hash ; | |
CONSULT: assoc-protocol lex-hash hash>> ; | |
: <lex-hash> ( a -- lex-hash ) lex-hash boa ; | |
: pos-or-0 ( neg? -- pos/0 ) dup 0 < [ drop 0 ] when ; | |
:: prepare-pos ( v i -- c l ) | |
[let | n [ i v head-slice ] | | |
v CHAR: \n n last-index -1 or 1 + - | |
n [ CHAR: \n = ] count 1 + | |
] ; | |
: store-pos ( v a -- ) | |
input of prepare-pos | |
lexer get [ line<< ] keep column<< ; | |
M: lex-hash set-at | |
swap { | |
{ pos [ store-pos ] } | |
[ swap hash>> set-at ] | |
} case ; | |
:: at-pos ( t l c -- p ) t l head-slice [ length ] map-sum l 1 - + c + ; | |
M: lex-hash at* | |
swap { | |
{ input [ drop lexer get text>> "\n" join t ] } | |
{ pos [ drop lexer get [ text>> ] [ line>> 1 - ] [ column>> 1 + ] tri at-pos t ] } | |
[ swap hash>> at* ] | |
} case ; | |
: with-global-lexer ( quot -- result ) | |
[ | |
f lrstack set | |
V{ } clone error-stack set H{ } clone \ heads set | |
H{ } clone \ packrat set | |
] f make-assoc <lex-hash> | |
swap bind ; inline | |
: parse* ( parser -- ast ) | |
compile | |
[ execute [ error-stack get first throw ] unless* ] with-global-lexer | |
ast>> ; inline | |
: create-bnf ( name parser -- ) | |
reset-tokenizer [ lexer get skip-blank parse* dup ignore? [ drop ] [ parsed ] if ] curry | |
define-syntax word make-inline ; | |
SYNTAX: ON-BNF: | |
scan-new-word reset-tokenizer ";ON-BNF" parse-multiline-string parse-ebnf | |
main of create-bnf ; | |
! Tokenizer like standard factor lexer | |
EBNF: factor | |
space = " " | "\n" | "\t" | |
spaces = space* => [[ drop ignore ]] | |
chunk = (!(space) .)+ => [[ >string ]] | |
expr = spaces chunk | |
;EBNF | |
]=] | |
FILE: [[peg-lexer/test-parsers/test-parsers.factor]] [=[USING: peg-lexer math.parser strings ; | |
IN: peg-lexer.test-parsers | |
ON-BNF: test1 | |
num = [1-4]* => [[ >string ]] | |
expr = num ( "-end" | "-done" ) | |
;ON-BNF | |
ON-BNF: test2 | |
num = [1-4]* => [[ >string string>number ]] | |
expr= num [5-9] | |
;ON-BNF | |
ON-BNF: test3 | |
tokenizer = <foreign factor> | |
expr= "heavy" "duty" "testing" | |
;ON-BNF | |
]=] | |
FILE: [[peg-lexer/peg-lexer-tests.factor]] [[USING: tools.test peg-lexer.test-parsers ; | |
IN: peg-lexer.tests | |
{ V{ "1234" "-end" } } [ | |
test1 1234-end | |
] unit-test | |
{ V{ 1234 53 } } [ | |
test2 12345 | |
] unit-test | |
{ V{ "heavy" "duty" "testing" } } [ | |
test3 heavy duty testing | |
] unit-test | |
]] | |
FILE: [[peg-lexer/summary.txt]] [[Use peg to write parsing words | |
]] | |
FILE: [[peg-lexer/peg-lexer-docs.factor]] [[USING: peg.ebnf help.syntax help.markup strings ; | |
IN: peg-lexer | |
HELP: ON-BNF: | |
{ $syntax "ON-BNF: word ... ;ON-BNF" } | |
{ $description "Creates a parsing word using a parser for lexer control, adding the resulting ast to the stack. Parser syntax is as in " { $link POSTPONE: EBNF: } } ; | |
HELP: create-bnf | |
{ $values { "name" string } { "parser" parser } } | |
{ $description "Runtime equivalent of " { $link POSTPONE: ON-BNF: } " also useful with manually constructed parsers." } ; | |
HELP: factor | |
{ $values { "input" string } { "ast" "a sequence of tokens" } } | |
{ $description "Tokenizer that acts like standard factor lexer, separating tokens by whitespace." } ; | |
]] | |
FILE: [[peg-lexer/authors.txt]] [[Sam Anklesaria | |
]] | |
FILE: [[peg-lexer/tags.txt]] [[extensions | |
reflection | |
]] | |
FILE: [[flatland/flatland.factor]] [[ | |
USING: accessors arrays combinators combinators.short-circuit | |
fry kernel locals math math.intervals math.vectors multi-methods | |
sequences ; | |
FROM: multi-methods => GENERIC: ; | |
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 } first ; | |
METHOD: y { sequence } second ; | |
METHOD: (x!) { number sequence } set-first ; | |
METHOD: (y!) { number sequence } set-second ; | |
METHOD: width { sequence } first ; | |
METHOD: height { sequence } 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 } v- norm ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! A class for objects with a position | |
TUPLE: pos pos ; | |
METHOD: x { pos } pos>> first ; | |
METHOD: y { pos } 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 } [ 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!) ; | |
: reverse-vertical-velocity ( vel -- ) vel>> [ y neg ] [ ] bi (y!) ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! 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 } dim>> first ; | |
METHOD: height { rectangle } dim>> second ; | |
METHOD: left { rectangle } x ; | |
METHOD: right { rectangle } [ x ] [ width ] bi + ; | |
METHOD: bottom { rectangle } y ; | |
METHOD: top { rectangle } [ 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 } | |
[ 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>> ; | |
METHOD: right { extent } right>> ; | |
METHOD: bottom { extent } bottom>> ; | |
METHOD: top { extent } top>> ; | |
METHOD: width { extent } [ right>> ] [ left>> ] bi - ; | |
METHOD: height { extent } [ 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* > ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
:: 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 ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
GENERIC: within? ( a b -- ? ) | |
METHOD: within? { pos rectangle } | |
{ | |
[ left to-the-right-of? ] | |
[ right to-the-left-of? ] | |
[ bottom above? ] | |
[ top below? ] | |
} | |
2&& ; | |
]] | |
FILE: [[models/combinators/combinators.factor]] [[USING: accessors arrays kernel models models.product monads | |
sequences sequences.extras shuffle ; | |
FROM: syntax => >> ; | |
IN: models.combinators | |
TUPLE: multi-model < model important? ; | |
GENERIC: (model-changed) ( model observer -- ) | |
: <multi-model> ( models kind -- model ) f swap new-model [ [ add-dependency ] curry each ] keep ; | |
M: multi-model model-changed over value>> [ (model-changed) ] [ 2drop ] if ; | |
M: multi-model model-activated dup dependencies>> [ value>> ] find nip | |
[ swap model-changed ] [ drop ] if* ; | |
: #1 ( model -- model' ) t >>important? ; | |
IN: models | |
: notify-connections ( model -- ) | |
dup connections>> dup [ dup multi-model? [ important?>> ] [ drop f ] if ] find-all | |
[ second tuck [ remove ] dip prefix ] each | |
[ model-changed ] with each ; | |
IN: models.combinators | |
TUPLE: basic-model < multi-model ; | |
M: basic-model (model-changed) [ value>> ] dip set-model ; | |
: merge ( models -- model ) basic-model <multi-model> ; | |
: 2merge ( model1 model2 -- model ) 2array merge ; | |
: <basic> ( value -- model ) basic-model new-model ; | |
TUPLE: filter-model < multi-model quot ; | |
M: filter-model (model-changed) [ value>> ] dip 2dup quot>> call( a -- ? ) | |
[ set-model ] [ 2drop ] if ; | |
: filter-model ( model quot -- filter-model ) [ 1array \ filter-model <multi-model> ] dip >>quot ; | |
TUPLE: fold-model < multi-model quot base values ; | |
M: fold-model (model-changed) 2dup base>> = | |
[ [ [ value>> ] [ [ values>> ] [ quot>> ] bi ] bi* swapd reduce* ] keep set-model ] | |
[ [ [ value>> ] [ values>> ] bi* push ] | |
[ [ [ value>> ] [ [ value>> ] [ quot>> ] bi ] bi* call( val oldval -- newval ) ] keep set-model ] 2bi | |
] if ; | |
M: fold-model model-activated drop ; | |
: new-fold-model ( deps -- model ) fold-model <multi-model> V{ } clone >>values ; | |
: fold ( model oldval quot -- model ) rot 1array new-fold-model swap >>quot | |
swap >>value ; | |
: fold* ( model oldmodel quot -- model ) over [ [ 2array new-fold-model ] dip >>quot ] | |
dip [ >>base ] [ value>> >>value ] bi ; | |
TUPLE: updater-model < multi-model values updates ; | |
M: updater-model (model-changed) [ tuck updates>> = | |
[ [ values>> value>> ] keep set-model ] | |
[ drop ] if ] keep f swap value<< ; | |
: updates ( values updates -- model ) [ 2array updater-model <multi-model> ] 2keep | |
[ >>values ] [ >>updates ] bi* ; | |
SYMBOL: switch | |
TUPLE: switch-model < multi-model original switcher on ; | |
M: switch-model (model-changed) 2dup switcher>> = | |
[ [ value>> ] dip over switch = [ nip [ original>> ] keep f >>on model-changed ] [ t >>on set-model ] if ] | |
[ dup on>> [ 2drop ] [ [ value>> ] dip over [ set-model ] [ 2drop ] if ] if ] if ; | |
: switch-models ( model1 model2 -- model' ) swap [ 2array switch-model <multi-model> ] 2keep | |
[ [ value>> >>value ] [ >>original ] bi ] [ >>switcher ] bi* ; | |
M: switch-model model-activated [ original>> ] keep model-changed ; | |
: >behavior ( event -- behavior ) t >>value ; | |
TUPLE: mapped-model < multi-model model quot ; | |
: new-mapped-model ( model quot class -- mapped-model ) [ over 1array ] dip | |
<multi-model> swap >>quot swap >>model ; | |
: <mapped> ( model quot -- model ) mapped-model new-mapped-model ; | |
M: mapped-model (model-changed) | |
[ [ value>> ] [ quot>> ] bi* call( old -- new ) ] [ nip ] 2bi | |
set-model ; | |
TUPLE: side-effect-model < mapped-model ; | |
M: side-effect-model (model-changed) [ value>> ] dip [ quot>> call( old -- ) ] 2keep set-model ; | |
TUPLE: quot-model < mapped-model ; | |
M: quot-model (model-changed) nip [ quot>> call( -- b ) ] keep set-model ; | |
TUPLE: action-value < basic-model parent ; | |
: <action-value> ( parent value -- model ) action-value new-model swap >>parent ; | |
M: action-value model-activated dup parent>> dup activate-model model-changed ; ! a fake dependency of sorts | |
TUPLE: action < multi-model quot ; | |
M: action (model-changed) [ [ value>> ] [ quot>> ] bi* call( a -- b ) ] keep value>> | |
[ swap add-connection ] 2keep model-changed ; | |
: <action> ( model quot -- action-model ) [ 1array action <multi-model> ] dip >>quot dup f <action-value> >>value value>> ; | |
TUPLE: collection < multi-model ; | |
: <collection> ( models -- product ) collection <multi-model> ; | |
M: collection (model-changed) | |
nip | |
dup dependencies>> [ value>> ] all? | |
[ dup [ value>> ] product-value swap set-model ] | |
[ drop ] if ; | |
M: collection model-activated dup (model-changed) ; | |
! for side effects | |
TUPLE: (when-model) < multi-model quot cond ; | |
: when-model ( model quot cond -- model ) rot 1array (when-model) <multi-model> swap >>cond swap >>quot ; | |
M: (when-model) (model-changed) [ quot>> ] 2keep | |
[ value>> ] [ cond>> ] bi* call( a -- ? ) [ call( model -- ) ] [ 2drop ] if ; | |
! only used in construction | |
: with-self ( quot: ( model -- model ) -- model ) [ f <basic> dup ] dip call swap [ add-dependency ] keep ; inline | |
USE: models.combinators.templates | |
<< { "$>" "<$" "fmap" } [ fmaps ] each >> | |
]] | |
FILE: [[models/combinators/summary.txt]] [[Model combination and manipulation]] | |
FILE: [[models/combinators/templates/templates.factor]] [[USING: kernel sequences functors fry macros generalizations ; | |
IN: models.combinators.templates | |
FROM: models.combinators => <collection> #1 ; | |
FUNCTOR: fmaps ( W -- ) | |
W IS ${W} | |
w-n DEFINES ${W}-n | |
w-2 DEFINES 2${W} | |
w-3 DEFINES 3${W} | |
w-4 DEFINES 4${W} | |
w-n* DEFINES ${W}-n* | |
w-2* DEFINES 2${W}* | |
w-3* DEFINES 3${W}* | |
w-4* DEFINES 4${W}* | |
WHERE | |
MACRO: w-n ( int -- quot ) dup '[ [ _ narray <collection> ] dip [ _ firstn ] prepend W ] ; | |
: w-2 ( a b quot -- mapped ) 2 w-n ; inline | |
: w-3 ( a b c quot -- mapped ) 3 w-n ; inline | |
: w-4 ( a b c d quot -- mapped ) 4 w-n ; inline | |
MACRO: w-n* ( int -- quot ) dup '[ [ _ narray <collection> #1 ] dip [ _ firstn ] prepend W ] ; | |
: w-2* ( a b quot -- mapped ) 2 w-n* ; inline | |
: w-3* ( a b c quot -- mapped ) 3 w-n* ; inline | |
: w-4* ( a b c d quot -- mapped ) 4 w-n* ; inline | |
;FUNCTOR | |
]] | |
FILE: [[models/combinators/authors.txt]] [[Sam Anklesaria | |
]] | |
FILE: [[models/combinators/combinators-docs.factor]] [[USING: help.markup help.syntax models models.arrow sequences monads ; | |
IN: models.combinators | |
HELP: merge | |
{ $values { "models" "a list of models" } { "model" basic-model } } | |
{ $description "Creates a model that merges the updates of others" } ; | |
HELP: filter-model | |
{ $values { "model" model } { "quot" "quotation with stack effect ( a b -- c )" } { "filter-model" filter-model } } | |
{ $description "Creates a model that uses the updates of another model only when they satisfy a given predicate" } ; | |
HELP: fold | |
{ $values { "model" model } { "oldval" "starting value" } { "quot" "applied to update and previous values" } { "model" model } } | |
{ $description "Similar to " { $link reduce } " but works on models, applying a quotation to the previous and new values at each update" } ; | |
HELP: switch-models | |
{ $values { "model1" model } { "model2" model } { "model'" model } } | |
{ $description "Creates a model that starts with the behavior of model2 and switches to the behavior of model1 on its update" } ; | |
HELP: <mapped> | |
{ $values { "model" model } { "quot" "applied to model's value on updates" } { "model" model } } | |
{ $description "An expanded version of " { $link <arrow> } ". Use " { $link fmap } " instead." } ; | |
HELP: when-model | |
{ $values { "model" model } { "quot" "called on the model if the quot yields true" } { "cond" "a quotation called on the model's value, yielding a boolean value" } } | |
{ $description "Calls quot when model updates if its value meets the condition set in cond" } ; | |
HELP: with-self | |
{ $values { "quot" "quotation that recieves its own return value" } { "model" model } } | |
{ $description "Fixed points for models: the quot reacts to the same model to gives" } ; | |
HELP: #1 | |
{ $values { "model" model } { "model'" model } } | |
{ $description "Moves a model to the top of its dependencies' connections, thus being notified before the others" } ; | |
ARTICLE: "models.combinators" "Extending models" | |
"The " { $vocab-link "models.combinators" } " library expands models to have discrete start and end times. " | |
"Also, it provides methods of manipulating and combining models, expecially useful when programming user interfaces: " | |
"The output models of some gadgets (see " { $vocab-link "ui.gadgets.controls" } " ) can be manipulated and used as the input models of others." ; | |
ABOUT: "models.combinators" | |
]] | |
FILE: [[alien/cxx/cxx.factor]] [[! Copyright (C) 2009 Jeremy Hughes. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: accessors alien.c-types alien.cxx.parser alien.marshall | |
alien.inline.types classes.mixin classes.tuple kernel namespaces | |
assocs sequences parser classes.parser alien.marshall.syntax | |
interpolate locals effects io strings make vocabs.parser words | |
generic fry quotations ; | |
IN: alien.cxx | |
<PRIVATE | |
: class-mixin ( str -- word ) | |
create-class-in [ define-mixin-class ] keep ; | |
: class-tuple-word ( word -- word' ) | |
"#" append create-word-in ; | |
: define-class-tuple ( word mixin -- ) | |
[ drop class-wrapper { } define-tuple-class ] | |
[ add-mixin-instance ] 2bi ; | |
PRIVATE> | |
: define-c++-class ( name superclass-mixin -- ) | |
[ [ class-tuple-word ] [ class-mixin ] bi dup ] dip | |
add-mixin-instance define-class-tuple ; | |
:: define-c++-method ( class-name generic name types effect virtual -- ) | |
[ name % "_" % class-name H{ { CHAR: : CHAR: _ } } substitute % ] "" make :> name' | |
effect [ in>> "self" suffix ] [ out>> ] bi <effect> :> effect' | |
types class-name "*" append suffix :> types' | |
effect in>> "," join :> args | |
class-name virtual [ "#" append ] unless current-vocab lookup :> class | |
SBUF" " clone dup [ I[ return self->${name}(${args});]I ] with-output-stream >string :> body | |
name' types' effect' body define-c-marshalled | |
class generic create-method name' current-vocab lookup 1quotation define ; | |
]] | |
FILE: [[alien/cxx/parser/parser.factor]] [[! Copyright (C) 2009 Jeremy Hughes. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: parser lexer alien.inline ; | |
IN: alien.cxx.parser | |
: parse-c++-class-definition ( -- class superclass-mixin ) | |
scan scan-word ; | |
: parse-c++-method-definition ( -- class-name generic name types effect ) | |
scan scan-word function-types-effect ; | |
]] | |
FILE: [[alien/cxx/parser/authors.txt]] [[Jeremy Hughes | |
]] | |
FILE: [[alien/cxx/authors.txt]] [[Jeremy Hughes | |
]] | |
FILE: [[alien/cxx/syntax/syntax.factor]] [[! Copyright (C) 2009 Jeremy Hughes. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: alien.cxx alien.cxx.parser ; | |
IN: alien.cxx.syntax | |
SYNTAX: C++-CLASS: | |
parse-c++-class-definition define-c++-class ; | |
SYNTAX: C++-METHOD: | |
parse-c++-method-definition f define-c++-method ; | |
SYNTAX: C++-VIRTUAL: | |
parse-c++-method-definition t define-c++-method ; | |
]] | |
FILE: [[alien/cxx/syntax/syntax-tests.factor]] [[! Copyright (C) 2009 Jeremy Hughes. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: tools.test alien.cxx.syntax alien.inline.syntax | |
alien.marshall.syntax alien.marshall accessors kernel ; | |
IN: alien.cxx.syntax.tests | |
DELETE-C-LIBRARY: test | |
C-LIBRARY: test | |
COMPILE-AS-C++ | |
C-INCLUDE: <string> | |
C-TYPEDEF: std::string string | |
C++-CLASS: std::string c++-root | |
GENERIC: to-string ( obj -- str ) | |
C++-METHOD: std::string to-string const-char* c_str ( ) | |
CM-FUNCTION: std::string* new_string ( const-char* s ) | |
return new std::string(s); | |
; | |
;C-LIBRARY | |
ALIAS: <std::string> new_string | |
{ 1 1 } [ new_string ] must-infer-as | |
{ 1 1 } [ c_str_std__string ] must-infer-as | |
[ t ] [ "abc" <std::string> std::string? ] unit-test | |
[ "abc" ] [ "abc" <std::string> to-string ] unit-test | |
DELETE-C-LIBRARY: inheritance | |
C-LIBRARY: inheritance | |
COMPILE-AS-C++ | |
C-INCLUDE: <cstring> | |
<RAW-C | |
class alpha { | |
public: | |
alpha(const char* s) { | |
str = s; | |
}; | |
const char* render() { | |
return str; | |
}; | |
virtual const char* chop() { | |
return str; | |
}; | |
virtual int length() { | |
return strlen(str); | |
}; | |
const char* str; | |
}; | |
class beta : alpha { | |
public: | |
beta(const char* s) : alpha(s + 1) { }; | |
const char* render() { | |
return str + 1; | |
}; | |
virtual const char* chop() { | |
return str + 2; | |
}; | |
}; | |
RAW-C> | |
C++-CLASS: alpha c++-root | |
C++-CLASS: beta alpha | |
CM-FUNCTION: alpha* new_alpha ( const-char* s ) | |
return new alpha(s); | |
; | |
CM-FUNCTION: beta* new_beta ( const-char* s ) | |
return new beta(s); | |
; | |
ALIAS: <alpha> new_alpha | |
ALIAS: <beta> new_beta | |
GENERIC: render ( obj -- obj ) | |
GENERIC: chop ( obj -- obj ) | |
GENERIC: length ( obj -- n ) | |
C++-METHOD: alpha render const-char* render ( ) | |
C++-METHOD: beta render const-char* render ( ) | |
C++-VIRTUAL: alpha chop const-char* chop ( ) | |
C++-VIRTUAL: beta chop const-char* chop ( ) | |
C++-VIRTUAL: alpha length int length ( ) | |
;C-LIBRARY | |
{ 1 1 } [ render_alpha ] must-infer-as | |
{ 1 1 } [ chop_beta ] must-infer-as | |
{ 1 1 } [ length_alpha ] must-infer-as | |
[ t ] [ "x" <alpha> alpha#? ] unit-test | |
[ t ] [ "x" <alpha> alpha? ] unit-test | |
[ t ] [ "x" <beta> alpha? ] unit-test | |
[ f ] [ "x" <beta> alpha#? ] unit-test | |
[ 5 ] [ "hello" <alpha> length ] unit-test | |
[ 4 ] [ "hello" <beta> length ] unit-test | |
[ "hello" ] [ "hello" <alpha> render ] unit-test | |
[ "llo" ] [ "hello" <beta> render ] unit-test | |
[ "ello" ] [ "hello" <beta> underlying>> \ alpha# new swap >>underlying render ] unit-test | |
[ "hello" ] [ "hello" <alpha> chop ] unit-test | |
[ "lo" ] [ "hello" <beta> chop ] unit-test | |
[ "lo" ] [ "hello" <beta> underlying>> \ alpha# new swap >>underlying chop ] unit-test | |
]] | |
FILE: [[alien/cxx/syntax/authors.txt]] [[Jeremy Hughes | |
]] | |
FILE: [[alien/inline/types/types.factor]] [=[! Copyright (C) 2009 Jeremy Hughes. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: accessors alien.c-types assocs combinators.short-circuit | |
continuations effects fry kernel math memoize sequences | |
splitting strings peg.ebnf make words ; | |
IN: alien.inline.types | |
: cify-type ( str -- str' ) | |
dup word? [ name>> ] when | |
H{ { CHAR: - CHAR: space } } substitute ; | |
: factorize-type ( str -- str' ) | |
cify-type | |
"const " ?head drop | |
"unsigned " ?head [ "u" prepend ] when | |
"long " ?head [ "long" prepend ] when | |
" const" ?tail drop ; | |
: const-pointer? ( str -- ? ) | |
cify-type { [ " const" tail? ] [ "&" tail? ] } 1|| ; | |
: pointer-to-const? ( str -- ? ) | |
cify-type "const " head? ; | |
: template-class? ( str -- ? ) | |
[ CHAR: < = ] any? ; | |
MEMO: resolved-primitives ( -- seq ) | |
primitive-types [ resolve-typedef ] map ; | |
: primitive-type? ( type -- ? ) | |
[ | |
factorize-type resolve-typedef [ resolved-primitives ] dip | |
'[ _ = ] any? | |
] [ 2drop f ] recover ; | |
: pointer? ( type -- ? ) | |
factorize-type [ "*" tail? ] [ "&" tail? ] bi or ; | |
: type-sans-pointer ( type -- type' ) | |
factorize-type [ '[ _ = ] "*&" swap any? ] trim-tail ; | |
: pointer-to-primitive? ( type -- ? ) | |
factorize-type | |
{ [ pointer? ] [ type-sans-pointer primitive-type? ] } 1&& ; | |
: pointer-to-non-const-primitive? ( str -- ? ) | |
{ | |
[ pointer-to-const? not ] | |
[ factorize-type pointer-to-primitive? ] | |
} 1&& ; | |
: types-effect>params-return ( types effect -- params return ) | |
[ in>> zip ] | |
[ nip out>> dup length 0 > [ first ] [ drop "void" ] if ] | |
2bi ; | |
: annotate-effect ( types effect -- types effect' ) | |
[ in>> ] [ out>> ] bi [ | |
zip | |
[ over pointer-to-primitive? [ ">" prepend ] when ] | |
assoc-map unzip | |
] dip <effect> ; | |
TUPLE: c++-type name params ptr ; | |
C: <c++-type> c++-type | |
EBNF: (parse-c++-type) | |
dig = [0-9] | |
alpha = [a-zA-Z] | |
alphanum = [1-9a-zA-Z] | |
name = [_a-zA-Z] [_a-zA-Z1-9:]* => [[ first2 swap prefix >string ]] | |
ptr = [*&] => [[ empty? not ]] | |
param = "," " "* type " "* => [[ third ]] | |
params = "<" " "* type " "* param* ">" => [[ [ 4 swap nth ] [ third ] bi prefix ]] | |
type = name " "* params? " "* ptr? => [[ { 0 2 4 } [ swap nth ] with map first3 <c++-type> ]] | |
;EBNF | |
: parse-c++-type ( str -- c++-type ) | |
factorize-type (parse-c++-type) ; | |
DEFER: c++-type>string | |
: params>string ( params -- str ) | |
[ "<" % [ c++-type>string ] map "," join % ">" % ] "" make ; | |
: c++-type>string ( c++-type -- str ) | |
[ | |
[ name>> % ] | |
[ params>> [ params>string % ] when* ] | |
[ ptr>> [ "*" % ] when ] | |
tri | |
] "" make ; | |
GENERIC: c++-type ( obj -- c++-type/f ) | |
M: object c++-type drop f ; | |
M: c++-type c-type ; | |
]=] | |
FILE: [[alien/inline/types/authors.txt]] [[Jeremy Hughes | |
]] | |
FILE: [[alien/inline/inline.factor]] [[! Copyright (C) 2009 Jeremy Hughes. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: accessors alien.inline.compiler alien.inline.types | |
alien.libraries alien.parser arrays assocs effects fry | |
generalizations grouping io.directories io.files | |
io.files.info io.files.temp kernel lexer math math.order | |
math.ranges multiline namespaces sequences source-files | |
splitting strings system vocabs.loader vocabs.parser words | |
alien.c-types alien.structs make parser continuations ; | |
IN: alien.inline | |
SYMBOL: c-library | |
SYMBOL: library-is-c++ | |
SYMBOL: linker-args | |
SYMBOL: c-strings | |
<PRIVATE | |
: cleanup-variables ( -- ) | |
{ c-library library-is-c++ linker-args c-strings } | |
[ off ] each ; | |
: arg-list ( types -- params ) | |
CHAR: a swap length CHAR: a + [a,b] | |
[ 1string ] map ; | |
: compile-library? ( -- ? ) | |
c-library get library-path dup exists? [ | |
file get [ | |
path>> | |
[ file-info modified>> ] bi@ <=> +lt+ = | |
] [ drop t ] if* | |
] [ drop t ] if ; | |
: compile-library ( -- ) | |
library-is-c++ get [ C++ ] [ C ] if | |
linker-args get | |
c-strings get "\n" join | |
c-library get compile-to-library ; | |
: c-library-name ( name -- name' ) | |
[ current-vocab name>> % "_" % % ] "" make ; | |
PRIVATE> | |
: parse-arglist ( parameters return -- types effect ) | |
[ 2 group unzip [ "," ?tail drop ] map ] | |
[ [ { } ] [ 1array ] if-void ] | |
bi* <effect> ; | |
: append-function-body ( prototype-str body -- str ) | |
[ swap % " {\n" % % "\n}\n" % ] "" make ; | |
: function-types-effect ( -- function types effect ) | |
scan scan swap ")" parse-tokens | |
[ "(" subseq? ] reject swap parse-arglist ; | |
: prototype-string ( function types effect -- str ) | |
[ [ cify-type ] map ] dip | |
types-effect>params-return cify-type -rot | |
[ " " join ] map ", " join | |
"(" prepend ")" append 3array " " join | |
library-is-c++ get [ "extern \"C\" " prepend ] when ; | |
: prototype-string' ( function types return -- str ) | |
[ dup arg-list ] <effect> prototype-string ; | |
: factor-function ( function types effect -- word quot effect ) | |
annotate-effect [ c-library get ] 3dip | |
[ [ factorize-type ] map ] dip | |
types-effect>params-return factorize-type -roll | |
concat make-function ; | |
: define-c-library ( name -- ) | |
c-library-name [ c-library set ] [ "c-library" set ] bi | |
V{ } clone c-strings set | |
V{ } clone linker-args set ; | |
: compile-c-library ( -- ) | |
compile-library? [ compile-library ] when | |
c-library get dup library-path cdecl add-library ; | |
: define-c-function ( function types effect body -- ) | |
[ | |
[ factor-function define-declared ] | |
[ prototype-string ] 3bi | |
] dip append-function-body c-strings get push ; | |
: define-c-function' ( function effect body -- ) | |
[ | |
[ in>> ] keep | |
[ factor-function define-declared ] | |
[ out>> prototype-string' ] 3bi | |
] dip append-function-body c-strings get push ; | |
: c-link-to ( str -- ) | |
"-l" prepend linker-args get push ; | |
: c-use-framework ( str -- ) | |
"-framework" swap linker-args get '[ _ push ] bi@ ; | |
: c-link-to/use-framework ( str -- ) | |
os macosx? [ c-use-framework ] [ c-link-to ] if ; | |
: c-include ( str -- ) | |
"#include " prepend c-strings get push ; | |
: define-c-typedef ( old new -- ) | |
[ typedef ] [ | |
[ swap "typedef " % % " " % % ";" % ] | |
"" make c-strings get push | |
] 2bi ; | |
: define-c-struct ( name fields -- ) | |
[ current-vocab swap define-struct ] [ | |
over | |
[ | |
"typedef struct " % "_" % % " {\n" % | |
[ first2 swap % " " % % ";\n" % ] each | |
"} " % % ";\n" % | |
] "" make c-strings get push | |
] 2bi ; | |
: delete-inline-library ( name -- ) | |
c-library-name [ remove-library ] | |
[ library-path dup exists? [ delete-file ] [ drop ] if ] bi ; | |
: with-c-library ( name quot -- ) | |
[ [ define-c-library ] dip call compile-c-library ] | |
[ cleanup-variables ] [ ] cleanup ; inline | |
: raw-c ( str -- ) | |
[ "\n" % % "\n" % ] "" make c-strings get push ; | |
]] | |
FILE: [[alien/inline/inline-docs.factor]] [[! Copyright (C) 2009 Jeremy Hughes. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: help.markup help.syntax kernel strings effects quotations ; | |
IN: alien.inline | |
<PRIVATE | |
: $binding-note ( x -- ) | |
drop | |
{ "This word requires that certain variables are correctly bound. " | |
"Call " { $link POSTPONE: define-c-library } " to set them up." } print-element ; | |
PRIVATE> | |
HELP: compile-c-library | |
{ $description "Writes, compiles, and links code generated since last invocation of " { $link POSTPONE: define-c-library } ". " | |
"Also calls " { $snippet "add-library" } ". " | |
"This word does nothing if the shared library is younger than the factor source file." } | |
{ $notes $binding-note } ; | |
HELP: c-use-framework | |
{ $values | |
{ "str" string } | |
} | |
{ $description "OS X only. Adds " { $snippet "-framework name" } " to linker command." } | |
{ $notes $binding-note } | |
{ $see-also c-link-to c-link-to/use-framework } ; | |
HELP: define-c-function | |
{ $values | |
{ "function" "function name" } { "types" "a sequence of C types" } { "effect" effect } { "body" string } | |
} | |
{ $description "Defines a C function and a factor word which calls it." } | |
{ $notes | |
{ $list | |
{ "The number of " { $snippet "types" } " must match the " { $snippet "in" } " count of the " { $snippet "effect" } "." } | |
{ "There must be only one " { $snippet "out" } " element. It must be a legal C return type with dashes (-) instead of spaces." } | |
$binding-note | |
} | |
} | |
{ $see-also POSTPONE: define-c-function' } ; | |
HELP: define-c-function' | |
{ $values | |
{ "function" "function name" } { "effect" effect } { "body" string } | |
} | |
{ $description "Defines a C function and a factor word which calls it. See " { $link define-c-function } " for more information." } | |
{ $notes | |
{ $list | |
{ "Each effect element must be a legal C type with dashes (-) instead of spaces. " | |
"C argument names will be generated alphabetically, starting with " { $snippet "a" } "." } | |
$binding-note | |
} | |
} | |
{ $see-also define-c-function } ; | |
HELP: c-include | |
{ $values | |
{ "str" string } | |
} | |
{ $description "Appends an include line to the C library in scope." } | |
{ $notes $binding-note } ; | |
HELP: define-c-library | |
{ $values | |
{ "name" string } | |
} | |
{ $description "Starts a new C library scope. Other " { $snippet "alien.inline" } " words can be used after this one." } ; | |
HELP: c-link-to | |
{ $values | |
{ "str" string } | |
} | |
{ $description "Adds " { $snippet "-lname" } " to linker command." } | |
{ $notes $binding-note } | |
{ $see-also c-use-framework c-link-to/use-framework } ; | |
HELP: c-link-to/use-framework | |
{ $values | |
{ "str" string } | |
} | |
{ $description "Equivalent to " { $link c-use-framework } " on OS X and " { $link c-link-to } " everywhere else." } | |
{ $notes $binding-note } | |
{ $see-also c-link-to c-use-framework } ; | |
HELP: define-c-struct | |
{ $values | |
{ "name" string } { "fields" "type/name pairs" } | |
} | |
{ $description "Defines a C struct and factor words which operate on it." } | |
{ $notes $binding-note } ; | |
HELP: define-c-typedef | |
{ $values | |
{ "old" "C type" } { "new" "C type" } | |
} | |
{ $description "Define C and factor typedefs." } | |
{ $notes $binding-note } ; | |
HELP: delete-inline-library | |
{ $values | |
{ "name" string } | |
} | |
{ $description "Delete the shared library file corresponding to " { $snippet "name" } "." } | |
{ $notes "Must be executed in the vocabulary where " { $snippet "name" } " is defined. " } ; | |
HELP: with-c-library | |
{ $values | |
{ "name" string } { "quot" quotation } | |
} | |
{ $description "Calls " { $link define-c-library } ", then the quotation, then " { $link compile-c-library } ", then sets all variables bound by " { $snippet "define-c-library" } " to " { $snippet "f" } "." } ; | |
HELP: raw-c | |
{ $values { "str" string } } | |
{ $description "Insert a string into the generated source file. Useful for macros and other details not implemented in " { $snippet "alien.inline" } "." } ; | |
]] | |
FILE: [[alien/inline/authors.txt]] [[Jeremy Hughes | |
]] | |
FILE: [[alien/inline/syntax/syntax.factor]] [[! Copyright (C) 2009 Jeremy Hughes. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: alien.inline lexer multiline namespaces parser ; | |
IN: alien.inline.syntax | |
SYNTAX: C-LIBRARY: scan define-c-library ; | |
SYNTAX: COMPILE-AS-C++ t library-is-c++ set ; | |
SYNTAX: C-LINK: scan c-link-to ; | |
SYNTAX: C-FRAMEWORK: scan c-use-framework ; | |
SYNTAX: C-LINK/FRAMEWORK: scan c-link-to/use-framework ; | |
SYNTAX: C-INCLUDE: scan c-include ; | |
SYNTAX: C-FUNCTION: | |
function-types-effect parse-here define-c-function ; | |
SYNTAX: C-TYPEDEF: scan scan define-c-typedef ; | |
SYNTAX: C-STRUCTURE: | |
scan parse-definition define-c-struct ; | |
SYNTAX: ;C-LIBRARY compile-c-library ; | |
SYNTAX: DELETE-C-LIBRARY: scan delete-inline-library ; | |
SYNTAX: <RAW-C "RAW-C>" parse-multiline-string raw-c ; | |
]] | |
FILE: [[alien/inline/syntax/syntax-tests.factor]] [[! Copyright (C) 2009 Jeremy Hughes. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: alien.inline alien.inline.syntax io.directories io.files | |
kernel namespaces tools.test alien.c-types alien.data alien.structs ; | |
IN: alien.inline.syntax.tests | |
DELETE-C-LIBRARY: test | |
C-LIBRARY: test | |
C-FUNCTION: const-int add ( int a, int b ) | |
return a + b; | |
; | |
C-TYPEDEF: double bigfloat | |
C-FUNCTION: bigfloat smaller ( bigfloat a ) | |
return a / 10; | |
; | |
C-STRUCTURE: rectangle | |
{ "int" "width" } | |
{ "int" "height" } ; | |
C-FUNCTION: int area ( rectangle c ) | |
return c.width * c.height; | |
; | |
;C-LIBRARY | |
{ 2 1 } [ add ] must-infer-as | |
[ 5 ] [ 2 3 add ] unit-test | |
[ t ] [ "double" "bigfloat" [ resolve-typedef ] same? ] unit-test | |
{ 1 1 } [ smaller ] must-infer-as | |
[ 1.0 ] [ 10 smaller ] unit-test | |
[ t ] [ "rectangle" resolve-typedef struct-type? ] unit-test | |
{ 1 1 } [ area ] must-infer-as | |
[ 20 ] [ | |
"rectangle" <c-object> | |
4 over set-rectangle-width | |
5 over set-rectangle-height | |
area | |
] unit-test | |
DELETE-C-LIBRARY: cpplib | |
C-LIBRARY: cpplib | |
COMPILE-AS-C++ | |
C-INCLUDE: <string> | |
C-FUNCTION: const-char* hello ( ) | |
std::string s("hello world"); | |
return s.c_str(); | |
; | |
;C-LIBRARY | |
{ 0 1 } [ hello ] must-infer-as | |
[ "hello world" ] [ hello ] unit-test | |
DELETE-C-LIBRARY: compile-error | |
C-LIBRARY: compile-error | |
C-FUNCTION: char* breakme ( ) | |
return not a string; | |
; | |
<< [ compile-c-library ] must-fail >> | |
]] | |
FILE: [[alien/inline/syntax/authors.txt]] [[Jeremy Hughes | |
]] | |
FILE: [[alien/inline/syntax/syntax-docs.factor]] [[! Copyright (C) 2009 Jeremy Hughes. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: help.markup help.syntax alien.inline ; | |
IN: alien.inline.syntax | |
HELP: ;C-LIBRARY | |
{ $syntax ";C-LIBRARY" } | |
{ $description "Writes, compiles, and links code generated since previous invocation of " { $link POSTPONE: C-LIBRARY: } "." } | |
{ $see-also POSTPONE: compile-c-library } ; | |
HELP: C-FRAMEWORK: | |
{ $syntax "C-FRAMEWORK: name" } | |
{ $description "OS X only. Link to named framework. Takes effect when " { $link POSTPONE: ;C-LIBRARY } " is called." } | |
{ $see-also POSTPONE: c-use-framework } ; | |
HELP: C-FUNCTION: | |
{ $syntax "C-FUNCTION: return name ( args ... )\nbody\n;" } | |
{ $description "Appends a function to the C library in scope and defines an FFI word that calls it." } | |
{ $examples | |
{ $example | |
"USING: alien.inline.syntax prettyprint ;" | |
"IN: cmath.ffi" | |
"" | |
"C-LIBRARY: cmathlib" | |
"" | |
"C-FUNCTION: int add ( int a, int b )" | |
" return a + b;" | |
";" | |
"" | |
";C-LIBRARY" | |
"" | |
"1 2 add ." | |
"3" } | |
} | |
{ $see-also POSTPONE: define-c-function } ; | |
HELP: C-INCLUDE: | |
{ $syntax "C-INCLUDE: name" } | |
{ $description "Appends an include line to the C library in scope." } | |
{ $see-also POSTPONE: c-include } ; | |
HELP: C-LIBRARY: | |
{ $syntax "C-LIBRARY: name" } | |
{ $description "Starts a new C library scope. Other " { $snippet "alien.inline" } " syntax can be used after this word." } | |
{ $examples | |
{ $example | |
"USING: alien.inline.syntax ;" | |
"IN: rectangle.ffi" | |
"" | |
"C-LIBRARY: rectlib" | |
"" | |
"C-STRUCTURE: rectangle { \"int\" \"width\" } { \"int\" \"height\" } ;" | |
"" | |
"C-FUNCTION: int area ( rectangle c )" | |
" return c.width * c.height;" | |
";" | |
"" | |
";C-LIBRARY" | |
"" } | |
} | |
{ $see-also POSTPONE: define-c-library } ; | |
HELP: C-LINK/FRAMEWORK: | |
{ $syntax "C-LINK/FRAMEWORK: name" } | |
{ $description "Equivalent to " { $link POSTPONE: C-FRAMEWORK: } " on OS X and " { $link POSTPONE: C-LINK: } " everywhere else." } | |
{ $see-also POSTPONE: c-link-to/use-framework } ; | |
HELP: C-LINK: | |
{ $syntax "C-LINK: name" } | |
{ $description "Link to named library. Takes effect when " { $link POSTPONE: ;C-LIBRARY } " is called." } | |
{ $see-also POSTPONE: c-link-to } ; | |
HELP: C-STRUCTURE: | |
{ $syntax "C-STRUCTURE: name pairs ... ;" } | |
{ $description "Like " { $snippet "C-STRUCT:" } " but also generates equivalent C code."} | |
{ $see-also POSTPONE: define-c-struct } ; | |
HELP: C-TYPEDEF: | |
{ $syntax "C-TYPEDEF: old new" } | |
{ $description "Like " { $snippet "TYPEDEF:" } " but generates a C typedef statement too." } | |
{ $see-also POSTPONE: define-c-typedef } ; | |
HELP: COMPILE-AS-C++ | |
{ $syntax "COMPILE-AS-C++" } | |
{ $description "Insert this word anywhere between " { $link POSTPONE: C-LIBRARY: } " and " { $link POSTPONE: ;C-LIBRARY } " and the generated code will be treated as C++ with " { $snippet "extern \"C\"" } " prepended to each function prototype." } ; | |
HELP: DELETE-C-LIBRARY: | |
{ $syntax "DELETE-C-LIBRARY: name" } | |
{ $description "Deletes the shared library file corresponding to " { $snippet "name" } " . " } | |
{ $notes | |
{ $list | |
{ "Must be executed in the vocabulary where " { $snippet "name" } " is defined. " } | |
"This word is mainly useful for unit tests." | |
} | |
} | |
{ $see-also POSTPONE: delete-inline-library } ; | |
HELP: <RAW-C | |
{ $syntax "<RAW-C code RAW-C>" } | |
{ $description "Insert a (multiline) string into the generated source file. Useful for macros and other details not implemented in " { $snippet "alien.inline" } "." } ; | |
]] | |
FILE: [[alien/inline/compiler/compiler.factor]] [[! Copyright (C) 2009 Jeremy Hughes. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: accessors arrays combinators fry generalizations | |
io.encodings.ascii io.files io.files.temp io.launcher kernel | |
locals make sequences system vocabs.parser words io.directories | |
io.pathnames ; | |
IN: alien.inline.compiler | |
SYMBOL: C | |
SYMBOL: C++ | |
: inline-libs-directory ( -- path ) | |
"alien-inline-libs" resource-path dup make-directories ; | |
: inline-library-file ( name -- path ) | |
inline-libs-directory prepend-path ; | |
: library-suffix ( -- str ) | |
os { | |
{ [ dup macosx? ] [ drop ".dylib" ] } | |
{ [ dup unix? ] [ drop ".so" ] } | |
{ [ dup windows? ] [ drop ".dll" ] } | |
} cond ; | |
: library-path ( str -- path ) | |
'[ "lib" % _ % library-suffix % ] "" make inline-library-file ; | |
HOOK: compiler os ( lang -- str ) | |
M: word compiler | |
{ | |
{ C [ "gcc" ] } | |
{ C++ [ "g++" ] } | |
} case ; | |
M: openbsd compiler | |
{ | |
{ C [ "gcc" ] } | |
{ C++ [ "eg++" ] } | |
} case ; | |
M: windows compiler | |
{ | |
{ C [ "gcc" ] } | |
{ C++ [ "g++" ] } | |
} case ; | |
HOOK: compiler-descr os ( lang -- descr ) | |
M: word compiler-descr compiler 1array ; | |
M: macosx compiler-descr | |
call-next-method cpu x86.64? | |
[ { "-arch" "x86_64" } append ] when ; | |
HOOK: link-descr os ( lang -- descr ) | |
M: word link-descr drop { "-shared" "-o" } ; | |
M: macosx link-descr | |
drop { "-g" "-prebind" "-dynamiclib" "-o" } | |
cpu x86.64? [ { "-arch" "x86_64" } prepend ] when ; | |
M: windows link-descr | |
{ | |
{ C [ { "-mno-cygwin" "-shared" "-o" } ] } | |
{ C++ [ { "-lstdc++" "-mno-cygwin" "-shared" "-o" } ] } | |
} case ; | |
<PRIVATE | |
: src-suffix ( lang -- str ) | |
{ | |
{ C [ ".c" ] } | |
{ C++ [ ".cpp" ] } | |
} case ; | |
: link-command ( args in out lang -- descr ) | |
[ 2array ] dip [ compiler 1array ] [ link-descr ] bi | |
append prepend prepend ; | |
:: compile-to-object ( lang contents name -- ) | |
name ".o" append temp-file | |
contents name lang src-suffix append temp-file | |
[ ascii set-file-contents ] keep 2array | |
lang compiler-descr { "-fPIC" "-c" "-o" } append prepend | |
try-process ; | |
:: link-object ( lang args name -- ) | |
args name [ library-path ] | |
[ ".o" append temp-file ] bi | |
lang link-command try-process ; | |
PRIVATE> | |
:: compile-to-library ( lang args contents name -- ) | |
lang contents name compile-to-object | |
lang args name link-object ; | |
]] | |
FILE: [[alien/inline/compiler/authors.txt]] [[Jeremy Hughes | |
]] | |
FILE: [[alien/inline/compiler/compiler-docs.factor]] [[! Copyright (C) 2009 Jeremy Hughes. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: help.markup help.syntax kernel strings words.symbol sequences ; | |
IN: alien.inline.compiler | |
HELP: C | |
{ $var-description "A symbol representing C source." } ; | |
HELP: C++ | |
{ $var-description "A symbol representing C++ source." } ; | |
HELP: compile-to-library | |
{ $values | |
{ "lang" symbol } { "args" sequence } { "contents" string } { "name" string } | |
} | |
{ $description "Compiles and links " { $snippet "contents" } " into a shared library called " { $snippet "libname.suffix" } | |
"in " { $snippet "resource:alien-inline-libs" } ". " { $snippet "suffix" } " is OS specific. " | |
{ $snippet "args" } " is a sequence of arguments for the linking stage." } | |
{ $notes | |
{ $list | |
"C and C++ are the only supported languages." | |
{ "Source and object files are placed in " { $snippet "resource:temp" } "." } } | |
} ; | |
HELP: compiler | |
{ $values | |
{ "lang" symbol } | |
{ "str" string } | |
} | |
{ $description "Returns a compiler name based on OS and source language." } | |
{ $see-also compiler-descr } ; | |
HELP: compiler-descr | |
{ $values | |
{ "lang" symbol } | |
{ "descr" "a process description" } | |
} | |
{ $description "Returns a compiler process description based on OS and source language." } | |
{ $see-also compiler } ; | |
HELP: inline-library-file | |
{ $values | |
{ "name" string } | |
{ "path" "a pathname string" } | |
} | |
{ $description "Appends " { $snippet "name" } " to the " { $link inline-libs-directory } "." } ; | |
HELP: inline-libs-directory | |
{ $values | |
{ "path" "a pathname string" } | |
} | |
{ $description "The directory where libraries created using " { $snippet "alien.inline" } " are stored." } ; | |
HELP: library-path | |
{ $values | |
{ "str" string } | |
{ "path" "a pathname string" } | |
} | |
{ $description "Converts " { $snippet "name" } " into a full path to the corresponding inline library." } ; | |
HELP: library-suffix | |
{ $values | |
{ "str" string } | |
} | |
{ $description "The appropriate shared library suffix for the current OS." } ; | |
HELP: link-descr | |
{ $values | |
{ "lang" "a language" } | |
{ "descr" sequence } | |
} | |
{ $description "Returns part of a process description. OS dependent." } ; | |
ARTICLE: "alien.inline.compiler" "Inline C compiler" | |
{ $vocab-link "alien.inline.compiler" } | |
; | |
ABOUT: "alien.inline.compiler" | |
]] | |
FILE: [[alien/marshall/marshall.factor]] [[! Copyright (C) 2009 Jeremy Hughes. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: accessors alien alien.c-types alien.inline.types | |
alien.marshall.private alien.strings byte-arrays classes | |
combinators combinators.short-circuit destructors fry | |
io.encodings.utf8 kernel libc sequences alien.data | |
specialized-arrays strings unix.utilities vocabs.parser | |
words libc.private locals generalizations math ; | |
FROM: alien.c-types => float short ; | |
SPECIALIZED-ARRAY: bool | |
SPECIALIZED-ARRAY: char | |
SPECIALIZED-ARRAY: double | |
SPECIALIZED-ARRAY: float | |
SPECIALIZED-ARRAY: int | |
SPECIALIZED-ARRAY: long | |
SPECIALIZED-ARRAY: longlong | |
SPECIALIZED-ARRAY: short | |
SPECIALIZED-ARRAY: uchar | |
SPECIALIZED-ARRAY: uint | |
SPECIALIZED-ARRAY: ulong | |
SPECIALIZED-ARRAY: ulonglong | |
SPECIALIZED-ARRAY: ushort | |
SPECIALIZED-ARRAY: void* | |
IN: alien.marshall | |
<< primitive-types [ [ void* = ] [ bool = ] bi or not ] | |
filter [ define-primitive-marshallers ] each >> | |
TUPLE: alien-wrapper { underlying alien } ; | |
TUPLE: struct-wrapper < alien-wrapper disposed ; | |
TUPLE: class-wrapper < alien-wrapper disposed ; | |
MIXIN: c++-root | |
GENERIC: unmarshall-cast ( alien-wrapper -- alien-wrapper' ) | |
M: alien-wrapper unmarshall-cast ; | |
M: struct-wrapper unmarshall-cast ; | |
M: struct-wrapper dispose* underlying>> free ; | |
M: class-wrapper c++-type class name>> parse-c++-type ; | |
: marshall-pointer ( obj -- alien ) | |
{ | |
{ [ dup alien? ] [ ] } | |
{ [ dup not ] [ ] } | |
{ [ dup byte-array? ] [ malloc-byte-array ] } | |
{ [ dup alien-wrapper? ] [ underlying>> ] } | |
} cond ; | |
: marshall-primitive ( n -- n ) | |
[ bool>arg ] ptr-pass-through ; | |
ALIAS: marshall-void* marshall-pointer | |
: marshall-void** ( seq -- alien ) | |
[ marshall-void* ] void*-array{ } map-as malloc-underlying ; | |
: (marshall-char*-or-string) ( n/string -- alien ) | |
dup string? | |
[ utf8 string>alien malloc-byte-array ] | |
[ (marshall-char*) ] if ; | |
: marshall-char*-or-string ( n/string -- alien ) | |
[ (marshall-char*-or-string) ] ptr-pass-through ; | |
: (marshall-char**-or-strings) ( seq -- alien ) | |
[ marshall-char*-or-string ] void*-array{ } map-as | |
malloc-underlying ; | |
: marshall-char**-or-strings ( seq -- alien ) | |
[ (marshall-char**-or-strings) ] ptr-pass-through ; | |
: marshall-bool ( ? -- n ) | |
>boolean [ 1 ] [ 0 ] if ; | |
: (marshall-bool*) ( ?/seq -- alien ) | |
[ marshall-bool <bool> malloc-byte-array ] | |
[ >bool-array malloc-underlying ] | |
marshall-x* ; | |
: marshall-bool* ( ?/seq -- alien ) | |
[ (marshall-bool*) ] ptr-pass-through ; | |
: (marshall-bool**) ( seq -- alien ) | |
[ marshall-bool* ] map >void*-array malloc-underlying ; | |
: marshall-bool** ( seq -- alien ) | |
[ (marshall-bool**) ] ptr-pass-through ; | |
: unmarshall-bool ( n -- ? ) | |
0 = not ; | |
: unmarshall-bool* ( alien -- ? ) | |
*bool unmarshall-bool ; | |
: unmarshall-bool*-free ( alien -- ? ) | |
[ *bool unmarshall-bool ] keep add-malloc free ; | |
: primitive-marshaller ( type -- quot/f ) | |
{ | |
{ "bool" [ [ ] ] } | |
{ "boolean" [ [ marshall-bool ] ] } | |
{ "char" [ [ marshall-primitive ] ] } | |
{ "uchar" [ [ marshall-primitive ] ] } | |
{ "short" [ [ marshall-primitive ] ] } | |
{ "ushort" [ [ marshall-primitive ] ] } | |
{ "int" [ [ marshall-primitive ] ] } | |
{ "uint" [ [ marshall-primitive ] ] } | |
{ "long" [ [ marshall-primitive ] ] } | |
{ "ulong" [ [ marshall-primitive ] ] } | |
{ "long" [ [ marshall-primitive ] ] } | |
{ "ulong" [ [ marshall-primitive ] ] } | |
{ "float" [ [ marshall-primitive ] ] } | |
{ "double" [ [ marshall-primitive ] ] } | |
{ "bool*" [ [ marshall-bool* ] ] } | |
{ "boolean*" [ [ marshall-bool* ] ] } | |
{ "char*" [ [ marshall-char*-or-string ] ] } | |
{ "uchar*" [ [ marshall-uchar* ] ] } | |
{ "short*" [ [ marshall-short* ] ] } | |
{ "ushort*" [ [ marshall-ushort* ] ] } | |
{ "int*" [ [ marshall-int* ] ] } | |
{ "uint*" [ [ marshall-uint* ] ] } | |
{ "long*" [ [ marshall-long* ] ] } | |
{ "ulong*" [ [ marshall-ulong* ] ] } | |
{ "longlong*" [ [ marshall-longlong* ] ] } | |
{ "ulonglong*" [ [ marshall-ulonglong* ] ] } | |
{ "float*" [ [ marshall-float* ] ] } | |
{ "double*" [ [ marshall-double* ] ] } | |
{ "bool&" [ [ marshall-bool* ] ] } | |
{ "boolean&" [ [ marshall-bool* ] ] } | |
{ "char&" [ [ marshall-char* ] ] } | |
{ "uchar&" [ [ marshall-uchar* ] ] } | |
{ "short&" [ [ marshall-short* ] ] } | |
{ "ushort&" [ [ marshall-ushort* ] ] } | |
{ "int&" [ [ marshall-int* ] ] } | |
{ "uint&" [ [ marshall-uint* ] ] } | |
{ "long&" [ [ marshall-long* ] ] } | |
{ "ulong&" [ [ marshall-ulong* ] ] } | |
{ "longlong&" [ [ marshall-longlong* ] ] } | |
{ "ulonglong&" [ [ marshall-ulonglong* ] ] } | |
{ "float&" [ [ marshall-float* ] ] } | |
{ "double&" [ [ marshall-double* ] ] } | |
{ "void*" [ [ marshall-void* ] ] } | |
{ "bool**" [ [ marshall-bool** ] ] } | |
{ "boolean**" [ [ marshall-bool** ] ] } | |
{ "char**" [ [ marshall-char**-or-strings ] ] } | |
{ "uchar**" [ [ marshall-uchar** ] ] } | |
{ "short**" [ [ marshall-short** ] ] } | |
{ "ushort**" [ [ marshall-ushort** ] ] } | |
{ "int**" [ [ marshall-int** ] ] } | |
{ "uint**" [ [ marshall-uint** ] ] } | |
{ "long**" [ [ marshall-long** ] ] } | |
{ "ulong**" [ [ marshall-ulong** ] ] } | |
{ "longlong**" [ [ marshall-longlong** ] ] } | |
{ "ulonglong**" [ [ marshall-ulonglong** ] ] } | |
{ "float**" [ [ marshall-float** ] ] } | |
{ "double**" [ [ marshall-double** ] ] } | |
{ "void**" [ [ marshall-void** ] ] } | |
[ drop f ] | |
} case ; | |
: marshall-non-pointer ( alien-wrapper/byte-array -- byte-array ) | |
{ | |
{ [ dup byte-array? ] [ ] } | |
{ [ dup alien-wrapper? ] | |
[ [ underlying>> ] [ class name>> heap-size ] bi | |
memory>byte-array ] } | |
} cond ; | |
: marshaller ( type -- quot ) | |
factorize-type dup primitive-marshaller [ nip ] [ | |
pointer? | |
[ [ marshall-pointer ] ] | |
[ [ marshall-non-pointer ] ] if | |
] if* ; | |
: unmarshall-char*-to-string ( alien -- string ) | |
utf8 alien>string ; | |
: unmarshall-char*-to-string-free ( alien -- string ) | |
[ unmarshall-char*-to-string ] keep add-malloc free ; | |
: primitive-unmarshaller ( type -- quot/f ) | |
{ | |
{ "bool" [ [ ] ] } | |
{ "boolean" [ [ unmarshall-bool ] ] } | |
{ "char" [ [ ] ] } | |
{ "uchar" [ [ ] ] } | |
{ "short" [ [ ] ] } | |
{ "ushort" [ [ ] ] } | |
{ "int" [ [ ] ] } | |
{ "uint" [ [ ] ] } | |
{ "long" [ [ ] ] } | |
{ "ulong" [ [ ] ] } | |
{ "longlong" [ [ ] ] } | |
{ "ulonglong" [ [ ] ] } | |
{ "float" [ [ ] ] } | |
{ "double" [ [ ] ] } | |
{ "bool*" [ [ unmarshall-bool*-free ] ] } | |
{ "boolean*" [ [ unmarshall-bool*-free ] ] } | |
{ "char*" [ [ ] ] } | |
{ "uchar*" [ [ unmarshall-uchar*-free ] ] } | |
{ "short*" [ [ unmarshall-short*-free ] ] } | |
{ "ushort*" [ [ unmarshall-ushort*-free ] ] } | |
{ "int*" [ [ unmarshall-int*-free ] ] } | |
{ "uint*" [ [ unmarshall-uint*-free ] ] } | |
{ "long*" [ [ unmarshall-long*-free ] ] } | |
{ "ulong*" [ [ unmarshall-ulong*-free ] ] } | |
{ "longlong*" [ [ unmarshall-long*-free ] ] } | |
{ "ulonglong*" [ [ unmarshall-ulong*-free ] ] } | |
{ "float*" [ [ unmarshall-float*-free ] ] } | |
{ "double*" [ [ unmarshall-double*-free ] ] } | |
{ "bool&" [ [ unmarshall-bool*-free ] ] } | |
{ "boolean&" [ [ unmarshall-bool*-free ] ] } | |
{ "char&" [ [ ] ] } | |
{ "uchar&" [ [ unmarshall-uchar*-free ] ] } | |
{ "short&" [ [ unmarshall-short*-free ] ] } | |
{ "ushort&" [ [ unmarshall-ushort*-free ] ] } | |
{ "int&" [ [ unmarshall-int*-free ] ] } | |
{ "uint&" [ [ unmarshall-uint*-free ] ] } | |
{ "long&" [ [ unmarshall-long*-free ] ] } | |
{ "ulong&" [ [ unmarshall-ulong*-free ] ] } | |
{ "longlong&" [ [ unmarshall-longlong*-free ] ] } | |
{ "ulonglong&" [ [ unmarshall-ulonglong*-free ] ] } | |
{ "float&" [ [ unmarshall-float*-free ] ] } | |
{ "double&" [ [ unmarshall-double*-free ] ] } | |
[ drop f ] | |
} case ; | |
: struct-primitive-unmarshaller ( type -- quot/f ) | |
{ | |
{ "bool" [ [ unmarshall-bool ] ] } | |
{ "boolean" [ [ unmarshall-bool ] ] } | |
{ "char" [ [ ] ] } | |
{ "uchar" [ [ ] ] } | |
{ "short" [ [ ] ] } | |
{ "ushort" [ [ ] ] } | |
{ "int" [ [ ] ] } | |
{ "uint" [ [ ] ] } | |
{ "long" [ [ ] ] } | |
{ "ulong" [ [ ] ] } | |
{ "longlong" [ [ ] ] } | |
{ "ulonglong" [ [ ] ] } | |
{ "float" [ [ ] ] } | |
{ "double" [ [ ] ] } | |
{ "bool*" [ [ unmarshall-bool* ] ] } | |
{ "boolean*" [ [ unmarshall-bool* ] ] } | |
{ "char*" [ [ ] ] } | |
{ "uchar*" [ [ unmarshall-uchar* ] ] } | |
{ "short*" [ [ unmarshall-short* ] ] } | |
{ "ushort*" [ [ unmarshall-ushort* ] ] } | |
{ "int*" [ [ unmarshall-int* ] ] } | |
{ "uint*" [ [ unmarshall-uint* ] ] } | |
{ "long*" [ [ unmarshall-long* ] ] } | |
{ "ulong*" [ [ unmarshall-ulong* ] ] } | |
{ "longlong*" [ [ unmarshall-long* ] ] } | |
{ "ulonglong*" [ [ unmarshall-ulong* ] ] } | |
{ "float*" [ [ unmarshall-float* ] ] } | |
{ "double*" [ [ unmarshall-double* ] ] } | |
{ "bool&" [ [ unmarshall-bool* ] ] } | |
{ "boolean&" [ [ unmarshall-bool* ] ] } | |
{ "char&" [ [ unmarshall-char* ] ] } | |
{ "uchar&" [ [ unmarshall-uchar* ] ] } | |
{ "short&" [ [ unmarshall-short* ] ] } | |
{ "ushort&" [ [ unmarshall-ushort* ] ] } | |
{ "int&" [ [ unmarshall-int* ] ] } | |
{ "uint&" [ [ unmarshall-uint* ] ] } | |
{ "long&" [ [ unmarshall-long* ] ] } | |
{ "ulong&" [ [ unmarshall-ulong* ] ] } | |
{ "longlong&" [ [ unmarshall-longlong* ] ] } | |
{ "ulonglong&" [ [ unmarshall-ulonglong* ] ] } | |
{ "float&" [ [ unmarshall-float* ] ] } | |
{ "double&" [ [ unmarshall-double* ] ] } | |
[ drop f ] | |
} case ; | |
: ?malloc-byte-array ( c-type -- alien ) | |
dup alien? [ malloc-byte-array ] unless ; | |
:: x-unmarshaller ( type type-quot superclass def clean -- quot/f ) | |
type type-quot call current-vocab lookup [ | |
dup superclasses superclass swap member? | |
[ def call ] [ drop clean call f ] if | |
] [ clean call f ] if* ; inline | |
: struct-unmarshaller ( type -- quot/f ) | |
[ ] \ struct-wrapper | |
[ '[ ?malloc-byte-array _ new swap >>underlying ] ] | |
[ ] | |
x-unmarshaller ; | |
: class-unmarshaller ( type -- quot/f ) | |
[ type-sans-pointer "#" append ] \ class-wrapper | |
[ '[ _ new swap >>underlying ] ] | |
[ ] | |
x-unmarshaller ; | |
: non-primitive-unmarshaller ( type -- quot/f ) | |
{ | |
{ [ dup pointer? ] [ class-unmarshaller ] } | |
[ struct-unmarshaller ] | |
} cond ; | |
: unmarshaller ( type -- quot ) | |
factorize-type { | |
[ primitive-unmarshaller ] | |
[ non-primitive-unmarshaller ] | |
[ drop [ ] ] | |
} 1|| ; | |
: struct-field-unmarshaller ( type -- quot ) | |
factorize-type { | |
[ struct-primitive-unmarshaller ] | |
[ non-primitive-unmarshaller ] | |
[ drop [ ] ] | |
} 1|| ; | |
: out-arg-unmarshaller ( type -- quot ) | |
dup pointer-to-non-const-primitive? | |
[ factorize-type primitive-unmarshaller ] | |
[ drop [ drop ] ] if ; | |
]] | |
FILE: [[alien/marshall/private/private.factor]] [[! Copyright (C) 2009 Jeremy Hughes. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: accessors alien alien.c-types alien.inline arrays | |
combinators fry functors kernel lexer libc macros math | |
sequences specialized-arrays libc.private | |
combinators.short-circuit alien.data ; | |
SPECIALIZED-ARRAY: void* | |
IN: alien.marshall.private | |
: bool>arg ( ? -- 1/0/obj ) | |
{ | |
{ t [ 1 ] } | |
{ f [ 0 ] } | |
[ ] | |
} case ; | |
MACRO: marshall-x* ( num-quot seq-quot -- alien ) | |
'[ bool>arg dup number? _ _ if ] ; | |
: ptr-pass-through ( obj quot -- alien ) | |
over { [ c-ptr? ] [ ] } 1&& [ drop ] [ call ] if ; inline | |
: malloc-underlying ( obj -- alien ) | |
underlying>> malloc-byte-array ; | |
FUNCTOR: define-primitive-marshallers ( TYPE -- ) | |
<TYPE> IS <${TYPE}> | |
*TYPE IS *${TYPE} | |
>TYPE-array IS >${TYPE}-array | |
marshall-TYPE DEFINES marshall-${TYPE} | |
(marshall-TYPE*) DEFINES (marshall-${TYPE}*) | |
(marshall-TYPE**) DEFINES (marshall-${TYPE}**) | |
marshall-TYPE* DEFINES marshall-${TYPE}* | |
marshall-TYPE** DEFINES marshall-${TYPE}** | |
marshall-TYPE*-free DEFINES marshall-${TYPE}*-free | |
marshall-TYPE**-free DEFINES marshall-${TYPE}**-free | |
unmarshall-TYPE* DEFINES unmarshall-${TYPE}* | |
unmarshall-TYPE*-free DEFINES unmarshall-${TYPE}*-free | |
WHERE | |
<PRIVATE | |
: (marshall-TYPE*) ( n/seq -- alien ) | |
[ <TYPE> malloc-byte-array ] | |
[ >TYPE-array malloc-underlying ] | |
marshall-x* ; | |
PRIVATE> | |
: marshall-TYPE* ( n/seq -- alien ) | |
[ (marshall-TYPE*) ] ptr-pass-through ; | |
<PRIVATE | |
: (marshall-TYPE**) ( seq -- alien ) | |
[ marshall-TYPE* ] void*-array{ } map-as malloc-underlying ; | |
PRIVATE> | |
: marshall-TYPE** ( seq -- alien ) | |
[ (marshall-TYPE**) ] ptr-pass-through ; | |
: unmarshall-TYPE* ( alien -- n ) | |
*TYPE ; inline | |
: unmarshall-TYPE*-free ( alien -- n ) | |
[ unmarshall-TYPE* ] keep add-malloc free ; | |
;FUNCTOR | |
SYNTAX: PRIMITIVE-MARSHALLERS: | |
";" parse-tokens [ define-primitive-marshallers ] each ; | |
]] | |
FILE: [[alien/marshall/private/authors.txt]] [[Jeremy Hughes | |
]] | |
FILE: [[alien/marshall/structs/structs-docs.factor]] [[! Copyright (C) 2009 Jeremy Hughes. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: classes help.markup help.syntax kernel quotations words | |
alien.marshall.structs strings alien.structs alien.marshall ; | |
IN: alien.marshall.structs | |
HELP: define-marshalled-struct | |
{ $values | |
{ "name" string } { "vocab" "a vocabulary specifier" } { "fields" "an alist" } | |
} | |
{ $description "Calls " { $link define-struct } " and " { $link define-struct-tuple } "." } ; | |
HELP: define-struct-tuple | |
{ $values | |
{ "name" string } | |
} | |
{ $description "Defines a subclass of " { $link struct-wrapper } ", a constructor, " | |
"and accessor words." | |
} ; | |
]] | |
FILE: [[alien/marshall/structs/structs.factor]] [[! Copyright (C) 2009 Jeremy Hughes. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: accessors alien.c-types alien.marshall arrays assocs | |
classes.tuple combinators destructors generalizations generic | |
kernel libc locals parser quotations sequences slots words | |
alien.structs lexer vocabs.parser fry effects alien.data ; | |
IN: alien.marshall.structs | |
<PRIVATE | |
: define-struct-accessor ( class name quot -- ) | |
[ "accessors" create create-method dup make-inline ] dip define ; | |
: define-struct-getter ( class name word type -- ) | |
[ ">>" append \ underlying>> ] 2dip | |
struct-field-unmarshaller \ call 4array >quotation | |
define-struct-accessor ; | |
: define-struct-setter ( class name word type -- ) | |
[ "<<" append ] 2dip | |
marshaller [ underlying>> ] \ bi* roll 4array >quotation | |
define-struct-accessor ; | |
: define-struct-accessors ( class name type reader writer -- ) | |
[ dup define-protocol-slot ] 3dip | |
[ drop swap define-struct-getter ] | |
[ nip swap define-struct-setter ] 5 nbi ; | |
: define-struct-constructor ( class -- ) | |
{ | |
[ name>> "<" prepend ">" append create-word-in ] | |
[ '[ _ new ] ] | |
[ name>> '[ _ malloc-struct >>underlying ] append ] | |
[ name>> 1array ] | |
} cleave { } swap <effect> define-declared ; | |
PRIVATE> | |
:: define-struct-tuple ( name -- ) | |
name create-word-in :> class | |
class struct-wrapper { } define-tuple-class | |
class define-struct-constructor | |
name c-type fields>> [ | |
class swap | |
{ | |
[ name>> H{ { CHAR: space CHAR: - } } substitute ] | |
[ type>> ] [ reader>> ] [ writer>> ] | |
} cleave define-struct-accessors | |
] each ; | |
: define-marshalled-struct ( name vocab fields -- ) | |
[ define-struct ] [ 2drop define-struct-tuple ] 3bi ; | |
]] | |
FILE: [[alien/marshall/structs/authors.txt]] [[Jeremy Hughes | |
]] | |
FILE: [[alien/marshall/marshall-docs.factor]] [[! Copyright (C) 2009 Jeremy Hughes. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: help.markup help.syntax kernel quotations sequences | |
strings alien alien.c-types alien.data math byte-arrays ; | |
IN: alien.marshall | |
<PRIVATE | |
: $memory-note ( arg -- ) | |
drop "This word returns a pointer to unmanaged memory." | |
print-element ; | |
: $c-ptr-note ( arg -- ) | |
drop "Does nothing if its argument is a non false c-ptr." | |
print-element ; | |
: $see-article ( arg -- ) | |
drop { "See " { $vocab-link "alien.inline" } "." } | |
print-element ; | |
PRIVATE> | |
HELP: ?malloc-byte-array | |
{ $values | |
{ "c-type" c-type } | |
{ "alien" alien } | |
} | |
{ $description "Does nothing if input is an alien, otherwise assumes it is a byte array and calls " | |
{ $snippet "malloc-byte-array" } "." | |
} | |
{ $notes $memory-note } ; | |
HELP: alien-wrapper | |
{ $var-description "For wrapping C pointers in a structure factor can dispatch on." } ; | |
HELP: unmarshall-cast | |
{ $values | |
{ "alien-wrapper" alien-wrapper } | |
{ "alien-wrapper'" alien-wrapper } | |
} | |
{ $description "Called immediately after unmarshalling. Useful for automatically casting to subtypes." } ; | |
HELP: marshall-bool | |
{ $values | |
{ "?" "a generalized boolean" } | |
{ "n" "0 or 1" } | |
} | |
{ $description "Marshalls objects to bool." } | |
{ $notes "Will treat " { $snippet "0" } " as " { $snippet "t" } "." } ; | |
HELP: marshall-bool* | |
{ $values | |
{ "?/seq" "t/f or sequence" } | |
{ "alien" alien } | |
} | |
{ $description "When the argument is a sequence, returns a pointer to an array of bool, " | |
"otherwise returns a pointer to a single bool value." | |
} | |
{ $notes { $list $c-ptr-note $memory-note } } ; | |
HELP: marshall-bool** | |
{ $values | |
{ "seq" sequence } | |
{ "alien" alien } | |
} | |
{ $description "Takes a one or two dimensional array of generalized booleans " | |
"and returns a pointer to the equivalent C structure." | |
} | |
{ $notes { $list $c-ptr-note $memory-note } } ; | |
HELP: marshall-primitive | |
{ $values | |
{ "n" number } | |
{ "n" number } | |
} | |
{ $description "Marshall numbers to C primitives." | |
$nl | |
"Factor marshalls numbers to primitives for FFI calls, so all " | |
"this word does is convert " { $snippet "t" } " to " { $snippet "1" } | |
", " { $snippet "f" } " to " { $snippet "0" } ", and lets anything else " | |
"pass through untouched." | |
} ; | |
HELP: marshall-char* | |
{ $values | |
{ "n/seq" "number or sequence" } | |
{ "alien" alien } | |
} | |
{ $description $see-article } | |
{ $notes { $list $c-ptr-note $memory-note } } ; | |
HELP: marshall-char** | |
{ $values | |
{ "seq" sequence } | |
{ "alien" alien } | |
} | |
{ $description $see-article } | |
{ $notes { $list $c-ptr-note $memory-note } } ; | |
HELP: marshall-char**-or-strings | |
{ $values | |
{ "seq" "a sequence of strings" } | |
{ "alien" alien } | |
} | |
{ $description "Marshalls an array of strings or characters to an array of C strings." } | |
{ $notes { $list $c-ptr-note $memory-note } } ; | |
HELP: marshall-char*-or-string | |
{ $values | |
{ "n/string" "a number or string" } | |
{ "alien" alien } | |
} | |
{ $description "Marshalls a string to a C string or a number to a pointer to " { $snippet "char" } "." } | |
{ $notes { $list $c-ptr-note $memory-note } } ; | |
HELP: marshall-double* | |
{ $values | |
{ "n/seq" "a number or sequence" } | |
{ "alien" alien } | |
} | |
{ $description $see-article } | |
{ $notes { $list $c-ptr-note $memory-note } } ; | |
HELP: marshall-double** | |
{ $values | |
{ "seq" sequence } | |
{ "alien" alien } | |
} | |
{ $description $see-article } | |
{ $notes { $list $c-ptr-note $memory-note } } ; | |
HELP: marshall-float* | |
{ $values | |
{ "n/seq" "a number or sequence" } | |
{ "alien" alien } | |
} | |
{ $description $see-article } | |
{ $notes { $list $c-ptr-note $memory-note } } ; | |
HELP: marshall-float** | |
{ $values | |
{ "seq" sequence } | |
{ "alien" alien } | |
} | |
{ $description $see-article } | |
{ $notes { $list $c-ptr-note $memory-note } } ; | |
HELP: marshall-int* | |
{ $values | |
{ "n/seq" "a number or sequence" } | |
{ "alien" alien } | |
} | |
{ $description $see-article } | |
{ $notes { $list $c-ptr-note $memory-note } } ; | |
HELP: marshall-int** | |
{ $values | |
{ "seq" sequence } | |
{ "alien" alien } | |
} | |
{ $description $see-article } | |
{ $notes { $list $c-ptr-note $memory-note } } ; | |
HELP: marshall-long* | |
{ $values | |
{ "n/seq" "a number or sequence" } | |
{ "alien" alien } | |
} | |
{ $description $see-article } | |
{ $notes { $list $c-ptr-note $memory-note } } ; | |
HELP: marshall-long** | |
{ $values | |
{ "seq" sequence } | |
{ "alien" alien } | |
} | |
{ $description $see-article } | |
{ $notes { $list $c-ptr-note $memory-note } } ; | |
HELP: marshall-longlong* | |
{ $values | |
{ "n/seq" "a number or sequence" } | |
{ "alien" alien } | |
} | |
{ $description $see-article } | |
{ $notes { $list $c-ptr-note $memory-note } } ; | |
HELP: marshall-longlong** | |
{ $values | |
{ "seq" sequence } | |
{ "alien" alien } | |
} | |
{ $description $see-article } | |
{ $notes { $list $c-ptr-note $memory-note } } ; | |
HELP: marshall-non-pointer | |
{ $values | |
{ "alien-wrapper/byte-array" "an alien-wrapper or byte-array" } | |
{ "byte-array" byte-array } | |
} | |
{ $description "Converts argument to a byte array." } | |
{ $notes "Not meant to be called directly. Use the output of " { $link marshaller } " instead." } ; | |
HELP: marshall-pointer | |
{ $values | |
{ "obj" object } | |
{ "alien" alien } | |
} | |
{ $description "Converts argument to a C pointer." } | |
{ $notes "Can marshall the following types: " { $snippet "alien, f, byte-array, alien-wrapper, struct-array" } "." } ; | |
HELP: marshall-short* | |
{ $values | |
{ "n/seq" "a number or sequence" } | |
{ "alien" alien } | |
} | |
{ $description $see-article } | |
{ $notes { $list $c-ptr-note $memory-note } } ; | |
HELP: marshall-short** | |
{ $values | |
{ "seq" sequence } | |
{ "alien" alien } | |
} | |
{ $description $see-article } | |
{ $notes { $list $c-ptr-note $memory-note } } ; | |
HELP: marshall-uchar* | |
{ $values | |
{ "n/seq" "a number or sequence" } | |
{ "alien" alien } | |
} | |
{ $description $see-article } | |
{ $notes { $list $c-ptr-note $memory-note } } ; | |
HELP: marshall-uchar** | |
{ $values | |
{ "seq" sequence } | |
{ "alien" alien } | |
} | |
{ $description $see-article } | |
{ $notes { $list $c-ptr-note $memory-note } } ; | |
HELP: marshall-uint* | |
{ $values | |
{ "n/seq" "a number or sequence" } | |
{ "alien" alien } | |
} | |
{ $description $see-article } | |
{ $notes { $list $c-ptr-note $memory-note } } ; | |
HELP: marshall-uint** | |
{ $values | |
{ "seq" sequence } | |
{ "alien" alien } | |
} | |
{ $description $see-article } | |
{ $notes { $list $c-ptr-note $memory-note } } ; | |
HELP: marshall-ulong* | |
{ $values | |
{ "n/seq" "a number or sequence" } | |
{ "alien" alien } | |
} | |
{ $description $see-article } | |
{ $notes { $list $c-ptr-note $memory-note } } ; | |
HELP: marshall-ulong** | |
{ $values | |
{ "seq" sequence } | |
{ "alien" alien } | |
} | |
{ $description $see-article } | |
{ $notes { $list $c-ptr-note $memory-note } } ; | |
HELP: marshall-ulonglong* | |
{ $values | |
{ "n/seq" "a number or sequence" } | |
{ "alien" alien } | |
} | |
{ $description $see-article } | |
{ $notes { $list $c-ptr-note $memory-note } } ; | |
HELP: marshall-ulonglong** | |
{ $values | |
{ "seq" sequence } | |
{ "alien" alien } | |
} | |
{ $description $see-article } | |
{ $notes { $list $c-ptr-note $memory-note } } ; | |
HELP: marshall-ushort* | |
{ $values | |
{ "n/seq" "a number or sequence" } | |
{ "alien" alien } | |
} | |
{ $description $see-article } | |
{ $notes { $list $c-ptr-note $memory-note } } ; | |
HELP: marshall-ushort** | |
{ $values | |
{ "seq" sequence } | |
{ "alien" alien } | |
} | |
{ $description $see-article } | |
{ $notes { $list $c-ptr-note $memory-note } } ; | |
HELP: marshall-void** | |
{ $values | |
{ "seq" sequence } | |
{ "alien" alien } | |
} | |
{ $description "Marshalls a sequence of objects to an array of pointers to void." } | |
{ $notes { $list $c-ptr-note $memory-note } } ; | |
HELP: marshaller | |
{ $values | |
{ "type" "a C type string" } | |
{ "quot" quotation } | |
} | |
{ $description "Given a C type, returns a quotation that will marshall its argument to that type." } ; | |
HELP: out-arg-unmarshaller | |
{ $values | |
{ "type" "a C type string" } | |
{ "quot" quotation } | |
} | |
{ $description "Like " { $link unmarshaller } " but returns an empty quotation " | |
"for all types except pointers to non-const primitives." | |
} ; | |
HELP: class-unmarshaller | |
{ $values | |
{ "type" " a C type string" } | |
{ "quot/f" quotation } | |
} | |
{ $description "If in the vocab in which this word is called, there is a subclass of " { $link alien-wrapper } | |
" named after the type argument, " { $snippet "pointer-unmarshaller" } " will return a quotation which " | |
"wraps its argument in an instance of that subclass. In any other case it returns an empty quotation." | |
} | |
{ $notes "Not meant to be called directly. Use the output of " { $link marshaller } " instead." } ; | |
HELP: primitive-marshaller | |
{ $values | |
{ "type" "a C type string" } | |
{ "quot/f" "a quotation or f" } | |
} | |
{ $description "Returns a quotation to marshall objects to the argument type." } | |
{ $notes "Not meant to be called directly. Use the output of " { $link marshaller } " instead." } ; | |
HELP: primitive-unmarshaller | |
{ $values | |
{ "type" "a C type string" } | |
{ "quot/f" "a quotation or f" } | |
} | |
{ $description "Returns a quotation to unmarshall objects from the argument type." } | |
{ $notes "Not meant to be called directly. Use the output of " { $link unmarshaller } " instead." } ; | |
HELP: struct-field-unmarshaller | |
{ $values | |
{ "type" "a C type string" } | |
{ "quot" quotation } | |
} | |
{ $description "Like " { $link unmarshaller } " but returns a quotation that " | |
"does not call " { $snippet "free" } " on its argument." | |
} | |
{ $notes "Not meant to be called directly. Use the output of " { $link unmarshaller } " instead." } ; | |
HELP: struct-primitive-unmarshaller | |
{ $values | |
{ "type" "a C type string" } | |
{ "quot/f" "a quotation or f" } | |
} | |
{ $description "Like " { $link primitive-unmarshaller } " but returns a quotation that " | |
"does not call " { $snippet "free" } " on its argument." } | |
{ $notes "Not meant to be called directly. Use the output of " { $link unmarshaller } " instead." } ; | |
HELP: struct-unmarshaller | |
{ $values | |
{ "type" "a C type string" } | |
{ "quot/f" quotation } | |
} | |
{ $description "Returns a quotation which wraps its argument in the subclass of " | |
{ $link struct-wrapper } " which matches the " { $snippet "type" } " arg." | |
} | |
{ $notes "Not meant to be called directly. Use the output of " { $link unmarshaller } " instead." } ; | |
HELP: struct-wrapper | |
{ $var-description "For wrapping C structs in a structure factor can dispatch on." } ; | |
HELP: unmarshall-bool | |
{ $values | |
{ "n" number } | |
{ "?" boolean } | |
} | |
{ $description "Unmarshalls a number to a boolean." } ; | |
HELP: unmarshall-bool* | |
{ $values | |
{ "alien" alien } | |
{ "?" boolean } | |
} | |
{ $description "Unmarshalls a C pointer to a boolean." } ; | |
HELP: unmarshall-bool*-free | |
{ $values | |
{ "alien" alien } | |
{ "?" boolean } | |
} | |
{ $description "Unmarshalls a C pointer to a boolean and frees the pointer." } ; | |
HELP: unmarshall-char* | |
{ $values | |
{ "alien" alien } | |
{ "n" number } | |
} | |
{ $description $see-article } ; | |
HELP: unmarshall-char*-free | |
{ $values | |
{ "alien" alien } | |
{ "n" number } | |
} | |
{ $description $see-article } ; | |
HELP: unmarshall-char*-to-string | |
{ $values | |
{ "alien" alien } | |
{ "string" string } | |
} | |
{ $description "Unmarshalls a " { $snippet "char" } " pointer to a factor string." } ; | |
HELP: unmarshall-char*-to-string-free | |
{ $values | |
{ "alien" alien } | |
{ "string" string } | |
} | |
{ $description "Unmarshalls a " { $snippet "char" } " pointer to a factor string and frees the pointer." } ; | |
HELP: unmarshall-double* | |
{ $values | |
{ "alien" alien } | |
{ "n" number } | |
} | |
{ $description $see-article } ; | |
HELP: unmarshall-double*-free | |
{ $values | |
{ "alien" alien } | |
{ "n" number } | |
} | |
{ $description $see-article } ; | |
HELP: unmarshall-float* | |
{ $values | |
{ "alien" alien } | |
{ "n" number } | |
} | |
{ $description $see-article } ; | |
HELP: unmarshall-float*-free | |
{ $values | |
{ "alien" alien } | |
{ "n" number } | |
} | |
{ $description $see-article } ; | |
HELP: unmarshall-int* | |
{ $values | |
{ "alien" alien } | |
{ "n" number } | |
} | |
{ $description $see-article } ; | |
HELP: unmarshall-int*-free | |
{ $values | |
{ "alien" alien } | |
{ "n" number } | |
} | |
{ $description $see-article } ; | |
HELP: unmarshall-long* | |
{ $values | |
{ "alien" alien } | |
{ "n" number } | |
} | |
{ $description $see-article } ; | |
HELP: unmarshall-long*-free | |
{ $values | |
{ "alien" alien } | |
{ "n" number } | |
} | |
{ $description $see-article } ; | |
HELP: unmarshall-longlong* | |
{ $values | |
{ "alien" alien } | |
{ "n" number } | |
} | |
{ $description $see-article } ; | |
HELP: unmarshall-longlong*-free | |
{ $values | |
{ "alien" alien } | |
{ "n" number } | |
} | |
{ $description $see-article } ; | |
HELP: unmarshall-short* | |
{ $values | |
{ "alien" alien } | |
{ "n" number } | |
} | |
{ $description $see-article } ; | |
HELP: unmarshall-short*-free | |
{ $values | |
{ "alien" alien } | |
{ "n" number } | |
} | |
{ $description $see-article } ; | |
HELP: unmarshall-uchar* | |
{ $values | |
{ "alien" alien } | |
{ "n" number } | |
} | |
{ $description $see-article } ; | |
HELP: unmarshall-uchar*-free | |
{ $values | |
{ "alien" alien } | |
{ "n" number } | |
} | |
{ $description $see-article } ; | |
HELP: unmarshall-uint* | |
{ $values | |
{ "alien" alien } | |
{ "n" number } | |
} | |
{ $description $see-article } ; | |
HELP: unmarshall-uint*-free | |
{ $values | |
{ "alien" alien } | |
{ "n" number } | |
} | |
{ $description $see-article } ; | |
HELP: unmarshall-ulong* | |
{ $values | |
{ "alien" alien } | |
{ "n" number } | |
} | |
{ $description $see-article } ; | |
HELP: unmarshall-ulong*-free | |
{ $values | |
{ "alien" alien } | |
{ "n" number } | |
} | |
{ $description $see-article } ; | |
HELP: unmarshall-ulonglong* | |
{ $values | |
{ "alien" alien } | |
{ "n" number } | |
} | |
{ $description $see-article } ; | |
HELP: unmarshall-ulonglong*-free | |
{ $values | |
{ "alien" alien } | |
{ "n" number } | |
} | |
{ $description $see-article } ; | |
HELP: unmarshall-ushort* | |
{ $values | |
{ "alien" alien } | |
{ "n" number } | |
} | |
{ $description $see-article } ; | |
HELP: unmarshall-ushort*-free | |
{ $values | |
{ "alien" alien } | |
{ "n" number } | |
} | |
{ $description $see-article } ; | |
HELP: unmarshaller | |
{ $values | |
{ "type" "a C type string" } | |
{ "quot" quotation } | |
} | |
{ $description "Given a C type, returns a quotation that will unmarshall values of that type." } ; | |
ARTICLE: "alien.marshall" "C marshalling" | |
{ $vocab-link "alien.marshall" } " provides alien wrappers and marshalling words for the " | |
"automatic marshalling and unmarshalling of C function arguments, return values, and output parameters." | |
{ $subheading "Important words" } | |
"Wrap an alien:" { $subsections alien-wrapper } | |
"Wrap a struct:" { $subsections struct-wrapper } | |
"Get the marshaller for a C type:" { $subsections marshaller } | |
"Get the unmarshaller for a C type:" { $subsections unmarshaller } | |
"Get the unmarshaller for an output parameter:" { $subsections out-arg-unmarshaller } | |
"Get the unmarshaller for a struct field:" { $subsections struct-field-unmarshaller } | |
$nl | |
"Other marshalling and unmarshalling words in this vocabulary are not intended to be " | |
"invoked directly." | |
$nl | |
"Most marshalling words allow non false c-ptrs to pass through unchanged." | |
{ $subheading "Primitive marshallers" } | |
{ $subsections marshall-primitive } "for marshalling primitive values." | |
{ $subsections marshall-int* } | |
"marshalls a number or sequence of numbers. If argument is a sequence, returns a pointer " | |
"to a C array, otherwise returns a pointer to a single value." | |
{ $subsections marshall-int** } | |
"marshalls a 1D or 2D array of numbers. Returns an array of pointers to arrays." | |
{ $subheading "Primitive unmarshallers" } | |
{ $snippet "unmarshall-<prim>*" } " and " { $snippet "unmarshall-<prim>*-free" } | |
" for all values of " { $snippet "<prim>" } " in " { $link primitive-types } "." | |
{ $subsections unmarshall-int* } | |
"unmarshalls a pointer to primitive. Returns a number. " | |
"Assumes the pointer is not an array (if it is, only the first value is returned). " | |
"C functions that return arrays are not handled correctly by " { $snippet "alien.marshall" } | |
" and must be unmarshalled by hand." | |
{ $subsections unmarshall-int*-free } | |
"unmarshalls a pointer to primitive, and then frees the pointer." | |
$nl | |
"Primitive values require no unmarshalling. The factor FFI already does this." | |
; | |
ABOUT: "alien.marshall" | |
]] | |
FILE: [[alien/marshall/authors.txt]] [[Jeremy Hughes | |
]] | |
FILE: [[alien/marshall/syntax/syntax.factor]] [[! Copyright (C) 2009 Jeremy Hughes. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: accessors alien.inline alien.inline.types alien.marshall | |
combinators effects generalizations kernel locals make namespaces | |
quotations sequences words alien.marshall.structs lexer parser | |
vocabs.parser multiline ; | |
IN: alien.marshall.syntax | |
:: marshalled-function ( name types effect -- word quot effect ) | |
name types effect factor-function | |
[ in>> ] | |
[ out>> types [ pointer-to-non-const-primitive? ] filter append ] | |
bi <effect> | |
[ | |
[ | |
types [ marshaller ] map , \ spread , , | |
types length , \ nkeep , | |
types [ out-arg-unmarshaller ] map | |
effect out>> dup empty? | |
[ drop ] [ first unmarshaller prefix ] if | |
, \ spread , | |
] [ ] make | |
] dip ; | |
: define-c-marshalled ( name types effect body -- ) | |
[ | |
[ marshalled-function define-declared ] | |
[ prototype-string ] 3bi | |
] dip append-function-body c-strings get push ; | |
: define-c-marshalled' ( name effect body -- ) | |
[ | |
[ in>> ] keep | |
[ marshalled-function define-declared ] | |
[ out>> prototype-string' ] 3bi | |
] dip append-function-body c-strings get push ; | |
SYNTAX: CM-FUNCTION: | |
function-types-effect parse-here define-c-marshalled ; | |
SYNTAX: M-FUNCTION: | |
function-types-effect marshalled-function define-declared ; | |
SYNTAX: M-STRUCTURE: | |
scan current-vocab parse-definition | |
define-marshalled-struct ; | |
SYNTAX: CM-STRUCTURE: | |
scan current-vocab parse-definition | |
[ define-marshalled-struct ] [ nip define-c-struct ] 3bi ; | |
]] | |
FILE: [[alien/marshall/syntax/syntax-tests.factor]] [[! Copyright (C) 2009 Jeremy Hughes. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: alien.inline.syntax alien.marshall.syntax destructors | |
tools.test accessors kernel ; | |
IN: alien.marshall.syntax.tests | |
DELETE-C-LIBRARY: test | |
C-LIBRARY: test | |
C-INCLUDE: <stdlib.h> | |
C-INCLUDE: <string.h> | |
C-INCLUDE: <stdbool.h> | |
CM-FUNCTION: void outarg1 ( int* a ) | |
*a += 2; | |
; | |
CM-FUNCTION: unsigned-long* outarg2 ( unsigned-long a, unsigned-long* b ) | |
unsigned long* x = malloc(sizeof(unsigned long*)); | |
*b = 10 + *b; | |
*x = a + *b; | |
return x; | |
; | |
CM-STRUCTURE: wedge | |
{ "double" "degrees" } ; | |
CM-STRUCTURE: sundial | |
{ "double" "radius" } | |
{ "wedge" "wedge" } ; | |
CM-FUNCTION: double hours ( sundial* d ) | |
return d->wedge.degrees / 30; | |
; | |
CM-FUNCTION: void change_time ( double hours, sundial* d ) | |
d->wedge.degrees = hours * 30; | |
; | |
CM-FUNCTION: bool c_not ( bool p ) | |
return !p; | |
; | |
CM-FUNCTION: char* upcase ( const-char* s ) | |
int len = strlen(s); | |
char* t = malloc(sizeof(char) * len); | |
int i; | |
for (i = 0; i < len; i++) | |
t[i] = toupper(s[i]); | |
t[i] = '\0'; | |
return t; | |
; | |
;C-LIBRARY | |
{ 1 1 } [ outarg1 ] must-infer-as | |
[ 3 ] [ 1 outarg1 ] unit-test | |
[ 3 ] [ t outarg1 ] unit-test | |
[ 2 ] [ f outarg1 ] unit-test | |
{ 2 2 } [ outarg2 ] must-infer-as | |
[ 18 15 ] [ 3 5 outarg2 ] unit-test | |
{ 1 1 } [ hours ] must-infer-as | |
[ 5.0 ] [ <sundial> <wedge> 150 >>degrees >>wedge hours ] unit-test | |
{ 2 0 } [ change_time ] must-infer-as | |
[ 150.0 ] [ 5 <sundial> <wedge> 11 >>degrees >>wedge [ change_time ] keep wedge>> degrees>> ] unit-test | |
{ 1 1 } [ c_not ] must-infer-as | |
[ f ] [ "x" c_not ] unit-test | |
[ f ] [ 0 c_not ] unit-test | |
{ 1 1 } [ upcase ] must-infer-as | |
[ "ABC" ] [ "abc" upcase ] unit-test | |
]] | |
FILE: [[alien/marshall/syntax/authors.txt]] [[Jeremy Hughes | |
]] | |
FILE: [[alien/marshall/syntax/syntax-docs.factor]] [[! Copyright (C) 2009 Jeremy Hughes. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: help.markup help.syntax kernel quotations words | |
alien.inline alien.syntax effects alien.marshall | |
alien.marshall.structs strings sequences alien.inline.syntax ; | |
IN: alien.marshall.syntax | |
HELP: CM-FUNCTION: | |
{ $syntax "CM-FUNCTION: return name args\n body\n;" } | |
{ $description "Like " { $link POSTPONE: C-FUNCTION: } " but with marshalling " | |
"of arguments and return values." | |
} | |
{ $examples | |
{ $example | |
"USING: alien.inline.syntax alien.marshall.syntax prettyprint ;" | |
"IN: example" | |
"" | |
"C-LIBRARY: exlib" | |
"" | |
"C-INCLUDE: <stdio.h>" | |
"C-INCLUDE: <stdlib.h>" | |
"CM-FUNCTION: char* sum_diff ( const-int a, const-int b, int* x, int* y )" | |
" *x = a + b;" | |
" *y = a - b;" | |
" char* s = (char*) malloc(sizeof(char) * 64);" | |
" sprintf(s, \"sum %i, diff %i\", *x, *y);" | |
" return s;" | |
";" | |
"" | |
";C-LIBRARY" | |
"" | |
"8 5 0 0 sum_diff . . ." | |
"3\n13\n\"sum 13, diff 3\"" | |
} | |
} | |
{ $see-also define-c-marshalled POSTPONE: C-FUNCTION: POSTPONE: M-FUNCTION: } ; | |
HELP: CM-STRUCTURE: | |
{ $syntax "CM-STRUCTURE: name fields ... ;" } | |
{ $description "Like " { $link POSTPONE: C-STRUCTURE: } " but with marshalling of fields. " | |
"Defines a subclass of " { $link struct-wrapper } " a constructor, and slot-like accessor words." | |
} | |
{ $see-also POSTPONE: C-STRUCTURE: POSTPONE: M-STRUCTURE: } ; | |
HELP: M-FUNCTION: | |
{ $syntax "M-FUNCTION: return name args ;" } | |
{ $description "Like " { $link POSTPONE: FUNCTION: } " but with marshalling " | |
"of arguments and return values." | |
} | |
{ $see-also marshalled-function POSTPONE: C-FUNCTION: POSTPONE: CM-FUNCTION: } ; | |
HELP: M-STRUCTURE: | |
{ $syntax "M-STRUCTURE: name fields ... ;" } | |
{ $description "Like " { $link POSTPONE: C-STRUCT: } " but with marshalling of fields. " | |
"Defines a subclass of " { $link struct-wrapper } " a constructor, and slot-like accessor words." | |
} | |
{ $see-also define-marshalled-struct POSTPONE: C-STRUCTURE: POSTPONE: CM-STRUCTURE: } ; | |
HELP: define-c-marshalled | |
{ $values | |
{ "name" string } { "types" sequence } { "effect" effect } { "body" string } | |
} | |
{ $description "Defines a C function and a factor word which calls it with marshalling of " | |
"args and return values." | |
} | |
{ $see-also define-c-marshalled' } ; | |
HELP: define-c-marshalled' | |
{ $values | |
{ "name" string } { "effect" effect } { "body" string } | |
} | |
{ $description "Like " { $link define-c-marshalled } ". " | |
"The effect elements must be C type strings." | |
} ; | |
HELP: marshalled-function | |
{ $values | |
{ "name" string } { "types" sequence } { "effect" effect } | |
{ "word" word } { "quot" quotation } { "effect" effect } | |
} | |
{ $description "Defines a word which calls the named C function. Arguments, " | |
"return value, and output parameters are marshalled and unmarshalled." | |
} ; | |
]] | |
FILE: [[specialized/specialized.factor]] [[! Copyright (C) 2009, 2010 Daniel Ehrenberg | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: words kernel locals accessors compiler.tree.propagation.info | |
sequences kernel.private assocs fry parser math quotations | |
effects arrays definitions compiler.units namespaces | |
compiler.tree.debugger generalizations stack-checker ; | |
IN: specialized | |
: in-compilation-unit? ( -- ? ) | |
changed-definitions get >boolean ; | |
: define-temp-in-unit ( quot effect -- word ) | |
in-compilation-unit? | |
[ [ define-temp ] with-nested-compilation-unit ] | |
[ [ define-temp ] with-compilation-unit ] | |
if ; | |
: final-info-quot ( word -- quot ) | |
[ stack-effect in>> length '[ _ ndrop ] ] | |
[ def>> [ final-info ] with-scope >quotation ] bi | |
compose ; | |
ERROR: bad-outputs word quot ; | |
: define-outputs ( word quot -- ) | |
2dup [ stack-effect ] [ infer ] bi* effect<= | |
[ "outputs" set-word-prop ] [ bad-outputs ] if ; | |
: record-final-info ( word -- ) | |
dup final-info-quot define-outputs ; | |
:: lookup-specialized ( #call word n -- special-word/f ) | |
#call in-d>> n tail* >array [ value-info class>> ] map | |
dup [ object = ] all? [ drop f ] [ | |
word "specialized-defs" word-prop [ | |
[ declare ] curry word def>> compose | |
word stack-effect define-temp-in-unit | |
dup record-final-info | |
1quotation | |
] cache | |
] if ; | |
: specialized-quot ( word n -- quot ) | |
'[ _ _ lookup-specialized ] ; | |
: make-specialized ( word n -- ) | |
[ drop H{ } clone "specialized-defs" set-word-prop ] | |
[ dupd specialized-quot "custom-inlining" set-word-prop ] 2bi ; | |
SYNTAX: specialized | |
last-word dup stack-effect in>> length make-specialized ; | |
PREDICATE: specialized-word < word | |
"specialized-defs" word-prop >boolean ; | |
]] | |
FILE: [[math/newtons-method/newtons-method.factor]] [[! Copyright (c) 2008 Reginald Keith Ford II. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: kernel math math.derivatives ; | |
IN: math.newtons-method | |
! Newton's method of approximating roots | |
<PRIVATE | |
: newton-step ( x function -- x2 ) | |
dupd [ call ] [ derivative ] 2bi / - ; inline | |
: newton-precision ( -- n ) 13 ; inline | |
PRIVATE> | |
: newtons-method ( guess function -- x ) | |
newton-precision [ [ newton-step ] keep ] times drop ; | |
]] | |
FILE: [[math/newtons-method/authors.txt]] [[Reginald Ford | |
]] | |
FILE: [[math/derivatives/derivatives.factor]] [[! Copyright (c) 2008 Reginald Keith Ford II, Eduardo Cavazos. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: kernel continuations combinators sequences math math.order math.ranges | |
accessors float-arrays ; | |
IN: math.derivatives | |
TUPLE: state x func h err i j errt fac hh ans a done ; | |
: largest-float ( -- x ) 0x7fefffffffffffff bits>double ; foldable | |
: ntab ( -- val ) 8 ; inline | |
: con ( -- val ) 1.6 ; inline | |
: con2 ( -- val ) con con * ; inline | |
: big ( -- val ) largest-float ; inline | |
: safe ( -- val ) 2.0 ; inline | |
! Yes, this was ported from C code. | |
: a[i][i] ( state -- elt ) [ i>> ] [ i>> ] [ a>> ] tri nth nth ; | |
: a[j][i] ( state -- elt ) [ i>> ] [ j>> ] [ a>> ] tri nth nth ; | |
: a[j-1][i] ( state -- elt ) [ i>> ] [ j>> 1 - ] [ a>> ] tri nth nth ; | |
: a[j-1][i-1] ( state -- elt ) [ i>> 1 - ] [ j>> 1 - ] [ a>> ] tri nth nth ; | |
: a[i-1][i-1] ( state -- elt ) [ i>> 1 - ] [ i>> 1 - ] [ a>> ] tri nth nth ; | |
: check-h ( state -- state ) | |
dup h>> 0 = [ "h must be nonzero in dfridr" throw ] when ; | |
: init-a ( state -- state ) ntab [ ntab <float-array> ] replicate >>a ; | |
: init-hh ( state -- state ) dup h>> >>hh ; | |
: init-err ( state -- state ) big >>err ; | |
: update-hh ( state -- state ) dup hh>> con / >>hh ; | |
: reset-fac ( state -- state ) con2 >>fac ; | |
: update-fac ( state -- state ) dup fac>> con2 * >>fac ; | |
! If error is decreased, save the improved answer | |
: error-decreased? ( state -- state ? ) [ ] [ errt>> ] [ err>> ] tri <= ; | |
: save-improved-answer ( state -- state ) | |
dup err>> >>errt | |
dup a[j][i] >>ans ; | |
! If higher order is worse by a significant factor SAFE, then quit early. | |
: check-safe ( state -- state ) | |
dup [ [ a[i][i] ] [ a[i-1][i-1] ] bi - abs ] | |
[ err>> safe * ] bi >= [ t >>done ] when ; | |
: x+hh ( state -- val ) [ x>> ] [ hh>> ] bi + ; | |
: x-hh ( state -- val ) [ x>> ] [ hh>> ] bi - ; | |
: limit-approx ( state -- val ) | |
[ | |
[ [ x+hh ] [ func>> ] bi call ] | |
[ [ x-hh ] [ func>> ] bi call ] bi - | |
] [ hh>> 2.0 * ] bi / ; | |
: a[0][0]! ( state -- state ) | |
{ [ ] [ limit-approx ] [ drop 0 ] [ drop 0 ] [ a>> ] } cleave nth set-nth ; | |
: a[0][i]! ( state -- state ) | |
{ [ ] [ limit-approx ] [ i>> ] [ drop 0 ] [ a>> ] } cleave nth set-nth ; | |
: a[j-1][i]*fac ( state -- val ) [ a[j-1][i] ] [ fac>> ] bi * ; | |
: new-a[j][i] ( state -- val ) | |
[ [ a[j-1][i]*fac ] [ a[j-1][i-1] ] bi - ] | |
[ fac>> 1.0 - ] bi / ; | |
: a[j][i]! ( state -- state ) | |
{ [ ] [ new-a[j][i] ] [ i>> ] [ j>> ] [ a>> ] } cleave nth set-nth ; | |
: update-errt ( state -- state ) | |
dup [ [ a[j][i] ] [ a[j-1][i] ] bi - abs ] | |
[ [ a[j][i] ] [ a[j-1][i-1] ] bi - abs ] bi max >>errt ; | |
: not-done? ( state -- state ? ) dup done>> not ; | |
: derive ( state -- state ) | |
init-a | |
check-h | |
init-hh | |
a[0][0]! | |
init-err | |
1 ntab [a,b) [ | |
>>i not-done? [ | |
update-hh | |
a[0][i]! | |
reset-fac | |
1 over i>> [a,b] [ | |
>>j | |
a[j][i]! | |
update-fac | |
update-errt | |
error-decreased? [ save-improved-answer ] when | |
] each check-safe | |
] when | |
] each ; | |
: derivative-state ( x func h err -- state ) | |
state new | |
swap >>err | |
swap >>h | |
swap >>func | |
swap >>x ; | |
! For scientists: | |
! h should be .001 to .5 -- too small can cause bad convergence, | |
! h should be small enough to give the correct sgn(f'(x)) | |
! err is the max tolerance of gain in error for a single iteration- | |
: (derivative) ( x func h err -- ans error ) | |
derivative-state derive [ ans>> ] [ errt>> ] bi ; | |
: derivative ( x func -- m ) 0.01 2.0 (derivative) drop ; | |
: derivative-func ( func -- der ) [ derivative ] curry ; | |
]] | |
FILE: [[math/derivatives/derivatives-tests.factor]] [[USING: math math.derivatives tools.test ; | |
IN: math.derivatives.test | |
[ 8 ] [ 4 [ sq ] derivative >integer ] unit-test | |
]] | |
FILE: [[math/derivatives/authors.txt]] [[Reginald Ford | |
Eduardo Cavazos | |
]] | |
FILE: [[math/derivatives/derivatives-docs.factor]] [[USING: help.markup help.syntax math math.functions ; | |
IN: math.derivatives | |
HELP: derivative | |
{ $values { "x" "a position on the function" } { "function" "a differentiable function" } { "m" number } } | |
{ $description | |
"Approximates the slope of the tangent line by using Ridders' " | |
"method of computing derivatives, from the chapter \"Accurate computation " | |
"of F'(x) and F'(x)F''(x)\", from \"Advances in Engineering Software, Vol. 4, pp. 75-76 ." | |
} | |
{ $examples | |
{ $example | |
"USING: math math.derivatives prettyprint ;" | |
"4 [ sq ] derivative >integer ." | |
"8" | |
} | |
{ $notes | |
"For applied scientists, you may play with the settings " | |
"in the source file to achieve arbitrary accuracy. " | |
} | |
} ; | |
HELP: (derivative) | |
{ $values | |
{ "x" "a position on the function" } | |
{ "func" "a differentiable function" } | |
{ | |
"h" "distance between the points of the first secant line used for " | |
"approximation of the tangent. This distance will be divided " | |
"constantly, by " { $link con } ". See " { $link init-hh } | |
" for the code which enforces this. H should be .001 to .5 -- too " | |
"small can cause bad convergence. Also, h should be small enough " | |
"to give the correct sgn(f'(x)). In other words, if you're expecting " | |
"a positive derivative, make h small enough to give the same " | |
"when plugged into the academic limit definition of a derivative. " | |
"See " { $link update-hh } " for the code which performs this task." | |
} | |
{ | |
"err" "maximum tolerance of increase in error. For example, if this " | |
"is set to 2.0, the program will terminate with its nearest answer " | |
"when the error multiplies by 2. See " { $link check-safe } " for " | |
"the enforcing code." | |
} | |
{ "ans" number } | |
{ "error" number } | |
} | |
{ $description | |
"Approximates the slope of the tangent line by using Ridders' " | |
"method of computing derivatives, from the chapter \"Accurate computation " | |
"of F'(x) and F'(x)F''(x)\", from \"Advances in Engineering Software, " | |
"Vol. 4, pp. 75-76 ." | |
} | |
{ $examples | |
{ $example | |
"USING: math math.derivatives prettyprint ;" | |
"4 [ sq ] derivative >integer ." | |
"8" | |
} | |
{ $notes | |
"For applied scientists, you may play with the settings " | |
"in the source file to achieve arbitrary accuracy. " | |
} | |
} ; | |
HELP: derivative-func | |
{ $values { "func" "a differentiable function" } { "der" "the derivative" } } | |
{ $description | |
"Provides the derivative of the function. The implementation simply " | |
"attaches the " { $link derivative } " word to the end of the function." | |
} | |
{ $examples | |
{ $example | |
"USING: kernel math.derivatives math.functions math.trig prettyprint ;" | |
"60 deg>rad [ sin ] derivative-func call 0.5 .001 ~ ." | |
"t" | |
} | |
{ $notes | |
"Without a heavy algebraic system, derivatives must be " | |
"approximated. With the current settings, there is a fair trade of " | |
"speed and accuracy; the first 12 digits " | |
"will always be correct with " { $link sin } " and " { $link cos } | |
". The following code performs a minumum and maximum error test." | |
{ $code | |
"USING: kernel math math.functions math.trig sequences sequences.lib ;" | |
"360" | |
"[" | |
" deg>rad" | |
" [ [ sin ] derivative-func call ]" | |
" ! Note: the derivative of sin is cos" | |
" [ cos ]" | |
" bi - abs" | |
"] map minmax" | |
} | |
} | |
} ; | |
ARTICLE: "derivatives" "The Derivative Toolkit" | |
"A toolkit for computing the derivative of functions." | |
{ $subsections | |
derivative | |
derivative-func | |
(derivative) | |
} ; | |
ABOUT: "derivatives" | |
]] | |
FILE: [[math/physics/vel/vel.factor]] [[ | |
USING: math.physics.pos ; | |
IN: math.physics.vel | |
TUPLE: vel < pos vel ; | |
]] | |
FILE: [[math/physics/pos/pos.factor]] [[ | |
USING: kernel sequences multi-methods accessors math.vectors ; | |
IN: math.physics.pos | |
TUPLE: pos pos ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
GENERIC: distance ( a b -- c ) | |
METHOD: distance { sequence sequence } v- norm ; | |
METHOD: distance { pos pos } [ pos>> ] bi@ distance ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
]] | |
FILE: [[mongodb/gridfs/gridfs/unmaintained-reason.txt]] [[Moved to unmaintained by Joe Groff October 13, 2011 | |
The input stream protocol was changed; streams should now provide methods for | |
stream-read-unsafe and stream-read-partial-unsafe, which read into a caller- | |
provided buffer. This module has no tests so I didn't want to break it in the | |
process of updating it. | |
]] | |
FILE: [[mongodb/gridfs/gridfs/gridfs.factor]] [[USING: accessors arrays assocs base64 bson.constants | |
byte-arrays byte-vectors calendar combinators | |
combinators.short-circuit destructors formatting fry hashtables | |
io kernel linked-assocs locals math math.parser mongodb.cmd | |
mongodb.connection mongodb.driver mongodb.msg namespaces | |
sequences splitting strings ; | |
FROM: mongodb.driver => update ; | |
IN: mongodb.gridfs | |
CONSTANT: default-chunk-size 262144 | |
TUPLE: gridfs | |
{ bucket string } | |
{ files string } | |
{ chunks string } ; | |
<PRIVATE | |
: gridfs> ( -- gridfs ) | |
gridfs get ; inline | |
: files-collection ( -- str ) gridfs> files>> ; inline | |
: chunks-collection ( -- str ) gridfs> chunks>> ; inline | |
: init-gridfs ( gridfs -- ) | |
chunks>> "ChunkIdx" H{ { "files_id" 1 } { "n" 1 } } | |
<index-spec> ensure-index ; inline | |
PRIVATE> | |
: <gridfs> ( bucket -- gridfs ) | |
[ ] | |
[ "files" "%s.%s" sprintf ] | |
[ "chunks" "%s.%s" sprintf ] tri | |
gridfs boa [ init-gridfs ] keep ; | |
: with-gridfs ( gridfs quot -- * ) | |
[ gridfs ] dip with-variable ; inline | |
TUPLE: entry | |
{ id oid } | |
{ filename string } | |
{ content-type string } | |
{ length integer } | |
{ chunk-size integer } | |
{ created timestamp } | |
{ aliases array } | |
{ metadata hashtable } | |
{ md5 string } ; | |
<PRIVATE | |
: id>base64 ( id -- str ) | |
[ a>> >hex ] [ b>> >hex ] bi | |
2array "#" join >base64 >string ; inline | |
: base64>id ( str -- objid ) | |
base64> >string "#" split | |
[ first ] [ second ] bi | |
[ hex> ] bi@ oid boa ; inline | |
PRIVATE> | |
: <entry> ( name content-type -- entry ) | |
entry new | |
swap >>content-type swap >>filename | |
<oid> >>id 0 >>length default-chunk-size >>chunk-size | |
now >>created ; inline | |
<PRIVATE | |
TUPLE: chunk | |
{ id oid } | |
{ fileid oid } | |
{ n integer } | |
{ data byte-array } ; | |
: at> ( assoc key -- value/f ) | |
swap at ; inline | |
:: >set-at ( assoc value key -- ) | |
value key assoc set-at ; inline | |
: (update-file) ( entry assoc -- entry ) | |
{ | |
[ "_id" at> >>id ] | |
[ "filename" at> >>filename ] | |
[ "contentType" at> >>content-type ] | |
[ "length" at> >>length ] | |
[ "chunkSize" at> >>chunk-size ] | |
[ "uploadDate" at> >>created ] | |
[ "aliases" at> >>aliases ] | |
[ "metadata" at> >>metadata ] | |
[ "md5" at> >>md5 ] | |
} cleave ; inline | |
: assoc>chunk ( assoc -- chunk ) | |
[ chunk new ] dip | |
{ | |
[ "_id" at> >>id ] | |
[ "files_id" at> >>fileid ] | |
[ "n" at> >>n ] | |
[ "data" at> >>data ] | |
} cleave ; | |
: assoc>entry ( assoc -- entry ) | |
[ entry new ] dip (update-file) ; | |
: entry>assoc ( entry -- assoc ) | |
[ H{ } clone ] dip | |
{ | |
[ id>> "_id" >set-at ] | |
[ filename>> "filename" >set-at ] | |
[ content-type>> "contentType" >set-at ] | |
[ length>> "length" >set-at ] | |
[ chunk-size>> "chunkSize" >set-at ] | |
[ created>> "uploadDate" >set-at ] | |
[ aliases>> "aliases" >set-at ] | |
[ metadata>> "metadata" >set-at ] | |
[ md5>> "md5" >set-at ] | |
[ drop ] | |
} 2cleave ; inline | |
: create-entry ( entry -- entry ) | |
[ [ files-collection ] dip entry>assoc save ] [ ] bi ; | |
TUPLE: state bytes count ; | |
: <state> ( -- state ) | |
0 0 state boa ; inline | |
: get-state ( -- n ) | |
state get ; inline | |
: with-state ( quot -- state ) | |
[ <state> state ] dip | |
[ get-state ] compose | |
with-variable ; inline | |
: update-state ( bytes -- ) | |
[ get-state ] dip | |
'[ _ + ] change-bytes | |
[ 1 + ] change-count drop ; inline | |
:: store-chunk ( chunk entry n -- ) | |
entry id>> :> id | |
H{ { "files_id" id } | |
{ "n" n } { "data" chunk } } | |
[ chunks-collection ] dip save ; inline | |
:: write-chunks ( stream entry -- length ) | |
entry chunk-size>> :> chunk-size | |
[ | |
[ | |
chunk-size stream stream-read dup [ | |
[ entry get-state count>> store-chunk ] | |
[ length update-state ] bi | |
] when* | |
] loop | |
] with-state bytes>> ; | |
: (entry-selector) ( entry -- selector ) | |
id>> "_id" associate ; inline | |
:: file-md5 ( id -- md5-str ) | |
filemd5-cmd make-cmd | |
id "filemd5" set-cmd-opt | |
gridfs> bucket>> "root" set-cmd-opt | |
send-cmd "md5" at> ; inline | |
: update-entry ( bytes entry -- entry ) | |
[ swap >>length dup id>> file-md5 >>md5 ] | |
[ nip [ (entry-selector) ] [ ] bi | |
[ length>> "length" associate "$set" associate | |
[ files-collection ] 2dip <update> update ] | |
[ md5>> "md5" associate "$set" associate | |
[ files-collection ] 2dip <update> update ] 2bi | |
] 2bi ; | |
TUPLE: gridfs-input-stream entry chunk n offset cpos ; | |
: <gridfs-input-stream> ( entry -- stream ) | |
[ gridfs-input-stream new ] dip | |
>>entry 0 >>offset 0 >>cpos -1 >>n ; | |
PRIVATE> | |
: write-entry ( input-stream entry -- entry ) | |
create-entry [ write-chunks ] keep update-entry ; | |
: get-entry ( id -- entry ) | |
[ files-collection ] dip | |
"_id" associate <query> find-one assoc>entry ; | |
: open-entry ( entry -- input-stream ) | |
<gridfs-input-stream> ; | |
: entry-contents ( entry -- bytearray ) | |
<gridfs-input-stream> stream-contents ; | |
<PRIVATE | |
: load-chunk ( stream -- chunk/f ) | |
[ entry>> id>> "files_id" associate ] | |
[ n>> "n" associate ] bi assoc-union | |
[ chunks-collection ] dip | |
<query> find-one dup [ assoc>chunk ] when ; | |
: exhausted? ( stream -- boolean ) | |
[ offset>> ] [ entry>> length>> ] bi = ; inline | |
: fresh? ( stream -- boolean ) | |
[ offset>> 0 = ] [ chunk>> f = ] bi and ; inline | |
: data-available ( stream -- int/f ) | |
[ cpos>> ] [ chunk>> data>> length ] bi | |
2dup < [ swap - ] [ 2drop f ] if ; inline | |
: next-chunk ( stream -- available chunk/f ) | |
0 >>cpos [ 1 + ] change-n | |
[ ] [ load-chunk ] bi >>chunk | |
[ data-available ] [ chunk>> ] bi ; inline | |
: ?chunk ( stream -- available chunk/f ) | |
dup fresh? [ next-chunk ] [ | |
dup exhausted? [ drop 0 f ] [ | |
dup data-available [ swap chunk>> ] [ next-chunk ] if* | |
] if | |
] if ; inline | |
: set-stream ( n stream -- ) | |
swap { | |
[ >>offset drop ] | |
[ over entry>> chunk-size>> /mod [ >>n ] [ >>cpos ] bi* drop ] | |
[ drop dup load-chunk >>chunk drop ] | |
} 2cleave ; inline | |
:: advance-stream ( n stream -- ) | |
stream [ n + ] change-cpos [ n + ] change-offset drop ; inline | |
: read-part ( n stream chunk -- seq/f ) | |
[ [ cpos>> swap [ drop ] [ + ] 2bi ] [ data>> ] bi* <slice> ] | |
[ drop advance-stream ] 3bi ; inline | |
:: (stream-read-partial) ( n stream -- seq/f ) | |
stream ?chunk :> chunk :> available | |
chunk [ | |
n available < | |
[ n ] [ available ] if | |
stream chunk read-part | |
] [ f ] if ; inline | |
:: (stream-read) ( n stream acc -- ) | |
n stream (stream-read-partial) | |
{ | |
{ [ dup not ] [ drop ] } | |
{ [ dup length n = ] [ acc push-all ] } | |
{ [ dup length n < ] [ | |
[ acc push-all ] [ length ] bi | |
n swap - stream acc (stream-read) ] | |
} | |
} cond ; inline recursive | |
PRIVATE> | |
M: gridfs-input-stream stream-element-type drop +byte+ ; | |
M: gridfs-input-stream stream-read ( n stream -- seq/f ) | |
over <byte-vector> [ (stream-read) ] [ ] bi | |
[ f ] [ >byte-array ] if-empty ; | |
M: gridfs-input-stream stream-read-partial ( n stream -- seq/f ) | |
(stream-read-partial) ; | |
M: gridfs-input-stream stream-tell ( stream -- n ) | |
offset>> ; | |
M: gridfs-input-stream stream-seek ( n seek-type stream -- ) | |
swap seek-absolute = | |
[ set-stream ] | |
[ "seek-type not supported" throw ] if ; | |
M: gridfs-input-stream dispose drop ; | |
]] | |
FILE: [[README.md]] [[# Factor | |
The Factor project is maintained and mirrored at [https://github.com/factor/factor](https://github.com/factor/factor) | |
## Unmaintained Factor Vocabularies | |
Unmaintained, neglected, bit-rotted, or just terrible vocabularies that were once in a subdirectory of the Factor project. | |
]] | |
FILE: [[fries/fries.factor]] [[USING: arrays vectors combinators effects kernel math sequences splitting | |
strings.parser parser fry sequences.extras ; | |
! a b c glue => acb | |
! c b a [ append ] dip prepend | |
IN: fries | |
: str-fry ( str on -- quot ) split | |
[ unclip-last [ [ [ append ] [ prepend ] bi* ] reduce-r ] 2curry ] | |
[ length 1 - 1 <effect> [ call-effect ] 2curry ] bi ; | |
: gen-fry ( str on -- quot ) split | |
[ unclip-last [ [ [ 1array ] [ append ] [ prepend ] tri* ] reduce-r ] 2curry ] | |
[ length 1 - 1 <effect> [ call-effect ] 2curry ] bi ; | |
SYNTAX: i" parse-string rest "_" str-fry append! ; | |
SYNTAX: i{ \ } parse-until >array { _ } gen-fry append! ; | |
SYNTAX: iV{ \ } parse-until >vector V{ _ } gen-fry append! ; | |
]] | |
FILE: [[fries/summary.txt]] [[Generalized Frying]] | |
FILE: [[fries/authors.txt]] [[Sam Anklesaria | |
]] | |
FILE: [[easy-help/expand-markup/expand-markup.factor]] [[ | |
USING: accessors arrays kernel lexer locals math namespaces parser | |
sequences splitting ; | |
IN: easy-help.expand-markup | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: scan-one-array ( string -- array rest ) | |
string-lines | |
lexer-factory get call | |
[ | |
[ | |
\ } parse-until >array | |
lexer get line-text>> | |
lexer get column>> tail | |
] | |
with-lexer | |
] | |
with-scope ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: contains-markup? ( string -- ? ) "{ $" swap subseq? ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
:: expand-markup ( LINE -- lines ) | |
LINE contains-markup? | |
[ | |
[let | N [ "{ $" LINE start ] | | |
LINE N head | |
LINE N 2 + tail scan-one-array dup " " head? [ 1 tail ] [ ] if | |
[ 2array ] dip | |
expand-markup | |
append ] | |
] | |
[ LINE 1array ] | |
if ; | |
]] | |
FILE: [[easy-help/easy-help.factor]] [[ | |
USING: arrays assocs compiler.units | |
grouping help help.markup help.topics kernel lexer multiline | |
namespaces parser sequences splitting words | |
easy-help.expand-markup ; | |
IN: easy-help | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: parse-text-block ( -- array ) | |
".." parse-multiline-string | |
string-lines | |
1 tail | |
[ dup " " head? [ 4 tail ] [ ] if ] map | |
[ expand-markup ] map | |
concat | |
[ dup "" = [ drop { $nl } ] [ ] if ] map ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: Text: parse-text-block parsed ; parsing | |
: Block: scan-word 1array parse-text-block append parsed ; parsing | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: Notes: { $notes } parse-text-block append parsed ; parsing | |
: Description: { $description } parse-text-block append parsed ; parsing | |
: Contract: { $contract } parse-text-block append parsed ; parsing | |
: Checked-Example: { $example } parse-text-block append parsed ; parsing | |
: Class-Description: | |
{ $class-description } parse-text-block append parsed ; parsing | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: Code: | |
{ $code } | |
parse-text-block [ dup array? [ drop "" ] [ ] if ] map | |
append | |
parsed | |
; parsing | |
: Example: | |
{ $heading "Example" } | |
{ $code } | |
parse-text-block | |
[ dup array? [ drop "" ] [ ] if ] map ! Each item in $code must be a string | |
append | |
2array parsed ; parsing | |
: Introduction: | |
{ $heading "Introduction" } | |
parse-text-block | |
2array parsed ; parsing | |
: Summary: | |
{ $heading "Summary" } | |
parse-text-block | |
2array parsed ; parsing | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: Values: | |
".." parse-multiline-string | |
string-lines | |
1 tail | |
[ dup " " head? [ 4 tail ] [ ] if ] map | |
[ " " split1 [ " " first = ] trim-head 2array ] map | |
\ $values prefix | |
parsed | |
; parsing | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: Word: | |
scan current-vocab create dup old-definitions get | |
[ delete-at ] with each dup set-word | |
bootstrap-word dup set-word | |
dup >link save-location | |
\ ; parse-until >array swap set-word-help ; parsing | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: Heading: { $heading } ".." parse-multiline-string suffix parsed ; parsing | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: List: | |
{ $list } | |
".." parse-multiline-string | |
string-lines | |
1 tail | |
[ dup " " head? [ 4 tail ] [ ] if ] map | |
[ expand-markup ] map | |
append parsed | |
; parsing | |
]] | |
FILE: [[sandbox/summary.txt]] [[Basic sandboxing | |
]] | |
FILE: [[sandbox/sandbox.factor]] [[! Copyright (C) 2009 Maxim Savchenko. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: kernel sequences vectors assocs namespaces parser lexer vocabs | |
combinators.short-circuit vocabs.parser ; | |
IN: sandbox | |
SYMBOL: whitelist | |
: with-sandbox-vocabs ( quot -- ) | |
"sandbox.syntax" load-vocab vocab-words 1vector | |
use [ auto-use? off call ] with-variable ; inline | |
: parse-sandbox ( lines assoc -- quot ) | |
whitelist [ [ parse-lines ] with-sandbox-vocabs ] with-variable ; | |
: reveal-in ( name -- ) | |
[ { [ search ] [ no-word ] } 1|| ] keep current-vocab vocab-words set-at ; | |
SYNTAX: REVEAL: scan reveal-in ; | |
SYNTAX: REVEALING: ";" parse-tokens [ reveal-in ] each ; | |
]] | |
FILE: [[sandbox/sandbox-tests.factor]] [[! Copyright (C) 2009 Maxim Savchenko | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: kernel accessors continuations lexer vocabs vocabs.parser | |
combinators.short-circuit sandbox tools.test ; | |
IN: sandbox.tests | |
<< "sandbox.syntax" load-vocab drop >> | |
USE: sandbox.syntax.private | |
: run-script ( x lines -- y ) | |
H{ { "kernel" "kernel" } { "math" "math" } { "sequences" "sequences" } } | |
parse-sandbox call( x -- x! ) ; | |
[ 120 ] | |
[ | |
5 | |
{ | |
"! Simple factorial example" | |
"APPLYING: kernel math sequences ;" | |
"1 swap [ 1+ * ] each" | |
} run-script | |
] unit-test | |
[ | |
5 | |
{ | |
"! Jailbreak attempt with USE:" | |
"USE: io" | |
"\"Hello world!\" print" | |
} run-script | |
] | |
[ | |
{ | |
[ lexer-error? ] | |
[ error>> condition? ] | |
[ error>> error>> no-word-error? ] | |
[ error>> error>> name>> "USE:" = ] | |
} 1&& | |
] must-fail-with | |
[ | |
5 | |
{ | |
"! Jailbreak attempt with unauthorized APPLY:" | |
"APPLY: io" | |
"\"Hello world!\" print" | |
} run-script | |
] | |
[ | |
{ | |
[ lexer-error? ] | |
[ error>> sandbox-error? ] | |
[ error>> vocab>> "io" = ] | |
} 1&& | |
] must-fail-with | |
]] | |
FILE: [[sandbox/authors.txt]] [[Maxim Savchenko | |
]] | |
FILE: [[sandbox/syntax/syntax.factor]] [[! Copyright (C) 2009 Maxim Savchenko. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: kernel sequences assocs namespaces lexer vocabs.parser sandbox ; | |
IN: sandbox.syntax | |
<PRIVATE | |
ERROR: sandbox-error vocab ; | |
: sandbox-use+ ( alias -- ) | |
dup whitelist get at [ add-use ] [ sandbox-error ] ?if ; | |
PRIVATE> | |
SYNTAX: APPLY: scan sandbox-use+ ; | |
SYNTAX: APPLYING: ";" parse-tokens [ sandbox-use+ ] each ; | |
REVEALING: | |
! ! | |
HEX: OCT: BIN: f t CHAR: " | |
[ { T{ | |
] } ; | |
REVEAL: ; | |
]] | |
FILE: [[recipes/summary.txt]] [[Database backed recipe sharing]] | |
FILE: [[recipes/icons/submit.tiff]] base64[[TU0AKgAAACAAAALQAAAACgAAAtAAAAAKAAgACAAIAAgADwD+AAQAAAABAAAAAAEAAAQAAAABAAAAGQEBAAQAAAABAAAAGQECAAMAAAAEAAAAGAEDAAMAAAABAAEAAAEGAAMAAAABAAIAAAERAAQAAAABAAAA2gEVAAMAAAABAAQAAAEWAAQAAAABAAAAGQEXAAQAAAABAAAJxAEaAAUAAAABAAAACAEbAAUAAAABAAAAEAEcAAMAAAABAAEAAAEoAAMAAAABAAIAAAFSAAMAAAABAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACY2Njf2lpaX9paWl/aWlpf2lpaX9paWl/aWlpf2lpaX9paWl/ZmZmf2lpaX9paWl/AAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC8XFxf//////////////////////////////////////////////////////9PT0/+Tl5f8AAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/FxMT///////X09P/19PT/9fT0//X09P/19PT/9fT0//Pz8//t7e3/0NHR/7a1tf/09PT/cnNzmAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPxcXF///////08/P/9PPz//Tz8//08/P/9PPz//Tz8//08/P/7u3t/9ra2v+1tLT/x8bG/+zs7P8AAAAxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8XExP//////9PPz//Tz8//08/P/9PPz//Tz8//08/P/9PPz/+/u7v/e3d3/ubm5/8PDw//8/Pz/9PT0/2pqaowAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/ExMT///////Py8v/z8vL/8/Ly//Py8v/z8vL/8/Ly//Py8v/w7+//4N/f/8DAwP+1tbX/z8/P/83Nzf/g4OD/Y2NjiAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPxMPD///////R0ND/r66u/7++vv+xsbH/urm5/9HQ0P+vrq7/7+/v/+Hg4P/Kycn/qaio/4qKiv+DhIT/iYmJ/7Guru+kQEC47peX+fKbm+RpNzcZAAAAAAAAAAAAAAAAAAAAD8PDw///////4eDg/+Hg4P/a2dn/3t3d/9DPz//Qz8//0M/P/+7u7v/k5OT/2dnZ/9DPz//Kysr/xcTE/7+/v//EsbH/8aKi/+GGhv+8VFT/bBERewAAAAAAAAAAAAAAAAAAAA/Dw8P///////Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P/v7u7/6unp/+jo6P/p6Oj/6unp/+rq6v/Pz8//+Pj4/9TNzf+kUFD/hwwM/4ACAmgAAAAAAAAAAAAAAAAAAAAPw8PD///////Ozs7/tLS0/8rKyv+4uLj/rKys/6ysrP/i4uL/u7u7/6yrq/+rqqr/v7+//7GwsP/l2rD/+e/B/+jo6P+YmJj/XllZ/2YUFNE5AAAJAAAAAAAAAAAAAAAAAAAAD8PDw///////7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/x7dr//umJ//7nhP/Br4P/XFxc/zQ0NOsgICAgAAAAAgAAAAAAAAAAAAAAAAAAAA/Dw8P//////97d3f/NzMz/1dXV/9va2v/NzMz/zczM/9bW1v/V1NT/zczM/9nZ2f/l4tX/8N6L//zTWf/5shX/u3MR/5OOiv8+Pj6GAAAADAAAAAEAAAAAAAAAAAAAAAAAAAAPwsLC///////Ly8v/qqqq/6qqqv/Jycn/qqqq/6qqqv+qqqr/ubm5/+fn5/+7tqD/+uR+//zUWv/4qAT/vmsB/7aHXP/p6en/QUFBfgAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAD8LCwv//////7Ovr/+zr6//s6+v/7Ovr/+zr6//s6+v/7Ovr/+zr6//u6db/++aC//3mef/5uCD/x3MB/6VTCf/HvbX/8fHx/0RERHsAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAA/CwsL//////8vLy/+wsLD/5+fn/6qqqv/Q0ND/2NjY/6qqqv+9u7X/9uF9//3ldf/7y0b/5JID/6NQBP+MdmL/tbW1//r6+v9FRUV6AAAABgAAAAAAAAAAAAAAAAAAAAAAAAAPwsLC///////a2tr/ycnJ/+Li4v/MzMz/ycnJ/8nJyf/e3dr/9eST//zbYf/5uin/65cD/6liFf+Thnr/sbGx/9ra2v//////RkZGeQAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAD8HBwf//////6enp/+np6f/p6en/6enp/+np6f/q6eX/9+OH//3cYP/3pQf/5ZEC/6dPAP+jkYL/x8fH/9/f3//q6ur//////0ZGRnkAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAA/BwcH//////+no6P/p6Oj/6ejo/+no6P/p6OX/9uOO//3jaP/6wDD/6JMC/6tSAP+ZcE7/sbGx/93c3P/n5ub/6+rq//////9GRkZ5AAAABgAAAAAAAAAAAAAAAAAAAAAAAAAPwcHB///////o6Oj/6Ojo/+jo6P/q5dH/+eN7//3gYP/6wjX/4o4F/6NcHf+XgGz/qamp/9XV1f/n5+f/6Ojo/+rq6v//////RkZGeQAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAD8TExP//////5+fn/+fn5//n5+f/49K2/9y4dP/vtEH/85wD/6hgGf+UlJT/s7Oz/9XV1f/m5ub/5+fn/+fn5//p6en//////0ZGRnkAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAA+urq7z/////+7u7v/u7u7/7u7u/9zDof/hwo//yo4h/7xmBf+ZemD/tbW1/9nZ2f/r6+v/7u7u/+7u7v/u7u7/8PDw//////9JSUl7AAAABgAAAAAAAAAAAAAAAAAAAAAAAAAOl5eX4P/////////////////////ewJH/yo4h/8aDAv+rbCT/sbCv/+fn5//7+/v/////////////////////////////////Pj4+dAAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAC0lJSWsLCwtUCQkJVQkJCVWKdVScaE8r2lQ4AqsyIgOUDAoFeggICGUJCQlWCQkJVQkJCVUJCQlVCQkJVQkJCVUKCgpUCQkJSwICAiYAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAHAAAACQAAAAgAAAAIAAAACAAAABIAAAAbAAAAEwAAAAwAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAYAAAADAAAAAQAAAAAAAAAA]] | |
FILE: [[recipes/icons/love.tiff]] base64[[TU0AKgAAACAAAALQAAAACgAAAtAAAAAKAAgACAAIAAgADwD+AAQAAAABAAAAAAEAAAQAAAABAAAAGQEBAAQAAAABAAAAGQECAAMAAAAEAAAAGAEDAAMAAAABAAEAAAEGAAMAAAABAAIAAAERAAQAAAABAAAA2gEVAAMAAAABAAQAAAEWAAQAAAABAAAAGQEXAAQAAAABAAAJxAEaAAUAAAABAAAACAEbAAUAAAABAAAAEAEcAAMAAAABAAEAAAEoAAMAAAABAAIAAAFSAAMAAAABAAEAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD//fYA//z0AP/89AD//PQA//z0AP/89AD+998A/vTTFP733wL/+/EA//z0AP/89AD//PQA//z0AP/89AD///0A////AP///wD///8A////AP///wD///8A////AP///wD///8A/fTSAP3xxwD98ccA/fHHAP3xxwD98ccA+c4+WPe/Avj4xRu7/euuDf7xxwD+8ccA/vHHAP7xxwD+8ccA//32AP///wD///8A////AP///wD///8A////AP///wD///8A////AP3z0QD98MYA/fDGAP3wxgD98MYA+tdrUfa7A/v2uwL/9rsC//fDIrv97LYH/vDFAP7wxQD+8MUA/vDFAP/99QD///8A////AP///wD///8A////AP///wD///8A////AP///wD98tEA/e/GAP3vxgD978YA+tZtV/W4Bvj1twT/9bcE//W3BP/1twT/98Emu/zprw3978UA/e/FAP3vxQD//PUA////AP///wD///8A////AP///wD///8A////AP///wD///8A/fHQAP3txAD97cUA+dFnV/SzBf30swX/9LMF//SzBf/0swX/9LMF//SzBf/2vSTC/Om3Cv3vyQD978kA//z2AP///wD///8A////AP///wD///8A////AP///wD///8A////AP3wzgD97MMA+dR3SPOwCPnzsAb/87AG//OwBv/zsAb/87AG//OwBv/zsAb/87AG//W7KrP86LYF/ezDAP/89QD///8A////AP///wD///8A////AP///wD///8A////AP///wD98dMA+teGOfOtCvTzrAf/86wH//OsB//zrAf/86wH//OsB//zrAf/86wH//OsB//zrAf/9bw3o/zqwAL//PYA////AP///wD///8A////AP///wD///8A////AP///wD///8A+96iKPKrD+3yqQj/8qkI//KpCP/yqQj/8qkI//KpCP/yqQj/8qkI//KpCP/yqQj/8qkI//KpCP/1vUKN/vrxAP///wD///8A////AP///wD///8A////AP///wD///8A////APW/UITxpgrs8aUJ7vGlCfHxpQn/8aUJ//GlCf/xpQn/8aUJ//GlCf/xpQn/8aYL+fGnDvDxpw3w8acM6P3z3hP///8A////AP///wD///8A////AP///wD///8A////AP///wD40IAA868oAPGjCgD0tj8l8KIJ//CiCv/wogr/8KIK//CiCv/wogr/8KIK//W9UXX74q4A++CrAPfIagD++OoA////AP///wD///8A////AP///wD///8A////AP///wD///8A+NCAAPOvKAD0uUkA9cBeFPCfCf/vngv/754L/++eC//vngv/754L/++eC//0t0pH98p3APvgqgD3yGoA/vjqAP///wD///8A////AP///wD///8A////AP///wD///8A////APjRgQD1vlkA9cBlAPW/ZALwnw3u75oN/++aDf/vmg3/75oN/++aDf/vmg3/87FDKPS3UAD1wGUA98VlAP746gD///8A////AP///wD///8A////AP///wD///8A////AP///wD41JYA9sZ6APbGegD2xnoA8qonsu6WDv/ulg7/7pYO/+6WDv/ulg7/7pYN//fIfiD40JEA+NCRAPjOiQD++OwA////AP///wD///8A////AP///wD///8A////AP///wD///8A+dWgAPfKiAD3yogA98qIAPOzUmTvnAr/7ZMP/+2TD//tkw//7ZMP/+2TDv/yr0wk87VZAPO1WQDztVkA/fPjAP///wD///8A////AP///wD///8A////AP///wD///8A////APjUoQD2yYkA9smJAPbJiQD1xYEN8KAN7uyPEP/sjxD/7I8Q/+yPEP/sjxD/8atLOfO2YgDztmIA87ZiAP3z5QD///8A////AP///wD///8A////AP///wD///8A////AP///wD52bAA99CcAPfQnAD30JwA99CcAPKyVHXvnQn/64sR/+uLEf/rixH/64sR//CkRFvztWUA87VlAPO1ZQD98+UA////AP///wD///8A////AP///wD///8A////AP///wD///8A+uTHAPnduQD53bkA+d25APnduQD527UF8aYmx+2TDf/qiBL/6ogS/+qIEv/unz+O9cGDAPXBgwD1wYMA/fXqAP///wD///8A////AP///wD///8A////AP///wD///8A////APzp1AD748kA++PJAPvjyQD748kA++PJAPfRpRnwnwzi7I0P/+qEE//qhBP/64wi1PXIkgD1yJIA9ciSAP327QD///8A////AP///wD///8A////AP///wD///8A////AP///wD86dMA++PIAPvjyAD748gA++PIAPvjyAD52bUA7ps/K/ChD+TulQz/6YET/+mBE//ztng/98ufAPTAjwD++fUA////AP///wD///8A////AP///wD///8A////AP///wD///8A/OnTAPvjyAD748gA++PIAPPbwQDSvacA0LWXAMiHQQDJkVgRx4IiiO6ZDPDsjw7/6ocl2/GvcCTzt4AAuLOvAO7u7gD///8A////AP///wD///8A////AP///wD///8A////APzp0wDx2sAANS0oBQMAAA0DAAARAwAAFAMAABYDAAAXAwAAGAMAABgeEAYkfUgOgM5+ENHqhRL1i00XdAMAAAXNzMwA////AP///wD///8A////AP///wD///8A////AP///wD++vYAzMfDAAMAAAwDAAAbAwAAIQMAACQDAAAmAwAAJwMAACgDAAAoAwAAJwMAACYDAAAkHxEGMBgMBScDAAALzczMAP///wD///8A////AP///wD///8A////AP///wD///8A////ANfW1gA1MzMANTMzAjUzMwM1MzMENTMzBTUzMwY1MzMGNTMzBjUzMwY1MzMFNTMzBDUzMwM1MzMCNTMzANfW1gD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A]] | |
FILE: [[recipes/icons/more.tiff]] base64[[TU0AKgAAACAAAALQAAAACgAAAtAAAAAKAAgACAAIAAgADwD+AAQAAAABAAAAAAEAAAQAAAABAAAAGQEBAAQAAAABAAAAGQECAAMAAAAEAAAAGAEDAAMAAAABAAEAAAEGAAMAAAABAAIAAAERAAQAAAABAAAA2gEVAAMAAAABAAQAAAEWAAQAAAABAAAAGQEXAAQAAAABAAAJxAEaAAUAAAABAAAACAEbAAUAAAABAAAAEAEcAAMAAAABAAEAAAEoAAMAAAABAAIAAAFSAAMAAAABAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5jhwJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiQwsATowd/0OFFW8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIkIKAOvzwP9zpED/Q4QUjStAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACFBCgDw97//6/Sx/8zelP9snjpLIUEKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhQAkA6/Sy/+Lvnf/j75//5fCo/4KsTP9CgBOWIT4KAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEF+EZZBfRH/QX0R/0F9Ef9BfRH/QX0R/0F9Ef9BfRH/QX0R/0F9Ef9BfRH/QX0R/+Xwpv/d7JT/3eyU/9/tmP/m8an/ssx6/0SAE2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACTtV3/2uqT/9rqk//a6pP/2uqT/9rqk//a6pP/2uqT/9rqk//a6pP/2uqT/9nqkv/V54r/1OaG/9Tmhv/U5ob/1eeI/9jojv+50Xr/Z5YyiiE8BwAhPgcAAAAAAAAAAAAAAAAAjbBR/8nfdv/J33b/yd92/8nfdv/J33b/yd92/8nfdv/J33b/yd92/8nfdv/J33b/yd92/8nfdv/J33b/yd92/8nfdv/J33b/yuB6/9Xmjf+3zXn/S38X/yA8BwAAAAAAAAAAAImtTP/A223/wNtt/8Dbbf/A223/wNtt/8Dbbf/A223/wNtt/8Dbbf/A223/wNtt/8Dbbf/A223/wNtt/8Dbbf/A223/wNtt/8Dbbf/C3G//yeB8/8ndhv9VhR+QQIAVDAAAAACGqkj/uNVj/7jVY/+41WP/uNVj/7jVY/+41WP/uNVj/7jVY/+41WP/uNVj/7jVY/+41WP/uNVj/7jVY/+41WP/uNVj/7jVY/+41WP/uNVj/7nWZP++2Wz/ssxy/z90C3UAAAAAc54i/4K1BP+CtQT/grUE/4K1BP+CtQT/grUE/4K1BP+CtQT/grUE/4K1BP+CtQT/grUE/4K1BP+CtQT/grUE/4K1BP+CtQT/grUE/4S2B/+NvBT/mcAt/3CZKJA8cgUJAAAAAG6aIf93rgP/d64D/3euA/93rgP/d64D/3euA/93rgP/d64D/3euA/93rgP/d64D/3euA/93rgP/d64D/3euA/93rgP/d64D/3yxCv+ZwjH/iKs//0NxDP8fNwQAAAAAAAAAAABslyH/cKoD/3CqA/9wqgP/cKoD/3CqA/9wqgP/cKoD/3CqA/9wqgP/cKoD/3CqA/9wqgP/cKoD/3CqA/9wqgP/cKoD/3OsB/+Oui7/ZIsl/z1rB5Y7aQcnAAAAAAAAAAAAAAAAeZ40/5W/Of+Vvzn/lb85/5W/Of+Vvzn/lb85/5W/Of+Vvzn/lb85/5W/Of+PvDL/dKwQ/2mlAv9ppQL/aqUD/3CpC/+Ityn/a5Ip/z1pBn4AAAAAAAAAAAAAAAAAAAAAAAAAAB80AwAfNAMAHzQDAB80AwAfNAMAHzQDAB80AwAfNAMAHzQDAB80AwAfNAMALk0EAIm4Mv9hoAL/ZKIF/3itIP9wmSf/V30ajR80AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB4yAgCKuTn/ZaIO/4S1Mv9egiD/O2IDYwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAeMQEAnMRQ/4q0QP9afh3/O2EBGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGCYBAF57JbYyTx9dHjAAKQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAACAAAAAwAAAARAAAAFwAAACMAAAApAAAALwAAADsAAABCAAAARgAAAEwAAABQAAAAUgAAAFIAAABPAAAATQAAAEsAAABAAAAANgAAACwAAAAgAAAADQAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA]] | |
FILE: [[recipes/icons/hate.tiff]] base64[[TU0AKgAAACAAAALQAAAACgAAAtAAAAAKAAgACAAIAAgADwD+AAQAAAABAAAAAAEAAAQAAAABAAAAGQEBAAQAAAABAAAAGQECAAMAAAAEAAAAGAEDAAMAAAABAAEAAAEGAAMAAAABAAIAAAERAAQAAAABAAAA2gEVAAMAAAABAAQAAAEWAAQAAAABAAAAGQEXAAQAAAABAAAJxAEaAAUAAAABAAAACAEbAAUAAAABAAAAEAEcAAMAAAABAAEAAAEoAAMAAAABAAIAAAFSAAMAAAABAAEAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD//fUA//zzAP/88wD//PMA//zzAP/88wD/++8A/vTaAP734AD+9t0A/vbcAP723AD+9tsA/vXVEv733Q7//vwA////AP///wD///8A////AP///wD///8A////AP///wD///8A/fHPAP3uwwD97sMA/e7DAP3uwwD97sMA/OiwAPjJQwD61WQA+dNYAPrSTQ75zDZu+MgsyffDFvT60ENv//vuAP///wD///8A////AP///wD///8A////AP///wD///8A////AP3xzwD97sMA/e7DAP3uwwD97sMA/e7DAPzosAD4yUMA+tViA/jLPXD4yTft98Mm//a/EOn61Vss+910AP/99QD///8A////AP///wD///8A////AP///wD///8A////AP///wD98c8A/e7DAP3uwwD97sMA/e7DAP3uwwD86LAA98U3JPjIPMz3wy3/9bgI//W3BP/51GdM/OKVAPvfggD//PQA////AP///wD///8A////AP///wD///8A////AP///wD///8A/fHQAP3uxAD97sQA/e7EAP3uxAD97sQA++OeGffFN+L1uRX/9LMF//SzBf/1uBXU+t2LAPrdiwD63YsA/vnsAP///wD///8A////AP///wD///8A////AP///wD///8A////AP3txQD86LYA/Oi2APzotgD86LYA/OexBffGRMf1uRz/87AG//OwBv/zsAb/9sA2jvrXfwD6138A+td/AP746gD///8A////AP///wD///8A////AP///wD///8A////AP///wD75KwA+t2XAPrdlwD63ZcA+t2XAPfJWXb2vS3/86wH//OsB//zrAf/86wH//a/PVv4y2AA+MtgAPjLYAD+9uUA////AP///wD///8A////AP///wD///8A////AP///wD///8A+t6eAPnWhgD51oYA+daGAPjTfQ31uy/u8qkJ//KpCP/yqQj/8qkI//KpCP/2v0Y598ddAPfHXQD3x10A/vbkAP///wD///8A////AP///wD///8A////AP///wD///8A////APrcnQD504UA+dOFAPnThQD2wVRk87Ig//GlCf/xpQn/8aUJ//GlCf/xpQn/9b1JJPbCVgD2wlYA9sJWAP714wD///8A////AP///wD///8A////AP///wD///8A////AP///wD41pQA98x4APfMeAD3zHgA9Lg7svCiC//wogr/8KIK//CiCv/wogr/8KEJ//jOfCD51Y8A+dWPAPjRiAD+9+wA////AP///wD///8A////AP///wD///8A////AP///wD///8A9siDAPXAZAD2xWsA9sVrAfGoHOvvngv/754L/++eC//vngv/754L/++eC//ztUMm9LpPAPW/XQD0vWcA/vbrAP///wD///8A////AP///wD///8A////AP///wD///8A////APbIggDwoi0A87RPAPS8XhLwnxP/75oN/++aDf/vmg3/75oN/++aDf/vmg3/87RLQ/bFcwD52aYA9L9sAP726wD///8A////AP///wD///8A////AP///wD///8A////AP///wD2yIMA76ErAO2UDgDyrEEm7pgQ/+6WDv/ulg7/7pYO/+6WDv/ulg7/7pYO//O1U3b63K4A+dqqAPS+bAD+9usA////AP///wD///8A////AP///wD///8A////AP///wD///8A8rFUhO2TEO3tkw/v7ZMP8u2TD//tkw//7ZMP/+2TD//tkw//7ZMP/+2TD//tkxD67ZMQ8e2TEPHtkxHp/fHfE////wD///8A////AP///wD///8A////AP///wD///8A////APjVpSjtkhft7I8Q/+yPEP/sjxD/7I8Q/+yPEP/sjxD/7I8Q/+yPEP/sjxD/7I8Q/+yPEP/sjxD/8apJjf758QD///8A////AP///wD///8A////AP///wD///8A////AP///wD869UA9siLOOuMFPTrixH/64sR/+uLEf/rixH/64sR/+uLEf/rixH/64sR/+uLEf/rixH/76I/o/vjxAL++/YA////AP///wD///8A////AP///wD///8A////AP///wD///8A/OnRAPvjxgD0v35H6okT+eqIEv/qiBL/6ogS/+qIEv/qiBL/6ogS/+qIEv/qiBL/7pk1s/reuwT748UA/vr1AP///wD///8A////AP///wD///8A////AP///wD///8A////APzp0gD748cA++PIAPK1b1fqhBP96oQT/+qEE//qhBP/6oQT/+qEE//qhBP/7ZQwwvnduwn75cwA++XMAP779wD///8A////AP///wD///8A////AP///wD///8A////AP///wD86dUA++PKAPvjygD748oA8a1laOmBFP7pgRT/6YEU/+mBFP/pgRT/64wp0PjVsBD748kA++PJAPvjyQD++vYA////AP///wD///8A////AP///wD///8A////AP///wD///8A/OnWAPvjzAD748wA2cWxANG9qgDOjExo6H0W++h9Ff/ofRX/2nwgxs+ujhPaxLAA++LKAPviygD74soA/vr2AP///wD///8A////AP///wD///8A////AP///wD///8A////AIR7dAINCQgLAwAADwMAABMDAAAVAwAAF2k5EGvleBb5vWUWxRwRCCMDAAAVAwAAEwMAAA8NCQgLemxhAv769wD///8A////AP///wD///8A////AP///wD///8A////AP///wA1MzMFAwAAFgMAAB4DAAAiAwAAJQMAACcDAAAnIBAFOQgDASgDAAAnAwAAJQMAACMDAAAfAwAAFw0JCAXd3NsA////AP///wD///8A////AP///wD///8A////AP///wD///8AXVxcADUzMwE1MzMCNTMzAzUzMwQ1MzMFNTMzBjUzMwY1MzMGNTMzBTUzMwQ1MzMDNTMzAjUzMwE1MzMA3d3dAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A]] | |
FILE: [[recipes/icons/back.tiff]] base64[[TU0AKgAAACAAAALQAAAACgAAAtAAAAAKAAgACAAIAAgADwD+AAQAAAABAAAAAAEAAAQAAAABAAAAGQEBAAQAAAABAAAAGQECAAMAAAAEAAAAGAEDAAMAAAABAAEAAAEGAAMAAAABAAIAAAERAAQAAAABAAAA2gEVAAMAAAABAAQAAAEWAAQAAAABAAAAGQEXAAQAAAABAAAJxAEaAAUAAAABAAAACAEbAAUAAAABAAAAEAEcAAMAAAABAAEAAAEoAAMAAAABAAIAAAFSAAMAAAABAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOY4cCQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ4UVb06MHf8iQws3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArQAADQ4QUjXOkQP/r88D/IkIKbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhQQo9bJ46v8zelP/r9LH/8Pe//yFBCn8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACE+Cg1CgBOWgqxM/+XwqP/j75//4u+d/+v0sv8hQAl/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCfhKvssx6/+bxqf/f7Zj/3eyU/93slP/l8Kb/QX0R/0F9Ef9BfRH/QX0R/0F9Ef9BfRH/QX0R/0F9Ef9BfRH/QX0R/0F9Ef9BfhHKAAAAAAAAAAAAAAAAIT4HGyE8B09nljLEudF6/9jojv/V54j/1OaG/9Tmhv/U5ob/1eeK/9nqkv/a6pP/2uqT/9rqk//a6pP/2uqT/9rqk//a6pP/2uqT/9rqk//a6pP/k7Vd/wAAAAAAAAAAIDwHN0t/F/+3zXn/1eaN/8rgev/J33b/yd92/8nfdv/J33b/yd92/8nfdv/J33b/yd92/8nfdv/J33b/yd92/8nfdv/J33b/yd92/8nfdv/J33b/yd92/42wUf8AAAAAQIAVDFWFH8fJ3Yb/yeB8/8Lcb//A223/wNtt/8Dbbf/A223/wNtt/8Dbbf/A223/wNtt/8Dbbf/A223/wNtt/8Dbbf/A223/wNtt/8Dbbf/A223/wNtt/8Dbbf+JrUz/AAAAAD90C3WyzHL/vtls/7nWZP+41WP/uNVj/7jVY/+41WP/uNVj/7jVY/+41WP/uNVj/7jVY/+41WP/uNVj/7jVY/+41WP/uNVj/7jVY/+41WP/uNVj/7jVY/+41WP/hqpI/wAAAAA8cgU9cJko45nALf+NvBT/hLYH/4K1BP+CtQT/grUE/4K1BP+CtQT/grUE/4K1BP+CtQT/grUE/4K1BP+CtQT/grUE/4K1BP+CtQT/grUE/4K1BP+CtQT/grUE/3OeIv8AAAAAAAAAAB83BDZDcQz/iKs//5nCMf98sQr/d64D/3euA/93rgP/d64D/3euA/93rgP/d64D/3euA/93rgP/d64D/3euA/93rgP/d64D/3euA/93rgP/d64D/3euA/9umiH/AAAAAAAAAAAAAAAAO2kHJz1rB5ZkiyX/jrou/3OsB/9wqgP/cKoD/3CqA/9wqgP/cKoD/3CqA/9wqgP/cKoD/3CqA/9wqgP/cKoD/3CqA/9wqgP/cKoD/3CqA/9wqgP/bJch/wAAAAAAAAAAAAAAAAAAAAAAAAAAPWkGfmuSKf+Ityn/cKkL/2qlA/9ppQL/aaUC/3SsEP+PvDL/lb85/5W/Of+Vvzn/lb85/5W/Of+Vvzn/lb85/5W/Of+Vvzn/lb85/3meNP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfNAI+V30axnCZJ/94rSD/ZKIF/2GgAv+JuDL/Lk0Evx80A38fNAN/HzQDfx80A38fNAN/HzQDfx80A38fNAN/HzQDfx80A38fNANlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7YgNjXoIg/4S1Mv9log7/irk5/x4yAn8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADthAVhafh3/irRA/5zEUP8eMQF/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAADAAAABQAAAAcAAAALAAAADwAAABEAAAASHjAATzdUBK1igiXaGigRSwAAABQAAAATAAAAEQAAABAAAAAOAAAADAAAAAkAAAAHAAAABQAAAAQAAAACAAAAAQAAAAEAAAAEAAAADQAAABYAAAAgAAAAMQAAAEAAAABHAAAATAAAAE8AAABQAAAAUgAAAFEAAABPAAAATAAAAEYAAAA+AAAANQAAAC8AAAAmAAAAHAAAABcAAAARAAAACgAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA]] | |
FILE: [[recipes/authors.txt]] [[Sam Anklesaria | |
]] | |
FILE: [[recipes/recipes.factor]] [[USING: accessors arrays colors.constants combinators | |
db.sqlite db.tuples db.types kernel locals math | |
monads persistency sequences sequences.extras ui ui.gadgets.controls | |
ui.gadgets.layout models.combinators ui.gadgets.labels | |
ui.gadgets.scrollers ui.pens.solid io.files.temp ; | |
FROM: sets => prune ; | |
IN: recipes | |
STORED-TUPLE: recipe { title { VARCHAR 100 } } { votes INTEGER } { txt TEXT } { genre { VARCHAR 100 } } ; | |
: <recipe> ( title genre text -- recipe ) recipe new swap >>txt swap >>genre swap >>title 0 >>votes ; | |
"recipes.db" temp-file <sqlite-db> recipe define-db | |
: top-recipes ( offset search -- recipes ) <query> T{ recipe } rot >>title >>tuple | |
"votes" >>order 30 >>limit swap >>offset get-tuples ; | |
: top-genres ( -- genres ) f f top-recipes [ genre>> ] map prune 4 short head-slice ; | |
: interface ( -- book ) [ | |
[ | |
[ $ TOOLBAR $ ] <hbox> COLOR: AliceBlue <solid> >>interior , | |
[ "Genres:" <label> , <spacer> $ ALL $ $ GENRES $ ] <hbox> | |
{ 5 0 } >>gap COLOR: gray <solid> >>interior , | |
$ RECIPES $ | |
] <vbox> , | |
[ | |
[ "Title:" <label> , $ TITLE $ "Genre:" <label> , $ GENRE $ ] <hbox> , | |
$ BODY $ | |
$ BUTTON $ | |
] <vbox> , | |
] <book*> { 350 245 } >>pref-dim ; | |
:: recipe-browser ( -- ) [ [ | |
interface | |
<table*> :> tbl | |
"okay" <model-border-btn> BUTTON -> :> ok | |
IMG-MODEL-BTN: submit [ store-tuple ] >>value TOOLBAR -> :> submit | |
IMG-MODEL-BTN: love 1 >>value TOOLBAR -> | |
IMG-MODEL-BTN: hate -1 >>value -> 2array merge :> votes | |
IMG-MODEL-BTN: back -> [ -30 ] <$ | |
IMG-MODEL-BTN: more -> [ 30 ] <$ 2array merge :> viewed | |
<spacer> <model-field*> ->% 1 :> search | |
submit ok [ [ drop ] ] <$ 2array merge [ drop ] >>value :> quot | |
viewed 0 [ + ] fold search ok t <basic> "all" <model-btn> ALL -> | |
tbl selection>> votes [ [ + ] curry change-votes modify-tuple ] 2$> | |
4array merge | |
[ drop [ f ] [ "%" dup surround <pattern> ] if-empty top-recipes ] 3fmap :> ups | |
ups [ top-genres [ <model-btn> GENRES -> ] map merge ] bind* | |
[ text>> T{ recipe } swap >>genre get-tuples ] fmap | |
tbl swap ups 2merge >>model | |
[ [ title>> ] [ genre>> ] bi 2array ] >>quot | |
{ "Title" "Genre" } >>column-titles dup <scroller> RECIPES ,% 1 actions>> | |
submit [ "" dup dup <recipe> ] <$ 2array merge | |
{ [ [ title>> ] fmap <model-field> TITLE ->% .5 ] | |
[ [ genre>> ] fmap <model-field> GENRE ->% .5 ] | |
[ [ txt>> ] fmap <model-editor> BODY ->% 1 ] | |
} cleave | |
[ <recipe> ] 3fmap | |
[ [ 1 ] <$ ] | |
[ quot ok updates #1 [ call( recipe -- ) 0 ] 2fmap ] bi | |
2merge 0 <basic> switch-models >>model | |
] with-interface "recipes" open-window ] with-ui ; | |
MAIN: recipe-browser | |
]] | |
FILE: [[L-system/models/abop-5-angular/abop-5-angular.factor]] [[ | |
USING: accessors ui L-system ; | |
IN: L-system.models.abop-5-angular | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: abop-5-angular ( <L-system> -- <L-system> ) | |
L-parser-dialect >>commands | |
"&(90)+(90)a" >>axiom | |
{ | |
{ "a" "F[+(45)l][-(45)l]^;ca" } | |
{ "l" "j" } | |
{ "j" "h" } | |
{ "h" "s" } | |
{ "s" "d" } | |
{ "d" "x" } | |
{ "x" "a" } | |
{ "F" "'(1.17)F'(.855)" } | |
} | |
>>rules ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: main ( -- ) [ L-system abop-5-angular "L-system" open-window ] with-ui ; | |
MAIN: main | |
]] | |
FILE: [[L-system/models/abop-1/abop-1.factor]] [[ | |
USING: accessors ui L-system ; | |
IN: L-system.models.abop-1 | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: abop-1 ( <L-system> -- <L-system> ) | |
L-parser-dialect >>commands | |
"c(12)FFAL" >>axiom | |
{ | |
{ "A" "F [ & '(.8) ! B L ] >(137) ' !(.9) A" } | |
{ "B" "F [ - '(.8) !(.9) $ C L ] ' !(.9) C" } | |
{ "C" "F [ + '(.8) !(.9) $ B L ] ' !(.9) B" } | |
{ "L" " ~ c(8) { +(30) f -(120) f -(120) f }" } | |
} | |
>>rules ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: main ( -- ) [ L-system abop-1 "L-system" open-window ] with-ui ; | |
MAIN: main | |
]] | |
FILE: [[L-system/models/abop-6/abop-6.factor]] [[ | |
USING: accessors ui L-system ; | |
IN: L-system.models.abop-6 | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: abop-6 ( <L-system> -- <L-system> ) | |
L-parser-dialect >>commands | |
[ 5 >>angle ] >>turtle-values | |
! "&(90)+(90)FFF[-(120)'(.6)x][-(60)'(.8)x][+(120)'(.6)x][+(60)'(.8)x]x" | |
"FFF[-(120)'(.6)x][-(60)'(.8)x][+(120)'(.6)x][+(60)'(.8)x]x" | |
>>axiom | |
{ | |
{ "a" "F[cdx][cex]F!(.9)a" } | |
{ "x" "a" } | |
{ "d" "+d" } | |
{ "e" "-e" } | |
{ "F" "'(1.25)F'(.8)" } | |
} | |
>>rules ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: main ( -- ) [ L-system abop-6 "L-system" open-window ] with-ui ; | |
MAIN: main | |
]] | |
FILE: [[L-system/models/abop-5/abop-5.factor]] [[ | |
USING: accessors ui L-system ; | |
IN: L-system.models.abop-5 | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: abop-5 ( <L-system> -- <L-system> ) | |
L-parser-dialect >>commands | |
[ 5 >>angle ] >>turtle-values | |
"a" >>axiom | |
{ | |
{ "a" "F[+(45)l][-(45)l]^;ca" } | |
{ "l" "j" } | |
{ "j" "h" } | |
{ "h" "s" } | |
{ "s" "d" } | |
{ "d" "x" } | |
{ "x" "a" } | |
{ "F" "'(1.17)F'(.855)" } | |
} | |
>>rules ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: main ( -- ) [ L-system abop-5 "L-system" open-window ] with-ui ; | |
MAIN: main | |
]] | |
FILE: [[L-system/models/abop-2/abop-2.factor]] [[ | |
USING: accessors ui L-system ; | |
IN: L-system.models.abop-2 | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: abop-2 ( <L-system> -- <L-system> ) | |
L-parser-dialect >>commands | |
[ 30 >>angle ] >>turtle-values | |
"c(12)FAL" >>axiom | |
{ | |
{ "A" "F [&'(.7)!BL] >(137) [&'(.6)!BL] >(137) '(.9) !(.9) A" } | |
{ "B" "F [- '(.7) !(.9) $ C L] '(.9) !(.9) C" } | |
{ "C" "F [+ '(.7) !(.9) $ B L] '(.9) !(.9) B" } | |
{ "L" "~c(8){+f(.1)-f(.1)-f(.1)+|+f(.1)-f(.1)-f(.1)}" } | |
} >>rules ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: main ( -- ) [ L-system abop-2 "L-system" open-window ] with-ui ; | |
MAIN: main | |
]] | |
FILE: [[L-system/models/tree-5/tree-5.factor]] [[ | |
USING: accessors ui L-system ; | |
IN: L-system.models.tree-5 | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: tree-5 ( <L-system> -- <L-system> ) | |
L-parser-dialect >>commands | |
[ 5 >>angle ] >>turtle-values | |
"c(4)FFS" >>axiom | |
{ | |
{ "S" "FFR>(60)R>(60)R>(60)R>(60)R>(60)R>(30)S" } | |
{ "R" "[Ba]" } | |
{ "a" "$tF[Cx]Fb" } | |
{ "b" "$tF[Dy]Fa" } | |
{ "B" "&B" } | |
{ "C" "+C" } | |
{ "D" "-D" } | |
{ "x" "a" } | |
{ "y" "b" } | |
{ "F" "'(1.25)F'(.8)" } | |
} | |
>>rules ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: main ( -- ) [ L-system tree-5 "L-system" open-window ] with-ui ; | |
MAIN: main | |
]] | |
FILE: [[L-system/models/airhorse/airhorse.factor]] [=[ | |
USING: accessors ui L-system ; | |
IN: L-system.models.airhorse | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: airhorse ( <L-system> -- <L-system> ) | |
L-parser-dialect >>commands | |
[ 10 >>angle ] >>turtle-values | |
"C" >>axiom | |
{ | |
{ "C" "LBW" } | |
{ "B" "[[''aH]|[g]]" } | |
{ "a" "Fs+;'a" } | |
{ "g" "Ft+;'g" } | |
{ "s" "[::cc!!!!&&[FFcccZ]^^^^FFcccZ]" } | |
{ "t" "[c!!!!&[FF]^^FF]" } | |
{ "L" "O" } | |
{ "O" "P" } | |
{ "P" "Q" } | |
{ "Q" "R" } | |
{ "R" "U" } | |
{ "U" "X" } | |
{ "X" "Y" } | |
{ "Y" "V" } | |
{ "V" "[cc!!!&(90)[Zp]|[Zp]]" } | |
{ "p" "h>(120)h>(120)h" } | |
{ "h" "[+(40)!F'''p]" } | |
{ "H" "[cccci[>(50)dcFFF][<(50)ecFFF]]" } | |
{ "d" "Z!&Z!&:'d" } | |
{ "e" "Z!^Z!^:'e" } | |
{ "i" "-:/i" } | |
{ "W" "[%[!!cb][<<<!!cb][>>>!!cb]]" } | |
{ "b" "Fl!+Fl+;'b" } | |
{ "l" "[-cc{--z++z++z--|--z++z++z}]" } | |
} | |
>>rules ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: main ( -- ) [ L-system airhorse "L-system" open-window ] with-ui ; | |
MAIN: main | |
]=] | |
FILE: [[L-system/models/abop-3/abop-3.factor]] [[ | |
USING: accessors ui L-system ; | |
IN: L-system.models.abop-3 | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: abop-3 ( <L-system> -- <L-system> ) | |
L-parser-dialect >>commands | |
[ 30 >>angle ] >>turtle-values | |
"c(12)FA" >>axiom | |
{ | |
{ "A" "!(.9)t(.4)FB>(94)B>(132)B" } | |
{ "B" "[&t(.4)F$A]" } | |
{ "F" "'(1.25)F'(.8)" } | |
} | |
>>rules ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: main ( -- ) [ L-system abop-3 "L-system" open-window ] with-ui ; | |
MAIN: main | |
]] | |
FILE: [[L-system/models/abop-4/abop-4.factor]] [[ | |
USING: accessors ui L-system ; | |
IN: L-system.models.abop-4 | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: abop-4 ( <L-system> -- <L-system> ) | |
L-parser-dialect >>commands | |
[ 18 >>angle ] >>turtle-values | |
"c(12)&(20)N" >>axiom | |
{ | |
{ | |
"N" | |
"FII[&(60)rY]>(90)[&(45)'(0.8)rA]>(90)[&(60)rY]>(90)[&(45)'(0.8)rD]!FIK" | |
} | |
{ "Y" "[c(4){++l.--l.--l.++|++l.--l.--l.}]" } | |
{ "l" "g(.2)l" } | |
{ "K" "[!c(2)FF>w>(72)w>(72)w>(72)w>(72)w]" } | |
{ "w" "[c(2)^!F][c(5)&(72){-(54)f(3)+(54)f(3)|-(54)f(3)+(54)f(3)}]" } | |
{ "f" "_" } | |
{ "A" "B" } | |
{ "B" "C" } | |
{ "C" "D" } | |
{ "D" "E" } | |
{ "E" "G" } | |
{ "G" "H" } | |
{ "H" "N" } | |
{ "I" "FoO" } | |
{ "O" "FoP" } | |
{ "P" "FoQ" } | |
{ "Q" "FoR" } | |
{ "R" "FoS" } | |
{ "S" "FoT" } | |
{ "T" "FoU" } | |
{ "U" "FoV" } | |
{ "V" "FoW" } | |
{ "W" "FoX" } | |
{ "X" "_" } | |
{ "o" "$t(-0.03)" } | |
{ "r" "~(30)" } | |
} | |
>>rules ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: main ( -- ) [ L-system abop-4 "L-system" open-window ] with-ui ; | |
MAIN: main | |
]] | |
FILE: [[L-system/L-system.factor]] [[ | |
USING: accessors arrays assocs calendar colors | |
combinators.short-circuit help.markup help.syntax kernel locals | |
math math.functions math.matrices math.order math.parser | |
math.trig math.vectors opengl opengl.demo-support opengl.gl | |
sbufs sequences strings threads ui.gadgets ui.gadgets.worlds | |
ui.gestures ui.render ui.tools.workspace ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
IN: L-system | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
TUPLE: <turtle> pos ori angle length thickness color vertices saved ; | |
DEFER: default-L-parser-values | |
: reset-turtle ( turtle -- turtle ) | |
{ 0 0 0 } clone >>pos | |
3 identity-matrix >>ori | |
V{ } clone >>vertices | |
V{ } clone >>saved | |
default-L-parser-values ; | |
: turtle ( -- turtle ) <turtle> new reset-turtle ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
:: step-turtle ( TURTLE LENGTH -- turtle ) | |
TURTLE | |
TURTLE pos>> TURTLE ori>> { 0 0 LENGTH } m.v v+ | |
>>pos ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
:: Rx ( ANGLE -- Rx ) | |
[let | ANGLE [ ANGLE deg>rad ] | | |
[let | A [ ANGLE cos ] | |
B [ ANGLE sin neg ] | |
C [ ANGLE sin ] | |
D [ ANGLE cos ] | | |
{ { 1 0 0 } | |
{ 0 A B } | |
{ 0 C D } } | |
] ] ; | |
:: Ry ( ANGLE -- Ry ) | |
[let | ANGLE [ ANGLE deg>rad ] | | |
[let | A [ ANGLE cos ] | |
B [ ANGLE sin ] | |
C [ ANGLE sin neg ] | |
D [ ANGLE cos ] | | |
{ { A 0 B } | |
{ 0 1 0 } | |
{ C 0 D } } | |
] ] ; | |
:: Rz ( ANGLE -- Rz ) | |
[let | ANGLE [ ANGLE deg>rad ] | | |
[let | A [ ANGLE cos ] | |
B [ ANGLE sin neg ] | |
C [ ANGLE sin ] | |
D [ ANGLE cos ] | | |
{ { A B 0 } | |
{ C D 0 } | |
{ 0 0 1 } } | |
] ] ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
:: apply-rotation ( TURTLE ROTATION -- turtle ) | |
TURTLE TURTLE ori>> ROTATION m. >>ori ; | |
: rotate-x ( turtle angle -- turtle ) Rx apply-rotation ; | |
: rotate-y ( turtle angle -- turtle ) Ry apply-rotation ; | |
: rotate-z ( turtle angle -- turtle ) Rz apply-rotation ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: pitch-up ( turtle angle -- turtle ) neg rotate-x ; | |
: pitch-down ( turtle angle -- turtle ) rotate-x ; | |
: turn-left ( turtle angle -- turtle ) rotate-y ; | |
: turn-right ( turtle angle -- turtle ) neg rotate-y ; | |
: roll-left ( turtle angle -- turtle ) neg rotate-z ; | |
: roll-right ( turtle angle -- turtle ) rotate-z ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: V ( -- V ) { 0 1 0 } ; | |
: X ( turtle -- 3array ) ori>> [ first ] map ; | |
: Y ( turtle -- 3array ) ori>> [ second ] map ; | |
: Z ( turtle -- 3array ) ori>> [ third ] map ; | |
: set-X ( turtle seq -- turtle ) over ori>> [ set-first ] 2each ; | |
: set-Y ( turtle seq -- turtle ) over ori>> [ set-second ] 2each ; | |
: set-Z ( turtle seq -- turtle ) over ori>> [ set-third ] 2each ; | |
:: roll-until-horizontal ( TURTLE -- turtle ) | |
TURTLE | |
V TURTLE Z cross normalize set-X | |
TURTLE Z TURTLE X cross normalize set-Y ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
:: strafe-up ( TURTLE LENGTH -- turtle ) | |
TURTLE 90 pitch-up LENGTH step-turtle 90 pitch-down ; | |
:: strafe-down ( TURTLE LENGTH -- turtle ) | |
TURTLE 90 pitch-down LENGTH step-turtle 90 pitch-up ; | |
:: strafe-left ( TURTLE LENGTH -- turtle ) | |
TURTLE 90 turn-left LENGTH step-turtle 90 turn-right ; | |
:: strafe-right ( TURTLE LENGTH -- turtle ) | |
TURTLE 90 turn-right LENGTH step-turtle 90 turn-left ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: polygon ( vertices -- ) GL_POLYGON glBegin [ first3 glVertex3d ] each glEnd ; | |
: start-polygon ( turtle -- turtle ) dup vertices>> delete-all ; | |
: finish-polygon ( turtle -- turtle ) dup vertices>> polygon ; | |
: polygon-vertex ( turtle -- turtle ) dup [ pos>> ] [ vertices>> ] bi push ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: record-vertex ( turtle -- turtle ) dup pos>> first3 glVertex3d ; | |
: draw-forward ( turtle length -- turtle ) | |
GL_LINES glBegin [ record-vertex ] dip step-turtle record-vertex glEnd ; | |
: move-forward ( turtle length -- turtle ) step-turtle polygon-vertex ; | |
: sneak-forward ( turtle length -- turtle ) step-turtle ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: scale-length ( turtle m -- turtle ) over length>> * >>length ; | |
: scale-angle ( turtle m -- turtle ) over angle>> * >>angle ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: set-thickness ( turtle i -- turtle ) dup glLineWidth >>thickness ; | |
: scale-thickness ( turtle m -- turtle ) | |
over thickness>> * 0.5 max set-thickness ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: color-table ( -- colors ) | |
{ | |
T{ rgba f 0 0 0 1 } ! black | |
T{ rgba f 0.5 0.5 0.5 1 } ! grey | |
T{ rgba f 1 0 0 1 } ! red | |
T{ rgba f 1 1 0 1 } ! yellow | |
T{ rgba f 0 1 0 1 } ! green | |
T{ rgba f 0.25 0.88 0.82 1 } ! turquoise | |
T{ rgba f 0 0 1 1 } ! blue | |
T{ rgba f 0.63 0.13 0.94 1 } ! purple | |
T{ rgba f 0.00 0.50 0.00 1 } ! dark green | |
T{ rgba f 0.00 0.82 0.82 1 } ! dark turquoise | |
T{ rgba f 0.00 0.00 0.50 1 } ! dark blue | |
T{ rgba f 0.58 0.00 0.82 1 } ! dark purple | |
T{ rgba f 0.50 0.00 0.00 1 } ! dark red | |
T{ rgba f 0.25 0.25 0.25 1 } ! dark grey | |
T{ rgba f 0.75 0.75 0.75 1 } ! medium grey | |
T{ rgba f 1 1 1 1 } ! white | |
} ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! : material-color ( color -- ) | |
! GL_FRONT_AND_BACK GL_AMBIENT_AND_DIFFUSE rot gl-material ; | |
: material-color ( color -- ) | |
GL_FRONT_AND_BACK GL_AMBIENT_AND_DIFFUSE rot color>raw 4array gl-material ; | |
: set-color ( turtle i -- turtle ) | |
dup color-table nth dup gl-color material-color >>color ; | |
: inc-color ( turtle -- turtle ) dup color>> 1 + set-color ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: save-turtle ( turtle -- turtle ) dup clone over saved>> push ; | |
: restore-turtle ( turtle -- turtle ) saved>> pop dup color>> set-color ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: default-L-parser-values ( turtle -- turtle ) | |
1 >>length 45 >>angle 1 >>thickness 2 >>color ; | |
: L-parser-dialect ( -- commands ) | |
{ | |
{ "+" [ dup angle>> turn-left ] } | |
{ "-" [ dup angle>> turn-right ] } | |
{ "&" [ dup angle>> pitch-down ] } | |
{ "^" [ dup angle>> pitch-up ] } | |
{ "<" [ dup angle>> roll-left ] } | |
{ ">" [ dup angle>> roll-right ] } | |
{ "|" [ 180.0 rotate-y ] } | |
{ "%" [ 180.0 rotate-z ] } | |
{ "$" [ roll-until-horizontal ] } | |
{ "F" [ dup length>> draw-forward ] } | |
{ "Z" [ dup length>> 2 / draw-forward ] } | |
{ "f" [ dup length>> move-forward ] } | |
{ "z" [ dup length>> 2 / move-forward ] } | |
{ "g" [ dup length>> sneak-forward ] } | |
{ "." [ polygon-vertex ] } | |
{ "[" [ save-turtle ] } | |
{ "]" [ restore-turtle ] } | |
{ "{" [ start-polygon ] } | |
{ "}" [ finish-polygon ] } | |
{ "/" [ 1.1 scale-length ] } ! double quote command in lparser | |
{ "'" [ 0.9 scale-length ] } | |
{ ";" [ 1.1 scale-angle ] } | |
{ ":" [ 0.9 scale-angle ] } | |
{ "?" [ 1.4 scale-thickness ] } | |
{ "!" [ 0.7 scale-thickness ] } | |
{ "c" [ dup color>> 1 + color-table length mod set-color ] } | |
} | |
; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
TUPLE: <L-system> < gadget | |
camera display-list pedestal paused | |
turtle-values | |
commands axiom rules string ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
:: iterate-system ( GADGET -- ) GADGET pedestal>> 0.5 + GADGET pedestal<< ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
:: start-rotation-thread ( GADGET -- ) | |
GADGET f >>paused drop | |
[ | |
[ | |
GADGET paused>> | |
[ f ] | |
[ GADGET iterate-system GADGET relayout-1 25 milliseconds sleep t ] | |
if | |
] | |
loop | |
] | |
in-thread ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: open-paren ( -- ch ) CHAR: ( ; | |
: close-paren ( -- ch ) CHAR: ) ; | |
: open-paren? ( obj -- ? ) open-paren = ; | |
: close-paren? ( obj -- ? ) close-paren = ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
:: read-instruction ( STRING -- next rest ) | |
{ [ STRING length 1 > ] [ STRING second open-paren? ] } 0&& | |
[ STRING close-paren STRING index 1 + cut ] | |
[ STRING 1 cut ] | |
if ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
:: iterate-string-loop ( STRING RULES ACCUM -- ) | |
STRING empty? not | |
[ | |
STRING read-instruction | |
[let | REST [ ] NEXT [ ] | | |
NEXT 1 head RULES at NEXT or ACCUM push-all | |
REST RULES ACCUM iterate-string-loop ] | |
] | |
when ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
:: iterate-string ( STRING RULES -- string ) | |
[let | ACCUM [ STRING length 10 * <sbuf> ] | | |
STRING RULES ACCUM iterate-string-loop | |
ACCUM >string ] ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
:: interpret-string ( STRING COMMANDS -- ) | |
STRING empty? not | |
[ | |
STRING read-instruction | |
[let | REST [ ] NEXT [ ] | | |
[let | COMMAND [ NEXT 1 head COMMANDS at ] | | |
COMMAND | |
[ | |
NEXT length 1 = | |
[ COMMAND call ] | |
[ | |
NEXT 2 tail 1 head* string>number | |
COMMAND 1 tail* | |
call | |
] | |
if | |
] | |
when ] | |
REST COMMANDS interpret-string ] | |
] | |
when ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
:: iterate-L-system-string ( L-SYSTEM -- ) | |
L-SYSTEM string>> L-SYSTEM axiom>> or | |
L-SYSTEM rules>> | |
iterate-string | |
L-SYSTEM string<< ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
:: do-camera-look-at ( CAMERA -- ) | |
[let | EYE [ CAMERA pos>> ] | |
FOCUS [ CAMERA clone 1 step-turtle pos>> ] | |
UP [ CAMERA clone 90 pitch-up 1 step-turtle pos>> CAMERA pos>> v- ] | |
| | |
EYE FOCUS UP gl-look-at ] ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
:: generate-display-list ( L-SYSTEM -- ) | |
L-SYSTEM find-gl-context | |
L-SYSTEM display-list>> GL_COMPILE glNewList | |
turtle | |
L-SYSTEM turtle-values>> [ ] or call | |
L-SYSTEM string>> L-SYSTEM axiom>> or | |
L-SYSTEM commands>> | |
interpret-string | |
drop | |
glEndList ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
M:: <L-system> draw-gadget* ( L-SYSTEM -- ) | |
black gl-clear | |
GL_FLAT glShadeModel | |
GL_PROJECTION glMatrixMode | |
glLoadIdentity | |
-1 1 -1 1 1.5 200 glFrustum | |
GL_MODELVIEW glMatrixMode | |
glLoadIdentity | |
L-SYSTEM camera>> do-camera-look-at | |
GL_FRONT_AND_BACK GL_LINE glPolygonMode | |
! draw axis | |
white gl-color GL_LINES glBegin { 0 0 0 } gl-vertex { 0 0 1 } gl-vertex glEnd | |
! rotate pedestal | |
L-SYSTEM pedestal>> 0 0 1 glRotated | |
L-SYSTEM display-list>> glCallList ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
M:: <L-system> graft* ( L-SYSTEM -- ) | |
L-SYSTEM find-gl-context | |
1 glGenLists L-SYSTEM display-list<< ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
M:: <L-system> pref-dim* ( L-SYSTEM -- dim ) { 400 400 } ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
:: with-camera ( L-SYSTEM QUOT -- ) | |
L-SYSTEM camera>> QUOT call drop | |
L-SYSTEM relayout-1 ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
<L-system> | |
H{ | |
{ T{ key-down f f "LEFT" } [ [ 5 turn-left ] with-camera ] } | |
{ T{ key-down f f "RIGHT" } [ [ 5 turn-right ] with-camera ] } | |
{ T{ key-down f f "UP" } [ [ 5 pitch-down ] with-camera ] } | |
{ T{ key-down f f "DOWN" } [ [ 5 pitch-up ] with-camera ] } | |
{ T{ key-down f f "a" } [ [ 1 step-turtle ] with-camera ] } | |
{ T{ key-down f f "z" } [ [ -1 step-turtle ] with-camera ] } | |
{ T{ key-down f f "q" } [ [ 5 roll-left ] with-camera ] } | |
{ T{ key-down f f "w" } [ [ 5 roll-right ] with-camera ] } | |
{ T{ key-down f { A+ } "LEFT" } [ [ 1 strafe-left ] with-camera ] } | |
{ T{ key-down f { A+ } "RIGHT" } [ [ 1 strafe-right ] with-camera ] } | |
{ T{ key-down f { A+ } "UP" } [ [ 1 strafe-up ] with-camera ] } | |
{ T{ key-down f { A+ } "DOWN" } [ [ 1 strafe-down ] with-camera ] } | |
{ T{ key-down f f "r" } [ start-rotation-thread ] } | |
{ | |
T{ key-down f f "x" } | |
[ | |
dup iterate-L-system-string | |
dup generate-display-list | |
dup relayout-1 | |
drop | |
] | |
} | |
{ T{ key-down f f "F1" } [ drop "L-system" help-window ] } | |
} | |
set-gestures | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: L-system ( -- L-system ) | |
<L-system> new-gadget | |
0 >>pedestal | |
! turtle 45 turn-left 45 pitch-up 5 step-turtle 180 turn-left >>camera ; | |
turtle 90 pitch-down -5 step-turtle 2 strafe-up >>camera | |
dup start-rotation-thread | |
; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
ARTICLE: "L-system" "L-system" | |
"Press 'x' to iterate the L-system." $nl | |
"Camera control:" | |
{ $table | |
{ "a" "Forward" } | |
{ "z" "Backward" } | |
{ "LEFT" "Turn left" } | |
{ "RIGHT" "Turn right" } | |
{ "UP" "Pitch down" } | |
{ "DOWN" "Pitch up" } | |
{ "q" "Roll left" } | |
{ "w" "Roll right" } } ; | |
ABOUT: "L-system" | |
]] | |
FILE: [[persistency/persistency.factor]] [[USING: accessors arrays byte-arrays calendar classes | |
classes.tuple classes.tuple.parser combinators db db.queries | |
db.tuples db.types kernel math nmake parser sequences strings | |
strings.parser unicode urls words ; | |
IN: persistency | |
TUPLE: persistent id ; | |
: add-types ( table -- table' ) [ dup array? [ [ first dup >upper ] [ second ] bi 3array ] | |
[ dup >upper FACTOR-BLOB 3array ] if | |
] map { "id" "ID" +db-assigned-id+ } prefix ; | |
: remove-types ( table -- table' ) [ dup array? [ first ] when ] map ; | |
SYNTAX: STORED-TUPLE: parse-tuple-definition [ drop persistent ] dip [ remove-types define-tuple-class ] | |
[ nip [ dup name>> >upper ] [ add-types ] bi* define-persistent ] 3bi ; | |
: define-db ( database class -- ) swap [ [ ensure-table ] with-db ] [ "database" set-word-prop ] 2bi ; | |
: query>tuple ( tuple/query -- tuple ) dup query? [ tuple>> ] when ; | |
: w/db ( query quot -- ) [ dup query>tuple class-of "database" word-prop ] dip with-db ; inline | |
: get-tuples ( query -- tuples ) [ select-tuples ] w/db ; | |
: get-tuple ( query -- tuple ) [ select-tuple ] w/db ; | |
: store-tuple ( tuple -- ) [ insert-tuple ] w/db ; | |
: modify-tuple ( tuple -- ) [ update-tuple ] w/db ; | |
: remove-tuples ( tuple -- ) [ delete-tuples ] w/db ; | |
TUPLE: pattern value ; C: <pattern> pattern | |
SYNTAX: %" parse-string <pattern> suffix! ; | |
M: pattern where value>> over column-name>> 0% " LIKE " 0% bind# ; | |
]] | |
FILE: [[persistency/authors.txt]] [[Sam Anklesaria | |
]] | |
FILE: [[cfdg/cfdg.factor]] [[ | |
USING: kernel alien.c-types combinators namespaces make arrays | |
sequences splitting | |
math math.functions math.vectors math.trig | |
opengl.gl opengl.glu opengl ui ui.gadgets.slate | |
vars colors self self.slots | |
random-weighted colors.hsv cfdg.gl accessors | |
ui.gadgets.handler ui.gestures assocs ui.gadgets macros | |
specialized-arrays.double ; | |
QUALIFIED: syntax | |
IN: cfdg | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
SELF-SLOTS: hsva | |
: clear-color ( color -- ) gl-clear-color GL_COLOR_BUFFER_BIT glClear ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! if (adjustment < 0) | |
! base + base * adjustment | |
! if (adjustment > 0) | |
! base + (1 - base) * adjustment | |
: adjust ( val num -- val ) dup 0 > [ 1 pick - * + ] [ dupd * + ] if ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: hue ( num -- ) hue-> + 360 mod ->hue ; | |
: saturation ( num -- ) saturation-> swap adjust ->saturation ; | |
: brightness ( num -- ) value-> swap adjust ->value ; | |
: alpha ( num -- ) alpha-> swap adjust ->alpha ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: h ( num -- ) hue ; | |
: sat ( num -- ) saturation ; | |
: b ( num -- ) brightness ; | |
: a ( num -- ) alpha ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
VAR: color-stack | |
: init-color-stack ( -- ) V{ } clone >color-stack ; | |
: push-color ( -- ) self> color-stack> push self> clone >self ; | |
: pop-color ( -- ) color-stack> pop dup >self gl-color ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! : double-nth* ( c-array indices -- seq ) swap [ double-nth ] curry map ; | |
: double-nth* ( c-array indices -- seq ) | |
swap byte-array>double-array [ nth ] curry map ; | |
: check-size ( modelview -- num ) { 0 1 4 5 } double-nth* [ abs ] map supremum ; | |
VAR: threshold | |
: iterate? ( -- ? ) get-modelview-matrix check-size threshold> > ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! cos 2a sin 2a 0 0 | |
! sin 2a -cos 2a 0 0 | |
! 0 0 1 0 | |
! 0 0 0 1 | |
! column major order | |
: gl-flip ( angle -- ) deg>rad dup dup dup | |
[ 2 * cos , 2 * sin , 0 , 0 , | |
2 * sin , 2 * cos neg , 0 , 0 , | |
0 , 0 , 1 , 0 , | |
0 , 0 , 0 , 1 , ] | |
double-array{ } make underlying>> glMultMatrixd ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: circle ( -- ) | |
self> gl-color | |
gluNewQuadric dup 0 0.5 20 10 gluDisk gluDeleteQuadric ; | |
: triangle ( -- ) | |
self> gl-color | |
GL_POLYGON glBegin | |
0 0.577 glVertex2d | |
0.5 -0.289 glVertex2d | |
-0.5 -0.289 glVertex2d | |
glEnd ; | |
: square ( -- ) | |
self> gl-color | |
GL_POLYGON glBegin | |
-0.5 0.5 glVertex2d | |
0.5 0.5 glVertex2d | |
0.5 -0.5 glVertex2d | |
-0.5 -0.5 glVertex2d | |
glEnd ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: size ( scale -- ) dup 1 glScaled ; | |
: size* ( scale-x scale-y -- ) 1 glScaled ; | |
: rotate ( angle -- ) 0 0 1 glRotated ; | |
: x ( x -- ) 0 0 glTranslated ; | |
: y ( y -- ) 0 swap 0 glTranslated ; | |
: flip ( angle -- ) gl-flip ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: s ( scale -- ) size ; | |
: s* ( scale-x scale-y -- ) size* ; | |
: r ( angle -- ) rotate ; | |
: f ( angle -- ) flip ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: do ( quot -- ) | |
push-modelview-matrix | |
push-color | |
call | |
pop-modelview-matrix | |
pop-color ; inline | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: recursive ( quot -- ) iterate? swap when ; inline | |
: multi ( seq -- ) random-weighted* call ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: [rules] ( seq -- quot ) | |
[ unclip swap [ [ do ] curry ] map concat 2array ] map | |
[ call-random-weighted ] swap prefix | |
[ when ] swap prefix | |
[ iterate? ] swap append ; | |
MACRO: rules ( seq -- quot ) [rules] ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: [rule] ( seq -- quot ) | |
[ [ do ] swap prefix ] map concat | |
[ when ] swap prefix | |
[ iterate? ] prepend ; | |
MACRO: rule ( seq -- quot ) [rule] ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
VAR: background | |
: set-initial-background ( -- ) T{ hsva f 0 0 1 1 } clone >self ; | |
: set-background ( -- ) | |
set-initial-background | |
background> call | |
self> clear-color ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
USING: rewrite-closures ; | |
VAR: viewport ! { left width bottom height } | |
VAR: start-shape | |
: set-initial-color ( -- ) T{ hsva f 0 0 0 1 } clone >self ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
SYMBOL: dlist | |
! : build-model-dlist ( -- ) | |
! 1 glGenLists dlist set | |
! dlist get GL_COMPILE_AND_EXECUTE glNewList | |
! start-shape> call | |
! glEndList ; | |
: build-model-dlist ( -- ) | |
1 glGenLists dlist set | |
dlist get GL_COMPILE_AND_EXECUTE glNewList | |
set-initial-color | |
self> gl-color | |
start-shape> call | |
glEndList ; | |
: display ( -- ) | |
GL_PROJECTION glMatrixMode | |
glLoadIdentity | |
viewport> first dup viewport> second + | |
viewport> third dup viewport> fourth + gluOrtho2D | |
GL_MODELVIEW glMatrixMode | |
glLoadIdentity | |
set-background | |
GL_COLOR_BUFFER_BIT glClear | |
init-modelview-matrix-stack | |
init-color-stack | |
dlist get not | |
[ build-model-dlist ] | |
[ dlist get glCallList ] | |
if ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: delete-dlist ( -- ) dlist get [ dlist get 1 glDeleteLists dlist off ] when ; | |
: cfdg-window* ( -- slate ) | |
C[ display ] <slate> | |
{ 500 500 } >>pdim | |
C[ delete-dlist ] >>ungraft | |
dup "CFDG" open-window ; | |
: cfdg-window ( -- slate ) [ cfdg-window* ] with-ui ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
SYMBOL: the-slate | |
: rebuild ( -- ) delete-dlist the-slate get relayout-1 ; | |
: <cfdg-gadget> ( -- slate ) | |
C[ display ] <slate> | |
dup the-slate set | |
{ 500 500 } >>pdim | |
C[ dlist get [ dlist get 1 glDeleteLists ] when ] >>ungraft | |
<handler> | |
H{ } clone | |
T{ key-down f f "ENTER" } C[ drop rebuild ] swap pick set-at | |
T{ button-down } C[ drop rebuild ] swap pick set-at | |
>>table ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
USE: fry | |
: cfdg-window. ( quot -- ) | |
'[ [ @ <cfdg-gadget> "CFDG" open-window ] with-scope ] with-ui ; | |
]] | |
FILE: [[cfdg/models/sierpinski/sierpinski.factor]] [[ | |
USING: kernel namespaces math opengl.gl opengl.glu ui ui.gadgets.slate | |
random-weighted cfdg ; | |
IN: cfdg.models.sierpinski | |
: shape ( -- ) circle ; | |
! : sierpinski ( -- ) | |
! iterate? [ | |
! shape | |
! [ 0.6 s 5 r 0.2 b -1.5 y 0 x sierpinski ] do | |
! [ 0.6 s 5 r -0.2 b 0.75 y -1.2990375 x sierpinski ] do | |
! [ 0.6 s 5 r 0.75 y 1.2990375 x sierpinski ] do | |
! ] when ; | |
: sierpinski ( -- ) | |
iterate? [ | |
shape | |
[ -1.5 y 0 x 0.6 s 5 r 0.2 b sierpinski ] do | |
[ 0.75 y -1.2990375 x 0.6 s 5 r -0.2 b sierpinski ] do | |
[ 0.75 y 1.2990375 x 0.6 s 5 r sierpinski ] do | |
] when ; | |
: top ( -- ) [ -13.5 r 0.5 b sierpinski ] do ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: init ( -- ) | |
[ ] >background | |
{ -4 8 -4 8 } >viewport | |
0.01 >threshold | |
[ top ] >start-shape ; | |
: run ( -- ) [ init ] cfdg-window. ; | |
MAIN: run | |
]] | |
FILE: [[cfdg/models/sierpinski/authors.txt]] [[Eduardo Cavazos | |
]] | |
FILE: [[cfdg/models/sierpinski/tags.txt]] [[demos | |
]] | |
FILE: [[cfdg/models/game1-turn6/game1-turn6.factor]] [[ | |
USING: kernel namespaces math opengl.gl opengl.glu ui ui.gadgets.slate | |
random-weighted cfdg ; | |
IN: cfdg.models.game1-turn6 | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: f-triangles ( -- ) | |
{ | |
[ 0.1 x 0.1 y -0.33 alpha 20 hue 0.7 sat 0.80 b triangle ] | |
[ 10 hue 0.9 sat 0.33 b triangle ] | |
[ 0.9 s 10 hue 0.5 sat 1.00 b triangle ] | |
[ 0.8 s 5 r f-triangles ] | |
} | |
rule ; | |
: f-squares ( -- ) | |
{ | |
[ 0.1 x 0.1 y -0.33 alpha 250 hue 0.70 sat 0.80 b square ] | |
[ 220 hue 0.90 sat 0.33 b square ] | |
[ 0.9 s 220 hue 0.25 sat 1.00 b square ] | |
[ 0.8 s 5 r f-squares ] | |
} | |
rule ; | |
DEFER: start | |
: spiral ( -- ) | |
{ | |
{ 1 [ f-squares ] | |
[ 0.5 x 0.5 y 45 r f-triangles ] | |
[ 1 y 25 r 0.9 s spiral ] } | |
{ 0.022 [ 90 flip 50 hue start ] } | |
} | |
rules ; | |
: start ( -- ) | |
[ spiral ] do | |
[ 120 r spiral ] do | |
[ 240 r spiral ] do ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: init ( -- ) | |
[ 66 hue 0.4 sat 0.5 b ] >background | |
{ -5 10 -5 10 } >viewport | |
0.001 >threshold | |
[ start ] >start-shape ; | |
: run ( -- ) [ init ] cfdg-window. ; | |
MAIN: run | |
]] | |
FILE: [[cfdg/models/game1-turn6/authors.txt]] [[Eduardo Cavazos | |
]] | |
FILE: [[cfdg/models/game1-turn6/tags.txt]] [[demos | |
]] | |
FILE: [[cfdg/models/aqua-star/aqua-star.factor]] [[ | |
USING: kernel namespaces math random opengl.gl opengl.glu ui ui.gadgets.slate | |
random-weighted cfdg ; | |
IN: cfdg.models.aqua-star | |
: tentacle ( -- ) | |
iterate? [ | |
{ { 1 [ circle | |
[ .23 y .99 s .002 b tentacle ] do ] } | |
{ 1 [ circle | |
[ .17 y 2 r .99 s .002 b tentacle ] do ] } | |
{ 1 [ circle | |
[ .12 y -2 r .99 s .001 b tentacle ] do ] } } | |
call-random-weighted | |
] when ; | |
: anemone ( -- ) | |
iterate? [ | |
tentacle | |
[ 10 x -11 r .995 s -.002 b anemone ] do | |
] when ; | |
: anemone-begin ( -- ) [ 196 hue 0.8324 sat 1 b anemone ] do ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: init ( -- ) | |
[ -1 b ] >background | |
{ -60 140 -120 140 } >viewport | |
0.1 >threshold | |
[ anemone-begin ] >start-shape ; | |
: run ( -- ) [ init ] cfdg-window. ; | |
MAIN: run | |
]] | |
FILE: [[cfdg/models/aqua-star/authors.txt]] [[Eduardo Cavazos | |
]] | |
FILE: [[cfdg/models/aqua-star/tags.txt]] [[demos | |
]] | |
FILE: [[cfdg/models/flower6/deploy.factor]] [[USING: tools.deploy.config ; | |
V{ | |
{ deploy-ui? t } | |
{ deploy-io 1 } | |
{ deploy-reflection 2 } | |
{ deploy-compiler? t } | |
{ deploy-math? t } | |
{ deploy-word-props? f } | |
{ deploy-c-types? f } | |
{ "stop-after-last-window?" t } | |
{ "bundle-name" "cfdg.models.flower6.app" } | |
} | |
]] | |
FILE: [[cfdg/models/flower6/authors.txt]] [[Eduardo Cavazos | |
]] | |
FILE: [[cfdg/models/flower6/tags.txt]] [[demos | |
]] | |
FILE: [[cfdg/models/flower6/flower6.factor]] [[ | |
USING: kernel namespaces sequences math | |
opengl.gl opengl.glu ui ui.gadgets.slate | |
random-weighted cfdg ; | |
IN: cfdg.models.flower6 | |
: petal6 ( -- ) | |
iterate? [ | |
[ 1 0.001 s* square ] do | |
[ -0.5 x 0.01 s -1 b circle ] do | |
[ 0.5 x 120.21 r 0.996 s 0.5 x 0.005 b petal6 ] do | |
] when ; | |
: flower6 ( -- ) | |
12 [ [ [ 30 r ] times petal6 ] do ] each | |
12 [ [ [ 30 r ] times 90 flip petal6 ] do ] each ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: init ( -- ) | |
[ ] >background | |
{ -1 2 -1 2 } >viewport | |
0.01 >threshold | |
[ flower6 ] >start-shape ; | |
: run ( -- ) [ init ] cfdg-window. ; | |
MAIN: run | |
]] | |
FILE: [[cfdg/models/snowflake/snowflake.factor]] [[ | |
USING: kernel namespaces math opengl.gl opengl.glu ui ui.gadgets.slate | |
random-weighted cfdg ; | |
IN: cfdg.models.snowflake | |
: spike ( -- ) | |
iterate? [ | |
{ { 1 [ square | |
[ 0.95 y 0.97 s spike ] do ] } | |
{ 0.03 [ square | |
[ 60 r spike ] do | |
[ -60 r spike ] do | |
[ 0.95 y 0.97 s spike ] do ] } } | |
call-random-weighted | |
] when ; | |
: snowflake ( -- ) | |
spike | |
[ 60 r spike ] do | |
[ 120 r spike ] do | |
[ 180 r spike ] do | |
[ 240 r spike ] do | |
[ 300 r spike ] do ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: init ( -- ) | |
[ ] >background | |
{ -40 80 -40 80 } >viewport | |
0.1 >threshold | |
[ snowflake ] >start-shape ; | |
: run ( -- ) [ init ] cfdg-window. ; | |
MAIN: run | |
]] | |
FILE: [[cfdg/models/snowflake/authors.txt]] [[Eduardo Cavazos | |
]] | |
FILE: [[cfdg/models/snowflake/tags.txt]] [[demos | |
]] | |
FILE: [[cfdg/models/rules08/rules08.factor]] [[ | |
USING: namespaces sequences math random-weighted cfdg ; | |
IN: cfdg.models.rules08 | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: insct ( -- ) | |
[ 1.5 5.5 size* -1 brightness triangle ] do | |
10 | |
[ [ [ 1 0.9 size* -0.15 y 0.05 brightness ] times 1 5 size* triangle ] do ] | |
each ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
DEFER: line | |
: ligne ( -- ) | |
{ | |
{ 1 [ 4.5 y 1.15 0.8 size* -0.3 b line ] } | |
{ 0.5 [ ] } | |
} | |
rules ; | |
: line ( -- ) { [ insct ligne ] } rule ; | |
: sole ( -- ) | |
{ | |
{ 1 [ 1 brightness 0.5 saturation ligne ] [ 140 r 1 hue sole ] } | |
{ 0.01 [ ] } | |
} | |
rules ; | |
: centre ( -- ) { [ 1 b 5 s circle ] [ sole ] } rule ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: init ( -- ) | |
[ -1 b ] >background | |
{ -20 40 -20 40 } viewport set | |
[ centre ] >start-shape | |
0.0001 >threshold ; | |
: run ( -- ) [ init ] cfdg-window. ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
MAIN: run | |
]] | |
FILE: [[cfdg/models/rules08/tags.txt]] [[demos | |
]] | |
FILE: [[cfdg/models/spirales/spirales.factor]] [[ | |
USING: namespaces sequences math random-weighted cfdg ; | |
IN: cfdg.models.spirales | |
DEFER: line | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: block ( -- ) { [ circle ] [ 0.3 s 60 flip line ] } rule ; | |
: a1 ( -- ) { [ 0.95 s 2 x 12 r 0.5 b 10 hue 1.5 sat a1 ] [ block ] } rule ; | |
: line ( -- ) -0.3 a { [ 0 r a1 ] [ 120 r a1 ] [ 240 r a1 ] } rule ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: init ( -- ) | |
[ -1 b ] >background | |
{ -20 40 -20 40 } >viewport | |
[ line ] >start-shape | |
0.04 >threshold ; | |
: run ( -- ) [ init ] cfdg-window. ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
MAIN: run | |
]] | |
FILE: [[cfdg/models/spirales/tags.txt]] [[demos | |
]] | |
FILE: [[cfdg/models/chiaroscuro/chiaroscuro.factor]] [[ | |
USING: kernel namespaces sequences math | |
opengl.gl opengl.glu ui ui.gadgets.slate | |
random-weighted cfdg ; | |
IN: cfdg.models.chiaroscuro | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
DEFER: white | |
: black ( -- ) | |
{ | |
{ 60 [ 0.6 s circle ] [ 0.1 x 5 r 0.99 s -0.01 b -0.01 a black ] } | |
{ 1 [ white black ] } | |
} | |
rules ; | |
: white ( -- ) | |
{ | |
{ 60 [ 0.6 s circle ] [ 0.1 x -5 r 0.99 s 0.01 b -0.01 a white ] } | |
{ 1 [ black white ] } | |
} | |
rules ; | |
: chiaroscuro ( -- ) { [ 0.5 b black ] } rule ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: init ( -- ) | |
[ -0.5 b ] >background | |
{ -3 6 -2 6 } >viewport | |
0.03 >threshold | |
[ chiaroscuro ] >start-shape ; | |
: run ( -- ) [ init ] cfdg-window. ; | |
MAIN: run | |
]] | |
FILE: [[cfdg/models/chiaroscuro/authors.txt]] [[Eduardo Cavazos | |
]] | |
FILE: [[cfdg/models/chiaroscuro/tags.txt]] [[demos | |
]] | |
FILE: [[cfdg/models/lesson/lesson.factor]] [[ | |
USING: kernel namespaces math opengl.gl opengl.glu ui ui.gadgets.slate | |
random-weighted cfdg ; | |
IN: cfdg.models.lesson | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: shapes ( -- ) | |
[ square ] do | |
[ 0.3 b circle ] do | |
[ 0.5 b triangle ] do | |
[ 0.7 b 60 r triangle ] do ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: chapter-1 ( -- ) | |
[ 2 x 5 y 3 size square ] do | |
[ 6 x 5 y 3 size circle ] do | |
[ 4 x 2 y 3 size triangle ] do | |
[ 1 y 3 size shapes ] do ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: foursquare ( -- ) | |
[ 0 x 0 y 5 3 size* square ] do | |
[ 0 x 5 y 2 4 size* square ] do | |
[ 5 x 5 y 3 size square ] do | |
[ 5 x 0 y 2 size square ] do ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: chapter-2 ( -- ) | |
[ square ] do | |
[ 3 x 7 y square ] do | |
[ 5 x 7 y 30 r square ] do | |
[ 3 x 5 y 0.75 size square ] do | |
[ 5 x 5 y 0.5 b square ] do | |
[ 7 x 6 y 45 r 0.7 size 0.7 b square ] do | |
[ 5 x 1 y 10 r 0.2 size foursquare ] do ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: spiral ( -- ) | |
iterate? [ | |
[ 0.5 size circle ] do | |
[ 0.2 y -3 r 0.995 size spiral ] do | |
] when ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: chapter-3 ( -- ) [ 0 x 3 y spiral ] do ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
DEFER: tree | |
: branch-left ( -- ) | |
{ { 1 [ 20 r tree ] } | |
{ 1 [ 30 r tree ] } | |
{ 1 [ 40 r tree ] } | |
{ 1 [ ] } } random-weighted* do ; | |
: branch-right ( -- ) | |
{ { 1 [ -20 r tree ] } | |
{ 1 [ -30 r tree ] } | |
{ 1 [ -40 r tree ] } | |
{ 1 [ ] } } random-weighted* do ; | |
: branch ( -- ) branch-left branch-right ; | |
: tree ( -- ) | |
iterate? [ | |
{ | |
{ 20 [ [ 0.25 size circle ] do | |
[ 0.1 y 0.97 size tree ] do ] } | |
{ 1.5 [ branch ] } | |
} random-weighted* do | |
] when ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: chapter-4 ( -- ) | |
[ 1 x 0 y tree ] do | |
[ 6 x 0 y tree ] do | |
[ 1 x 4 y tree ] do | |
[ 6 x 4 y tree ] do ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: toc ( -- ) | |
[ 0 x 0 y chapter-1 ] do | |
[ 10 x 0 y chapter-2 ] do | |
[ 0 x -10 y chapter-3 ] do | |
[ 10 x -10 y chapter-4 ] do ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: init ( -- ) | |
[ ] >background | |
{ -5 25 -15 25 } >viewport | |
0.03 >threshold | |
[ toc ] >start-shape ; | |
: run ( -- ) [ init ] cfdg-window. ; | |
MAIN: run | |
]] | |
FILE: [[cfdg/models/lesson/authors.txt]] [[Eduardo Cavazos | |
]] | |
FILE: [[cfdg/models/lesson/tags.txt]] [[demos | |
]] | |
FILE: [[cfdg/summary.txt]] [[Implementation of: http://contextfreeart.org | |
]] | |
FILE: [[cfdg/gl/gl.factor]] [[ | |
USING: kernel alien.c-types namespaces sequences opengl.gl ; | |
IN: cfdg.gl | |
: get-modelview-matrix ( -- alien ) | |
GL_MODELVIEW_MATRIX 16 "GLdouble" <c-array> tuck glGetDoublev ; | |
SYMBOL: modelview-matrix-stack | |
: init-modelview-matrix-stack ( -- ) V{ } clone modelview-matrix-stack set ; | |
: push-modelview-matrix ( -- ) | |
get-modelview-matrix modelview-matrix-stack get push ; | |
: pop-modelview-matrix ( -- ) modelview-matrix-stack get pop glLoadMatrixd ; | |
]] | |
FILE: [[cfdg/gl/authors.txt]] [[Eduardo Cavazos | |
]] | |
FILE: [[cfdg/authors.txt]] [[Eduardo Cavazos | |
]] | |
FILE: [[golden-section/summary.txt]] [[Golden section demo | |
]] | |
FILE: [[golden-section/deploy.factor]] [[USING: tools.deploy.config ; | |
V{ | |
{ deploy-ui? t } | |
{ deploy-io 1 } | |
{ deploy-reflection 1 } | |
{ deploy-compiler? t } | |
{ deploy-math? t } | |
{ deploy-word-props? f } | |
{ deploy-c-types? f } | |
{ "stop-after-last-window?" t } | |
{ deploy-name "Golden Section" } | |
} | |
]] | |
FILE: [[golden-section/authors.txt]] [[Eduardo Cavazos | |
]] | |
FILE: [[golden-section/tags.txt]] [[demos | |
]] | |
FILE: [[golden-section/golden-section.factor]] [[ | |
USING: kernel namespaces math math.constants math.functions math.order | |
arrays sequences | |
opengl opengl.gl opengl.glu ui ui.render ui.gadgets ui.gadgets.theme | |
ui.gadgets.cartesian colors accessors combinators.cleave | |
processing.shapes ; | |
IN: golden-section | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! omega(i) = 2*pi*i*(phi-1) | |
! x(i) = 0.5*i*cos(omega(i)) | |
! y(i) = 0.5*i*sin(omega(i)) | |
! radius(i) = 10*sin((pi*i)/720) | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: omega ( i -- omega ) phi 1- * 2 * pi * ; | |
: x ( i -- x ) [ omega cos ] [ 0.5 * ] bi * ; | |
: y ( i -- y ) [ omega sin ] [ 0.5 * ] bi * ; | |
: center ( i -- point ) { x y } 1arr ; | |
: radius ( i -- radius ) pi * 720 / sin 10 * ; | |
: color ( i -- i ) dup 360.0 / dup 0.25 1 rgba boa >fill-color ; | |
: line-width ( i -- i ) dup radius 0.5 * 1 max glLineWidth ; | |
: draw ( i -- ) [ center ] [ radius 1.5 * 2 * ] bi circle ; | |
: dot ( i -- ) color line-width draw ; | |
: golden-section ( -- ) 720 [ dot ] each ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: <golden-section> ( -- gadget ) | |
<cartesian> | |
{ 600 600 } >>pdim | |
{ -400 400 } x-range | |
{ -400 400 } y-range | |
[ golden-section ] >>action ; | |
: golden-section-window ( -- ) | |
[ <golden-section> "Golden Section" open-window ] with-ui ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
MAIN: golden-section-window | |
]] | |
FILE: [[db/mysql/ffi/ffi.factor]] [[! Copyright (C) 2007 Berlin Brown, 2008 Doug Coleman. | |
! See http://factorcode.org/license.txt for BSD license. | |
! Adapted from mysql.h and mysql.c | |
! Tested with MySQL version - 5.0.24a | |
USING: alien alien.syntax combinators kernel system ; | |
IN: db.mysql.ffi | |
<< "mysql" { | |
{ [ os winnt? ] [ "libmySQL.dll" stdcall ] } | |
{ [ os macosx? ] [ "libmysqlclient.14.dylib" cdecl ] } | |
{ [ os unix? ] [ "libmysqlclient.so.14" cdecl ] } | |
} cond add-library >> | |
LIBRARY: mysql | |
FUNCTION: void* mysql_init ( void* mysql ) ; | |
FUNCTION: char* mysql_error ( void* mysql ) ; | |
FUNCTION: void* mysql_real_connect ( void* mysql, char* host, char* user, char* passwd, char* db, int port, char* unixsocket, long clientflag ) ; | |
FUNCTION: void mysql_close ( void* sock ) ; | |
FUNCTION: int mysql_query ( void* mysql, char* q ) ; | |
FUNCTION: void* mysql_use_result ( void* mysql ) ; | |
FUNCTION: void mysql_free_result ( void* result ) ; | |
FUNCTION: char** mysql_fetch_row ( void* result ) ; | |
FUNCTION: int mysql_num_fields ( void* result ) ; | |
FUNCTION: ulong mysql_affected_rows ( void* mysql ) ; | |
]] | |
FILE: [[db/mysql/lib/lib.factor]] [[! Copyright (C) 2007 Berlin Brown, 2008 Doug Coleman. | |
! See http://factorcode.org/license.txt for license. | |
! Adapted from mysql.h and mysql.c | |
! Tested with MySQL version - 5.0.24a | |
USING: kernel alien io prettyprint sequences | |
namespaces arrays math db.mysql.ffi system accessors ; | |
IN: db.mysql.lib | |
SYMBOL: my-conn | |
TUPLE: mysql-db handle host user password db port ; | |
TUPLE: mysql-statement ; | |
TUPLE: mysql-result-set ; | |
: new-mysql ( -- conn ) | |
f mysql_init ; | |
: mysql-error ( mysql -- ) | |
[ mysql_error throw ] when* ; | |
! : mysql-connect ( mysql-connection -- ) | |
! new-mysql over set-mysql-db-handle | |
! dup { | |
! mysql-db-handle | |
! mysql-db-host | |
! mysql-db-user | |
! mysql-db-password | |
! mysql-db-db | |
! mysql-db-port | |
! } get-slots f 0 mysql_real_connect mysql-error ; | |
! ========================================================= | |
! Low level mysql utility definitions | |
! ========================================================= | |
: (mysql-query) ( mysql-connection query -- ret ) | |
>r db-handle>> r> mysql_query ; | |
! : (mysql-result) ( mysql-connection -- ret ) | |
! [ mysql-db-handle mysql_use_result ] keep | |
! [ set-mysql-connection-resulthandle ] keep ; | |
! : (mysql-affected-rows) ( mysql-connection -- n ) | |
! mysql-connection-mysqlconn mysql_affected_rows ; | |
! : (mysql-free-result) ( mysql-connection -- ) | |
! mysql-connection-resulthandle drop ; | |
! : (mysql-row) ( mysql-connection -- row ) | |
! mysql-connection-resulthandle mysql_fetch_row ; | |
! : (mysql-num-cols) ( mysql-connection -- n ) | |
! mysql-connection-resulthandle mysql_num_fields ; | |
! : mysql-char*-nth ( index object -- str ) | |
! ! Utility based on 'char*-nth' to perform an additional sanity check on the value | |
! ! extracted from the array of strings. | |
! void*-nth [ alien>char-string ] [ "" ] if* ; | |
! : mysql-row>seq ( object n -- seq ) | |
! [ swap mysql-char*-nth ] map-with ; | |
! : (mysql-result>seq) ( seq -- seq ) | |
! my-conn get (mysql-row) dup [ | |
! my-conn get (mysql-num-cols) mysql-row>seq | |
! over push | |
! (mysql-result>seq) | |
! ] [ drop ] if | |
! ! Perform needed cleanup on fetched results | |
! my-conn get (mysql-free-result) ; | |
! : mysql-query ( query -- ret ) | |
! >r my-conn get r> (mysql-query) drop | |
! my-conn get (mysql-result) ; | |
! : mysql-command ( query -- n ) | |
! mysql-query drop | |
! my-conn get (mysql-affected-rows) ; | |
]] | |
FILE: [[db/mysql/mysql.factor]] [[! Copyright (C) 2008 Doug Coleman. | |
! See http://factorcode.org/license.txt for license. | |
USING: alien continuations destructors io kernel prettyprint | |
sequences db db.mysql.ffi ; | |
IN: db.mysql | |
TUPLE: mysql-db handle host user password db port ; | |
TUPLE: mysql-statement ; | |
TUPLE: mysql-result-set ; | |
M: mysql-db db-open ( mysql-db -- ) | |
; | |
M: mysql-db dispose ( mysql-db -- ) | |
mysql-db-handle mysql_close ; | |
M: mysql-db <simple-statement> ( str in out -- statement ) | |
3drop f ; | |
M: mysql-db <prepared-statement> ( str in out -- statement ) | |
3drop f ; | |
M: mysql-statement prepare-statement ( statement -- ) | |
drop ; | |
M: mysql-statement bind-statement* ( statement -- ) | |
drop ; | |
M: mysql-statement query-results ( query -- result-set ) | |
drop f ; | |
M: mysql-result-set #rows ( result-set -- n ) | |
drop 0 ; | |
M: mysql-result-set #columns ( result-set -- n ) | |
drop 0 ; | |
M: mysql-result-set row-column ( result-set n -- obj ) | |
2drop f ; | |
M: mysql-result-set advance-row ( result-set -- ) | |
drop ; | |
M: mysql-db begin-transaction ( -- ) | |
; | |
M: mysql-db commit-transaction ( -- ) | |
; | |
M: mysql-db rollback-transaction ( -- ) | |
; | |
]] | |
FILE: [[springies/ui/ui.factor]] [[ | |
USING: kernel namespaces threads sequences math math.vectors | |
opengl.gl opengl colors ui ui.gadgets ui.gadgets.slate | |
fry rewrite-closures vars springies accessors math.geometry.rect ; | |
IN: springies.ui | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: draw-node ( node -- ) pos>> { -5 -5 } v+ [ { 10 10 } gl-rect ] with-translation ; | |
: draw-spring ( spring -- ) | |
[ node-a>> pos>> ] [ node-b>> pos>> ] bi gl-line ; | |
: draw-nodes ( -- ) nodes> [ draw-node ] each ; | |
: draw-springs ( -- ) springs> [ draw-spring ] each ; | |
: set-projection ( -- ) | |
GL_PROJECTION glMatrixMode | |
glLoadIdentity | |
0 world-width 1- 0 world-height 1- -1 1 glOrtho | |
GL_MODELVIEW glMatrixMode | |
glLoadIdentity ; | |
! : display ( -- ) set-projection black gl-color draw-nodes draw-springs ; | |
: display ( -- ) set-projection black gl-color draw-nodes draw-springs ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
VAR: slate | |
VAR: loop | |
: update-world-size ( -- ) slate> rect-dim >world-size ; | |
: refresh-slate ( -- ) slate> relayout-1 ; | |
DEFER: maybe-loop | |
: run ( -- ) | |
update-world-size | |
iterate-system | |
refresh-slate | |
yield | |
maybe-loop ; | |
: maybe-loop ( -- ) loop> [ run ] when ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: springies-window* ( -- ) | |
C[ display ] <slate> | |
{ 800 600 } >>pdim | |
C[ { 500 500 } >world-size loop on [ run ] in-thread ] >>graft | |
C[ loop off ] >>ungraft | |
[ >slate ] [ "Springies" open-window ] bi ; | |
: springies-window ( -- ) [ [ springies-window* ] with-scope ] with-ui ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: go* ( quot -- ) '[ [ springies-window* 1000 sleep @ ] with-scope ] with-ui ; | |
]] | |
FILE: [[springies/ui/authors.txt]] [[Eduardo Cavazos | |
]] | |
FILE: [[springies/models/belt-tire/belt-tire.factor]] [[ | |
USING: kernel namespaces arrays sequences threads math ui random | |
springies springies.ui ; | |
IN: springies.models.belt-tire | |
: model ( -- ) | |
{ } clone >nodes | |
{ } clone >springs | |
0.008 >time-slice | |
gravity on | |
1 274.078806900597328 346.307117178664043 0 0 1 0.5 mass | |
2 284.142891110742823 329.83402842231834 0 0 1 0.5 mass | |
3 295.307158356938658 355.695013578746227 0 0 1 0.5 mass | |
4 300.698527801927128 337.003548930923216 0 0 1 0.5 mass | |
5 318.093036910029696 359.203044347904552 0 0 1 0.5 mass | |
6 318.542098798246286 339.592403450546044 0 0 1 0.5 mass | |
7 340.949296214486822 356.831259237330983 0 0 1 0.5 mass | |
8 336.494524828869885 337.754019325244656 0 0 1 0.5 mass | |
9 362.534986907234952 348.770558940029559 0 0 1 0.5 mass | |
10 353.491265306914897 331.642140359094469 0 0 1 0.5 mass | |
11 381.368850422101502 335.37878701564847 0 0 1 0.5 mass | |
12 368.085531061140216 321.055018811315335 0 0 1 0.5 mass | |
13 396.117634938806759 317.519287773537314 0 0 1 0.5 mass | |
14 379.675208211408915 307.277961968837246 0 0 1 0.5 mass | |
15 405.655157991023771 296.391903048606025 0 0 1 0.5 mass | |
16 387.124676448692242 290.862310093183567 0 0 1 0.5 mass | |
17 409.337178964708642 273.594658653786666 0 0 1 0.5 mass | |
18 389.76569804010461 273.012494879567555 0 0 1 0.5 mass | |
19 407.11203230551871 250.712646124396059 0 0 1 0.5 mass | |
20 387.966228461346304 255.061007930370067 0 0 1 0.5 mass | |
21 399.188308328902735 229.098161823607285 0 0 1 0.5 mass | |
22 381.896222954111181 238.073977723246998 0 0 1 0.5 mass | |
23 385.883224011375262 210.148208473511374 0 0 1 0.5 mass | |
24 371.614761646970464 223.279700317395225 0 0 1 0.5 mass | |
25 367.955378160003875 195.334436550727929 0 0 1 0.5 mass | |
26 357.817091674528911 211.717360072075536 0 0 1 0.5 mass | |
27 346.743525482831387 185.884698478394085 0 0 1 0.5 mass | |
28 341.291169697238729 204.55711005838188 0 0 1 0.5 mass | |
29 323.935265230381788 182.330460182137188 0 0 1 0.5 mass | |
30 323.466187791799882 201.937076877994031 0 0 1 0.5 mass | |
31 301.04141769400843 184.703602685435726 0 0 1 0.5 mass | |
32 305.532794735419941 203.763859300438838 0 0 1 0.5 mass | |
33 279.442362700896183 192.851996602076866 0 0 1 0.5 mass | |
34 288.551113492738239 209.893932668644339 0 0 1 0.5 mass | |
35 260.65997798024199 206.334196608396638 0 0 1 0.5 mass | |
36 273.960657978745814 220.516324161880476 0 0 1 0.5 mass | |
37 246.029909853431349 224.197583023911335 0 0 1 0.5 mass | |
38 262.719165304227545 234.58428660123181 0 0 1 0.5 mass | |
39 236.458142984593252 245.235572499606377 0 0 1 0.5 mass | |
40 254.870454491934908 250.81914136861181 0 0 1 0.5 mass | |
41 232.703447579492519 268.042376651164432 0 0 1 0.5 mass | |
42 252.226120754560156 268.679895159358864 0 0 1 0.5 mass | |
43 234.96767702938331 291.007702051922024 0 0 1 0.5 mass | |
44 254.040589506795527 286.621843971355872 0 0 1 0.5 mass | |
45 242.759412026738119 312.577114225657738 0 0 1 0.5 mass | |
46 260.111088599530603 303.593264087352964 0 0 1 0.5 mass | |
47 256.101782779606651 331.52509923420655 0 0 1 0.5 mass | |
48 270.373388641766439 318.366074596339615 0 0 1 0.5 mass | |
49 320.448537383965288 270.292364746678743 0 0 10 0.5 mass | |
1 1 4 200 2 28.284271247461902 spng | |
2 4 5 200 2 28.284271247461902 spng | |
3 5 8 200 2 28.284271247461902 spng | |
4 8 9 200 2 28.284271247461902 spng | |
5 9 12 200 2 28.284271247461902 spng | |
6 12 13 200 2 28.284271247461902 spng | |
7 13 16 200 2 28.284271247461902 spng | |
8 16 17 200 2 28.284271247461902 spng | |
9 17 20 200 2 28.284271247461902 spng | |
10 20 21 200 2 28.284271247461902 spng | |
11 21 24 200 2 28.284271247461902 spng | |
12 24 25 200 2 28.284271247461902 spng | |
13 25 28 200 2 28.284271247461902 spng | |
14 28 29 200 2 28.284271247461902 spng | |
15 29 32 200 2 28.284271247461902 spng | |
16 32 33 200 2 28.284271247461902 spng | |
17 33 36 200 2 28.284271247461902 spng | |
18 36 37 200 2 28.284271247461902 spng | |
19 37 40 200 2 28.284271247461902 spng | |
20 40 41 200 2 28.284271247461902 spng | |
21 41 44 200 2 28.284271247461902 spng | |
22 44 45 200 2 28.284271247461902 spng | |
23 45 48 200 2 28.284271247461902 spng | |
24 3 6 200 2 28.284271247461902 spng | |
25 7 10 200 2 28.284271247461902 spng | |
26 11 14 200 2 28.284271247461902 spng | |
27 15 18 200 2 28.284271247461902 spng | |
28 19 22 200 2 28.284271247461902 spng | |
29 23 26 200 2 28.284271247461902 spng | |
30 27 30 200 2 28.284271247461902 spng | |
31 31 34 200 2 28.284271247461902 spng | |
32 35 38 200 2 28.284271247461902 spng | |
33 39 44 200 2 44.7213595499957961 spng | |
34 39 42 200 2 28.284271247461902 spng | |
35 43 46 200 2 28.284271247461902 spng | |
36 47 46 200 2 28.284271247461902 spng | |
37 43 42 200 2 28.284271247461902 spng | |
38 39 38 200 2 28.284271247461902 spng | |
39 35 34 200 2 28.284271247461902 spng | |
40 2 3 200 2 28.284271247461902 spng | |
41 6 7 200 2 28.284271247461902 spng | |
42 10 11 200 2 28.284271247461902 spng | |
43 14 15 200 2 28.284271247461902 spng | |
44 18 19 200 2 28.284271247461902 spng | |
45 22 23 200 2 28.284271247461902 spng | |
46 26 27 200 2 28.284271247461902 spng | |
47 30 31 200 2 28.284271247461902 spng | |
48 1 6 200 2 44.7213595499957961 spng | |
49 3 8 200 2 44.7213595499957961 spng | |
50 5 10 200 2 44.7213595499957961 spng | |
51 7 12 200 2 44.7213595499957961 spng | |
52 9 14 200 2 44.7213595499957961 spng | |
53 11 16 200 2 44.7213595499957961 spng | |
54 13 18 200 2 44.7213595499957961 spng | |
55 15 20 200 2 44.7213595499957961 spng | |
56 17 22 200 2 44.7213595499957961 spng | |
57 19 24 200 2 44.7213595499957961 spng | |
58 21 26 200 2 44.7213595499957961 spng | |
59 23 28 200 2 44.7213595499957961 spng | |
60 25 30 200 2 44.7213595499957961 spng | |
61 27 32 200 2 44.7213595499957961 spng | |
62 29 34 200 2 44.7213595499957961 spng | |
63 31 36 200 2 44.7213595499957961 spng | |
64 33 38 200 2 44.7213595499957961 spng | |
65 35 40 200 2 44.7213595499957961 spng | |
66 37 42 200 2 44.7213595499957961 spng | |
67 41 46 200 2 44.7213595499957961 spng | |
68 43 48 200 2 44.7213595499957961 spng | |
69 2 5 200 2 44.7213595499957961 spng | |
70 4 7 200 2 44.7213595499957961 spng | |
71 6 9 200 2 44.7213595499957961 spng | |
72 8 11 200 2 44.7213595499957961 spng | |
73 10 13 200 2 44.7213595499957961 spng | |
74 12 15 200 2 44.7213595499957961 spng | |
75 14 17 200 2 44.7213595499957961 spng | |
76 16 19 200 2 44.7213595499957961 spng | |
77 18 21 200 2 44.7213595499957961 spng | |
78 20 23 200 2 44.7213595499957961 spng | |
79 22 25 200 2 44.7213595499957961 spng | |
80 24 27 200 2 44.7213595499957961 spng | |
81 26 29 200 2 44.7213595499957961 spng | |
82 28 31 200 2 44.7213595499957961 spng | |
83 30 33 200 2 44.7213595499957961 spng | |
84 32 35 200 2 44.7213595499957961 spng | |
85 34 37 200 2 44.7213595499957961 spng | |
86 36 39 200 2 44.7213595499957961 spng | |
87 38 41 200 2 44.7213595499957961 spng | |
88 40 43 200 2 44.7213595499957961 spng | |
89 42 45 200 2 44.7213595499957961 spng | |
90 44 47 200 2 44.7213595499957961 spng | |
91 1 8 200 2 63.2455532033675851 spng | |
92 3 10 200 2 63.2455532033675851 spng | |
93 5 12 200 2 63.2455532033675851 spng | |
94 7 14 200 2 63.2455532033675851 spng | |
95 9 16 200 2 63.2455532033675851 spng | |
96 11 18 200 2 63.2455532033675851 spng | |
97 13 20 200 2 63.2455532033675851 spng | |
98 15 22 200 2 63.2455532033675851 spng | |
99 17 24 200 2 63.2455532033675851 spng | |
100 19 26 200 2 63.2455532033675851 spng | |
101 21 28 200 2 63.2455532033675851 spng | |
102 23 30 200 2 63.2455532033675851 spng | |
103 25 32 200 2 63.2455532033675851 spng | |
104 27 34 200 2 63.2455532033675851 spng | |
105 29 36 200 2 63.2455532033675851 spng | |
106 31 38 200 2 63.2455532033675851 spng | |
107 33 40 200 2 63.2455532033675851 spng | |
108 35 42 200 2 63.2455532033675851 spng | |
109 37 44 200 2 63.2455532033675851 spng | |
110 39 46 200 2 63.2455532033675851 spng | |
111 48 41 200 2 63.2455532033675851 spng | |
112 2 7 200 2 63.2455532033675851 spng | |
113 4 9 200 2 63.2455532033675851 spng | |
114 6 11 200 2 63.2455532033675851 spng | |
115 8 13 200 2 63.2455532033675851 spng | |
116 10 15 200 2 63.2455532033675851 spng | |
117 12 17 200 2 63.2455532033675851 spng | |
118 14 19 200 2 63.2455532033675851 spng | |
119 16 21 200 2 63.2455532033675851 spng | |
120 18 23 200 2 63.2455532033675851 spng | |
121 20 25 200 2 63.2455532033675851 spng | |
122 22 27 200 2 63.2455532033675851 spng | |
123 24 29 200 2 63.2455532033675851 spng | |
124 26 31 200 2 63.2455532033675851 spng | |
125 28 33 200 2 63.2455532033675851 spng | |
126 30 35 200 2 63.2455532033675851 spng | |
127 32 37 200 2 63.2455532033675851 spng | |
128 34 39 200 2 63.2455532033675851 spng | |
129 36 41 200 2 63.2455532033675851 spng | |
130 38 43 200 2 63.2455532033675851 spng | |
131 40 45 200 2 63.2455532033675851 spng | |
132 42 47 200 2 63.2455532033675851 spng | |
133 1 3 200 2 20 spng | |
134 3 5 200 2 20 spng | |
135 5 7 200 2 20 spng | |
136 7 9 200 2 20 spng | |
137 9 11 200 2 20 spng | |
138 11 13 200 2 20 spng | |
139 13 15 200 2 20 spng | |
140 15 17 200 2 20 spng | |
141 17 19 200 2 20 spng | |
142 19 21 200 2 20 spng | |
143 21 23 200 2 20 spng | |
144 23 25 200 2 20 spng | |
145 25 27 200 2 20 spng | |
146 27 29 200 2 20 spng | |
147 29 31 200 2 20 spng | |
148 31 33 200 2 20 spng | |
149 33 35 200 2 20 spng | |
150 35 37 200 2 20 spng | |
151 37 39 200 2 20 spng | |
152 39 41 200 2 20 spng | |
153 41 43 200 2 20 spng | |
154 43 45 200 2 20 spng | |
155 45 47 200 2 20 spng | |
156 2 4 200 2 20 spng | |
157 4 6 200 2 20 spng | |
158 6 8 200 2 20 spng | |
159 8 10 200 2 20 spng | |
160 10 12 200 2 20 spng | |
161 12 14 200 2 20 spng | |
162 14 16 200 2 20 spng | |
163 16 18 200 2 20 spng | |
164 18 20 200 2 20 spng | |
165 20 22 200 2 20 spng | |
166 22 24 200 2 20 spng | |
167 24 26 200 2 20 spng | |
168 26 28 200 2 20 spng | |
169 28 30 200 2 20 spng | |
170 30 32 200 2 20 spng | |
171 32 34 200 2 20 spng | |
172 34 36 200 2 20 spng | |
173 36 38 200 2 20 spng | |
174 38 40 200 2 20 spng | |
175 40 42 200 2 20 spng | |
176 42 44 200 2 20 spng | |
177 44 46 200 2 20 spng | |
178 46 48 200 2 20 spng | |
179 1 2 200 2 20 spng | |
180 3 4 200 2 20 spng | |
181 5 6 200 2 20 spng | |
182 7 8 200 2 20 spng | |
183 9 10 200 2 20 spng | |
184 11 12 200 2 20 spng | |
185 13 14 200 2 20 spng | |
186 15 16 200 2 20 spng | |
187 17 18 200 2 20 spng | |
188 19 20 200 2 20 spng | |
189 21 22 200 2 20 spng | |
190 23 24 200 2 20 spng | |
191 25 26 200 2 20 spng | |
192 27 28 200 2 20 spng | |
193 29 30 200 2 20 spng | |
194 31 32 200 2 20 spng | |
195 33 34 200 2 20 spng | |
196 35 36 200 2 20 spng | |
197 37 38 200 2 20 spng | |
198 39 40 200 2 20 spng | |
199 41 42 200 2 20 spng | |
200 43 44 200 2 20 spng | |
201 45 46 200 2 20 spng | |
202 47 48 200 2 20 spng | |
203 47 2 200 2 28.284271247461902 spng | |
204 1 48 200 2 28.284271247461902 spng | |
205 1 46 200 2 44.7213595499957961 spng | |
206 1 44 200 2 63.2455532033675851 spng | |
207 47 4 200 2 44.7213595499957961 spng | |
208 48 3 200 2 44.7213595499957961 spng | |
209 47 6 200 2 63.2455532033675851 spng | |
210 48 5 200 2 63.2455532033675851 spng | |
211 46 3 200 2 63.2455532033675851 spng | |
212 45 4 200 2 63.2455532033675851 spng | |
213 47 1 200 2 20 spng | |
214 48 2 200 2 20 spng | |
215 18 49 300 3 69.2603782836911677 spng | |
216 49 20 300 3 69.050706006528273 spng | |
217 22 49 300 3 69.3541635375988079 spng | |
218 49 24 300 3 69.5269731830747872 spng | |
219 26 49 300 3 69.6347614342147381 spng | |
220 49 28 300 3 68.9492567037527948 spng | |
221 30 49 300 3 68.2641926635040477 spng | |
222 49 32 300 3 68.0661443009665419 spng | |
223 34 49 300 3 68.4470598345904051 spng | |
224 49 36 300 3 68.1175454637056106 spng | |
225 38 49 300 3 67.6756972627545252 spng | |
226 49 40 300 3 68.6221538571910514 spng | |
227 42 49 300 3 68.1835757349231386 spng | |
228 49 44 300 3 68.249542123006222 spng | |
229 46 49 300 3 68.8767014308902503 spng | |
230 49 48 300 3 69.4262198308391305 spng | |
231 2 49 300 3 69.8927750200262068 spng | |
232 49 4 300 3 69.5701085237043486 spng | |
233 6 49 300 3 69.1809222257119103 spng | |
234 8 49 300 3 69.2314957226839027 spng | |
235 49 10 300 3 69.7782200976780445 spng | |
236 12 49 300 3 69.5269731830747872 spng | |
237 49 14 300 3 69.8927750200262068 spng | |
238 16 49 300 3 69.8927750200262068 spng | |
nodes> 200 random -100 + 100 2array [ swap set-node-vel ] curry each ; | |
: go ( -- ) [ model ] go* ; | |
MAIN: go | |
]] | |
FILE: [[springies/models/belt-tire/deploy.factor]] [[USING: tools.deploy.config ; | |
V{ | |
{ deploy-ui? t } | |
{ deploy-io 2 } | |
{ deploy-reflection 1 } | |
{ deploy-compiler? t } | |
{ deploy-math? t } | |
{ deploy-word-props? f } | |
{ deploy-word-defs? f } | |
{ deploy-c-types? f } | |
{ "stop-after-last-window?" t } | |
{ "bundle-name" "Belt Tire.app" } | |
} | |
]] | |
FILE: [[springies/models/belt-tire/authors.txt]] [[Eduardo Cavazos | |
]] | |
FILE: [[springies/models/belt-tire/tags.txt]] [[demos | |
]] | |
FILE: [[springies/models/2x2snake/deploy.factor]] [[USING: tools.deploy.config ; | |
H{ | |
{ deploy-compiler? t } | |
{ deploy-word-props? f } | |
{ deploy-ui? t } | |
{ deploy-reflection 1 } | |
{ deploy-name "springies.models.2x2snake" } | |
{ deploy-c-types? f } | |
{ deploy-word-defs? f } | |
{ "stop-after-last-window?" t } | |
{ deploy-math? t } | |
{ deploy-io 1 } | |
} | |
]] | |
FILE: [[springies/models/2x2snake/2x2snake.factor]] [[ | |
USING: kernel namespaces arrays sequences threads math math.vectors | |
ui random springies springies.ui ; | |
IN: springies.models.2x2snake | |
: model ( -- ) | |
{ } clone >nodes | |
{ } clone >springs | |
0.002 >time-slice | |
gravity off | |
1 147.0 324.0 0.0 0.0 1.0 1.0 mass | |
2 164.0 324.0 0.0 0.0 1.0 1.0 mass | |
3 182.0 324.0 0.0 0.0 1.0 1.0 mass | |
4 200.0 324.0 0.0 0.0 1.0 1.0 mass | |
5 218.0 324.0 0.0 0.0 1.0 1.0 mass | |
6 236.0 324.0 0.0 0.0 1.0 1.0 mass | |
7 254.0 324.0 0.0 0.0 1.0 1.0 mass | |
8 272.0 324.0 0.0 0.0 1.0 1.0 mass | |
9 290.0 324.0 0.0 0.0 1.0 1.0 mass | |
10 308.0 324.0 0.0 0.0 1.0 1.0 mass | |
11 326.0 324.0 0.0 0.0 1.0 1.0 mass | |
12 344.0 324.0 0.0 0.0 1.0 1.0 mass | |
13 362.0 324.0 0.0 0.0 1.0 1.0 mass | |
14 380.0 324.0 0.0 0.0 1.0 1.0 mass | |
15 398.0 324.0 0.0 0.0 1.0 1.0 mass | |
16 416.0 324.0 0.0 0.0 1.0 1.0 mass | |
17 434.0 324.0 0.0 0.0 1.0 1.0 mass | |
18 452.0 324.0 0.0 0.0 1.0 1.0 mass | |
19 470.0 324.0 0.0 0.0 1.0 1.0 mass | |
20 147.0 298.0 0.0 0.0 1.0 1.0 mass | |
21 164.0 298.0 0.0 0.0 1.0 1.0 mass | |
22 182.0 298.0 0.0 0.0 1.0 1.0 mass | |
23 200.0 298.0 0.0 0.0 1.0 1.0 mass | |
24 218.0 298.0 0.0 0.0 1.0 1.0 mass | |
25 236.0 298.0 0.0 0.0 1.0 1.0 mass | |
26 254.0 298.0 0.0 0.0 1.0 1.0 mass | |
27 272.0 298.0 0.0 0.0 1.0 1.0 mass | |
28 290.0 298.0 0.0 0.0 1.0 1.0 mass | |
29 308.0 298.0 0.0 0.0 1.0 1.0 mass | |
30 326.0 298.0 0.0 0.0 1.0 1.0 mass | |
31 344.0 298.0 0.0 0.0 1.0 1.0 mass | |
32 362.0 298.0 0.0 0.0 1.0 1.0 mass | |
33 380.0 298.0 0.0 0.0 1.0 1.0 mass | |
34 398.0 298.0 0.0 0.0 1.0 1.0 mass | |
35 416.0 298.0 0.0 0.0 1.0 1.0 mass | |
36 434.0 298.0 0.0 0.0 1.0 1.0 mass | |
37 452.0 298.0 0.0 0.0 1.0 1.0 mass | |
38 470.0 298.0 0.0 0.0 1.0 1.0 mass | |
1 1 2 200.0 1.500000 18.0 spng | |
2 3 2 200.0 1.500000 18.0 spng | |
3 3 4 200.0 1.500000 18.0 spng | |
4 4 5 200.0 1.500000 18.0 spng | |
5 5 6 200.0 1.500000 18.0 spng | |
6 6 7 200.0 1.500000 18.0 spng | |
7 7 8 200.0 1.500000 18.0 spng | |
8 8 9 200.0 1.500000 18.0 spng | |
9 9 10 200.0 1.500000 18.0 spng | |
10 10 11 200.0 1.500000 18.0 spng | |
11 11 12 200.0 1.500000 18.0 spng | |
12 12 13 200.0 1.500000 18.0 spng | |
13 13 14 200.0 1.500000 18.0 spng | |
14 14 15 200.0 1.500000 18.0 spng | |
15 15 16 200.0 1.500000 18.0 spng | |
16 16 17 200.0 1.500000 18.0 spng | |
17 17 18 200.0 1.500000 18.0 spng | |
18 18 19 200.0 1.500000 18.0 spng | |
19 1 3 200.0 1.500000 36.0 spng | |
20 2 4 200.0 1.500000 36.0 spng | |
21 3 5 200.0 1.500000 36.0 spng | |
22 4 6 200.0 1.500000 36.0 spng | |
23 5 7 200.0 1.500000 36.0 spng | |
24 6 8 200.0 1.500000 36.0 spng | |
25 7 9 200.0 1.500000 36.0 spng | |
26 8 10 200.0 1.500000 36.0 spng | |
27 9 11 200.0 1.500000 36.0 spng | |
28 10 12 200.0 1.500000 36.0 spng | |
29 11 13 200.0 1.500000 36.0 spng | |
30 12 14 200.0 1.500000 36.0 spng | |
31 13 15 200.0 1.500000 36.0 spng | |
32 14 16 200.0 1.500000 36.0 spng | |
33 15 17 200.0 1.500000 36.0 spng | |
34 16 18 200.0 1.500000 36.0 spng | |
35 17 19 200.0 1.500000 36.0 spng | |
36 20 21 200.0 1.500000 18.0 spng | |
37 22 21 200.0 1.500000 18.0 spng | |
38 22 23 200.0 1.500000 18.0 spng | |
39 23 24 200.0 1.500000 18.0 spng | |
40 24 25 200.0 1.500000 18.0 spng | |
41 25 26 200.0 1.500000 18.0 spng | |
42 26 27 200.0 1.500000 18.0 spng | |
43 27 28 200.0 1.500000 18.0 spng | |
44 28 29 200.0 1.500000 18.0 spng | |
45 29 30 200.0 1.500000 18.0 spng | |
46 30 31 200.0 1.500000 18.0 spng | |
47 31 32 200.0 1.500000 18.0 spng | |
48 32 33 200.0 1.500000 18.0 spng | |
49 33 34 200.0 1.500000 18.0 spng | |
50 34 35 200.0 1.500000 18.0 spng | |
51 35 36 200.0 1.500000 18.0 spng | |
52 36 37 200.0 1.500000 18.0 spng | |
53 37 38 200.0 1.500000 18.0 spng | |
54 20 22 200.0 1.500000 36.0 spng | |
55 21 23 200.0 1.500000 36.0 spng | |
56 22 24 200.0 1.500000 36.0 spng | |
57 23 25 200.0 1.500000 36.0 spng | |
58 24 26 200.0 1.500000 36.0 spng | |
59 25 27 200.0 1.500000 36.0 spng | |
60 26 28 200.0 1.500000 36.0 spng | |
61 27 29 200.0 1.500000 36.0 spng | |
62 28 30 200.0 1.500000 36.0 spng | |
63 29 31 200.0 1.500000 36.0 spng | |
64 30 32 200.0 1.500000 36.0 spng | |
65 31 33 200.0 1.500000 36.0 spng | |
66 32 34 200.0 1.500000 36.0 spng | |
67 33 35 200.0 1.500000 36.0 spng | |
68 34 36 200.0 1.500000 36.0 spng | |
69 35 37 200.0 1.500000 36.0 spng | |
70 36 38 200.0 1.500000 36.0 spng | |
71 1 20 200.0 1.500000 26.0 spng | |
72 2 21 200.0 1.500000 26.0 spng | |
73 3 22 200.0 1.500000 26.0 spng | |
74 4 23 200.0 1.500000 26.0 spng | |
75 5 24 200.0 1.500000 26.0 spng | |
76 25 6 200.0 1.500000 26.0 spng | |
77 7 26 200.0 1.500000 26.0 spng | |
78 27 8 200.0 1.500000 26.0 spng | |
79 9 28 200.0 1.500000 26.0 spng | |
80 29 10 200.0 1.500000 26.0 spng | |
81 11 30 200.0 1.500000 26.0 spng | |
82 31 12 200.0 1.500000 26.0 spng | |
83 13 32 200.0 1.500000 26.0 spng | |
84 33 14 200.0 1.500000 26.0 spng | |
85 15 34 200.0 1.500000 26.0 spng | |
86 35 16 200.0 1.500000 26.0 spng | |
87 17 36 200.0 1.500000 26.0 spng | |
88 37 18 200.0 1.500000 26.0 spng | |
89 19 38 200.0 1.500000 26.0 spng | |
90 1 21 200.0 1.500000 31.064449 spng | |
91 2 20 200.0 1.500000 31.064449 spng | |
92 2 22 200.0 1.500000 31.622777 spng | |
93 3 21 200.0 1.500000 31.622777 spng | |
94 3 23 200.0 1.500000 31.622777 spng | |
95 4 22 200.0 1.500000 31.622777 spng | |
96 4 24 200.0 1.500000 31.622777 spng | |
97 5 23 200.0 1.500000 31.622777 spng | |
98 5 25 200.0 1.500000 31.622777 spng | |
99 6 24 200.0 1.500000 31.622777 spng | |
100 6 26 200.0 1.500000 31.622777 spng | |
101 7 25 200.0 1.500000 31.622777 spng | |
102 7 27 200.0 1.500000 31.622777 spng | |
103 8 26 200.0 1.500000 31.622777 spng | |
104 8 28 200.0 1.500000 31.622777 spng | |
105 9 27 200.0 1.500000 31.622777 spng | |
106 9 29 200.0 1.500000 31.622777 spng | |
107 10 28 200.0 1.500000 31.622777 spng | |
108 10 30 200.0 1.500000 31.622777 spng | |
109 11 29 200.0 1.500000 31.622777 spng | |
110 11 31 200.0 1.500000 31.622777 spng | |
111 12 30 200.0 1.500000 31.622777 spng | |
112 12 32 200.0 1.500000 31.622777 spng | |
113 13 31 200.0 1.500000 31.622777 spng | |
114 13 33 200.0 1.500000 31.622777 spng | |
115 14 32 200.0 1.500000 31.622777 spng | |
116 14 34 200.0 1.500000 31.622777 spng | |
117 15 33 200.0 1.500000 31.622777 spng | |
118 15 35 200.0 1.500000 31.622777 spng | |
119 16 34 200.0 1.500000 31.622777 spng | |
120 16 36 200.0 1.500000 31.622777 spng | |
121 17 35 200.0 1.500000 31.622777 spng | |
122 17 37 200.0 1.500000 31.622777 spng | |
123 18 36 200.0 1.500000 31.622777 spng | |
124 18 38 200.0 1.500000 31.622777 spng | |
125 19 37 200.0 1.500000 31.622777 spng | |
126 1 22 200.0 1.500000 43.600459 spng | |
127 3 20 200.0 1.500000 43.600459 spng | |
128 2 23 200.0 1.500000 44.407207 spng | |
129 4 21 200.0 1.500000 44.407207 spng | |
130 3 24 200.0 1.500000 44.407207 spng | |
131 5 22 200.0 1.500000 44.407207 spng | |
132 4 25 200.0 1.500000 44.407207 spng | |
133 6 23 200.0 1.500000 44.407207 spng | |
134 5 26 200.0 1.500000 44.407207 spng | |
135 7 24 200.0 1.500000 44.407207 spng | |
136 6 27 200.0 1.500000 44.407207 spng | |
137 8 25 200.0 1.500000 44.407207 spng | |
138 7 28 200.0 1.500000 44.407207 spng | |
139 9 26 200.0 1.500000 44.407207 spng | |
140 8 29 200.0 1.500000 44.407207 spng | |
141 10 27 200.0 1.500000 44.407207 spng | |
142 9 30 200.0 1.500000 44.407207 spng | |
143 11 28 200.0 1.500000 44.407207 spng | |
144 10 31 200.0 1.500000 44.407207 spng | |
145 12 29 200.0 1.500000 44.407207 spng | |
146 11 32 200.0 1.500000 44.407207 spng | |
147 13 30 200.0 1.500000 44.407207 spng | |
148 12 33 200.0 1.500000 44.407207 spng | |
149 14 31 200.0 1.500000 44.407207 spng | |
150 13 34 200.0 1.500000 44.407207 spng | |
151 15 33 200.0 1.500000 31.622777 spng | |
152 32 15 200.0 1.500000 44.407207 spng | |
153 14 35 200.0 1.500000 44.407207 spng | |
154 16 33 200.0 1.500000 44.407207 spng | |
155 15 36 200.0 1.500000 44.407207 spng | |
156 34 17 200.0 1.500000 44.407207 spng | |
157 16 37 200.0 1.500000 44.407207 spng | |
158 18 35 200.0 1.500000 44.407207 spng | |
159 17 38 200.0 1.500000 44.407207 spng | |
160 19 36 200.0 1.500000 44.407207 spng | |
! Send the half of the snake in a random direction | |
nodes> 10 [ swap nth ] with map | |
nodes> 10 [ 19 + swap nth ] with map append | |
100 random -50 + 100 random 100 + { -1 1 } random * 2array | |
[ swap set-node-vel ] curry | |
each ; | |
: go ( -- ) [ model ] go* ; | |
MAIN: go | |
]] | |
FILE: [[springies/models/2x2snake/authors.txt]] [[Eduardo Cavazos | |
]] | |
FILE: [[springies/models/2x2snake/tags.txt]] [[demos | |
]] | |
FILE: [[springies/models/2snake/authors.txt]] [[Eduardo Cavazos | |
]] | |
FILE: [[springies/models/2snake/2snake.factor]] [[ | |
USING: kernel namespaces arrays sequences math math.vectors random | |
springies springies.ui ; | |
IN: springies.models.2snake | |
: model ( -- ) | |
{ } clone >nodes | |
{ } clone >springs | |
0.001 >time-slice | |
gravity off | |
1 19.0 328.0 0.0 0.0 1.0 1.0 mass | |
2 36.0 328.0 0.0 0.0 1.0 1.0 mass | |
3 54.0 328.0 0.0 0.0 1.0 1.0 mass | |
4 72.0 328.0 0.0 0.0 1.0 1.0 mass | |
5 90.0 328.0 0.0 0.0 1.0 1.0 mass | |
6 108.0 328.0 0.0 0.0 1.0 1.0 mass | |
7 126.0 328.0 0.0 0.0 1.0 1.0 mass | |
8 144.0 328.0 0.0 0.0 1.0 1.0 mass | |
9 162.0 328.0 0.0 0.0 1.0 1.0 mass | |
10 180.0 328.0 0.0 0.0 1.0 1.0 mass | |
11 198.0 328.0 0.0 0.0 1.0 1.0 mass | |
12 216.0 328.0 0.0 0.0 1.0 1.0 mass | |
13 234.0 328.0 0.0 0.0 1.0 1.0 mass | |
14 252.0 328.0 0.0 0.0 1.0 1.0 mass | |
15 270.0 328.0 0.0 0.0 1.0 1.0 mass | |
16 288.0 328.0 0.0 0.0 1.0 1.0 mass | |
17 306.0 328.0 0.0 0.0 1.0 1.0 mass | |
18 324.0 328.0 0.0 0.0 1.0 1.0 mass | |
19 342.0 328.0 0.0 0.0 1.0 1.0 mass | |
20 360.0 328.0 0.0 0.0 1.0 1.0 mass | |
21 378.0 328.0 0.0 0.0 1.0 1.0 mass | |
22 396.0 328.0 0.0 0.0 1.0 1.0 mass | |
23 414.0 328.0 0.0 0.0 1.0 1.0 mass | |
24 432.0 328.0 0.0 0.0 1.0 1.0 mass | |
25 450.0 328.0 0.0 0.0 1.0 1.0 mass | |
26 468.0 328.0 0.0 0.0 1.0 1.0 mass | |
27 504.0 328.0 0.0 0.0 1.0 1.0 mass | |
28 486.0 328.0 0.0 0.0 1.0 1.0 mass | |
29 522.0 328.0 0.0 0.0 1.0 1.0 mass | |
30 540.0 328.0 0.0 0.0 1.0 1.0 mass | |
31 558.0 328.0 0.0 0.0 1.0 1.0 mass | |
32 576.0 328.0 0.0 0.0 1.0 1.0 mass | |
33 594.0 328.0 0.0 0.0 1.0 1.0 mass | |
34 612.0 328.0 0.0 0.0 1.0 1.0 mass | |
35 630.0 328.0 0.0 0.0 1.0 1.0 mass | |
1 1 2 200.0 1.500000 18.0 spng | |
2 3 2 200.0 1.500000 18.0 spng | |
3 3 4 200.0 1.500000 18.0 spng | |
4 4 5 200.0 1.500000 18.0 spng | |
5 5 6 200.0 1.500000 18.0 spng | |
6 6 7 200.0 1.500000 18.0 spng | |
7 7 8 200.0 1.500000 18.0 spng | |
8 8 9 200.0 1.500000 18.0 spng | |
9 9 10 200.0 1.500000 18.0 spng | |
10 10 11 200.0 1.500000 18.0 spng | |
11 11 12 200.0 1.500000 18.0 spng | |
12 12 13 200.0 1.500000 18.0 spng | |
13 13 14 200.0 1.500000 18.0 spng | |
14 14 15 200.0 1.500000 18.0 spng | |
15 15 16 200.0 1.500000 18.0 spng | |
16 16 17 200.0 1.500000 18.0 spng | |
17 17 18 200.0 1.500000 18.0 spng | |
18 18 19 200.0 1.500000 18.0 spng | |
19 19 20 200.0 1.500000 18.0 spng | |
20 20 21 200.0 1.500000 18.0 spng | |
21 21 22 200.0 1.500000 18.0 spng | |
22 22 23 200.0 1.500000 18.0 spng | |
23 23 24 200.0 1.500000 18.0 spng | |
24 24 25 200.0 1.500000 18.0 spng | |
25 25 26 200.0 1.500000 18.0 spng | |
26 26 28 200.0 1.500000 18.0 spng | |
27 28 27 200.0 1.500000 18.0 spng | |
28 27 29 200.0 1.500000 18.0 spng | |
29 29 30 200.0 1.500000 18.0 spng | |
30 30 31 200.0 1.500000 18.0 spng | |
31 31 32 200.0 1.500000 18.0 spng | |
32 32 33 200.0 1.500000 18.0 spng | |
33 33 34 200.0 1.500000 18.0 spng | |
34 34 35 200.0 1.500000 18.0 spng | |
35 1 3 200.0 1.500000 36.0 spng | |
36 2 4 200.0 1.500000 36.0 spng | |
37 3 5 200.0 1.500000 36.0 spng | |
38 4 6 200.0 1.500000 36.0 spng | |
39 5 7 200.0 1.500000 36.0 spng | |
40 6 8 200.0 1.500000 36.0 spng | |
41 7 9 200.0 1.500000 36.0 spng | |
42 8 10 200.0 1.500000 36.0 spng | |
43 9 11 200.0 1.500000 36.0 spng | |
44 10 12 200.0 1.500000 36.0 spng | |
45 11 13 200.0 1.500000 36.0 spng | |
46 12 14 200.0 1.500000 36.0 spng | |
47 13 15 200.0 1.500000 36.0 spng | |
48 14 16 200.0 1.500000 36.0 spng | |
49 15 17 200.0 1.500000 36.0 spng | |
50 16 18 200.0 1.500000 36.0 spng | |
51 17 19 200.0 1.500000 36.0 spng | |
52 18 20 200.0 1.500000 36.0 spng | |
53 19 21 200.0 1.500000 36.0 spng | |
54 20 22 200.0 1.500000 36.0 spng | |
55 21 23 200.0 1.500000 36.0 spng | |
56 22 24 200.0 1.500000 36.0 spng | |
57 23 25 200.0 1.500000 36.0 spng | |
58 24 26 200.0 1.500000 36.0 spng | |
59 25 28 200.0 1.500000 36.0 spng | |
60 26 27 200.0 1.500000 36.0 spng | |
61 28 29 200.0 1.500000 36.0 spng | |
62 27 30 200.0 1.500000 36.0 spng | |
63 29 31 200.0 1.500000 36.0 spng | |
64 30 32 200.0 1.500000 36.0 spng | |
65 31 33 200.0 1.500000 36.0 spng | |
66 32 34 200.0 1.500000 36.0 spng | |
67 33 35 200.0 1.500000 36.0 spng | |
nodes> [ 400 random -200 + 400 random -200 + 2array swap set-node-vel ] each ; | |
USING: threads ui ; | |
: go ( -- ) [ [ springies-window* 1000 sleep model ] with-scope ] with-ui ; | |
MAIN: go | |
]] | |
FILE: [[springies/models/2snake/tags.txt]] [[demos | |
]] | |
FILE: [[springies/models/ball/ball.factor]] [[ | |
USING: kernel namespaces sequences springies springies.ui ; | |
IN: springies.models.ball | |
: model ( -- ) | |
{ } clone >nodes | |
{ } clone >springs | |
0.01 >time-slice | |
gravity on | |
1 325.191871 140.872641 40.832215 -5.301529 1.0 1.0 mass | |
2 313.933994 149.011616 55.240875 5.026852 1.0 1.0 mass | |
3 309.133386 162.523019 72.798059 5.594199 1.0 1.0 mass | |
4 312.887152 176.436760 83.754277 -1.370025 1.0 1.0 mass | |
5 321.660596 187.895952 91.634021 -8.308630 1.0 1.0 mass | |
6 335.256132 192.503856 94.772924 -18.985044 1.0 1.0 mass | |
7 348.254504 188.731936 92.657963 -29.982110 1.0 1.0 mass | |
8 359.050972 180.780059 86.668616 -39.817638 1.0 1.0 mass | |
9 363.685639 167.752177 76.554871 -47.987107 1.0 1.0 mass | |
10 360.449954 154.092353 57.992242 -48.045772 1.0 1.0 mass | |
11 352.201411 142.382665 41.200547 -39.924209 1.0 1.0 mass | |
12 338.754859 137.460615 32.306364 -22.707784 1.0 1.0 mass | |
13 312.911184 114.835962 8.342965 5.878311 1.0 1.0 mass | |
14 290.521818 132.872407 33.212103 28.391710 1.0 1.0 mass | |
15 281.048450 160.314206 66.319674 32.935324 1.0 1.0 mass | |
16 287.450075 188.730522 93.898071 21.966741 1.0 1.0 mass | |
17 305.987715 211.206959 112.571044 5.089593 1.0 1.0 mass | |
18 333.289699 220.830317 121.166705 -17.204713 1.0 1.0 mass | |
19 361.089678 214.901909 117.183695 -41.776506 1.0 1.0 mass | |
20 382.690515 197.005784 101.789802 -63.980298 1.0 1.0 mass | |
21 392.095364 170.108402 75.453780 -78.414351 1.0 1.0 mass | |
22 386.286391 142.033621 41.812216 -77.402424 1.0 1.0 mass | |
23 368.355658 119.326317 12.658676 -58.885262 1.0 1.0 mass | |
24 341.159901 109.253775 -0.645459 -27.346079 1.0 1.0 mass | |
25 300.792976 88.652764 -23.770230 17.788258 1.0 1.0 mass | |
26 266.917041 116.942125 11.387083 52.603190 1.0 1.0 mass | |
27 252.824303 157.992984 59.144863 62.163730 1.0 1.0 mass | |
28 261.812599 201.245775 103.542171 47.141708 1.0 1.0 mass | |
29 290.323965 234.792944 133.016945 18.136362 1.0 1.0 mass | |
30 330.805232 249.331769 145.899409 -16.478401 1.0 1.0 mass | |
31 373.715232 241.181453 141.068680 -55.103677 1.0 1.0 mass | |
32 406.314817 213.217096 116.087430 -90.844012 1.0 1.0 mass | |
33 420.647493 172.661774 73.304028 -110.880720 1.0 1.0 mass | |
34 412.375908 129.697207 24.072484 -106.129512 1.0 1.0 mass | |
35 384.555754 95.915740 -16.565355 -77.142380 1.0 1.0 mass | |
36 344.134757 80.886540 -34.250916 -30.871105 1.0 1.0 mass | |
37 288.774590 62.672780 -55.431084 28.821437 1.0 1.0 mass | |
38 244.055965 100.457489 -9.756397 76.701354 1.0 1.0 mass | |
39 224.574635 156.693148 53.845562 91.755892 1.0 1.0 mass | |
40 235.856891 213.935639 112.462316 73.437061 1.0 1.0 mass | |
41 273.697931 257.991035 152.320671 33.701056 1.0 1.0 mass | |
42 329.129445 277.782400 170.727571 -15.899371 1.0 1.0 mass | |
43 386.065290 267.474982 165.436658 -68.761273 1.0 1.0 mass | |
44 429.946314 229.605765 132.087682 -116.795195 1.0 1.0 mass | |
45 449.164590 174.189613 73.084826 -143.228528 1.0 1.0 mass | |
46 438.674101 117.351918 9.340834 -136.225613 1.0 1.0 mass | |
47 401.586435 72.955570 -42.523445 -98.317857 1.0 1.0 mass | |
48 346.207804 52.561279 -67.447974 -34.980297 1.0 1.0 mass | |
1 1 2 150.0 2.0 14.0 spng | |
2 2 3 150.0 2.0 14.0 spng | |
3 3 4 150.0 2.0 14.0 spng | |
4 4 5 150.0 2.0 14.0 spng | |
5 5 6 150.0 2.0 14.0 spng | |
6 6 7 150.0 2.0 14.0 spng | |
7 7 8 150.0 2.0 14.0 spng | |
8 8 9 150.0 2.0 14.0 spng | |
9 9 10 150.0 2.0 14.0 spng | |
10 10 11 150.0 2.0 14.0 spng | |
11 11 12 150.0 2.0 14.0 spng | |
12 12 1 150.0 2.0 14.0 spng | |
13 13 14 150.0 2.0 28.0 spng | |
14 14 15 150.0 2.0 28.0 spng | |
15 15 16 150.0 2.0 28.0 spng | |
16 16 17 150.0 2.0 28.0 spng | |
17 17 18 150.0 2.0 28.0 spng | |
18 18 19 150.0 2.0 28.0 spng | |
19 19 20 150.0 2.0 28.0 spng | |
20 20 21 150.0 2.0 28.0 spng | |
21 21 22 150.0 2.0 28.0 spng | |
22 22 23 150.0 2.0 28.0 spng | |
23 23 24 150.0 2.0 28.0 spng | |
24 24 13 150.0 2.0 28.0 spng | |
25 25 26 150.0 2.0 44.0 spng | |
26 26 27 150.0 2.0 43.0 spng | |
27 27 28 150.0 2.0 44.0 spng | |
28 28 29 150.0 2.0 44.0 spng | |
29 29 30 150.0 2.0 43.0 spng | |
30 30 31 150.0 2.0 44.0 spng | |
31 31 32 150.0 2.0 43.0 spng | |
32 32 33 150.0 2.0 43.0 spng | |
33 33 34 150.0 2.0 44.0 spng | |
34 34 35 150.0 2.0 44.0 spng | |
35 35 36 150.0 2.0 43.0 spng | |
36 36 25 150.0 2.0 44.0 spng | |
37 37 38 150.0 2.0 58.0 spng | |
38 38 39 150.0 2.0 59.0 spng | |
39 39 40 150.0 2.0 58.0 spng | |
40 40 41 150.0 2.0 58.0 spng | |
41 41 42 150.0 2.0 59.0 spng | |
42 42 43 150.0 2.0 58.0 spng | |
43 43 44 150.0 2.0 58.0 spng | |
44 44 45 150.0 2.0 59.0 spng | |
45 45 46 150.0 2.0 58.0 spng | |
46 46 47 150.0 2.0 58.0 spng | |
47 47 48 150.0 2.0 59.0 spng | |
48 48 37 150.0 2.0 58.0 spng | |
49 1 13 150.0 2.0 29.0 spng | |
50 2 14 150.0 2.0 28.0 spng | |
51 3 15 150.0 2.0 28.0 spng | |
52 4 16 150.0 2.0 29.0 spng | |
53 5 17 150.0 2.0 28.0 spng | |
54 6 18 150.0 2.0 28.0 spng | |
55 7 19 150.0 2.0 29.0 spng | |
56 8 20 150.0 2.0 28.0 spng | |
57 9 21 150.0 2.0 28.0 spng | |
58 10 22 150.0 2.0 29.0 spng | |
59 11 23 150.0 2.0 28.0 spng | |
60 12 24 150.0 2.0 28.0 spng | |
61 13 25 150.0 2.0 29.0 spng | |
62 14 26 150.0 2.0 28.0 spng | |
63 15 27 150.0 2.0 28.0 spng | |
64 16 28 150.0 2.0 29.0 spng | |
65 17 29 150.0 2.0 28.0 spng | |
66 18 30 150.0 2.0 28.0 spng | |
67 19 31 150.0 2.0 29.0 spng | |
68 20 32 150.0 2.0 28.0 spng | |
69 21 33 150.0 2.0 28.0 spng | |
70 22 34 150.0 2.0 29.0 spng | |
71 23 35 150.0 2.0 28.0 spng | |
72 24 36 150.0 2.0 28.0 spng | |
73 25 37 150.0 2.0 29.0 spng | |
74 26 38 150.0 2.0 28.0 spng | |
75 27 39 150.0 2.0 28.0 spng | |
76 28 40 150.0 2.0 29.0 spng | |
77 29 41 150.0 2.0 28.0 spng | |
78 30 42 150.0 2.0 28.0 spng | |
79 31 43 150.0 2.0 29.0 spng | |
80 32 44 150.0 2.0 28.0 spng | |
81 33 45 150.0 2.0 28.0 spng | |
82 34 46 150.0 2.0 29.0 spng | |
83 35 47 150.0 2.0 28.0 spng | |
84 36 48 150.0 2.0 28.0 spng | |
85 1 14 150.0 2.0 35.0 spng | |
86 2 15 150.0 2.0 35.0 spng | |
87 3 16 150.0 2.0 34.0 spng | |
88 4 17 150.0 2.0 35.0 spng | |
89 5 18 150.0 2.0 35.0 spng | |
90 6 19 150.0 2.0 34.0 spng | |
91 7 20 150.0 2.0 35.0 spng | |
92 8 21 150.0 2.0 35.0 spng | |
93 9 22 150.0 2.0 34.0 spng | |
94 10 23 150.0 2.0 35.0 spng | |
95 11 24 150.0 2.0 35.0 spng | |
96 12 13 150.0 2.0 34.0 spng | |
97 13 26 150.0 2.0 46.0 spng | |
98 14 27 150.0 2.0 45.0 spng | |
99 15 28 150.0 2.0 45.0 spng | |
100 16 29 150.0 2.0 46.0 spng | |
101 17 30 150.0 2.0 45.0 spng | |
102 18 31 150.0 2.0 45.0 spng | |
103 19 32 150.0 2.0 45.0 spng | |
104 20 33 150.0 2.0 45.0 spng | |
105 21 34 150.0 2.0 45.0 spng | |
106 22 35 150.0 2.0 46.0 spng | |
107 23 36 150.0 2.0 45.0 spng | |
108 24 25 150.0 2.0 45.0 spng | |
109 25 38 150.0 2.0 58.0 spng | |
110 26 39 150.0 2.0 58.0 spng | |
111 27 40 150.0 2.0 58.0 spng | |
112 28 41 150.0 2.0 58.0 spng | |
113 29 42 150.0 2.0 58.0 spng | |
114 30 43 150.0 2.0 58.0 spng | |
115 31 44 150.0 2.0 58.0 spng | |
116 32 45 150.0 2.0 58.0 spng | |
117 33 46 150.0 2.0 58.0 spng | |
118 34 47 150.0 2.0 58.0 spng | |
119 35 48 150.0 2.0 58.0 spng | |
120 36 37 150.0 2.0 58.0 spng | |
121 1 24 150.0 2.0 35.0 spng | |
122 2 13 150.0 2.0 34.0 spng | |
123 3 14 150.0 2.0 35.0 spng | |
124 4 15 150.0 2.0 35.0 spng | |
125 5 16 150.0 2.0 34.0 spng | |
126 6 17 150.0 2.0 35.0 spng | |
127 7 18 150.0 2.0 35.0 spng | |
128 8 19 150.0 2.0 34.0 spng | |
129 9 20 150.0 2.0 35.0 spng | |
130 10 21 150.0 2.0 35.0 spng | |
131 11 22 150.0 2.0 34.0 spng | |
132 12 23 150.0 2.0 35.0 spng | |
133 13 36 150.0 2.0 46.0 spng | |
134 14 25 150.0 2.0 45.0 spng | |
135 15 26 150.0 2.0 45.0 spng | |
136 16 27 150.0 2.0 46.0 spng | |
137 17 28 150.0 2.0 45.0 spng | |
138 18 29 150.0 2.0 45.0 spng | |
139 19 30 150.0 2.0 46.0 spng | |
140 20 31 150.0 2.0 45.0 spng | |
141 21 32 150.0 2.0 45.0 spng | |
142 22 33 150.0 2.0 46.0 spng | |
143 23 34 150.0 2.0 45.0 spng | |
144 24 35 150.0 2.0 45.0 spng | |
145 25 48 150.0 2.0 58.0 spng | |
146 26 37 150.0 2.0 58.0 spng | |
147 27 38 150.0 2.0 58.0 spng | |
148 28 39 150.0 2.0 58.0 spng | |
149 29 40 150.0 2.0 58.0 spng | |
150 30 41 150.0 2.0 58.0 spng | |
151 31 42 150.0 2.0 58.0 spng | |
152 32 43 150.0 2.0 58.0 spng | |
153 33 44 150.0 2.0 58.0 spng | |
154 34 45 150.0 2.0 58.0 spng | |
155 35 46 150.0 2.0 58.0 spng | |
156 36 47 150.0 2.0 58.0 spng | |
157 10 4 150.0 2.0 52.331631 spng | |
158 7 1 150.0 2.0 52.436772 spng | |
159 12 6 150.0 2.0 54.680698 spng | |
160 5 11 150.0 2.0 54.589379 spng | |
161 9 3 150.0 2.0 54.451569 spng | |
162 2 8 150.0 2.0 54.482231 spng | |
163 45 11 150.0 2.0 101.408150 spng | |
164 46 12 150.0 2.0 101.542452 spng | |
165 47 1 150.0 2.0 101.963064 spng | |
166 48 2 150.0 2.0 101.517329 spng | |
167 37 3 150.0 2.0 101.603694 spng | |
168 38 4 150.0 2.0 102.014031 spng | |
169 39 5 150.0 2.0 101.547660 spng | |
170 40 6 150.0 2.0 101.573762 spng | |
171 41 7 150.0 2.0 101.897300 spng | |
172 42 8 150.0 2.0 101.497982 spng | |
173 43 9 150.0 2.0 101.870594 spng | |
174 44 10 150.0 2.0 102.043753 spng | |
175 45 11 150.0 2.0 101.408150 spng | |
176 46 8 150.0 2.0 101.548938 spng | |
177 47 10 150.0 2.0 90.645939 spng | |
178 48 10 150.0 2.0 101.952119 spng | |
179 37 11 150.0 2.0 101.552352 spng | |
180 38 12 150.0 2.0 101.491447 spng | |
181 39 1 150.0 2.0 101.971524 spng | |
182 40 2 150.0 2.0 101.587400 spng | |
183 41 3 150.0 2.0 101.519279 spng | |
184 42 4 150.0 2.0 101.976181 spng | |
185 43 5 150.0 2.0 101.714570 spng | |
186 44 6 150.0 2.0 101.388747 spng | |
187 45 7 150.0 2.0 101.773286 spng | |
nodes> [ { 0 100 } swap set-node-vel ] each ; | |
USING: threads ui ; | |
: go ( -- ) [ [ springies-window* 1000 sleep model ] with-scope ] with-ui ; | |
MAIN: go | |
]] | |
FILE: [[springies/models/ball/authors.txt]] [[Eduardo Cavazos | |
]] | |
FILE: [[springies/models/ball/tags.txt]] [[demos | |
]] | |
FILE: [[springies/models/3snake/3snake.factor]] [[ | |
USING: kernel namespaces arrays sequences threads math ui random fry | |
springies springies.ui ; | |
IN: springies.models.3snake | |
: random-range ( a b -- n ) 1+ over - random + ; | |
: model ( -- ) | |
{ } clone >nodes | |
{ } clone >springs | |
0.001 >time-slice | |
gravity off | |
1 19.0 328.0 0.0 0.0 1.0 1.0 mass | |
2 36.0 328.0 0.0 0.0 1.0 1.0 mass | |
3 54.0 328.0 0.0 0.0 1.0 1.0 mass | |
4 72.0 328.0 0.0 0.0 1.0 1.0 mass | |
5 90.0 328.0 0.0 0.0 1.0 1.0 mass | |
6 108.0 328.0 0.0 0.0 1.0 1.0 mass | |
7 126.0 328.0 0.0 0.0 1.0 1.0 mass | |
8 144.0 328.0 0.0 0.0 1.0 1.0 mass | |
9 162.0 328.0 0.0 0.0 1.0 1.0 mass | |
10 180.0 328.0 0.0 0.0 1.0 1.0 mass | |
11 198.0 328.0 0.0 0.0 1.0 1.0 mass | |
12 216.0 328.0 0.0 0.0 1.0 1.0 mass | |
13 234.0 328.0 0.0 0.0 1.0 1.0 mass | |
14 252.0 328.0 0.0 0.0 1.0 1.0 mass | |
15 270.0 328.0 0.0 0.0 1.0 1.0 mass | |
16 288.0 328.0 0.0 0.0 1.0 1.0 mass | |
17 306.0 328.0 0.0 0.0 1.0 1.0 mass | |
18 324.0 328.0 0.0 0.0 1.0 1.0 mass | |
19 342.0 328.0 0.0 0.0 1.0 1.0 mass | |
20 360.0 328.0 0.0 0.0 1.0 1.0 mass | |
21 378.0 328.0 0.0 0.0 1.0 1.0 mass | |
22 396.0 328.0 0.0 0.0 1.0 1.0 mass | |
23 414.0 328.0 0.0 0.0 1.0 1.0 mass | |
24 432.0 328.0 0.0 0.0 1.0 1.0 mass | |
25 450.0 328.0 0.0 0.0 1.0 1.0 mass | |
26 468.0 328.0 0.0 0.0 1.0 1.0 mass | |
27 504.0 328.0 0.0 0.0 1.0 1.0 mass | |
28 486.0 328.0 0.0 0.0 1.0 1.0 mass | |
29 522.0 328.0 0.0 0.0 1.0 1.0 mass | |
30 540.0 328.0 0.0 0.0 1.0 1.0 mass | |
31 558.0 328.0 0.0 0.0 1.0 1.0 mass | |
32 576.0 328.0 0.0 0.0 1.0 1.0 mass | |
33 594.0 328.0 0.0 0.0 1.0 1.0 mass | |
34 612.0 328.0 0.0 0.0 1.0 1.0 mass | |
35 626.0 328.0 0.0 0.0 1.0 1.0 mass | |
1 1 2 200.0 1.500000 18.0 spng | |
2 3 2 200.0 1.500000 18.0 spng | |
3 3 4 200.0 1.500000 18.0 spng | |
4 4 5 200.0 1.500000 18.0 spng | |
5 5 6 200.0 1.500000 18.0 spng | |
6 6 7 200.0 1.500000 18.0 spng | |
7 7 8 200.0 1.500000 18.0 spng | |
8 8 9 200.0 1.500000 18.0 spng | |
9 9 10 200.0 1.500000 18.0 spng | |
10 10 11 200.0 1.500000 18.0 spng | |
11 11 12 200.0 1.500000 18.0 spng | |
12 12 13 200.0 1.500000 18.0 spng | |
13 13 14 200.0 1.500000 18.0 spng | |
14 14 15 200.0 1.500000 18.0 spng | |
15 15 16 200.0 1.500000 18.0 spng | |
16 16 17 200.0 1.500000 18.0 spng | |
17 17 18 200.0 1.500000 18.0 spng | |
18 18 19 200.0 1.500000 18.0 spng | |
19 19 20 200.0 1.500000 18.0 spng | |
20 20 21 200.0 1.500000 18.0 spng | |
21 21 22 200.0 1.500000 18.0 spng | |
22 22 23 200.0 1.500000 18.0 spng | |
23 23 24 200.0 1.500000 18.0 spng | |
24 24 25 200.0 1.500000 18.0 spng | |
25 25 26 200.0 1.500000 18.0 spng | |
26 26 28 200.0 1.500000 18.0 spng | |
27 28 27 200.0 1.500000 18.0 spng | |
28 27 29 200.0 1.500000 18.0 spng | |
29 29 30 200.0 1.500000 18.0 spng | |
30 30 31 200.0 1.500000 18.0 spng | |
31 31 32 200.0 1.500000 18.0 spng | |
32 32 33 200.0 1.500000 18.0 spng | |
33 33 34 200.0 1.500000 18.0 spng | |
34 34 35 200.0 1.500000 18.0 spng | |
35 1 3 200.0 1.500000 36.0 spng | |
36 2 4 200.0 1.500000 36.0 spng | |
37 3 5 200.0 1.500000 36.0 spng | |
38 4 6 200.0 1.500000 36.0 spng | |
39 5 7 200.0 1.500000 36.0 spng | |
40 6 8 200.0 1.500000 36.0 spng | |
41 7 9 200.0 1.500000 36.0 spng | |
42 8 10 200.0 1.500000 36.0 spng | |
43 9 11 200.0 1.500000 36.0 spng | |
44 10 12 200.0 1.500000 36.0 spng | |
45 11 13 200.0 1.500000 36.0 spng | |
46 12 14 200.0 1.500000 36.0 spng | |
47 13 15 200.0 1.500000 36.0 spng | |
48 14 16 200.0 1.500000 36.0 spng | |
49 15 17 200.0 1.500000 36.0 spng | |
50 16 18 200.0 1.500000 36.0 spng | |
51 17 19 200.0 1.500000 36.0 spng | |
52 18 20 200.0 1.500000 36.0 spng | |
53 19 21 200.0 1.500000 36.0 spng | |
54 20 22 200.0 1.500000 36.0 spng | |
55 21 23 200.0 1.500000 36.0 spng | |
56 22 24 200.0 1.500000 36.0 spng | |
57 23 25 200.0 1.500000 36.0 spng | |
58 24 26 200.0 1.500000 36.0 spng | |
59 25 28 200.0 1.500000 36.0 spng | |
60 26 27 200.0 1.500000 36.0 spng | |
61 28 29 200.0 1.500000 36.0 spng | |
62 27 30 200.0 1.500000 36.0 spng | |
63 29 31 200.0 1.500000 36.0 spng | |
64 30 32 200.0 1.500000 36.0 spng | |
65 31 33 200.0 1.500000 36.0 spng | |
66 32 34 200.0 1.500000 36.0 spng | |
67 33 35 200.0 1.500000 36.0 spng | |
68 1 4 200.0 1.500000 53.0 spng | |
69 2 5 200.0 1.500000 54.0 spng | |
70 3 6 200.0 1.500000 54.0 spng | |
71 4 7 200.0 1.500000 54.0 spng | |
72 5 8 200.0 1.500000 54.0 spng | |
73 6 9 200.0 1.500000 54.0 spng | |
74 7 10 200.0 1.500000 54.0 spng | |
75 8 11 200.0 1.500000 54.0 spng | |
76 9 12 200.0 1.500000 54.0 spng | |
77 10 13 200.0 1.500000 54.0 spng | |
78 11 14 200.0 1.500000 54.0 spng | |
79 12 15 200.0 1.500000 54.0 spng | |
80 13 16 200.0 1.500000 54.0 spng | |
81 14 17 200.0 1.500000 54.0 spng | |
82 15 18 200.0 1.500000 54.0 spng | |
83 16 19 200.0 1.500000 54.0 spng | |
84 17 20 200.0 1.500000 54.0 spng | |
85 18 21 200.0 1.500000 54.0 spng | |
86 19 22 200.0 1.500000 54.0 spng | |
87 20 23 200.0 1.500000 54.0 spng | |
88 21 24 200.0 1.500000 54.0 spng | |
89 22 25 200.0 1.500000 54.0 spng | |
90 23 26 200.0 1.500000 54.0 spng | |
91 24 28 200.0 1.500000 54.0 spng | |
92 25 27 200.0 1.500000 54.0 spng | |
93 26 29 200.0 1.500000 54.0 spng | |
94 28 30 200.0 1.500000 54.0 spng | |
95 27 31 200.0 1.500000 54.0 spng | |
96 29 32 200.0 1.500000 54.0 spng | |
97 30 33 200.0 1.500000 54.0 spng | |
98 31 34 200.0 1.500000 54.0 spng | |
99 32 35 200.0 1.500000 50.0 spng | |
10 | |
[ | |
-400 400 random-range -400 400 random-range 2array | |
nodes> random | |
set-node-vel | |
] | |
times | |
; | |
! : go* ( quot -- ) | |
! [ [ [ springies-window* 1000 sleep % ] with-scope ] with-ui ] bake call ; | |
: go* ( quot -- ) '[ [ springies-window* 1000 sleep @ ] with-scope ] with-ui ; | |
! : go ( -- ) [ [ springies-window* 1000 sleep model ] with-scope ] with-ui ; | |
: go ( -- ) [ model ] go* ; | |
MAIN: go | |
]] | |
FILE: [[springies/models/3snake/authors.txt]] [[Eduardo Cavazos | |
]] | |
FILE: [[springies/models/3snake/tags.txt]] [[demos | |
]] | |
FILE: [[springies/models/urchin/urchin.factor]] [[ | |
USING: kernel namespaces arrays sequences threads math math.vectors | |
ui random | |
springies springies.ui ; | |
IN: springies.models.urchin | |
: model ( -- ) | |
{ } clone >nodes | |
{ } clone >springs | |
0.007 >time-slice | |
gravity on | |
1 507.296953 392.174236 -11.451186 -71.267273 1.0 1.0 mass | |
2 514.879820 372.128025 11.950035 -70.858717 1.0 1.0 mass | |
3 536.571268 364.423706 18.394466 -41.159445 1.0 1.0 mass | |
4 554.886966 369.953895 15.173664 -11.009243 1.0 1.0 mass | |
5 572.432935 379.927626 8.228103 -1.120846 1.0 1.0 mass | |
6 585.774508 392.380791 5.443281 -8.186599 1.0 1.0 mass | |
7 584.650543 411.934530 -15.582843 -24.911756 1.0 1.0 mass | |
8 569.409148 424.155713 -24.100159 -42.285960 1.0 1.0 mass | |
9 553.751996 434.663690 -26.069217 -41.610454 1.0 1.0 mass | |
10 536.684374 444.915694 -30.702349 -45.021926 1.0 1.0 mass | |
11 516.677286 435.936238 -33.128410 -60.977340 1.0 1.0 mass | |
12 514.170680 414.649472 -24.471518 -64.104425 1.0 1.0 mass | |
13 602.101547 478.298945 1.612646 -53.040881 1.0 1.0 mass | |
14 637.0 427.598266 0.0 0.0 1.0 1.0 mass | |
15 608.000171 350.425575 31.812856 23.456940 1.0 1.0 mass | |
16 484.367809 332.414622 42.575378 -91.238351 1.0 1.0 mass | |
17 480.857379 475.215663 -24.240991 -53.909049 1.0 1.0 mass | |
18 548.580015 492.173168 -34.565312 -52.436468 1.0 1.0 mass | |
19 578.155338 487.173526 22.544495 -71.920721 1.0 1.0 mass | |
20 630.992588 379.333707 16.662115 37.873709 1.0 1.0 mass | |
21 591.256916 324.817423 63.036114 27.988433 1.0 1.0 mass | |
22 539.051461 311.597938 159.501014 -27.955219 1.0 1.0 mass | |
23 448.396171 396.882674 -15.045910 -138.652372 1.0 1.0 mass | |
24 448.194414 419.993896 -27.625008 -84.936708 1.0 1.0 mass | |
1 1 2 200.0 3.0 20.0 spng | |
2 2 3 200.0 3.0 20.0 spng | |
3 3 4 200.0 3.0 20.0 spng | |
4 4 5 200.0 3.0 20.0 spng | |
5 5 6 200.0 3.0 20.0 spng | |
6 6 7 200.0 3.0 20.0 spng | |
7 7 8 200.0 3.0 20.0 spng | |
8 8 9 200.0 3.0 20.0 spng | |
9 9 10 200.0 3.0 20.0 spng | |
10 10 11 200.0 3.0 20.0 spng | |
11 11 12 200.0 3.0 20.0 spng | |
12 1 3 200.0 3.0 40.0 spng | |
13 2 4 200.0 3.0 40.0 spng | |
14 3 5 200.0 3.0 40.0 spng | |
15 4 6 200.0 3.0 40.0 spng | |
16 6 8 200.0 3.0 40.0 spng | |
17 7 9 200.0 3.0 40.0 spng | |
18 8 10 200.0 3.0 40.0 spng | |
19 9 11 200.0 3.0 40.0 spng | |
20 10 12 200.0 3.0 40.0 spng | |
21 12 1 200.0 3.0 21.0 spng | |
22 12 2 200.0 3.0 41.0 spng | |
23 11 1 200.0 3.0 41.0 spng | |
24 6 12 200.0 3.0 72.681733 spng | |
25 5 11 200.0 3.0 81.191259 spng | |
26 10 4 200.0 3.0 76.026311 spng | |
27 3 9 200.0 3.0 72.615425 spng | |
28 8 2 200.0 3.0 74.966659 spng | |
29 1 7 200.0 3.0 80.280757 spng | |
30 17 11 200.0 3.0 55.036352 spng | |
31 10 18 200.0 3.0 49.819675 spng | |
32 19 9 200.0 3.0 54.918121 spng | |
33 8 13 200.0 3.0 62.201286 spng | |
34 14 7 200.0 3.0 58.600341 spng | |
35 6 20 200.0 3.0 46.400431 spng | |
36 15 5 200.0 3.0 44.045431 spng | |
37 4 21 200.0 3.0 57.454330 spng | |
38 22 3 200.0 3.0 53.823787 spng | |
39 2 16 200.0 3.0 51.039201 spng | |
40 23 1 200.0 3.0 58.668561 spng | |
41 12 24 200.0 3.0 64.404969 spng | |
42 24 11 200.0 3.0 71.217975 spng | |
43 17 12 200.0 3.0 65.0 spng | |
44 11 18 200.0 3.0 60.745370 spng | |
45 18 9 200.0 3.0 60.406953 spng | |
46 9 13 200.0 3.0 67.779053 spng | |
47 13 7 200.0 3.0 66.708320 spng | |
48 7 20 200.0 3.0 55.659680 spng | |
49 20 5 200.0 3.0 60.0 spng | |
50 5 21 200.0 3.0 61.846584 spng | |
51 21 3 200.0 3.0 64.031242 spng | |
52 3 16 200.0 3.0 63.568860 spng | |
53 16 1 200.0 3.0 59.774577 spng | |
54 1 24 200.0 3.0 65.802736 spng | |
55 17 10 200.0 3.0 64.845971 spng | |
56 10 19 200.0 3.0 58.249464 spng | |
57 19 8 200.0 3.0 67.268120 spng | |
58 8 14 200.0 3.0 67.268120 spng | |
59 14 6 200.0 3.0 64.629715 spng | |
60 6 15 200.0 3.0 50.089919 spng | |
61 15 4 200.0 3.0 56.320511 spng | |
62 4 22 200.0 3.0 60.728906 spng | |
63 22 2 200.0 3.0 61.032778 spng | |
64 2 23 200.0 3.0 66.528190 spng | |
65 23 12 200.0 3.0 72.277244 spng | |
nodes> | |
75 random -75 + 0 2array [ over node-vel v+ swap set-node-vel ] | |
curry each | |
; | |
: go ( -- ) [ model ] go* ; | |
MAIN: go | |
]] | |
FILE: [[springies/models/urchin/authors.txt]] [[Eduardo Cavazos | |
]] | |
FILE: [[springies/models/urchin/tags.txt]] [[demos | |
]] | |
FILE: [[springies/models/nifty/nifty.factor]] [[ | |
USING: kernel namespaces arrays sequences threads math math.vectors | |
ui random springies springies.ui ; | |
IN: springies.models.nifty | |
: model ( -- ) | |
{ } clone >nodes | |
{ } clone >springs | |
0.007 >time-slice | |
gravity off | |
1 148.581450999999987 350.573888000000011 0 -7.75 1 0.1 mass | |
2 168.564277000000004 351.402524000000028 0 -7.75 1 0.1 mass | |
3 188.54710399999999 352.231158999999991 0 -7.75 1 0.1 mass | |
4 208.529931000000005 353.059794000000011 0 -7.75 1 0.1 mass | |
5 228.512757999999991 353.888428999999974 0 -7.75 1 0.1 mass | |
6 248.495584000000008 354.717063999999993 0 -7.75 1 0.1 mass | |
7 149.410086000000007 330.591061000000025 0 -7.75 1 0.1 mass | |
8 150.238720999999998 310.608234999999979 0 -7.75 1 0.1 mass | |
9 151.06735599999999 290.625407999999993 0 -7.75 1 0.1 mass | |
10 151.895991000000009 270.642581000000007 0 -7.75 1 0.1 mass | |
11 152.724626000000001 250.65975499999999 0 -7.75 1 0.1 mass | |
12 172.707452999999987 251.48839000000001 0 -7.749999 1 0.1 mass | |
13 192.690280000000001 252.317025000000001 0 -7.75 1 0.1 mass | |
14 212.67310599999999 253.145659999999992 0 -7.75 1 0.1 mass | |
15 232.655933000000005 253.974295000000012 0 -7.75 1 0.1 mass | |
16 252.638759999999991 254.802930000000003 0 -7.75 1 0.1 mass | |
17 251.810124999999999 274.78575699999999 0 -7.75 1 0.1 mass | |
18 250.98148900000001 294.768583999999976 0 -7.75 1 0.1 mass | |
19 249.324218999999999 334.734237000000007 0 -7.75 1 0.1 mass | |
20 250.152853999999991 314.751410000000021 0 -7.75 1 0.1 mass | |
1 1 2 200 1.5 20 spng | |
2 2 3 200 1.5 20 spng | |
3 3 4 200 1.5 20 spng | |
4 4 5 200 1.5 20 spng | |
5 5 6 200 1.5 20 spng | |
6 6 19 200 1.5 20 spng | |
7 19 20 200 1.5 20 spng | |
8 20 18 200 1.5 20 spng | |
9 18 17 200 1.5 20 spng | |
10 17 16 200 1.5 20 spng | |
11 16 15 200 1.5 20 spng | |
12 15 14 200 1.5 20 spng | |
13 14 13 200 1.5 20 spng | |
14 13 12 200 1.5 20 spng | |
15 12 11 200 1.5 20 spng | |
16 11 10 200 1.5 20 spng | |
17 10 9 200 1.5 20 spng | |
18 9 8 200 1.5 20 spng | |
19 8 7 200 1.5 20 spng | |
20 7 1 200 1.5 20 spng | |
21 1 19 200 1.5 101.98039 spng | |
22 19 14 200 1.5 89.4427189999999968 spng | |
23 14 8 200 1.5 84.8528139999999951 spng | |
24 8 5 200 1.5 89.4427189999999968 spng | |
25 5 16 200 1.5 101.98039 spng | |
26 16 10 200 1.5 101.98039 spng | |
27 10 3 200 1.5 89.4427189999999968 spng | |
28 3 18 200 1.5 84.8528139999999951 spng | |
29 18 12 200 1.5 89.4427189999999968 spng | |
30 12 1 200 1.5 101.98039 spng | |
31 2 20 200 1.5 89.4427189999999968 spng | |
32 20 13 200 1.5 84.8528139999999951 spng | |
33 13 7 200 1.5 89.4427189999999968 spng | |
34 7 6 200 1.5 101.98039 spng | |
35 6 15 200 1.5 101.98039 spng | |
36 15 9 200 1.5 89.4427189999999968 spng | |
37 9 4 200 1.5 84.8528139999999951 spng | |
38 4 17 200 1.5 89.4427189999999968 spng | |
39 17 11 200 1.5 101.98039 spng | |
40 11 2 200 1.5 101.98039 spng | |
nodes> 200 random -100 + 200 random -100 + 2array [ swap set-node-vel ] curry | |
each ; | |
: go ( -- ) [ model ] go* ; | |
MAIN: go | |
]] | |
FILE: [[springies/models/nifty/authors.txt]] [[Eduardo Cavazos | |
]] | |
FILE: [[springies/models/nifty/tags.txt]] [[demos | |
]] | |
FILE: [[springies/summary.txt]] [[Mass and spring simulation (inspired by xspringies) | |
]] | |
FILE: [[springies/springies.factor]] [[ | |
USING: kernel combinators sequences arrays math math.vectors | |
generalizations vars accessors math.physics.vel ; | |
IN: springies | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: scalar-projection ( a b -- n ) [ v. ] [ nip norm ] 2bi / ; | |
: vector-projection ( a b -- vec ) | |
[ nip normalize ] [ scalar-projection ] 2bi v*n ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
VAR: nodes | |
VAR: springs | |
VAR: time-slice | |
VAR: world-size | |
: world-width ( -- width ) world-size> first ; | |
: world-height ( -- height ) world-size> second ; | |
VAR: gravity | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! node | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
TUPLE: node < vel mass elas force ; | |
C: <node> node | |
: node-vel ( node -- vel ) vel>> ; | |
: set-node-vel ( vel node -- ) swap >>vel drop ; | |
: pos-x ( node -- x ) pos>> first ; | |
: pos-y ( node -- y ) pos>> second ; | |
: vel-x ( node -- y ) vel>> first ; | |
: vel-y ( node -- y ) vel>> second ; | |
: >>pos-x ( node x -- node ) over pos>> set-first ; | |
: >>pos-y ( node y -- node ) over pos>> set-second ; | |
: >>vel-x ( node x -- node ) over vel>> set-first ; | |
: >>vel-y ( node y -- node ) over vel>> set-second ; | |
: apply-force ( node vec -- ) over force>> v+ >>force drop ; | |
: reset-force ( node -- node ) 0 0 2array >>force ; | |
: node-id ( id -- node ) 1- nodes> nth ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! spring | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
TUPLE: spring rest-length k damp node-a node-b ; | |
C: <spring> spring | |
: end-points ( spring -- b-pos a-pos ) | |
[ node-b>> pos>> ] [ node-a>> pos>> ] bi ; | |
: spring-length ( spring -- length ) end-points v- norm ; | |
: stretch-length ( spring -- length ) | |
[ spring-length ] [ rest-length>> ] bi - ; | |
: dir ( spring -- vec ) end-points v- normalize ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! Hooke | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! | |
! F = -kx | |
! | |
! k :: spring constant | |
! x :: distance stretched beyond rest length | |
! | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: hooke-force-mag ( spring -- mag ) [ k>> ] [ stretch-length ] bi * ; | |
: hooke-force ( spring -- force ) [ dir ] [ hooke-force-mag ] bi v*n ; | |
: hooke-forces ( spring -- a b ) hooke-force dup vneg ; | |
: act-on-nodes-hooke ( spring -- ) | |
[ node-a>> ] [ node-b>> ] [ ] tri hooke-forces swapd | |
apply-force | |
apply-force ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! damping | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! | |
! F = -bv | |
! | |
! b :: Damping constant | |
! v :: Velocity | |
! | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! : damping-force-a ( spring -- vec ) | |
! [ spring-node-a node-vel ] [ spring-damp ] bi v*n vneg ; | |
! : damping-force-b ( spring -- vec ) | |
! [ spring-node-b node-vel ] [ spring-damp ] bi v*n vneg ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: relative-velocity-a ( spring -- vel ) | |
[ node-a>> vel>> ] [ node-b>> vel>> ] bi v- ; | |
: unit-vec-b->a ( spring -- vec ) | |
[ node-a>> pos>> ] [ node-b>> pos>> ] bi v- ; | |
: relative-velocity-along-spring-a ( spring -- vel ) | |
[ relative-velocity-a ] [ unit-vec-b->a ] bi vector-projection ; | |
: damping-force-a ( spring -- vec ) | |
[ relative-velocity-along-spring-a ] [ damp>> ] bi v*n vneg ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: relative-velocity-b ( spring -- vel ) | |
[ node-b>> vel>> ] [ node-a>> vel>> ] bi v- ; | |
: unit-vec-a->b ( spring -- vec ) | |
[ node-b>> pos>> ] [ node-a>> pos>> ] bi v- ; | |
: relative-velocity-along-spring-b ( spring -- vel ) | |
[ relative-velocity-b ] [ unit-vec-a->b ] bi vector-projection ; | |
: damping-force-b ( spring -- vec ) | |
[ relative-velocity-along-spring-b ] [ damp>> ] bi v*n vneg ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: act-on-nodes-damping ( spring -- ) | |
dup | |
[ node-a>> ] [ damping-force-a ] bi apply-force | |
[ node-b>> ] [ damping-force-b ] bi apply-force ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: below? ( node -- ? ) pos-y 0 < ; | |
: above? ( node -- ? ) pos-y world-height >= ; | |
: beyond-left? ( node -- ? ) pos-x 0 < ; | |
: beyond-right? ( node -- ? ) pos-x world-width >= ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: bounce-top ( node -- ) | |
world-height 1- >>pos-y | |
dup [ vel-y ] [ elas>> ] bi * neg >>vel-y | |
drop ; | |
: bounce-bottom ( node -- ) | |
0 >>pos-y | |
dup [ vel-y ] [ elas>> ] bi * neg >>vel-y | |
drop ; | |
: bounce-left ( node -- ) | |
0 >>pos-x | |
dup [ vel-x ] [ elas>> ] bi * neg >>vel-x | |
drop ; | |
: bounce-right ( node -- ) | |
world-width 1- >>pos-x | |
dup [ vel-x ] [ elas>> ] bi * neg >>vel-x | |
drop ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: handle-bounce ( node -- ) | |
{ { [ dup above? ] [ bounce-top ] } | |
{ [ dup below? ] [ bounce-bottom ] } | |
{ [ dup beyond-left? ] [ bounce-left ] } | |
{ [ dup beyond-right? ] [ bounce-right ] } | |
{ [ t ] [ drop ] } } | |
cond ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: act-on-nodes ( spring -- ) | |
dup | |
act-on-nodes-hooke | |
act-on-nodes-damping ; | |
! : act-on-nodes ( spring -- ) act-on-nodes-hooke ; | |
: loop-over-springs ( -- ) springs> [ act-on-nodes ] each ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: apply-gravity ( node -- ) { 0 -9.8 } apply-force ; | |
: do-gravity ( -- ) gravity> [ nodes> [ apply-gravity ] each ] when ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! F = ma | |
: calc-acceleration ( node -- vec ) [ force>> ] [ mass>> ] bi v/n ; | |
: new-vel ( node -- vel ) | |
[ vel>> ] [ calc-acceleration time-slice> v*n ] bi v+ ; | |
: new-pos ( node -- pos ) [ pos>> ] [ vel>> time-slice> v*n ] bi v+ ; | |
: iterate-node ( node -- ) | |
dup new-pos >>pos | |
dup new-vel >>vel | |
reset-force | |
handle-bounce ; | |
: iterate-nodes ( -- ) nodes> [ iterate-node ] each ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: iterate-system ( -- ) do-gravity loop-over-springs iterate-nodes ; | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! Reading xspringies data files | |
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
: mass ( id x y x-vel y-vel mass elas -- ) | |
node new | |
swap >>elas | |
swap >>mass | |
-rot 2array >>vel | |
-rot 2array >>pos | |
0 0 2array >>force | |
nodes> swap suffix >nodes | |
drop ; | |
: spng ( id id-a id-b k damp rest-length -- ) | |
spring new | |
swap >>rest-length | |
swap >>damp | |
swap >>k | |
swap node-id >>node-b | |
swap node-id >>node-a | |
springs> swap suffix >springs | |
drop ; | |
]] | |
FILE: [[springies/authors.txt]] [[Eduardo Cavazos | |
]] | |
FILE: [[springies/tags.txt]] [[simulation | |
physics | |
demos]] | |
FILE: [[gstreamer/plugins/pbutils/pbutils.factor]] [[! Copyright (C) 2010 Anton Gorenko. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: gstreamer.pbutils.ffi ; | |
IN: gstreamer.pbutils | |
]] | |
FILE: [[gstreamer/plugins/pbutils/GstPbutils-0.10.gir]] [[<?xml version="1.0"?> | |
<!-- This file was automatically generated from C sources - DO NOT EDIT! | |
To affect the contents of this file, edit the original C definitions, | |
and/or use gtk-doc annotations. --> | |
<repository version="1.2" | |
xmlns="http://www.gtk.org/introspection/core/1.0" | |
xmlns:c="http://www.gtk.org/introspection/c/1.0" | |
xmlns:glib="http://www.gtk.org/introspection/glib/1.0"> | |
<include name="GLib" version="2.0"/> | |
<include name="GModule" version="2.0"/> | |
<include name="GObject" version="2.0"/> | |
<include name="Gst" version="0.10"/> | |
<include name="libxml2" version="2.0"/> | |
<package name="gstreamer-pbutils-0.10"/> | |
<c:include name="gst/pbutils/codec-utils.h"/> | |
<c:include name="gst/pbutils/descriptions.h"/> | |
<c:include name="gst/pbutils/encoding-profile.h"/> | |
<c:include name="gst/pbutils/encoding-target.h"/> | |
<c:include name="gst/pbutils/gstdiscoverer.h"/> | |
<c:include name="gst/pbutils/gstpluginsbaseversion.h"/> | |
<c:include name="gst/pbutils/install-plugins.h"/> | |
<c:include name="gst/pbutils/missing-plugins.h"/> | |
<c:include name="gst/pbutils/pbutils-enumtypes.h"/> | |
<c:include name="gst/pbutils/pbutils.h"/> | |
<namespace name="GstPbutils" | |
version="0.10" | |
shared-library="libgstpbutils-0.10.so.0,libgstreamer-0.10.so.0" | |
c:identifier-prefixes="Gst" | |
c:symbol-prefixes="gst"> | |
<alias name="DiscovererAudioInfoClass" | |
c:type="GstDiscovererAudioInfoClass"> | |
<type name="Gst.MiniObjectClass" c:type="GstMiniObjectClass"/> | |
</alias> | |
<alias name="DiscovererContainerInfoClass" | |
c:type="GstDiscovererContainerInfoClass"> | |
<type name="Gst.MiniObjectClass" c:type="GstMiniObjectClass"/> | |
</alias> | |
<alias name="DiscovererInfoClass" c:type="GstDiscovererInfoClass"> | |
<type name="Gst.MiniObjectClass" c:type="GstMiniObjectClass"/> | |
</alias> | |
<alias name="DiscovererStreamInfoClass" | |
c:type="GstDiscovererStreamInfoClass"> | |
<type name="Gst.MiniObjectClass" c:type="GstMiniObjectClass"/> | |
</alias> | |
<alias name="DiscovererVideoInfoClass" | |
c:type="GstDiscovererVideoInfoClass"> | |
<type name="Gst.MiniObjectClass" c:type="GstMiniObjectClass"/> | |
</alias> | |
<alias name="EncodingAudioProfileClass" | |
c:type="GstEncodingAudioProfileClass"> | |
<type name="EncodingProfileClass" c:type="GstEncodingProfileClass"/> | |
</alias> | |
<alias name="EncodingContainerProfileClass" | |
c:type="GstEncodingContainerProfileClass"> | |
<type name="EncodingProfileClass" c:type="GstEncodingProfileClass"/> | |
</alias> | |
<alias name="EncodingProfileClass" c:type="GstEncodingProfileClass"> | |
<type name="Gst.MiniObjectClass" c:type="GstMiniObjectClass"/> | |
</alias> | |
<alias name="EncodingTargetClass" c:type="GstEncodingTargetClass"> | |
<type name="Gst.MiniObjectClass" c:type="GstMiniObjectClass"/> | |
</alias> | |
<alias name="EncodingVideoProfileClass" | |
c:type="GstEncodingVideoProfileClass"> | |
<type name="EncodingProfileClass" c:type="GstEncodingProfileClass"/> | |
</alias> | |
<class name="Discoverer" | |
c:symbol-prefix="discoverer" | |
c:type="GstDiscoverer" | |
version="0.10.31" | |
parent="GObject.Object" | |
glib:type-name="GstDiscoverer" | |
glib:get-type="gst_discoverer_get_type" | |
glib:type-struct="DiscovererClass"> | |
<doc xml:whitespace="preserve">The #GstDiscoverer structure.</doc> | |
<constructor name="new" | |
c:identifier="gst_discoverer_new" | |
version="0.10.31" | |
throws="1"> | |
<doc xml:whitespace="preserve">Creates a new #GstDiscoverer with the provided timeout. | |
If an error occurred when creating the discoverer, @err will be set | |
accordingly and %NULL will be returned. If @err is set, the caller must | |
free it when no longer needed using g_error_free().</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">The new #GstDiscoverer.</doc> | |
<type name="Discoverer" c:type="GstDiscoverer*"/> | |
</return-value> | |
<parameters> | |
<parameter name="timeout" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">timeout per file, in nanoseconds. Allowed are values between one second (#GST_SECOND) and one hour (3600 * #GST_SECOND)</doc> | |
<type name="Gst.ClockTime" c:type="GstClockTime"/> | |
</parameter> | |
</parameters> | |
</constructor> | |
<method name="discover_uri" | |
c:identifier="gst_discoverer_discover_uri" | |
version="0.10.31" | |
throws="1"> | |
<doc xml:whitespace="preserve">Synchronously discovers the given @uri. | |
A copy of @uri will be made internally, so the caller can safely g_free() | |
afterwards. | |
error occurred.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">the result of the scanning. Can be %NULL if an</doc> | |
<type name="DiscovererInfo" c:type="GstDiscovererInfo*"/> | |
</return-value> | |
<parameters> | |
<parameter name="uri" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">The URI to run on.</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
</parameters> | |
</method> | |
<method name="discover_uri_async" | |
c:identifier="gst_discoverer_discover_uri_async" | |
version="0.10.31"> | |
<doc xml:whitespace="preserve">Appends the given @uri to the list of URIs to discoverer. The actual | |
discovery of the @uri will only take place if gst_discoverer_start() has | |
been called. | |
A copy of @uri will be made internally, so the caller can safely g_free() | |
afterwards. | |
uris, else %FALSE</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">%TRUE if the @uri was succesfully appended to the list of pending</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</return-value> | |
<parameters> | |
<parameter name="uri" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the URI to add.</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
</parameters> | |
</method> | |
<method name="start" | |
c:identifier="gst_discoverer_start" | |
version="0.10.31"> | |
<doc xml:whitespace="preserve">Allow asynchronous discovering of URIs to take place. | |
A #GMainLoop must be available for #GstDiscoverer to properly work in | |
asynchronous mode.</doc> | |
<return-value transfer-ownership="none"> | |
<type name="none" c:type="void"/> | |
</return-value> | |
</method> | |
<method name="stop" c:identifier="gst_discoverer_stop" version="0.10.31"> | |
<doc xml:whitespace="preserve">Stop the discovery of any pending URIs and clears the list of | |
pending URIS (if any).</doc> | |
<return-value transfer-ownership="none"> | |
<type name="none" c:type="void"/> | |
</return-value> | |
</method> | |
<property name="timeout" | |
writable="1" | |
construct="1" | |
transfer-ownership="none"> | |
<type name="guint64"/> | |
</property> | |
<field name="parent"> | |
<type name="GObject.Object" c:type="GObject"/> | |
</field> | |
<field name="priv"> | |
<type name="DiscovererPrivate" c:type="GstDiscovererPrivate*"/> | |
</field> | |
<field name="_reserved"> | |
<array zero-terminated="0" c:type="gpointer" fixed-size="4"> | |
<type name="gpointer" c:type="gpointer"/> | |
</array> | |
</field> | |
<glib:signal name="discovered"> | |
<doc xml:whitespace="preserve">Will be emitted when all information on a URI could be discovered.</doc> | |
<return-value transfer-ownership="none"> | |
<type name="none"/> | |
</return-value> | |
<parameters> | |
<parameter name="object" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the results #GstDiscovererInfo</doc> | |
<type name="DiscovererInfo"/> | |
</parameter> | |
<parameter name="p0" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">#GError, which will be non-NULL if an error occurred during discovery</doc> | |
<type name="GLib.Error"/> | |
</parameter> | |
</parameters> | |
</glib:signal> | |
<glib:signal name="finished"> | |
<doc xml:whitespace="preserve">Will be emitted when all pending URIs have been processed.</doc> | |
<return-value transfer-ownership="none"> | |
<type name="none"/> | |
</return-value> | |
</glib:signal> | |
<glib:signal name="starting"> | |
<doc xml:whitespace="preserve">Will be emitted when the discover starts analyzing the pending URIs</doc> | |
<return-value transfer-ownership="none"> | |
<type name="none"/> | |
</return-value> | |
</glib:signal> | |
</class> | |
<class name="DiscovererAudioInfo" | |
c:symbol-prefix="discoverer_audio_info" | |
c:type="GstDiscovererAudioInfo" | |
version="0.10.31" | |
parent="DiscovererStreamInfo" | |
glib:type-name="GstDiscovererAudioInfo" | |
glib:get-type="gst_discoverer_audio_info_get_type" | |
glib:fundamental="1"> | |
<doc xml:whitespace="preserve">#GstDiscovererStreamInfo specific to audio streams.</doc> | |
<method name="get_bitrate" | |
c:identifier="gst_discoverer_audio_info_get_bitrate" | |
version="0.10.31"> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the average or nominal bitrate of the stream in bits/second.</doc> | |
<type name="guint" c:type="guint"/> | |
</return-value> | |
</method> | |
<method name="get_channels" | |
c:identifier="gst_discoverer_audio_info_get_channels" | |
version="0.10.31"> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the number of channels in the stream.</doc> | |
<type name="guint" c:type="guint"/> | |
</return-value> | |
</method> | |
<method name="get_depth" | |
c:identifier="gst_discoverer_audio_info_get_depth" | |
version="0.10.31"> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the number of bits used per sample in each channel.</doc> | |
<type name="guint" c:type="guint"/> | |
</return-value> | |
</method> | |
<method name="get_max_bitrate" | |
c:identifier="gst_discoverer_audio_info_get_max_bitrate" | |
version="0.10.31"> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the maximum bitrate of the stream in bits/second.</doc> | |
<type name="guint" c:type="guint"/> | |
</return-value> | |
</method> | |
<method name="get_sample_rate" | |
c:identifier="gst_discoverer_audio_info_get_sample_rate" | |
version="0.10.31"> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the sample rate of the stream in Hertz.</doc> | |
<type name="guint" c:type="guint"/> | |
</return-value> | |
</method> | |
</class> | |
<record name="DiscovererClass" | |
c:type="GstDiscovererClass" | |
glib:is-gtype-struct-for="Discoverer"> | |
<field name="parentclass"> | |
<type name="GObject.ObjectClass" c:type="GObjectClass"/> | |
</field> | |
<field name="finished"> | |
<callback name="finished"> | |
<return-value transfer-ownership="none"> | |
<type name="none" c:type="void"/> | |
</return-value> | |
<parameters> | |
<parameter name="discoverer" transfer-ownership="none"> | |
<type name="Discoverer" c:type="GstDiscoverer*"/> | |
</parameter> | |
</parameters> | |
</callback> | |
</field> | |
<field name="starting"> | |
<callback name="starting"> | |
<return-value transfer-ownership="none"> | |
<type name="none" c:type="void"/> | |
</return-value> | |
<parameters> | |
<parameter name="discoverer" transfer-ownership="none"> | |
<type name="Discoverer" c:type="GstDiscoverer*"/> | |
</parameter> | |
</parameters> | |
</callback> | |
</field> | |
<field name="discovered"> | |
<callback name="discovered"> | |
<return-value transfer-ownership="none"> | |
<type name="none" c:type="void"/> | |
</return-value> | |
<parameters> | |
<parameter name="discoverer" transfer-ownership="none"> | |
<type name="Discoverer" c:type="GstDiscoverer*"/> | |
</parameter> | |
<parameter name="info" transfer-ownership="none"> | |
<type name="DiscovererInfo" c:type="GstDiscovererInfo*"/> | |
</parameter> | |
<parameter name="err" transfer-ownership="none"> | |
<type name="GLib.Error" c:type="GError*"/> | |
</parameter> | |
</parameters> | |
</callback> | |
</field> | |
<field name="_reserved"> | |
<array zero-terminated="0" c:type="gpointer" fixed-size="4"> | |
<type name="gpointer" c:type="gpointer"/> | |
</array> | |
</field> | |
</record> | |
<class name="DiscovererContainerInfo" | |
c:symbol-prefix="discoverer_container_info" | |
c:type="GstDiscovererContainerInfo" | |
version="0.10.31" | |
parent="DiscovererStreamInfo" | |
glib:type-name="GstDiscovererContainerInfo" | |
glib:get-type="gst_discoverer_container_info_get_type" | |
glib:fundamental="1"> | |
<doc xml:whitespace="preserve">#GstDiscovererStreamInfo specific to container streams.</doc> | |
<method name="get_streams" | |
c:identifier="gst_discoverer_container_info_get_streams" | |
version="0.10.31" | |
introspectable="0"> | |
<doc xml:whitespace="preserve">#GstDiscovererStreamInfo this container stream offers. | |
Free with gst_discoverer_stream_info_list_free() after usage.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">the list of</doc> | |
<type name="GLib.List" c:type="GList*"> | |
<type name="Gst.DiscovererStreamInfo"/> | |
</type> | |
</return-value> | |
</method> | |
</class> | |
<class name="DiscovererInfo" | |
c:symbol-prefix="discoverer_info" | |
c:type="GstDiscovererInfo" | |
version="0.10.31" | |
parent="Gst.MiniObject" | |
glib:type-name="GstDiscovererInfo" | |
glib:get-type="gst_discoverer_info_get_type" | |
glib:fundamental="1"> | |
<doc xml:whitespace="preserve">Structure containing the information of a URI analyzed by #GstDiscoverer.</doc> | |
<method name="copy" | |
c:identifier="gst_discoverer_info_copy" | |
introspectable="0"> | |
<return-value> | |
<type name="DiscovererInfo" c:type="GstDiscovererInfo*"/> | |
</return-value> | |
</method> | |
<method name="get_audio_streams" | |
c:identifier="gst_discoverer_info_get_audio_streams" | |
version="0.10.31" | |
introspectable="0"> | |
<doc xml:whitespace="preserve">Finds all the #GstDiscovererAudioInfo contained in @info | |
matching #GstDiscovererStreamInfo. The caller should free it with | |
gst_discoverer_stream_info_list_free().</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">A #GList of</doc> | |
<type name="GLib.List" c:type="GList*"> | |
<type name="Gst.DiscovererStreamInfo"/> | |
</type> | |
</return-value> | |
</method> | |
<method name="get_container_streams" | |
c:identifier="gst_discoverer_info_get_container_streams" | |
version="0.10.31" | |
introspectable="0"> | |
<doc xml:whitespace="preserve">Finds all the #GstDiscovererContainerInfo contained in @info | |
matching #GstDiscovererStreamInfo. The caller should free it with | |
gst_discoverer_stream_info_list_free().</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">A #GList of</doc> | |
<type name="GLib.List" c:type="GList*"> | |
<type name="Gst.DiscovererStreamInfo"/> | |
</type> | |
</return-value> | |
</method> | |
<method name="get_duration" | |
c:identifier="gst_discoverer_info_get_duration" | |
version="0.10.31"> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the duration of the URI in #GstClockTime (nanoseconds).</doc> | |
<type name="Gst.ClockTime" c:type="GstClockTime"/> | |
</return-value> | |
</method> | |
<method name="get_misc" | |
c:identifier="gst_discoverer_info_get_misc" | |
version="0.10.31"> | |
<doc xml:whitespace="preserve">(for example: information about missing plugins). If you wish to use the | |
#GstStructure after the life-time of @info, you will need to copy it.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">Miscellaneous information stored as a #GstStructure</doc> | |
<type name="Gst.Structure" c:type="GstStructure*"/> | |
</return-value> | |
</method> | |
<method name="get_result" | |
c:identifier="gst_discoverer_info_get_result" | |
version="0.10.31"> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the result of the discovery as a #GstDiscovererResult.</doc> | |
<type name="DiscovererResult" c:type="GstDiscovererResult"/> | |
</return-value> | |
</method> | |
<method name="get_seekable" | |
c:identifier="gst_discoverer_info_get_seekable" | |
version="0.10.32"> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the wheter the URI is seekable.</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</return-value> | |
</method> | |
<method name="get_stream_info" | |
c:identifier="gst_discoverer_info_get_stream_info" | |
version="0.10.31"> | |
<doc xml:whitespace="preserve">#GstDiscovererStreamInfo. | |
This structure can be traversed to see the original hierarchy. Unref with | |
gst_discoverer_stream_info_unref() after usage.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">the structure (or topology) of the URI as a</doc> | |
<type name="DiscovererStreamInfo" c:type="GstDiscovererStreamInfo*"/> | |
</return-value> | |
</method> | |
<method name="get_stream_list" | |
c:identifier="gst_discoverer_info_get_stream_list" | |
version="0.10.31" | |
introspectable="0"> | |
<doc xml:whitespace="preserve">all streams contained in the #info. Free after usage | |
with gst_discoverer_stream_info_list_free().</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">the list of</doc> | |
<type name="GLib.List" c:type="GList*"> | |
<type name="Gst.DiscovererStreamInfo"/> | |
</type> | |
</return-value> | |
</method> | |
<method name="get_streams" | |
c:identifier="gst_discoverer_info_get_streams" | |
version="0.10.31" | |
introspectable="0"> | |
<doc xml:whitespace="preserve">Finds the #GstDiscovererStreamInfo contained in @info that match the | |
given @streamtype. | |
matching #GstDiscovererStreamInfo. The caller should free it with | |
gst_discoverer_stream_info_list_free().</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">A #GList of</doc> | |
<type name="GLib.List" c:type="GList*"> | |
<type name="Gst.DiscovererStreamInfo"/> | |
</type> | |
</return-value> | |
<parameters> | |
<parameter name="streamtype" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a #GType derived from #GstDiscovererStreamInfo</doc> | |
<type name="GType" c:type="GType"/> | |
</parameter> | |
</parameters> | |
</method> | |
<method name="get_tags" | |
c:identifier="gst_discoverer_info_get_tags" | |
version="0.10.31"> | |
<doc xml:whitespace="preserve">the tags after the life-time of @info, you will need to copy them.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">all tags contained in the %URI. If you wish to use</doc> | |
<type name="Gst.TagList" c:type="GstTagList*"/> | |
</return-value> | |
</method> | |
<method name="get_uri" | |
c:identifier="gst_discoverer_info_get_uri" | |
version="0.10.31"> | |
<doc xml:whitespace="preserve">Copy it if you wish to use it after the life-time of @info.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the URI to which this information corresponds to.</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</return-value> | |
</method> | |
<method name="get_video_streams" | |
c:identifier="gst_discoverer_info_get_video_streams" | |
version="0.10.31" | |
introspectable="0"> | |
<doc xml:whitespace="preserve">Finds all the #GstDiscovererVideoInfo contained in @info | |
matching #GstDiscovererStreamInfo. The caller should free it with | |
gst_discoverer_stream_info_list_free().</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">A #GList of</doc> | |
<type name="GLib.List" c:type="GList*"> | |
<type name="Gst.DiscovererStreamInfo"/> | |
</type> | |
</return-value> | |
</method> | |
</class> | |
<record name="DiscovererPrivate" | |
c:type="GstDiscovererPrivate" | |
disguised="1"> | |
</record> | |
<enumeration name="DiscovererResult" | |
version="0.10.31" | |
glib:type-name="GstDiscovererResult" | |
glib:get-type="gst_discoverer_result_get_type" | |
c:type="GstDiscovererResult"> | |
<doc xml:whitespace="preserve">Result values for the discovery process.</doc> | |
<member name="ok" | |
value="0" | |
c:identifier="GST_DISCOVERER_OK" | |
glib:nick="ok"/> | |
<member name="uri_invalid" | |
value="1" | |
c:identifier="GST_DISCOVERER_URI_INVALID" | |
glib:nick="uri-invalid"/> | |
<member name="error" | |
value="2" | |
c:identifier="GST_DISCOVERER_ERROR" | |
glib:nick="error"/> | |
<member name="timeout" | |
value="3" | |
c:identifier="GST_DISCOVERER_TIMEOUT" | |
glib:nick="timeout"/> | |
<member name="busy" | |
value="4" | |
c:identifier="GST_DISCOVERER_BUSY" | |
glib:nick="busy"/> | |
<member name="missing_plugins" | |
value="5" | |
c:identifier="GST_DISCOVERER_MISSING_PLUGINS" | |
glib:nick="missing-plugins"/> | |
</enumeration> | |
<class name="DiscovererStreamInfo" | |
c:symbol-prefix="discoverer_stream_info" | |
c:type="GstDiscovererStreamInfo" | |
version="0.10.31" | |
parent="Gst.MiniObject" | |
glib:type-name="GstDiscovererStreamInfo" | |
glib:get-type="gst_discoverer_stream_info_get_type" | |
glib:fundamental="1"> | |
<doc xml:whitespace="preserve">Base structure for information concerning a media stream. Depending on the | |
stream type, one can find more media-specific information in | |
#GstDiscovererAudioInfo, #GstDiscovererVideoInfo, and | |
#GstDiscovererContainerInfo. | |
The #GstDiscovererStreamInfo represents the topology of the stream. Siblings | |
can be iterated over with gst_discoverer_stream_info_get_next() and | |
gst_discoverer_stream_info_get_previous(). Children (sub-streams) of a | |
stream can be accessed using the #GstDiscovererContainerInfo API. | |
As a simple example, if you run #GstDiscoverer on an AVI file with one audio | |
and one video stream, you will get a #GstDiscovererContainerInfo | |
corresponding to the AVI container, which in turn will have a | |
#GstDiscovererAudioInfo sub-stream and a #GstDiscovererVideoInfo sub-stream | |
for the audio and video streams respectively.</doc> | |
<function name="list_free" | |
c:identifier="gst_discoverer_stream_info_list_free"> | |
<doc xml:whitespace="preserve">Decrements the reference count of all contained #GstDiscovererStreamInfo | |
and fress the #GList.</doc> | |
<return-value transfer-ownership="none"> | |
<type name="none" c:type="void"/> | |
</return-value> | |
<parameters> | |
<parameter name="infos" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a #GList of #GstDiscovererStreamInfo</doc> | |
<type name="GLib.List" c:type="GList*"> | |
<type name="gpointer" c:type="gpointer"/> | |
</type> | |
</parameter> | |
</parameters> | |
</function> | |
<method name="get_caps" | |
c:identifier="gst_discoverer_stream_info_get_caps" | |
version="0.10.31"> | |
<doc xml:whitespace="preserve">#gst_caps_unref after usage.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">the #GstCaps of the stream. Unref with</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</return-value> | |
</method> | |
<method name="get_misc" | |
c:identifier="gst_discoverer_stream_info_get_misc" | |
version="0.10.31"> | |
<doc xml:whitespace="preserve">example codec version, profile, etc..). If you wish to use the #GstStructure | |
after the life-time of @info you will need to copy it.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">additional information regarding the stream (for</doc> | |
<type name="Gst.Structure" c:type="GstStructure*"/> | |
</return-value> | |
</method> | |
<method name="get_next" | |
c:identifier="gst_discoverer_stream_info_get_next" | |
version="0.10.31"> | |
<doc xml:whitespace="preserve">for final streams. | |
Unref with #gst_discoverer_stream_info_unref after usage.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">the next #GstDiscovererStreamInfo in a chain. %NULL</doc> | |
<type name="DiscovererStreamInfo" c:type="GstDiscovererStreamInfo*"/> | |
</return-value> | |
</method> | |
<method name="get_previous" | |
c:identifier="gst_discoverer_stream_info_get_previous" | |
version="0.10.31"> | |
<doc xml:whitespace="preserve">%NULL for starting points. Unref with #gst_discoverer_stream_info_unref | |
after usage.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">the previous #GstDiscovererStreamInfo in a chain.</doc> | |
<type name="DiscovererStreamInfo" c:type="GstDiscovererStreamInfo*"/> | |
</return-value> | |
</method> | |
<method name="get_stream_type_nick" | |
c:identifier="gst_discoverer_stream_info_get_stream_type_nick" | |
version="0.10.31"> | |
<doc xml:whitespace="preserve">"container",...).</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a human readable name for the stream type of the given @info (ex : "audio",</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</return-value> | |
</method> | |
<method name="get_tags" | |
c:identifier="gst_discoverer_stream_info_get_tags" | |
version="0.10.31"> | |
<doc xml:whitespace="preserve">use the tags after the life-time of @info you will need to copy them.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the tags contained in this stream. If you wish to</doc> | |
<type name="Gst.TagList" c:type="GstTagList*"/> | |
</return-value> | |
</method> | |
</class> | |
<class name="DiscovererVideoInfo" | |
c:symbol-prefix="discoverer_video_info" | |
c:type="GstDiscovererVideoInfo" | |
version="0.10.31" | |
parent="DiscovererStreamInfo" | |
glib:type-name="GstDiscovererVideoInfo" | |
glib:get-type="gst_discoverer_video_info_get_type" | |
glib:fundamental="1"> | |
<doc xml:whitespace="preserve">#GstDiscovererStreamInfo specific to video streams (this includes images).</doc> | |
<method name="get_bitrate" | |
c:identifier="gst_discoverer_video_info_get_bitrate" | |
version="0.10.31"> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the average or nominal bitrate of the video stream in bits/second.</doc> | |
<type name="guint" c:type="guint"/> | |
</return-value> | |
</method> | |
<method name="get_depth" | |
c:identifier="gst_discoverer_video_info_get_depth" | |
version="0.10.31"> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the depth in bits of the video stream.</doc> | |
<type name="guint" c:type="guint"/> | |
</return-value> | |
</method> | |
<method name="get_framerate_denom" | |
c:identifier="gst_discoverer_video_info_get_framerate_denom" | |
version="0.10.31"> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the framerate of the video stream (denominator).</doc> | |
<type name="guint" c:type="guint"/> | |
</return-value> | |
</method> | |
<method name="get_framerate_num" | |
c:identifier="gst_discoverer_video_info_get_framerate_num" | |
version="0.10.31"> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the framerate of the video stream (numerator).</doc> | |
<type name="guint" c:type="guint"/> | |
</return-value> | |
</method> | |
<method name="get_height" | |
c:identifier="gst_discoverer_video_info_get_height" | |
version="0.10.31"> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the height of the video stream in pixels.</doc> | |
<type name="guint" c:type="guint"/> | |
</return-value> | |
</method> | |
<method name="get_max_bitrate" | |
c:identifier="gst_discoverer_video_info_get_max_bitrate" | |
version="0.10.31"> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the maximum bitrate of the video stream in bits/second.</doc> | |
<type name="guint" c:type="guint"/> | |
</return-value> | |
</method> | |
<method name="get_par_denom" | |
c:identifier="gst_discoverer_video_info_get_par_denom" | |
version="0.10.31"> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the Pixel Aspect Ratio (PAR) of the video stream (denominator).</doc> | |
<type name="guint" c:type="guint"/> | |
</return-value> | |
</method> | |
<method name="get_par_num" | |
c:identifier="gst_discoverer_video_info_get_par_num" | |
version="0.10.31"> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the Pixel Aspect Ratio (PAR) of the video stream (numerator).</doc> | |
<type name="guint" c:type="guint"/> | |
</return-value> | |
</method> | |
<method name="get_width" | |
c:identifier="gst_discoverer_video_info_get_width" | |
version="0.10.31"> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the width of the video stream in pixels.</doc> | |
<type name="guint" c:type="guint"/> | |
</return-value> | |
</method> | |
<method name="is_image" | |
c:identifier="gst_discoverer_video_info_is_image" | |
version="0.10.31"> | |
<doc xml:whitespace="preserve">one frame).</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">#TRUE if the video stream corresponds to an image (i.e. only contains</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</return-value> | |
</method> | |
<method name="is_interlaced" | |
c:identifier="gst_discoverer_video_info_is_interlaced" | |
version="0.10.31"> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">%TRUE if the stream is interlaced, else %FALSE.</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</return-value> | |
</method> | |
</class> | |
<constant name="ENCODING_CATEGORY_CAPTURE" value="capture"> | |
<type name="utf8" c:type="gchar*"/> | |
</constant> | |
<constant name="ENCODING_CATEGORY_DEVICE" value="device"> | |
<type name="utf8" c:type="gchar*"/> | |
</constant> | |
<constant name="ENCODING_CATEGORY_ONLINE_SERVICE" value="online-service"> | |
<type name="utf8" c:type="gchar*"/> | |
</constant> | |
<constant name="ENCODING_CATEGORY_STORAGE_EDITING" value="storage-editing"> | |
<type name="utf8" c:type="gchar*"/> | |
</constant> | |
<class name="EncodingAudioProfile" | |
c:symbol-prefix="encoding_audio_profile" | |
c:type="GstEncodingAudioProfile" | |
version="0.10.32" | |
parent="EncodingProfile" | |
glib:type-name="GstEncodingAudioProfile" | |
glib:get-type="gst_encoding_audio_profile_get_type" | |
glib:fundamental="1"> | |
<doc xml:whitespace="preserve">Variant of #GstEncodingProfile for audio streams.</doc> | |
<constructor name="new" | |
c:identifier="gst_encoding_audio_profile_new" | |
version="0.10.32"> | |
<doc xml:whitespace="preserve">Creates a new #GstEncodingAudioProfile | |
All provided allocatable arguments will be internally copied, so can be | |
safely freed/unreferenced after calling this method.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">the newly created #GstEncodingAudioProfile.</doc> | |
<type name="EncodingAudioProfile" c:type="GstEncodingAudioProfile*"/> | |
</return-value> | |
<parameters> | |
<parameter name="format" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the #GstCaps</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</parameter> | |
<parameter name="preset" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the preset(s) to use on the encoder, can be #NULL</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
<parameter name="restriction" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the #GstCaps used to restrict the input to the encoder, can be NULL. See gst_encoding_profile_get_restriction() for more details.</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</parameter> | |
<parameter name="presence" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the number of time this stream must be used. 0 means any number of times (including never)</doc> | |
<type name="guint" c:type="guint"/> | |
</parameter> | |
</parameters> | |
</constructor> | |
</class> | |
<class name="EncodingContainerProfile" | |
c:symbol-prefix="encoding_container_profile" | |
c:type="GstEncodingContainerProfile" | |
version="0.10.32" | |
parent="EncodingProfile" | |
glib:type-name="GstEncodingContainerProfile" | |
glib:get-type="gst_encoding_container_profile_get_type" | |
glib:fundamental="1"> | |
<doc xml:whitespace="preserve">Encoding profiles for containers. Keeps track of a list of #GstEncodingProfile</doc> | |
<constructor name="new" | |
c:identifier="gst_encoding_container_profile_new" | |
version="0.10.32"> | |
<doc xml:whitespace="preserve">Creates a new #GstEncodingContainerProfile.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">The newly created #GstEncodingContainerProfile.</doc> | |
<type name="EncodingContainerProfile" | |
c:type="GstEncodingContainerProfile*"/> | |
</return-value> | |
<parameters> | |
<parameter name="name" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">The name of the container profile, can be %NULL</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
<parameter name="description" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">The description of the container profile, can be %NULL</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
<parameter name="format" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">The format to use for this profile</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</parameter> | |
<parameter name="preset" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">The preset to use for this profile</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
</parameters> | |
</constructor> | |
<method name="add_profile" | |
c:identifier="gst_encoding_container_profile_add_profile" | |
version="0.10.32"> | |
<doc xml:whitespace="preserve">Add a #GstEncodingProfile to the list of profiles handled by @container. | |
No copy of @profile will be made, if you wish to use it elsewhere after this | |
method you should increment its reference count.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">%TRUE if the @stream was properly added, else %FALSE.</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</return-value> | |
<parameters> | |
<parameter name="profile" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the #GstEncodingProfile to add.</doc> | |
<type name="EncodingProfile" c:type="GstEncodingProfile*"/> | |
</parameter> | |
</parameters> | |
</method> | |
<method name="contains_profile" | |
c:identifier="gst_encoding_container_profile_contains_profile" | |
version="0.10.32"> | |
<doc xml:whitespace="preserve">Checks if @container contains a #GstEncodingProfile identical to | |
to @profile, else %FALSE.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">%TRUE if @container contains a #GstEncodingProfile identical</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</return-value> | |
<parameters> | |
<parameter name="profile" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a #GstEncodingProfile</doc> | |
<type name="EncodingProfile" c:type="GstEncodingProfile*"/> | |
</parameter> | |
</parameters> | |
</method> | |
<method name="get_profiles" | |
c:identifier="gst_encoding_container_profile_get_profiles"> | |
<return-value transfer-ownership="none"> | |
<type name="GLib.List" c:type="GList*"> | |
<type name="gpointer" c:type="gpointer"/> | |
</type> | |
</return-value> | |
</method> | |
</class> | |
<class name="EncodingProfile" | |
c:symbol-prefix="encoding_profile" | |
c:type="GstEncodingProfile" | |
version="0.10.32" | |
parent="Gst.MiniObject" | |
glib:type-name="GstEncodingProfile" | |
glib:get-type="gst_encoding_profile_get_type" | |
glib:fundamental="1"> | |
<doc xml:whitespace="preserve">The opaque base class object for all encoding profiles. This contains generic | |
information like name, description, format and preset.</doc> | |
<function name="find" | |
c:identifier="gst_encoding_profile_find" | |
version="0.10.32"> | |
<doc xml:whitespace="preserve">Find the #GstEncodingProfile with the specified name and category.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">The matching #GstEncodingProfile or %NULL.</doc> | |
<type name="EncodingProfile" c:type="GstEncodingProfile*"/> | |
</return-value> | |
<parameters> | |
<parameter name="targetname" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">The name of the target</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
<parameter name="profilename" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">The name of the profile</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
<parameter name="category" transfer-ownership="none" allow-none="1"> | |
<doc xml:whitespace="preserve">The target category. Can be %NULL</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<method name="get_description" | |
c:identifier="gst_encoding_profile_get_description" | |
version="0.10.32"> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the description of the profile, can be %NULL.</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</return-value> | |
</method> | |
<method name="get_format" | |
c:identifier="gst_encoding_profile_get_format" | |
version="0.10.32"> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the #GstCaps corresponding to the media format used in the profile.</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</return-value> | |
</method> | |
<method name="get_input_caps" | |
c:identifier="gst_encoding_profile_get_input_caps" | |
version="0.10.32"> | |
<doc xml:whitespace="preserve">Computes the full output caps that this @profile will be able to consume. | |
when you are done with the caps.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">The full caps the given @profile can consume. Call gst_caps_unref()</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</return-value> | |
</method> | |
<method name="get_name" | |
c:identifier="gst_encoding_profile_get_name" | |
version="0.10.32"> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the name of the profile, can be %NULL.</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</return-value> | |
</method> | |
<method name="get_presence" | |
c:identifier="gst_encoding_profile_get_presence" | |
version="0.10.32"> | |
<doc xml:whitespace="preserve">container profile. If 0, it is not a mandatory stream.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">The number of times the profile is used in its parent</doc> | |
<type name="guint" c:type="guint"/> | |
</return-value> | |
</method> | |
<method name="get_preset" | |
c:identifier="gst_encoding_profile_get_preset" | |
version="0.10.32"> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the name of the #GstPreset to be used in the profile.</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</return-value> | |
</method> | |
<method name="get_restriction" | |
c:identifier="gst_encoding_profile_get_restriction" | |
version="0.10.32"> | |
<doc xml:whitespace="preserve">that will be used in the profile. The fields present in restriction caps are | |
properties of the raw stream (that is before encoding), such as height and | |
width for video and depth and sampling rate for audio. Does not apply to | |
#GstEncodingContainerProfile (since there is no corresponding raw stream). | |
Can be %NULL.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">The restriction #GstCaps to apply before the encoder</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</return-value> | |
</method> | |
<method name="get_type_nick" | |
c:identifier="gst_encoding_profile_get_type_nick" | |
version="0.10.32"> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the human-readable name of the type of @profile.</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</return-value> | |
</method> | |
<method name="is_equal" | |
c:identifier="gst_encoding_profile_is_equal" | |
version="0.10.32"> | |
<doc xml:whitespace="preserve">Checks whether the two #GstEncodingProfile are equal</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">%TRUE if @a and @b are equal, else %FALSE.</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</return-value> | |
<parameters> | |
<parameter name="b" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a #GstEncodingProfile</doc> | |
<type name="EncodingProfile" c:type="GstEncodingProfile*"/> | |
</parameter> | |
</parameters> | |
</method> | |
<method name="set_description" | |
c:identifier="gst_encoding_profile_set_description" | |
version="0.10.32"> | |
<doc xml:whitespace="preserve">Set @description as the given description for the @profile. A copy of @description will be made | |
internally.</doc> | |
<return-value transfer-ownership="none"> | |
<type name="none" c:type="void"/> | |
</return-value> | |
<parameters> | |
<parameter name="description" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the description to set on the profile</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
</parameters> | |
</method> | |
<method name="set_format" | |
c:identifier="gst_encoding_profile_set_format" | |
version="0.10.32"> | |
<doc xml:whitespace="preserve">Sets the media format used in the profile.</doc> | |
<return-value transfer-ownership="none"> | |
<type name="none" c:type="void"/> | |
</return-value> | |
<parameters> | |
<parameter name="format" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the media format to use in the profile.</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</parameter> | |
</parameters> | |
</method> | |
<method name="set_name" | |
c:identifier="gst_encoding_profile_set_name" | |
version="0.10.32"> | |
<doc xml:whitespace="preserve">Set @name as the given name for the @profile. A copy of @name will be made | |
internally.</doc> | |
<return-value transfer-ownership="none"> | |
<type name="none" c:type="void"/> | |
</return-value> | |
<parameters> | |
<parameter name="name" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the name to set on the profile</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
</parameters> | |
</method> | |
<method name="set_presence" | |
c:identifier="gst_encoding_profile_set_presence" | |
version="0.10.32"> | |
<doc xml:whitespace="preserve">Set the number of time the profile is used in its parent | |
container profile. If 0, it is not a mandatory stream</doc> | |
<return-value transfer-ownership="none"> | |
<type name="none" c:type="void"/> | |
</return-value> | |
<parameters> | |
<parameter name="presence" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the number of time the profile can be used</doc> | |
<type name="guint" c:type="guint"/> | |
</parameter> | |
</parameters> | |
</method> | |
<method name="set_preset" | |
c:identifier="gst_encoding_profile_set_preset" | |
version="0.10.32"> | |
<doc xml:whitespace="preserve">Sets the preset to use for the profile.</doc> | |
<return-value transfer-ownership="none"> | |
<type name="none" c:type="void"/> | |
</return-value> | |
<parameters> | |
<parameter name="preset" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the element preset to use</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
</parameters> | |
</method> | |
<method name="set_restriction" | |
c:identifier="gst_encoding_profile_set_restriction" | |
version="0.10.32"> | |
<doc xml:whitespace="preserve">Set the restriction #GstCaps to apply before the encoder | |
that will be used in the profile. See gst_encoding_profile_set_restriction() | |
for more about restrictions. Does not apply to #GstEncodingContainerProfile.</doc> | |
<return-value transfer-ownership="none"> | |
<type name="none" c:type="void"/> | |
</return-value> | |
<parameters> | |
<parameter name="restriction" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the restriction to apply</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</parameter> | |
</parameters> | |
</method> | |
</class> | |
<class name="EncodingTarget" | |
c:symbol-prefix="encoding_target" | |
c:type="GstEncodingTarget" | |
version="0.10.32" | |
parent="Gst.MiniObject" | |
glib:type-name="GstEncodingTarget" | |
glib:get-type="gst_encoding_target_get_type" | |
glib:fundamental="1"> | |
<doc xml:whitespace="preserve">Collection of #GstEncodingProfile for a specific target or use-case. | |
When being stored/loaded, targets come from a specific category, like | |
#GST_ENCODING_CATEGORY_DEVICE.</doc> | |
<constructor name="new" | |
c:identifier="gst_encoding_target_new" | |
version="0.10.32" | |
introspectable="0"> | |
<doc xml:whitespace="preserve">Creates a new #GstEncodingTarget. | |
The name and category can only consist of lowercase ASCII letters for the | |
first character, followed by either lowercase ASCII letters, digits or | |
hyphens ('-'). | |
The @category <emphasis>should</emphasis> be one of the existing | |
well-defined categories, like #GST_ENCODING_CATEGORY_DEVICE, but it | |
<emphasis>can</emphasis> be a application or user specific category if | |
needed. | |
there was an error.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">The newly created #GstEncodingTarget or %NULL if</doc> | |
<type name="EncodingTarget" c:type="GstEncodingTarget*"/> | |
</return-value> | |
<parameters> | |
<parameter name="name" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">The name of the target.</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
<parameter name="category" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">The name of the category to which this @target belongs. For example: #GST_ENCODING_CATEGORY_DEVICE.</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
<parameter name="description" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">A description of #GstEncodingTarget in the current locale.</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
<parameter name="profiles" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">A #GList of #GstEncodingProfile.</doc> | |
<type name="GLib.List" c:type="GList*"> | |
<type name="Gst.EncodingProfile"/> | |
</type> | |
</parameter> | |
</parameters> | |
</constructor> | |
<function name="load" | |
c:identifier="gst_encoding_target_load" | |
version="0.10.32" | |
throws="1"> | |
<doc xml:whitespace="preserve">Searches for the #GstEncodingTarget with the given name, loads it | |
and returns it. | |
If the category name is specified only targets from that category will be | |
searched for.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">The #GstEncodingTarget if available, else %NULL.</doc> | |
<type name="EncodingTarget" c:type="GstEncodingTarget*"/> | |
</return-value> | |
<parameters> | |
<parameter name="name" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the name of the #GstEncodingTarget to load.</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
<parameter name="category" transfer-ownership="none" allow-none="1"> | |
<doc xml:whitespace="preserve">the name of the target category, like #GST_ENCODING_CATEGORY_DEVICE. Can be %NULL</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="load_from_file" | |
c:identifier="gst_encoding_target_load_from_file" | |
version="0.10.32" | |
throws="1"> | |
<doc xml:whitespace="preserve">Opens the provided file and returns the contained #GstEncodingTarget. | |
%NULL</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">The #GstEncodingTarget contained in the file, else</doc> | |
<type name="EncodingTarget" c:type="GstEncodingTarget*"/> | |
</return-value> | |
<parameters> | |
<parameter name="filepath" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">The file location to load the #GstEncodingTarget from</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<method name="add_profile" | |
c:identifier="gst_encoding_target_add_profile" | |
version="0.10.32"> | |
<doc xml:whitespace="preserve">Adds the given @profile to the @target. Each added profile must have | |
a unique name within the profile. | |
The @target will steal a reference to the @profile. If you wish to use | |
the profile after calling this method, you should increase its reference | |
count.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">%TRUE if the profile was added, else %FALSE.</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</return-value> | |
<parameters> | |
<parameter name="profile" transfer-ownership="full"> | |
<doc xml:whitespace="preserve">the #GstEncodingProfile to add</doc> | |
<type name="EncodingProfile" c:type="GstEncodingProfile*"/> | |
</parameter> | |
</parameters> | |
</method> | |
<method name="get_category" | |
c:identifier="gst_encoding_target_get_category" | |
version="0.10.32"> | |
<doc xml:whitespace="preserve">#GST_ENCODING_CATEGORY_DEVICE.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">The category of the @target. For example:</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</return-value> | |
</method> | |
<method name="get_description" | |
c:identifier="gst_encoding_target_get_description" | |
version="0.10.32"> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">The description of the @target.</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</return-value> | |
</method> | |
<method name="get_name" | |
c:identifier="gst_encoding_target_get_name" | |
version="0.10.32"> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">The name of the @target.</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</return-value> | |
</method> | |
<method name="get_profile" | |
c:identifier="gst_encoding_target_get_profile" | |
version="0.10.32"> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">The matching #GstEncodingProfile, or %NULL.</doc> | |
<type name="EncodingProfile" c:type="GstEncodingProfile*"/> | |
</return-value> | |
<parameters> | |
<parameter name="name" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the name of the profile to retrieve</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
</parameters> | |
</method> | |
<method name="get_profiles" | |
c:identifier="gst_encoding_target_get_profiles" | |
version="0.10.32" | |
introspectable="0"> | |
<doc xml:whitespace="preserve">#GstEncodingProfile(s) this @target handles.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">A list of</doc> | |
<type name="GLib.List" c:type="GList*"> | |
<type name="Gst.EncodingProfile"/> | |
</type> | |
</return-value> | |
</method> | |
<method name="save" | |
c:identifier="gst_encoding_target_save" | |
version="0.10.32" | |
throws="1"> | |
<doc xml:whitespace="preserve">Saves the @target to a default user-local directory.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">%TRUE if the target was correctly saved, else %FALSE.</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</return-value> | |
</method> | |
<method name="save_to_file" | |
c:identifier="gst_encoding_target_save_to_file" | |
version="0.10.32" | |
throws="1"> | |
<doc xml:whitespace="preserve">Saves the @target to the provided file location.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">%TRUE if the target was correctly saved, else %FALSE.</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</return-value> | |
<parameters> | |
<parameter name="filepath" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the location to store the @target at.</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
</parameters> | |
</method> | |
</class> | |
<class name="EncodingVideoProfile" | |
c:symbol-prefix="encoding_video_profile" | |
c:type="GstEncodingVideoProfile" | |
version="0.10.32" | |
parent="EncodingProfile" | |
glib:type-name="GstEncodingVideoProfile" | |
glib:get-type="gst_encoding_video_profile_get_type" | |
glib:fundamental="1"> | |
<doc xml:whitespace="preserve">Variant of #GstEncodingProfile for video streams, allows specifying the @pass.</doc> | |
<constructor name="new" | |
c:identifier="gst_encoding_video_profile_new" | |
version="0.10.32"> | |
<doc xml:whitespace="preserve">Creates a new #GstEncodingVideoProfile | |
All provided allocatable arguments will be internally copied, so can be | |
safely freed/unreferenced after calling this method. | |
If you wish to control the pass number (in case of multi-pass scenarios), | |
please refer to the gst_encoding_video_profile_set_pass() documentation. | |
If you wish to use/force a constant framerate please refer to the | |
gst_encoding_video_profile_set_variableframerate() documentation.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">the newly created #GstEncodingVideoProfile.</doc> | |
<type name="EncodingVideoProfile" c:type="GstEncodingVideoProfile*"/> | |
</return-value> | |
<parameters> | |
<parameter name="format" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the #GstCaps</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</parameter> | |
<parameter name="preset" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the preset(s) to use on the encoder, can be #NULL</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
<parameter name="restriction" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the #GstCaps used to restrict the input to the encoder, can be NULL. See gst_encoding_profile_get_restriction() for more details.</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</parameter> | |
<parameter name="presence" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the number of time this stream must be used. 0 means any number of times (including never)</doc> | |
<type name="guint" c:type="guint"/> | |
</parameter> | |
</parameters> | |
</constructor> | |
<method name="get_pass" | |
c:identifier="gst_encoding_video_profile_get_pass" | |
version="0.10.32"> | |
<doc xml:whitespace="preserve">1 for multi-pass. 0 if this is not a multi-pass profile</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">The pass number if this is part of a multi-pass profile. Starts at</doc> | |
<type name="guint" c:type="guint"/> | |
</return-value> | |
</method> | |
<method name="get_variableframerate" | |
c:identifier="gst_encoding_video_profile_get_variableframerate" | |
version="0.10.32"> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">Whether non-constant video framerate is allowed for encoding.</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</return-value> | |
</method> | |
<method name="set_pass" | |
c:identifier="gst_encoding_video_profile_set_pass" | |
version="0.10.32"> | |
<doc xml:whitespace="preserve">Sets the pass number of this video profile. The first pass profile should have | |
this value set to 1. If this video profile isn't part of a multi-pass profile, | |
you may set it to 0 (the default value).</doc> | |
<return-value transfer-ownership="none"> | |
<type name="none" c:type="void"/> | |
</return-value> | |
<parameters> | |
<parameter name="pass" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the pass number for this profile</doc> | |
<type name="guint" c:type="guint"/> | |
</parameter> | |
</parameters> | |
</method> | |
<method name="set_variableframerate" | |
c:identifier="gst_encoding_video_profile_set_variableframerate" | |
version="0.10.32"> | |
<doc xml:whitespace="preserve">If set to %TRUE, then the incoming streamm will be allowed to have non-constant | |
framerate. If set to %FALSE (default value), then the incoming stream will | |
be normalized by dropping/duplicating frames in order to produce a | |
constance framerate.</doc> | |
<return-value transfer-ownership="none"> | |
<type name="none" c:type="void"/> | |
</return-value> | |
<parameters> | |
<parameter name="variableframerate" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a boolean</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</parameter> | |
</parameters> | |
</method> | |
</class> | |
<record name="InstallPluginsContext" | |
c:type="GstInstallPluginsContext" | |
version="0.10.12" | |
glib:type-name="GstInstallPluginsContext" | |
glib:get-type="gst_install_plugins_context_get_type" | |
c:symbol-prefix="install_plugins_context"> | |
<doc xml:whitespace="preserve">Opaque context structure for the plugin installation. Use the provided | |
API to set details on it.</doc> | |
<constructor name="new" | |
c:identifier="gst_install_plugins_context_new" | |
version="0.10.12"> | |
<doc xml:whitespace="preserve">Creates a new #GstInstallPluginsContext. | |
gst_install_plugins_context_free() when no longer needed</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">a new #GstInstallPluginsContext. Free with</doc> | |
<type name="InstallPluginsContext" | |
c:type="GstInstallPluginsContext*"/> | |
</return-value> | |
</constructor> | |
<method name="free" | |
c:identifier="gst_install_plugins_context_free" | |
version="0.10.12"> | |
<doc xml:whitespace="preserve">Frees a #GstInstallPluginsContext.</doc> | |
<return-value transfer-ownership="none"> | |
<type name="none" c:type="void"/> | |
</return-value> | |
</method> | |
<method name="set_xid" | |
c:identifier="gst_install_plugins_context_set_xid" | |
version="0.10.12"> | |
<doc xml:whitespace="preserve">This function is for X11-based applications (such as most Gtk/Qt | |
applications on linux/unix) only. You can use it to tell the external | |
installer the XID of your main application window. That way the installer | |
can make its own window transient to your application window during the | |
installation. | |
If set, the XID will be passed to the installer via a --transient-for=XID | |
command line option. | |
Gtk+/Gnome application should be able to obtain the XID of the top-level | |
window like this: | |
<programlisting> | |
##include &lt;gtk/gtk.h&gt; | |
##ifdef GDK_WINDOWING_X11 | |
##include &lt;gdk/gdkx.h&gt; | |
##endif | |
... | |
##ifdef GDK_WINDOWING_X11 | |
xid = GDK_WINDOW_XWINDOW (GTK_WIDGET (application_window)-&gt;window); | |
##endif | |
... | |
</programlisting></doc> | |
<return-value transfer-ownership="none"> | |
<type name="none" c:type="void"/> | |
</return-value> | |
<parameters> | |
<parameter name="xid" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the XWindow ID (XID) of the top-level application</doc> | |
<type name="guint" c:type="guint"/> | |
</parameter> | |
</parameters> | |
</method> | |
</record> | |
<callback name="InstallPluginsResultFunc" | |
c:type="GstInstallPluginsResultFunc" | |
version="0.10.12"> | |
<doc xml:whitespace="preserve">The prototype of the callback function that will be called once the | |
external plugin installer program has returned. You only need to provide | |
a callback function if you are using the asynchronous interface.</doc> | |
<return-value transfer-ownership="none"> | |
<type name="none" c:type="void"/> | |
</return-value> | |
<parameters> | |
<parameter name="result" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">whether the installation of the requested plugins succeeded or not</doc> | |
<type name="InstallPluginsReturn" c:type="GstInstallPluginsReturn"/> | |
</parameter> | |
<parameter name="user_data" transfer-ownership="none" closure="1"> | |
<doc xml:whitespace="preserve">the user data passed to gst_install_plugins_async()</doc> | |
<type name="gpointer" c:type="gpointer"/> | |
</parameter> | |
</parameters> | |
</callback> | |
<enumeration name="InstallPluginsReturn" | |
version="0.10.12" | |
glib:type-name="GstInstallPluginsReturn" | |
glib:get-type="gst_install_plugins_return_get_type" | |
c:type="GstInstallPluginsReturn"> | |
<doc xml:whitespace="preserve">Result codes returned by gst_install_plugins_async() and | |
gst_install_plugins_sync(), and also the result code passed to the | |
#GstInstallPluginsResultFunc specified with gst_install_plugin_async(). | |
These codes indicate success or failure of starting an external installer | |
program and to what extent the requested plugins could be installed.</doc> | |
<member name="success" | |
value="0" | |
c:identifier="GST_INSTALL_PLUGINS_SUCCESS" | |
glib:nick="success"/> | |
<member name="not_found" | |
value="1" | |
c:identifier="GST_INSTALL_PLUGINS_NOT_FOUND" | |
glib:nick="not-found"/> | |
<member name="error" | |
value="2" | |
c:identifier="GST_INSTALL_PLUGINS_ERROR" | |
glib:nick="error"/> | |
<member name="partial_success" | |
value="3" | |
c:identifier="GST_INSTALL_PLUGINS_PARTIAL_SUCCESS" | |
glib:nick="partial-success"/> | |
<member name="user_abort" | |
value="4" | |
c:identifier="GST_INSTALL_PLUGINS_USER_ABORT" | |
glib:nick="user-abort"/> | |
<member name="crashed" | |
value="100" | |
c:identifier="GST_INSTALL_PLUGINS_CRASHED" | |
glib:nick="crashed"/> | |
<member name="invalid" | |
value="101" | |
c:identifier="GST_INSTALL_PLUGINS_INVALID" | |
glib:nick="invalid"/> | |
<member name="started_ok" | |
value="200" | |
c:identifier="GST_INSTALL_PLUGINS_STARTED_OK" | |
glib:nick="started-ok"/> | |
<member name="internal_failure" | |
value="201" | |
c:identifier="GST_INSTALL_PLUGINS_INTERNAL_FAILURE" | |
glib:nick="internal-failure"/> | |
<member name="helper_missing" | |
value="202" | |
c:identifier="GST_INSTALL_PLUGINS_HELPER_MISSING" | |
glib:nick="helper-missing"/> | |
<member name="install_in_progress" | |
value="203" | |
c:identifier="GST_INSTALL_PLUGINS_INSTALL_IN_PROGRESS" | |
glib:nick="install-in-progress"/> | |
</enumeration> | |
<constant name="PLUGINS_BASE_VERSION_MAJOR" value="0"> | |
<type name="gint" c:type="gint"/> | |
</constant> | |
<constant name="PLUGINS_BASE_VERSION_MICRO" value="32"> | |
<type name="gint" c:type="gint"/> | |
</constant> | |
<constant name="PLUGINS_BASE_VERSION_MINOR" value="10"> | |
<type name="gint" c:type="gint"/> | |
</constant> | |
<constant name="PLUGINS_BASE_VERSION_NANO" value="0"> | |
<type name="gint" c:type="gint"/> | |
</constant> | |
<function name="codec_utils_aac_caps_set_level_and_profile" | |
c:identifier="gst_codec_utils_aac_caps_set_level_and_profile" | |
version="0.10.31"> | |
<doc xml:whitespace="preserve">Sets the level and profile on @caps if it can be determined from | |
gst_codec_utils_aac_get_profile() for more details on the parameters. | |
If mpegversion is 4, the "base-profile" field is also set in @caps.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">%TRUE if the level and profile could be set, %FALSE otherwise.</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</return-value> | |
<parameters> | |
<parameter name="caps" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the #GstCaps to which level and profile fields are to be added</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</parameter> | |
<parameter name="audio_config" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a pointer to the AudioSpecificConfig as specified in the Elementary Stream Descriptor (esds) in ISO/IEC 14496-1 (see below for a more details).</doc> | |
<type name="guint8" c:type="guint8*"/> | |
</parameter> | |
<parameter name="len" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">Length of @audio_config in bytes</doc> | |
<type name="guint" c:type="guint"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="codec_utils_aac_get_level" | |
c:identifier="gst_codec_utils_aac_get_level" | |
version="0.10.31"> | |
<doc xml:whitespace="preserve">Determines the level of a stream as defined in ISO/IEC 14496-3. For AAC LC | |
streams, the constraints from the AAC audio profile are applied. For AAC | |
Main, LTP, SSR and others, the Main profile is used. | |
The @audio_config parameter follows the following format, starting from the | |
most significant bit of the first byte: | |
<itemizedlist> | |
<listitem><para> | |
Bit 0:4 contains the AudioObjectType | |
</para></listitem> | |
<listitem><para> | |
Bit 5:8 contains the sample frequency index (if this is 0xf, then the | |
next 24 bits define the actual sample frequency, and subsequent | |
fields are appropriately shifted). | |
</para></listitem> | |
<listitem><para> | |
Bit 9:12 contains the channel configuration | |
</para></listitem> | |
</itemizedlist> | |
<note> | |
HE-AAC support has not yet been implemented. | |
</note> | |
determined.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">The level as a const string and %NULL if the level could not be</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</return-value> | |
<parameters> | |
<parameter name="audio_config" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a pointer to the AudioSpecificConfig as specified in the Elementary Stream Descriptor (esds) in ISO/IEC 14496-1.</doc> | |
<type name="guint8" c:type="guint8*"/> | |
</parameter> | |
<parameter name="len" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">Length of @audio_config in bytes</doc> | |
<type name="guint" c:type="guint"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="codec_utils_aac_get_profile" | |
c:identifier="gst_codec_utils_aac_get_profile" | |
version="0.10.31"> | |
<doc xml:whitespace="preserve">Returns the profile of the given AAC stream as a string. The profile is | |
determined using the AudioObjectType field which is in the first 5 bits of | |
<note> | |
HE-AAC support has not yet been implemented. | |
</note> | |
determined.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">The profile as a const string and %NULL if the profile could not be</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</return-value> | |
<parameters> | |
<parameter name="audio_config" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a pointer to the AudioSpecificConfig as specified in the Elementary Stream Descriptor (esds) in ISO/IEC 14496-1 (see gst_codec_utils_aac_get_level() for a more details).</doc> | |
<type name="guint8" c:type="guint8*"/> | |
</parameter> | |
<parameter name="len" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">Length of @audio_config in bytes</doc> | |
<type name="guint" c:type="guint"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="codec_utils_aac_get_sample_rate_from_index" | |
c:identifier="gst_codec_utils_aac_get_sample_rate_from_index" | |
version="0.10.31"> | |
<doc xml:whitespace="preserve">Translates the sample rate index found in AAC headers to the actual sample | |
rate.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">The sample rate if @sr_idx is valid, 0 otherwise.</doc> | |
<type name="guint" c:type="guint"/> | |
</return-value> | |
<parameters> | |
<parameter name="sr_idx" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">Sample rate index as from the AudioSpecificConfig (MPEG-4 container) or ADTS frame header</doc> | |
<type name="guint" c:type="guint"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="codec_utils_h264_caps_set_level_and_profile" | |
c:identifier="gst_codec_utils_h264_caps_set_level_and_profile" | |
version="0.10.31"> | |
<doc xml:whitespace="preserve">Sets the level and profile in @caps if it can be determined from @sps. See | |
gst_codec_utils_h264_get_level() and gst_codec_utils_h264_get_profile() | |
for more details on the parameters.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">%TRUE if the level and profile could be set, %FALSE otherwise.</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</return-value> | |
<parameters> | |
<parameter name="caps" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the #GstCaps to which the level and profile are to be added</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</parameter> | |
<parameter name="sps" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">Pointer to the sequence parameter set for the stream.</doc> | |
<type name="guint8" c:type="guint8*"/> | |
</parameter> | |
<parameter name="len" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">Length of the data available in @sps.</doc> | |
<type name="guint" c:type="guint"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="codec_utils_h264_get_level" | |
c:identifier="gst_codec_utils_h264_get_level" | |
version="0.10.31"> | |
<doc xml:whitespace="preserve">Converts the level indication (level_idc) in the stream's | |
sequence parameter set into a string. The SPS is expected to have the | |
same format as for gst_codec_utils_h264_get_profile().</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">The level as a const string, or %NULL if there is an error.</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</return-value> | |
<parameters> | |
<parameter name="sps" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">Pointer to the sequence parameter set for the stream.</doc> | |
<type name="guint8" c:type="guint8*"/> | |
</parameter> | |
<parameter name="len" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">Length of the data available in @sps.</doc> | |
<type name="guint" c:type="guint"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="codec_utils_h264_get_profile" | |
c:identifier="gst_codec_utils_h264_get_profile" | |
version="0.10.31"> | |
<doc xml:whitespace="preserve">Converts the profile indication (profile_idc) in the stream's | |
sequence parameter set into a string. The SPS is expected to have the | |
following format, as defined in the H.264 specification. The SPS is viewed | |
as a bitstream here, with bit 0 being the most significant bit of the first | |
byte. | |
<itemizedlist> | |
<listitem><para>Bit 0:7 - Profile indication</para></listitem> | |
<listitem><para>Bit 8 - constraint_set0_flag</para></listitem> | |
<listitem><para>Bit 9 - constraint_set1_flag</para></listitem> | |
<listitem><para>Bit 10 - constraint_set2_flag</para></listitem> | |
<listitem><para>Bit 11 - constraint_set3_flag</para></listitem> | |
<listitem><para>Bit 12 - constraint_set3_flag</para></listitem> | |
<listitem><para>Bit 13:15 - Reserved</para></listitem> | |
<listitem><para>Bit 16:24 - Level indication</para></listitem> | |
</itemizedlist></doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">The profile as a const string, or %NULL if there is an error.</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</return-value> | |
<parameters> | |
<parameter name="sps" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">Pointer to the sequence parameter set for the stream.</doc> | |
<type name="guint8" c:type="guint8*"/> | |
</parameter> | |
<parameter name="len" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">Length of the data available in @sps.</doc> | |
<type name="guint" c:type="guint"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="codec_utils_mpeg4video_caps_set_level_and_profile" | |
c:identifier="gst_codec_utils_mpeg4video_caps_set_level_and_profile" | |
version="0.10.31"> | |
<doc xml:whitespace="preserve">Sets the level and profile in @caps if it can be determined from | |
gst_codec_utils_mpeg4video_get_profile() for more details on the | |
parameters.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">%TRUE if the level and profile could be set, %FALSE otherwise.</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</return-value> | |
<parameters> | |
<parameter name="caps" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the #GstCaps to which the level and profile are to be added</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</parameter> | |
<parameter name="vis_obj_seq" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">Pointer to the visual object sequence for the stream.</doc> | |
<type name="guint8" c:type="guint8*"/> | |
</parameter> | |
<parameter name="len" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">Length of the data available in @sps.</doc> | |
<type name="guint" c:type="guint"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="codec_utils_mpeg4video_get_level" | |
c:identifier="gst_codec_utils_mpeg4video_get_level" | |
version="0.10.31"> | |
<doc xml:whitespace="preserve">Converts the level indication in the stream's visual object sequence into | |
a string. @vis_obj_seq is expected to be the data following the visual | |
object sequence start code. Only the first byte | |
(profile_and_level_indication) is used.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">The level as a const string, or NULL if there is an error.</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</return-value> | |
<parameters> | |
<parameter name="vis_obj_seq" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">Pointer to the visual object sequence for the stream.</doc> | |
<type name="guint8" c:type="guint8*"/> | |
</parameter> | |
<parameter name="len" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">Length of the data available in @sps.</doc> | |
<type name="guint" c:type="guint"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="codec_utils_mpeg4video_get_profile" | |
c:identifier="gst_codec_utils_mpeg4video_get_profile" | |
version="0.10.31"> | |
<doc xml:whitespace="preserve">Converts the profile indication in the stream's visual object sequence into | |
a string. @vis_obj_seq is expected to be the data following the visual | |
object sequence start code. Only the first byte | |
(profile_and_level_indication) is used.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">The profile as a const string, or NULL if there is an error.</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</return-value> | |
<parameters> | |
<parameter name="vis_obj_seq" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">Pointer to the visual object sequence for the stream.</doc> | |
<type name="guint8" c:type="guint8*"/> | |
</parameter> | |
<parameter name="len" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">Length of the data available in @sps.</doc> | |
<type name="guint" c:type="guint"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="encoding_list_all_targets" | |
c:identifier="gst_encoding_list_all_targets" | |
version="0.10.32"> | |
<doc xml:whitespace="preserve">List all available #GstEncodingTarget for the specified category, or all categories | |
if @categoryname is %NULL.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">The list of #GstEncodingTarget</doc> | |
<type name="GLib.List" c:type="GList*"> | |
<type name="EncodingTarget"/> | |
</type> | |
</return-value> | |
<parameters> | |
<parameter name="categoryname" | |
transfer-ownership="none" | |
allow-none="1"> | |
<doc xml:whitespace="preserve">The category, for ex: #GST_ENCODING_CATEGORY_DEVICE. Can be %NULL.</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="encoding_list_available_categories" | |
c:identifier="gst_encoding_list_available_categories" | |
version="0.10.32"> | |
<doc xml:whitespace="preserve">Lists all #GstEncodingTarget categories present on disk. | |
of #GstEncodingTarget categories.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">A list</doc> | |
<type name="GLib.List" c:type="GList*"> | |
<type name="utf8"/> | |
</type> | |
</return-value> | |
</function> | |
<function name="install_plugins_async" | |
c:identifier="gst_install_plugins_async" | |
version="0.10.12"> | |
<doc xml:whitespace="preserve">Requests plugin installation without blocking. Once the plugins have been | |
installed or installation has failed, @func will be called with the result | |
of the installation and your provided @user_data pointer. | |
This function requires a running GLib/Gtk main loop. If you are not | |
running a GLib/Gtk main loop, make sure to regularly call | |
g_main_context_iteration(NULL,FALSE). | |
The installer strings that make up @detail are typically obtained by | |
calling gst_missing_plugin_message_get_installer_detail() on missing-plugin | |
messages that have been caught on a pipeline's bus or created by the | |
application via the provided API, such as gst_missing_element_message_new(). | |
It is possible to request the installation of multiple missing plugins in | |
one go (as might be required if there is a demuxer for a certain format | |
installed but no suitable video decoder and no suitable audio decoder).</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">result code whether an external installer could be started</doc> | |
<type name="InstallPluginsReturn" c:type="GstInstallPluginsReturn"/> | |
</return-value> | |
<parameters> | |
<parameter name="details" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">NULL-terminated array of installer string details (see below)</doc> | |
<type name="utf8" c:type="gchar**"/> | |
</parameter> | |
<parameter name="ctx" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a #GstInstallPluginsContext, or NULL</doc> | |
<type name="InstallPluginsContext" | |
c:type="GstInstallPluginsContext*"/> | |
</parameter> | |
<parameter name="func" | |
transfer-ownership="none" | |
scope="async" | |
closure="3"> | |
<doc xml:whitespace="preserve">the function to call when the installer program returns</doc> | |
<type name="InstallPluginsResultFunc" | |
c:type="GstInstallPluginsResultFunc"/> | |
</parameter> | |
<parameter name="user_data" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the user data to pass to @func when called, or NULL</doc> | |
<type name="gpointer" c:type="gpointer"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="install_plugins_installation_in_progress" | |
c:identifier="gst_install_plugins_installation_in_progress" | |
version="0.10.12"> | |
<doc xml:whitespace="preserve">Checks whether plugin installation (initiated by this application only) | |
is currently in progress.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">TRUE if plugin installation is in progress, otherwise FALSE</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</return-value> | |
</function> | |
<function name="install_plugins_return_get_name" | |
c:identifier="gst_install_plugins_return_get_name" | |
version="0.10.12"> | |
<doc xml:whitespace="preserve">Convenience function to return the descriptive string associated | |
with a status code. This function returns English strings and | |
should not be used for user messages. It is here only to assist | |
in debugging.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a descriptive string for the status code in @ret</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</return-value> | |
<parameters> | |
<parameter name="ret" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the return status code</doc> | |
<type name="InstallPluginsReturn" c:type="GstInstallPluginsReturn"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="install_plugins_supported" | |
c:identifier="gst_install_plugins_supported" | |
version="0.10.15"> | |
<doc xml:whitespace="preserve">Checks whether plugin installation is likely to be supported by the | |
current environment. This currently only checks whether the helper script | |
that is to be provided by the distribution or operating system vendor | |
exists.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">TRUE if plugin installation is likely to be supported.</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</return-value> | |
</function> | |
<function name="install_plugins_sync" | |
c:identifier="gst_install_plugins_sync" | |
version="0.10.12"> | |
<doc xml:whitespace="preserve">Requests plugin installation and block until the plugins have been | |
installed or installation has failed. | |
This function should almost never be used, it only exists for cases where | |
a non-GLib main loop is running and the user wants to run it in a separate | |
thread and marshal the result back asynchronously into the main thread | |
using the other non-GLib main loop. You should almost always use | |
gst_install_plugins_async() instead of this function.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the result of the installation.</doc> | |
<type name="InstallPluginsReturn" c:type="GstInstallPluginsReturn"/> | |
</return-value> | |
<parameters> | |
<parameter name="details" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">NULL-terminated array of installer string details</doc> | |
<type name="utf8" c:type="gchar**"/> | |
</parameter> | |
<parameter name="ctx" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a #GstInstallPluginsContext, or NULL</doc> | |
<type name="InstallPluginsContext" | |
c:type="GstInstallPluginsContext*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="is_missing_plugin_message" | |
c:identifier="gst_is_missing_plugin_message"> | |
<doc xml:whitespace="preserve">Checks whether @msg is a missing plugins message.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">%TRUE if @msg is a missing-plugins message, otherwise %FALSE.</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</return-value> | |
<parameters> | |
<parameter name="msg" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a #GstMessage</doc> | |
<type name="Gst.Message" c:type="GstMessage*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="missing_decoder_installer_detail_new" | |
c:identifier="gst_missing_decoder_installer_detail_new" | |
version="0.10.15"> | |
<doc xml:whitespace="preserve">Returns an opaque string containing all the details about the missing | |
element to be passed to an external installer called via | |
gst_install_plugins_async() or gst_install_plugins_sync(). | |
This function is mainly for applications that call external plugin | |
installation mechanisms using one of the two above-mentioned functions in | |
the case where the application knows exactly what kind of plugin it is | |
missing. | |
with g_free() when not needed any longer.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">a newly-allocated detail string, or NULL on error. Free string</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</return-value> | |
<parameters> | |
<parameter name="decode_caps" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the (fixed) caps for which a decoder element is needed</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="missing_decoder_message_new" | |
c:identifier="gst_missing_decoder_message_new"> | |
<doc xml:whitespace="preserve">Creates a missing-plugin message for @element to notify the application | |
that a decoder element for a particular set of (fixed) caps is missing. | |
This function is mainly for use in plugins.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">a new #GstMessage, or NULL on error</doc> | |
<type name="Gst.Message" c:type="GstMessage*"/> | |
</return-value> | |
<parameters> | |
<parameter name="element" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the #GstElement posting the message</doc> | |
<type name="Gst.Element" c:type="GstElement*"/> | |
</parameter> | |
<parameter name="decode_caps" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the (fixed) caps for which a decoder element is needed</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="missing_element_installer_detail_new" | |
c:identifier="gst_missing_element_installer_detail_new" | |
version="0.10.15"> | |
<doc xml:whitespace="preserve">Returns an opaque string containing all the details about the missing | |
element to be passed to an external installer called via | |
gst_install_plugins_async() or gst_install_plugins_sync(). | |
This function is mainly for applications that call external plugin | |
installation mechanisms using one of the two above-mentioned functions in | |
the case where the application knows exactly what kind of plugin it is | |
missing. | |
with g_free() when not needed any longer.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">a newly-allocated detail string, or NULL on error. Free string</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</return-value> | |
<parameters> | |
<parameter name="factory_name" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the name of the missing element (element factory), e.g. "videoscale" or "cdparanoiasrc"</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="missing_element_message_new" | |
c:identifier="gst_missing_element_message_new"> | |
<doc xml:whitespace="preserve">Creates a missing-plugin message for @element to notify the application | |
that a certain required element is missing. This function is mainly for | |
use in plugins.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">a new #GstMessage, or NULL on error</doc> | |
<type name="Gst.Message" c:type="GstMessage*"/> | |
</return-value> | |
<parameters> | |
<parameter name="element" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the #GstElement posting the message</doc> | |
<type name="Gst.Element" c:type="GstElement*"/> | |
</parameter> | |
<parameter name="factory_name" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the name of the missing element (element factory), e.g. "videoscale" or "cdparanoiasrc"</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="missing_encoder_installer_detail_new" | |
c:identifier="gst_missing_encoder_installer_detail_new" | |
version="0.10.15"> | |
<doc xml:whitespace="preserve">Returns an opaque string containing all the details about the missing | |
element to be passed to an external installer called via | |
gst_install_plugins_async() or gst_install_plugins_sync(). | |
This function is mainly for applications that call external plugin | |
installation mechanisms using one of the two above-mentioned functions in | |
the case where the application knows exactly what kind of plugin it is | |
missing. | |
with g_free() when not needed any longer.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">a newly-allocated detail string, or NULL on error. Free string</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</return-value> | |
<parameters> | |
<parameter name="encode_caps" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the (fixed) caps for which an encoder element is needed</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="missing_encoder_message_new" | |
c:identifier="gst_missing_encoder_message_new"> | |
<doc xml:whitespace="preserve">Creates a missing-plugin message for @element to notify the application | |
that an encoder element for a particular set of (fixed) caps is missing. | |
This function is mainly for use in plugins.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">a new #GstMessage, or NULL on error</doc> | |
<type name="Gst.Message" c:type="GstMessage*"/> | |
</return-value> | |
<parameters> | |
<parameter name="element" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the #GstElement posting the message</doc> | |
<type name="Gst.Element" c:type="GstElement*"/> | |
</parameter> | |
<parameter name="encode_caps" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the (fixed) caps for which an encoder element is needed</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="missing_plugin_message_get_description" | |
c:identifier="gst_missing_plugin_message_get_description"> | |
<doc xml:whitespace="preserve">Returns a localised string describing the missing feature, for use in | |
error dialogs and the like. Should never return NULL unless @msg is not | |
a valid missing-plugin message. | |
This function is mainly for applications that need a human-readable string | |
describing a missing plugin, given a previously collected missing-plugin | |
message | |
string with g_free() when not needed any longer.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">a newly-allocated description string, or NULL on error. Free</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</return-value> | |
<parameters> | |
<parameter name="msg" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a missing-plugin #GstMessage of type #GST_MESSAGE_ELEMENT</doc> | |
<type name="Gst.Message" c:type="GstMessage*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="missing_plugin_message_get_installer_detail" | |
c:identifier="gst_missing_plugin_message_get_installer_detail"> | |
<doc xml:whitespace="preserve">Returns an opaque string containing all the details about the missing | |
element to be passed to an external installer called via | |
gst_install_plugins_async() or gst_install_plugins_sync(). | |
This function is mainly for applications that call external plugin | |
installation mechanisms using one of the two above-mentioned functions. | |
with g_free() when not needed any longer.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">a newly-allocated detail string, or NULL on error. Free string</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</return-value> | |
<parameters> | |
<parameter name="msg" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a missing-plugin #GstMessage of type #GST_MESSAGE_ELEMENT</doc> | |
<type name="Gst.Message" c:type="GstMessage*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="missing_uri_sink_installer_detail_new" | |
c:identifier="gst_missing_uri_sink_installer_detail_new" | |
version="0.10.15"> | |
<doc xml:whitespace="preserve">Returns an opaque string containing all the details about the missing | |
element to be passed to an external installer called via | |
gst_install_plugins_async() or gst_install_plugins_sync(). | |
This function is mainly for applications that call external plugin | |
installation mechanisms using one of the two above-mentioned functions in | |
the case where the application knows exactly what kind of plugin it is | |
missing. | |
with g_free() when not needed any longer.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">a newly-allocated detail string, or NULL on error. Free string</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</return-value> | |
<parameters> | |
<parameter name="protocol" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the URI protocol the missing source needs to implement, e.g. "http" or "mms"</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="missing_uri_sink_message_new" | |
c:identifier="gst_missing_uri_sink_message_new"> | |
<doc xml:whitespace="preserve">Creates a missing-plugin message for @element to notify the application | |
that a sink element for a particular URI protocol is missing. This | |
function is mainly for use in plugins.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">a new #GstMessage, or NULL on error</doc> | |
<type name="Gst.Message" c:type="GstMessage*"/> | |
</return-value> | |
<parameters> | |
<parameter name="element" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the #GstElement posting the message</doc> | |
<type name="Gst.Element" c:type="GstElement*"/> | |
</parameter> | |
<parameter name="protocol" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the URI protocol the missing sink needs to implement, e.g. "http" or "smb"</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="missing_uri_source_installer_detail_new" | |
c:identifier="gst_missing_uri_source_installer_detail_new" | |
version="0.10.15"> | |
<doc xml:whitespace="preserve">Returns an opaque string containing all the details about the missing | |
element to be passed to an external installer called via | |
gst_install_plugins_async() or gst_install_plugins_sync(). | |
This function is mainly for applications that call external plugin | |
installation mechanisms using one of the two above-mentioned functions in | |
the case where the application knows exactly what kind of plugin it is | |
missing. | |
with g_free() when not needed any longer.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">a newly-allocated detail string, or NULL on error. Free string</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</return-value> | |
<parameters> | |
<parameter name="protocol" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the URI protocol the missing source needs to implement, e.g. "http" or "mms"</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="missing_uri_source_message_new" | |
c:identifier="gst_missing_uri_source_message_new"> | |
<doc xml:whitespace="preserve">Creates a missing-plugin message for @element to notify the application | |
that a source element for a particular URI protocol is missing. This | |
function is mainly for use in plugins.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">a new #GstMessage, or NULL on error</doc> | |
<type name="Gst.Message" c:type="GstMessage*"/> | |
</return-value> | |
<parameters> | |
<parameter name="element" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the #GstElement posting the message</doc> | |
<type name="Gst.Element" c:type="GstElement*"/> | |
</parameter> | |
<parameter name="protocol" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the URI protocol the missing source needs to implement, e.g. "http" or "mms"</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="pb_utils_add_codec_description_to_tag_list" | |
c:identifier="gst_pb_utils_add_codec_description_to_tag_list"> | |
<doc xml:whitespace="preserve">Adds a codec tag describing the format specified by @caps to @taglist.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">TRUE if a codec tag was added, FALSE otherwise.</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</return-value> | |
<parameters> | |
<parameter name="taglist" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a #GstTagList</doc> | |
<type name="Gst.TagList" c:type="GstTagList*"/> | |
</parameter> | |
<parameter name="codec_tag" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a GStreamer codec tag such as #GST_TAG_AUDIO_CODEC, #GST_TAG_VIDEO_CODEC or #GST_TAG_CODEC</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
<parameter name="caps" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the (fixed) #GstCaps for which a codec tag should be added.</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="pb_utils_get_codec_description" | |
c:identifier="gst_pb_utils_get_codec_description"> | |
<doc xml:whitespace="preserve">Returns a localised (as far as this is possible) string describing the | |
media format specified in @caps, for use in error dialogs or other messages | |
to be seen by the user. Should never return NULL unless @caps is invalid. | |
Also see the convenience function | |
gst_pb_utils_add_codec_description_to_tag_list(). | |
string with g_free() when not needed any longer.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">a newly-allocated description string, or NULL on error. Free</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</return-value> | |
<parameters> | |
<parameter name="caps" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the (fixed) #GstCaps for which an format description is needed</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="pb_utils_get_decoder_description" | |
c:identifier="gst_pb_utils_get_decoder_description"> | |
<doc xml:whitespace="preserve">Returns a localised string describing an decoder for the format specified | |
in @caps, for use in error dialogs or other messages to be seen by the user. | |
Should never return NULL unless @factory_name or @caps are invalid. | |
This function is mainly for internal use, applications would typically | |
use gst_missing_plugin_message_get_description() to get a description of | |
a missing feature from a missing-plugin message. | |
string with g_free() when not needed any longer.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">a newly-allocated description string, or NULL on error. Free</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</return-value> | |
<parameters> | |
<parameter name="caps" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the (fixed) #GstCaps for which an decoder description is needed</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="pb_utils_get_element_description" | |
c:identifier="gst_pb_utils_get_element_description"> | |
<doc xml:whitespace="preserve">Returns a localised string describing the given element, for use in | |
error dialogs or other messages to be seen by the user. Should never | |
return NULL unless @factory_name is invalid. | |
This function is mainly for internal use, applications would typically | |
use gst_missing_plugin_message_get_description() to get a description of | |
a missing feature from a missing-plugin message. | |
string with g_free() when not needed any longer.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">a newly-allocated description string, or NULL on error. Free</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</return-value> | |
<parameters> | |
<parameter name="factory_name" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the name of the element, e.g. "gnomevfssrc"</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="pb_utils_get_encoder_description" | |
c:identifier="gst_pb_utils_get_encoder_description"> | |
<doc xml:whitespace="preserve">Returns a localised string describing an encoder for the format specified | |
in @caps, for use in error dialogs or other messages to be seen by the user. | |
Should never return NULL unless @factory_name or @caps are invalid. | |
This function is mainly for internal use, applications would typically | |
use gst_missing_plugin_message_get_description() to get a description of | |
a missing feature from a missing-plugin message. | |
string with g_free() when not needed any longer.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">a newly-allocated description string, or NULL on error. Free</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</return-value> | |
<parameters> | |
<parameter name="caps" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the (fixed) #GstCaps for which an encoder description is needed</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="pb_utils_get_sink_description" | |
c:identifier="gst_pb_utils_get_sink_description"> | |
<doc xml:whitespace="preserve">Returns a localised string describing a sink element handling the protocol | |
specified in @protocol, for use in error dialogs or other messages to be | |
seen by the user. Should never return NULL unless @protocol is invalid. | |
This function is mainly for internal use, applications would typically | |
use gst_missing_plugin_message_get_description() to get a description of | |
a missing feature from a missing-plugin message. | |
string with g_free() when not needed any longer.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">a newly-allocated description string, or NULL on error. Free</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</return-value> | |
<parameters> | |
<parameter name="protocol" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the protocol the sink element needs to handle, e.g. "http"</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="pb_utils_get_source_description" | |
c:identifier="gst_pb_utils_get_source_description"> | |
<doc xml:whitespace="preserve">Returns a localised string describing a source element handling the protocol | |
specified in @protocol, for use in error dialogs or other messages to be | |
seen by the user. Should never return NULL unless @protocol is invalid. | |
This function is mainly for internal use, applications would typically | |
use gst_missing_plugin_message_get_description() to get a description of | |
a missing feature from a missing-plugin message. | |
string with g_free() when not needed any longer.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">a newly-allocated description string, or NULL on error. Free</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</return-value> | |
<parameters> | |
<parameter name="protocol" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the protocol the source element needs to handle, e.g. "http"</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="pb_utils_init" | |
c:identifier="gst_pb_utils_init" | |
version="0.10.12"> | |
<doc xml:whitespace="preserve">Initialises the base utils support library. This function is not | |
thread-safe. Applications should call it after calling gst_init(), | |
plugins should call it from their plugin_init function. | |
This function may be called multiple times. It will do nothing if the | |
library has already been initialised.</doc> | |
<return-value transfer-ownership="none"> | |
<type name="none" c:type="void"/> | |
</return-value> | |
</function> | |
<function name="plugins_base_version" | |
c:identifier="gst_plugins_base_version" | |
version="0.10.31"> | |
<doc xml:whitespace="preserve">Gets the version number of the GStreamer Plugins Base libraries.</doc> | |
<return-value transfer-ownership="none"> | |
<type name="none" c:type="void"/> | |
</return-value> | |
<parameters> | |
<parameter name="major" | |
direction="out" | |
caller-allocates="0" | |
transfer-ownership="full"> | |
<doc xml:whitespace="preserve">pointer to a guint to store the major version number, or %NULL</doc> | |
<type name="guint" c:type="guint*"/> | |
</parameter> | |
<parameter name="minor" | |
direction="out" | |
caller-allocates="0" | |
transfer-ownership="full"> | |
<doc xml:whitespace="preserve">pointer to a guint to store the minor version number, or %NULL</doc> | |
<type name="guint" c:type="guint*"/> | |
</parameter> | |
<parameter name="micro" | |
direction="out" | |
caller-allocates="0" | |
transfer-ownership="full"> | |
<doc xml:whitespace="preserve">pointer to a guint to store the micro version number, or %NULL</doc> | |
<type name="guint" c:type="guint*"/> | |
</parameter> | |
<parameter name="nano" | |
direction="out" | |
caller-allocates="0" | |
transfer-ownership="full"> | |
<doc xml:whitespace="preserve">pointer to a guint to store the nano version number, or %NULL</doc> | |
<type name="guint" c:type="guint*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="plugins_base_version_string" | |
c:identifier="gst_plugins_base_version_string" | |
version="0.10.31"> | |
<doc xml:whitespace="preserve">This function returns a string that is useful for describing this version | |
strings, logging, about dialogs ...</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">a newly allocated string describing this version of gst-plugins-base</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</return-value> | |
</function> | |
</namespace> | |
</repository> | |
]] | |
FILE: [[gstreamer/plugins/pbutils/ffi/ffi.factor]] [[! Copyright (C) 2010 Anton Gorenko. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: alien alien.libraries combinators kernel system | |
gobject-introspection glib.ffi gstreamer.ffi ; | |
IN: gstreamer.pbutils.ffi | |
<< | |
"gstreamer.pbutils" { | |
{ [ os winnt? ] [ drop ] } | |
{ [ os macosx? ] [ drop ] } | |
{ [ os unix? ] [ "libgstpbutils-0.10.so" cdecl add-library ] } | |
} cond | |
>> | |
GIR: vocab:gstreamer/pbutils/GstPbutils-0.10.gir | |
]] | |
FILE: [[gstreamer/plugins/video/GstVideo-0.10.gir]] [[<?xml version="1.0"?> | |
<!-- This file was automatically generated from C sources - DO NOT EDIT! | |
To affect the contents of this file, edit the original C definitions, | |
and/or use gtk-doc annotations. --> | |
<repository version="1.2" | |
xmlns="http://www.gtk.org/introspection/core/1.0" | |
xmlns:c="http://www.gtk.org/introspection/c/1.0" | |
xmlns:glib="http://www.gtk.org/introspection/glib/1.0"> | |
<include name="GLib" version="2.0"/> | |
<include name="GModule" version="2.0"/> | |
<include name="GObject" version="2.0"/> | |
<include name="Gst" version="0.10"/> | |
<include name="GstBase" version="0.10"/> | |
<include name="libxml2" version="2.0"/> | |
<package name="gstreamer-video-0.10"/> | |
<c:include name="gst/video/gstvideofilter.h"/> | |
<c:include name="gst/video/gstvideosink.h"/> | |
<c:include name="gst/video/video-enumtypes.h"/> | |
<c:include name="gst/video/video.h"/> | |
<namespace name="GstVideo" | |
version="0.10" | |
shared-library="libgstvideo-0.10.so.0" | |
c:identifier-prefixes="Gst" | |
c:symbol-prefixes="gst"> | |
<constant name="VIDEO_BYTE1_MASK_24" value="0x00FF0000"> | |
<type name="utf8" c:type="gchar*"/> | |
</constant> | |
<constant name="VIDEO_BYTE1_MASK_24_INT" value="16711680"> | |
<type name="gint" c:type="gint"/> | |
</constant> | |
<constant name="VIDEO_BYTE1_MASK_32" value="0xFF000000"> | |
<type name="utf8" c:type="gchar*"/> | |
</constant> | |
<constant name="VIDEO_BYTE1_MASK_32_INT" value="-16777216"> | |
<type name="gint" c:type="gint"/> | |
</constant> | |
<constant name="VIDEO_BYTE2_MASK_24" value="0x0000FF00"> | |
<type name="utf8" c:type="gchar*"/> | |
</constant> | |
<constant name="VIDEO_BYTE2_MASK_24_INT" value="65280"> | |
<type name="gint" c:type="gint"/> | |
</constant> | |
<constant name="VIDEO_BYTE2_MASK_32" value="0x00FF0000"> | |
<type name="utf8" c:type="gchar*"/> | |
</constant> | |
<constant name="VIDEO_BYTE2_MASK_32_INT" value="16711680"> | |
<type name="gint" c:type="gint"/> | |
</constant> | |
<constant name="VIDEO_BYTE3_MASK_24" value="0x000000FF"> | |
<type name="utf8" c:type="gchar*"/> | |
</constant> | |
<constant name="VIDEO_BYTE3_MASK_24_INT" value="255"> | |
<type name="gint" c:type="gint"/> | |
</constant> | |
<constant name="VIDEO_BYTE3_MASK_32" value="0x0000FF00"> | |
<type name="utf8" c:type="gchar*"/> | |
</constant> | |
<constant name="VIDEO_BYTE3_MASK_32_INT" value="65280"> | |
<type name="gint" c:type="gint"/> | |
</constant> | |
<constant name="VIDEO_BYTE4_MASK_32" value="0x000000FF"> | |
<type name="utf8" c:type="gchar*"/> | |
</constant> | |
<constant name="VIDEO_BYTE4_MASK_32_INT" value="255"> | |
<type name="gint" c:type="gint"/> | |
</constant> | |
<constant name="VIDEO_CAPS_GRAY8" | |
value="video/x-raw-gray, bpp = (int) 8, depth = (int) 8, width = "> | |
<type name="utf8" c:type="gchar*"/> | |
</constant> | |
<constant name="VIDEO_CAPS_RGB8_PALETTED" | |
value="video/x-raw-rgb, bpp = (int)8, depth = (int)8, width = "> | |
<type name="utf8" c:type="gchar*"/> | |
</constant> | |
<constant name="VIDEO_COMP1_MASK_15" value="0x7c00"> | |
<type name="utf8" c:type="gchar*"/> | |
</constant> | |
<constant name="VIDEO_COMP1_MASK_15_INT" value="31744"> | |
<type name="gint" c:type="gint"/> | |
</constant> | |
<constant name="VIDEO_COMP1_MASK_16" value="0xf800"> | |
<type name="utf8" c:type="gchar*"/> | |
</constant> | |
<constant name="VIDEO_COMP1_MASK_16_INT" value="63488"> | |
<type name="gint" c:type="gint"/> | |
</constant> | |
<constant name="VIDEO_COMP2_MASK_15" value="0x03e0"> | |
<type name="utf8" c:type="gchar*"/> | |
</constant> | |
<constant name="VIDEO_COMP2_MASK_15_INT" value="992"> | |
<type name="gint" c:type="gint"/> | |
</constant> | |
<constant name="VIDEO_COMP2_MASK_16" value="0x07e0"> | |
<type name="utf8" c:type="gchar*"/> | |
</constant> | |
<constant name="VIDEO_COMP2_MASK_16_INT" value="2016"> | |
<type name="gint" c:type="gint"/> | |
</constant> | |
<constant name="VIDEO_COMP3_MASK_15" value="0x001f"> | |
<type name="utf8" c:type="gchar*"/> | |
</constant> | |
<constant name="VIDEO_COMP3_MASK_15_INT" value="31"> | |
<type name="gint" c:type="gint"/> | |
</constant> | |
<constant name="VIDEO_COMP3_MASK_16" value="0x001f"> | |
<type name="utf8" c:type="gchar*"/> | |
</constant> | |
<constant name="VIDEO_COMP3_MASK_16_INT" value="31"> | |
<type name="gint" c:type="gint"/> | |
</constant> | |
<constant name="VIDEO_FPS_RANGE" value="(fraction) [ 0, max ]"> | |
<type name="utf8" c:type="gchar*"/> | |
</constant> | |
<constant name="VIDEO_SIZE_RANGE" value="(int) [ 1, max ]"> | |
<type name="utf8" c:type="gchar*"/> | |
</constant> | |
<callback name="VideoConvertFrameCallback" | |
c:type="GstVideoConvertFrameCallback"> | |
<return-value transfer-ownership="none"> | |
<type name="none" c:type="void"/> | |
</return-value> | |
<parameters> | |
<parameter name="buf" transfer-ownership="none"> | |
<type name="Gst.Buffer" c:type="GstBuffer*"/> | |
</parameter> | |
<parameter name="error" transfer-ownership="none"> | |
<type name="GLib.Error" c:type="GError*"/> | |
</parameter> | |
<parameter name="user_data" transfer-ownership="none" closure="2"> | |
<type name="gpointer" c:type="gpointer"/> | |
</parameter> | |
</parameters> | |
</callback> | |
<class name="VideoFilter" | |
c:symbol-prefix="video_filter" | |
c:type="GstVideoFilter" | |
parent="GstBase.BaseTransform" | |
abstract="1" | |
glib:type-name="GstVideoFilter" | |
glib:get-type="gst_video_filter_get_type" | |
glib:type-struct="VideoFilterClass"> | |
<field name="element"> | |
<type name="GstBase.BaseTransform" c:type="GstBaseTransform"/> | |
</field> | |
<field name="inited"> | |
<type name="gboolean" c:type="gboolean"/> | |
</field> | |
</class> | |
<record name="VideoFilterClass" | |
c:type="GstVideoFilterClass" | |
glib:is-gtype-struct-for="VideoFilter"> | |
<field name="parent_class"> | |
<type name="GstBase.BaseTransformClass" | |
c:type="GstBaseTransformClass"/> | |
</field> | |
</record> | |
<enumeration name="VideoFormat" | |
glib:type-name="GstVideoFormat" | |
glib:get-type="gst_video_format_get_type" | |
c:type="GstVideoFormat"> | |
<doc xml:whitespace="preserve">Enum value describing the most common video formats.</doc> | |
<member name="unknown" | |
value="0" | |
c:identifier="GST_VIDEO_FORMAT_UNKNOWN" | |
glib:nick="unknown"/> | |
<member name="i420" | |
value="1" | |
c:identifier="GST_VIDEO_FORMAT_I420" | |
glib:nick="i420"/> | |
<member name="yv12" | |
value="2" | |
c:identifier="GST_VIDEO_FORMAT_YV12" | |
glib:nick="yv12"/> | |
<member name="yuy2" | |
value="3" | |
c:identifier="GST_VIDEO_FORMAT_YUY2" | |
glib:nick="yuy2"/> | |
<member name="uyvy" | |
value="4" | |
c:identifier="GST_VIDEO_FORMAT_UYVY" | |
glib:nick="uyvy"/> | |
<member name="ayuv" | |
value="5" | |
c:identifier="GST_VIDEO_FORMAT_AYUV" | |
glib:nick="ayuv"/> | |
<member name="rgbx" | |
value="6" | |
c:identifier="GST_VIDEO_FORMAT_RGBx" | |
glib:nick="rgbx"/> | |
<member name="bgrx" | |
value="7" | |
c:identifier="GST_VIDEO_FORMAT_BGRx" | |
glib:nick="bgrx"/> | |
<member name="xrgb" | |
value="8" | |
c:identifier="GST_VIDEO_FORMAT_xRGB" | |
glib:nick="xrgb"/> | |
<member name="xbgr" | |
value="9" | |
c:identifier="GST_VIDEO_FORMAT_xBGR" | |
glib:nick="xbgr"/> | |
<member name="rgba" | |
value="10" | |
c:identifier="GST_VIDEO_FORMAT_RGBA" | |
glib:nick="rgba"/> | |
<member name="bgra" | |
value="11" | |
c:identifier="GST_VIDEO_FORMAT_BGRA" | |
glib:nick="bgra"/> | |
<member name="argb" | |
value="12" | |
c:identifier="GST_VIDEO_FORMAT_ARGB" | |
glib:nick="argb"/> | |
<member name="abgr" | |
value="13" | |
c:identifier="GST_VIDEO_FORMAT_ABGR" | |
glib:nick="abgr"/> | |
<member name="rgb" | |
value="14" | |
c:identifier="GST_VIDEO_FORMAT_RGB" | |
glib:nick="rgb"/> | |
<member name="bgr" | |
value="15" | |
c:identifier="GST_VIDEO_FORMAT_BGR" | |
glib:nick="bgr"/> | |
<member name="y41b" | |
value="16" | |
c:identifier="GST_VIDEO_FORMAT_Y41B" | |
glib:nick="y41b"/> | |
<member name="y42b" | |
value="17" | |
c:identifier="GST_VIDEO_FORMAT_Y42B" | |
glib:nick="y42b"/> | |
<member name="yvyu" | |
value="18" | |
c:identifier="GST_VIDEO_FORMAT_YVYU" | |
glib:nick="yvyu"/> | |
<member name="y444" | |
value="19" | |
c:identifier="GST_VIDEO_FORMAT_Y444" | |
glib:nick="y444"/> | |
<member name="v210" | |
value="20" | |
c:identifier="GST_VIDEO_FORMAT_v210" | |
glib:nick="v210"/> | |
<member name="v216" | |
value="21" | |
c:identifier="GST_VIDEO_FORMAT_v216" | |
glib:nick="v216"/> | |
<member name="nv12" | |
value="22" | |
c:identifier="GST_VIDEO_FORMAT_NV12" | |
glib:nick="nv12"/> | |
<member name="nv21" | |
value="23" | |
c:identifier="GST_VIDEO_FORMAT_NV21" | |
glib:nick="nv21"/> | |
<member name="gray8" | |
value="24" | |
c:identifier="GST_VIDEO_FORMAT_GRAY8" | |
glib:nick="gray8"/> | |
<member name="gray16_be" | |
value="25" | |
c:identifier="GST_VIDEO_FORMAT_GRAY16_BE" | |
glib:nick="gray16-be"/> | |
<member name="gray16_le" | |
value="26" | |
c:identifier="GST_VIDEO_FORMAT_GRAY16_LE" | |
glib:nick="gray16-le"/> | |
<member name="v308" | |
value="27" | |
c:identifier="GST_VIDEO_FORMAT_v308" | |
glib:nick="v308"/> | |
<member name="y800" | |
value="28" | |
c:identifier="GST_VIDEO_FORMAT_Y800" | |
glib:nick="y800"/> | |
<member name="y16" | |
value="29" | |
c:identifier="GST_VIDEO_FORMAT_Y16" | |
glib:nick="y16"/> | |
<member name="rgb16" | |
value="30" | |
c:identifier="GST_VIDEO_FORMAT_RGB16" | |
glib:nick="rgb16"/> | |
<member name="bgr16" | |
value="31" | |
c:identifier="GST_VIDEO_FORMAT_BGR16" | |
glib:nick="bgr16"/> | |
<member name="rgb15" | |
value="32" | |
c:identifier="GST_VIDEO_FORMAT_RGB15" | |
glib:nick="rgb15"/> | |
<member name="bgr15" | |
value="33" | |
c:identifier="GST_VIDEO_FORMAT_BGR15" | |
glib:nick="bgr15"/> | |
<member name="uyvp" | |
value="34" | |
c:identifier="GST_VIDEO_FORMAT_UYVP" | |
glib:nick="uyvp"/> | |
<member name="a420" | |
value="35" | |
c:identifier="GST_VIDEO_FORMAT_A420" | |
glib:nick="a420"/> | |
<member name="rgb8_paletted" | |
value="36" | |
c:identifier="GST_VIDEO_FORMAT_RGB8_PALETTED" | |
glib:nick="rgb8-paletted"/> | |
<member name="yuv9" | |
value="37" | |
c:identifier="GST_VIDEO_FORMAT_YUV9" | |
glib:nick="yuv9"/> | |
<member name="yvu9" | |
value="38" | |
c:identifier="GST_VIDEO_FORMAT_YVU9" | |
glib:nick="yvu9"/> | |
<member name="iyu1" | |
value="39" | |
c:identifier="GST_VIDEO_FORMAT_IYU1" | |
glib:nick="iyu1"/> | |
</enumeration> | |
<record name="VideoRectangle" c:type="GstVideoRectangle"> | |
<doc xml:whitespace="preserve">Helper structure representing a rectangular area.</doc> | |
<field name="x" writable="1"> | |
<type name="gint" c:type="gint"/> | |
</field> | |
<field name="y" writable="1"> | |
<type name="gint" c:type="gint"/> | |
</field> | |
<field name="w" writable="1"> | |
<type name="gint" c:type="gint"/> | |
</field> | |
<field name="h" writable="1"> | |
<type name="gint" c:type="gint"/> | |
</field> | |
</record> | |
<class name="VideoSink" | |
c:symbol-prefix="video_sink" | |
c:type="GstVideoSink" | |
parent="GstBase.BaseSink" | |
glib:type-name="GstVideoSink" | |
glib:get-type="gst_video_sink_get_type" | |
glib:type-struct="VideoSinkClass"> | |
<doc xml:whitespace="preserve">The video sink instance structure. Derived video sinks should set the</doc> | |
<function name="center_rect" c:identifier="gst_video_sink_center_rect"> | |
<doc xml:whitespace="preserve">Takes @src rectangle and position it at the center of @dst rectangle with or | |
without @scaling. It handles clipping if the @src rectangle is bigger than | |
the @dst one and @scaling is set to FALSE.</doc> | |
<return-value transfer-ownership="none"> | |
<type name="none" c:type="void"/> | |
</return-value> | |
<parameters> | |
<parameter name="src" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the #GstVideoRectangle describing the source area</doc> | |
<type name="VideoRectangle" c:type="GstVideoRectangle"/> | |
</parameter> | |
<parameter name="dst" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the #GstVideoRectangle describing the destination area</doc> | |
<type name="VideoRectangle" c:type="GstVideoRectangle"/> | |
</parameter> | |
<parameter name="result" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a pointer to a #GstVideoRectangle which will receive the result area</doc> | |
<type name="VideoRectangle" c:type="GstVideoRectangle*"/> | |
</parameter> | |
<parameter name="scaling" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a #gboolean indicating if scaling should be applied or not</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</parameter> | |
</parameters> | |
</function> | |
<virtual-method name="show_frame"> | |
<return-value transfer-ownership="none"> | |
<type name="Gst.FlowReturn" c:type="GstFlowReturn"/> | |
</return-value> | |
<parameters> | |
<parameter name="buf" transfer-ownership="none"> | |
<type name="Gst.Buffer" c:type="GstBuffer*"/> | |
</parameter> | |
</parameters> | |
</virtual-method> | |
<property name="show-preroll-frame" | |
writable="1" | |
construct="1" | |
transfer-ownership="none"> | |
<type name="gboolean"/> | |
</property> | |
<field name="element"> | |
<type name="GstBase.BaseSink" c:type="GstBaseSink"/> | |
</field> | |
<field name="width"> | |
<type name="gint" c:type="gint"/> | |
</field> | |
<field name="height"> | |
<type name="gint" c:type="gint"/> | |
</field> | |
<field name="priv"> | |
<type name="VideoSinkPrivate" c:type="GstVideoSinkPrivate*"/> | |
</field> | |
<field name="_gst_reserved"> | |
<array zero-terminated="0" c:type="gpointer" fixed-size="3"> | |
<type name="gpointer" c:type="gpointer"/> | |
</array> | |
</field> | |
</class> | |
<record name="VideoSinkClass" | |
c:type="GstVideoSinkClass" | |
glib:is-gtype-struct-for="VideoSink"> | |
<doc xml:whitespace="preserve">The video sink class structure. Derived classes should override the</doc> | |
<field name="parent_class"> | |
<type name="GstBase.BaseSinkClass" c:type="GstBaseSinkClass"/> | |
</field> | |
<field name="show_frame"> | |
<callback name="show_frame"> | |
<return-value transfer-ownership="none"> | |
<type name="Gst.FlowReturn" c:type="GstFlowReturn"/> | |
</return-value> | |
<parameters> | |
<parameter name="video_sink" transfer-ownership="none"> | |
<type name="VideoSink" c:type="GstVideoSink*"/> | |
</parameter> | |
<parameter name="buf" transfer-ownership="none"> | |
<type name="Gst.Buffer" c:type="GstBuffer*"/> | |
</parameter> | |
</parameters> | |
</callback> | |
</field> | |
<field name="_gst_reserved"> | |
<array zero-terminated="0" c:type="gpointer" fixed-size="3"> | |
<type name="gpointer" c:type="gpointer"/> | |
</array> | |
</field> | |
</record> | |
<record name="VideoSinkPrivate" c:type="GstVideoSinkPrivate" disguised="1"> | |
</record> | |
<function name="video_calculate_display_ratio" | |
c:identifier="gst_video_calculate_display_ratio" | |
version="0.10.7"> | |
<doc xml:whitespace="preserve">Given the Pixel Aspect Ratio and size of an input video frame, and the | |
pixel aspect ratio of the intended display device, calculates the actual | |
display ratio the video will be rendered with. | |
dar_n and dar_d parameters. | |
The return value is FALSE in the case of integer overflow or other error.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">A boolean indicating success and a calculated Display Ratio in the</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</return-value> | |
<parameters> | |
<parameter name="dar_n" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">Numerator of the calculated display_ratio</doc> | |
<type name="guint" c:type="guint*"/> | |
</parameter> | |
<parameter name="dar_d" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">Denominator of the calculated display_ratio</doc> | |
<type name="guint" c:type="guint*"/> | |
</parameter> | |
<parameter name="video_width" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">Width of the video frame in pixels</doc> | |
<type name="guint" c:type="guint"/> | |
</parameter> | |
<parameter name="video_height" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">Height of the video frame in pixels</doc> | |
<type name="guint" c:type="guint"/> | |
</parameter> | |
<parameter name="video_par_n" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">Numerator of the pixel aspect ratio of the input video.</doc> | |
<type name="guint" c:type="guint"/> | |
</parameter> | |
<parameter name="video_par_d" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">Denominator of the pixel aspect ratio of the input video.</doc> | |
<type name="guint" c:type="guint"/> | |
</parameter> | |
<parameter name="display_par_n" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">Numerator of the pixel aspect ratio of the display device</doc> | |
<type name="guint" c:type="guint"/> | |
</parameter> | |
<parameter name="display_par_d" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">Denominator of the pixel aspect ratio of the display device</doc> | |
<type name="guint" c:type="guint"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="video_convert_frame" | |
c:identifier="gst_video_convert_frame" | |
version="0.10.31" | |
introspectable="0" | |
throws="1"> | |
<doc xml:whitespace="preserve">Converts a raw video buffer into the specified output caps. | |
The output caps can be any raw video formats or any image formats (jpeg, png, ...). | |
The width, height and pixel-aspect-ratio can also be specified in the output caps. | |
will point to the #GError).</doc> | |
<return-value> | |
<doc xml:whitespace="preserve">The converted #GstBuffer, or %NULL if an error happened (in which case @err</doc> | |
<type name="Gst.Buffer" c:type="GstBuffer*"/> | |
</return-value> | |
<parameters> | |
<parameter name="buf" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a #GstBuffer</doc> | |
<type name="Gst.Buffer" c:type="GstBuffer*"/> | |
</parameter> | |
<parameter name="to_caps" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the #GstCaps to convert to</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</parameter> | |
<parameter name="timeout" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the maximum amount of time allowed for the processing.</doc> | |
<type name="Gst.ClockTime" c:type="GstClockTime"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="video_convert_frame_async" | |
c:identifier="gst_video_convert_frame_async" | |
version="0.10.31"> | |
<doc xml:whitespace="preserve">Converts a raw video buffer into the specified output caps. | |
The output caps can be any raw video formats or any image formats (jpeg, png, ...). | |
The width, height and pixel-aspect-ratio can also be specified in the output caps. | |
finish after @timeout. @callback will always be called from the thread default | |
%GMainContext, see g_main_context_get_thread_default(). If GLib before 2.22 is used, | |
this will always be the global default main context. | |
anymore.</doc> | |
<return-value transfer-ownership="none"> | |
<type name="none" c:type="void"/> | |
</return-value> | |
<parameters> | |
<parameter name="buf" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a #GstBuffer</doc> | |
<type name="Gst.Buffer" c:type="GstBuffer*"/> | |
</parameter> | |
<parameter name="to_caps" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the #GstCaps to convert to</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</parameter> | |
<parameter name="timeout" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the maximum amount of time allowed for the processing.</doc> | |
<type name="Gst.ClockTime" c:type="GstClockTime"/> | |
</parameter> | |
<parameter name="callback" | |
transfer-ownership="none" | |
scope="notified" | |
closure="4" | |
destroy="5"> | |
<doc xml:whitespace="preserve">%GstVideoConvertFrameCallback that will be called after conversion.</doc> | |
<type name="VideoConvertFrameCallback" | |
c:type="GstVideoConvertFrameCallback"/> | |
</parameter> | |
<parameter name="user_data" transfer-ownership="none"> | |
<type name="gpointer" c:type="gpointer"/> | |
</parameter> | |
<parameter name="destroy_notify" | |
transfer-ownership="none" | |
scope="async"> | |
<doc xml:whitespace="preserve">%GDestroyNotify to be called after @user_data is not needed anymore</doc> | |
<type name="GLib.DestroyNotify" c:type="GDestroyNotify"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="video_event_new_still_frame" | |
c:identifier="gst_video_event_new_still_frame" | |
version="0.10.26" | |
introspectable="0"> | |
<doc xml:whitespace="preserve">Creates a new Still Frame event. If @in_still is %TRUE, then the event | |
represents the start of a still frame sequence. If it is %FALSE, then | |
the event ends a still frame sequence. | |
To parse an event created by gst_video_event_new_still_frame() use | |
gst_video_event_parse_still_frame().</doc> | |
<return-value> | |
<doc xml:whitespace="preserve">The new GstEvent</doc> | |
<type name="Gst.Event" c:type="GstEvent*"/> | |
</return-value> | |
<parameters> | |
<parameter name="in_still" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">boolean value for the still-frame state of the event.</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="video_event_parse_still_frame" | |
c:identifier="gst_video_event_parse_still_frame" | |
version="0.10.26"> | |
<doc xml:whitespace="preserve">Parse a #GstEvent, identify if it is a Still Frame event, and | |
return the still-frame state from the event if it is. | |
If the event represents the start of a still frame, the in_still | |
variable will be set to TRUE, otherwise FALSE. It is OK to pass NULL for the | |
in_still variable order to just check whether the event is a valid still-frame | |
event. | |
Create a still frame event using gst_video_event_new_still_frame()</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">%TRUE if the event is a valid still-frame event. %FALSE if not</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</return-value> | |
<parameters> | |
<parameter name="event" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">A #GstEvent to parse</doc> | |
<type name="Gst.Event" c:type="GstEvent*"/> | |
</parameter> | |
<parameter name="in_still" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">A boolean to receive the still-frame status from the event, or NULL</doc> | |
<type name="gboolean" c:type="gboolean*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="video_format_convert" | |
c:identifier="gst_video_format_convert" | |
version="0.10.16"> | |
<doc xml:whitespace="preserve">Converts among various #GstFormat types. This function handles | |
GST_FORMAT_BYTES, GST_FORMAT_TIME, and GST_FORMAT_DEFAULT. For | |
raw video, GST_FORMAT_DEFAULT corresponds to video frames. This | |
function can be to handle pad queries of the type GST_QUERY_CONVERT.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">TRUE if the conversion was successful.</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</return-value> | |
<parameters> | |
<parameter name="format" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a #GstVideoFormat</doc> | |
<type name="VideoFormat" c:type="GstVideoFormat"/> | |
</parameter> | |
<parameter name="width" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the width of video</doc> | |
<type name="gint" c:type="int"/> | |
</parameter> | |
<parameter name="height" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the height of video</doc> | |
<type name="gint" c:type="int"/> | |
</parameter> | |
<parameter name="fps_n" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">frame rate numerator</doc> | |
<type name="gint" c:type="int"/> | |
</parameter> | |
<parameter name="fps_d" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">frame rate denominator</doc> | |
<type name="gint" c:type="int"/> | |
</parameter> | |
<parameter name="src_format" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">#GstFormat of the @src_value</doc> | |
<type name="Gst.Format" c:type="GstFormat"/> | |
</parameter> | |
<parameter name="src_value" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">value to convert</doc> | |
<type name="gint64" c:type="gint64"/> | |
</parameter> | |
<parameter name="dest_format" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">#GstFormat of the @dest_value</doc> | |
<type name="Gst.Format" c:type="GstFormat"/> | |
</parameter> | |
<parameter name="dest_value" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">pointer to destination value</doc> | |
<type name="gint64" c:type="gint64*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="video_format_from_fourcc" | |
c:identifier="gst_video_format_from_fourcc" | |
version="0.10.16"> | |
<doc xml:whitespace="preserve">Converts a FOURCC value into the corresponding #GstVideoFormat. | |
If the FOURCC cannot be represented by #GstVideoFormat, | |
#GST_VIDEO_FORMAT_UNKNOWN is returned.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the #GstVideoFormat describing the FOURCC value</doc> | |
<type name="VideoFormat" c:type="GstVideoFormat"/> | |
</return-value> | |
<parameters> | |
<parameter name="fourcc" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a FOURCC value representing raw YUV video</doc> | |
<type name="guint32" c:type="guint32"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="video_format_get_component_height" | |
c:identifier="gst_video_format_get_component_height" | |
version="0.10.16"> | |
<doc xml:whitespace="preserve">Calculates the height of the component. See | |
of the component index.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">height of component @component</doc> | |
<type name="gint" c:type="int"/> | |
</return-value> | |
<parameters> | |
<parameter name="format" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a #GstVideoFormat</doc> | |
<type name="VideoFormat" c:type="GstVideoFormat"/> | |
</parameter> | |
<parameter name="component" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the component index</doc> | |
<type name="gint" c:type="int"/> | |
</parameter> | |
<parameter name="height" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the height of video</doc> | |
<type name="gint" c:type="int"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="video_format_get_component_offset" | |
c:identifier="gst_video_format_get_component_offset" | |
version="0.10.16"> | |
<doc xml:whitespace="preserve">Calculates the offset (in bytes) of the first pixel of the component | |
with index @component. For packed formats, this will typically be a | |
small integer (0, 1, 2, 3). For planar formats, this will be a | |
(relatively) large offset to the beginning of the second or third | |
component planes. See @gst_video_format_get_row_stride for a description | |
of the component index.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">offset of component @component</doc> | |
<type name="gint" c:type="int"/> | |
</return-value> | |
<parameters> | |
<parameter name="format" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a #GstVideoFormat</doc> | |
<type name="VideoFormat" c:type="GstVideoFormat"/> | |
</parameter> | |
<parameter name="component" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the component index</doc> | |
<type name="gint" c:type="int"/> | |
</parameter> | |
<parameter name="width" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the width of video</doc> | |
<type name="gint" c:type="int"/> | |
</parameter> | |
<parameter name="height" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the height of video</doc> | |
<type name="gint" c:type="int"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="video_format_get_component_width" | |
c:identifier="gst_video_format_get_component_width" | |
version="0.10.16"> | |
<doc xml:whitespace="preserve">Calculates the width of the component. See | |
of the component index.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">width of component @component</doc> | |
<type name="gint" c:type="int"/> | |
</return-value> | |
<parameters> | |
<parameter name="format" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a #GstVideoFormat</doc> | |
<type name="VideoFormat" c:type="GstVideoFormat"/> | |
</parameter> | |
<parameter name="component" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the component index</doc> | |
<type name="gint" c:type="int"/> | |
</parameter> | |
<parameter name="width" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the width of video</doc> | |
<type name="gint" c:type="int"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="video_format_get_pixel_stride" | |
c:identifier="gst_video_format_get_pixel_stride" | |
version="0.10.16"> | |
<doc xml:whitespace="preserve">Calculates the pixel stride (number of bytes from one pixel to the | |
pixel to its immediate left) for the video component with an index | |
of @component. See @gst_video_format_get_row_stride for a description | |
of the component index.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">pixel stride of component @component</doc> | |
<type name="gint" c:type="int"/> | |
</return-value> | |
<parameters> | |
<parameter name="format" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a #GstVideoFormat</doc> | |
<type name="VideoFormat" c:type="GstVideoFormat"/> | |
</parameter> | |
<parameter name="component" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the component index</doc> | |
<type name="gint" c:type="int"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="video_format_get_row_stride" | |
c:identifier="gst_video_format_get_row_stride" | |
version="0.10.16"> | |
<doc xml:whitespace="preserve">Calculates the row stride (number of bytes from one row of pixels to | |
the next) for the video component with an index of @component. For | |
YUV video, Y, U, and V have component indices of 0, 1, and 2, | |
respectively. For RGB video, R, G, and B have component indicies of | |
0, 1, and 2, respectively. Alpha channels, if present, have a component | |
index of 3. The @width parameter always represents the width of the | |
video, not the component.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">row stride of component @component</doc> | |
<type name="gint" c:type="int"/> | |
</return-value> | |
<parameters> | |
<parameter name="format" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a #GstVideoFormat</doc> | |
<type name="VideoFormat" c:type="GstVideoFormat"/> | |
</parameter> | |
<parameter name="component" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the component index</doc> | |
<type name="gint" c:type="int"/> | |
</parameter> | |
<parameter name="width" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the width of video</doc> | |
<type name="gint" c:type="int"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="video_format_get_size" | |
c:identifier="gst_video_format_get_size" | |
version="0.10.16"> | |
<doc xml:whitespace="preserve">Calculates the total number of bytes in the raw video format. This | |
number should be used when allocating a buffer for raw video.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">size (in bytes) of raw video format</doc> | |
<type name="gint" c:type="int"/> | |
</return-value> | |
<parameters> | |
<parameter name="format" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a #GstVideoFormat</doc> | |
<type name="VideoFormat" c:type="GstVideoFormat"/> | |
</parameter> | |
<parameter name="width" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the width of video</doc> | |
<type name="gint" c:type="int"/> | |
</parameter> | |
<parameter name="height" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the height of video</doc> | |
<type name="gint" c:type="int"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="video_format_has_alpha" | |
c:identifier="gst_video_format_has_alpha" | |
version="0.10.16"> | |
<doc xml:whitespace="preserve">Returns TRUE or FALSE depending on if the video format provides an | |
alpha channel.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">TRUE if @format has an alpha channel</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</return-value> | |
<parameters> | |
<parameter name="format" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a #GstVideoFormat</doc> | |
<type name="VideoFormat" c:type="GstVideoFormat"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="video_format_is_gray" | |
c:identifier="gst_video_format_is_gray" | |
version="0.10.29"> | |
<doc xml:whitespace="preserve">Determine whether the video format is a grayscale format.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">TRUE if @format represents grayscale video</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</return-value> | |
<parameters> | |
<parameter name="format" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a #GstVideoFormat</doc> | |
<type name="VideoFormat" c:type="GstVideoFormat"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="video_format_is_rgb" | |
c:identifier="gst_video_format_is_rgb" | |
version="0.10.16"> | |
<doc xml:whitespace="preserve">Determine whether the video format is an RGB format.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">TRUE if @format represents RGB video</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</return-value> | |
<parameters> | |
<parameter name="format" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a #GstVideoFormat</doc> | |
<type name="VideoFormat" c:type="GstVideoFormat"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="video_format_is_yuv" | |
c:identifier="gst_video_format_is_yuv" | |
version="0.10.16"> | |
<doc xml:whitespace="preserve">Determine whether the video format is a YUV format.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">TRUE if @format represents YUV video</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</return-value> | |
<parameters> | |
<parameter name="format" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a #GstVideoFormat</doc> | |
<type name="VideoFormat" c:type="GstVideoFormat"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="video_format_new_caps" | |
c:identifier="gst_video_format_new_caps" | |
version="0.10.16"> | |
<doc xml:whitespace="preserve">Creates a new #GstCaps object based on the parameters provided.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">a new #GstCaps object, or NULL if there was an error</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</return-value> | |
<parameters> | |
<parameter name="format" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the #GstVideoFormat describing the raw video format</doc> | |
<type name="VideoFormat" c:type="GstVideoFormat"/> | |
</parameter> | |
<parameter name="width" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">width of video</doc> | |
<type name="gint" c:type="int"/> | |
</parameter> | |
<parameter name="height" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">height of video</doc> | |
<type name="gint" c:type="int"/> | |
</parameter> | |
<parameter name="framerate_n" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">numerator of frame rate</doc> | |
<type name="gint" c:type="int"/> | |
</parameter> | |
<parameter name="framerate_d" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">denominator of frame rate</doc> | |
<type name="gint" c:type="int"/> | |
</parameter> | |
<parameter name="par_n" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">numerator of pixel aspect ratio</doc> | |
<type name="gint" c:type="int"/> | |
</parameter> | |
<parameter name="par_d" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">denominator of pixel aspect ratio</doc> | |
<type name="gint" c:type="int"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="video_format_new_caps_interlaced" | |
c:identifier="gst_video_format_new_caps_interlaced" | |
version="0.10.23"> | |
<doc xml:whitespace="preserve">Creates a new #GstCaps object based on the parameters provided.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">a new #GstCaps object, or NULL if there was an error</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</return-value> | |
<parameters> | |
<parameter name="format" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the #GstVideoFormat describing the raw video format</doc> | |
<type name="VideoFormat" c:type="GstVideoFormat"/> | |
</parameter> | |
<parameter name="width" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">width of video</doc> | |
<type name="gint" c:type="int"/> | |
</parameter> | |
<parameter name="height" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">height of video</doc> | |
<type name="gint" c:type="int"/> | |
</parameter> | |
<parameter name="framerate_n" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">numerator of frame rate</doc> | |
<type name="gint" c:type="int"/> | |
</parameter> | |
<parameter name="framerate_d" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">denominator of frame rate</doc> | |
<type name="gint" c:type="int"/> | |
</parameter> | |
<parameter name="par_n" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">numerator of pixel aspect ratio</doc> | |
<type name="gint" c:type="int"/> | |
</parameter> | |
<parameter name="par_d" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">denominator of pixel aspect ratio</doc> | |
<type name="gint" c:type="int"/> | |
</parameter> | |
<parameter name="interlaced" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">#TRUE if the format is interlaced</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="video_format_parse_caps" | |
c:identifier="gst_video_format_parse_caps" | |
version="0.10.16"> | |
<doc xml:whitespace="preserve">Determines the #GstVideoFormat of @caps and places it in the location | |
pointed to by @format. Extracts the size of the video and places it | |
in the location pointed to by @width and @height. If @caps does not | |
represent one of the raw video formats listed in #GstVideoFormat, the | |
function will fail and return FALSE.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">TRUE if @caps was parsed correctly.</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</return-value> | |
<parameters> | |
<parameter name="caps" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the #GstCaps to parse</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</parameter> | |
<parameter name="format" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the #GstVideoFormat of the video represented by @caps (output)</doc> | |
<type name="VideoFormat" c:type="GstVideoFormat*"/> | |
</parameter> | |
<parameter name="width" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the width of the video represented by @caps, may be NULL (output)</doc> | |
<type name="gint" c:type="int*"/> | |
</parameter> | |
<parameter name="height" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the height of the video represented by @caps, may be NULL (output)</doc> | |
<type name="gint" c:type="int*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="video_format_parse_caps_interlaced" | |
c:identifier="gst_video_format_parse_caps_interlaced" | |
version="0.10.23"> | |
<doc xml:whitespace="preserve">Extracts whether the caps represents interlaced content or not and places it | |
in @interlaced.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">TRUE if @caps was parsed correctly.</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</return-value> | |
<parameters> | |
<parameter name="caps" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the fixed #GstCaps to parse</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</parameter> | |
<parameter name="interlaced" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">whether @caps represents interlaced video or not, may be NULL (output)</doc> | |
<type name="gboolean" c:type="gboolean*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="video_format_to_fourcc" | |
c:identifier="gst_video_format_to_fourcc" | |
version="0.10.16"> | |
<doc xml:whitespace="preserve">Converts a #GstVideoFormat value into the corresponding FOURCC. Only | |
a few YUV formats have corresponding FOURCC values. If @format has | |
no corresponding FOURCC value, 0 is returned.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the FOURCC corresponding to @format</doc> | |
<type name="guint32" c:type="guint32"/> | |
</return-value> | |
<parameters> | |
<parameter name="format" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a #GstVideoFormat video format</doc> | |
<type name="VideoFormat" c:type="GstVideoFormat"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="video_frame_rate" c:identifier="gst_video_frame_rate"> | |
<doc xml:whitespace="preserve">A convenience function to retrieve a GValue holding the framerate | |
from the caps on a pad. | |
The pad needs to have negotiated caps containing a framerate property. | |
do not contain a framerate.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">NULL if the pad has no configured caps or the configured caps</doc> | |
<type name="GObject.Value" c:type="GValue*"/> | |
</return-value> | |
<parameters> | |
<parameter name="pad" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">pointer to a #GstPad</doc> | |
<type name="Gst.Pad" c:type="GstPad*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="video_get_size" c:identifier="gst_video_get_size"> | |
<doc xml:whitespace="preserve">Inspect the caps of the provided pad and retrieve the width and height of | |
the video frames it is configured for. | |
The pad needs to have negotiated caps containing width and height properties.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">TRUE if the width and height could be retrieved.</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</return-value> | |
<parameters> | |
<parameter name="pad" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">pointer to a #GstPad</doc> | |
<type name="Gst.Pad" c:type="GstPad*"/> | |
</parameter> | |
<parameter name="width" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">pointer to integer to hold pixel width of the video frames (output)</doc> | |
<type name="gint" c:type="gint*"/> | |
</parameter> | |
<parameter name="height" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">pointer to integer to hold pixel height of the video frames (output)</doc> | |
<type name="gint" c:type="gint*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="video_parse_caps_chroma_site" | |
c:identifier="gst_video_parse_caps_chroma_site" | |
version="0.10.29"> | |
<doc xml:whitespace="preserve">Extracts the chroma site used by the caps. Possible values are | |
"mpeg2" for MPEG-2 style chroma siting (co-sited horizontally, | |
halfway-sited vertically), "jpeg" for JPEG and Theora style | |
chroma siting (halfway-sited both horizontally and vertically). | |
Other chroma site values are possible, but uncommon. | |
When no chroma site is specified in the caps, it should be assumed | |
to be "mpeg2". | |
determined.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a chroma site string, or NULL if no chroma site could be</doc> | |
<type name="utf8" c:type="char*"/> | |
</return-value> | |
<parameters> | |
<parameter name="caps" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the fixed #GstCaps to parse</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="video_parse_caps_color_matrix" | |
c:identifier="gst_video_parse_caps_color_matrix" | |
version="0.10.29"> | |
<doc xml:whitespace="preserve">Extracts the color matrix used by the caps. Possible values are | |
"sdtv" for the standard definition color matrix (as specified in | |
Rec. ITU-R BT.470-6) or "hdtv" for the high definition color | |
matrix (as specified in Rec. ITU-R BT.709) | |
determined.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a color matrix string, or NULL if no color matrix could be</doc> | |
<type name="utf8" c:type="char*"/> | |
</return-value> | |
<parameters> | |
<parameter name="caps" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the fixed #GstCaps to parse</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="video_parse_caps_framerate" | |
c:identifier="gst_video_parse_caps_framerate" | |
version="0.10.16"> | |
<doc xml:whitespace="preserve">Extracts the frame rate from @caps and places the values in the locations | |
pointed to by @fps_n and @fps_d. Returns TRUE if the values could be | |
parsed correctly, FALSE if not. | |
This function can be used with #GstCaps that have any media type; it | |
is not limited to formats handled by #GstVideoFormat.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">TRUE if @caps was parsed correctly.</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</return-value> | |
<parameters> | |
<parameter name="caps" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">pointer to a #GstCaps instance</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</parameter> | |
<parameter name="fps_n" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">pointer to integer to hold numerator of frame rate (output)</doc> | |
<type name="gint" c:type="int*"/> | |
</parameter> | |
<parameter name="fps_d" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">pointer to integer to hold denominator of frame rate (output)</doc> | |
<type name="gint" c:type="int*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="video_parse_caps_palette" | |
c:identifier="gst_video_parse_caps_palette" | |
version="0.10.32" | |
introspectable="0"> | |
<doc xml:whitespace="preserve">Returns the palette data from the caps as a #GstBuffer. For | |
#GST_VIDEO_FORMAT_RGB8_PALETTED this is containing 256 #guint32 | |
values, each containing ARGB colors in native endianness.</doc> | |
<return-value> | |
<doc xml:whitespace="preserve">a #GstBuffer containing the palette data. Unref after usage.</doc> | |
<type name="Gst.Buffer" c:type="GstBuffer*"/> | |
</return-value> | |
<parameters> | |
<parameter name="caps" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">#GstCaps to parse</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</parameter> | |
</parameters> | |
</function> | |
<function name="video_parse_caps_pixel_aspect_ratio" | |
c:identifier="gst_video_parse_caps_pixel_aspect_ratio" | |
version="0.10.16"> | |
<doc xml:whitespace="preserve">Extracts the pixel aspect ratio from @caps and places the values in | |
the locations pointed to by @par_n and @par_d. Returns TRUE if the | |
values could be parsed correctly, FALSE if not. | |
This function can be used with #GstCaps that have any media type; it | |
is not limited to formats handled by #GstVideoFormat.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">TRUE if @caps was parsed correctly.</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</return-value> | |
<parameters> | |
<parameter name="caps" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">pointer to a #GstCaps instance</doc> | |
<type name="Gst.Caps" c:type="GstCaps*"/> | |
</parameter> | |
<parameter name="par_n" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">pointer to numerator of pixel aspect ratio (output)</doc> | |
<type name="gint" c:type="int*"/> | |
</parameter> | |
<parameter name="par_d" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">pointer to denominator of pixel aspect ratio (output)</doc> | |
<type name="gint" c:type="int*"/> | |
</parameter> | |
</parameters> | |
</function> | |
</namespace> | |
</repository> | |
]] | |
FILE: [[gstreamer/plugins/video/video.factor]] [[! Copyright (C) 2010 Anton Gorenko. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: gstreamer.video.ffi ; | |
IN: gstreamer.video | |
]] | |
FILE: [[gstreamer/plugins/video/ffi/ffi.factor]] [[! Copyright (C) 2010 Anton Gorenko. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: alien alien.c-types alien.libraries combinators kernel | |
system | |
gobject-introspection glib.ffi gobject.ffi gstreamer.ffi ; | |
IN: gstreamer.video.ffi | |
<< | |
"gstreamer.video" { | |
{ [ os winnt? ] [ drop ] } | |
{ [ os macosx? ] [ drop ] } | |
{ [ os unix? ] [ "libgstvideo-0.10.so" cdecl add-library ] } | |
} cond | |
>> | |
IMPLEMENT-STRUCTS: GstVideoRectangle ; | |
GIR: vocab:gstreamer/video/GstVideo-0.10.gir | |
]] | |
FILE: [[gstreamer/plugins/rtsp/rtsp.factor]] [[! Copyright (C) 2010 Anton Gorenko. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: gstreamer.rtsp.ffi ; | |
IN: gstreamer.rtsp | |
]] | |
FILE: [[gstreamer/plugins/rtsp/ffi/ffi.factor]] [[! Copyright (C) 2010 Anton Gorenko. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: alien alien.syntax alien.libraries combinators kernel | |
system | |
gobject-introspection glib.ffi gstreamer.ffi gstreamer.sdp.ffi ; | |
IN: gstreamer.rtsp.ffi | |
<< | |
"gstreamer.rtsp" { | |
{ [ os winnt? ] [ drop ] } | |
{ [ os macosx? ] [ drop ] } | |
{ [ os unix? ] [ "libgstrtsp-0.10.so" cdecl add-library ] } | |
} cond | |
>> | |
! git error (there is _GstRTSPTransport only in .gir) | |
C-TYPE: GstRTSPTransport | |
GIR: vocab:gstreamer/rtsp/GstRtsp-0.10.gir | |
]] | |
FILE: [[gstreamer/plugins/rtsp/GstRtsp-0.10.gir]] [[<?xml version="1.0"?> | |
<!-- This file was automatically generated from C sources - DO NOT EDIT! | |
To affect the contents of this file, edit the original C definitions, | |
and/or use gtk-doc annotations. --> | |
<repository version="1.2" | |
xmlns="http://www.gtk.org/introspection/core/1.0" | |
xmlns:c="http://www.gtk.org/introspection/c/1.0" | |
xmlns:glib="http://www.gtk.org/introspection/glib/1.0"> | |
<include name="GLib" version="2.0"/> | |
<include name="GModule" version="2.0"/> | |
<include name="GObject" version="2.0"/> | |
<include name="Gst" version="0.10"/> | |
<include name="GstSdp" version="0.10"/> | |
<include name="libxml2" version="2.0"/> | |
<package name="gstreamer-rtsp-0.10"/> | |
<c:include name="gst/audio/gstrtsp-enumtypes.h"/> | |
<c:include name="gst/audio/gstrtspbase64.h"/> | |
<c:include name="gst/audio/gstrtspconnection.h"/> | |
<c:include name="gst/audio/gstrtspdefs.h"/> | |
<c:include name="gst/audio/gstrtspextension.h"/> | |
<c:include name="gst/audio/gstrtspmessage.h"/> | |
<c:include name="gst/audio/gstrtsprange.h"/> | |
<c:include name="gst/audio/gstrtsptransport.h"/> | |
<c:include name="gst/audio/gstrtspurl.h"/> | |
<namespace name="GstRtsp" | |
version="0.10" | |
shared-library="libgstrtsp-0.10.so.0" | |
c:identifier-prefixes="Gst" | |
c:symbol-prefixes="gst"> | |
<enumeration name="RTSPAuthMethod" | |
glib:type-name="GstRTSPAuthMethod" | |
glib:get-type="gst_rtsp_auth_method_get_type" | |
c:type="GstRTSPAuthMethod"> | |
<doc xml:whitespace="preserve">Authentication methods, ordered by strength</doc> | |
<member name="none" | |
value="0" | |
c:identifier="GST_RTSP_AUTH_NONE" | |
glib:nick="none"/> | |
<member name="basic" | |
value="1" | |
c:identifier="GST_RTSP_AUTH_BASIC" | |
glib:nick="basic"/> | |
<member name="digest" | |
value="2" | |
c:identifier="GST_RTSP_AUTH_DIGEST" | |
glib:nick="digest"/> | |
</enumeration> | |
<record name="RTSPConnection" c:type="GstRTSPConnection" disguised="1"> | |
<doc xml:whitespace="preserve">Opaque RTSP connection object.</doc> | |
<method name="clear_auth_params" | |
c:identifier="gst_rtsp_connection_clear_auth_params" | |
version="0.10.20"> | |
<doc xml:whitespace="preserve">Clear the list of authentication directives stored in @conn.</doc> | |
<return-value transfer-ownership="none"> | |
<type name="none" c:type="void"/> | |
</return-value> | |
</method> | |
<method name="close" c:identifier="gst_rtsp_connection_close"> | |
<doc xml:whitespace="preserve">Close the connected @conn. After this call, the connection is in the same | |
state as when it was first created.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">#GST_RTSP_OK on success.</doc> | |
<type name="RTSPResult" c:type="GstRTSPResult"/> | |
</return-value> | |
</method> | |
<method name="connect" c:identifier="gst_rtsp_connection_connect"> | |
<doc xml:whitespace="preserve">Attempt to connect to the url of @conn made with | |
gst_rtsp_connection_create(). If @timeout is #NULL this function can block | |
forever. If @timeout contains a valid timeout, this function will return | |
#GST_RTSP_ETIMEOUT after the timeout expired. | |
This function can be cancelled with gst_rtsp_connection_flush().</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">#GST_RTSP_OK when a connection could be made.</doc> | |
<type name="RTSPResult" c:type="GstRTSPResult"/> | |
</return-value> | |
<parameters> | |
<parameter name="timeout" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a #GTimeVal timeout</doc> | |
<type name="GLib.TimeVal" c:type="GTimeVal*"/> | |
</parameter> | |
</parameters> | |
</method> | |
<method name="do_tunnel" | |
c:identifier="gst_rtsp_connection_do_tunnel" | |
version="0.10.23"> | |
<doc xml:whitespace="preserve">If @conn received the first tunnel connection and @conn2 received | |
the second tunnel connection, link the two connections together so that | |
After this call, @conn2 cannot be used anymore and must be freed with | |
gst_rtsp_connection_free(). | |
If @conn2 is %NULL then only the base64 decoding context will be setup for</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">return GST_RTSP_OK on success.</doc> | |
<type name="RTSPResult" c:type="GstRTSPResult"/> | |
</return-value> | |
<parameters> | |
<parameter name="conn2" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a #GstRTSPConnection or %NULL</doc> | |
<type name="RTSPConnection" c:type="GstRTSPConnection*"/> | |
</parameter> | |
</parameters> | |
</method> | |
<method name="flush" c:identifier="gst_rtsp_connection_flush"> | |
<doc xml:whitespace="preserve">Start or stop the flushing action on @conn. When flushing, all current | |
and future actions on @conn will return #GST_RTSP_EINTR until the connection | |
is set to non-flushing mode again.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">#GST_RTSP_OK.</doc> | |
<type name="RTSPResult" c:type="GstRTSPResult"/> | |
</return-value> | |
<parameters> | |
<parameter name="flush" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">start or stop the flush</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</parameter> | |
</parameters> | |
</method> | |
<method name="free" c:identifier="gst_rtsp_connection_free"> | |
<doc xml:whitespace="preserve">Close and free @conn.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">#GST_RTSP_OK on success.</doc> | |
<type name="RTSPResult" c:type="GstRTSPResult"/> | |
</return-value> | |
</method> | |
<method name="get_ip" | |
c:identifier="gst_rtsp_connection_get_ip" | |
version="0.10.20"> | |
<doc xml:whitespace="preserve">Retrieve the IP address of the other end of @conn. | |
connection is closed.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">The IP address as a string. this value remains valid until the</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</return-value> | |
</method> | |
<method name="get_readfd" | |
c:identifier="gst_rtsp_connection_get_readfd" | |
version="0.10.23"> | |
<doc xml:whitespace="preserve">Get the file descriptor for reading. | |
descriptor remains valid until the connection is closed.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the file descriptor used for reading or -1 on error. The file</doc> | |
<type name="gint" c:type="gint"/> | |
</return-value> | |
</method> | |
<method name="get_tunnelid" | |
c:identifier="gst_rtsp_connection_get_tunnelid" | |
version="0.10.23"> | |
<doc xml:whitespace="preserve">Get the tunnel session id the connection.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">returns a non-empty string if @conn is being tunneled over HTTP.</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</return-value> | |
</method> | |
<method name="get_url" | |
c:identifier="gst_rtsp_connection_get_url" | |
version="0.10.23"> | |
<doc xml:whitespace="preserve">Retrieve the URL of the other end of @conn. | |
connection is freed.</doc> | |
<return-value transfer-ownership="full"> | |
<doc xml:whitespace="preserve">The URL. This value remains valid until the</doc> | |
<type name="RTSPUrl" c:type="GstRTSPUrl*"/> | |
</return-value> | |
</method> | |
<method name="get_writefd" | |
c:identifier="gst_rtsp_connection_get_writefd" | |
version="0.10.23"> | |
<doc xml:whitespace="preserve">Get the file descriptor for writing. | |
descriptor remains valid until the connection is closed.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the file descriptor used for writing or -1 on error. The file</doc> | |
<type name="gint" c:type="gint"/> | |
</return-value> | |
</method> | |
<method name="is_tunneled" | |
c:identifier="gst_rtsp_connection_is_tunneled" | |
version="0.10.23"> | |
<doc xml:whitespace="preserve">Get the tunneling state of the connection.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">if @conn is using HTTP tunneling.</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</return-value> | |
</method> | |
<method name="next_timeout" | |
c:identifier="gst_rtsp_connection_next_timeout"> | |
<doc xml:whitespace="preserve">Calculate the next timeout for @conn, storing the result in @timeout.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">#GST_RTSP_OK.</doc> | |
<type name="RTSPResult" c:type="GstRTSPResult"/> | |
</return-value> | |
<parameters> | |
<parameter name="timeout" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a timeout</doc> | |
<type name="GLib.TimeVal" c:type="GTimeVal*"/> | |
</parameter> | |
</parameters> | |
</method> | |
<method name="poll" | |
c:identifier="gst_rtsp_connection_poll" | |
version="0.10.15"> | |
<doc xml:whitespace="preserve">Wait up to the specified @timeout for the connection to become available for | |
at least one of the operations specified in @events. When the function returns | |
with #GST_RTSP_OK, @revents will contain a bitmask of available operations on | |
This function can be cancelled with gst_rtsp_connection_flush().</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">#GST_RTSP_OK on success.</doc> | |
<type name="RTSPResult" c:type="GstRTSPResult"/> | |
</return-value> | |
<parameters> | |
<parameter name="events" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a bitmask of #GstRTSPEvent flags to check</doc> | |
<type name="RTSPEvent" c:type="GstRTSPEvent"/> | |
</parameter> | |
<parameter name="revents" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">location for result flags</doc> | |
<type name="RTSPEvent" c:type="GstRTSPEvent*"/> | |
</parameter> | |
<parameter name="timeout" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a timeout</doc> | |
<type name="GLib.TimeVal" c:type="GTimeVal*"/> | |
</parameter> | |
</parameters> | |
</method> | |
<method name="read" c:identifier="gst_rtsp_connection_read"> | |
<doc xml:whitespace="preserve">Attempt to read @size bytes into @data from the connected @conn, blocking up to | |
the specified @timeout. @timeout can be #NULL, in which case this function | |
might block forever. | |
This function can be cancelled with gst_rtsp_connection_flush().</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">#GST_RTSP_OK on success.</doc> | |
<type name="RTSPResult" c:type="GstRTSPResult"/> | |
</return-value> | |
<parameters> | |
<parameter name="data" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the data to read</doc> | |
<type name="guint8" c:type="guint8*"/> | |
</parameter> | |
<parameter name="size" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the size of @data</doc> | |
<type name="guint" c:type="guint"/> | |
</parameter> | |
<parameter name="timeout" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a timeout value or #NULL</doc> | |
<type name="GLib.TimeVal" c:type="GTimeVal*"/> | |
</parameter> | |
</parameters> | |
</method> | |
<method name="receive" c:identifier="gst_rtsp_connection_receive"> | |
<doc xml:whitespace="preserve">Attempt to read into @message from the connected @conn, blocking up to | |
the specified @timeout. @timeout can be #NULL, in which case this function | |
might block forever. | |
This function can be cancelled with gst_rtsp_connection_flush().</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">#GST_RTSP_OK on success.</doc> | |
<type name="RTSPResult" c:type="GstRTSPResult"/> | |
</return-value> | |
<parameters> | |
<parameter name="message" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the message to read</doc> | |
<type name="RTSPMessage" c:type="GstRTSPMessage*"/> | |
</parameter> | |
<parameter name="timeout" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a timeout value or #NULL</doc> | |
<type name="GLib.TimeVal" c:type="GTimeVal*"/> | |
</parameter> | |
</parameters> | |
</method> | |
<method name="reset_timeout" | |
c:identifier="gst_rtsp_connection_reset_timeout"> | |
<doc xml:whitespace="preserve">Reset the timeout of @conn.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">#GST_RTSP_OK.</doc> | |
<type name="RTSPResult" c:type="GstRTSPResult"/> | |
</return-value> | |
</method> | |
<method name="send" c:identifier="gst_rtsp_connection_send"> | |
<doc xml:whitespace="preserve">Attempt to send @message to the connected @conn, blocking up to | |
the specified @timeout. @timeout can be #NULL, in which case this function | |
might block forever. | |
This function can be cancelled with gst_rtsp_connection_flush().</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">#GST_RTSP_OK on success.</doc> | |
<type name="RTSPResult" c:type="GstRTSPResult"/> | |
</return-value> | |
<parameters> | |
<parameter name="message" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the message to send</doc> | |
<type name="RTSPMessage" c:type="GstRTSPMessage*"/> | |
</parameter> | |
<parameter name="timeout" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">a timeout value or #NULL</doc> | |
<type name="GLib.TimeVal" c:type="GTimeVal*"/> | |
</parameter> | |
</parameters> | |
</method> | |
<method name="set_auth" c:identifier="gst_rtsp_connection_set_auth"> | |
<doc xml:whitespace="preserve">Configure @conn for authentication mode @method with @user and @pass as the | |
user and password respectively.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">#GST_RTSP_OK.</doc> | |
<type name="RTSPResult" c:type="GstRTSPResult"/> | |
</return-value> | |
<parameters> | |
<parameter name="method" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">authentication method</doc> | |
<type name="RTSPAuthMethod" c:type="GstRTSPAuthMethod"/> | |
</parameter> | |
<parameter name="user" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the user</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
<parameter name="pass" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the password</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
</parameters> | |
</method> | |
<method name="set_auth_param" | |
c:identifier="gst_rtsp_connection_set_auth_param" | |
version="0.10.20"> | |
<doc xml:whitespace="preserve">Setup @conn with authentication directives. This is not necesary for | |
methods #GST_RTSP_AUTH_NONE and #GST_RTSP_AUTH_BASIC. For | |
#GST_RTSP_AUTH_DIGEST, directives should be taken from the digest challenge | |
in the WWW-Authenticate response header and can include realm, domain, | |
nonce, opaque, stale, algorithm, qop as per RFC2617.</doc> | |
<return-value transfer-ownership="none"> | |
<type name="none" c:type="void"/> | |
</return-value> | |
<parameters> | |
<parameter name="param" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">authentication directive</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
<parameter name="value" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">value</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
</parameters> | |
</method> | |
<method name="set_http_mode" | |
c:identifier="gst_rtsp_connection_set_http_mode" | |
version="0.10.25"> | |
<doc xml:whitespace="preserve">By setting the HTTP mode to %TRUE the message parsing will support HTTP | |
messages in addition to the RTSP messages. It will also disable the | |
automatic handling of setting up an HTTP tunnel.</doc> | |
<return-value transfer-ownership="none"> | |
<type name="none" c:type="void"/> | |
</return-value> | |
<parameters> | |
<parameter name="enable" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">%TRUE to enable manual HTTP mode</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</parameter> | |
</parameters> | |
</method> | |
<method name="set_ip" | |
c:identifier="gst_rtsp_connection_set_ip" | |
version="0.10.23"> | |
<doc xml:whitespace="preserve">Set the IP address of the server.</doc> | |
<return-value transfer-ownership="none"> | |
<type name="none" c:type="void"/> | |
</return-value> | |
<parameters> | |
<parameter name="ip" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">an ip address</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
</parameters> | |
</method> | |
<method name="set_proxy" | |
c:identifier="gst_rtsp_connection_set_proxy" | |
version="0.10.23"> | |
<doc xml:whitespace="preserve">Set the proxy host and port.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">#GST_RTSP_OK.</doc> | |
<type name="RTSPResult" c:type="GstRTSPResult"/> | |
</return-value> | |
<parameters> | |
<parameter name="host" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the proxy host</doc> | |
<type name="utf8" c:type="gchar*"/> | |
</parameter> | |
<parameter name="port" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the proxy port</doc> | |
<type name="guint" c:type="guint"/> | |
</parameter> | |
</parameters> | |
</method> | |
<method name="set_qos_dscp" | |
c:identifier="gst_rtsp_connection_set_qos_dscp" | |
version="0.10.20"> | |
<doc xml:whitespace="preserve">Configure @conn to use the specified DSCP value.</doc> | |
<return-value transfer-ownership="none"> | |
<doc xml:whitespace="preserve">#GST_RTSP_OK on success.</doc> | |
<type name="RTSPResult" c:type="GstRTSPResult"/> | |
</return-value> | |
<parameters> | |
<parameter name="qos_dscp" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">DSCP value</doc> | |
<type name="guint" c:type="guint"/> | |
</parameter> | |
</parameters> | |
</method> | |
<method name="set_tunneled" | |
c:identifier="gst_rtsp_connection_set_tunneled" | |
version="0.10.23"> | |
<doc xml:whitespace="preserve">Set the HTTP tunneling state of the connection. This must be configured before | |
the @conn is connected.</doc> | |
<return-value transfer-ownership="none"> | |
<type name="none" c:type="void"/> | |
</return-value> | |
<parameters> | |
<parameter name="tunneled" transfer-ownership="none"> | |
<doc xml:whitespace="preserve">the new state</doc> | |
<type name="gboolean" c:type="gboolean"/> | |
</parameter> | |
</parameters> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment