diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock new file mode 100644 index 0000000..eceddc5 --- /dev/null +++ b/docs/Gemfile.lock @@ -0,0 +1,199 @@ +GEM + remote: https://rubygems.org/ + specs: + activesupport (4.2.8) + i18n (~> 0.7) + minitest (~> 5.1) + thread_safe (~> 0.3, >= 0.3.4) + tzinfo (~> 1.1) + addressable (2.5.1) + public_suffix (~> 2.0, >= 2.0.2) + coffee-script (2.4.1) + coffee-script-source + execjs + coffee-script-source (1.12.2) + colorator (1.1.0) + ethon (0.10.1) + ffi (>= 1.3.0) + execjs (2.7.0) + faraday (0.12.1) + multipart-post (>= 1.2, < 3) + ffi (1.9.18) + forwardable-extended (2.6.0) + gemoji (3.0.0) + github-pages (141) + activesupport (= 4.2.8) + github-pages-health-check (= 1.3.4) + jekyll (= 3.4.3) + jekyll-avatar (= 0.4.2) + jekyll-coffeescript (= 1.0.1) + jekyll-default-layout (= 0.1.4) + jekyll-feed (= 0.9.2) + jekyll-gist (= 1.4.0) + jekyll-github-metadata (= 2.4.0) + jekyll-mentions (= 1.2.0) + jekyll-optional-front-matter (= 0.1.2) + jekyll-paginate (= 1.1.0) + jekyll-readme-index (= 0.1.0) + jekyll-redirect-from (= 0.12.1) + jekyll-relative-links (= 0.4.1) + jekyll-sass-converter (= 1.5.0) + jekyll-seo-tag (= 2.2.3) + jekyll-sitemap (= 1.0.0) + jekyll-swiss (= 0.4.0) + jekyll-theme-architect (= 0.0.4) + jekyll-theme-cayman (= 0.0.4) + jekyll-theme-dinky (= 0.0.4) + jekyll-theme-hacker (= 0.0.4) + jekyll-theme-leap-day (= 0.0.4) + jekyll-theme-merlot (= 0.0.4) + jekyll-theme-midnight (= 0.0.4) + jekyll-theme-minimal (= 0.0.4) + jekyll-theme-modernist (= 0.0.4) + jekyll-theme-primer (= 0.2.1) + jekyll-theme-slate (= 0.0.4) + jekyll-theme-tactile (= 0.0.4) + jekyll-theme-time-machine (= 0.0.4) + jekyll-titles-from-headings (= 0.2.0) + jemoji (= 0.8.0) + kramdown (= 1.13.2) + liquid (= 3.0.6) + listen (= 3.0.6) + mercenary (~> 0.3) + minima (= 2.1.1) + rouge (= 1.11.1) + terminal-table (~> 1.4) + github-pages-health-check (1.3.4) + addressable (~> 2.3) + net-dns (~> 0.8) + octokit (~> 4.0) + public_suffix (~> 2.0) + typhoeus (~> 0.7) + html-pipeline (2.6.0) + activesupport (>= 2) + nokogiri (>= 1.4) + i18n (0.8.5) + jekyll (3.4.3) + addressable (~> 2.4) + colorator (~> 1.0) + jekyll-sass-converter (~> 1.0) + jekyll-watch (~> 1.1) + kramdown (~> 1.3) + liquid (~> 3.0) + mercenary (~> 0.3.3) + pathutil (~> 0.9) + rouge (~> 1.7) + safe_yaml (~> 1.0) + jekyll-avatar (0.4.2) + jekyll (~> 3.0) + jekyll-coffeescript (1.0.1) + coffee-script (~> 2.2) + jekyll-default-layout (0.1.4) + jekyll (~> 3.0) + jekyll-feed (0.9.2) + jekyll (~> 3.3) + jekyll-gist (1.4.0) + octokit (~> 4.2) + jekyll-github-metadata (2.4.0) + jekyll (~> 3.1) + octokit (~> 4.0, != 4.4.0) + jekyll-mentions (1.2.0) + activesupport (~> 4.0) + html-pipeline (~> 2.3) + jekyll (~> 3.0) + jekyll-optional-front-matter (0.1.2) + jekyll (~> 3.0) + jekyll-paginate (1.1.0) + jekyll-readme-index (0.1.0) + jekyll (~> 3.0) + jekyll-redirect-from (0.12.1) + jekyll (~> 3.3) + jekyll-relative-links (0.4.1) + jekyll (~> 3.3) + jekyll-sass-converter (1.5.0) + sass (~> 3.4) + jekyll-seo-tag (2.2.3) + jekyll (~> 3.3) + jekyll-sitemap (1.0.0) + jekyll (~> 3.3) + jekyll-swiss (0.4.0) + jekyll-theme-architect (0.0.4) + jekyll (~> 3.3) + jekyll-theme-cayman (0.0.4) + jekyll (~> 3.3) + jekyll-theme-dinky (0.0.4) + jekyll (~> 3.3) + jekyll-theme-hacker (0.0.4) + jekyll (~> 3.3) + jekyll-theme-leap-day (0.0.4) + jekyll (~> 3.3) + jekyll-theme-merlot (0.0.4) + jekyll (~> 3.3) + jekyll-theme-midnight (0.0.4) + jekyll (~> 3.3) + jekyll-theme-minimal (0.0.4) + jekyll (~> 3.3) + jekyll-theme-modernist (0.0.4) + jekyll (~> 3.3) + jekyll-theme-primer (0.2.1) + jekyll (~> 3.3) + jekyll-theme-slate (0.0.4) + jekyll (~> 3.3) + jekyll-theme-tactile (0.0.4) + jekyll (~> 3.3) + jekyll-theme-time-machine (0.0.4) + jekyll (~> 3.3) + jekyll-titles-from-headings (0.2.0) + jekyll (~> 3.3) + jekyll-watch (1.5.0) + listen (~> 3.0, < 3.1) + jemoji (0.8.0) + activesupport (~> 4.0) + gemoji (~> 3.0) + html-pipeline (~> 2.2) + jekyll (>= 3.0) + kramdown (1.13.2) + liquid (3.0.6) + listen (3.0.6) + rb-fsevent (>= 0.9.3) + rb-inotify (>= 0.9.7) + mercenary (0.3.6) + mini_portile2 (2.2.0) + minima (2.1.1) + jekyll (~> 3.3) + minitest (5.10.2) + multipart-post (2.0.0) + net-dns (0.8.0) + nokogiri (1.8.0) + mini_portile2 (~> 2.2.0) + octokit (4.7.0) + sawyer (~> 0.8.0, >= 0.5.3) + pathutil (0.14.0) + forwardable-extended (~> 2.6) + public_suffix (2.0.5) + rb-fsevent (0.10.2) + rb-inotify (0.9.10) + ffi (>= 0.5.0, < 2) + rouge (1.11.1) + safe_yaml (1.0.4) + sass (3.4.25) + sawyer (0.8.1) + addressable (>= 2.3.5, < 2.6) + faraday (~> 0.8, < 1.0) + terminal-table (1.8.0) + unicode-display_width (~> 1.1, >= 1.1.1) + thread_safe (0.3.6) + typhoeus (0.8.0) + ethon (>= 0.8.0) + tzinfo (1.2.3) + thread_safe (~> 0.1) + unicode-display_width (1.3.0) + +PLATFORMS + ruby + +DEPENDENCIES + github-pages + +BUNDLED WITH + 1.14.6 diff --git a/docs/_config.yml b/docs/_config.yml new file mode 100644 index 0000000..06dd47f --- /dev/null +++ b/docs/_config.yml @@ -0,0 +1,34 @@ +# Welcome to Jekyll! +# +# This config file is meant for settings that affect your whole blog, values +# which you are expected to set up once and rarely edit after that. If you find +# yourself editing this file very often, consider using Jekyll's data files +# feature for the data you need to update frequently. +# +# For technical reasons, this file is *NOT* reloaded automatically when you use +# 'bundle exec jekyll serve'. If you change this file, please restart the server process. + +# Site settings +# These are used to personalize your new site. If you look in the HTML files, +# you will see them accessed via {{ site.title }}, {{ site.email }}, and so on. +# You can create any custom variable you would like, and they will be accessible +# in the templates via {{ site.myvariable }}. +title: Draco 3D Data Compression + +email: webmaster@webmproject.org +description: > + Description here +baseurl: "/docs" # the subpath of your site, e.g. /blog +url: "" # the base hostname & protocol for your site, e.g. http://example.com +twitter_username: webm +github_username: webmproject +timezone: America/Los_Angeles + +# Build settings +markdown: kramdown +gems: +exclude: + - Gemfile + - Gemfile.lock +sass: + style: compressed diff --git a/docs/_layouts/spec.html b/docs/_layouts/spec.html new file mode 100644 index 0000000..1181d44 --- /dev/null +++ b/docs/_layouts/spec.html @@ -0,0 +1,29 @@ + + + + + {{ page.title }} + + + + + +{{ content }} + + + + diff --git a/docs/_site/DracoLogo.jpeg b/docs/_site/DracoLogo.jpeg new file mode 100644 index 0000000..d41c320 Binary files /dev/null and b/docs/_site/DracoLogo.jpeg differ diff --git a/docs/_site/artwork/draco3d-horiz-320x79.png b/docs/_site/artwork/draco3d-horiz-320x79.png new file mode 100644 index 0000000..17838c6 Binary files /dev/null and b/docs/_site/artwork/draco3d-horiz-320x79.png differ diff --git a/docs/_site/artwork/draco3d-horiz-640x158.png b/docs/_site/artwork/draco3d-horiz-640x158.png new file mode 100644 index 0000000..ca47e0c Binary files /dev/null and b/docs/_site/artwork/draco3d-horiz-640x158.png differ diff --git a/docs/_site/artwork/draco3d-horiz.ai b/docs/_site/artwork/draco3d-horiz.ai new file mode 100644 index 0000000..381c884 --- /dev/null +++ b/docs/_site/artwork/draco3d-horiz.ai @@ -0,0 +1,348 @@ +%PDF-1.5 % +1 0 obj <>/OCGs[5 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream + + + + + Adobe Illustrator CC 2015.3 (Macintosh) + 2016-10-31T10:56:20-05:00 + 2016-10-31T10:56:20-05:00 + 2016-10-31T10:56:20-05:00 + + + + 256 + 64 + JPEG + /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgAQAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q88/Nn88PJ/5bWajU XN7rU687TRrdh6zr0DyMaiKOo+0ev7INDir5I88/85O/mr5pmkS31JtB05j+7s9MJhYD/LuB++Y0 60YD2xV5be6hf30xnvbmW6mPWWZ2kY/7JiTiqppms6vpU4n0y+uLCcbiW2leF6j/ACkKnFXrvkH/ AJyu/M3y3NFDrE48yaWpAeC9NLkL34XSjny95A+Kvrv8tfzW8n/mHpJvtBuf38QH13TpqLcwMezo CaqezKSp8cVZhirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirz 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 V2KuxV2Kv//Z + + + + 1 + False + False + + 10.888902 + 4.355556 + Inches + + + + Cyan + Magenta + Yellow + Black + + + + + + Default Swatch Group + 0 + + + + Document + application/pdf + + + DRACO_ID_horiz + + + proof:pdf + uuid:31458fc1-188b-9f40-ac8f-d6f37511f8e0 + uuid:ad63e1da-0fe2-1b46-99cd-97a55da3e11d + Adobe PDF library 15.00 + + + + + + + + + + + + + + + + + + + + + + + + + endstream endobj 3 0 obj <> endobj 7 0 obj <>/Resources<>/Properties<>>>/Thumb 11 0 R/TrimBox[0.0 0.0 784.001 313.6]/Type/Page>> endobj 8 0 obj <>stream +HtWK$ )-J"%mf50 /|{f1`TVkw~E>#_?h֮8W)vi?>8LCvnWm~5los縆ϣ kJi|<WDK󷧙Gz@9N;eӏn=qfê6I~-Da[gQL>ʹϻtߏE~ٚrsDm`酀LXMc[ؾoO\pW ^حFzEa81Vgq*`1Gk1 +7p\e mWZ;߶&0uѯʈw  2Z0+p].ŀ "9Up8?F}sW=wϻoo/O3HC{`` %8!  }Q]P9(D+LUL=TEY騗0)F4}N_4UqMf2[4c4Tm Pφ B&UuurՅ:\ L$>̘Cf- +:ӑ '*O={x@Oߣ2׽Me瞠E΍JgkOw*]CytB 5=}1B)JPawB'5yՍT$9xOk6$k]K>eEρ7Kd<Nب&yx(]j53*7Bˮf?&8xҲilAc(~NЪ Ur."wu }PdRw(MJ +W{6 8jn!Yq hXWriсZFcm0` +E3 2ej$8J\;˪ +nyS%FK +n=JX,O }H.pG~wn5H_Du3E]|rly _BmR<"`%:/rgR$L2QuvkLͦvGѪȫ q4 $ Fc=V K*͓>2I6чU=,S$ .D 6l:$QKZ5]'Y&GFPR2%Fe[N_ CHXl!%YtLcS{߹_,81l‹S="(> A,bDREFtndXtf nc!*T"{{K`t6{4||I"\/ꀎNYzYS{ԥF˾]t<,Yv7 )!&&՜:IzI`ZYQgc]",aa 6k(S )j* AV~ R * }BAᏼE2ҔDb?hV0 \-2CY5ŠML8Y7t3djaJH`wj7+|+@)m‘# 5q#Cˬ#,#bFW%tqM}2oКR^ƭ~+˅ZIM,a_gX[.$`|ci02łafRLZx9jD2.fKBQjEFjb՗|( +On<>0S̖m$=5^x@]/馞X!~ܭ_݉ũujG|ȎDf{8)&εXRd)AT75\x@VK<|Ub>~c{yvwhYHIթ +Pj\r贇B֑qdQI ]cpO1A8?ā*[ +]ڛAE+t6ѿ~#ztͨYPb/b}M XkZ/wmoeoL*AHX|mfBx+0ی0|ٴ;j}CHbDŎ@R!߀9HX7B=+?v5VzufUK^WbdTN@3|!>("&o]-(7˖ߝL1L ~튞v]dpuغ#Q\Tba??),E:zus +60N ZXu^-hxq?d-j/ Y]'U +\H2A5\͂&g\OӿefD +JVP!|ᜄZŎ kƻiqVU>kt8"j厳[ƅ :'P̍1(IXWm퉭t5jsw@6, + +qV'#d۪OՕp7JULEѠlڷẙ5y# @afȨi 3i +1aT{npUF, lJ\,`Pf:FOlEfu(ӻ?]5=* O]V߶ x,|ۺL=RK~V|vosA)ajDc M t[J\fWSӓ.R1t'ifWN[O (m\?1GjFù߼~*DNχ5$ -Qc|ݙ5|7 +4Q<7鏥J +jޯǡLsSݙ,5kImXHLz0ʾ폧{Hڌx0+q===m YǛatbZF@oWxKҙM~ʋ19*⵵xeڰA-XK'h''8'u:`zHF+k=f]!8x|5!(>Vɡ[ԮL?*)_T2;gm/<<)/Κit^|SGI`yۮ\)v[Ra?Lwyfi<xZ zE]˯Pf3jѥf6f9aG[avxxj >NC=dm8ѾHA{!ݟ˟D#QfV"4䣕>t (I+@3"Q]UO] + ]b/]?*km؜{wD q%bXx,1xivXC><5mK_788f8kO'd89md=T*ʰڏW?$⟒^{\VHk.—1pLѓEMsstThan?f*A #p +d:]=%banj̬>9"t(C {6*%R(OPZl956| I[dڀeUq̹T}Y.E"d|eZeO~UQ O.>i=Y Qd*[C A0 `L[@xl˃k$MKzjzZv@jݞk"Nh?tHݟMfh;DWiXՒǃk*8NASTٕfY2U)iSջ(e{\h'Cq9׬uo`Xsv|ߵ㍶ΕSG u;  yEY{u<4!:.*xC_.|bt +\-2SyڸZ[Np@Ur,>n,}[Z}.>5>tE%Xu|6 WFTp*!rry3Y -U4]G =rT=zCh`B!v /6pMڭcXA+3E {*š^{#AoT˛ŝ +J*Ho=&F3~a؏^4L%C@utR$.BYtx஁r4En~V75* "'E`nn٫F^ߛ!s.“<@2Й HR1p*pg|6&Xr-Y~R] l8 y]noyK0TZ3;6T9j(yXx-|_4# ~R^\hqy7k>[xZfy \&[ եbSVStr7_` Y fHG7,f `vǔU=p| ~:ǔwW@#f[]9څ{^ʷ_@ dyWz6|Xr'o +O6~J]${iw-D&I'Xitv"M3mZsQVİ6>d~;rmbgs@yH͕2{IPCs@k{TRF\N${稺G1A?rP!jݪ`U&B/4@3b[a= +*"z%`DQhP j}ijN,u]8U'}`g1+FԼ|!gǙ;*ub\K!pdhA=+턑LnK.ԟvN옸-N bs{XEݥ +YMG'WW!/4KUsKǿ~>OGFB'?S~Ruѿ.22;$5OI.)ʱˁtGB5LGT$],u-+'qGVJjF+s{khkb-aPDR28_>4˖JCqw~3Sl:ř]9[9:+.i-"L]3)zk$Ls9)TpS{`(8*9]!$~n^٠L[p-8C#%r*Fm\oyRAMko"d^(,Mȍ%D6h=B6vwx@_%MoZ[m2)oB\A'F-̖lP1Z;\Cp|/7y&tC(3IJƂ]):w}{TdgPulWI$ +9=}|ATd:e: N"FVM暻l/mIAy֏ԽAuUMD}{;5W#|G}4,7Ӑн滻_ }GJ'E%c }k,y\b>OqsJ'&;uݫ+c +mirdV*~0X߆k0L5l}֛S0-_7>Ы0S#ݻQH .džRv㺨8DQj-,skF ˳g7~!HUC>{זH[B$J>jʂ݉m[~>˧]/ć kkF';`Wäu`O汅RKN@3cɄoxkKl5&`Ρ/`aiso/8a[Bzu~+ #RMi!#G!E I{P,w[x1ڣM(vRsS$%N`ՠ+ ~WϰM a6=oQ=Ɣl#‰K $WG$GGvXi↷8t8W~e#0yWP]|2A:>)s~hGo5β%~ M3u~oǯzIjzŠW@u6 J3q/h T}ˆ v\3}n'^暕>b1 ^0a%*÷f7eva b*a)G7צ|Cfvو.ivX2c6zd沉#:&n}:>>Qoc;26mwSֶ3r>cmA|SAT׽uug-j "YXxjQ)P= 9M]%V 60@OlAv^WBtn }w}4PEo2Fxc#Z;$ȍ5\ {0w*xgj?lj;^h# ~E,vᑬdsgW%K+6rG<x\+|4CFVn`aqĭhaͼZ$&R_.8 Rd Tlh7@Ou9 aF' z6`\IT""3I6FV!00n!ڝ%@r$c3Pו#e&ϥ$o"Ηơe +@oȁ:9Q"\hԟ@or*ltFd_~ͦ R%[V4l4QKףӧc)9=c wqոWhT}Y;C>q0Ƴ$\P;7l@ߒe)<821_F ^c + +:-TwT1ڢ&0={x lK,:U.2H"XVцk? >d`~0 Q)#8Zsɪ g{7j6JTsITٝWʋ ,bz^bNZ^c|j"%᪰*gD^h%(? q,7 himHDX%d_kpAdF_z1={u#WbdxA!WȀz%lw2J>R3w> '5a) *OpkH?`*.,9r$u +] qΣm*2Ag6S|ߏ٭;H'=r b[YآIu~-uF%_W)PXuKO.7FM MO&sU)EsԟU,~Ph-lEx"c鼻Zh U"!x+R}TU5j涸^Tp%Xn#WDmsf~CZ xTl곁_VM(wqR 4vt)i'˸ MV5XpBX\Fҝjƛ{K)UZ|C3J,ո_Е`r6᳕z( KҜj>9,Zh-  4S܅cΨ<:R0bҤ+ncOOZqhG1/;~:ltPa} ukZL^;Dف$S|#Gd +K?."n`S!wbQZp~5!BwE"^ zaë/b5G5ZjZ^k4۫]#?o~7҆0TRBږؾl+Q#85-nkP +w8UG2,,B ~)Q 0%y|vsU*?חWⳭ8ԤLΠ +:|dfVo޼-W+o\n!=ÿTaghT׵vUY{ە4OLDٓNHjTWt[JY)_ S&OIAրBTræxEp/}…`TCvO坟Ix:o }i-ALE<z?CS_ ht@8~jӮa\fAjݍbsvK'eoJa͐$@'떘8b8#mpl^6Qҧ k̙xEH{ >&eiR$PY#JVLDiD#<,>b=B՝05e1WL\F1GQXKFiJDtUb׊+G+|Z]frf}cbpflx{?QN3e\Y#+qҌ'v1Z~<i' h:c9p x +|||$t 5QiUSǫjeS=9ҵ<ט>=xOO?Q~oΞWL*I9asV<!B4uyEy%.zJz=F,?AYvO(UuW`fD-/a + +LK}Dρ$[=@aW 2Γ;?Zo+yI嗍&+qXV4܍`Z 8 Qvޅ ir RwTQ]} [Kάq}e¨P1&KecEQQs me]Cc4\vEٮ,97h>ev;|ۖyV +H[aŁV뮻.I"bN@!g zYjy_,vcO{rd`X %H֍_+wAvE vb>8=0jq$@&L#khn^l/t_~ΝfN^7H"ğ$Ȇ*Fܨ#JUS*:̀XK6 trWQŌ&z1sv1^F :B%-h-EFpeJ +̺Gh28#E14t?c/P/*顚\[HrHz +dVqv@٦x2.**uE^jl̯ +J +?{DQ'L|emgF fc|㗏?>gџb ]u)QxwJš(dW?ۇMZcX3:z Q׬$UA:rZ7ʐ,AE](l>k@1V*Fg"7A{!oӽn/9m7,EqAS1$oY6=( :Y62^T  m],Bz$8-PivI0?사?/& $F?`2:M!EIoGLoS96C+Y۽VEn(hWGo +,sifX$\&`'gv ;XS2uɉUw6^&lx8^]C%u0m ifýʵu]@-', _-yd_s5pyk\t7+ * ^VJċ zʱÌFKmM`pPVW޿|;4waTm1fVs&Us8O9I uVLo OųZ,=4Lٟ~S` endstream endobj 11 0 obj <>stream +8;Z\u;%CJt#Xc0&"`p5K>I55`dcQ0VPOKB&.1_WL*M_/"rCStJ?,)>,+5N%NH'k![15dc4Bc)H/M[VEX.*t50U1u=5GF? +-hpPD' endstream endobj 12 0 obj [/Indexed/DeviceRGB 255 13 0 R] endobj 13 0 obj <>stream +8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 +b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` +E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn +6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( +l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> endstream endobj 5 0 obj <> endobj 14 0 obj [/View/Design] endobj 15 0 obj <>>> endobj 10 0 obj <> endobj 9 0 obj <> endobj 16 0 obj <> endobj 17 0 obj <>stream +%!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 17.0 %%AI8_CreatorVersion: 20.1.0 %%For: (Abby Lindstrom) () %%Title: (DRACO_ID_horiz.svg) %%CreationDate: 10/31/16 10:56 AM %%Canvassize: 16383 %%BoundingBox: 63 75 721 238 %%HiResBoundingBox: 63.7369820929635 75.9780118971212 720.263061523438 237.622017584928 %%DocumentProcessColors: Cyan Magenta Yellow Black %AI5_FileFormat 13.0 %AI12_BuildNumber: 174 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%RGBProcessColor: 0 0 0 ([Registration]) %AI3_Cropmarks: 0 0 784.0009765625 313.600006103516 %AI3_TemplateBox: 391.5 156.100006103516 391.5 156.100006103516 %AI3_TileBox: 12.00048828125 -133.199996948242 772.00048828125 446.800003051758 %AI3_DocumentPreview: None %AI5_ArtSize: 14400 14400 %AI5_RulerUnits: 0 %AI9_ColorModel: 1 %AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 1 %AI17_Begin_Content_if_version_gt:17 1 %AI9_OpenToView: -379 660.600006103516 1 1928 1104 26 0 0 -4 37 0 0 0 1 1 0 1 1 0 1 %AI17_Alternate_Content %AI9_OpenToView: -379 660.600006103516 1 1928 1104 26 0 0 -4 37 0 0 0 1 1 0 1 1 0 1 %AI17_End_Versioned_Content %AI5_OpenViewLayers: 7 %%PageOrigin:86 -240.399993896484 %AI7_GridSettings: 72 8 72 8 1 0 0.800000011920929 0.800000011920929 0.800000011920929 0.899999976158142 0.899999976158142 0.899999976158142 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream endobj 18 0 obj <>stream +%%BoundingBox: 63 75 721 238 %%HiResBoundingBox: 63.7369820929635 75.9780118971212 720.263061523438 237.622017584928 %AI7_Thumbnail: 128 32 8 %%BeginData: 5102 Hex Bytes %0000330000660000990000CC0033000033330033660033990033CC0033FF %0066000066330066660066990066CC0066FF009900009933009966009999 %0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 %00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 %3333663333993333CC3333FF3366003366333366663366993366CC3366FF %3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 %33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 %6600666600996600CC6600FF6633006633336633666633996633CC6633FF %6666006666336666666666996666CC6666FF669900669933669966669999 %6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 %66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF %9933009933339933669933999933CC9933FF996600996633996666996699 %9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 %99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF %CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 %CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 %CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF %CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC %FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 %FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 %FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 %000011111111220000002200000022222222440000004400000044444444 %550000005500000055555555770000007700000077777777880000008800 %000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB %DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF %00FF0000FFFFFF0000FF00FFFFFF00FFFFFF %524C45FD0AFFA85252FD05F82752A8FD73FF7D27FD0BF82752A8FD6FFF27 %FD10F87DFD6CFF7DFD13F827A8FD69FF7DFD06F827A87D27F8F8F852FD07 %F827FD68FFA8FD05F852A8FFFF52FD04F8527DFD07F827FD67FFFD05F87D %FFA8FFFFF8F8F87D7DFFFFA8FD07F852FD65FF27FD04F87DFF7D27FF52F8 %F8F852FD05FF27FD06F8A8FD0CFFA852527D527D527D7D7DA8FD07FFA852 %527D527D527D527D7DFD0BFF5252527D52A8FD0AFFA87D5252275252FD0B %FF7D522727277D7DFD06FF7DFD04F87DFFFF52A8FF27F8F852FFFFFF5252 %7DA8FD06F827FD0CFFA8FD09F82727A8FD05FF7DFD0BF8A8FD08FF7DFD05 %F827FD09FF52FD08F87DFD07FF7DFD08F827A8FD04FF27F8F8F827FFFFA8 %27A8A8F8F8F82752FFFFFF2752FFA8FD06F87DFD0BFF7DFD0CF852FD04FF %7DFD0CF87DFD07FF27FD06F8A8FD06FFA8FD0BF852FD05FF52FD0BF87DFF %FFA8FD04F8A8A8FFFF27FF7DF8F8527D27FD07FFA82727F8F8F852FD0BFF %A8FD0DF852FFFFFF7DFD0DF8FD06FFA8FD07F87DFD06FFFD0DF87DFFFFFF %52FD0DF8A8FF52F8F8F827FF27FF7D52FF7DF8F8F8FF2727A8FF7DA8A8FF %7D5252FD04F8FD0BFF7DFD04F87D7D7D5252FD05F87DFFFF7DFD04F8FD04 %7D27FD04F852FD05FF52FD07F827FD05FF27FD04F8277DA8A87DFD05F8FF %FF7DFD05F8527DA87D27FD05F8FF52F8F8F87DFF52FFA852FF52F8F8F8A8 %FF5252F8F8F82752A8A87DFD04F8A8FD0AFFA8F8F8F827FD05FFA8FD05F8 %FFFF7DF8F8F827FD05FF27F8F8F852FD05FF27F8F8F852FD04F8A8FFFFFF %A8FD04F852FD05FFA8F8F852FFFFFF27FD04F8A8FD05FF7DFD04F87DFD04 %F8A8FF27FF7D52FF525227F8277DA8A827FD05F827FD05F87DFD0AFF7DFD %04F8FD06FF7DFD04F87DFF7DFD04F8FD05FFFD04F852FD04FFA8FD04F8A8 %27F8F8F852FFFFFF52FD04F8A8FD06FFA8A8FFFFFF7DFD04F87DFD07FF27 %F8F8F827FD04F8FFA852FFA852FF52FFFFA87D7D277DA82727FD09F852FD %0AFFA8F8F8F827FD06FFA8FD04F87DFF7DF8F8F8277DA87DA852FD04F87D %FD04FF27F8F8F827FF52FD04F8FFFFFF27F8F8F827FD0CFF7DFD04F8A8FD %07FF52FD07F827FFFF27FF7D52FF52F87DA8FFFFFF27FF7D2727FD08F852 %FD0AFF7DFD04F8FD07FFFD04F852FF7DFD0DF8A8FFFFFFA8FD04F87DFFA8 %FD04F87DFFA827F8F8F852FD0CFF52FD04F8FD08FF7DFD08F8FFFF52FFA8 %52FF7D27522752FFFFA8A8FF275227FD07F852FD0AFFA8F8F8F827FD07FF %27F8F8F87DFFA8FD0CF87DFD04FF7DFD04F8A8FFFF27F8F8F852FFFF27F8 %F8F852FD0CFF7DF8F8F827FD08FF7DFD08F8A8FF27A8A827FF7D52FF7D27 %FD05FF527D7DFD07F87DFD0AFF7DFD04F8FD06FFA8FD04F87DFF7DFD0AF8 %277DFD05FF27F8F8F827A8A8FF52FD04F8FFFF52F8F8F827FD0CFF7DFD04 %F8A8FD07FF52FD04F827F8F8F8A8FF527DFF27FFFF52FFFF52A8FD04FF27 %525227FD06F87DFD0AFFA8F8F8F827FD06FF27FD04F8FFFF7DFD04F8527D %FD04F827FD05FFA8FD04F827F8F8F827FD04F87DFF7DFD04F87DFD06FF27 %52A8FFFFFFFD04F827FD07FFFD04F82727F8F8F852FF5252FF5252FF277D %FFFF7DFD04FF277DA827FD06F8A8FD0AFF7DFD04F8FFFFFFA8A827FD04F8 %52FFFF7DFD04F8FFFF7DFD04F87DFD04FF52FD0DF827FFFFFD05F87DFD04 %FF52F8F8F852FFFF52FD04F852FD04FFA8FD05F8A87DF8F8F827FFA827FF %7D52FFA827FD06FFA8F8525227FD05F827FD0BFFA8F8F8F8FD0527FD06F8 %A8FFFF7DF8F8F827FFFFFF27F8F8F827FD04FFFD0FF8A8FF7DFD05F82752 %5227FD04F827FFFFA8FD06F8525252FD05F852FFA8FD04F8A8FF27A8FF27 %A8FF277DFD05FF27A8FFFF27FD05F852FD0BFF7DFD0DF87DFFFFFF7DFD04 %F8FFFFFF52FD04F87DFFFF7DFD04F827FD0652FD04F852FFFF52FD0CF8A8 %FFFFFF7DFD0CF827A8FFFF52F8F8F827FF527DFF7D52FF7D27FD04FF2727 %7DA852FD06F8A8FD0BFFA8FD0BF827A8FD04FF7DF8F8F827FD04FFFD05F8 %FFFF52FD04F8A8FD06FF27F8F8F827FFFFFF7DFD09F827A8FD05FF7D27FD %09F852FD05FFFD04F827FF27FFA827A8FF5252FF7DF87DA87D27FD06F852 %FD0CFF7DFD08F82752A8FD06FF7DFD04F8FD04FF7DFD04F87DFFFD04F827 %FD07FF52FD04F87DFFFFFFA82727FD05F852A8FD07FFA87DFD06F8277DFD %06FF7DFD04F827277DFF5252FFFF2727525252FFA827FD05F827FD48FFA8 %A8A8FD0DFFA8A87DA8FD0AFF27FD05F827A8FF27A8FFFFF87DFF27FD08F8 %7DFD67FF27FD05F8275252F8FFFFFF2727FD08F87DFD68FFA827FD09F87D %7D7DFD08F852FD6BFF52FD11F8277DFD6DFFA827FD0EF852A8FD70FF7D52 %FD09F82752FD76FF7D7D5252527D7DA8FD6BFFFF %%EndData endstream endobj 19 0 obj <>stream +%AI12_CompressedDataxܽz*(1眳If&zk?URuӉ0gl/*TYUR2q~-;FVqX2Y5*No5NZaGtWs4*hoFFW2:UVď:󝎧9h5eP<{;(}vzHRex./y^/`JJ|v:vWĸ*U /EN]8]9]8tx~E^DIԠ+5ǫ&[Ԇߍש5bW?vo*F;ӪԾb2l5;ߕAW^x6[wxU o˛>g||Ó`˽vzl|4N_FNf&8UEV9.°sDWo 99Jg<6~&&i-ˋb.iW-$Ii؟Ɉ}ڟ_߫NA1\ (uHѿݴNQ|ҩ7Z}UHuQuZ{̈́Kx\@: @0ܷ毷(} Vy6κuL%+z\Q82x8sR\PȘR\TQ_t5hڰj&nfȁF'xČ +{$|kjV5%$.'"HD }׬t +q!kA G} d.V XiJYuӲxoaߑW[CyAs`tMF! ܐ@S²~^oqi53OA66k՟Efޭ7A0y`+ @I(j4lN|w_}V 2աL4:`U7h} XMWc'akO+ߍJ,a6g111}\Ƹ*`K ++ :ZQu^M w$Ț.+udp7/L/7<I酋e Sia// Ȟm(+-0dm Ol8wcga;v5GpALBA2=xvݥGӳ" ՟(HN'`LƯݭ2D.^uZb!|7:KӎCru#>3`nרHTe +NWwn vπ㹸Ɖ>4qS-"[,y(5VI7Epivp显/%98nV0A#ogق 9ǭϋWC:t1ZKoLܫvt{k?TSWiڟGYNeA4m\|DžxբCEQ[5Imn9{Zz[6z0a$`\w% Geo5~j3ԣztT^5jvg8`ONŠjgɺ:64e[s87 +(`հo ʝgT p_4df.z\I5r]ıiFMMGdE/V5-jvAb &}ee e5_ "Ibukz߰M~n7Q+ַJt;UQ㥩٢w}LB7Ju+5˰|4b 0\R4㓱[VDoG{W+A3bt,vjx +XHx%TGM>/qHڂ(g2&=;60Wհ)wjOܼGCҷ,Pg92NфIڔ0;ӧ>(qyF IaH=2)qzmP זZy;fݩ_n@Xjvܿ0@?F"CGi7 +p +[#Q S)GUYi2'doq L:T1 -؝ +ໂװͻ_9ί_95dosRn5sg~tFTv{9fSB긟k + ?h4<[<^H~۪oC&4؄5 ic@HZg0ʌxAZL/-P=0[xU'-xzq(ۍm_v k[%LL3Q Άɍa:jzGu% 6gCA%gd$!4I!N>m)z +T~7cf^Ow5-hӝ3eᅭWe%cq5#j-`~uHXk&'qAn^Jei0=6|FM4sjvc&1rG}Kj8& /:zJqTkׄlI?,5&wEGEuL\߸w~d 1u10y07I!4Z6)P0Q3Pu=f\_$]LX+{@16֣A%w"gއg`kW%zo5vBvp|Z}\{ApmQIh&3v&+]RlbJBe;x TJ/(8c"zӫD na4z Z[IoJl΄ u 4ǃsqx8*gWBUiq>>6N6)\d:;ƻ@YqVvQ`O0]&*Vu2Ql~]"Q/ + $2u~g"^GXȚ1 +F.AՎ14uPĒEF\O WI=ԮG|voG_ &H3CuP)u2lP9 O("qDqA_2vt]rnc%9D VgP+4ID8j\^na;Ye㜧wk`Kڟܨ~q[!q|&F"_%ͯDQO|6\"3\JܗYD)^NR_J_|?gN[nQ%{͍ja{z}7\(cẼQبm@ƛ`Nד+Z +g[]N_Dzĩ٩I+\^ ӉsyObIl5VcAhO'}F &8sIʉ0XXR>W^/>nt~yeOPy}QJ6XVz~@{/?ŪrY +^@a7}IO-:]/{n!U]|&@0`2T_~@g|s4ϕɳɥ\α/Хc7p@@#` ~(uFVuuazZSZk\](rZr[%4&?@_ק@%4tUf@Wx hiKX3+WֹSOsu[8ʕ_^(d\Wz +Kjȱ`~e˘C6bSi}*;>sjG#@©$U?=V|*Wĝ,.=Y;z$=j\Ч,w(s=o>=S@o@>/ kE(= XLޔ7v|޾ wuTzz @1~eoe~ 2wU&m~zNs.]!@ARi@b42*,m3=ޗW teDӼ%÷ks~gq:ʸfE@w \o64G\Xt5Zf +t?:ʟ+]VGN (+6s~n+^1^\4ޯzkTu!,vVO^o kXL1iP]o3o۟s{`&,_.o]S cǙzk-26WZ__ӷ~tW7o-?~[=jx[ʘVۻd5\Zݰߎ`=.༻Vعzk`kŚP6}իc-&}N ߷BBXHZv79\o3-m1{³ [9vq} Easƺf795 C<'ʉe܁7A*a xSn愥 $!6EdokpSDk/y?D @n77imsdšY>.|*7mn} +ʿN +5WZgJW PtZ_\?]Y~2@@P'5Wх`^}>tܗz9W;Ez"b/E kǚ6t[wpKumޟƧiН!/v`υ =/{DZ l0ߜ_]lvSk'*@f7eGaS{*ت"dl&?+'1Mh`j])#Bo'(%?NyYKe9sp] #/2(ta;II.lH_אbIcPo% ݓai;#6@%A29rc ]И{HD~Wཆ5e{~G[A\BCethgrXgQ}-k)k'qBq> Ky'DSmc}siIWc"3=q.・] >Y] ܙQ}:\IbyS{pqLMܺ> F4"g(LY5s.rۙzB +3c)aӋ02t~|d6Lڱ(q̻0:sʯD0p%~<s1vF$cjwA?v{6*e⒂lgg֠\{ܫ& ﷹ&?b,IftI{:.>4} _ҕki뷺{}RLSNRx5:٥1! :(ZH/l"w_;ؠX;]gEYuB=;1a,Įcoah`HDP{#`-X-6u?+x#v?Qol͌+w"80⏎bk408%v6ZɶMm Jt R m9@u.05?1t" 馦侴{^ΆOH7j0;5ad8cC# A2$X8GaK#KSϖ}wK`i3F}rg]DBd,.._y'YIsD|"$@s퐬gOdiFHAY-M35*1$ +olCZ24A t#L8!GqC~pC"&,{ۖ%vQ48M!ci(pS6%V/ՠS֍N!jˑ[N4bɈRhQmJ5DJ8Uo/Pl$# @̛;L?- ] %GeqjY㛔0\yʽ9#8t6x+v5zdd.JufRf+e\[m'mO}R/HdolA|ʹݨ5trzVБSfPC\AKΦnJk+Zp5t* b +:Zp:OVW$5ttWٵoWСE [D9+ǯUel:2U/l]o*L'Wi4b)^ Xd.vȄmTߚĕ4*>-`T Ev}+"4]g;?gS~Z:"1 |n&Ki=B5.bŔpV"nz1+R'u=\E=eM^.9$Sy'CSoulW֣z9dV,is"mۉV%za{t* (&HLTNYl.I%2cExFkń YlxA;O +ep#*5Kp:k[ Ƌ39 V B +>( ㏆`G:1IưP{ԋE˥_dɱH̽yNPZz ƫHME,*RYTb,*R+RwE1[w##aeh lx׊m;M)})̴>>>i)7f] +ѯ.yPӔdDLX +l2A+_t%HwFƯt\;6d=,I]~9S“,G %o.(>‰iZ#g}F>q+9$ 27>Z|}[_כR|>K¾r}XՊŝ^Bp5Q1'g5V@z6bQtN3T\N':~nvr=2zǿ/ծ} P}f]WM[`>TPY_SoSPwP] yqWa%{bn/ŵ7?#j' :_X}kz!4Ta[4,m&6Hb'8g#&!L$AE8Мo~Mr^ +#O)Ô"800}9i:lI aFg9ҸɔCrEF5Dv+[1j:w3ej:yj"<9V5~,l馊ZGr><(yj:`9yt^t^fj:/96j:Z:kufta訥3mgWMUKgafUM絺$j=j:]YWy )ƌg6t^yTt^t$t^],.tg`pLEij,joʛΫњiX%~5#Wy1dSWy҅+:A5 +=a5;]._鋎7;VyM}Xt!8NcAԣBk*b^?a΢?:obE7!5k̒3vR<:W9 iG.jy!x +\ ?b!!?D#Pw]z4(Jlke>tcl|k".◠")]s7^~ܹN n5w7M)u͝+/so_s\ԑ9qO: G*b4y%6SfkM +&+*rUq&=J* [M=1#TN"hDExhjpmo2aXH6PY\HPYr"fR8b<i$IE=3-r'M{ڳ:<+Th3M{Q:&J/zX7T=8W!r)tv\1 <&q ~>]cB;io^fqJN.Ȉq8ҍޓX0v!CX}'Ά ]7M^_9 w6 wtq1+'')oz6nog1oҙz熻wMQ4fH +kܷLxZ[҃+OfPϹ"PL>r$fvz]^P6\M+="XELQ8gEث1ɺp5=XMؕ;3GcgQ?nX;qeLAELo=_=KWz?~7 =K$Rc~sٙ{fWccck\?\hޔ7b.ﻁKtW:K#C=5.ñsBiau/JëVzQ9.ׅ͹U<$b(;ݺd:lyjU%﫼/P-U) e^[stoH~jt@iڹ__R{LrLZ>i*?j!h2NK~po@/;J+@/]@iޅEG@wwoU]+'swm)=r˫c&a;kڮP9,b$ UN;wJQ&#b\4!6i*!=ژ[6%aFR o&e}|}̟wey:Q'ҽ~59zF/Տx{:i{\刮'xƭ~\#Se{>~q-\U>fZZl{v9<~n+' c3!Ǹ/_9~o0tgA^?ka=ocN^X^cS;89 /xs!tG^?sHtO|RW9ޛ(n}Ha$z.ĎamntklS:6bYC{=r<.p/6zAKSW{eXEYNeK;?;iag$+u>o/hkœKIsRM;)r|'\~lկNƩsjZ+ˣXk~il?oOVNw[K bjOIz:8H?矤sc,-ܼM2 6..ms坣v)޻;Rէs:c},{;xٜ>.]{<~ .ɫ.xO.E,zB"pR|zsú, +pUOԱ,M W)櫝IMbPNr :<;8 }`jE;jēd慉M%Yˍ{r}fe^9-|VwW@[{su{KD1h̗ŌkljUs/ݽevoLâo=9qA +ssK'>Ebǀ _eR  _7VWbO=Z̙?+˻‰sJrXN+Ko9У4JTqfȲ/^Ն"Ͼ?(X ɞZ||n9~ozk O|ƒn}}3kBs +yq$~q hD8,P/ ;˭߁D. +cB8'A4z7TY,9j?EwTl;8sKi*%K~¬ed`ǖy:g\3aMAZF¼Xs +krfnc0w~/':(e?%_׳u {Ǡx󃭣¾|us{_bZ+ܿ_Hww%ncɉcIoQ-wϥԷUkVmb(zHd ]1zZRDckG gjBQy<:>= B&>tbɱk!ǦkBcQ9sIc2H6̙JpR0w<TNRb FNqd dY"K-]l)& C8L^ fv6N18xHJOuByVX91_COE=;'& r2XrFĿ 0UjX+_oI!)sC*^ +*Kb3񔎠d_F`ft/5OC?#O{^ +#˅VwN>A?r?ո|/cQ{'b ˱kĔ^b,7xb}7b}'MA^yj՝<JCݥ'?SՅg2'8Z(xeQ |\X(xQsHҺ&E Ļ)oG>׉B$l~M$,'HZH0%dIP`Wl L&l$$b:Z=>P}Cx !]2R@h]n8S%X.y?1 A +iq,Li94nVDj.^]xJϔ]iѹ_C,9҅>XF+dՁ/+c`;`@:`Ű0S klj΋cO\FtzPL]87cv/?v~Fon鸾υ;X=TfbXT2B dt NuW=I$4* @cQ-O*uLW8~RȽ ^ipd7]y3> X^v'ՙcoocZ+ /VYQx_^IV\]8v-"sVLҭkgBNs죥RdK}.lٴrF5NȑR 9u׌XmFZ>trx1E,EeMc^bX4\olI;ili4K!4cK b9c4 .'S#Oe*C)S#/eZ\#@%8h~O4Xy1g>ifϙ*+#Yƃm|vq* 4@7,zrfIēM{:w0-;wVb.g Y>PhG$8̞ +jd9?9Ԇr:]'$ߗaB 佲{>u 1B v뼘!D;?Ț>pϏs4޸q~%'?=$B;g/K6vp¸SZ;|p+ / l 7kO[.hxriج[lע}$xD!izIOX{vSe%2aQ'U$ D> [iьZPnq|V*ƪ*jd9_ugnݔI42r|M﮳8xʓu9G_3)3Hf{U_ooK4) M.RƖh3HBD(F}6zJvfyȫ3>W"gzȫ4%%ٌŒCۮd\5.6vqO?ÿ-.2|q5"m|:~܎qn,/fm+?U|tr|sPk {*o077~hĆ>Ve:_oxw'.^G1ҤSt?Y˩ +vr$H&'S$AtY:'[#HM/uMUuA8Ax{ѵ,hb8&ZӠ9Ul#I9 +:kX>I3<5n>A2/BhAV ,hAX3҆(a6,FG֊1k2dH(<Ef 2ƣ*0*K6aM%T]! +XI5;#A/ yI* $0D '.RSHDˠF ဒp,DU@U"E8 +&, Ou4u$ +SQLJspr +Nɚ+Tb|Ɣ +] >,ft+$nJ^2ZK0(KQ8:2A\N*Jц#P D)QsWĘUQg ;F4Ѝ. GڠRUG;-! %h0 [Hf1G)e#&I惎:Z\GQfŴHKk*4"D0=Q%S; +@~h80Q@5bAY0LšfE R a㒢2*@8 [-D8H8 `5ȕ']"? A2y`j`oFelNÀ +<r1E l{#䐲`.\InH M-P$0"V5s:a ٶ)5ݱ/2@ +: -Nh,(Db;x(# U2E ŃD*tEHzq8Bi *BBStƤcvh#Mq(A/@ %@Z2Z>T c BtTF)OW0B?JnR+2/A0MSc &U7&(Q@2"DOMe GEEeppLh XAࢠ=Ǔ:`8BCă`M"Ҵ6v| H@b` hDcrhAvDMRD6~lɖ+XýXd'qVcAqCb =EY -D%"1-d8`% %T2ם%~"(n3zw\yQ(f8?EG'B/YLU!V7L-Grm*븵 $9 %D3p0x$U< +(* RV8٘Cģˇ^)lu0H97D\Bd˯˜j(AP4=mցu! bqz8fZfܘ6*nQԒ6@3ΔtF-3}PRuH\ H#(h~&Q8*[Du8a{Ƹ& Rhj 8[7"FLm|2h!m4\#T:1Pӿ +vHrg@  +hca=TܫtlDhaq T#du",%Q LDtآW`F#y$a ' -acNNvJsh >z&LQ4d=kAdXEQ% *bQ[ r:M3v`P22S&,3rfرHhpD50MBT(?A&8Bp8Zފ7b0HÚ6eJv=Y'oPƸUUYez`6i8hL=~"2v &X 11cZ~E+o䎣} +Dű֧l +*kx' <Ǟ3\m6/~GtrSnE1cC*JNng4 +|r\r( jca<:28u4r{<[ +`׏]οț])YOINQ¾<E d^쭺}kueԑ6#ZPfQϵurr'&"l{HGQ9Lž6+!\^{3Wپ%TS:U6{5Cm5T#ayxzcwUl ihA?T" -gٙ1h'l7j8%]9E,"NME##Tbȳ(GٴT84ƀf}"\hMf?Gm"s503/A-i T4wW3):UbO9.>OРӞ(~nc˃yE:sí/hB5WZ>"ަ=*/A)̑)ZBEP-^JGdkoKQfe/6;yQQW<=z@f̢3 {}{n+=>LvͻJk`靪T~pU%/6b*b#洵R vEX->q#W55pϷi奿?݋3u00W7_(,$N7c64,',hCAƗoؘY~bA0wwd,<g5=}/wvK-$ "$Xg (**U;(+@k&] 7Xfe%S(i9ۮD=8'A|rVJhUYE+oziWʖ5 lG P6'SI~h< f=Gx4Ө`+ cZ6wP""D`k$K +~H/ΰfVe<ϝf~Ī@E w{ČȈ+5L'֮"XN9Z]Ѻ`.0Ę.#wMl`>{U篥{Ucspýzn_Bg*4{glcS+> |OiilM'U2AqBNSC /^bf:Ϯ3sCz +Pk5Nc˘B~>O"n/LtZyJܮWxt#0j;\ +zZ">*032}/*v]JlUŮtλˁqJfa΃lCB%{ y4'YkS3ϰ|T^=_һݹ7/^O)غK@VP{)'qp;ASG#PwyMm +&[egEij`QJr،xAJ)jAmSzjءӭ(M3ibߣWnl\~lez;`&,u;NAh}7eUzEuܙ-k|Kmn! z5į76Yn%"FrUkc?V|^UER>\G퓀5TT8;?")# n+ZW'arI Njκi`x [:y;$HWP$zvN}*?.q/X]ei.7QOjfqa_r\Hh3N(i_呂զ ?lRAC hrdu`UA`K" i({ U42/(:#9w661g"ȾIM#DWvVB+E쁻 dOYSēs$`2 GP +#g$q/%?l9W~F|Wbԟ.vm|1(,楟#FO̫٪]7(0Kh\43W%^=0QK順D@ޛOX:> 84' ?C:p/4NFc .a躜F`jv+.q8Md7j#Zc"O:^ėS2)2ű|k i kM"d +%9PF 2=cI`;\7J?D+BrLOܩm˘$Uΰ`榒D<(SN*=w6[ +PQɷp`'I?>0!6d IyKNZ27Mjwdi κxg2ã͚?`X*]k dg\eq6Z\׃ 5Fȶ&uG߰ _bc~]"õfEζ^ S[]사1򱍿UvChZ<0]$u-ް(@fYU#x4._5t#Y_)d\oz^F ę~~hnML(ˣmvbYƮd؟j%edkCA]Gfmqްes h /4Y0O^}:w{^e 0R\F87iFi ̣ +WfNaDFB,*@I/8E7/]ظllv|_'sネjEJlw&V3|cl3TgfX-E rEqB,ǚs1rqpjE/!0C}Xxb|l!mï\SϜl="m%e{c{BjbAiUi. ڼs5OZG6oXDӹWyY]ށvCi 7?oww1h9,M:5,`ݡTl찯á1xCajj"G~Yo$1'{5TS6Q"N6]Np-؟v^84e\,x#cu +ř\z)kkӜx}db-vKYiL8:i)0x_=+>#85W^A=u0}c/ޯCNֈuUO| >WM_-*K)ynޡXܔ@V#9dSn}kƻZad̎0Y3Kikpɞ%~Â;7:JHCiգ2ʰ2e/)HLЂ| mDo{.{?#)%+-KE PGuM@jy`;sͮaKJj*YV`V^FwM-iyS)-Si| [9XfunP3NC4z7%l/nf1sk!+Wawq ^yۛ(d): +z|ɦm-^HJNig@8i}csr- v/BU$T {'K]*,p|+͕Xa- k)2NW'49oncY˪R-|׀E "[8C5n幓ZoM(Q# +RQF-0d鎉əF^{`jTa2߷:4!l}MK^xs^k9: Z*Zȁ L8N}| +B&/?ŏ^:hҁJ ޲4>Z!fwhA>6%Na*oicb K׆s w[/q:CƎNCmf7LIeo6 8.D}y n*[ 0f?9GhʘL֧-O7s=Y7 _$$MlBJ*VЃD +gN:b^;u*]2]wr9re+Fؔ׳gSƁһ:ΌyOq`;g"JB<+FLXR i8ӵ6;AvK;JoȢA[hx%OST=d`#[BqK&?k~/SP*i8X](<`p)!,.jS{icw*jv]Y'6p@ dw,vKsX`mLLNrzCOR.*-)ǂxrb8 $r%|P{Q4M4+Xl5Я i8EPm1PLAvzNCR8:c#EոTb e^OLx*1,BPxV_,*^trd"JgwqlձD[ ڛ+^bU'.(-T3ДnC.k…pthTݛRߍPQo7}%[ٹ/Aq"װԀ}q4aq XuĨ'0B1K|r3# SykA+ ډ]\3HMDA-׸TTlI50Ub1OK?ۄ'P9gsIEn}."rL TcoC2P|ɿ+I~9S+c";vb a>@RBŤ!#`c;#8jj2"Wxpf 0ur0vA~ ܮ1!@SLޜV{0"K;H>6oϮY!J#@phkbPajxo9.C#ʮqo\4oCiZ}W+ז[Z6|&8dP؅^e (Bcz@LD"bY N>98c8ⰵxQyTԱۍX3l2G&nKOG6 !.swMuv4M~ԓ;Bi3,J{>m܂r <4 :\A;b8Gl +ե-usHJ\xN U#g3LWE۱E h:WDS670M~(aV0xuu`{0nWgv|ftxH* +ZX|; #p lp ?飖x7ADMWsRDAح,Z"!߅ޒ3^yqd>36>!YahO8cӞ-JBQ&"VNUp[|PAbCxI(C9˝"yW+;P)܂̛f"{ +u#u e.G1=+2}dwh~/KprHTׁD.2Rw=x+4B#bMܕsj,TTnױj9M +k޼շٹI"*vOw8s?=zAZn\,Y9AD]!~$5Ŭ> +ew;@ˋN⿁28/|vFbP`2wG,"P3 س^ #J2E$D9-ۋs66e&=ʝHS4U*_q B.uTQ)mT-Lؘs|)A3Mڗ=06z q2sst׫1}mWgmcg5d9f4eo,%̲պ(yɪ c(be=DI{ F<'"U>C.*'S36d8nGN2 +dԯd>, +I]bG\1MJ0l/$HU+ӊlhkΥl My)PW]8{|EDX[[uA8v:Ո/d5 l + fQ , }hY0${+dٛSfۉnN+LF~SƹYۇI dkՠViaU6l T$JWI4z&^ڭpx,pνǙ0z , t+0t*夝 ؕW:%ȿK` xɊ|iq +V?ŶG>lbq/VIZT9hk5A"C7gv$Z=a$_)\a#Y%VLf>cf(Cb)s,,#_'MLǢE9'YJôt7_drA\ǂ,F:t-Su29&6|z%vH`REP*`1)IXI8w|8"¯?l"k%^i5K7~y3<ߊ,auvS,ρ_ t,i-mE/PD윐b;E&_\+r;+H-zKa9a{jڶAƄM X$=T$hSX:`̒NzQ?nDW +"Iʢ:zwLHR&q nRU=|>҂{O}R,o1`>dyƷ6{\}8+GoX`E,y3ٴlUz9xpt5} a摶ef`A+4$tWbhҵ_@c٨{[,Kٻ$(vgJ Z.l{,fhܒ> 𽟊y}ū~ŪQ{GV29ޯ$i-6Ce}`l\sjׁFw0@)ؤv>u~Y˱)R5qa_0 weK-Yz 3ƩM|%CeGԫSmQ r.ױKo/-ج:zүqJzgsݳd{mЧӑ94tų Fx]v{LWl*? +E =Y.C('UK':B&"R淟M,cJ5g%FFhuIٶ)*STv/O]jTd $o/|vH+ +碪[w'E,qAD!on!Y@S2@c&WNY$t|¤^/I(#JU$%Lmsd Ш%x,c^SsXPem>+fgb%,PI- \$0;4SLq{*j\M7EQ $HQ|ſ1x* +q \3P3O+Ь"z>HC:@{$nm,va ժI;A(<2 +`=< H+;``xJb +XDUh:&|C~y"}iyY$NX()|:Wj=QqTEX=9;+c\]ƨ<ޛ6Kjc5FV]U}, ‰'%CWħ8k+>l]T2O {@,# ͦMROqS(Y"זCMs2`Ov/u/CHLZEwdD1LtYTUdY;(=Ǜ""Ԛc~v\T% x)~zqKxM.a9jC1I`lTAe?f /vpA)e 8/ILC{fɯ`'^%<),f%9*FEqa.^Ҏ2{iic iQG,^{q=p!b\胓v:mH:Mw&<㝂r)!Wa +Jmm``U&Zk Pc )o *#덓ovոbKLu-r*{׋S_xc-]ᴘ89A7j:Ӛ2_1[@}Ԣ]p]vv|QKBjgW^P07,5N_g*]fu7O7Vnp[,R&mo5zHnpet-^T9!ޗSKonR +u4}s-!]v~ +Kam8## 9 nj^Qt 11QnfV$#;#;crvDG EctXcXLd)w:,dƏțqM(jOA|\>R:z6z-w R`px +@HOD6U~õ*G_sϱzȻvt814nqlaЯ|o{~ +IZ9H ыajLvF^[ t^3Q/QFJD Q,-H{ $_>WPbtgl'|܅_.ֺxd/%b?b14#F;+R܆G&}!?W*NmtSU1x!Eb"WH}e61C{fKb;[,jM*^t)Oj(q5bS.b_VJ9D´n=y/WnSjE4'U4=eEVbtG<8'ՠz0bs/6s#EioLa~֡ZBk [bk(zM{lY/dmoy-)38%.l{̧ #l$-?O3*GtZJ)9BMj0k-KS]z-P .++s4ʏ3Em^ g>X~uv[ʲWwk7;Z)Q]#:E+4De7Klts -%ޮ 6$c 9_Fˆ`sQ4ڇQn@0꬜,1tBluMoY;؁'ړI_)v'(duZ'o=@;Jm[czwX[_;C 5$śN\UJ'U)tJ;cM4 Srйm[aE@e>N0K 8Is/:Pi3N:?iוYf9k;rh2r8N9бP "`V2`٭ ‘%:٭? FP.mOKa/$5'5d3}?ƒo*sq S=gT=#*,>۫kg7~bq=Yy.ҟbQLN~Ls0';7 6_Fծ,;a8|?,B$ul;g`|1KݽMGk#L}|8M2$yv&:fc VYy8(vtCk m'NռvJLKCVq`%Z~bHŒQbs|-4,*Lt/^1U4 P=>:p&AjDK$n3y>}%e8ʄlk{Xێ^Φ͛>y<"&Ԥ.Lm41wR~yyoS舅wBHx-'!b,uc[xBD0Aa-8'9aA/u=#\yVxݦ6u@*LaǂR=ӬJ bnE5缡 +М΄^?.?hN:&/Rv3ggYtprQ&nb8(*|g/.]Hr{/=\8Je$X׈X?k>MsQ-k\kN..GdGRHj:uڞEsP35"aŎXXbGx#㨻8_]rʯR)e'[KL)c(T~s]϶)Pk"y( K?=B@o/ȝo&WvAt㽔j|.H^C~jcVy?O~UL*9Esl;lRqcn c[P^'<{j4Joa}}08Rgqgŭ`E5J^|JO9cјP @)uҢG=%EZMÉXOڶ=$x\vdla'(bT%Ҏq&TĆ (2(5wR$88euu|c!mA?5>a L Ä g}Ә@}ŨYs(y\)+ +t妃'rk=K{3~yͥyIj;l řרr?W`G9Db☘ɞWE +*eoRz +ZE]k'Io] +.2]^ij=[0Xl1[}[d@%0M~V8=ag vAN8kzx᝹h׃K +Y7aQ'm-6US 9&4'gG,i5dSl c\l7$Aޑ0щ j5RV V^1XЬgUYoΖyTܔhy!|D +}ÂqcV. ⛥؂d5ˢD]3Jy]p[[bxYT /RCr ήy|C-,dkgK";c_IK/vzݲitNl"Ϗ̝[Ε௿U^M`B*b08 E8owmY@6Iq98 +=T%ck{dJ׽kzdW2.hSc|D%EcS+IB5@/-b=3(`=iWȠ|< ,G;Mv72-eB|æi5NиBT}UWs(0U&$7MfIRJS;a¥l8M ,̣,T,;qp#Խ+F ~2W"6I((%Qsʑ7 #' '^?  7yx"MU:nrQ}ۖ znůc-R#'$[R#&&+1K6iRi*013E:7`Y@ 7w$7I&fq%6uHWw&{pX$Ux@[+iYsjKcX|҈ShMR,۾х>; SX%@ +p@5ϥ-+%QJeCXRZ̹q4B gD8NBܵ(#}& +nM0k# + br&t8wM +4gbH Vyc1Z3WdVjh@DRcM6C!Tg udhQ9{YONτ#JC{h?k +@/'~H*Xb +2ST1[.sAg&+m +-*88J~p}&z<'r1H!HZ>y&>3?r,Q4̙X0'ߴ)Q\Jj7غkN}=Μx-uXSHrҷ nd5jYlW})V=YdtFbu_n% -赴T^5SSƏ b׼̶֣DBNJ<ƽR{0>-UC{ hѩLqaկ54MpG o/: a91:w s֜ؗ0Oq8@H6zĿׇ`7+FdiؗZN(H8uXJrlRM痈<:Vaől9"a9Xړͧ>~ ioewIo>R̅X.%/4G.9,)1ANS>9KQKgbBT,%Ku `Wi8F`=9q5InadP6|e|- +ɓ O"E-#5! +)McYő +whh#2>I`¨$akU3uR ++89,\ܛQQ1E/ʔV#6PKfqG1f΄sx#-0gՀA3^ZDK]\-ҶE-mQB=Rف[M1ܶY$@ +TW N?ĘCu*gvFU'q& ;ҏU[,EöDjH;8)ҁjlR]^t~re?.n`߳9*ԁԇ%j^GW|\@l= ge#w'-ځ۠u>~耪f"tJs] T4aם(9Ab-jM ||@[TAR6Q rZq"C/eiT'>uUUT9?Oe[ ˚2aVi_ϑfYFfW݁!וW[E0AT,je1Cw1N3!˘cLfJ(_mx%oDyƓ5q ړd>C4QO5 N [Y?~g.=-DldkD"^}=s"q:dH4qC{Ee?M]ExW%rf6knU:*9b{U5FX\ G(PaLu= ˷by1-i[j&@1羚KKx^-H4q ^WᏙVX F9l̂L;qD;1qxI&.#+Jj14,geN2Y|~/hx'">t%&yڃ"KQfNGg5}AṀVNTZo=),Uwj0Z,NHXxov ܈ iI1Q0vȳ2k +@$jzz]5 ڪ]#-p%|obԀHK&\.\Er%iJ?sj56Ix m۩\s1N5&43JzEIVXGi2v#m ƭNeR%+W{Ө̒Q~NP`wyDO.rgԄv&sëi!{r˞|׉k\VaYӇ 5&=Bx=X[NDpTzl=A)L}QfPf/'lR .}"4F% Ahdvv1;#n%ȍ3zךL y+ v̕[(`Cc9*+C9O/ =p7-,L5M¸݈mXPNjąu孞tֵ=׍*lU;OG^3_ ;5 nc(<'gY-},-3#ft+ *lIa(q%L'd%lt֤s| +׫_gy>0r&S6S ^_yA +]`M ˱73`IWБL+yPw9tzE,]ojbSlAC4(isv)er;,^YJyx~6`/yiYbt +|rH)+\x]p$FƚbakR-|_H|{d9>Cz^M4.C_JMNhncbIb7C/#?c-x'>Rukh!)o_>4qMJ7 cm"=`UJDT&6IޯCͬv4zlV-1rͷ[\1;nA3ŋSiЬE6%AdGyV}='Tm Y_G|dcY<9J$Qo _"{s:P]=Ae]w^4N^Y|?s ĿnBJDGUDnU[ϨE7T`5є%i,be]; Di+Ztd"fADvW/`{oyR]S͇NI;j1Jn4E%C͗`6Jdkba:J\ub̯ם e¿ɹ$1ly ,#sK?!^`*.U}A qSп:e76"3կ=nw,'ҵ2rl` JPbMAe\;A,pt74zvuWM:* zp_Izu(viٷ[ݯuaG`K"\pQl;t",,{,L0v!ډ.;"Q%oκ&XGzljo%2{up3_4!uy6dAĆC> ^bUs\έy CdwxpN~#[-{rYujW-*n aQN֎)!˱78~3 +BJug,P4s/wmrܯYa|fsڕEb˴յAYŔ2KPBO߷s6e6&574(Vn(j+ٶmR kAl׆>+g7E{[!9r4ZfF6O|O`2ԍ<1ǥ-eۣqv]b1aj7{@b/ \Me\"d6uUD=pb(SG| ɆYY] k!D0s]y Ȃ s|['E*BleޛǻLsII hBA ne&f+?1ڮRW^B՛r̟ cyE4d[B%ܟx fkbe}mZeze:Ih̍SxP"GBUuPZ6|.dI&N̛}\d"?,M4mH y81&yRX0G:{v'T[z L =: owiMm .1IEZ/^&gj̓ dcVx Lg'Q[K&W *MڿH\ĨWpݽ] j$sGS$kn28AGH:~ ,Ke?jH2PXaqE_kΖɠh8?8+o:Y1 +e=(iy+Xl +qk✂'|ϥEGq@&ں\Ņ|_s]RkPBq=xN@{/In1I$C@FZ `jV4cɹ8( +`څ#XPǎ3%f}{q)?(H, gt7 tĉ}'5Y;)axTTNl(++Ń0-z`YOu0܊6:",9SSؑ_ӰI;T W4%V8>/ I̲-:C^ñY=#c-f.x' 9ɔ,'v WSl;Ş;dGR(34r :O +ó+pND2 lbVK~؉6U[V_](|ip/"φ0gZU4kDH%J~BnX.ZHy?U};e'#'γh;{s%<-Q7f}~q*ʙ&8 a=7Ol#&@|vA&.GN+t h&ȶz6ʝa>Ș+; RS>gH +1}qo ~.MD tB{aFy(\yc18A:?^Im +,%(Y( d~/=; dޫqA;\ 2jM*qw^W8uܔ+EWgGL՞\^?h.E/wM|oo_O??o_7.7kp\^ǗO/~׿W?Ï_?߼O?ӏ?'W? endstream endobj 6 0 obj [5 0 R] endobj 20 0 obj <> endobj xref 0 21 0000000000 65535 f +0000000016 00000 n +0000000144 00000 n +0000014358 00000 n +0000000000 00000 f +0000031035 00000 n +0000088517 00000 n +0000014409 00000 n +0000014747 00000 n +0000031334 00000 n +0000031221 00000 n +0000030083 00000 n +0000030474 00000 n +0000030522 00000 n +0000031105 00000 n +0000031136 00000 n +0000031407 00000 n +0000031581 00000 n +0000033000 00000 n +0000038333 00000 n +0000088540 00000 n +trailer <<030446611B2C4A3C977BCB0D4BD19E13>]>> startxref 88739 %%EOF \ No newline at end of file diff --git a/docs/_site/artwork/draco3d-horiz.svg b/docs/_site/artwork/draco3d-horiz.svg new file mode 100644 index 0000000..d648d82 --- /dev/null +++ b/docs/_site/artwork/draco3d-horiz.svg @@ -0,0 +1,323 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/_site/artwork/draco3d-mark-180x180.png b/docs/_site/artwork/draco3d-mark-180x180.png new file mode 100644 index 0000000..5d138fc Binary files /dev/null and b/docs/_site/artwork/draco3d-mark-180x180.png differ diff --git a/docs/_site/artwork/draco3d-mark-360x360.png b/docs/_site/artwork/draco3d-mark-360x360.png new file mode 100644 index 0000000..4dcf90d Binary files /dev/null and b/docs/_site/artwork/draco3d-mark-360x360.png differ diff --git a/docs/_site/artwork/draco3d-mark.ai b/docs/_site/artwork/draco3d-mark.ai new file mode 100644 index 0000000..5268690 --- /dev/null +++ b/docs/_site/artwork/draco3d-mark.ai @@ -0,0 +1,364 @@ +%PDF-1.5 % +1 0 obj <>/OCGs[5 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream + + + + + Adobe Illustrator CC 2015.3 (Macintosh) + 2016-10-31T10:57:44-05:00 + 2016-10-31T10:57:44-05:00 + 2016-10-31T10:57:44-05:00 + + + + 256 + 256 + JPEG + /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7 FXYq7FUm8y+cvKnle1F15h1a10uEglPrMqoz06iNCebn2UHFXjHmr/nMz8u9NLxaBY3mvTLXjJQW du3+zlDS/wDJLFXlGv8A/OZv5mXzMuk2Wn6RCfsMI3uZh83lb0z/AMi8Vef6v+fP5xaqSbrzZqCc uotJBZjrXpbCHFWK3nmjzNetzvdXvbluvKa4lkNaU6sx7YqlmKuxVM7PzN5ksW5WWq3lq380NxLG dtv2WGKsp0n89/zh0pg1r5t1B+NCBdS/XBtv0uRMMVegaB/zmX+Z1iVXVrTT9Yi25M0TW8x+TwsI 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 q3+UemKvrryt5n0rzPodtrWkmZrC7XlC08MtuxHjwlVCR/lDY9jiqa4qhr3U9NsFVr67htFbZWnk SME+xYjFV9pfWV7F61ncR3MJ29SF1kWvzUkYq57yzS4S2eeNbmTeOEuodgN9lJqcVVsVYz+Y2p22 leVrjUbrzJJ5VtrZkaXVooYLhgCeIj9KeK4DcmYbKvLwOKvnzTvPGv8Am7VZdJ8l/nLcza7L6jaf YanpENpFcso5cEnVOKGgOxj+QxV6l+TnnHW/P35V6iPNGnRX+t6fPeaPqdlKFiiu5oI1bjIArInM Sqj0WlakDtir4FlqJHBT0zyNY9/h36fFU7e+KrMVdirsVfaf/OGPmptR/Ly/0CV+Uug3hMS/y294 DKg/5HLMcVeU/wDOZnmFr/8AM2z0hGrDo+nxqyeE1yzSufpj9PFXgWKuxV2Kvq3/AJwj8pAReYfN s0e7GPS7KSm4ApPcD6aw/dir6nxV8CQkap/zlKGLCSOTziWBZdmij1GoBWndFpvir77xVAeYbprT QNSul+1b2s8q703SNm69umKviP8A5xEtDP8AnNaS0J+q2V3KSO1UEW//ACMxV914q+fv+c1Lsx/l lpVspINxrERbpQrHbXBIP+yK4q+LMVdirsVfdX/OJnnWLX/ytg0mR66h5ckNnMpNWMDkyW7+w4kx j/UxVn35iflh5Q/MDSP0d5htPUaOptL6KiXNuzftRSUP0qaqe4xV81a9/wA4ifmB5Yvoda8larba 1NZSCe3guI0guA6HkoCTGW3kpT9phXwxVMB/zl1+Y/ladtI87eT4zqsAo45y6e7dQHKOlwrA+KfC e2KoHUf+ciPzw8/aPqJ8k6bb6fDZKDexaewudUWJusiJIeZQdC8UVVPcYq+dNS1DU9QvZLrU7ma7 vXP76e5d5JSR/MzksfpxVU0jXNa0a7W80i/uNOu1+zcWsrwyD/ZIVOKvUrP897bzHaQaX+aWk/p6 GCi2fmKxK2us2ncNHKoVJOPXi1Kndq4q9a8ofmh+YPl3Tf0jomoD80/IsNPXZax69p6HtcRHlK3H f4mDA0+0q4q9W8t/mf8AlJ+aekzaPFeW94L2Phd6BqAEVwR1K+k5+PiQDyiLAHvXFW9F/wCcffyf 0TUbTUdM8upb31jMlza3H1i6dkljYOrD1JWrQjodsVZd5b8s6V5etLq102P047y9utQnO1WmvJmm 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 + + + + 1 + False + False + + 6.944444 + 6.944444 + Inches + + + + Cyan + Magenta + Yellow + Black + + + + + + Default Swatch Group + 0 + + + + Document + application/pdf + + + DRACO_ID_mark + + + proof:pdf + uuid:719e3667-786c-f34f-8712-210d238d46b7 + uuid:0b647850-d2df-6b4b-885f-97b4d2ac81ad + Adobe PDF library 15.00 + + + + + + + + + + + + + + + + + + + + + + + + + endstream endobj 3 0 obj <> endobj 7 0 obj <>/Resources<>/Properties<>>>/Thumb 11 0 R/TrimBox[0.0 0.0 500.0 500.0]/Type/Page>> endobj 8 0 obj <>stream +Htώ&9S |5NuB0./fj4ݝ.Ό˟?|^5Jǯ+.ח?\? agݫysoz~vڮhwkڸg"\ow^ ż޼3j\p;b]c3NhƸU}tgk4~ <'*׹n~#^3K#5WK|8Vs'w2>|=^-?92>C޵'Gv&L2e3^ɓ]OP? 4I pE*K-4q̓N6;aC'M6I{&EK~(^֨+y +)r`zB3wզC WRg&AX@Vgr9Na`;]^ K AM{WC݅%v+:879vQA(,c]5 ޳ݛ0gCZav߭̋L6Ҝe`uR8J|smm6ա: *\^`cU5hA?.rܭy;l%6mw!2Xud6i=jn,!Qy¹K*<±Z89?-'#^@I7aH:TՑo y[ ]b^;|2pq&NFq!4jI\"#CdEY u!\ʒz𴺉 K-%fEQ3sݬ$vNHBBќ + - I.Ѻ6"rr5V{55ADhڵ9l7$TLȂt*9ULƊCm.* YkêYG45$ +L4 i& 5! b^1黩] 3f{bi¤fEos02.vjpр.HhP fsj8 H-/Q&MAkT) rBH{D)k,DD:(@u&ky`*E%w8[-M-axGBE.#"%lIaTR3WVse-LmM=mI8r&,T+FėFd&f} @ 8,ͷWO㱼%`ZbI#U울T3kEI%QrV]wY|6q+(HEDayzv8$ti=9d!}=I,y$5``DeIi5{'2,)0x + 2 IvjueI˻M:a,qeq+ir[N_l-AXӽ䊽da +y8-L툧 m [dG.nyOW. ]sض&O̱[o0[:W$I!}d[A}I0NBiqSM@Jwb ($<!I\v5QP +1H5ՇAp% s aI=-]jnCpib@\K,$ǾU>N. ;S;ke2a+%dW7R"j^^%Vn}E]mQ-i +zY,tm?y8洷Yn;4',e +&ޯ.Šrg!VyvfT@`Rj ٠4c#lX<Z;fImĉ[6emI0  xn8bMe%I +YM1fJM!ΚB|3_r3E"! EbƖ4=TH6[64JwZb!H+5RP 4%8 +EXúT*m" kN qR9e %)_7*9zD=uۣ6Bifi]MҊn'R6.G$l^-"CBw'.{{1M,63άDFiF|lw8o<# S_14%Ld:]JA-rv}fj)|Iw2-Z"[;/(LKBBy'"$ _3]/{N.iY ZQ|&n 3U5\H/y?3VҒLՇ/XHޕܻf$F ?n_UGX[ev*MõM2"Ҙ[٦6oB$#hVOGO8ƝRlSaH(u tt]6m$&+\JՕu^,nYM$sz"agrs(EuTU#d2RrqУ3uiJ +j++ԴK{/80 mT)ť˦ +TTiwi;6v?[2J8DI䜆56URב3&[e+ռ*^>~II[D{\D#?(,u.$;n u +]x+k<_^u'W"FY`ۆ;+R:5?}`]]ggvCfÈ^E`X jvlaqE/M<ĉ b]Ιkoڰn[.Yc0?:ٱy}`1;NAsEϒ5GMO 7a_(DZՇ<9Q G6)P K7T$$ɶw+ǡ;]4Ϋ{a郵MS=M[.ԦͲnVH1?Η;)mcY:1|{S"!?B~MEHmKd>%=xZ-7}?(V3IűYpXD2^fl-Y.нL@䳛;u3-4ZQ:T [356<5SmrtiW.vEyWWtrf"*c=uH 6$ԉ0_r |uqC]itӉ7vOiM0=- +Fp⮓N 5,(}(?XV$7ƵMΥ +%[0,J'u0^UJHmۯ+ +p:(i=gC,>9M%S +b/,U#:<\4gy^@; vQLsg;6P.x̿ݱ}̆N,AXqళ-_jԁ,嚭ni'69co+/Wz=(ꐜkztnKXXtzyOLW :j)5?W[Bp + Y8x.xsvUM܂yn n n-@?n\9F!thޝަ.˙)-"BA_yN ԘG U9)qt-?m>unE~[lվjCI$ iOҀM~S0X:1:u[coWџY+t.bmabj^I>(`銚Pl9 ^j0VǸew :Jkg +^"&luFwC5tTH~e^[ۀ!2w-[m +:dn n2*ՂXqzZt#;ܝW FEx@FڻOZW>^_@]tTh:%}kӘȔ -k 1.V$Av/qnŁ^ZKg5 Mݔ, bz%Dʚ r};- VE=%lkaα&ϾZĤɏT>-Κq:)V;1Sf$3OVzO/|.-.ɱ5Iwըq<-zS5~{/m\%]`Dvfy3 I#*Ǜ}~x)ufgGُ 7L>O_|D`[}x[ScQKxD qfG~U=րrc=Ћ^'y1wRYO~O>nߧ#r<:ֱ({tsq}֦;Q_$ƭ>-A-FRbe.[bi#PKd6)#XE_Zzg*PghE(1э5CB4G?zxze;D4Y_X⦬sfFnP*Xt->ܡk wlVS2Jƾ74Ė;nk^cKavFnADl_ƫsȡ4D B.Кʔ.XbHS˿6k +Q67tG})&QMdnSMDhb" R~qܝP0+Kk-kjC-Ru4C,P;sm[TXɅ\L+rOf7(c31.jACAqx-܊_ȫ,B(yN:Rwm H}tM'}d7;C"?'ɶF-s_ +mW!fjs +Xߋjm$h+}(,eޥMY +!/v'⋽!;ŏyXý =d؀}f ._ +(]k—xYbci]$'+c|Tu_,]&|/8 2ijeD_~|+]ݺ-݃ 7܅v/5IY6.k D" jjs /aV/F$_̈́'e|஠8.4!l9\Ulru^Hzଲ؎hu, | ['., ls|@uU{ +%20.SK +8CNBp*`&XfyD/#׼E eX!%]6<%1XD.2 +Nܪ!T"rAx`%0(GxgEoZvzCKPxJd=5xK,^}HL'Q#2,Z^nf(l^DoM[@xQ\a>ϢXB:S= M}IH&,4#ajA>F%D8 M?[^?S)^Cm=G֊կaO8zE`OE )bu|+N >r'W.OKVlu)ɚvI(A,3./Ǚ#?d7Ѥ}O0"Bg I6h>"}4@VA[@]N5dn2Ÿ7 qF(92kƼrBSh8H+Q~zUgm}K`RLv%Ov߁R ǩgW`V"@4&du+s;bQ8)`K*DP$X"ͩ=?``*j,xpG'+.E#FVY0Z(;䋨JG.‘5#oxjŤ^CfTM]| lWBY$;_4-Y%N7O/h +3AF:] :xD8 F/OnRI90+gF7ʩDI+.s[?51ؾb& ÕgSZjd#qSP,p為uF[E@l'+WXw5x:1dևR8>BLGsRGxoѴNH۴bYJK*#$8 xTBO|Lɳ*وvXUR}*;#e%HFKзkO dc-F^j8rCN<Ϣie02J@^{p|+H8#jELȐQ +7 +vݎjWރn߼MBJ;RTu&KJa={HT4#0i>[>{6LC2 |ş&0lU"# 6Ɵ*j$.#̗;g0}}88mFaBDE6nQCDHeMJÞ?qu ӛ|ɓ8;ϟb?ܜ-% 13粜JHC ̩+dAAC\BzE^Q.KMe$?BGHa . *A0 kw7` ׿}zH*QB\^A _Na8Jpg%Nn1~pIGa'Y6'r]wJ1CTIf9(j^w`aRQݴ)J*/xQ G`eR%".-@Ѻ ,Ti{ T9|BF[|RK~"J)M5R.&SS +*0/P >Tw(m7c a!Zٚ22 +.؄Z5Ȥ[,g(.!PyHiobe:v>|~8yWM $S478pK$Y3~S|ܸ/gFIN> 1(DnBw9,B~^"',ԍ<n=1vґ:i䴘!nrcZt+)Ou7.$lXXCch4+1B[چ ﯭ2ۏ~Kʌ@灹8F/7jr!|­S+(T~,kO%X?I`#(o6qLo:_!։b!(A T ?1_·gLȯQ\5P+s:;ɯS0x5,+BX頴2(mi*Lѭqb5}LFwsdETOJ8 _\m~A?wuۍޠC)t;Rz xPq6fø;5sXɍu> lu vކ1_o7JTМ K#rowIQK3vR=ZL(JiHk lΝ.$UyG KBRuYQVz\ YA\!d@+EY=Z˩p_hXuA/8T8SBgWieÂ3p{i@D@[ jիD,ފiFIK{g*cۉ.B)+/#hqyݳRPUqÕEBFK{b5^Glwn +gPzsjbmf,Wq@uQLa '{"M 퐄w%1Picb06,,@%@rAjvf ?T<"RQQ0Ow%{OVw{"Ȳ|DgeV/"'U4͆`*=8Öe˖b?+5w(3;Cj~ob%no=̙'t#)6^1dAcqOfL0Oɓ;^ZIH DsDb!a 8Px><=n\_{fFuQn6&5Hܹơa3}JpqyQ.%oXU 漬N\=3y ?xr EZԎ xԗxg32a#-bo3:UDe~'cKb+)H +.3;27F[I7v[L-Ē>n!LSʝR>pwƪ 5[V^+ջWW 0";\_)Q|q +bdSfd!++nQ?-SܭNC%DW-M xJ,fn'J뱊ϑ| HZq1~. \)1K(6'ԟϫwJ +$|BfF^jy56س܄dƔCaWU'.kn*M?isL8?"ygٟzTa[4%QS婹f$H$K=na`گdݚ qV%<"KSvf9y$gگ!;:MQÙoҾ8dH~uݠJy%VW4n/4o>ݣaqthz#r9*[X hA( 8.H$ ΍aVK*T*>5|&Nm_'5WKFC-lҢtO6P<>nVt_u;仡[u,W) w-%&-,V<iGz9p{)+B,;M`l='ņ48sVJV=FhcQIA8lj0 ap+P2 +ˁVlvWGc .Ce\ܪ(c&M-RLF,״<OͪxG c= +cǩNIh^}i,u8KJw/nk]$K`oouo + H$@P0@΄C$B!@ eį@s + od^ނ8&u)c!.\pudY"Qpޫ >imv'$֍5::DUb{8B LZZz1&o(LE@CQ[KbHƛ D\Z9 CĐp8 p.yh77"x,3(8V]u;~ln|_py`A1u>%%+_z S޺Qb;2re(YΉq=uQe<I6 `,;pQ)C~DEV Xe@r8 +̨VDΉN2j+=pE1EAfJ"̸}5]-G{#Aṇl?wXKceQO5 +UXAL|mɼ186AuJbP&N댝q x"9}57.hVT/=$J݂!#gsUqVtq& XJw(j\ON)Y_}y#jӕsc kL fƣVG)2JΟ + ndž5+VUJWCڑ'ޑ j'>~s(o'vi{ƿ 5wŒ?q&cE߬))fЁX7A6q\wwZMPHxtnRk5NO&S_G{~Ӛ?aK̬Ь_!<ሬH>OzJ9Ai*&w'@oqT|MތߘQLg^ېOo,3|f"]0}f]78c~Ԥ_=$x2E;BKTzVw{)@υ4FH ZgŎ3)Ќt[lZp*3Lu0m({^JC Ck%=\ q_%=QQT l +ߘF)>TN=v1Hw7$}a&]G^ɌN5-s]ὕIeEֈNmϻ3nBڅsV7'T^x{ +~ +ْ}3Nj+Q]#Sv.S-KQx,>ǕȺVd,[R{IfɽN#O(_b)8ݓQ`fx(˘2S7[V[F}>S)#B̑cs.D6 +ɭtn E'"Zn0%ޤ||JC uJgu>4uQشwK68@W8O":9ڪI+ÌN~^Hʆ<2?aaᘳ!oƕ&!FA#=@Lv:W%F UG=C/ +M G6!rZdp+2Ξ,BZM}i}knTqJw3TȘPAbRVR/GʔQ! +wW hEd3oigI#m֣20( %`~c;`;ghrizU-,?b| wi[".S=P9Y~2О%mEUK$[6f-?C+/)u f>wKGEjf @#ٞ<s\(+>g,eһK>W!}WtOm4rMq6D =3Ry)w~O- Tc2>ʊ#Tx_ C=o+|eߩk+^9zFnk?ah.YaJ }0~3iliQO;EW^;$jq1㼒AOX?m +E@t {K٫2OS]\A~|R_ iavU[|kAEX {6YÂY yu zA]iiB-vV\%G) [$ݚζ*Wmϑio;{d\ƨQvtJ zɉ>( s5JAN~Ox(2lo;61w%tW^Ua1R֔ŎCUW\vyW36a\J "o]dbj_=Hyd]8v@dl8t3p$mNwuU KS#b;jU;7uHu* qbOp`Ne?QEMDf4mPJEed.,kF-()ԸY!~X soADsCBu7R%R$4Y}r o9W =0@b6Sio`7[lt)/ÎJD'4ffv5Qz肔 l^Mm x|&WE4O"% 3+շPUEJsW<l nT'.em˺Iqpd3D3ʄpd߀fpYP Oo4J]6ۄLA<*nǰPEn'(=/s洳@J:5J1C"Q3Z/w;5L*'z8B kAX68^-:Bwŀ;O:4 x9ynA'SLV $Y8u`R+qɦrԹֻiyP$gr뉹޴Sߵ Gwz&O"Ta?XGMdR!:TzylmVS\-rI۵UO]bqC$í,\_92=eb5CevCK1dvuc=O;_ElD㑈~F$w~ʏ}ӊ~O]ޱd$n1on%UE3I"O{d!pnJy[S'GFwLɛxk4b冶-m,7<<г!tVg_[r8WCB?!^ipm6H t!#R\ NХ޺euTO\ן; "{ ;ʯ\ow`Abc٨R麆Xq!y'#^23tD cūvT6Z? Bkf #>$6@x +To`"JiE[yZx7dL'L^@)#*b!?uqyeP. ٺ8o|׫W^|*1:??A4%W.3 <_>'XcU:w_> +$]Q+WSWRUϯc;TL>ul2" ̛:KיNIޟ>stream +8;Z]`>HYgs$j=rDItQSf&h'_$1ObQ1KUT);lB?5D_A.@I^T;S/(Nb$kTEC6ldrX=6 +.5#jRF7'Bjg_L@J?,`mje+<5e*)n78%7ZNGpRaKMG=)(Vj`gc1M[S:ko%s&RBm">b +U:&*rOFi9L82jf +h.iQq4#WqAmjQW-kcFB#j3**/f6X:4Pk;<"a@`PjCD=M/AK!dQNB;Hcgg0(>7R,"P +S+'faD2*87$gd;>ju0U/i=(P@IiF\K0RbJ)\A]+U`mh=@06$>pb^%5ahmMBm&Ui4@ +YL`b/f endstream endobj 12 0 obj [/Indexed/DeviceRGB 255 13 0 R] endobj 13 0 obj <>stream +8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 +b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` +E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn +6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( +l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> endstream endobj 5 0 obj <> endobj 14 0 obj [/View/Design] endobj 15 0 obj <>>> endobj 10 0 obj <> endobj 9 0 obj <> endobj 16 0 obj <> endobj 17 0 obj <>stream +%!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 17.0 %%AI8_CreatorVersion: 20.1.0 %%For: (Abby Lindstrom) () %%Title: (DRACO_ID_mark.svg) %%CreationDate: 10/31/16 10:57 AM %%Canvassize: 16383 %%BoundingBox: 60 60 440 440 %%HiResBoundingBox: 60.2979633274945 60.3760065136557 439.703031687162 439.624020110948 %%DocumentProcessColors: Cyan Magenta Yellow Black %AI5_FileFormat 13.0 %AI12_BuildNumber: 174 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%RGBProcessColor: 0 0 0 ([Registration]) %AI3_Cropmarks: 0 0 500 500 %AI3_TemplateBox: 250.5 249.5 250.5 249.5 %AI3_TileBox: -40 -130 540 630 %AI3_DocumentPreview: None %AI5_ArtSize: 14400 14400 %AI5_RulerUnits: 0 %AI9_ColorModel: 1 %AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 1 %AI17_Begin_Content_if_version_gt:17 1 %AI9_OpenToView: -520 754 1 1928 1104 26 0 0 -4 37 0 0 0 1 1 0 1 1 0 1 %AI17_Alternate_Content %AI9_OpenToView: -520 754 1 1928 1104 26 0 0 -4 37 0 0 0 1 1 0 1 1 0 1 %AI17_End_Versioned_Content %AI5_OpenViewLayers: 7 %%PageOrigin:-55 -147 %AI7_GridSettings: 72 8 72 8 1 0 0.800000011920929 0.800000011920929 0.800000011920929 0.899999976158142 0.899999976158142 0.899999976158142 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream endobj 18 0 obj <>stream +%%BoundingBox: 60 60 440 440 %%HiResBoundingBox: 60.2979633274945 60.3760065136557 439.703031687162 439.624020110948 %AI7_Thumbnail: 128 128 8 %%BeginData: 10786 Hex Bytes %0000330000660000990000CC0033000033330033660033990033CC0033FF %0066000066330066660066990066CC0066FF009900009933009966009999 %0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 %00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 %3333663333993333CC3333FF3366003366333366663366993366CC3366FF %3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 %33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 %6600666600996600CC6600FF6633006633336633666633996633CC6633FF %6666006666336666666666996666CC6666FF669900669933669966669999 %6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 %66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF %9933009933339933669933999933CC9933FF996600996633996666996699 %9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 %99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF %CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 %CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 %CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF %CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC %FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 %FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 %FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 %000011111111220000002200000022222222440000004400000044444444 %550000005500000055555555770000007700000077777777880000008800 %000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB %DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF %00FF0000FFFFFF0000FF00FFFFFF00FFFFFF %524C45FD35FFA87D52522727F827FD07F8272752527D7DA8A8FD64FFA87D %5227FD19F85252A8A8FD5CFF7D52FD21F827277DA8FD56FF7D52FD28F827 %7DA8FD50FFA852FD2DF82752A8FD4CFF7D27FD32F8277DFD48FF7D27FD37 %F87DFD44FF7DFD3BF8277DFD40FF7D27FD3EF827A8FD3DFF27FD42F852A8 %FD39FF7DFD45F8277DFD36FFA852FD48F827FD34FF7D27FD4BF8A8FD31FF %52FD4EF87DFD2FFF27FD50F852FD2DFF27FD52F827A8FD2AFFFD1FF82727 %527DFFA8FD30F827A8FD27FFA8FD1DF827527DA8FD04FF52FD32F87DFD25 %FFA8FD1BF82752A8FD07FF7DFD0EF8277D5227FD22F8A8FD23FFA8FD1AF8 %277DA8FD09FFFD10F827FFFFA827FD21F87DFD22FFFD19F852A8FD0BFF52 %FD0AF85227FD05F827FFFFFFA852FD1FF827A8FD20FFFD18F827A8FD0CFF %A8FD0BF8A827FD06F852FD04FF7DFD1FF827A8FD1EFF27FD16F8277DFD0E %FF52FD0AF852FFFD09F82752A8FFA8FD1FF827FD1DFF27FD16F852FD0FFF %A8FD0BF87DFF27FD08F8275252A8FFA8FD1FF852FD1BFF52FD16F8A8FD10 %FF52FD0BF87DFF7DFD04F8277DA8FD07FFA8FD1FF87DFD19FF7DFD15F827 %FD11FFA8FD0CF8A8FFFF52F827A8FD0BFF7DFD1FF8A8FD18FF27FD14F852 %FD12FF52FD0CF852FFFFFF7DFD0EFFA8FD1FF8FD17FF52FD14F87DFD08FF %A82752FD08FFFD0DF827FD14FF52FD1DF827FD15FFA8FD14F87DFD08FFA8 %F8F87DFD07FF52FD0EF8FD15FFA852FD1CF87DFD14FFFD14F87DFD08FFA8 %F8F8F8FD08FF27FD0EF852FD16FFA852FD1BF8A8FD12FF52FD13F87DFD09 %FF52F8F852FD07FFA8FD0FF827FD18FFA827FD19F852FD11FF7DFD13F87D %FD0AFF27F8F87DFD07FF27FD10F8A8FD18FF7DFD1AF8A8FD10FF27FD12F8 %52FD0BFFF8F8F8FD08FF27FD09F8277D7D527D7DFD19FFA852FD1AF827FD %0FFF7DFD12F827FD0BFF7DF8F852FD07FFA8FD0BF87DFD0EFFA852F8F8F8 %7DA8FD05FFA87DA8FF52FD1BF87DFD0EFFFD13F8FD0CFF52F8F852FD07FF %52FD0CF8FD0FFFA87D27F8F8277DFD05FF2752FFFFFD1BF827FD0DFF52FD %12F8A8FD0CFFF8F8F8A8FD07FF27FD0CF827FD11FF52F8F8F827A8FFFFA8 %2727FFFFA8FD1BF87DFD0CFF27FD11F87DFD0CFFA8F8F827FD07FFA8FD0E %F87DFD11FF27FD04F82727F8F8A8FFFFFF7DFD1BF8FD0BFF7DFD11F827FD %0DFF7DF8F827FD07FF52FD0FF87DFD10FF52FD07F87DFD05FF7DFD1AF87D %FD0AFF27FD11F8A8FD0DFF52F8F87DFD07FF52FD0BF87D7DF8F8F852FD0F %FFA8FD04F8277DFD08FFA8FD19F827FD09FF7DFD11F852FD0EFF27F8F87D %FD07FFFD0CF87DFF52FD04F8527DFD0DFF7D5252A8FD0BFFA8FD19F8A8FD %08FF52FD11F8FD0FFFF8F8F8FD07FFA8FD0CF8A8FFFF7DFD05F8A8FD1DFF %27FD17F852FD08FFFD11F87DFD06FFA8FD07FFA8F8F827FD07FF7DFD0CF8 %A8FFA827FD04F827FD1FFF52FD17F8A8FD06FF7DFD10F827A8FD05FF527D %FD07FFA8F8F852FD07FF52FD0CF8FFFFFF27F8F8277DFD21FFA827FD15F8 %7DFD06FF52FD10F852FD05FF7DF8A8FD07FF52F8F87DFD07FF52FD0CF8A8 %FFFFFFF8F8F87DFD23FFA87D5227FD11F827FD06FFFD11F8FD06FF52F8FD %08FF52F8F87DFD07FF27FD0CF8FD04FFA8F8F8F87DFD1EFFA8FFA8FFA8FF %FFFF7DFD11F8A8FD04FF7DFD10F852FD05FFA8F827FD08FF27F8F8A8FD06 %FFA8FD0DF8A8FD04FF52F8F8F852A8FD1BFFA8522727F8F827FFFFFFFD11 %F87DFD04FF52FD10F8A8FD05FF27F827FD08FF27F8F8A8FD06FFA8FD0DF8 %A8FD05FF7DFD04F852A8FD1BFFA87DFF7DF87DFF7DFD11F852FD04FFFD10 %F827FD05FFA8F8F852FD08FFF8F8F8FD07FF7DFD0DF852FD05FF7DFD05F8 %27FD09FFA8A87DFD05FF7DFD07FFA827F8F8F8FF2752FFFFFD11F827FFFF %FFA8FD10F87DFD05FF7DF8F852FD07FFA827F827FD07FF7DFD0DF852FD05 %FF52FD04F852FD07FFA852FD05F82752FFFF52F87DFD06FF522727277D7D %7DFFFF52FD11F8A8FFFF7DFD10F8A8FD05FF52F8F87DFD07FFA8F8F827FD %07FF52FD0EF8FD06FF7DFD04F827A8A8FFA87D27FD0AF852A8A8F8F87DFD %05FFA8FFFFFFA8FFFFFF27FD11F852FFFF52FD0FF827FD06FF7DF8F87DFD %07FFA8F8F852FD07FF7DFD0EF87DFD07FFA87DF8F8F827F8F8F827FD0CF8 %52FF7DF8F8A8FD0BFF52FD11F852FFFF27FD0FF852FD06FF52F8F87DFD07 %FFA8F8F827FD07FF27FD0EF827FD0AFF7D27FD04F87D7DFD0DF87DA852F8 %F852FD09FF27FD12F8FFFFFD10F87DFD06FF52F8F87DFD07FF7DF8F852FD %07FF52FD0FF8A8FD0BFF7DF8F8F8277DFF27FD0CF827A8FF27F8F87DA8FD %06FF27FD11F827A87DFD10F8FD07FF52F8F8A8FD07FF7DF8F852FD07FF27 %F8F8A827FD0CF8FD0DFF27F8F8F85227FD0EF827A8A852F8F8F852527D52 %27FD13F8A87DFD0FF852FD07FF52F8F87DFD07FF7DF8F87DFD07FF52F827 %FFFF7D27FD0AF852FD0DFF52FD05F82752FD0DF87DFFFF5227FD18F87D52 %FD0FF852FD07FF27F8F8A8FD07FF7DF8F852FD07FF27F8F8FFFFFFA87DFD %0AF827FD04527DA8FD07FF7DF8F8F827FFFF7DFD0EF8527D27FD18F85252 %FD0FF87DFD07FF52F8F87DFD07FF7DF8F87DFD07FF52F827FD06FF7D52FD %0EF827A8FD06FF7DF8F8F87DFFA8FD29F85227FD0FF87DFD07FF27F8F8A8 %FD07FF7DF8F852FD07FF52F8F8FD09FF7D522727FD0BF852FD06FF52F8F8 %F85227FD29F82727FD0FF8FD08FF52F8F8A8FD07FF7DF8F87DFD07FF52F8 %F8A8FD0FFFFD04A85227F8F8F827FD06FF52FD05F827A8FD26F827FD0FF8 %27A8FD07FF52F8F8A8FD07FF7DF8F827FD07FF52F8F8A8FD15FF7DF8F8F8 %27FD06FFFD04F827FFFFA8FD25F827FD0FF827FD08FF52F8F87DFD07FF7D %F8F852FD07FF7DF8F87DFD17FFF8F8F87DFD05FFA8F8F8F8FFFFFFA827FD %34F827FD08FF52F8F87DFD07FFA8F8F827FD07FF52F8F8A8FD17FFA8F8F8 %F8FD06FF52F8F852FF7DFD36F827FD08FF7DF8F852FD07FFA8F8F852FD07 %FFA8F8F827A8FD17FF7DF8F87DFD05FFA827F82752F8F8F82752FD32F827 %FD08FF52F8F852FD07FFA8F8F827FD07FF7DFD04F82727A8A8FD14FF27F8 %7DFD06FF52FD05F827FFA827FD31F827FD08FFA8F8F852FD07FFA827F827 %FD08FFFD07F827277DA8FD11FF52F87DFD07FFFD04F852FFFFFF7DFD31F8 %27FD08FF7DF8F852FD08FFF8F8F8FD08FF27FD0BF82752A8A8FD0CFF7DF8 %A8FD07FF52F8F852FFFFFF7D27FD31F827FD08FFA8F8F827FD08FF27F8F8 %A8FD07FF27F8F827FD0BF8277DFD0BFF7DF8A8FD07FF7DF8F87DFFFF7DFD %33F827FD08FFA8F8F827FD08FF27F8F8A8FD07FF52F8F87DFFA8A87D7D27 %27FD06F8A8FD0AFF7D52FD08FFA8F8F827FF27F8F8F85252FD20F827FD0E %F827FD09FFF8F8F8FD08FF7DF8F87DFD07FF7DF8F8A8FD08FF7DFD04F8FD %0BFFA8FD0AFF27FD06F852FFFF27FD1FF827FD0EF827FD09FF27F8F8A8FD %07FF7DF8F852FD07FFA8F8F852FD09FF52F8F827FD16FF27FD04F8277DFF %FFFF52FD1EF82752FD0FF8FD09FF52F8F8A8FD07FFA8F8F827FD07FFA827 %F827FD0AFFF8F827FD16FF7DF8F8F852A8FD05FFFD1EF82727FD0FF87DFD %08FF7DF8F852FD07FFA8F8F827A8FD07FF27F8F8FD0AFF27F852FD16FF7D %F8F87DFD07FF27FD1DF8527DFD0FF8A8FD08FF7DF8F852FD08FF27F8F8FD %08FF7DF8F87DFD09FF52F852FD16FF7DF8F87DFD05FFA852FD1EF8527DFD %0FF852FD08FFA8F8F827FD08FF52F8F87DFD07FF7DF8F852FD09FF7DF852 %FD16FF7DF8F87DFD04FF52FD20F87DA8FD0FF852FD08FFA827F8F8A8FD07 %FF52F8F852FD08FFF8F827FD09FFA8F827FD16FF7DF8F87DFFA852FD04F8 %2752FD1CF8A8A8FD10F8FD09FF27F8F8A8FD07FFA8F8F827FD08FF52F8F8 %A8FD09FF27F87DFD15FF7DF8F82727FD05F852FF7DFD1CF8FFFF27FD0FF8 %A8FD08FF7DF8F852FD08FF27F8F8A8FD07FF7DF8F87DFD0AFFF827A8FD14 %FF7DFD07F87DFFFFFFA8FD1BF827FFFF52FD0FF87DFD08FF7DF8F852FD08 %FF27F8F87DFD08FFF8F827FD0AFF7DF827A8FD13FF52FD04F8527DFD05FF %A827FD1AF827FFFF7DFD0FF852FD08FFA8F8F8F8FD08FF7DF8F852FD08FF %52F8F8A8FD0AFF7DF8F87DFD12FF27F8277DFD09FF27FD1AF87DFFFFA8FD %0FF827FD09FF27F8F8A8FD07FF7DF8F827FD08FF7DF8F852FD0BFFA82752 %A8FD11FFF8F827FD0AFF27FD1AF8A8FFFFFF27FD0FF8A8FD08FF52F8F87D %FD08FFF8F8F8A8FD08FFF8F8F8FD1FFF7DF8F87DFD08FF7D27FD1BF8FD04 %FF52FD0FF852FD08FF7DF8F827FD08FF52F8F852FD08FF52F8F87DFD1EFF %52F8F8A8FFFFFFA8A87D27FD1DF852FD04FF7DFD0FF827FD08FFA8F8F827 %FD08FF7DF8F827FD08FFA8F8F827FD1EFFF8F8F85252522727FD20F87DFD %04FFA8FD10F87DFD08FF27F8F87DFD08FFF8F8F8A8FD08FF27F8F8A8FD1C %FF7DFD0CF87DA827FD19F8A8FD05FF27FD0FF827FD08FF7DF8F852FD08FF %52F8F852FD08FFA8F8F827FD1CFF27FD05F827F827527DA8FFFFFFFD19F8 %52FD06FF7DFD10F87DFD07FFA8F8F827FD08FF7DF8F827FD09FF27F8F87D %FD1AFF7DF8F827A87DA8A8FD07FFA8FD19F87DFD06FFA827FD0FF852FD08 %FF27F8F8A8FD08FF27F8F8A8FD08FF7DF8F827FD1AFFF8F8F8A8FD0BFF7D %FD19F8FD08FF27FD10F8A8FD07FF7DF8F827FD08FF7DF8F827FD09FF27F8 %F87DFD18FF52F8F852FD0CFF27FD18F852FD08FFA8FD10F827FD07FFA8F8 %F827FD08FFA8F8F8F8A8FD08FFA8F8F827FD17FF7DF8F827A8FD0BFFA8FD %19F87DFD09FF27FD10F87DFD07FF27F8F87DFD08FF27F8F852FD09FF52F8 %F852FD15FFA8F8F8F87DFD0CFF52FD18F827FD0AFF7DFD10F827FD07FF7D %F8F827FD08FFA8F8F8F8FD09FFA8F8F8F8A8FD14FF27F8F827FD0CFFA8FD %19F87DFD0BFFFD11F852FD06FFA8F8F8F8A8FD08FF27F8F852FD09FF52F8 %F827FD12FFA827FD04F8277D7DFD09FF27FD18F827A8FD0BFFA8FD11F87D %FD06FF52F8F87DFD08FF7DF8F827FD0AFF27F8F87DFD10FFA827FD09F827 %27525252275227FD19F87DFD0DFF27FD11F8A8FD05FFA8F8F8F8FD09FF27 %F8F87DFD09FFA8F8F8F8A8FD0EFF7DF8F8F827A85227FD25F8FD0EFF7DFD %11F827FD06FF27F8F87DFD08FF7DF8F8F8FD0AFF52F8F827FD0DFF27F8F8 %F827FD05FF7D7D2727F8F8F827FD1BF87DFD0FFF27FD11F827FD05FF7DF8 %F827A8FD08FF27F8F852FD0AFF27F8F852FD09FFA87DFD04F852FD0BFFA8 %FF7DFD1AF827FD10FFA8FD12F827FD05FF27F8F8A8FD08FF7DF8F827A8FD %09FFA8F8F8F87DFD06FFA85227F8F8F827A8FD0EFF27FD1AF87DFD11FF52 %FD12F827FD04FF7DF8F8F8FD09FF27F8F852FD0AFF52F8F8F8A8FFA8A852 %27FD06F827FD0DFFA827FD1AF827FD12FFA827FD12F827FD04FF27F8F87D %FD08FFA8F8F8F8A8FD0AFF52F8F8272727FD05F82727F8F8F827A8FD0AFF %7DFD1CF8FD14FF7DFD14F852A8FF52F8F827FD09FF52F8F8F8FD0BFFFD08 %F8277DA8FF7DFD04F852A8FD07FF52FD1CF87DFD15FF52FD15F85252F8F8 %F87DFD08FFA827F8F852FD0BFFFD04F852A8A8FD05FFA827F8F8F82752FD %04FFA827FD1CF852FD17FFFD1BF8FD09FF7DF8F8F8A8FD0AFFA8F8F8F852 %FD09FF7DFD05F8527D52FD1DF827A8FD17FFA8FD1AF852FD09FF27F8F827 %FD0BFFA8F8F8F87DFD0AFF5227FD22F87DFD19FF7DFD1AF8A8FD08FFA8F8 %F8F87DFD0BFF7DF8F8F852FD0AFF52FD21F852FD1BFF52FD19F852FD09FF %7DF8F8F8A8FD0BFFA8F8F8F852FD06FFA87D2727FD20F827FD1DFF27FD19 %F852A8FD08FF27F8F8F8FD0CFF7DF8F8F852A8FF7D5227FD23F827FD1FFF %27FD1AF827527DFD06FF27F8F827FD0CFFA8F8F8F827FD27F8FD20FFA8FD %1EF827527D7DFF52F8F8F852FD0CFFA8FD29F8A8FD21FFA827FD21F827FD %04F87DFD0DFF27FD26F8A8FD23FFA827FD26F8A8FD0DFF27FD24F8A8FD25 %FFA827FD25F827A8FD0DFF52FD22F8A8FD27FFA827FD25F827A8FD0DFF27 %FD20F8A8FD2AFF27FD25F8275252527D527D527D52522752FD20F827FD2D %FF52FD50F827FD2FFF7DFD4EF87DFD31FFA8FD4BF8277DFD34FF52FD48F8 %52FD37FF7DFD46F87DFD3AFF52FD42F852FD3DFFA827FD3EF8277DFD40FF %7D27FD3AF8277DFD44FF7DFD37F8277DFD48FF7D52FD32F827A8FD4CFFA8 %52FD2EF852A8FD51FFA85227FD27F8527DFD56FFA87D5227FD21F8527DFD %5DFFA87D522727FD17F827527DA8FD64FFA8A87D7D52522727FD07F827F8 %272752527DA8FD34FFFF %%EndData endstream endobj 19 0 obj <>stream +%AI12_CompressedDataxܽgC*((@`FsYVH|UաD{9@wQaʡ*8j#+x,,A'Oְ?e:Ϋ97movګqe*Tv~NSixutY(޾+\92tU E>+aUVlQiUQNgخ7;V +$/o^69AWuEU%q̋ #IS9yESyE A9]ҠR6nN;N/'xS?4ZVof ⼈*ΰ٪ JX|#]/?c\5X ka?Gl%mtt}Lȿu8 2イ_BZeY^N"il?nlG7Vwn +:IhA{VoוGci /5sqO7ƫo;6tߚ1XUL;6ם[,pqU`L^82Ukb4zm9lm jl!d2`_9L:5YYmTc{fF1Ukraz.Q/ QPn` o,V^|##I:,t;{6;%o^:AW'Y#NKkY7F&\Mvy>ݝO'Q VUGWR&;؆r%j7ץ/stW2v*J7 +l!6l #dp>[ڀyadB7jWBWZ͏^٬wzgiY}{aߑW[Cy|e d߬T[(}ȤM˫ {xگ62H,*:ts/bi&~Y΋EU &/?͏(Tf2c\ɜE [3ՍvBVO$/X3:?QV?*6;N2 Ǎ_/^uZ!HJԥiO9ៈ]Lc|cc/QgO=i< 9^ OFd!;D3êhD^ gj3xY=L(*N qPPy +&EJ\NFdxS6S_J; yjX7N{пD>t3ʃ/kr_^c Miha.ϩZMau2aSE2" +!7؟Z.t<MDSjzϲ<ݱZ'{hV`wvztK}ksdMc05],X- q7ԓN{yٯ1nd聩5$ßu+5Ks>2;e)haeH+LP1:}gKbBl@,$_\*WjBFxMe L }٪ώnw Ll5lL]ӱ6T-(emy٬}Sb5`?X.H; +gS|Z]3w(UL .2 vaq}vf07!f f62OGEF~sF;0Vz:iԛ︝2jJzYNeg1&8ԨOOK_%gF3ٙgATߤL6{uGpdwC!+:BN5zӫ73? M~p 3Ճ(m7i`/KɬQ{~e+O0;ᴇ-2i>+S* e6Qq´ +w4g̭ֈQnk`6vsrQQcZZ /G;U#tt9 rЀE5lWFW1 ۜ${$պ^q ^s-ء\:~zpl ^=ׯu[?mb!zL訵v?`f;}Vz @y2=}s"K DO^2XLUh=@IJ`GyzblА +.MTirXť*ܧ0>J'2)t hDBq<_As}vzc/'o;n?<'2}8ai*nM\K1ӍbJdPԣ~6.N%eQ2]O?![p~uځm103a̸FY'&5\)Dg[ sn9+<9e I< =vaIi0XATz'^kU 4Vr+`Qeڍ-ܢ2P+L#S%5 ~м29f+NҦF`期^} 1 9C +9N+~͈t/vnkުZg(vFdt^?|=p-f^}K8f6`<8j3 +O3PPȒ~ ۵yN> bF >-txl=;;NB$Lj~ocLU*Ci_iV^]6 "&*|r@Cp l~4 fc֦b#3Bp`yIX>?L)bhDn. !=Ft8F}4F1*Pp2>$xHA;6ݱchfy&A%_Aƻ ޤy, Fl7M9">n)z +T~x1^Mȏf4_ٱUZ5]VB#F\l}oTwdDX;4w]il &cgvAḠSs?9EbI4á_|hqTm(31XjM+98g-5q"y$_tqj'Ge.l'1ʞ:]00#C{HDvx"*|-b2 97b5Muk<:d1u10 07I!8Z6)1Q5Pu=e\_"]D^X;{@N1X];P3Ç3-+S;!V3rl6h\c}dTgX tϊ.Mm6|cxb_D8 \ *z1"q=[U"܈냠u! ޱ"`A{k M隚sߒ`c?xtXqHl_Ȼ*m8s ]_gg:x0+4֠J}T"k:Z`O۰]&*V&L6Qt~]"^/:ZPdo$znH̱Q%/ec÷\TՎ94uE CnN.T+ZvjW܉#M>;7U yL::A>CD<3~G|b9FC_en^t~6`eJ rhm߉حZ@ #]o0ssx= .1NJ}w˳N#ɕT{o/J:0M96Wq;HObN')\4@f6w5u[sI69 _֋ y&n]vJˍJi2g"-o$X2ZOOg^%2ի})N."ˉbB \K:{w4QS{މ\~5dQ-tO~+w#Wz,?\7 +5~QąA"eDUil7VW+4qiivi%.'[$ Qt>L&8sIʉ0XXR>W^/>nt'~yeO@y rAcIװ3XU.+YkPvu_ғ/AK נ{n!U]|&}aֺϠKTzx;^ƒrw5y>) ZVo +KcʖևlE4[3tq;V<<2~C(5aծ{OAy^~ĝ,Aa:WkKG+)]`ϵ7N)Ao^}^G1nރɛ9AoD{:*yzz9ׁkP21^Y^g&zv^*m~zf/]t +RJ7*]D~<,AԾsj]4obEYaa :ʸVA<NFl&pr5hfmNnGYǠJW:}' # +6˹+4:&&Wc zswxQyS\څY߻>\߷~o?Qz58?Ңϯa3ŤwCuU4͜wKsmǒg߷|duAL/5_g[ٯ5b\kmqOZ]}dkܪmmBm)cjo|siu~;䫺߃ۯ[a߯akCAڼ}[kW!X+'VJEsN_@m0)1ƫ\|7',mg i'Y 9/"~ScL3'Z{ !d0w`_xF5 mn͝Yfօ An뉕(n}+:Ԡ5uvPjT;ݹb/.ۃ?]Y~2k9M? +5qb;Xk]FgЇΕC;JlAvt=bd%_wPG{'cA*>ֿ[vvh;eu0>-O ~k~.dMoy#rmdg_>WP7.?6dS VeGMnr1 +9=XF6qx6JIϥӲ0\^gV.p˜9|]DcnlB.G $(y6/kJ1Ɋ]x@91.uOɽB$" ݿ+^wpZ߲P?ģ _Dž2Bb3~yw9(ȾԘ Xtȃj8!8i%<z61>u׹⤻|cu ^٬?LO(>dTɲmo$<ϥ=ڍq&n^eh}3R&ʪEcG}rۙzAh +3saӋ06t~G1&lca2qyØwueau椻Q_){Q(KwaN+7 +y2bDF8cjwC?{7*e.I13 <絹W{-0osM~D ؒ|e\,|qK*%+ P0ow"N %"kO='vE][Lju3Kc6>Sb}tR*uO_p#EؿvBGl(;w= 20;j +):{6bƃX^7z3&XבF RlxS҇&6T9ؚU,D0a⏎Bk608%t6XɶN3(0&D@,&NrPb?]aGj~Ʌ*-eҠ侴{^ΆO4`v Fqj0TqQ<ư4fGf/d`p0pa +7|qa.wK`i3Fmrg]D"d$.._y'IHsx|<$smp'Q}}=$ҖYpj7áS,NY S<&\ɇ#Ru!\`b X޺%BG8< NUz{HXe 31\>Ui?zՋdll1h-u.cDr--X2"W:1sGn7тN d[7Iy|Ȃ6vOl,AtY V-*xvY|]f6->U_CI;CgbW7.OFpa3;7_I/ifwL؏zB5؀~Tؽ?."E*`%7$՗rhDW/n&y=^#}}s5Mbz'0Ջ_ +gԤd6oJ,ȑ?$ a}4g`ʉEK,+,ű(.iK]%O,&H? )FZ^de' pDRU4|qq_|j*bz >KC^SX._꾏DݡlۀX$7.a's^T,ݸ >ya허xk}Lez$@7 +oќExpuU# j2Hp*6?ģV!;?uG&dn㤂$tqUYi 0fH,m[Ѧ:јMU hZ:"9  +D4Ae=@θcg{[i>- ۯ`XRuva_>,jN/!(r` +l=svz(:jg'T\N':~nvr=zǿ/ծ XaՙAf֠b7jںՐ-񥂊o +;e~G>V=<՝}Uu5;n|*A>1 mqoЋTr5' <_}kz(F9micC5 b5w}S]sgKEw˔/?yk\x_t7㚻&|ƺΔݹGE={4gNܺN2qQʢXD{4MɰԅtcZBɊ\Uɩ+`R8ƯJûVSaH"#&Z=%wEh)޳w_&, # +:) +:_N8L*ǽc1w?SԒ^ -#D5=hҼ'qW roU{VbWG}emfi7s:"(YCC=WQk&?]4*D.eΎ"Ƹ^GgU>F-dc\e䂔x;;='s)= c2dwlupgO3, oqz"'Ñ)o [:<2;zI!'|n ˺XX{=LԾͬ} E%=duKn+O T-Gk&o(_߾Z!Ք2#/ޏUsV* WS׃n®ޜE=;B~K'dWG-c +*bzY2x51jDR*5bw_17} Jmv5K^0T\=GոsyN,9ҙ_H/FLi " {4<@ * oץ/?+7J[{FO{紶\6JT. 1 tQן}8g]U{VOz8.ɿ 7|_}ܲ_2^_XY_p8W?޸%߼-Pv.k-өOiZ:ƹdZ>Z?TOJwzA/TwVt J.,=tw|b}2J0yW; +іb#Z bV p,O`'r *EMpFpiӈģ1STkcNnZ?[qFKB12NW! hѫ"VEJ ьOfWl+$7.biYLj$Ok)*XyZASO@/,-c67M沓]Nc6W B0̗;}C6$03p/z"dK<ˁgEF860Z-^\hGIqX;fr ty6r<3ϏwzXJy?CN3r— 4r!})ggD8J6TַGdv`sۂNF;&埬DfT)(ĥ^Ѯ[f: 8t^vE*v6zWNYX-8 \X<}!6R.k̎u#_&ZʱG]Ǯ (<. 䐪hD1K(9/sݗ/]s?/ 7|KR_SS +'%@w& ?j{;j{X5zgC N^ z|_R)lH 5{orZĉR[\ iVI*V^[Ҹo:e{(3/8_?Zj~Q+A#3<~vភ ƹ/x'fTn^`i5 :^M]{D-㛆^l^pn9{S~{ +؛)V}a"5a]14~`XUl; Y9[Ʀ}{&ϣ^^B|_~1A>6{o%!C{ƬJY5{_T>vtx{7~wߤ㾏o{L^?/gX'D/ؠ&Z^[B17OuX6M|Ϛ>qYM_ o7mΕy;H12U/r5~^c!&/llr{ 1r{"ڕS){p{FCǭ~(Sgm~iS\ 3v#a 6ս~y0{ !E/V?znS.1J{G_@kxob9r"y4GI(\t2mkᮐJ/bɯ}j?v[9Mܝn--=% =:ύUs6˼n'̺͕wv!,^zz^J/WέRF>{9weswQ]xj]dW]k_>;\.lz;XąDJ?SB}Y|c-YtSW;iD|}uxvq*]΋g'SYo l J8,=rZm~}m^9,+*scvK/L/^׎=w_8{'Xy+E+Ԩߔzr" L9/O|&jˤAn Şz3VΗw 2䰜?8W>bIsGi>X/2Lze_ E}-~0̫/8]fݤfŇT^6"aϖE"OyE/~RlՏ b6-Vײ<6c7_:@].n(XԺ>`u1L B:+FHom(ki> _ǥĕVP*֫I;Bz>~^Qz8ްzܑ Gp5\h>9\o2|.6+y?&z]KK[*E,P( ˛}W_n;z;" :I>Iݵo>ʸϏyJ~O aZlDG}QZح}\lѸ\K/hкJWdvuּ*]p޺M%g*./.xjL˓ J(>K-].jL|\ ~ą[%wPn2bZFLԥŎ \.etYZ7fw ^3E7er8}>ذog|)aWӄ&?91빏oqM|jpKRLJJ"}cl%明ʭ:Uݬ>9O\^ݻ/=XkrUs/,fq)rDk5.;* z_|* 9!@G)쀗jglT&Bvt᠟3'> +f7>Ce\ETnѓ=H>L-v+B~M&Vn_e"s1oقꉕD[I$I_"H +c BV[yn߷o. +kS'8_jn{}ԅsETg4?"Zl{0vgP~[ٟ/}KB,Yuѿ$O,z]6:!jg[|Q؝_j, K/رvzV 9Q'm$!<;g/,;;yޅsl[ޖמ?J^Fz0B/Qrc*58<\.h̯_n6;_y) &R1hQ*5A]*r~{6`xZp1uXK]7|OpE򕟬{>Qzb{l#x} Ub% vyg%ղt̵}Nj$DC$Xrrb|طۣ:}F&9Lx##":/<]Նԃ)g} zcnJQ-*6>%[IL|L)> 7@q,Kr"PXc4͚WM(MWSM1%{'C0N +]nP8-2aaTz,^ +nz&  ;hi[|kÏ͕Ի\>3<9*+G/y24? ׷w'>cIgxRY>> =Hv^!`5Gyq$~qhD8,ڠ(_aR.~^;cPО¡= hu!bQ):B4)tƙkJS Xr6C`xf,F vl;%.s4C֔oe$Ȼk4Wa|B<4l rtF.uDlßzvdv~uTؗor nn+W^]VKuW7cm,9sXқwŝs).mA/dcteg|mg%'#B鹴|EkPFOFnl`#y:ŽmX5rcSX5!q񱨛ı 8ya`)sح.t&2D%+oCXS(Y-{H0-DP矉K̮)fXOiNh#B@=yr2#!6k`x?QΈ%BӏL1>)/`í7?Dڟ?[=1HP%ĶRL<#㳑)Yo*wFv}e0KAS}i`mWO듿&C_rUOOOl5n'%y,8rR0r{cur>6r \́/mYorƜYD)kw#G&].,,>5|\y6.f/:Fꛝ+ɚo2N1~cgP>=R:yfD%Ѧ`oR1r鳌XӎgAo#H{D]"ۄlt+ v={bKZ!?iwrgҼk#b=LRdLT<+43zY;ceBGG%)j) + C`}_^08鋵)aR7ur$\dDG1b!{ g_F0V;;r9̓4 1D]_yxp3U]|+sWDžG /ka[d\O@6p6_| Wr cPĀlIʔÄ Z[wG_rso 䲾xuK&WyT +ߍ4]gu="":242]PQ82-']j\P)66 Oi۾+-:u+\;={%Gp~̸:0 u7eslHl\ KaQY?Zv;exG Dmم*|s{;fSOq@lo'm,햎\8%ݓڻIe:k΍ &EEӽ)AFXwE"/@ 8u\ı}嘟.PV wtQ}MNu`G&9tyoćȗ HTQn,dpLL.O%Ѯ"kDM*meIAP7U},}Z\x.>Ɖm\ɟ\}!=](!ZyQ:O±|=sS6oXSF)UՇ'we.n@y}3J5h!+1ƵԺOçWMWތOFu6[:[ +oKU|꿭WU/We~(] Ȝ%OizQ%ړl|*Urhw]gK_ʥ\py[na:uwtZxJWMv;Ds6~vX6eij٨(/[+W3n20qKS^sPxʗP>eH=U65N!ex&Ž汯r9}2|)NN\~S"TjpZU2*HG(Ff9gh$+Y!P ½]7ir/9'9zep*R0} 2t +g3$^َbߴrѸn3(ujF{_ WŃM.5jz#N.UAH`p 2/}krR=l%1NV>,KdWX'TJdz>yc5cA`l"UOx(~L)'j*KHz,]YM@mݘ榚_ǒ櫍 P0_m%Ey2_Yk7xū`X+0/rȸK<M) {/.yZu۴gx9j !؈ G52w[{~G,2ݜhR +>c0($J-+닫>$C0b&l̵3GNjKץF {:A`ϱh͛EE^aѫzF4〒MR_=>H'P +{U槺D0%nj{S`~=qWui.Z + N~ +xM*~*峝61, Œzy:{[& TrOTճ!n%/v>඼\Sos'NUŷePzQ 螛wd5cv8+l<Ą{#uDsdKId:6t@P\ vײ\u&Xj#Sq,d An%3 | j;bXQ]w" Aj͕ 9ׁj$d48p\ W5|d(obr8ek}ib>óQ)%|T5ϖ>YU9.'9_`s 03я뙍z@oF?= C?lQ8 tn<|[Λ@[(wʎivaR~ (- X*-iYgx5ASf2$`N!&D4{aS cޗ!FT5!sJ7P_Y xfA0|:@po@/R)3Vfԓa`wH,ؼD}fL| Xҿ Z&bys=}2f,BB~T؅8 A,Nne wA+&M;`сYޅrlQw#bh;gKCRHCP<[rCەc#Wޱfn ǂ}X~8T6y!cAp$ıa/X"!DN,/.娜.,pN< $Y OkyrL`>8{?b#`2WhB#ؤu;3R>VF2QlwcU{ci)JrbfM{:{#h 4~O^$E)x!-'?q32g^a\#'ڣ3NשeG0Ff佲{:wCATDu^gadMtlX9o\ڸ;CÓv 3]ȥ  ;}8Eu_rh;Xz̏sc7{S= ;yZ~5{+v-ڧڻK<+٪Te['M?UnSҎ ;>$n L&,}ӈᓵVYWUW##ee&uS'X]+6]gqq') 0Ys$fSfރ<3O|e~+ٿ^ߺoqS~\0h3H\Q olv:֕`Wc]ag|ױ'`Wc]iJ[%1BۮX2 Oao;fыq_UdKq>?nǸxa7|zR6hvڕޟ*>?99(Wox +ĽAkxƸL 0vu۪ ҕ@!| \$8e4ǔx*3/dzgtIu_1F(TN8^y&JN5]uWhs:+qr,oTAE=.B5D1'J؇ p*'E]< jb5%?6P6@[jƕTM數@'4`$yFT$*]BN8]EPtЋ,*ȂmdI5MyH/s'*TU`𻜪q*^8BN`҆袦+$zX ?X0'DZ" XAI,`P^8-2؋)$, @U$ϩi\1 )BTYE&Β& Êa UI'Kt -ҰNI=BԠ EEb !*@ˊ1 Kt"I4 +"h6GlX8`tE/Ȱ>PT$^8wdUdUBq]lI x?!+~Np+o  󂪋 ~樚щ[*RHi!"NN_0Z@FVI9X* +v$Ep ˓4Mx0q 5!HiRp?&LFD! @6.8@m`10y:6_E㰅#HC!Keq؎jCVDq+)6 +U7y~/ +p0'TܜSC,`S)0^dtH"r|~Q[@"6_,"AtFő e%: 3eDXF$ +h Kd*@qِ ȄT5`0HLI@$PDB*@@*Q.4-d $Lv` A[@Nx5 "@> +G(`PPSTt#̕G*}`NqTvOdͰb+3~ sB-`a5 &%@6AP LP-U86C +%)2%@,C:`-x*;i d&PI D }kP + +$QE[{eQ7ڠ8UTېp``9@$@ ‘BD +2l(QyЌd{DWR P5"@ʀє Hqj%Pب3x`TEeh DOi" = +}򐁣ℬq<*L4"DA͕pӀ,$@)l%85F!O-X8" +PRαMLO+(kH Zcj1"J' ©9f(0H9*JNM@B9Jm`'H+JไMzl%DTD$*% ɱ@BZ5.F$'( .!Q ǑMZ +amS{ : nJVnڂ!OX*Е,#"mhQ7%DnDn1mc(*pMТ]"%+XlzD Qx@ՙH EƱL:Dʮ43v -82 j@|0ỳl( 6/hr/ +!K4%k"dO VGDZ d*G@dUlWQ#O睋r'ӵ)[ zx\*O=NS`3Zh(2_2*N;()' 2^[[Q 5ʼnY0Ca 'C w@%P'P|\t esD\EԈ-du9 +BED]AàLlA#t_BZ8fFu4h[ + !x8W+N0A"7V 4  22L#^:4С?{Fl]Uk5)!YkMFɏm2Ds*1'҂7,lUQ8"AQD: mM`g -`^IP~5<dk83-l ( +Dđc}3<5 uM`ˢ&X$00%",$W48 `s$ 0A ʆHA&?N$QpKP.M'zlãfcG_BphIR -."AztgRF :&%K.ݢ +d +. ֖ƨq$P8ŒC'Dض[P!;ĉ!&swb.-G$YڋLa<ֈ +c]5L;mpafrNC*QXx]$xK#N&8BK"gX% Hsh=ihSZ$fGO;ƅza_+9(Ц1L0PIDLCD7`̧5^`0ԕ<:G%h% +P-g43q'9>a( d{,G U-D3#5t2;t|1.g0|l׮N Ȅ(SnBKxHΓ>XMa+A8?Fp,SLA HFDG? +QyYq{+1K=2 h#Ȣ 4a1Ht [_P%pGτ-`?Hip"iNh!\xX-|}r W0K*;eӱM\ tD@Q}P@2ēM@8@]\(1|"L⪶z?"S +cZFAu"h;5-HH2`[8{* :HՉd9x𵃲7:56hfU0e!J f1 ^gC$PimN#VCΣc,0O 1;PNwb 0t'@ϧn5I҂N&чǸ:^q:Ġ +&@{&,ئA70fЊ !UC6@A`)Q- [VUp6>J, ptPPQWOdsL *xM,U6HVal$UA6(Ly@h "c?Lcwh1ZH\DC cQϹɀaP/Cl +KSMY܁6 XAfglU0ف> - `l I^NO<0>E5^6_QҜ +ќ& h 2<3b Mg MK`QV YČ$F}Etaxl.Y#9 mEAfBHN#Z'X\5cF@7+d8(jBbfB[^` lX s3N/Hy1in Tlp^pqA9a!f098GE FCK, ȢBiBa!q9;2.cl%#7B(2uC3)$$ S-hH wgTcS1O ]ӆCP F>̀V7F<7" +}S Z$RفԲ$jX'04[ufpb=Oi|wyWʢ2KgUk`0ی!ީrF4aaWK!^r$; uGѠqġT1xӿ[O •*`EgJ?#tH{LHE o7`-xCW: (9`-pH=g2b~/ks=-DP϶@$5a+SGH4=gcuc=}':թ{}"&U<82[#/ M=p㕜7 +…Yh/F{`81uc`z[;k]*`vCc{'8SX^H?6{0F<]cT]0Zd@u_2Wm{T +E +@'kP0Wc\vUF1Sg:evBDs; 8׻|FnNir{-kl|yc)<7nc?fj!c<'*x8j)lvdB50gϩ\QՂ,%ih7Hatbv~ t\B&^s~b\Y=vCCDB !h q)ʡ"Rod-'B_8#=#cG݉^ ɿy\YlWoX7+p#cډ㾜S{ +P"832ʆ0g]nǷ ev!J$\v׍3w + UثS$}vVd/> aϽ?:/KHId[Ge//GΨ}\Zxs|=-aPfbl=OlI-0Gp_WCn~}F̙;-ug|>|pVAD`!VXiuY'>Z-DW`9?D|}#*@<׷~w DDۃuADS"`'A\x|F̐T +xjm⛀u +cf`u:2z/SuT:Ax +G# О̼F^Ɯ7{:x |EK (`=Srey|BE +pR с:g&I߸`,쉠s8c+YRhYr` +~`J$Xՠ]r8PBӁ'n@~ +8%2>Pv7:)hL=PS66u۝fs ho_ڢ! :_'P1-91\mp T!e} \A¸:tQ3sGƄDpX"sا肀TRZZZ/lJŒ{թ;! |T?0"&6Ϥ|1'hK [2f13ETVO/>m'0@?/ʇ<` T y6NWB`bMw@^ˆZ|oL}p rl[pJX g @D/^DɅI͇ݝ]¥{(C- Tǖh!rss]0wz ձAh(EϑиZ"ϖ`)L|-Yb ^"O[5Ѳ!8{7Ee7J@atݡ,^PUF0-8u5ƚa?[Tkp|y#2}2 +&Twg`A]L,amlr2EF܊mIXeU_;/'Aw\38f6*ؠ_֠r'Wˌ:۟*gD$F-h\xڈ7wIZX)r>jH?ٟGu2 nc)MTȾEZxjpnBݮ5/'Jh +&=Þ;2?(ZnFĥu Ē#!yӠS*$ K,hL1vj箋HEC9@P}+Hz{yO;_X1u%ώȁ +w +Byn}Y{޷B%q]Dmo '%ۄtP)Ɔ#pnwQȐ͒: 61?wٶ<`hm a[|4 +dn!CHېk5ПOFrt;Wc5b$UԲaS:M^&ANv[P>Pvrȉb[V|;x6鮐_;#@&rҼK؈ ~BV|~~8t(*nTxL-nM 19A5*Y1s9Dc}1Gy7Ȥ z cF3bse&*U7ϯsQCK_fs\aĭ/@yyYz\@6}K.t|uP(Z0vF J_ (̶!W el{Β)<~ ;cJŒtӎ!"Q|lW)-sv2{q^-6xщIcRUw}bQ=Qrj(,OF`[?3*)`@ kew8ЧȬ|L$,?;ٺp,G#$ME8 YjJB7;nfo6N%0͆_< Kvל۹2n1=Q#8ݶ$V{˃d$ , 5[ŧzL/@z!2/KKL"*18.g!ǣ̪>VÃfm;q_8ܕnkwf(>m#2Zö~8?B{HN-ή{ N*.`_ǾC +[ʚwñd7Wob0W!\nd$A<ng޾j[v!ch aZ6zF?mS?`+Ⱥ^%=M*TaY!+`?1;`C7bpt/3: rB`۰c*@x"  vNpX0\7HJt;K2^춏mjw IHFT9D)oWvQpys+?:}R#GGP߀w]B̢i+~|aTxb8TV@I!DH :ւHu"[34/ݽ^_dNB\ ^{1(ע)Ȋ^5l`ulS"T";1|EY0EB{ME }tp&r)N7X<:`E&zO!lƀ",  +{$(vPbk1WҘx# +#4"͈M."Aunln>)`Py;/JY wجu77FþE[bC`J[=Pv,R 2l҈ WJ3Pd>@HIǭ^G͢n3Fr9Hwwoeo(F)rs$wR;xx2)x xm]\X]@{/s/.PG_:Xc{h? _[8u/M Up9P?3Bk&\/ -uҞ"v.ʖ,]dw"RH7૶4;oIbpbkf)=F2bĈSV1Ϥ.ƹ_5FȢ+Gy%m=!*8aͼ) + +}kg]#@3~{!"#";f.ybAwAP5pbΡ؆rAMI$G> p̑ n8Ԩ3UIL}lqͥ܄{7zXD!=zCV{O1z?ZXTV#@ o/pTe~oׇ#~,o5NpT.cЗ~~ +ZG|Ac!Г<".$bZ~!iYR;Hml2? f_j`W.'@ttCĈ")mޅ=n 0I ]{p[*Ϩ5 +%=xA' S/]GQ%H E `ܑTW\g=]'h QHB41Dɩ,jz\zaC;V#Z1!>K)r&p 8EEZү@I`ؑ.VeO ;[Fs}w!qȁ] ƒ#<reNSC1 u桇4o'q,7(.ay'CxUwFeod9R_>-k#"[I@S}\X&|2 s*H%0pmNPyJnY J9V#̔/?=b!_ BLAlI#5[gud l[[Dir ucRmEoGrM^]_$3Fa9~j ~dBDhڪ Aad1"}k\DIh TUMf׋BGվ2,է稐a3 si-Śs-z@̎ +\sz!nlW^`ߓ_~2DfDWND _"<$ X%{'AhH.Mhq=⽝${KY&y3 #\{@nH&?ݯf `;iw6"|I/І~=[QKvr`DIaJ:SHNbˈH"#R3#3AANHpz!~ⴞH:xd$D ߖ7O ~ܱ.H6#6yIe&];p6`)`w)" o%K [2PyDK8\dB_=={dF=}rϢPx'ز2B8^1p 41wTIˏAGifPniAB:N7u+ء?QdqMݬC^"dIho0x-QE~|ST>DӯDu d@yZeQ>Za!v bԳ#bW:8O5=GVJ1_XS?Σr6CDgBT/uxrdy#^⠘Z_O萋8nk#k*wuip;RK*~ґ<>wOoA=^lsWi[͊4QQHv,KL 뜵eGn1"Nş|9OY' Sx,>4ӋOֲAI[%m2T&N 9qb=mC*A%ޣ2( s(>/JM/j*eS/_%^@cUtYtz WE6%^~)˿b)UPe[U bZ9f+F{2syY]6eq~< +3+/w<6Wٻ 3I  #wNvF嫶oрlr1[&̝evKs z'HN~%sDO6˞Tjڳu8H}v>\rxd^8LvqQ$O|ly}_y.q^l' h N6 &~{@XVA>;&)o q= 1b؊Y(+7PkB(ݞ[TYǍ7O@{pv\/Qkq'c(_\,\lc OZXz|Jo Q߄Fh1HjcTNޑJE@/- g> +$Yb-:ـsZ7[>:KRk,2\tj= ؠ +ؚv0TnD|Sd%xwB{]r#yПP0*R՞;Zo>&7<u@\Q=^DZha&C~Hx> |3".R/8D~/i]7rWdVvM7R&x[7oV7DMKoV3YˍncMfǗ "G!J`0S5[I"U[4X`{ k*t=G +nmt)7 wcl7]Q#hkۃQ +]XR1$ 0R`" kvzާ D@gdX M_'OؤL%DG 0Ih9\`kfI)d}q:u2 *ԆxQqZpz?c, 3mP +"tK^,"f_%Y@EyԼC16jxDn\g2R +ǯslw늪oG-iEХ i%7[# * A.%z`]uE ,ѻ}I{I>v%m4gAv d7q 'Ic-vrx`C`Bk?,8x<Ƥ,Çkv*N7ƚzvn_l[2' ?[uqpw -N&{q/VJL)pοӏ8b@s4E`,*JMm^XIS1fADxFaВWcjEڣOИ`ZsQ~3׀=`٦S6ϨyEc>sfF'uu+ϣ3:L=%x٨ljK406AlSKJlyWY]dG1G&{a‡8ytnlJc<ͱ + 8D(=-GQEص;`ȟ[nt|thź;p`m.ߎ/`> +Hl5n|e^+c {sހ=jl$-_ >dz/̳k 20'ݭ{۸\ӘsxƑuww]{gtja1d +bC%S22-*z8n1m[49ּ[T2xL06Htm$c}pPׯL~ڐ8HKnxslp*\žQ8eɨs+fHywCa\;4\\ȭk r֨hX,qB\GjxnnN@ՎsF,B6.NH;<!膪Ц'ŕ8u8@s_}P/ E׿?qfMO--NӧI;2[ɽ%.oɣpLFؑϑq OCL1M 1Wx@TxM@ۅ<{6WO,'gj<.r&!r%Vy6j Qv\܍»4-m\vf^G|a~%cN@Ty;Q;(Cٟ W@o[ 92FXJq'$Pu&-m(Ȋ;ɲ쵑WڭWBJҎ0Wh5S7QJ4cw ,[u>YZg3v;#O JrQ` ަZ6Ӂb%{ۿ?(G0],Q[PҚ7PSz#&082>ve.`Ob/jQ%`TGDPP`ulZeZz C/ID + |mPFV=]ˉKVKH:0\ R_ʤ!99zT;:^S9-Ԣ:Jw-=RE7RmXI"Bl3'_5ZP_|OAV)/#c`*T|woܥ&W2bں١ҼE~ԩ @{KY5H ߫pij P3TMb%UQ9RsEeSkTNf\MH6޺nds:Jr&Ǫ'W%l< (ҚтY60Vg`Nm9ų6X:яP[liO +)jI1C{W uTiRl4 Ly +ؾ :/nл(#}C}S?-_kiWۨbL-,,:6S@4r{u}Úl.C/k m^:XWW1`2@" +%1 "pwq0T+介[8ϙ [+kep!;:xnUiuMPQG@ +,_rʥR8p%Xl _H-DW; p,2+&ɌiT߃~ 4*!.ʰDDRLopXiI{KPv]n$\6(!f+E!KЇ4o(b&|}19դǹ[Srq/~!Ux `pǞ<:׎W:|oSÆ|Y-<i7q_SY%mT=/]hH"In_qM.ɒQm66Փ)`](qJ#i/:/ +-= uB`,C r^XHgWqhQ7<ϋ P,g0GSz6UZ]C̙ļ/knۗ (78G"YNzD?Bƈf uDIuj<s,.j?&bWij⁈e2'S7dXP4)$0B8V(PNM٩v*#oi 6d0![ēlx=|p GnwfKaA2yH}O/- A9 m])@d1%.D\ڟ43C)kہϫuY)};a*=_==> +F +fѼB<e +Z̃Ԉ=N/oۓ5 `mR0R655vDB~H0ֻm{|=\(<S*~ xIޟ0YLG?V Gڜ$U&0G &0sܖsd`@2i@T+ #tH[H͙{)*x)J,_~Gx}iߥ$>p MΕ^ oQѲ=yJSٳgZi~{EBbl7JNq^/ 5S2kWWu + ZDQc-_Z!tY@9Քۺ~gF2ǫ蓇LR\IlJlFO/=Vc]1Go5ՕVMi`HRR&tVڕg>2@`e+;:+}+gZ_*Wi4*,Efg=3I|zd,[ɝUc9rW<5xZ}f9!u}<}ҙbe"Z" u lOb Y}p- W3}3&9 1B;(+ +D6]n|c̦#_P/"U}# lAB!KLqGAqEgS.Sĺ`xnbJ4~cN0&X+LHs!{AiccF *ܶw#z)ٳ+:[zNNs>D.x6U1O­}mwq6N^;*P"n(\]Je.  7Y:'ƊJtWn*jns!f$sJ4$)񳹋κ'!)HW*1˪.!RbgzիB*-8QȄhQ%ZxO"tV7gV9 +3 &Y\") M8_ޜlq>&e d*X>S*$ Vz\::MVO}w/pU5$ +2O"^{POTA0{1Rcz<*' Fd̹ 'A@ Vy1kD߹oP< X׋n +5o걉=02L@^ XFSe@^5wHx^i &NuDq[ZZ6~8c(e{"F +DL<ő{K[¥zM*W[$NɅ9(y RzPu.]r}n<9¢w߂lkDn)j, 󉾟H`m& J՛hՃb<~9dK9Hz+ňsuǩOhPȸiXAG"zQz& "2ˆl7eIJk͈H-^?­^v;mwBI%$\q0}v0'n M ,. B !!F>|[p>ռ]` a$u|_ƒA:O~r;[!\ ʥ {Tf&Elb\'ɉ_^۰jKǿgQM +S_ VOM4SŪ\q)׫/s7Er;Pt9`q+B97''yqjDJMy'g'X-rj +ei Mޅ"^qYGTG@5KLXcꖀl/5%M;"wZamwCEHɽ[7Z=kE`su9Lhi=M-'LU`%U5Fw⽊(n HHczyVP'U# /'S!:m$O{ͦPeQڎC,̑_T +}_/^!cg}_E@ +rK=kPRw@5.SXp%}i &σ$pyyP3\|i̪m [F}qʰ'R%0э\./99GwF}g1~fDJX5yVEDMWIgj.P'G[li_!Jvཛྷ<2¦XC)ӂN/%˧PFUM٦G0ѝZeF+6&i8cR?4_"Yá@mÜpS,a %:XQ +ŧnq_F[D"g/>@ dzk[2 2k##vx"xab k#ԉhf( e]1ɑcn2v>{tr>D-,)BzݘvgXm!/^Fu#%($I>:Fl J+_ǡ|M\ 7Y/u8]'2:!w\@lja3_^P2ˇ4s[1~+kADl/q +D wgF _2 j[A ?!:V-V,{Hp`sxM~0xy~rp4ڤhy` "l)!f:GG  !xl-GHȏcŶ2ߋ˜ɐcP\ګddG>ҹ;‡iZSHݰ*'8$s@ST"M+9~HHr)NSY @let)2)i$< F@0zݕʄ6} [\Wǧ՞^Ȥt! [B}e=. +"Ss|btA|&O%*׬gڶ1AStAnAb0kze#T>ʷ (.vE*:HܗBT~iW^Fb`/ĭ'IfȬ"=[˥G ,W2( ݥU)~#K &/@ŸՕ|2Sbw>'>#$Ū)) EF, +F#UBƽD2SRM_r9]>ށЪCLxP1N}ZzJRC cRoN_VMzPoԉcw +ηW#ֶvNE|8T1ap~ftB.MziwxTDذrAb +1B(תb3^Ub2#̾pj!sk6edO}"~,Fz_g5{1_5r\ehKx \\A_Q+(b6ʂgKriL/jm g a#{!w6=oE;be \v+h5iqQ i:!B^,Pwhlu8^ ̙յ yØ_>"$)0d/(15E<ȹ!Ҥn۲u4Cz^]KXn<8Un; "&3-"n}ck @gl0y#D0DXz 1MXܤF. w4k(5–N\3>XtݹE5˧ WhC5UFb'[Ә?UѠ\e`V1EL{{'~U$ +ŚI rs1v"5y܀3W*f꛳[]=@PIW׎}6N 慈9` ~4oA z6}YYO@lGSXz"KIYIy̱\8&?(Ŝ^Rz%n3"ZxRxキeς\#!M?Z̙WLycPoy^ k*SrFD&nI3`n> b^$[6c/8/JXAN)h[(ɊG8Ad+tDjTXV\U~l׀1TZP;Jb8\EWA%HثT>lF`.mO{ 2G[~f(6qV*DX,M䦩_EQs"TK]pzLPr[ivݗH/0(i$ߞū')ؑF}0;8T"Q#J* ױև,:8_[cm@%=KJej@"Rn#m<(!@'ӏF3[eD2;58mZX4Ȩ/(#҇ıkj b;ߌ1z}ѼFʵR-1ɖ]jtNB%8f`]`@0XudDt3HLߎ#F&R4QцS%f9ZXctg1/V]F2SF$Af CeQ.df?[*KݚoEPeiG:SDqGiMTnUn)"E^Ic($;{,R%ZeqQ)΍TM25B8RbdJ_m%](|b,m...36te:,|{}.7 sU@DW Om 3Cgz.?W2v/Ln<ש>)|:IhgY1u3P6|nezKz]ZѶi8qxcAH#b15Wݵ1"1)m9Gb+DG?/o%>pڍXh ЄĂsUKfhIs@%&֢iNY\r5!j߮9,Qp1A\e(Z:%fk/LXMPߙN-H;z=XD;4)w-K*h:C_(“fˆ[8܌ld"X ƫC"%E$JØ˧&.KP.x~vwo}߼_˿x/h\'_//ߴe_߿?O??O0F endstream endobj 6 0 obj [5 0 R] endobj 20 0 obj <> endobj xref 0 21 0000000000 65535 f +0000000016 00000 n +0000000144 00000 n +0000027685 00000 n +0000000000 00000 f +0000045164 00000 n +0000107718 00000 n +0000027736 00000 n +0000028068 00000 n +0000045463 00000 n +0000045350 00000 n +0000044121 00000 n +0000044603 00000 n +0000044651 00000 n +0000045234 00000 n +0000045265 00000 n +0000045536 00000 n +0000045710 00000 n +0000046995 00000 n +0000058015 00000 n +0000107741 00000 n +trailer <]>> startxref 107939 %%EOF \ No newline at end of file diff --git a/docs/_site/artwork/draco3d-mark.svg b/docs/_site/artwork/draco3d-mark.svg new file mode 100644 index 0000000..11ff9b9 --- /dev/null +++ b/docs/_site/artwork/draco3d-mark.svg @@ -0,0 +1,306 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/_site/artwork/draco3d-vert-180x137.png b/docs/_site/artwork/draco3d-vert-180x137.png new file mode 100644 index 0000000..845e5df Binary files /dev/null and b/docs/_site/artwork/draco3d-vert-180x137.png differ diff --git a/docs/_site/artwork/draco3d-vert-360x274.png b/docs/_site/artwork/draco3d-vert-360x274.png new file mode 100644 index 0000000..8ea7510 Binary files /dev/null and b/docs/_site/artwork/draco3d-vert-360x274.png differ diff --git a/docs/_site/artwork/draco3d-vert-452x344.png b/docs/_site/artwork/draco3d-vert-452x344.png new file mode 100644 index 0000000..f55f48d Binary files /dev/null and b/docs/_site/artwork/draco3d-vert-452x344.png differ diff --git a/docs/_site/artwork/draco3d-vert.ai b/docs/_site/artwork/draco3d-vert.ai new file mode 100644 index 0000000..0ff3ffd --- /dev/null +++ b/docs/_site/artwork/draco3d-vert.ai @@ -0,0 +1,424 @@ +%PDF-1.5 % +1 0 obj <>/OCGs[5 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream + + + + + Adobe Illustrator CC 2015.3 (Macintosh) + 2016-10-31T10:58:13-05:00 + 2016-10-31T10:58:13-05:00 + 2016-10-31T10:58:13-05:00 + + + + 256 + 196 + JPEG + /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgAxAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7 FXYq7FXYq7FUu1/zFofl7S5tV1u+h0/T4BWS4nYKteyjuzHso3PbFXzX+YP/ADmjFHJJZ+RNMEwF VGraiGCntWO2Uq3yLsPdcVeE+ZPzv/NfzE7nUvM16IpK1trWT6pDQ/smO39NSP8AWrirC7i5uLiQ y3ErzSHq8jFm+81xVu1vLy0lEtpPJbyjpJE7I3j1Ug4qzny1+fP5ueXXX6j5lu5oVP8AvPet9cjI /lpcepxH+qRir3r8vf8AnM/TLuSKy886aNPkYhf0rYcpLep7yQMWlQe6s/yGKvpDSdY0rWNPh1LS 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 nxf33Gn7NK02pir/AP/Z + + + + 1 + False + False + + 6.944444 + 6.944444 + Inches + + + + Cyan + Magenta + Yellow + Black + + + + + + Default Swatch Group + 0 + + + + Document + application/pdf + + + DRACO_ID_vert + + + proof:pdf + uuid:6436b92d-aa49-0745-82a6-f812a072dafa + uuid:f9e66d04-1cc9-fa42-90d0-b17bb78aa951 + Adobe PDF library 15.00 + + + + + + + + + + + + + + + + + + + + + + + + + endstream endobj 3 0 obj <> endobj 7 0 obj <>/Resources<>/Properties<>>>/Thumb 11 0 R/TrimBox[0.0 0.0 500.0 500.0]/Type/Page>> endobj 8 0 obj <>stream +HWɮd ߯? a6U^ +Nuw9$u$ 0 G%QC>9n*ea=RG#=S(l14!)𷗶csZ8Nkv]_lLXdC+PZ)^/2( :5AD\w]KO}q4긚) +opK2MX;r *0l|hu*R3}% / v+5lI>~a0,ZG#b`[0~s29"/xkn=]@Y8KҌf ?gj(uKN[?}ۖ*^W8u$-|iׅX!+"3^̏@rQ3pfVb:0n{)!1L>>+Ux'H6\0*e1p{S\e7k81G3[-ԒάJm`wxc^gem-+dߡ(}7,(mNI$ڝjg ED$}qӷVq%l먡|q]'sΟ>;!1X +*܎\ HAp5"WZwY Z7U%so RcFDO~l]P A U)mު|9!t pM-o `߬T d`F\'J0,>qX#ixÍ(`ǘXRYHOR((Ǐ2oF02`BT,Bӎ.Ϭ z"G3#%h AAcȣQh _xlE:γ %^c3|n&EzNxQ(Jx?mj,5fi)$Gil i +oE.; +b~92NPߴBxj0(yN,YzJҪWB2}GRsIp?렞 +ޗwDy@?Un{jB{%|3 t``T̄T)6g5yX -K&qN씁MOgia#+;sNli>f$2)"'0ޠ߬[#"?"f#*-qrS>~T%i:UMs,%/w70j4CGYh<'xOj]-2V+P +1Q }*34% +dje +: sZk67Nbi|y6˲bu47.4yz`ohP :~(bNxGH1Ȉ/&Ӗ$4ЪlADXpXc.hA6'x߱OHkpo`L#x n1w?iJ%}be âs+on5hЕ*:bbYߗK#24C[ 1u M|Y n8iX.4\,wÍr7pC f77.I|ۛ9w̆u˖UlmRͶBcãKh_<|Y9 qסw܍YPg[({m"g"W@CR]BU<tCӿ-1uF%Ştʿtk骷ޚtk/MW?~kJt{UߤWiM3뻈K*e4UȰ|m +4U!F5< 9߿\E s둉k0ណH׌1"ׇt +L%M N01!Gr, aC`Tp bJ; OTc }!* +ӆzeN%@TD"سTm62{fhv ۞Jeq42dsF͕ΐiO < Mo}uhjC7%ytGed$<`DsHEfJ:a0$v6H'3B2 Nm0b#zJ]`JI Cc],0r@zb 7P;p˴E6 g PV]Lt f&8T <Xa0"JTاO6 +I +OH܌xlGrM@66ɒ,$mmHharMzrfiVў%n)*H]8">LIa@@GN* a֌ %QvU.4 jn)(Spfj ,s u4̑ΜÂXśqaH' +`pK< ++"jrhRn+c*FRF$LUj5QȒЉC|ix$& V0u BEbBW0Mٛ~p=f . :)KB%A$YP$ÿ.,;rkYOOz+h\@/>mOdB"A4XafuA%}M9QܯGQ_{ OzsѸ sܡZ?c HnGGλeسA?IjSHG%sk5[\ J} 2V6)nΰB4$iz@G.^L E,ζUrk2Y{Nrn)U]hxQ8o/À஫ +b> +=T`>'#mȃZYЧ@V&H. qh79dSYٖ0~<$Mmه"r刬) ;+KatT ;I&səJt`V|u+csi nfOGPr 8_RtRm|TqZ +R` WC8cM S(붙[ iT_GoZIKq[nnjT+]:n|r4.5ah)DnŷЖ0^ۉ:3o= rrvQ"ݽbfKVW!Jf4Ar<~>H7ܚQ û9t"W,z&HNq61ݥtۧShkd\}[E%# \2fkt/23n&HSmgܮ97*3ǝ}{18|"6*5*Ŷ#;s9f9E "aT3C8 +B"n<=̒˔umY !mqO1u6v^ +)8;x(<@= N>Y(cK{!98*=z(cx"­ Ҹ6S[P7K#Rob_CnX2n ۫aQ~lXRԴ|<Z}FtZD.dB^ɟb0ԜyeE2$&sž/29k;mU>w{W=Ϲ tےPa$1<4 gܸb3{5+8ĥ؞1ˎ[L {yVvcODӅ* aw([2}mטx{&V,ƛYzcw=>ǽ/h!r?#6bO[c/\tfumq|%CrIywn"Hx%cM?1G=%z,^=;{Nk4:Rco 3x\wf[{=PufMӓn3LQT6o,sթ`^0t4-X28LȊb@(?bJB;Q\K@1ocۮW՘/3hHw#iL1ZZ릂=VS N n?Wepӿ[&(HSnlET7m! 6?:;,F h:դ}ܨƂ9l%t檁p +MPeB܃cɄUtFkU޶x@\**+5 /Qp>?#l]&&@ZX̋Zɶ3nn32=Sef6'åm)D-k}2n/g2.J԰}$Le7ݮq>@v_n"xE/vӨZm ܟkf + LCŌCgXͤ:uLx5ٰ3#Rs*VsO P#7VCT5U~gl]p+fcE@_s~}Ҟ>EӘ4#_#%uNJ@RTؘxƛ)/L<$y UPGg3fyyD!{Xm#㡷m3^E.ھh~FG;b$mvPP7o^k3f[VQ 1Z\hG1Ve]c N^ q +iO4MZyf:xYu쪹&|/:oc 7uNIFL=nJqo=MT|=>XVOOhL:oPQaTTB΃mg =h,S_7]bc\b& Tfɝ⊏&ϺPelS{33}-m|4캆,`NK GGY] Eng<R]w 闐:r3} s0@TscmubdC:W;=NMY0c AD2HDz݃G՘RZG%Z;P̍vi M_lm;jꞤZ#"A4{_8v."Vu_u \j +piӿ؞#N20ПP9_9K`&كXW @Dv|[ӧ:fVH. YX]31U2C2b3Tcz$@w@BũLyT3,9v$Y0tߧ dN6 ϊ2M\% 6ii@(,n[""r8 L's<+<$Pڔ7_ ',4E%g5+e ])"'=#]5x9PC =Ra%sro%ٺV4}^%fly~zo9L֦x4kxt/ +ޖf5)=G;ohuxSgĸ:g\KuBdj.eo _!@OCBRhg[q7c]G5S߳WZ +'3͙cWwfbx|&{=nhl߾٩ڠ=σ%_W.S`{K"M~`Ԙ[//)ŽLTҥ=* +_~FҼVUeL9:2η(WSѻyRYr~{WWJ!!z}ssf^~=͖2Z7>T[QhMjP@3DeVгfZG6E;HI&4؀߼7eQ}쯴)MJر+P!Oy`YʌMtySѬPgdZk똵w^ωXvrn+vU_6kSW +[:u?VPnN'C:,TSlʅկ7eev`/Ԇ;4wnN!I.L=0)hbcwqOٿ#Y&B&o?Tcs%չ{ظ]Q6Zti"V)JVdϲ x_Th0x돡áfXyu :7#:- /I6Λç%^Y{4ҮQsGOviZ:FeP$pS:(%x)|?5H1Y +ʋ%%b +Jnc6Ux9k~uNU@?Kk^U"o>)@mX3 +Y! Zb*43;6(?r( 5@0B + YYH/S@#ٽ d1Ž6{1z*믱4ڴ( gblE0AߠB?L%K + Jb;a2qwz/QW| ͚^OaՈJAw t(vcZ2wGF!GаmZ专AXE5+$g#Tm[=U!LԂyQߧ="n[m&9oݐt2ZofTnB=Ԫ'G8N{o[`VNEG='߂g.E Y/Km&ػ7.wX ЉAn&2/=go4D5CRIږH.?͟&|Ԯ˪k*$Y{sԓ (1@XlnZa1 ؛O(|Ogk`zlPh ݆o|nfYgh X X q{bZ~i;mP)B?Ph #4麴~H-M$&9 +"[X/&q1 ;Jt%K\ gp?}=Ӱw: |w,zHZq +AB0Dd^`nsh5v/8*?{l}2tv+zu6brقd'pG?e%vҥH 1j`wj TS3dןz`* JoP9h?d\gT>"U#@(KTIo䈎/"ElbCI^vv)d2)v\uM&r8Ҳ| MQ_NJ pc,-pՋ,.+t5v#+RXc/Fؖt7󏇃'x〦 Le6lP|C7m_<@}`LD/҃aXh'2WK;āKKhR4&- !5F5[JW5)TdxU,A2#cI3IХK*0K"0J.H-$٭Sv|xASJ* zӾE\MG<ȩvUmdr*vkPS +Ȱ]kHaHY vGc1w>j0ԩh{L)p3՗5"fNzU#vV8*5vP8j .ilWv'~:1Һ, Du +\9TUI-v+v?0f;F +x1 ɃwQqaeC'uaO0{ D>vn_t,tC8YM),~) + kϕ c;پt҆ۖTIC \v?+o|9tκcŹ2 [NmC ˴y.Z=|;I|kV"u}BCmnvee6 up>TJZɏ/̹=dL'f-5U CxI}kVSaQuM5>a.4HDj "EL;שUM^ f:+ +Vx$y)Ø;8xeYQjto֙+(AZ1*nЌW(GXɦ[%8r)D $Ra< ):<|W [OK(HD'$%"]&):1Yx1l/ (05L9o*H[j,LNF:Ѷv + -#<nYVF2Z&iN[ +w>5 +iUJ<%9dpHHFM~ <Я*H׮][sS˺j.jO@3l\TO_b,GL7nv܂xn^A< 3[_0g"$+5# b#%/ڣ#a~j|#".3fs2z?h8"Dz0@2RL|g2`|Hk׭w{DfP)|8Yttc QTk&LU& etȕ#F|Y3{pk^<2 .< 'Q#@#>iLFi'02<{:2~EُP `F5C#ĺIޢr+r[AbLxr<슧.wU&O^8Fej.hY8ׄ55/oǕ,&8W8HLKG^Uˮ֌pUql^ujbZ(0"ԶXe1gƩYƬH﵂'4%F'\ƒkIbU8'Xm@VC/excm/p .oᓹފI6tx-tPoqkIWr(]$s42g Ɏg;[G}ܵzoZτs~)''ZPg~+Wў)j~*ٽ9aT*l(tګ*9O\6>fJ,eq_ى^nR`W~tDQе|vѶu(|('nrvfudԿP֋&SOn_'ßK7UY]t_$[:PF׷ҡAcNqjՃġz+#:/N$.Ե$ͭ0-N!8>]Oik>*`ښ۫ +$YZ +n[-{_'7~tbqMe=l L+}GM4Cp(,8EkhR$rƐ$vi^$ <2M̮nZ/0?z&*߄*cռp"81vaE4N^ +nK=Na`P/e/pI(NxuJК[5`qXpj"k ~5=,6B_fըk#"t2'wt.^AlrH!H7Rͧ)ɩ;6}oYE UZ<WͱMpIM|M/}DV +lICDA,+Բ˖Ð8 ^Pvr,j=[D`%tK=}W;{ 6o></ w:-(!~tY#ABņGx=rT\ @ \+s{zPٍ"-w5o6҆pɭRDBZՉm ,R& K4r D) F3[!ڦ5ϵ|ݙVU=\"Zp.T%kZNp_cά-'NzRr-p50OL,pDZ0Ra*ϕMT [P* zs>NtXFsPySX\5L.T=&]9CtiYx:~{( CWtnwMYNquO ]|[RAot4 E:kVa@a]5[٩-sv<nnߴ.ĺ.mGOGuVLyN Nו$ 騿=tȨ%XttRKN,N^P!]"YVh`:t1 +W Dp`WNkl{tUv8]C@M&V46?emEv^dϵXG6[T;3(*xų]3԰z.&hT*E5@@W;W=t{.Z">HC󁦓=V;%Um/#~D#F-7itSVMʹ&rs'MH[o,c3`_&+Z,T"U]hs*6~t`hATQ-XU$;.8׏nvZ䕐 #vweE[fj$EɍuZM НZM'nGT*-OdXڜU]q nZD%`V썎QO4k!'k 񀆂 C6avi]W^iZ/*4o:omawi:@=H{Crp -_|sSzBP&z; +_npZ'[OÃѪv"|=ب<"f/kSO&. e QAiv&\7=-f}qX0[1.gضӊ"zH{Dx]bleo<,¶:Jñ;# 5æ-05 ILK_b8 'it7 S=FrcLW+0:C,F"fz)n< +)Iy. ;IѸ'Q?E3N!|Tb)1d`/ ".ȹJ-X rTb,byՖ$o(~"q>ݰB5Yݯ6_ +^B'\vYJ&-~]S}Yh4}v#Y0Sj"VȔ3L;i-QF=+ 4=D2b +XtrػC"]Q]+EcSfW|!7d#"@֯Y)g_*砃uBqC1*`7Οu~gԨJK-Fu40,3h6wo`Ό% +ZLB\8jS%-n v{T]Nm)%sBY,;ͦz7d80ѡO +vr٤qa҉(jqgq#4[~S;-wG2yihF +aR7JItSldhKetHȡFj1%Gdz/e[di =_Vi׮?Mj3 9A"\SB-ѤVX/`d~$bf$U8j:Hc8NTv?I ~̞͊P0]I?76U eVKڡabXI-CfZ]7P.ˮ)ɛyBuZ3ޣKn&ٸيo,SosK3*)){BVqU %mqAK?hbf-CK:^ oS:*0L"&B +ꟶo* yφ.pI+'HP#{{d=Kw~sy?ۙgr 9П\uxHd-ĤJAvu޿!Ncq'XZz&ciIOc4[d51s˹I# V@7PUf {]4=LM*kc,/啭j8lp̄NG۟{ֳף6?[:@O-N;ϕ@lqsDK1⮷>b_^OTR ˶UWS*#*F㡒/|#Ok8?6%qyk;2{v_^EiqIWN-k$W:Ld(78!ڼ*i@FڳsفuTd@((k?[l +Z3xRچrngiz +2'd++} i_~#s(~R7Z}.FV3pj + 8^=ܻkd[߼]*QV磪7 j_@:`3L3S~_5PYAą` )JC$/MscS|Uǯ?~ǿ$'LM@9azf>+.%3QkJX}>kĚVǢT.;]psKY"V?ar뛏:P sCG`Y1R&&٢ccB/#7d$%ti[k4(|VX[+o! +"LJppkx")Q]hawl(_>p% 7v|$20{7`Vl^ppձȣO^q4^稘է +H "ŊSQm݋2UPhp[`N|q? es>n:WtLt!csT/joUY`2I*D_By~S/pP0SLUi [1n1r3A;ALH_[ϋ6,'ݭ#GT`fN.ߢEl(9UZ 4 F+3tZH/ ҙ,lþ*{D_/ V endstream endobj 11 0 obj <>stream +8;Z\u=Ur;&$q,OD$dNl+7?5tX3(?l?bX^9tFM+CM[^J@B@Wg<j;=\EQ(5)f:$!o.%Sc+cVN.:mYS^R*6I +c*G%*Y3h6:E@NocQ]\RtUhTKYF9/3kdttAf3>W/2_,tcm+Y7]k/NBX]3qZ6>bkbuE$9([#\1%Y7Yt endstream endobj 12 0 obj [/Indexed/DeviceRGB 255 13 0 R] endobj 13 0 obj <>stream +8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 +b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` +E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn +6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( +l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> endstream endobj 5 0 obj <> endobj 14 0 obj [/View/Design] endobj 15 0 obj <>>> endobj 10 0 obj <> endobj 9 0 obj <> endobj 16 0 obj <> endobj 17 0 obj <>stream +%!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 17.0 %%AI8_CreatorVersion: 20.1.0 %%For: (Abby Lindstrom) () %%Title: (DRACO_ID_vert.svg) %%CreationDate: 10/31/16 10:58 AM %%Canvassize: 16383 %%BoundingBox: 25 81 477 426 %%HiResBoundingBox: 25.0400009155273 81.7850036621094 476.735992431641 425.735009354476 %%DocumentProcessColors: Cyan Magenta Yellow Black %AI5_FileFormat 13.0 %AI12_BuildNumber: 174 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%RGBProcessColor: 0 0 0 ([Registration]) %AI3_Cropmarks: 0 0 500 500 %AI3_TemplateBox: 250.5 249.5 250.5 249.5 %AI3_TileBox: -40 -130 540 630 %AI3_DocumentPreview: None %AI5_ArtSize: 14400 14400 %AI5_RulerUnits: 0 %AI9_ColorModel: 1 %AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 1 %AI17_Begin_Content_if_version_gt:17 1 %AI9_OpenToView: -520 754 1 1928 1104 26 0 0 -4 37 0 0 0 1 1 0 1 1 0 1 %AI17_Alternate_Content %AI9_OpenToView: -520 754 1 1928 1104 26 0 0 -4 37 0 0 0 1 1 0 1 1 0 1 %AI17_End_Versioned_Content %AI5_OpenViewLayers: 7 %%PageOrigin:-55 -147 %AI7_GridSettings: 72 8 72 8 1 0 0.800000011920929 0.800000011920929 0.800000011920929 0.899999976158142 0.899999976158142 0.899999976158142 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream endobj 18 0 obj <>stream +%%BoundingBox: 25 81 477 426 %%HiResBoundingBox: 25.0400009155273 81.7850036621094 476.735992431641 425.735009354476 %AI7_Thumbnail: 128 100 8 %%BeginData: 9568 Hex Bytes %0000330000660000990000CC0033000033330033660033990033CC0033FF %0066000066330066660066990066CC0066FF009900009933009966009999 %0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 %00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 %3333663333993333CC3333FF3366003366333366663366993366CC3366FF %3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 %33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 %6600666600996600CC6600FF6633006633336633666633996633CC6633FF %6666006666336666666666996666CC6666FF669900669933669966669999 %6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 %66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF %9933009933339933669933999933CC9933FF996600996633996666996699 %9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 %99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF %CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 %CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 %CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF %CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC %FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 %FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 %FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 %000011111111220000002200000022222222440000004400000044444444 %550000005500000055555555770000007700000077777777880000008800 %000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB %DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF %00FF0000FFFFFF0000FF00FFFFFF00FFFFFF %524C45FD39FFA87D2727FD05F82727527DA8FD6FFFA852FD0FF82752FD6B %FFA827FD14F852A8FD66FFA852FD18F852FD64FF7D27FD1AF827FD62FF52 %FD1EF8A8FD5FFF52FD0AF82752A827FD12F8A8FD5DFF52FD09F852A8FFFF %A8FD06F85252FD0CF87DFD5BFF7DFD08F852A8FD04FF52F8F8F852F8F8F8 %7D7D27FD0BF8A8FD59FF7DFD08F87DFD05FFA8FD04F87D52277D7DFFA8FD %0CF8FD59FF27FD07F8A8FFFF7DA8FFFF27FD04F87DFD06FFA852FD0AF852 %FD57FF52FD07F8FFFFFF7DF8A8FFA8FD06F8FD08FFA8FD0AF87DFD55FFA8 %FD07F8A8FFFFFF5227FFFF7DF8F8F8277D7DFD04FF7DA8FFFFFF7DFD09F8 %27FD55FF27FD06F87DFD04FFF87DFFFF27FD04F8A8FD05FF7DF8527D52A8 %FD0AF87DFD53FFA8FD06F852FD04FFA8F8A8FFA8FD04F827F8A8FD05FF52 %F827A8FF7DFD09F827FD53FF52FD06F8A8FFA8FFFF7DF8FFFFA8FD04F87D %52F852FD04FFA8A8FD04FFA827FD08F87DFD52FFFD06F852FFA87DFFFF52 %27FFFF7DFD04F8A8A8F87DFD0BFFA87D27FD06F852FD51FF7DFD06F8A8FF %527DFFFF5227FFFF52FD04F852FF52F87DFD09FFA87D52A827FD06F8FD51 %FF7DFD05F827FFFFF8A8FFFF277DFFFF27FD04F852FFA8F8F87DFF7D5227 %527D7DFFFF527DA87DFD06F8A8FD50FF27FD05F852FFA8F8A8FFFF2752FF %FF27FD05F8FFFFA85227F827FD05F8527DA8FFFF52FD06F87DFD50FF27FD %05F8A8FFFFF8FFFFFFF87DFFFF2752FD04F852FD04FF52F827FD05F82727 %525227FD06F852FD50FFFD06F8A8FFA8F8A8FFFF2752FFFF277DFF5227F8 %F8272727FFFF52F87DFD0FF852FD4FFFA8FD05F827FFFFFFF8A8FFFFF87D %FFFF277DFFFFFFA8A8A87D27F8FFFF52F87D27FD0DF827FD4FFFA8FD05F8 %27FFFFA8F8A8FFFF2752FFFF2752FD08FF5227FFA8F85227FD0DF827A8FD %4EFF7DFD05F827FFFFFFF8A8FFFF277DFFFF52F8F87D7DFD06FF27FFFF7D %F852A8FD0CF827FD4FFFA8FD05F827FFFFA8277DFFFF5227FFFF7DF827F8 %F8F852FD04FF52FFFFA8F8A827FD0CF827FD4FFFA8FD05F827FFFFFF277D %FFFF5227FFFF7D27FFFFFF52F8FD08FF27F87DFF27FD0AF827FD50FFFD06 %F8A8FFFF5227FFFF7DF8FFFFA8F8FFFFFF7D27FD08FF2752FFA8FD0BF852 %FD50FF27FD05F8FFFFFF5227FFFFA827A8FFFF277DFFFFFF27FD08FF5252 %52F827FD0AF852FD50FF27FD05F87DFFFFA8F8FFFFFFF87DFFFF5227FFFF %FF7D52FD07FF27F827A8FFFD0AF87DFD50FF7DFD05F852FFFFA8F87DFFFF %5227FFFFA8F8FD04FFA8A8FD05FFA827A8FFFF7DFD0AF8A8FD50FF7DFD06 %F8FFFFFFF852FFFF7DF8A8FFFF2752FD0AFF7DF8522727FD0BF8FD52FF27 %FD05F87DFFFF7DF8FFFFFFF8A8FFFF7D27FD0AFF2727527D7DA8FD09F852 %FD52FF52FD05F827FFFFA8F8A8FFFF5227FFFFFFF87DFD08FF7DF8A8FFFF %FF7DFD09F87DFD52FFA8FD06F87DFFFF2752FFFFA8F8A8FFFF7DF8FD07FF %A8F852FD04FF27FD08F827FD54FF27FD06F8A8FF7DF8FFFFFFF852FFFFFF %2727FD05FF7DF8F827F8272727FD09F87DFD55FFFD07F8FFFFF87DFFFFA8 %F8FFFFFFA8F87DFFFFFF52F87DFFA8A87D52FD09F827FD56FF52FD06F827 %FF5227FFFFFF2727FFFFFF7DF85227F8F8F8A8FFFFFF7DFD0AF87DFD57FF %27FD07F852F87DFFFFA8F87DFFFFFF52F852FFFF52F852A852FD0AF852FD %58FF7DFD0AF8FFFFFF52F8A8FFFFFF2727FFFFFF7DFD0DF8FD5AFF7DFD09 %F827A8A8FFF852FD04FF27275252FD0DF8FD5CFF52FD0BF82727F87DFD04 %FF52FD0EF8A8FD5DFF52FD0EF8A8FFFFA8FF27FD0CF8A8FD5FFF7DFD1EF8 %A8FD61FFA827FD1AF827FD64FFA852FD17F8277DFD67FFA852FD14F87DA8 %FD6AFFA852FD0FF82752FD70FFA87D52522727F827F827277D7DFD7AFFA8 %FDFCFFFDFCFFFDFCFFFDFCFFFDFCFFFD53FFFD0CA8FD0FFFFD0FA8FD11FF %FD08A8FD12FFA87D527D527D7DA8FD12FFA87D527D527D7DA8FD09FFFD0D %F827277DA8FD0AFF27FD0EF8277DFD0EFF7DFD08F8A8FD0EFFA852FD09F8 %2752FD0DFFA852FD09F82752A8FD06FF27FD0FF82752FD09FF27FD10F852 %A8FD0CFF52FD08F852FD0DFF52FD0DF827A8FD0AFF52FD0EF87DFD05FFFD %13F87DFD07FF27FD11F827A8FD0BFFFD0AF8A8FD0BFF27FD10F87DFD08FF %27FD10F827A8FFFFFF27FD13F87DFD06FF27FD12F852FD0AFF7DFD0AF8A8 %FD0AFF27FD12F8A8FD06FF27FD12F852FFFFFFFD15F8A8FD05FF27FD13F8 %A8FD09FF27FD0AF827FD09FF27FD14F8FD05FF27FD14F852FFFF27FD05F8 %275252527D5227FD09F8FD05FF27FD05F8277D5252527D27FD07F852FD08 %FFA8FD0CF8A8FD07FF7DFD08F8527DA8A87D27FD07F852FFFFFF7DFD08F8 %527DA8A87D27FD08F8A8FFFD06F852FD06FFA827FD07F852FFFFFFA827FD %05F87DFD06FF7DFD06F827FD08FF52FD0CF87DFD06FFA827FD07F8A8FD06 %FF52FD05F827A8FFFFA827FD07F8A8FD06FF7D27FD06F827FF27FD05F852 %FD08FF52FD06F827FD04FF27FD05F852FD07FF52FD05F827FD08FF27FD05 %F85252FD05F827FD06FFA8FD07F8FD09FF52F8F8277DFD04FFA8FD07F8FD %09FFA827FD06F8A8FD06F852FD09FF27FD06F8A8FFFFFF27FD05F87DFD07 %FF52FD05F827FD07FFA8FD06F87DA8FD06F87DFD05FF27FD06F87DFD0AFF %52A8FD06FF27FD06F87DFD0AFF7DFD06F85227FD05F852FD09FFA8FD06F8 %52FFFFFF27FD05F87DFD07FFFD06F827FD07FF52FD06F8FFFF27FD05F852 %FD05FF27FD05F827FD13FF27FD05F827FD0CFFFD06F827FD06F852FD09FF %A8FD06F852FFFFFF27FD05F852A8A87DA87D7DFD07F852FD06FFA8FD06F8 %52FFFF27FD06F8FD04FFA8FD06F852FD13FFFD06F852FD0CFF52FD06F827 %FD05F852FD0AFF27FD05F827FFFFFF27FD13F87DFD06FFA8FD06F87DFFFF %A8FD06F87DFFFFFFA827FD05F87DFD12FFA8FD06F87DFD0CFF52FD0CF852 %FD0AFF27FD05F827FFFFFF27FD12F827FD07FF27FD06F8FFFFFFA827FD05 %F852FFFFFFA8FD06F87DFD12FFA8FD06F87DFD0CFF7DFD06F827FD05F852 %FD0AFFFD06F852FFFFFF27FD12F8A8FD06FFA8FD06F852FD04FF27FD06F8 %FFFFFFA8FD06F87DFD12FFA8FD06F87DFD0CFF52FD0CF827FD09FFA8FD06 %F852FFFFA827FD11F8A8FD07FF7DFD06F87DFD04FFA8FD06F852FFFFFFFD %06F827FD13FFFD06F827FD0CFF27FD06F827FD05F852FD09FF52FD06F87D %FFFFFF27FD0FF852FD09FF27FD06F87D527D527D5227FD05F827FFFFFF27 %FD05F827FD13FF27FD05F827A8FD0BFFFD06F827FD06F852FD08FFA8FD07 %F8A8FFFFFF27FD05F8527D7D52FD06F87DFD08FFA8FD14F8A8FFFF52FD06 %F852FD09FFA8F852A8FD05FF52FD06F852FD0AFF52FD06F87D27FD05F852 %FD07FFA8FD07F852FD04FF27FD05F87DFFFFFF27FD06F8FD08FF7DFD14F8 %52FFFFA8FD07F87DFD08FF27F8F8F852A8FFFFFFA8FD07F87DFD08FF7DFD %07F8A8FD06F852FFA8FFFFFF7D52FD08F87DFD04FF27FD05F87DFFFFFF7D %FD06F827FD07FFFD15F827FFFFFF27FD07F852A8FD04FFA827FD06F852FF %FFFF27FD07F852A8FD05FF52FD07F827FF27FD05F827F8272727FD0AF852 %FD05FF27FD05F852FD04FF27FD06F8A8FD05FF7DFD16F8A8FFFFA8FD08F8 %27277D5252FD08F87DFFFFFFA8FD08F827527D5252FD09F8FFFFFD15F8FD %06FF27FD05F87DFD04FF7DFD06F827FD05FF52FD16F827FFFFFF52FD13F8 %52FD05FF52FD14F87DFFFF27FD12F827FD07FF27FD05F852FD05FFFD07F8 %A8FD04FFFD07F8A8A8A87DA8A8A87DA87DFD06F827A8FFFFFF52FD11F827 %FD07FF52FD12F87DFFFFFFFD12F827FD07FFA827FD05F87DFD05FF7DFD07 %F8FFFFFF52FD06F827FD0AFF27FD06F87DFD04FF52FD0FF827FD09FF52FD %10F87DFD04FF27FD0FF852A8FD09FF27FD05F852FD06FF27FD06F87DFFFF %27FD06F852FD0AFF7DFD06F827FD05FFA852FD0BF82752FD0BFFA852FD0C %F827FD06FFFD0D27527DFD0CFF52FD0427F87DFD06FF7DFD062752FFFFFD %0727A8FD0AFFA8FD0727A8FD06FFA85227FD06F82752A8FD0EFFA85227FD %06F82752A8FD5EFFFD05A8FD15FFFD05A8FDFCFFFDFCFFFD30FFA8FD07FF %A8FD37FFA8FD22FF7D7DA8FFFFFFA8A87DA8FD07FFA87DA87DFD05FFA8A8 %A8FFFFA87DA87DA8A8FFFFFF7DFD09FFA87D7DFD05FF7D7DA8FFFFFFA8A8 %A8FFFFFF7DFFFFFF7DA87DFFFFFFA8A87DA8A8FFFFFF7DA87DA8A8FFFFA8 %7DA8FD04FF7D7DA8FFFFFF7DFD04FFA87DA8FD04FF7DFFFFFF7DFFFF27F8 %F8F827FFA8FD04F827A8FD05FF27FD04F8A8FFFFFF52F852FFFF27FD04F8 %7DFFFFF8F852FD07FF52FD04F8A8FFA8FD04F852FFFF52F827FFFF27F852 %FF7DFD04F87DFF7DFD04F87DFF7DFD04F87DFF7DF8F8F827FFFF27F8F8F8 %52FF7DF8A8FFA827F8F8F852FFFF7DF827FFFFF852FF7D7DFF27F8FFFFF8 %52FF7DF852FD05FF2727FFA827F8FFFFFFF827F8FFFFFFA82727FFA8FF7D %F8F827FD06FF7DF852FF7D27A8FF27F8A8FF52F87DFF52F8F8FFA8F8F87D %FF7DF8A8FF27F8FF7DF8A8FF2727FFA8F87DA8FFFFFFF827FFA87DFF7DF8 %52FF7DA8FFA8F8A8FF52F8A8FF7DF87DFF7DF8F87DFFF87DFFFFA827F852 %FFA8F852FFFF52F8FD05FF2727FFFF7DF87DFF52F87DF852FFFFFFF852FF %FFFF52F8A8F87DFD05FF27F8FD05FFA8F852FFFFFFF852FF7DF8F85252F8 %F852FF7DF852A8F827FF7DF8A87DF8F8FF7DF8272727A8FF27F82752FFFF %A8F8F8277DFFFF7DF8A8FFF852FFFFFF2727FF7DF8F8F8A8F852FFFF7D27 %F852FFFFF87DFFFF52F8FD05FF2727FFFFA8F8A8FF2727FF2727FFFFFF27 %52FFFFFFF852FFF827FD05FF2727FD06FFF87DFFFFFFF827FF52275227F8 %7DF87DFF7DF8F8F827A8FF7DFD04F8A8FFA8F8272752A8FFFF7D27F8F8FF %FFFF5227F852FFA8F8FFFFF852FFFFFF2727FF7DF8A8F827F87DFF7DA8FF %52F8FFFFF852FF7DF827FD05FF2727FFFFF8F8A8A8FD05F8A8FFFFF852FF %FF7DFD05F8A8FD04FF7DF87DFFA827A8FF27F8FFFF7DF87DFF52F8A8F8F8 %A8F852FF7DF87DFD04FF7DF8A8F827FFFF7DF87DFD04FF7DA8FF52F87DFF %52FFFF27F8FF7DF8A8FF27F8A8FF7DF852FF7DF8A8A8F8F852FF27F827F8 %27FFFFFD04F827FD06FF27F827F8F87DFF27F87DA87DF852FFFF2727FFFF %27F87D7D7DF87DFD05FF52F827F8F8A8FF7DF8F827F852FFFF52F8FF2727 %FFF852FF7DF8FD05FF7DF8FFA8F87DFFA8F827F8F87DFFFD04F827FFA8F8 %F827F852FFA8F8A8FFA8FD04F827FFFF7DF8FFFF52F87DFFA87D527DA8FF %A8FD047DFD07FFFD047DA8FFFF7D7DFFFFFF7DA8FFFF7DA8FFFF7DA8FFFF %FF7D7DFD06FF7D527DA8FFFFFFA87D527DFFFFFFA87DFFA8A8FF7DA8FFA8 %7DA8FD04FFA87DFFFF7D7DFFA8FD047DA8FFFF7D5252FFFFFFA87D527DFF %FFA87DA8FFFFFF52527DFFFFFFA87DA8FFA87DA8FF %%EndData endstream endobj 19 0 obj <>stream +%AI12_CompressedDatax}w_*˲|PQ 朳,ezRLO {}g Օ;:o;XtkTroA\dZhk_{5o~^N +\'+vfOٮ۝l2GWA[_ޠ#k MṢy>,Zr!~"j"vIIP^@8, U9NTt V +( "AsOr6ngN:N,xRM7ZVɯfaU?~7m*+imAV_`0G_$K8}Κ:joƳw7 lBDT^y^F" 9il< +zKc$Xbj́1}qh~U[䝿UwZKp|T"6 0/G׏2`iѾܐeK}%yBjwm^0l8wWu tXWn΀N{M@r^a%ՠ^*$5rAx z_t?Ue8ȁ<%^KsK +̼FDEhu>gg^v yk yhvۿ:! A5Ƴ$yrV ~QuPmvM^~5Oo7{ӨpV'OlGWT ,CϚ9IZF]na;j:]Y.V]Ȳ/xRtD.F]@iýԣUΨq&o핪VW~6kްtZvیv?3ߌA5d7##a}ڧmcM=ޞ@~4@_.!VWib +SPOz#$)AO3_^ZoA,k`HoK'bZW3v^Mc 2SZ 1b"V#G&F_+6#qzaJUP%/`,?X٠jbQ q(E +gl0d貮2>5g陀6v"fO,Oʷ;1?qf?=+6۝N4;0EY`xj @T`.M:}qDꢀSz U0ީIcg.IYy $GﶪYd.!)ζ._ph:FcN%O}|-K|͸Չm-4y>iȾ]6YQYX/i7z5W$[}o?n'j߭$?zzo7* QUk}kw6),<4ݰH;is'nHͰbNb8 +·>ɯvю~` 9Z{^)|, =X}DVU[MSԻ͂-8[A'yQ=p,6qٵiE^*N|ؓ0d YofpOA vO,3$@cvJ&M9խ +yH50Г+Q,5Z="߀QT,NƂXP5)RX+{46܃-ݐ|mU{ ށ~cP C?~% 4uqo)Mm9UNlz=HFD +/z~jvA`9 haZ=wG3{zLfgX <)*ő5]CҶsDAU0Qta`A) 'r0.d eO՚ʹO|HY@ؕaeLj{Ln #Ʃ]z!t0Wp@| R ^ -UV%xO+ $KIa@uL]|70AWp(1pjMأšL6P$:ͳy٬}Ʃq. +emu,#eejQ@yAC'ShQYNF81A_4sHQp0!$YS%f0qWa*xܨ7I'J<-K3H:0ZǍmSYp>ETI%f/ov lw7A@ZuD:Azӫ7~,tǖ<8Y~/eg-X_$m2]*ImpC|j+[G ⏢*_;te6?x߰+?|/p\s +0hn|NlΩ̾^bZ 9/fD:ǕDN໊:6ݏczׯ4eX 8Ifn|on~Ȉjn@VB V(AP7?n=;zZ^׺ڟ`2Y&aXJ +kiDޫ~ `x| PYyO qv[f?RILOԂ> +f୉ )F:X36XZ62kS{4y.8]U2 "$z˅nWڶpx= T/:1JG\-UJ\Y@$D?;lĚcƒZ) aA$b[()!`:֓H^K9ojW@&,eUİncXaCB/,A3H>U_|Fa&{|x 0Āa3@_o7͏6Y{{-zMЅu|NwUpb c BQ (Xg0`]@) 0<44)!(} 1dIZ>7`̘HiQv~.\dl==={&"4G~3MGWmkcTaPߟA#JvM=!Ee֋F4l% #=:exy zzo\[JH̘qq8w Q9 KdFi&pfqRv0-@\d(dմ̭2HFJe +,0/I4Z6* 3tWa.ʲ'a +,GZ}rO(n܉A&ϴ׮Kn:jlG?fu(6P@%Q0MTɺFX,v@* _0ڮW{a+JD vnXNB41f;ݷu&0xF`JO$]{Ҍ3'Rɿ?dʮj>.뜬glrL.$H&᯻?a kJ6GtuW0䠃M&V&L2P~L^N3Fom !O_x:H!X5{dy 10zYE30l5ZFC_EAlYo?tKk:a•lwdUob^w/5ț e܉,YR}P iφ%/|Oę'ÿ+辬Ÿ-_/m TnwVȅG'y9<@Onηʤ̓>~1?Y 8yL4?E#0|gB(PӁSo\9} q* z |B&(ܺ6nދ\1wm|D$HˢDW/}kobZݯOڅʊ{k|q"NֿVSٓ=لGo +p2t|WNc+gHr=BW6NmMԔa5V騷"Wwr{R"뭯o-uO6z[tW~_Uֶj6{F`̘\'n^Sy-r%JvRKu9m~Rv&-]pE٘9t+FȮkNdxԇa/ =Ux s뻩yb_M;eٕ]9[>ƁwsҌTJ4t+_Nz?NKE5/:k|\$=tuf0: +s'ҩ.T\X TV~N'r}4Tkl(Ӆ#8׽pf}`^:U][7;=[XtH\;Nȕ+;WQdv: T-\ &ҞnaUE˹>3EՄŋয়՗c0P |(Za=%SfOgj{ok{{}鯅u|,{\-1ߔsxz~/>ל>_Թκ{OnsSc_a+rAZ |Zk_cl>5tg@ؘ1o{ڢ5̊i꼿a>-V\wzNxvqn2YO76OQa)XBf8gkVyC\3a0o)?} +[%T([uZ3hHŶ%7{3Y|"kFqSXk/y7D ko\{ςlAw'tU -6'PwN|y +sr:M IF Kg )6:\=^6}'b T ClsRLj)yg1T?w k +[ ׁ뇞xx(4YfSh]WC+y[OLYO?xOɘ9 \Pk9,Fx =(jd0.s\}$&\}VXȒKR qta4-F[WAbo"FG1Ŷn9UK t2AN/ ] +6쥋~6k~YݳIe{ZR'p'f4Eua75m u]jֽBbX{rl3ױas`cfj\}3Q6lx;$Yj9P&;64܋ +^`(]HD:.Nܶh1hxG87465 Ӣ/Pl!v`p`%<=LZc8xHQ~lpatQCA}1D:r~繿?MS| Ό]BP Yn,t\ѥ P̤'$Y۩>pWP6hj L͐p76[-n] C:ƜE>:F7=hahHD<ymQb`H۔c1 t'mJ:ty:|4APܸV)"B rUcM-8D:T:9#йCCkB) +<peAyDze7 x,nV-8+-'my|Y]z vƦoŦ7LFITwvnJ/.œV7Z1,ؐv&ةpZdؘ{0кSKY")cƌ{HWbcBa=@Tn,b&ܡIW.J4@OĺD[swדH4ODv$ƥJPއuD#NDKogWN~v)29ǽ`#SB!J1,Dx|qͽ;vnBh56YK1yIMl[㺟 {4݌K͓4PV\=QO+A*K=h3;&@+,Lr^m9'_Vg.)#y|wӱܺ0h۸u"F"O?>yHO p]OvbaZ3}t ~Ч U6|o$jL<,' ={ YCw,vn$KX@ݑbX,v.a% ,.R k7x%Ilr%R+>T*y$'MؾsGd E2PmEٻiqnh +D\*A{|cMɷ.5$'>b>[L}R/H!*-+vɬ#L..N SW!-' jiTAgzЅWЙՂ1;+XՂЅWYgwLZC^AԾMVC^Arl5t^·fW^CWet:2U-Tq!} iU?BA}dׯD0m1v9* {Wr4O Nce#b,(ygTꙸUQߘrIM|DMx9{{. l"J<HQP[3B\\'-n!,.ȯ FGTi,kOaÄ" I_&g +_xjʃQJ(9(<%u3Y5mA>ǹL{8eS'cXq:$8vmuA1$9V6RD&N"^LDdƌȸ% 878\9F4B)GGdq&n#M1!9d,s\̔K#{P7X>C 3(č=dtܙ*1P2JGNF-g&1w)B|,8L(]W7aC̺!m6hRz1^ah4ΛwFڔFo>Y7y}%M{5.fńpv"nꑀz+RǬcW N.ZZNζ/ՈQ8z8 V:fn9A!KllҜHGtbDFU|,lẁ?AbjtҤfsɓR'T*0!o,Rǰ.8 6j3Z^&4챈Ɇ7Z1hEllZ]„Y8b5^iF`9+@+쎒0h( ~$Hߞ#gpLv3CͨK c#-VZyeQZyg FHNE4*RiTb4*R+RoEj1[>ڕ22͆yޅǵgNR +b/ \9q-cclڥp1 K5I)/#bRpÐ\D'A»32z]-$1lX'uNi& +Os1@J✯6kW~N|`u;{T:i!1׀\~ۺgÝ>RZ?,J \g^~mn)WBT.%]K[srWcԝonΗEwJ?SʟT'.®?Si]mWՠNB+v:թ>\[WM۷`}|b7inu;NQOvaugav+V}|GzP]#.ӝ]"x-uz#%`W{ɤe!Wb(=a/fi#aZ[4,M*6/Ml]Gw*jvOb}{d7ɱ_CWN&9B4#]a1nqy)B.f\:lm k lH/L2$Ox~mD\C$өcл0y5wgtuXtN.xrtArtEcWӱ%OXM2Z:7OUKǒ0UӱԫXtԪLUKgeNUKaUMZ]j5{Wtt!%L~̓'c҅[JTӱJXt5] M!O c6QMcTӱjݷiVӱj7MRMj_32i5{$fdj:H6q5.^1X+rFttZx~e :b/[MǚLC +qC*R c~ܣ"k*bƞ?QN?:u1bߛy_]ܚAn;.ʃpNUnQdq[鿂6R8O申AR6$'Kd= szףGq`\s,v0cc#^s;v15w6]tL)蚻ǽsJnkoHS;KW^t<.pÉ#s5v뗱cT%bIMJɭe'. <!ךҍWTLO\{J* [Q'LYnP9nd[K|FaGL +RF?z.9ۆtV1P̄eDZUq"r4ГUu3K,B}Hs3RVؐQ1eqӄG\#U +e1WRߍo[ɤj8Ww *8Y?F! ~MӽHvy.he&{#TbcǝorƢjyFXhعiGS |H7Qe*5. +?v  +0d9^<9V`؃F=f6T*5szV'KWƯ[G[^i?+|F_/#]ut.3$|)群R|)(Q/\bڥ|LK).ۙ&llqEVφQ^Щe&S:P<j*7B}ıcέ~[̦4̺oJѳ+F/V4,n^; ׏}_sbIc]=6ʽ~+T6rwVqXkYQſo[ƺodǾotZqdwEKi^bD'/<Ɉ^?*] Su_~슡 7ҦSiʩ=o 7q^V"}_~!{|=4n#rl +H†X6*kVr,^ɬŹo{o>q{߸[ǮL^?V0mubPsp_~kb['oSƾS>QYM^ o7iΕu_@8L13U&/r5~1bh wۍ w۽\9~,̄^~^?ae{eG6?ѽ~(g7~;6&=.oprls_B@ 8g{! b=J)2Cr0jxb;Qi%Id.zZ_R24̮2n-V8ኧ ^/zg +A*x2TRs.Nk]I}Tcgz1.lls{'[?m%TmsN[\?_\jqpX]mz~y~^5N䟛LVV*8L[wF{m$u{0'fvsQ<5Ғ˛T!>~nr&W>*jܮ2^_~Ͼ(}.ʭH~{^6ϲw}]ե+GVbk '9|Ӌ[G,dtt8 +g8yZk.1mSu%=CSåtjmRڪ\]F~; }`jg%'jƓ ]Io bu%]*;r}fyN9)g6ՃbRgvn7@[{}usHo)whjָ@3T,f\9JȬ;G~鞵 +Xd8}xN\q\ׁ#‚ϐ1DmWu׵%c +kbeG8֠=.W^J+}~i5z郪 G?8yڰ O=E̻|D?ߐߛP%{H m\n#=_2@js)@"ym EZks9"sX]LӜKh_Q+ +nx_l +[g_GԥC@UW^euY x~f-pP?pVCeԬyx"Zu%Q/o +y um"[hfMW%ڠDd4ZhX6LmZ _s;+~ [5Q߮;S nmr;bZJM6ԅ n܀\,tYZfwճSE6*E|03}=\oSfx Ʈd Y 7?H1"멏Oq-|™"DFg\xy3O +1챥S7UXu>z|>>@ [d֜!U?|f_ۭv-WXԛVɁY\cbv4R VԐDŹA9Y,v8hdŹ-kC<%:Lav@IeOTV?۩%rb|ͮ,n^SE*w>3O/S-qSKw{lZJ(nlC`6r3v*? IDNmkS|ۼYߺZ)?* 23m.+b:?ӝ%R2߃~6;{UYK˿2WO˽,1'rtc˿滳bHkvM݃/%4[ 9QmdBd/O6+eY~'=g wߴ.n<} oү(z֯_w<^)-wW:wq[5evbsydwΚVqRn&/J&(rBA}YJ c>Oŝx"=#'&4?1'>8\']\]M-tP}`L-e7A.n/Z%m@ϟm7pPs.#! '3{|#xilW^W736-a"\QHhg464"(}_1(8g]av3Wmqy z NGp)+2i(-BHMf$s5,/_MLc6F1WxN\Xi ݟl-uͭI: ykOy;u]=ʭ9m{ }V^wighZ]( 5HwKh!9yq$~p xD<,^_norz \9S(e=D1'uiq 6-h"=!z0 +6==;ǐa k…72?4g#WatB]1g;VorfnqKVwx(/p}W{ޗ3] +#Md;7G/.^~ *"}u:~E&vM">9}KLvH dSxk@Z%Y&eѴcG +^to$xl˻6k`H5Nf"LԖ!kUl_cY\Z^'͏}wK\;;xH}MI$ TJ< X=/ը8M-^xQ ,NOc8&sQ"1|~n7 ݽmev'05!+yu}D=D;LnbX\2" ?7ƺL= +`h,4qEc{?m\^&Azj%=ԁ^?rLD˳=_0QSQD-V R#u\2!FS;DTȽޑ,>kAɛyIxFӖg6CjoBU6^}$fEORS q=C*;ȩLrG5H;O3*6.~hQ8,?: zXߨJ]KyHR +k) 􃏵_TI,&:DO2Qv ]& + NV9 gTZube!m m[`Vl*%lc{|m|·G<+Wr/+:J*6b +@p~[B;ʼnV8:QWztHoYp2iQ!%!;Y]+6P_R͇} ӕYZn] V_Ofu&P[:kȨ^foٻO,U(ۏ$^m4r-\;Y;qus0T2e"i+ח42 dht#%x5++ğ9eTMr!Ab3gs&M[c%gݣ"'nL*GNۂ-2PuOj)^ [il'+>_JѸj3(wjF{\N.K\n:F\&Tà3>Õ'`q_{k/~ݛEH}e"Fg +pʩRdʌwEZ~0d/g~] K_$_ysm\W2DzUJkփcD= փ"|N)o?xkί4vKK +EORkƒ (T޸N׳MePx9j~#jM'=),iet3_IE>9=R@A9yz!r:^H#Jr&<%-vtp3[t#gs]M+ ~}-eo X^g-â*~J,%mlq~> fha]`ޫ.&̥ -1cR_酧V]X8Z7U큾 /)մ։ +x*}*6Q"J?Ƒ[lT3Ief>UyS1jcȃbv}EWގӺa̿U`7׳bGwܬ+\yDѲx\Vse ewf)7g(P@n\t#9N5 t!AwߵhY6]^Sqs*m,b?(-sD{^mM/TΖ~y7(`si9G9s:PlV]Nx+a֐¹\R^L{\bh/KY@٨%r߆i}Ӧ6u\Nsd/afqsk;C5ct.exl5voC~ѹvmot^7:2ySq(llR?:M\MXex?& T^z<[gk&LeR%`NB\ {_4YƲA4UĦixduXph,#h,DcK#OfBb\Gi;o6]9F4UFRS#/eZ_#@%8h~-yO1Xm1̧%#|ҺWR>R|ŃM|NrsOFxcaؤ+ɉ?'zO6L=E(GX2&d|- +0׊ɋPB'(e('!~QY7P#qN/GTs*"}w7sTy^==吾sfh9 ~r$h}gy'.Q7.݁pvɁuh$B`);WȚ}9:vzZ¸c Z'|uQ) i/hv זK[+oOuվ5“ۏ/eZSg%ţ%* +i/Sn:sc%2aA#$ D> !F+ju]@úiA< +T|}H2q]#X]{]iqX$) 0-2Iv9R|7W:ڬ<|ʿՍ;Ɉ-2H LϓP*f3>]YǺ:<ؕu+veJdTvejD뉕Dw(_wuzw2N/v>i|'yAK + _d=!I>^BhkÇTJTQ/ D&L [bD5 ^t`%6^P '*H,ĉd}0B#{L*J,0}vhcAx5Dl:> @H6 q&Lg2H<^z6q E8|~a(,#xf{~蘬_~?V^v$0cDӉp`C —$015--vr/7G &/%3ZT4%L!HB&fA0A&#!b @Lh1ㅀaŀAGSA:, lZqU7A)ME?epOYx 22a0@ +4v[ՈG#㬀;Oєn3'R0"IZ"$(x`'0Y}h_C 5 +E`l-?FbF!/Ρ * $d l°,܏l0 U ;QW%>_aB t񀋱4,y,PA.}Dt D@NPGrZ4̘f!w`gH;aaEЁ34jM DI uXjb\5NsI#]*)T #Nx@r! m: `$# ؕ.hG0ECxM bEӴ!qHt8 M  Ɓm"DLI\D\|%R;CcFc !J1pg5|F̀Q 卉IEZLYc`k`)~Rl)Зtp s0|rs # 22=gt ʓ/xHv +c >0v-v` +>ʀD]~? +jE K`]| `|`7B"g)!K1pg1XeT+`dOľQ3X \Hb Ɋkhj* + ~]PU' јڎR]BSX #qs9R26T4@Vi9!xдFE4<fBX0`8聓hÀ""tu`A{H9Z7^[&# o<@ѠA֧d\w0a4M+$0 vp {`(m ĿR2 +(:\Ea]aSGaQE$v&5p \Fg*o=c.i~2*Ɔӕ$u ;QԂ#f8 iZ`mpn q4-"ql6wYLhnVETP J An<_3%ct Fp0H. 'n:+n4lAn6)шfDJ5+:xI f|5 _;)Xno^Fοv$pE3)7('E4B>z ` +z\^b+XOCɖ)za.08 HKSA!BP /+V<(nŊ hkn@xFDćƙQB\;s.DI6tFj3SD J sېgF2ĻKA*i>i`M0|@:PVEuY|-nͧ9'F=%|8ţQp +C`@:pv uLijY4σI"hkw$z;=f, HuЙ&xF˿e/Gd3[H "CCѿZJc{OV_V;9MN*w0mar 7 ybI)R!9X6հThgp2bdI6c~tP{BEK}0"g8D|0"qh[DIRx | @Zm~Ɂ=xVbQ2<2웏DDq̑k` @m)cC[F`3qgVq[@V)1w#~$#+?gV ެMWK/{iŪ0 +BL-Zn@qU b7Ird, +bAQʆ +&ML-櫊vxVqw,p*JdN3Tf܂ H#w Gc'H4Mzqv8"ǁar4J,G NQ=MтFzQ@ֲ&KTS3a#a=`Ģؚs%sT9igd%pϷ"d[9Q`|?@ 3:AUBF_b lj<q!R}ŀaG X 1^q``RnlB_A9 X !*,^t5Ɂ!b1.:8)V2dElbH$+ Zc]z!0F( +f[Sol] /L-ndf@z!;  #PHtJ +taadd. (=BNQqxUv?}ހiQ3Rmcߒ&Jsf$JRj@Vɠ QUA:jZ'HF?.y,"-$i(LdFbE,Z'@ܢImeIiٝ8K"NX\+X_'2و@ދW5^4P AIPA qݼ0+)sq!N"3T+HNA%2PXTK1F0HY2v7$P& 1r"JSiVzSh?%TeA ?@ SL;ъ)CLyab +FD !!,1)hs^jPe}72ZbvU*zab%tD2.R + @U_r`lL)g6`#]M`Xwq,yE-|O" +T-&SJ+| ( ٧*CDOXKM:CDk /@*`YٌQrdl㮐c%zaF>.hW^0 0z<$8IF^!SiJ{vH$( c2l"@`jJF+ + +WDг`}0mH|tc +oq#ՇYH".1X19>מDJ6黎1m*u" KQ2Z:a +0|km}>M cD˙xpIL1L8YK +a5U@L0,$s80,(cNxta9WY?ςaΈDk5H<-+Kx$l8WR%} +־@&h +J`7Hp\ubMhRMG)dD`3̩V42ec֐Γ[7ƣETV$9ư>mL1!@5-hrv G (vã #F$0x:xRڽI@nme@!@ST5+Kf+OIGkǽ 2GF +!jsU^~D 805( jjJ 8 Qm]-J +9Kދ6zQ\w8sN4̎c!uE hEcEA~$kָ-CuKDUR%wILVu ٛpX JP&2[ufC(6~DD V="& +P3 A4~d=ZȃSh@0!x:Xf·`K3$ +k@IdDչI<ƛdeaCC4* +!8, TSN l/ۘ%9dY' ,#y< .(x({<`WʔHJ4FuvNXA(b%tS+9g }pn+"Y<7a()zm +DfB 1Ru!  +o]E#*L#bzuLg+#.!dj #J$7T AӀjSe"] %8 @n4.@G"bf,#UՌ8^)ߚ@JR`x `?0u`sE%d0_YNqM71WۻlǁO7(cܪZZe_i>yzl# 3(z dDCd?CHvGuZ\'T#l\2'Dm~l vc/]Ǣf߀/$(͝x XoM N [v +Gm;ՕcMߎ#f:a‰er%p,8u\c'9$>'V垜 ld䛾tPFhX.$!ORUh?>=1", )_,{&OA\*V0R`(?adu:,$DZ[ɠvUtd9JX޺=IƮ5);\ ȜqX_C1enDflv|G@dሐ=ٵ}ytu>!gaKzU^%&"k0Y X(u%EVeb[ow Zٔ*!(8f߫2-1Q4EWCxiH0l_VdK{#6uVE9LΘ3˃aoĎ83K9ܺkl+$#(ʊ~9w 0k [i:;qB0ƹj: A6!DVLy2Y{mv-By8}vJj⧌痆DG *6:G7vx7r^5ƪX԰J&(o%VfCHZMGʥShsX6Y#XKˡ}ɳ rS(CA+I 1NWv?Z 6QY/Az؂Pm;(.yꇑk)ʆyQ[z1ޑy3j",+ `\޺mb,Po3)i'♇]]rJO09Rޅ#0h́b?#vYx +T=~m-LC,#l57X Qq7C4ʶLDƨ +sPaiQ+ RZ)Y9mk&lӎv,;(5 ҝ\^qM SـM#/q +cx̟.:?TMͅ)DZy~ŹxC>JiKKM%nP%A/80+z)Pdjmo^9'FzlHrN8֬<>nb vKr@8`ٷK xm8Tem+famX4MD2}" D8_6S\5R]ao>xb(ݓ\ .Q5:"I0Z4p.o#.ڳikoRDΤ~xiuOGBŹ `jLr= |@ĉu!$P1eKU {E+D۲BNB<|u +֞.9loyݺg\"$; N|Sh@d`/l:,$%|61rlalK0GӃ!J8=p'Q`#h]131X?KCTݶ|IޣB\` [ 47Cj#v UI"sA$b#r/ v&aSy7^201wݜ.TdH, C@C`y;T0kt`˅ܨm0vj;+pQN02fuQU/`wÉ`%*HH5@fzNm)NR(C +ٿ)04MnP4BⰀM;}gR#h`͔sĢr&'Ƴr1 ,) 4>ȇԲW:+c8DJ=#V^$OD(Nե .9,̓1Eq,IfP̊KI"vdQOGb?AtI 91l'HDBu3Dk>5|(46VD[&q]\Sv:b0{(rδ&pCҴB2 hty$xl' *!㍢ӫ cK~h#t<Gh#`R Dfxx4{Py,6blHl#4q,w=y)V +s ޵xSЕzH:jIex V2X$S[j.q6~ +`ϭz?g0}o„d_)_zc<>f!"݃03dfn}2"!SeΓ R$!qNeR'J[B[V +@2S6/Hz=HFd-;2":|%~ έ]=jx=N:?5IƟ~@{kKJeJ§aoYSAF:G19gYD߷_+J$q{ 37Vo>!4`5M &I(77;S&+_vOm1ρ{l#Ю?^Cۀxt3#q "B NUzwG1͎vFܒIx:N\Yn95 +X6D +}Wo"ԹuPÖ33P'hkk}ni,?_R QȊvު @ Ա9\LllXK¨F@ NeWKR$Rڅޅiz>3Ld\V"p +*yC(~ߜpQaP:]nd\5&o8]0FVɛ[XCIDX%fVţ:1?1 GU>; 2Z+")w 5} n\?k!g- AN+L@$!M;CGʼn%8v;*4lo$e dZdecvng +׽s&ψU DVνx# 5nq1fo܅2K༪Ya 'FWdھuPŪJфI58.PK A?2èsilv$qi~up˧&@c${bu",P(uH\Qly2nͧ}Ka Ƕ ʊa}zcqԥk`sB#Ş >yxkkQp*y~6棵/Ҥ {'Y< j i C2Zc~޼;,bLH=A{7(.+=qR ph ̛+(@t.KDmd\|0סQh4EρpYQВ/rDƀr8a-zl3׻HS2B1ppe1"#_<H|o"C~t~qt42J d$  h (]{i"↴HbP^IzF_ T UZEPm\RGF`Y[b㈘Zc[Y"nIҕM|ŏT!1ᰯ;xGyj`XtmF' 7\!, U,4l9IKxlBc=;Ot="݃Fh| +iڷpo/9.@")QU, b,/' QĂ%Kby^ÂN$Bda_đ)W +Ib}y>"$}zFې +2vv VT;Aa P#w {νXܰA[>'${7WaFI/o`7v]*r=b{Q?.5,Ck)661A^ JN Dưg0iR:Dt3XDqT[/dʒF@߀zE#QW1R:e.X`o+akj˦`MB~naHQ{ۧrV$&a@ܨҭ"#Co:B V-q٦xfC щ3TO?TJPf-x +>\EPҠ #UX[ޤ`E!@0}065){9퉽w.%#Œ= +l[E +$Mj_@-xHȕ3V4SWQ.fHL.gYb4^ d*y^JQI$s;ΠnÃmBJug,+^əi"hv֛n\KH!7eyVp"eVr^ ڬ٘ kȺm+A032j_?M!"Iڢ& *:czXN|ԈKl,93PEjbD&9pJeY0eXfC B EvyC@ .6晴DhSkpCdgN@*_4*ڨ\k )g! ] &gT"pXLƧR 5GILH2ߒ]7BFf4qDdp?Z5>4w:qXe3 ;]0%Jd\rݩt^zmzb:Ig4)$WnWݾL6~M(G:qupE9y珓m6N`mR99\snP5$f~߯mq@`?ɿo;6l_z-6BwL +iȍ}]m-_Яy0 Ih2- $k%M.8ݳ(Mדt_kHGORqg~Sui1& 74O+@T Yy\=Za)5"HN`+|Q]&L:y|U [=,?BpoOBD 󭠶D<)Lh=\@zojdx^e8ly'P-,jC]Z$(&d0VJXb0@DG\mTZ|t := +HTH(;~+<•'l""P9k8P*7{csZ~+AR s2w\ +Iv^ ު%1$7N~gL@hXxsY@FtW`ڦxR}s E"4KiZdPEuj t,c) ⋋'x@1F`_92K|9ɌbXFdА0 FQЄ\A +,N}jO=z=76ڔϞ*&`Bc \7~$' 8' TWZld[pR6ABB4D5qWPͅdx2zgS0gO'DʣWUź + 6AB;(*Y[/'~o.R0(e k@lסFy"ܽna){ko槸5c~cJ1C ;`{:5) swEBޓˉ+(C{p`B2kPk*$viW䴳e,~0{YI)o7 RQMH@ û,J`G#0S !-HB;Po/$K;ɹLYaJ\)呢b*ޢy5i-7te"1f C,*hS5O[S8l1#=H<)f +%𦌗r1;XoO"T}-al!`\Д[0~o>QќQ$1lu/\d㦃o3PR#vK1P~!&{6ђ4O8m Y zIU"cmJ atW}‚-x PF8%[F!$t,5vb teOJV\J{n) $UV4#┙yl9K?i1;lh5{'N|qb~0J&$,B:- q9,L Sm@>{7P +XumT؛lY^ϩCN5[TOd)-3(Ad8W2EG!BwDD{" YĈ,Tѐ7[rqCD pθv2pb `k# &M@ƛu8FX;;):"ŝUP *j("h)QN$L|*ۭl9,H,ju``aId=Hp.¹t6;#ֱc$1Ex1281׶nFLu?@"_;p /儴pDPkЉB1jϘn~ub +Q[bxැq([tX'24=å kdm "ids Z)%ML{ D|qu ?Xs,d.oD/eZ~["fblFbIUpEYw跿D[@xk'Nէ˒;{ FC[txBv0Ie{U!A]+PJ# DѓGH &PXط(!:4q^s?cSءyeŌR.ƙ NuOb8BtQ`s,0fxu-ysrZABMVjmvҀ1Ħ[r)22ɢ_=k)R"qh Pޤj +lW:-9 ^,z\M Ѵ _I Ő)13rta<0⽽\qrW}ҽuX"9 ?N[XQX v/M_AcAcn%8FY~[<-dY7ceJ;+$W!f@ 4qEw 'z*'^vU2~ca3R"qhܣS>9wzH8*[eKd5qDHǯL~qDy+gL hk*BIP^ XV9d3R%fqg~eft^& Qnyƙ0`KBaPVVpu< B}Y@;׻! 5.@!hW2&_no/_1yG.ΔQ0<*"hcˀ#qH|ѳEq$O %t(۷dZtrGHGEP?~%Ў0[fL^˔I.ǗQ}kg{0RXP>zu(j. Ab?C%לF޲au*0NzDX`b*Wf7G8ΥDE2*m57dʬkw!Tbc秬G=Fۻl/r'6BE@%>]{kwgO%ZYP@#IuћuD ,F$MI 1i͢XybцN+4suɡ!u4o*x}qJ?ʥ mG)&f喙wh asu'G5$⮧'Mg0H~~"qmGH3 gkaHn h \}E*qáG:zV9;pt[PּE` i`C,\{jh{LtY)9pP9H9,L +*RGܗP"lugEmPI z .xM*\[}]KgC`t\^vY +AFn~^%By/y0{G= +[hl$@%c쑱`0]@4=Pn'_JqNAobT%lQ k8m!uv)r@4$=\=rH_eT)iٙL (4ܶ4..BGGEVV/k!.3膁b FhtbI&*F>qmm5 +t0iI^&F$" 56uEJr?iOpX*n`E xF7(:upnA7osPwzW#i ex-L@ 8 yk"D|[H>0[l#zM Qъ;3_% bvz w6ށ2 +w".g:׉Q{hő3p`{9lVvwX߻wc#*5@`G;e:NLW=2 j!["Np|u"iBV{z:Q{ܭFߊR>;k1/w;t Y4iRFtxB񛱄]PND0 Ǟ&L:BHlD*;q c`ǗeqJê#BfT_Ḋ| +N{eHVemi3 f;t\ "v9}m,ڂ1{ p'B͹@6ή>9DP&ZƞD@d*rQ')T_MJ}͗&ީ$B޴Cp!#:BP_qtV:aŬTSvĜ?ϛv\(|\c&ݻ瑅G"΅V+l4rW+deHWp3| m&H51›(:P&ng97@s0yA){GJ1GM!V߫>K.֟fS3ΡWҔzH&M笜KN1k} *iu`l\/{WJdl2nfS񸈖Acm J!,Lv"BL&ہjYal ν=ncD[?Ҁ<7ٞ}>ݏFT_dBH_yNke2F8 V"^RJywM# s\Hx;Ёgm<)50:wĮFn@m/3ƮrG[XxE +Q{xx6Cb9QA)x'h<7ų& gkzkA`J,2M㎭8K,֮D]bh·!1=p3_tGW&1<<йٰ!쭉8c. Plކe_>|uL5L<-Jඎ9Eĵvg0l*DCr@횰"/ү\ 0GHLo56z$Q +h1T] ~c8vV@;4IvnLN^:;M-wQc˟u)s1` ;3[@)(Qy̌9k.\y$Jfoo \:nqE0m_ی5$ǒs %Ǜ˼/[RMe@t/I -}["x@#%~Xץ~M~]?7ܶf16Nl4Xy + +Z~ +Zj{yZCtyld@JkUǩN<x4 M?n8.NUGSZy\9"w?$-<´XGmݢE)蚌JZ(aSXӣu9V90_>^]*>GGuI+*{r<%j#ߴ!35k@5imVGLmI$KGّǣS#7m* +z6 5I^!~fOKEF +"'$\|D߽NGE/wcwr;;ױXNz:{䭑![d8)#} +qp|K^ike9>`mBoҳ_ƖUA$^J-;2T$Cgte/.sHhLSQ&"kg뺌zUz 6 O lQTL<1] $UD JĄBr卨!ՎaZ&pD 4oD!.&Fssui];^ U݆ ܇wrE((5uVO \ߦ )`|D!u|jKPJNH%kL@KQS9;L 7rD#Л`'.>6;ٞ3.r#qcC;&)Lgh b0 2.͉ff!O$-qSHo)E[\椖eBFo]ζ; Tte7tt'pڠ?E:gg/Y:vR] 0۩~BˠOL1]KPsg~>r:{+FP$uN}$Q +e_s؄!dNȋĊQ Ng,MġYk\b ԅ-м=J 9;Z[?X)p5cΝ:gh=za:c̬*)UU\KIYbܢus4Z[ygQD/hj`rV=C3ǗI_䙳Fr,N87km +Q6D R*aB 0QޑPlB '"{? xt_M[T)T2%f0# +:ɣ{Yl"|"= UX=yf/VW AUgf(="G؈#fsb +L'I]yi]8޽&+*PT+:gzFω&>|ؐf;'Bh]Ay½@as׊ JqU> S@ Sn0I7hVAڒ @ߺ6ÿ vc/Es,@@/:1x[kdۃ +2o^J;OY~G؅־"v40qSo@$yfu;0A: $ |;4mpL> sf:DYs)tqIDu.Zl]uNS!'>zøWU,\#'3԰/&&-#N" sXCJ zX NjʹEt{Rdt9'E%J8`$i3\Ȣ6BlzYA]lm~XW:U*sj $5oP=ۧ\(ve8CRB!d] ӗ;[^* I}yfi$n"nDr62a.c +eA[-NDKS"pX5k(^4gռ2qM[5MtOS}+>Ow06)b)oځkyn J}#cs $tRNnV,iy9<}z8Y]/gѻYkz7LiZtVg[{Qk^B~uз<<zJ&;e,_nqG":z/x54| wMyܡ\iP.Ds>Dwz~ui4W)ǧ, ו>l7 :xU\ $Zi: "n /ߴ/N6 I 7.afpH+A X~nEpϕ;lb }A,s1\۬<[D4^~c +l 4C l2Ocj?Fi`2]˳U_q=dmv7̰9׉GR>Ĵ;.jFvOٛ1Wk> +ʛ[T|CE,8=g`RcD??WF`4V{sIͧIxb0PLueP9n; )3(zyYؔZD( h$zxB@[WY ?Wr-6eJ'`3`oQ7ɀ{p8w)NruK흡qsa :Y#jz'u}: +2ŇA̾65jD3r+.9q{pbI,QQ]6ge꺸^ HMI} xiXlLi#2icԊdw,*xBeE(<$\ALpfƖHxX&))Cs7&-JUW`umq710lAVrۧr{Р5U%-=oW02R^Ccad 2].RR$. +;,ia?6sGֳǡ1=}t"DYnp^~?-_g_}BuHUI317[ƐMT y49A\ٯEۧw0 09)Ok[ ?U\j+:{ 'MIo|I r}zxVcNqW Swş>x=]¢;Ce9A-.$UCRp*praçccM '[Tw҃ {u0K-VLj +'a'.Bw8XcrWDdd1dO-:N-4V)Ҕ݂7 5/y D/.if-~ %t&D}gSd'8|6Q.|B A@:xS1``1"O~n4P ,-:.goic4i4| aݼ$x`rGF HaMdG%IVpOBL[ѵέ"Ѷl +5 W*LLk[ZX`A5gWɨ[U JKz4آ>‹ugYGE(z~.넒# 9` G9ԉ)7WzwXTEa:@>HK̪?cT\jtv`t'\Ol*8n?65JB # ɫNɇ~#|zY,"S{In?[DGŬQΝ +-<_A^iALмBm7~N I:ׁEf`yI.]BxyUL0?,iq57*B\4bK˒;mġ><5߃V8S `x+DLri@8D)!uROOeH@7o !0L KDve Knk/j^f!+t׻$,*ǫG4%'bjt!o|iJ3QFJ`"Bz_|?ߜL! Gt>siܗ +$e]IO*zxv C/N + /[ڮE; ZBP@骪v.O7.K= !rzQ" 2:SSơ,I'XǞoQ__WT< \EB@<4_(AG-Kq VS詡 + +D\q|WJ5`/=Vw.C*@R`'`CdPsa~pUBLj_ ֋z)9K%oftcdž)]T'jљqGGѯ@%z>8FrHh@a@* Da1|1:“Y8aW@Þv[ڀMn *X~3GV ڦR(X4|"՟oC&g:gN :8T^ ; + w +Qgv{aO}G\ +0i}hr׌uc\HI˽$Zܸ{BtIWF c BTG'wߵ礟u-:Ћ̒%Ѩ>;gPnwΑ\!}AS3H0[}/rɷOluj1("pB6 P]?G&Qi",8YM>uK )r40@E"p1N(;Nǐ(aPɲW<S+7 *9O.>Q 8~!g\$w[j@/ZT%,O|GY5G"G(lXXgYJsR0F8'5k{ U' ovZfO;z^& ΄ϣ.lXjV -V +c6Y<ӣ+ % I~dV':^؄d4MJ͟WXBxߒ0Rb,*^uaLu<ٹYs |IkK(H%==N'3Q[; @'\N&IVͦ/ ry=ZG#]ilusrIRVTL5?>B> rKZVhT`2bS?TcEܰ[~\yIB6`#dž`fU `r,^ r2tܹ9Nt_ /a~I4f;ŵl<>SM-UʞE¡*G/r` ӽ Ly{edӃZ`[2!yui_v<.; p ⵎ|~Xs 7̩{Zh֤23pP8qX%-w᎑;*KTJ:ԩLQ_t&,FyAA,Нw?U_ %f1P^}{ aoع`YQK)o'\NR}3 +~ҏuΜ#n` DXb=xnDۧw18vaڞ ȫ繣[QP? z{$瓢ׁz-S.dy6y6XL@i̘>A!)x Y)eE!I=A)|&IoԖ۟:#ZD +"mS]z;_ Q\/G4(mH0&*9o<&vB[C"on]$šҕ߃_i꫐)㣵a3P* +1+}4 0_󒅔IS@<I2TcNJ*-غ; +UaƔ0LmWRdn*%KCjXwFF'Q$ G<:Xo#_yKVqt`Gvk c=Ă)op` vOP9$C[`i@ j-EOj2r,TmImN'I=D;W +z|H⒅&)/?u5 +l4|X8M-!RAFѦ&sjD%˸ƅhiܳ/Ҏ!JۯL ) #ɋ"B[> 4̉,{J$C`jXy}rRC"̧c˥kp%o奈6ᬪRTkGN~TA- [ݵڤ&WG׻F1E :{SECx5 M)6q]" +#d%$ 5 liy꾓ŨvSɭ3zwi{C˚2W_"6s&p<B:Q 6DM"۶q˔up\ny0U>"#W\`\3Xu`jAz:ac~ΕpH` ~bVҷ+VT4P 0fNkbAǂ!!?EzReJ F J)H,ȡQ,>x*$4'(+rNJ!2I&O^LVBcWmDOzbxA ݨ|vCʶ*☍ 5>H+&Qn ^ \:>ӊ >^>Dݸ0'Օd)^& KE3*0՜}5$ZזMn7 ^$ *eߋʃ1@h+s/O BbO8hkdIU{!EXN o;ܔ^ppCĎ:ZQl?݀]CՔ+|+֪2M8Zd3tMyh%ǢzNc N+[V[%}0P2}i/E_O{)8B֛:~Yi} -?a,a@$M7TJf=6*QScNEqnXOƌ}@XL|\p bKtj&~[+Ӝ#O\(vMD8 d8?C ح%\1'NӅ +[ 93 ?gmJMMo2+|.q@hYX:[G@p PR+l@JC1~gYUNB7a"5(#"ҭ\4n[dM5J%{֐C#XΨ(O_X/8[unlYsJ`a3thz6Hgm/R0ۂ,ǁ )! m(lLW)TO{ؑrP4U7pNkp $7V3DCH=d߂rJ{Q Z9O!-'.P< Tv3.wl#;A 1zo ?iD!^Ne%;.wkXǰ +D ~*cm ta6ia +,cqrN^F۲DN<%O ?QKUMXF:( :^z ECc B$q!y6ZƇlDC4A}x䢘g'[uAw]6@3שft:C.⏌. :*hҊ> ѫ% l0=}@8[I=T]D + /}E>ٚgWս8@3G(]B*a,N :&qaЦ9\fG&G>T'VSS k{aG0b3<2z/3h_CG̼O!A_`>Wf"nXsUȻ=L.,ݰ:(~1 /@=0"ؗہ_ g +-\β C$@l#!$ TS"6ieY8Dlr-n6# -ԭ~/P[͍@97? Y~Z@ض%Q})2ЕF +DnG_$au.e@h/]^E ZOyeCĝ#!%PI"ڊpJc_yiYo-"*T}4b#J@ 6!51 x!4{植Ġ>_\PU9rKܱw %<1om^PZK\Y0Q!2!c19 FB@lBd_IsdWQywAURV* F4X)E֡"$1#@ZQWEm{upƤ5"_jq{z }Jų3!b j<*LQBnPw +AK<y^˅`q]:`9B +5. 43N>Ўi56SG55'FVX|N0&-&]9foJH0h.frC(w1%sk{1ѶSb0uWBW#M_L]G{ t8~u#G/^h/F+_e;Q6}, oT% 4J;th"pz8@qnhaG.JIDS BZOn>o %v6l!c?-1I17^<(XR/jX'ǩˌULtnM &բdBzM9<0n#@9gShX#jSÖy?b)u˓ \=utu69WF=DvW@4M cqo'CSEByYgJB6"})#C'`ngm8 LH%'1ZtU9:]9퓌$NQw0–}$x&kNdJ%ӂ +q" B݌x̟ik5d,>iy,R2j)1Ahn֠42*mfr]ɤ喸 (pY(҂BnJq*yYi0fDž92QcjzguE _;05{3^,4x \q0\XA6zu‡ഥֆ1?qRSR+⣾I3x;J`D[dZU;tGn [En"݉gq_1sHqg~mc.K wzo>XHrNaڄFp˾۱gֺ!(fQϴ1_F`] m$Lg-v,I×z̞c:f-4ǝNV켌ïs`v[4cqT`菓׼k|^FǾX2{Z нLعx 4콜B4SJ_Dd-/p),fqS:_=#<8l"%L{ Ȕȹ3ś" >;!C>9Olpa +:RrW1poбաJg\Dniːy5jm"7z8Ѽ5vlhA!Ru&0~|NZC>GM8`P'L;w +Fg7,v,RT ;XؑfS͖{te2-'F ur w:Ix`QVO^د{ґX{}cs|%=cTw@S{TP KÜ.:W1| Ns`9( +7$vE<3Vw ]qƤ{d(r&UħF5Gg,{]ltf]N=x%B .Xyݯ5IФ:/? eRB/,{s#P=,Sx`oɆ)=[!٨vqu'N)/íjN+X.MYrkx=f]SFR@@akg.9(~SUHhKDâ*akYAî $qNZI%pvB@D+'dII6A@~EF&s|T #a{V`K^Z<0pR.ڗr95WGfG?pQy'ҋΝ|< ZH_.tJOC>|oo??gt}>?~i4/mRDq'hb Z背9YQDI %WG*&)>dYvZ8:_ +;ݧ;EQP}DL/sm׃Ͻ>@1,תݵJ[O\lm"`bPW]]T@U1+1gVSR@bqCklD-JlNj;P +EJc\+J*x +Ðc$y +Ll.@vޱV x 1V >@HĴ'y',LGS1S0zŷC+@q7v.:ńexqZ{h˔uH \N|Ʒӊ/hx`_j-*%+̜4' 5Wiuv}l /jc4|=nCo_q2OzL{dƑU=<4SwJA_ev|I /A_Je}Nz*,VȯsW]ꅔӃAc v$i2DY> TBJ'9ðOӈ4 כ(_ĨN9 (gc)'UqFqÍʴ 8O)Ҳ{(ՃW;*Ȏ~5_}L[! kU! ?8QLRo=#{}WbWČFլy .wˈybɣsg%x}v= Q aJ> H[ =*54\( +RDr~=դʆ}\^_,( +5[ې-EԘ^Y&@dQl=U䉰:4wLjpn6ø|=7Oo ?xoo?ϿW_ߝ m%_ÿi\rӯ~??OϏ~??7?˟??_?i endstream endobj 6 0 obj [5 0 R] endobj 20 0 obj <> endobj xref 0 21 0000000000 65535 f +0000000016 00000 n +0000000144 00000 n +0000025786 00000 n +0000000000 00000 f +0000043971 00000 n +0000108138 00000 n +0000025837 00000 n +0000026168 00000 n +0000044270 00000 n +0000044157 00000 n +0000042969 00000 n +0000043410 00000 n +0000043458 00000 n +0000044041 00000 n +0000044072 00000 n +0000044343 00000 n +0000044517 00000 n +0000045802 00000 n +0000055602 00000 n +0000108161 00000 n +trailer <<789BB656F89545E690763E9D89E26D02>]>> startxref 108359 %%EOF \ No newline at end of file diff --git a/docs/_site/artwork/draco3d-vert.svg b/docs/_site/artwork/draco3d-vert.svg new file mode 100644 index 0000000..3a443af --- /dev/null +++ b/docs/_site/artwork/draco3d-vert.svg @@ -0,0 +1,374 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/_site/assets/css/pygments/README.md b/docs/_site/assets/css/pygments/README.md new file mode 100644 index 0000000..83c205a --- /dev/null +++ b/docs/_site/assets/css/pygments/README.md @@ -0,0 +1,23 @@ +# jekyll-pygments-themes + +A set of CSS theme files for Pygments (Python-based code highlighting tool) +created from the original built-in Pygments styles, ready for use with Jekyll. + +## Theme Previews and Custom Theme Builder +- + +## Using Themes Without Jekyll +If you want to use the themes with something other than Jekyll, you may need to +remove or change the CSS style prefix of `.highlight`. + +## Links + +- [Jekyll](http://jekyllrb.com/) ([direct link to code highlighting documentation](http://jekyllrb.com/docs/templates/#code-snippet-highlighting)) +- [Pygments](http://pygments.org) + +## Hacking + +If you want to hack on the site, check out the [gh-pages](https://github.com/jwarby/jekyll-pygments-themes/tree/gh-pages) branch. + +## Acknowledgements +Forked from [richleland/pygments-css](https://github.com/richleland/pygments-css). diff --git a/docs/_site/assets/css/pygments/UNLICENSE.txt b/docs/_site/assets/css/pygments/UNLICENSE.txt new file mode 100644 index 0000000..cf1ab25 --- /dev/null +++ b/docs/_site/assets/css/pygments/UNLICENSE.txt @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/docs/_site/assets/css/pygments/autumn.css b/docs/_site/assets/css/pygments/autumn.css new file mode 100644 index 0000000..a5f3d4c --- /dev/null +++ b/docs/_site/assets/css/pygments/autumn.css @@ -0,0 +1,58 @@ +.highlight .hll { background-color: #ffffcc } +.highlight .c { color: #aaaaaa; font-style: italic } /* Comment */ +.highlight .err { color: #F00000; background-color: #F0A0A0 } /* Error */ +.highlight .k { color: #0000aa } /* Keyword */ +.highlight .cm { color: #aaaaaa; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #4c8317 } /* Comment.Preproc */ +.highlight .c1 { color: #aaaaaa; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #0000aa; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #aa0000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #aa0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00aa00 } /* Generic.Inserted */ +.highlight .go { color: #888888 } /* Generic.Output */ +.highlight .gp { color: #555555 } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #aa0000 } /* Generic.Traceback */ +.highlight .kc { color: #0000aa } /* Keyword.Constant */ +.highlight .kd { color: #0000aa } /* Keyword.Declaration */ +.highlight .kn { color: #0000aa } /* Keyword.Namespace */ +.highlight .kp { color: #0000aa } /* Keyword.Pseudo */ +.highlight .kr { color: #0000aa } /* Keyword.Reserved */ +.highlight .kt { color: #00aaaa } /* Keyword.Type */ +.highlight .m { color: #009999 } /* Literal.Number */ +.highlight .s { color: #aa5500 } /* Literal.String */ +.highlight .na { color: #1e90ff } /* Name.Attribute */ +.highlight .nb { color: #00aaaa } /* Name.Builtin */ +.highlight .nc { color: #00aa00; text-decoration: underline } /* Name.Class */ +.highlight .no { color: #aa0000 } /* Name.Constant */ +.highlight .nd { color: #888888 } /* Name.Decorator */ +.highlight .ni { color: #800000; font-weight: bold } /* Name.Entity */ +.highlight .nf { color: #00aa00 } /* Name.Function */ +.highlight .nn { color: #00aaaa; text-decoration: underline } /* Name.Namespace */ +.highlight .nt { color: #1e90ff; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #aa0000 } /* Name.Variable */ +.highlight .ow { color: #0000aa } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #009999 } /* Literal.Number.Float */ +.highlight .mh { color: #009999 } /* Literal.Number.Hex */ +.highlight .mi { color: #009999 } /* Literal.Number.Integer */ +.highlight .mo { color: #009999 } /* Literal.Number.Oct */ +.highlight .sb { color: #aa5500 } /* Literal.String.Backtick */ +.highlight .sc { color: #aa5500 } /* Literal.String.Char */ +.highlight .sd { color: #aa5500 } /* Literal.String.Doc */ +.highlight .s2 { color: #aa5500 } /* Literal.String.Double */ +.highlight .se { color: #aa5500 } /* Literal.String.Escape */ +.highlight .sh { color: #aa5500 } /* Literal.String.Heredoc */ +.highlight .si { color: #aa5500 } /* Literal.String.Interpol */ +.highlight .sx { color: #aa5500 } /* Literal.String.Other */ +.highlight .sr { color: #009999 } /* Literal.String.Regex */ +.highlight .s1 { color: #aa5500 } /* Literal.String.Single */ +.highlight .ss { color: #0000aa } /* Literal.String.Symbol */ +.highlight .bp { color: #00aaaa } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #aa0000 } /* Name.Variable.Class */ +.highlight .vg { color: #aa0000 } /* Name.Variable.Global */ +.highlight .vi { color: #aa0000 } /* Name.Variable.Instance */ +.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */ diff --git a/docs/_site/assets/css/pygments/borland.css b/docs/_site/assets/css/pygments/borland.css new file mode 100644 index 0000000..2e98c79 --- /dev/null +++ b/docs/_site/assets/css/pygments/borland.css @@ -0,0 +1,46 @@ +.highlight .hll { background-color: #ffffcc } +.highlight .c { color: #008800; font-style: italic } /* Comment */ +.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ +.highlight .k { color: #000080; font-weight: bold } /* Keyword */ +.highlight .cm { color: #008800; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #008080 } /* Comment.Preproc */ +.highlight .c1 { color: #008800; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #008800; font-weight: bold } /* Comment.Special */ +.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #aa0000 } /* Generic.Error */ +.highlight .gh { color: #999999 } /* Generic.Heading */ +.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ +.highlight .go { color: #888888 } /* Generic.Output */ +.highlight .gp { color: #555555 } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #aaaaaa } /* Generic.Subheading */ +.highlight .gt { color: #aa0000 } /* Generic.Traceback */ +.highlight .kc { color: #000080; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #000080; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #000080; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #000080; font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { color: #000080; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #000080; font-weight: bold } /* Keyword.Type */ +.highlight .m { color: #0000FF } /* Literal.Number */ +.highlight .s { color: #0000FF } /* Literal.String */ +.highlight .na { color: #FF0000 } /* Name.Attribute */ +.highlight .nt { color: #000080; font-weight: bold } /* Name.Tag */ +.highlight .ow { font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #0000FF } /* Literal.Number.Float */ +.highlight .mh { color: #0000FF } /* Literal.Number.Hex */ +.highlight .mi { color: #0000FF } /* Literal.Number.Integer */ +.highlight .mo { color: #0000FF } /* Literal.Number.Oct */ +.highlight .sb { color: #0000FF } /* Literal.String.Backtick */ +.highlight .sc { color: #800080 } /* Literal.String.Char */ +.highlight .sd { color: #0000FF } /* Literal.String.Doc */ +.highlight .s2 { color: #0000FF } /* Literal.String.Double */ +.highlight .se { color: #0000FF } /* Literal.String.Escape */ +.highlight .sh { color: #0000FF } /* Literal.String.Heredoc */ +.highlight .si { color: #0000FF } /* Literal.String.Interpol */ +.highlight .sx { color: #0000FF } /* Literal.String.Other */ +.highlight .sr { color: #0000FF } /* Literal.String.Regex */ +.highlight .s1 { color: #0000FF } /* Literal.String.Single */ +.highlight .ss { color: #0000FF } /* Literal.String.Symbol */ +.highlight .il { color: #0000FF } /* Literal.Number.Integer.Long */ diff --git a/docs/_site/assets/css/pygments/bw.css b/docs/_site/assets/css/pygments/bw.css new file mode 100644 index 0000000..632756b --- /dev/null +++ b/docs/_site/assets/css/pygments/bw.css @@ -0,0 +1,34 @@ +.highlight .hll { background-color: #ffffcc } +.highlight .c { font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { font-weight: bold } /* Keyword */ +.highlight .cm { font-style: italic } /* Comment.Multiline */ +.highlight .c1 { font-style: italic } /* Comment.Single */ +.highlight .cs { font-style: italic } /* Comment.Special */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gh { font-weight: bold } /* Generic.Heading */ +.highlight .gp { font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { font-weight: bold } /* Generic.Subheading */ +.highlight .kc { font-weight: bold } /* Keyword.Constant */ +.highlight .kd { font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { font-weight: bold } /* Keyword.Namespace */ +.highlight .kr { font-weight: bold } /* Keyword.Reserved */ +.highlight .s { font-style: italic } /* Literal.String */ +.highlight .nc { font-weight: bold } /* Name.Class */ +.highlight .ni { font-weight: bold } /* Name.Entity */ +.highlight .ne { font-weight: bold } /* Name.Exception */ +.highlight .nn { font-weight: bold } /* Name.Namespace */ +.highlight .nt { font-weight: bold } /* Name.Tag */ +.highlight .ow { font-weight: bold } /* Operator.Word */ +.highlight .sb { font-style: italic } /* Literal.String.Backtick */ +.highlight .sc { font-style: italic } /* Literal.String.Char */ +.highlight .sd { font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { font-style: italic } /* Literal.String.Double */ +.highlight .se { font-weight: bold; font-style: italic } /* Literal.String.Escape */ +.highlight .sh { font-style: italic } /* Literal.String.Heredoc */ +.highlight .si { font-weight: bold; font-style: italic } /* Literal.String.Interpol */ +.highlight .sx { font-style: italic } /* Literal.String.Other */ +.highlight .sr { font-style: italic } /* Literal.String.Regex */ +.highlight .s1 { font-style: italic } /* Literal.String.Single */ +.highlight .ss { font-style: italic } /* Literal.String.Symbol */ diff --git a/docs/_site/assets/css/pygments/colorful.css b/docs/_site/assets/css/pygments/colorful.css new file mode 100644 index 0000000..e5abd69 --- /dev/null +++ b/docs/_site/assets/css/pygments/colorful.css @@ -0,0 +1,61 @@ +.highlight .hll { background-color: #ffffcc } +.highlight .c { color: #808080 } /* Comment */ +.highlight .err { color: #F00000; background-color: #F0A0A0 } /* Error */ +.highlight .k { color: #008000; font-weight: bold } /* Keyword */ +.highlight .o { color: #303030 } /* Operator */ +.highlight .cm { color: #808080 } /* Comment.Multiline */ +.highlight .cp { color: #507090 } /* Comment.Preproc */ +.highlight .c1 { color: #808080 } /* Comment.Single */ +.highlight .cs { color: #cc0000; font-weight: bold } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #808080 } /* Generic.Output */ +.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0040D0 } /* Generic.Traceback */ +.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #003080; font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #303090; font-weight: bold } /* Keyword.Type */ +.highlight .m { color: #6000E0; font-weight: bold } /* Literal.Number */ +.highlight .s { background-color: #fff0f0 } /* Literal.String */ +.highlight .na { color: #0000C0 } /* Name.Attribute */ +.highlight .nb { color: #007020 } /* Name.Builtin */ +.highlight .nc { color: #B00060; font-weight: bold } /* Name.Class */ +.highlight .no { color: #003060; font-weight: bold } /* Name.Constant */ +.highlight .nd { color: #505050; font-weight: bold } /* Name.Decorator */ +.highlight .ni { color: #800000; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #F00000; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #0060B0; font-weight: bold } /* Name.Function */ +.highlight .nl { color: #907000; font-weight: bold } /* Name.Label */ +.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #007000 } /* Name.Tag */ +.highlight .nv { color: #906030 } /* Name.Variable */ +.highlight .ow { color: #000000; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #6000E0; font-weight: bold } /* Literal.Number.Float */ +.highlight .mh { color: #005080; font-weight: bold } /* Literal.Number.Hex */ +.highlight .mi { color: #0000D0; font-weight: bold } /* Literal.Number.Integer */ +.highlight .mo { color: #4000E0; font-weight: bold } /* Literal.Number.Oct */ +.highlight .sb { background-color: #fff0f0 } /* Literal.String.Backtick */ +.highlight .sc { color: #0040D0 } /* Literal.String.Char */ +.highlight .sd { color: #D04020 } /* Literal.String.Doc */ +.highlight .s2 { background-color: #fff0f0 } /* Literal.String.Double */ +.highlight .se { color: #606060; font-weight: bold; background-color: #fff0f0 } /* Literal.String.Escape */ +.highlight .sh { background-color: #fff0f0 } /* Literal.String.Heredoc */ +.highlight .si { background-color: #e0e0e0 } /* Literal.String.Interpol */ +.highlight .sx { color: #D02000; background-color: #fff0f0 } /* Literal.String.Other */ +.highlight .sr { color: #000000; background-color: #fff0ff } /* Literal.String.Regex */ +.highlight .s1 { background-color: #fff0f0 } /* Literal.String.Single */ +.highlight .ss { color: #A06000 } /* Literal.String.Symbol */ +.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #306090 } /* Name.Variable.Class */ +.highlight .vg { color: #d07000; font-weight: bold } /* Name.Variable.Global */ +.highlight .vi { color: #3030B0 } /* Name.Variable.Instance */ +.highlight .il { color: #0000D0; font-weight: bold } /* Literal.Number.Integer.Long */ diff --git a/docs/_site/assets/css/pygments/default.css b/docs/_site/assets/css/pygments/default.css new file mode 100644 index 0000000..8070f2f --- /dev/null +++ b/docs/_site/assets/css/pygments/default.css @@ -0,0 +1,61 @@ +.highlight .hll { background-color: #ffffcc } +.highlight .c { color: #408080; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #008000; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #BC7A00 } /* Comment.Preproc */ +.highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #408080; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #808080 } /* Generic.Output */ +.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0040D0 } /* Generic.Traceback */ +.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #008000 } /* Keyword.Pseudo */ +.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #B00040 } /* Keyword.Type */ +.highlight .m { color: #666666 } /* Literal.Number */ +.highlight .s { color: #BA2121 } /* Literal.String */ +.highlight .na { color: #7D9029 } /* Name.Attribute */ +.highlight .nb { color: #008000 } /* Name.Builtin */ +.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.highlight .no { color: #880000 } /* Name.Constant */ +.highlight .nd { color: #AA22FF } /* Name.Decorator */ +.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #0000FF } /* Name.Function */ +.highlight .nl { color: #A0A000 } /* Name.Label */ +.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #19177C } /* Name.Variable */ +.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #666666 } /* Literal.Number.Float */ +.highlight .mh { color: #666666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666666 } /* Literal.Number.Oct */ +.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ +.highlight .sc { color: #BA2121 } /* Literal.String.Char */ +.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #BA2121 } /* Literal.String.Double */ +.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ +.highlight .sx { color: #008000 } /* Literal.String.Other */ +.highlight .sr { color: #BB6688 } /* Literal.String.Regex */ +.highlight .s1 { color: #BA2121 } /* Literal.String.Single */ +.highlight .ss { color: #19177C } /* Literal.String.Symbol */ +.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #19177C } /* Name.Variable.Class */ +.highlight .vg { color: #19177C } /* Name.Variable.Global */ +.highlight .vi { color: #19177C } /* Name.Variable.Instance */ +.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ diff --git a/docs/_site/assets/css/pygments/emacs.css b/docs/_site/assets/css/pygments/emacs.css new file mode 100644 index 0000000..489c0ad --- /dev/null +++ b/docs/_site/assets/css/pygments/emacs.css @@ -0,0 +1,61 @@ +.highlight .hll { background-color: #ffffcc } +.highlight .c { color: #008800; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #AA22FF; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .cm { color: #008800; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #008800 } /* Comment.Preproc */ +.highlight .c1 { color: #008800; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #008800; font-weight: bold } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #808080 } /* Generic.Output */ +.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0040D0 } /* Generic.Traceback */ +.highlight .kc { color: #AA22FF; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #AA22FF; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #AA22FF; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #AA22FF } /* Keyword.Pseudo */ +.highlight .kr { color: #AA22FF; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #00BB00; font-weight: bold } /* Keyword.Type */ +.highlight .m { color: #666666 } /* Literal.Number */ +.highlight .s { color: #BB4444 } /* Literal.String */ +.highlight .na { color: #BB4444 } /* Name.Attribute */ +.highlight .nb { color: #AA22FF } /* Name.Builtin */ +.highlight .nc { color: #0000FF } /* Name.Class */ +.highlight .no { color: #880000 } /* Name.Constant */ +.highlight .nd { color: #AA22FF } /* Name.Decorator */ +.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #00A000 } /* Name.Function */ +.highlight .nl { color: #A0A000 } /* Name.Label */ +.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #B8860B } /* Name.Variable */ +.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #666666 } /* Literal.Number.Float */ +.highlight .mh { color: #666666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666666 } /* Literal.Number.Oct */ +.highlight .sb { color: #BB4444 } /* Literal.String.Backtick */ +.highlight .sc { color: #BB4444 } /* Literal.String.Char */ +.highlight .sd { color: #BB4444; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #BB4444 } /* Literal.String.Double */ +.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #BB4444 } /* Literal.String.Heredoc */ +.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ +.highlight .sx { color: #008000 } /* Literal.String.Other */ +.highlight .sr { color: #BB6688 } /* Literal.String.Regex */ +.highlight .s1 { color: #BB4444 } /* Literal.String.Single */ +.highlight .ss { color: #B8860B } /* Literal.String.Symbol */ +.highlight .bp { color: #AA22FF } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #B8860B } /* Name.Variable.Class */ +.highlight .vg { color: #B8860B } /* Name.Variable.Global */ +.highlight .vi { color: #B8860B } /* Name.Variable.Instance */ +.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ diff --git a/docs/_site/assets/css/pygments/friendly.css b/docs/_site/assets/css/pygments/friendly.css new file mode 100644 index 0000000..846e048 --- /dev/null +++ b/docs/_site/assets/css/pygments/friendly.css @@ -0,0 +1,61 @@ +.highlight .hll { background-color: #ffffcc } +.highlight .c { color: #60a0b0; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #007020; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .cm { color: #60a0b0; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #007020 } /* Comment.Preproc */ +.highlight .c1 { color: #60a0b0; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #60a0b0; background-color: #fff0f0 } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #808080 } /* Generic.Output */ +.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0040D0 } /* Generic.Traceback */ +.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #007020 } /* Keyword.Pseudo */ +.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #902000 } /* Keyword.Type */ +.highlight .m { color: #40a070 } /* Literal.Number */ +.highlight .s { color: #4070a0 } /* Literal.String */ +.highlight .na { color: #4070a0 } /* Name.Attribute */ +.highlight .nb { color: #007020 } /* Name.Builtin */ +.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ +.highlight .no { color: #60add5 } /* Name.Constant */ +.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ +.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #007020 } /* Name.Exception */ +.highlight .nf { color: #06287e } /* Name.Function */ +.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ +.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #bb60d5 } /* Name.Variable */ +.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #40a070 } /* Literal.Number.Float */ +.highlight .mh { color: #40a070 } /* Literal.Number.Hex */ +.highlight .mi { color: #40a070 } /* Literal.Number.Integer */ +.highlight .mo { color: #40a070 } /* Literal.Number.Oct */ +.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ +.highlight .sc { color: #4070a0 } /* Literal.String.Char */ +.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #4070a0 } /* Literal.String.Double */ +.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ +.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ +.highlight .sx { color: #c65d09 } /* Literal.String.Other */ +.highlight .sr { color: #235388 } /* Literal.String.Regex */ +.highlight .s1 { color: #4070a0 } /* Literal.String.Single */ +.highlight .ss { color: #517918 } /* Literal.String.Symbol */ +.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ +.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ +.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ +.highlight .il { color: #40a070 } /* Literal.Number.Integer.Long */ diff --git a/docs/_site/assets/css/pygments/fruity.css b/docs/_site/assets/css/pygments/fruity.css new file mode 100644 index 0000000..9152350 --- /dev/null +++ b/docs/_site/assets/css/pygments/fruity.css @@ -0,0 +1,70 @@ +.highlight pre { background-color: #333; } +.highlight .hll { background-color: #333333 } +.highlight .c { color: #008800; font-style: italic; background-color: #0f140f } /* Comment */ +.highlight .err { color: #ffffff } /* Error */ +.highlight .g { color: #ffffff } /* Generic */ +.highlight .k { color: #fb660a; font-weight: bold } /* Keyword */ +.highlight .l { color: #ffffff } /* Literal */ +.highlight .n { color: #ffffff } /* Name */ +.highlight .o { color: #ffffff } /* Operator */ +.highlight .x { color: #ffffff } /* Other */ +.highlight .p { color: #ffffff } /* Punctuation */ +.highlight .cm { color: #008800; font-style: italic; background-color: #0f140f } /* Comment.Multiline */ +.highlight .cp { color: #ff0007; font-weight: bold; font-style: italic; background-color: #0f140f } /* Comment.Preproc */ +.highlight .c1 { color: #008800; font-style: italic; background-color: #0f140f } /* Comment.Single */ +.highlight .cs { color: #008800; font-style: italic; background-color: #0f140f } /* Comment.Special */ +.highlight .gd { color: #ffffff } /* Generic.Deleted */ +.highlight .ge { color: #ffffff } /* Generic.Emph */ +.highlight .gr { color: #ffffff } /* Generic.Error */ +.highlight .gh { color: #ffffff; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #ffffff } /* Generic.Inserted */ +.highlight .go { color: #444444; background-color: #222222 } /* Generic.Output */ +.highlight .gp { color: #ffffff } /* Generic.Prompt */ +.highlight .gs { color: #ffffff } /* Generic.Strong */ +.highlight .gu { color: #ffffff; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #ffffff } /* Generic.Traceback */ +.highlight .kc { color: #fb660a; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #fb660a; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #fb660a; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #fb660a } /* Keyword.Pseudo */ +.highlight .kr { color: #fb660a; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #cdcaa9; font-weight: bold } /* Keyword.Type */ +.highlight .ld { color: #ffffff } /* Literal.Date */ +.highlight .m { color: #0086f7; font-weight: bold } /* Literal.Number */ +.highlight .s { color: #0086d2 } /* Literal.String */ +.highlight .na { color: #ff0086; font-weight: bold } /* Name.Attribute */ +.highlight .nb { color: #ffffff } /* Name.Builtin */ +.highlight .nc { color: #ffffff } /* Name.Class */ +.highlight .no { color: #0086d2 } /* Name.Constant */ +.highlight .nd { color: #ffffff } /* Name.Decorator */ +.highlight .ni { color: #ffffff } /* Name.Entity */ +.highlight .ne { color: #ffffff } /* Name.Exception */ +.highlight .nf { color: #ff0086; font-weight: bold } /* Name.Function */ +.highlight .nl { color: #ffffff } /* Name.Label */ +.highlight .nn { color: #ffffff } /* Name.Namespace */ +.highlight .nx { color: #ffffff } /* Name.Other */ +.highlight .py { color: #ffffff } /* Name.Property */ +.highlight .nt { color: #fb660a; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #fb660a } /* Name.Variable */ +.highlight .ow { color: #ffffff } /* Operator.Word */ +.highlight .w { color: #888888 } /* Text.Whitespace */ +.highlight .mf { color: #0086f7; font-weight: bold } /* Literal.Number.Float */ +.highlight .mh { color: #0086f7; font-weight: bold } /* Literal.Number.Hex */ +.highlight .mi { color: #0086f7; font-weight: bold } /* Literal.Number.Integer */ +.highlight .mo { color: #0086f7; font-weight: bold } /* Literal.Number.Oct */ +.highlight .sb { color: #0086d2 } /* Literal.String.Backtick */ +.highlight .sc { color: #0086d2 } /* Literal.String.Char */ +.highlight .sd { color: #0086d2 } /* Literal.String.Doc */ +.highlight .s2 { color: #0086d2 } /* Literal.String.Double */ +.highlight .se { color: #0086d2 } /* Literal.String.Escape */ +.highlight .sh { color: #0086d2 } /* Literal.String.Heredoc */ +.highlight .si { color: #0086d2 } /* Literal.String.Interpol */ +.highlight .sx { color: #0086d2 } /* Literal.String.Other */ +.highlight .sr { color: #0086d2 } /* Literal.String.Regex */ +.highlight .s1 { color: #0086d2 } /* Literal.String.Single */ +.highlight .ss { color: #0086d2 } /* Literal.String.Symbol */ +.highlight .bp { color: #ffffff } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #fb660a } /* Name.Variable.Class */ +.highlight .vg { color: #fb660a } /* Name.Variable.Global */ +.highlight .vi { color: #fb660a } /* Name.Variable.Instance */ +.highlight .il { color: #0086f7; font-weight: bold } /* Literal.Number.Integer.Long */ diff --git a/docs/_site/assets/css/pygments/github.css b/docs/_site/assets/css/pygments/github.css new file mode 100644 index 0000000..5c45e67 --- /dev/null +++ b/docs/_site/assets/css/pygments/github.css @@ -0,0 +1,61 @@ +.highlight .hll { background-color: #ffffcc } +.highlight .c { color: #999988; font-style: italic } /* Comment */ +.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ +.highlight .k { color: #000000; font-weight: bold } /* Keyword */ +.highlight .o { color: #000000; font-weight: bold } /* Operator */ +.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #999999; font-weight: bold; font-style: italic } /* Comment.Preproc */ +.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ +.highlight .ge { color: #000000; font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #aa0000 } /* Generic.Error */ +.highlight .gh { color: #999999 } /* Generic.Heading */ +.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ +.highlight .go { color: #888888 } /* Generic.Output */ +.highlight .gp { color: #555555 } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #aaaaaa } /* Generic.Subheading */ +.highlight .gt { color: #aa0000 } /* Generic.Traceback */ +.highlight .kc { color: #000000; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #000000; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #000000; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #000000; font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { color: #000000; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */ +.highlight .m { color: #009999 } /* Literal.Number */ +.highlight .s { color: #d01040 } /* Literal.String */ +.highlight .na { color: #008080 } /* Name.Attribute */ +.highlight .nb { color: #0086B3 } /* Name.Builtin */ +.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */ +.highlight .no { color: #008080 } /* Name.Constant */ +.highlight .nd { color: #3c5d5d; font-weight: bold } /* Name.Decorator */ +.highlight .ni { color: #800080 } /* Name.Entity */ +.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */ +.highlight .nl { color: #990000; font-weight: bold } /* Name.Label */ +.highlight .nn { color: #555555 } /* Name.Namespace */ +.highlight .nt { color: #000080 } /* Name.Tag */ +.highlight .nv { color: #008080 } /* Name.Variable */ +.highlight .ow { color: #000000; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #009999 } /* Literal.Number.Float */ +.highlight .mh { color: #009999 } /* Literal.Number.Hex */ +.highlight .mi { color: #009999 } /* Literal.Number.Integer */ +.highlight .mo { color: #009999 } /* Literal.Number.Oct */ +.highlight .sb { color: #d01040 } /* Literal.String.Backtick */ +.highlight .sc { color: #d01040 } /* Literal.String.Char */ +.highlight .sd { color: #d01040 } /* Literal.String.Doc */ +.highlight .s2 { color: #d01040 } /* Literal.String.Double */ +.highlight .se { color: #d01040 } /* Literal.String.Escape */ +.highlight .sh { color: #d01040 } /* Literal.String.Heredoc */ +.highlight .si { color: #d01040 } /* Literal.String.Interpol */ +.highlight .sx { color: #d01040 } /* Literal.String.Other */ +.highlight .sr { color: #009926 } /* Literal.String.Regex */ +.highlight .s1 { color: #d01040 } /* Literal.String.Single */ +.highlight .ss { color: #990073 } /* Literal.String.Symbol */ +.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #008080 } /* Name.Variable.Class */ +.highlight .vg { color: #008080 } /* Name.Variable.Global */ +.highlight .vi { color: #008080 } /* Name.Variable.Instance */ +.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */ diff --git a/docs/_site/assets/css/pygments/index.html b/docs/_site/assets/css/pygments/index.html new file mode 100644 index 0000000..4d692ed --- /dev/null +++ b/docs/_site/assets/css/pygments/index.html @@ -0,0 +1,27 @@ +

jekyll-pygments-themes

+ +

A set of CSS theme files for Pygments (Python-based code highlighting tool) +created from the original built-in Pygments styles, ready for use with Jekyll.

+ +

Theme Previews and Custom Theme Builder

+ + +

Using Themes Without Jekyll

+

If you want to use the themes with something other than Jekyll, you may need to +remove or change the CSS style prefix of .highlight.

+ + + + + +

Hacking

+ +

If you want to hack on the site, check out the gh-pages branch.

+ +

Acknowledgements

+

Forked from richleland/pygments-css.

diff --git a/docs/_site/assets/css/pygments/manni.css b/docs/_site/assets/css/pygments/manni.css new file mode 100644 index 0000000..d5bc47e --- /dev/null +++ b/docs/_site/assets/css/pygments/manni.css @@ -0,0 +1,61 @@ +.highlight .hll { background-color: #ffffcc } +.highlight .c { color: #0099FF; font-style: italic } /* Comment */ +.highlight .err { color: #AA0000; background-color: #FFAAAA } /* Error */ +.highlight .k { color: #006699; font-weight: bold } /* Keyword */ +.highlight .o { color: #555555 } /* Operator */ +.highlight .cm { color: #0099FF; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #009999 } /* Comment.Preproc */ +.highlight .c1 { color: #0099FF; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #0099FF; font-weight: bold; font-style: italic } /* Comment.Special */ +.highlight .gd { background-color: #FFCCCC; border: 1px solid #CC0000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #003300; font-weight: bold } /* Generic.Heading */ +.highlight .gi { background-color: #CCFFCC; border: 1px solid #00CC00 } /* Generic.Inserted */ +.highlight .go { color: #AAAAAA } /* Generic.Output */ +.highlight .gp { color: #000099; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #003300; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #99CC66 } /* Generic.Traceback */ +.highlight .kc { color: #006699; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #006699; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #006699; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #006699 } /* Keyword.Pseudo */ +.highlight .kr { color: #006699; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #007788; font-weight: bold } /* Keyword.Type */ +.highlight .m { color: #FF6600 } /* Literal.Number */ +.highlight .s { color: #CC3300 } /* Literal.String */ +.highlight .na { color: #330099 } /* Name.Attribute */ +.highlight .nb { color: #336666 } /* Name.Builtin */ +.highlight .nc { color: #00AA88; font-weight: bold } /* Name.Class */ +.highlight .no { color: #336600 } /* Name.Constant */ +.highlight .nd { color: #9999FF } /* Name.Decorator */ +.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #CC0000; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #CC00FF } /* Name.Function */ +.highlight .nl { color: #9999FF } /* Name.Label */ +.highlight .nn { color: #00CCFF; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #330099; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #003333 } /* Name.Variable */ +.highlight .ow { color: #000000; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #FF6600 } /* Literal.Number.Float */ +.highlight .mh { color: #FF6600 } /* Literal.Number.Hex */ +.highlight .mi { color: #FF6600 } /* Literal.Number.Integer */ +.highlight .mo { color: #FF6600 } /* Literal.Number.Oct */ +.highlight .sb { color: #CC3300 } /* Literal.String.Backtick */ +.highlight .sc { color: #CC3300 } /* Literal.String.Char */ +.highlight .sd { color: #CC3300; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #CC3300 } /* Literal.String.Double */ +.highlight .se { color: #CC3300; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #CC3300 } /* Literal.String.Heredoc */ +.highlight .si { color: #AA0000 } /* Literal.String.Interpol */ +.highlight .sx { color: #CC3300 } /* Literal.String.Other */ +.highlight .sr { color: #33AAAA } /* Literal.String.Regex */ +.highlight .s1 { color: #CC3300 } /* Literal.String.Single */ +.highlight .ss { color: #FFCC33 } /* Literal.String.Symbol */ +.highlight .bp { color: #336666 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #003333 } /* Name.Variable.Class */ +.highlight .vg { color: #003333 } /* Name.Variable.Global */ +.highlight .vi { color: #003333 } /* Name.Variable.Instance */ +.highlight .il { color: #FF6600 } /* Literal.Number.Integer.Long */ diff --git a/docs/_site/assets/css/pygments/monokai.css b/docs/_site/assets/css/pygments/monokai.css new file mode 100644 index 0000000..5ce9493 --- /dev/null +++ b/docs/_site/assets/css/pygments/monokai.css @@ -0,0 +1,66 @@ +.highlight pre, pre.highlight { background-color: #272822; } +.highlight code { color: #fff; } +.highlight .hll { background-color: #272822; } +.highlight .c { color: #75715e } /* Comment */ +.highlight .err { color: #960050; background-color: #1e0010 } /* Error */ +.highlight .k { color: #66d9ef } /* Keyword */ +.highlight .l { color: #ae81ff } /* Literal */ +.highlight .n { color: #f8f8f2 } /* Name */ +.highlight .o { color: #f92672 } /* Operator */ +.highlight .p { color: #f8f8f2 } /* Punctuation */ +.highlight .cm { color: #75715e } /* Comment.Multiline */ +.highlight .cp { color: #75715e } /* Comment.Preproc */ +.highlight .c1 { color: #75715e } /* Comment.Single */ +.highlight .cs { color: #75715e } /* Comment.Special */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .kc { color: #66d9ef } /* Keyword.Constant */ +.highlight .kd { color: #66d9ef } /* Keyword.Declaration */ +.highlight .kn { color: #f92672 } /* Keyword.Namespace */ +.highlight .kp { color: #66d9ef } /* Keyword.Pseudo */ +.highlight .kr { color: #66d9ef } /* Keyword.Reserved */ +.highlight .kt { color: #66d9ef } /* Keyword.Type */ +.highlight .ld { color: #e6db74 } /* Literal.Date */ +.highlight .m { color: #ae81ff } /* Literal.Number */ +.highlight .s { color: #e6db74 } /* Literal.String */ +.highlight .na { color: #a6e22e } /* Name.Attribute */ +.highlight .nb { color: #f8f8f2 } /* Name.Builtin */ +.highlight .nc { color: #a6e22e } /* Name.Class */ +.highlight .no { color: #66d9ef } /* Name.Constant */ +.highlight .nd { color: #a6e22e } /* Name.Decorator */ +.highlight .ni { color: #f8f8f2 } /* Name.Entity */ +.highlight .ne { color: #a6e22e } /* Name.Exception */ +.highlight .nf { color: #a6e22e } /* Name.Function */ +.highlight .nl { color: #f8f8f2 } /* Name.Label */ +.highlight .nn { color: #f8f8f2 } /* Name.Namespace */ +.highlight .nx { color: #a6e22e } /* Name.Other */ +.highlight .py { color: #f8f8f2 } /* Name.Property */ +.highlight .nt { color: #f92672 } /* Name.Tag */ +.highlight .nv { color: #f8f8f2 } /* Name.Variable */ +.highlight .ow { color: #f92672 } /* Operator.Word */ +.highlight .w { color: #f8f8f2 } /* Text.Whitespace */ +.highlight .mf { color: #ae81ff } /* Literal.Number.Float */ +.highlight .mh { color: #ae81ff } /* Literal.Number.Hex */ +.highlight .mi { color: #ae81ff } /* Literal.Number.Integer */ +.highlight .mo { color: #ae81ff } /* Literal.Number.Oct */ +.highlight .sb { color: #e6db74 } /* Literal.String.Backtick */ +.highlight .sc { color: #e6db74 } /* Literal.String.Char */ +.highlight .sd { color: #e6db74 } /* Literal.String.Doc */ +.highlight .s2 { color: #e6db74 } /* Literal.String.Double */ +.highlight .se { color: #ae81ff } /* Literal.String.Escape */ +.highlight .sh { color: #e6db74 } /* Literal.String.Heredoc */ +.highlight .si { color: #e6db74 } /* Literal.String.Interpol */ +.highlight .sx { color: #e6db74 } /* Literal.String.Other */ +.highlight .sr { color: #e6db74 } /* Literal.String.Regex */ +.highlight .s1 { color: #e6db74 } /* Literal.String.Single */ +.highlight .ss { color: #e6db74 } /* Literal.String.Symbol */ +.highlight .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #f8f8f2 } /* Name.Variable.Class */ +.highlight .vg { color: #f8f8f2 } /* Name.Variable.Global */ +.highlight .vi { color: #f8f8f2 } /* Name.Variable.Instance */ +.highlight .il { color: #ae81ff } /* Literal.Number.Integer.Long */ + +.highlight .gh { } /* Generic Heading & Diff Header */ +.highlight .gu { color: #75715e; } /* Generic.Subheading & Diff Unified/Comment? */ +.highlight .gd { color: #f92672; } /* Generic.Deleted & Diff Deleted */ +.highlight .gi { color: #a6e22e; } /* Generic.Inserted & Diff Inserted */ diff --git a/docs/_site/assets/css/pygments/murphy.css b/docs/_site/assets/css/pygments/murphy.css new file mode 100644 index 0000000..482d46b --- /dev/null +++ b/docs/_site/assets/css/pygments/murphy.css @@ -0,0 +1,61 @@ +.highlight .hll { background-color: #ffffcc } +.highlight .c { color: #606060; font-style: italic } /* Comment */ +.highlight .err { color: #F00000; background-color: #F0A0A0 } /* Error */ +.highlight .k { color: #208090; font-weight: bold } /* Keyword */ +.highlight .o { color: #303030 } /* Operator */ +.highlight .cm { color: #606060; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #507090 } /* Comment.Preproc */ +.highlight .c1 { color: #606060; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #c00000; font-weight: bold; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #808080 } /* Generic.Output */ +.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0040D0 } /* Generic.Traceback */ +.highlight .kc { color: #208090; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #208090; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #208090; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #0080f0; font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { color: #208090; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #6060f0; font-weight: bold } /* Keyword.Type */ +.highlight .m { color: #6000E0; font-weight: bold } /* Literal.Number */ +.highlight .s { background-color: #e0e0ff } /* Literal.String */ +.highlight .na { color: #000070 } /* Name.Attribute */ +.highlight .nb { color: #007020 } /* Name.Builtin */ +.highlight .nc { color: #e090e0; font-weight: bold } /* Name.Class */ +.highlight .no { color: #50e0d0; font-weight: bold } /* Name.Constant */ +.highlight .nd { color: #505050; font-weight: bold } /* Name.Decorator */ +.highlight .ni { color: #800000 } /* Name.Entity */ +.highlight .ne { color: #F00000; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #50e0d0; font-weight: bold } /* Name.Function */ +.highlight .nl { color: #907000; font-weight: bold } /* Name.Label */ +.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #007000 } /* Name.Tag */ +.highlight .nv { color: #003060 } /* Name.Variable */ +.highlight .ow { color: #000000; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #6000E0; font-weight: bold } /* Literal.Number.Float */ +.highlight .mh { color: #005080; font-weight: bold } /* Literal.Number.Hex */ +.highlight .mi { color: #6060f0; font-weight: bold } /* Literal.Number.Integer */ +.highlight .mo { color: #4000E0; font-weight: bold } /* Literal.Number.Oct */ +.highlight .sb { background-color: #e0e0ff } /* Literal.String.Backtick */ +.highlight .sc { color: #8080F0 } /* Literal.String.Char */ +.highlight .sd { color: #D04020 } /* Literal.String.Doc */ +.highlight .s2 { background-color: #e0e0ff } /* Literal.String.Double */ +.highlight .se { color: #606060; font-weight: bold; background-color: #e0e0ff } /* Literal.String.Escape */ +.highlight .sh { background-color: #e0e0ff } /* Literal.String.Heredoc */ +.highlight .si { background-color: #e0e0e0 } /* Literal.String.Interpol */ +.highlight .sx { color: #f08080; background-color: #e0e0ff } /* Literal.String.Other */ +.highlight .sr { color: #000000; background-color: #e0e0ff } /* Literal.String.Regex */ +.highlight .s1 { background-color: #e0e0ff } /* Literal.String.Single */ +.highlight .ss { color: #f0c080 } /* Literal.String.Symbol */ +.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #c0c0f0 } /* Name.Variable.Class */ +.highlight .vg { color: #f08040 } /* Name.Variable.Global */ +.highlight .vi { color: #a0a0f0 } /* Name.Variable.Instance */ +.highlight .il { color: #6060f0; font-weight: bold } /* Literal.Number.Integer.Long */ diff --git a/docs/_site/assets/css/pygments/native.css b/docs/_site/assets/css/pygments/native.css new file mode 100644 index 0000000..eac4a78 --- /dev/null +++ b/docs/_site/assets/css/pygments/native.css @@ -0,0 +1,70 @@ +.highlight pre { background-color: #404040 } +.highlight .hll { background-color: #404040 } +.highlight .c { color: #999999; font-style: italic } /* Comment */ +.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ +.highlight .g { color: #d0d0d0 } /* Generic */ +.highlight .k { color: #6ab825; font-weight: bold } /* Keyword */ +.highlight .l { color: #d0d0d0 } /* Literal */ +.highlight .n { color: #d0d0d0 } /* Name */ +.highlight .o { color: #d0d0d0 } /* Operator */ +.highlight .x { color: #d0d0d0 } /* Other */ +.highlight .p { color: #d0d0d0 } /* Punctuation */ +.highlight .cm { color: #999999; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #cd2828; font-weight: bold } /* Comment.Preproc */ +.highlight .c1 { color: #999999; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #e50808; font-weight: bold; background-color: #520000 } /* Comment.Special */ +.highlight .gd { color: #d22323 } /* Generic.Deleted */ +.highlight .ge { color: #d0d0d0; font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #d22323 } /* Generic.Error */ +.highlight .gh { color: #ffffff; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #589819 } /* Generic.Inserted */ +.highlight .go { color: #cccccc } /* Generic.Output */ +.highlight .gp { color: #aaaaaa } /* Generic.Prompt */ +.highlight .gs { color: #d0d0d0; font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #ffffff; text-decoration: underline } /* Generic.Subheading */ +.highlight .gt { color: #d22323 } /* Generic.Traceback */ +.highlight .kc { color: #6ab825; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #6ab825; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #6ab825; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #6ab825 } /* Keyword.Pseudo */ +.highlight .kr { color: #6ab825; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #6ab825; font-weight: bold } /* Keyword.Type */ +.highlight .ld { color: #d0d0d0 } /* Literal.Date */ +.highlight .m { color: #3677a9 } /* Literal.Number */ +.highlight .s { color: #ed9d13 } /* Literal.String */ +.highlight .na { color: #bbbbbb } /* Name.Attribute */ +.highlight .nb { color: #24909d } /* Name.Builtin */ +.highlight .nc { color: #447fcf; text-decoration: underline } /* Name.Class */ +.highlight .no { color: #40ffff } /* Name.Constant */ +.highlight .nd { color: #ffa500 } /* Name.Decorator */ +.highlight .ni { color: #d0d0d0 } /* Name.Entity */ +.highlight .ne { color: #bbbbbb } /* Name.Exception */ +.highlight .nf { color: #447fcf } /* Name.Function */ +.highlight .nl { color: #d0d0d0 } /* Name.Label */ +.highlight .nn { color: #447fcf; text-decoration: underline } /* Name.Namespace */ +.highlight .nx { color: #d0d0d0 } /* Name.Other */ +.highlight .py { color: #d0d0d0 } /* Name.Property */ +.highlight .nt { color: #6ab825; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #40ffff } /* Name.Variable */ +.highlight .ow { color: #6ab825; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #666666 } /* Text.Whitespace */ +.highlight .mf { color: #3677a9 } /* Literal.Number.Float */ +.highlight .mh { color: #3677a9 } /* Literal.Number.Hex */ +.highlight .mi { color: #3677a9 } /* Literal.Number.Integer */ +.highlight .mo { color: #3677a9 } /* Literal.Number.Oct */ +.highlight .sb { color: #ed9d13 } /* Literal.String.Backtick */ +.highlight .sc { color: #ed9d13 } /* Literal.String.Char */ +.highlight .sd { color: #ed9d13 } /* Literal.String.Doc */ +.highlight .s2 { color: #ed9d13 } /* Literal.String.Double */ +.highlight .se { color: #ed9d13 } /* Literal.String.Escape */ +.highlight .sh { color: #ed9d13 } /* Literal.String.Heredoc */ +.highlight .si { color: #ed9d13 } /* Literal.String.Interpol */ +.highlight .sx { color: #ffa500 } /* Literal.String.Other */ +.highlight .sr { color: #ed9d13 } /* Literal.String.Regex */ +.highlight .s1 { color: #ed9d13 } /* Literal.String.Single */ +.highlight .ss { color: #ed9d13 } /* Literal.String.Symbol */ +.highlight .bp { color: #24909d } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #40ffff } /* Name.Variable.Class */ +.highlight .vg { color: #40ffff } /* Name.Variable.Global */ +.highlight .vi { color: #40ffff } /* Name.Variable.Instance */ +.highlight .il { color: #3677a9 } /* Literal.Number.Integer.Long */ diff --git a/docs/_site/assets/css/pygments/pastie.css b/docs/_site/assets/css/pygments/pastie.css new file mode 100644 index 0000000..538bdc6 --- /dev/null +++ b/docs/_site/assets/css/pygments/pastie.css @@ -0,0 +1,60 @@ +.highlight .hll { background-color: #ffffcc } +.highlight .c { color: #888888 } /* Comment */ +.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ +.highlight .k { color: #008800; font-weight: bold } /* Keyword */ +.highlight .cm { color: #888888 } /* Comment.Multiline */ +.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ +.highlight .c1 { color: #888888 } /* Comment.Single */ +.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ +.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #aa0000 } /* Generic.Error */ +.highlight .gh { color: #303030 } /* Generic.Heading */ +.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ +.highlight .go { color: #888888 } /* Generic.Output */ +.highlight .gp { color: #555555 } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #606060 } /* Generic.Subheading */ +.highlight .gt { color: #aa0000 } /* Generic.Traceback */ +.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #008800 } /* Keyword.Pseudo */ +.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ +.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ +.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ +.highlight .na { color: #336699 } /* Name.Attribute */ +.highlight .nb { color: #003388 } /* Name.Builtin */ +.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ +.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ +.highlight .nd { color: #555555 } /* Name.Decorator */ +.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ +.highlight .nl { color: #336699; font-style: italic } /* Name.Label */ +.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ +.highlight .py { color: #336699; font-weight: bold } /* Name.Property */ +.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #336699 } /* Name.Variable */ +.highlight .ow { color: #008800 } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ +.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ +.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ +.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ +.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ +.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ +.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ +.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ +.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ +.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ +.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ +.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ +.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ +.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ +.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ +.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #336699 } /* Name.Variable.Class */ +.highlight .vg { color: #dd7700 } /* Name.Variable.Global */ +.highlight .vi { color: #3333bb } /* Name.Variable.Instance */ +.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */ diff --git a/docs/_site/assets/css/pygments/perldoc.css b/docs/_site/assets/css/pygments/perldoc.css new file mode 100644 index 0000000..50516f2 --- /dev/null +++ b/docs/_site/assets/css/pygments/perldoc.css @@ -0,0 +1,58 @@ +.highlight .hll { background-color: #ffffcc } +.highlight .c { color: #228B22 } /* Comment */ +.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ +.highlight .k { color: #8B008B; font-weight: bold } /* Keyword */ +.highlight .cm { color: #228B22 } /* Comment.Multiline */ +.highlight .cp { color: #1e889b } /* Comment.Preproc */ +.highlight .c1 { color: #228B22 } /* Comment.Single */ +.highlight .cs { color: #8B008B; font-weight: bold } /* Comment.Special */ +.highlight .gd { color: #aa0000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #aa0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00aa00 } /* Generic.Inserted */ +.highlight .go { color: #888888 } /* Generic.Output */ +.highlight .gp { color: #555555 } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #aa0000 } /* Generic.Traceback */ +.highlight .kc { color: #8B008B; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #8B008B; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #8B008B; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #8B008B; font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { color: #8B008B; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #a7a7a7; font-weight: bold } /* Keyword.Type */ +.highlight .m { color: #B452CD } /* Literal.Number */ +.highlight .s { color: #CD5555 } /* Literal.String */ +.highlight .na { color: #658b00 } /* Name.Attribute */ +.highlight .nb { color: #658b00 } /* Name.Builtin */ +.highlight .nc { color: #008b45; font-weight: bold } /* Name.Class */ +.highlight .no { color: #00688B } /* Name.Constant */ +.highlight .nd { color: #707a7c } /* Name.Decorator */ +.highlight .ne { color: #008b45; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #008b45 } /* Name.Function */ +.highlight .nn { color: #008b45; text-decoration: underline } /* Name.Namespace */ +.highlight .nt { color: #8B008B; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #00688B } /* Name.Variable */ +.highlight .ow { color: #8B008B } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #B452CD } /* Literal.Number.Float */ +.highlight .mh { color: #B452CD } /* Literal.Number.Hex */ +.highlight .mi { color: #B452CD } /* Literal.Number.Integer */ +.highlight .mo { color: #B452CD } /* Literal.Number.Oct */ +.highlight .sb { color: #CD5555 } /* Literal.String.Backtick */ +.highlight .sc { color: #CD5555 } /* Literal.String.Char */ +.highlight .sd { color: #CD5555 } /* Literal.String.Doc */ +.highlight .s2 { color: #CD5555 } /* Literal.String.Double */ +.highlight .se { color: #CD5555 } /* Literal.String.Escape */ +.highlight .sh { color: #1c7e71; font-style: italic } /* Literal.String.Heredoc */ +.highlight .si { color: #CD5555 } /* Literal.String.Interpol */ +.highlight .sx { color: #cb6c20 } /* Literal.String.Other */ +.highlight .sr { color: #1c7e71 } /* Literal.String.Regex */ +.highlight .s1 { color: #CD5555 } /* Literal.String.Single */ +.highlight .ss { color: #CD5555 } /* Literal.String.Symbol */ +.highlight .bp { color: #658b00 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #00688B } /* Name.Variable.Class */ +.highlight .vg { color: #00688B } /* Name.Variable.Global */ +.highlight .vi { color: #00688B } /* Name.Variable.Instance */ +.highlight .il { color: #B452CD } /* Literal.Number.Integer.Long */ diff --git a/docs/_site/assets/css/pygments/tango.css b/docs/_site/assets/css/pygments/tango.css new file mode 100644 index 0000000..bfd3803 --- /dev/null +++ b/docs/_site/assets/css/pygments/tango.css @@ -0,0 +1,69 @@ +.highlight .hll { background-color: #ffffcc } +.highlight .c { color: #8f5902; font-style: italic } /* Comment */ +.highlight .err { color: #a40000; border: 1px solid #ef2929 } /* Error */ +.highlight .g { color: #000000 } /* Generic */ +.highlight .k { color: #204a87; font-weight: bold } /* Keyword */ +.highlight .l { color: #000000 } /* Literal */ +.highlight .n { color: #000000 } /* Name */ +.highlight .o { color: #ce5c00; font-weight: bold } /* Operator */ +.highlight .x { color: #000000 } /* Other */ +.highlight .p { color: #000000; font-weight: bold } /* Punctuation */ +.highlight .cm { color: #8f5902; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #8f5902; font-style: italic } /* Comment.Preproc */ +.highlight .c1 { color: #8f5902; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #8f5902; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #a40000 } /* Generic.Deleted */ +.highlight .ge { color: #000000; font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #ef2929 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #000000; font-style: italic } /* Generic.Output */ +.highlight .gp { color: #8f5902 } /* Generic.Prompt */ +.highlight .gs { color: #000000; font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #a40000; font-weight: bold } /* Generic.Traceback */ +.highlight .kc { color: #204a87; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #204a87; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #204a87; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #204a87; font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { color: #204a87; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #204a87; font-weight: bold } /* Keyword.Type */ +.highlight .ld { color: #000000 } /* Literal.Date */ +.highlight .m { color: #0000cf; font-weight: bold } /* Literal.Number */ +.highlight .s { color: #4e9a06 } /* Literal.String */ +.highlight .na { color: #c4a000 } /* Name.Attribute */ +.highlight .nb { color: #204a87 } /* Name.Builtin */ +.highlight .nc { color: #000000 } /* Name.Class */ +.highlight .no { color: #000000 } /* Name.Constant */ +.highlight .nd { color: #5c35cc; font-weight: bold } /* Name.Decorator */ +.highlight .ni { color: #ce5c00 } /* Name.Entity */ +.highlight .ne { color: #cc0000; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #000000 } /* Name.Function */ +.highlight .nl { color: #f57900 } /* Name.Label */ +.highlight .nn { color: #000000 } /* Name.Namespace */ +.highlight .nx { color: #000000 } /* Name.Other */ +.highlight .py { color: #000000 } /* Name.Property */ +.highlight .nt { color: #204a87; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #000000 } /* Name.Variable */ +.highlight .ow { color: #204a87; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #f8f8f8; text-decoration: underline } /* Text.Whitespace */ +.highlight .mf { color: #0000cf; font-weight: bold } /* Literal.Number.Float */ +.highlight .mh { color: #0000cf; font-weight: bold } /* Literal.Number.Hex */ +.highlight .mi { color: #0000cf; font-weight: bold } /* Literal.Number.Integer */ +.highlight .mo { color: #0000cf; font-weight: bold } /* Literal.Number.Oct */ +.highlight .sb { color: #4e9a06 } /* Literal.String.Backtick */ +.highlight .sc { color: #4e9a06 } /* Literal.String.Char */ +.highlight .sd { color: #8f5902; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #4e9a06 } /* Literal.String.Double */ +.highlight .se { color: #4e9a06 } /* Literal.String.Escape */ +.highlight .sh { color: #4e9a06 } /* Literal.String.Heredoc */ +.highlight .si { color: #4e9a06 } /* Literal.String.Interpol */ +.highlight .sx { color: #4e9a06 } /* Literal.String.Other */ +.highlight .sr { color: #4e9a06 } /* Literal.String.Regex */ +.highlight .s1 { color: #4e9a06 } /* Literal.String.Single */ +.highlight .ss { color: #4e9a06 } /* Literal.String.Symbol */ +.highlight .bp { color: #3465a4 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #000000 } /* Name.Variable.Class */ +.highlight .vg { color: #000000 } /* Name.Variable.Global */ +.highlight .vi { color: #000000 } /* Name.Variable.Instance */ +.highlight .il { color: #0000cf; font-weight: bold } /* Literal.Number.Integer.Long */ diff --git a/docs/_site/assets/css/pygments/trac.css b/docs/_site/assets/css/pygments/trac.css new file mode 100644 index 0000000..851ba3c --- /dev/null +++ b/docs/_site/assets/css/pygments/trac.css @@ -0,0 +1,59 @@ +.highlight .hll { background-color: #ffffcc } +.highlight .c { color: #999988; font-style: italic } /* Comment */ +.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ +.highlight .k { font-weight: bold } /* Keyword */ +.highlight .o { font-weight: bold } /* Operator */ +.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */ +.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #aa0000 } /* Generic.Error */ +.highlight .gh { color: #999999 } /* Generic.Heading */ +.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ +.highlight .go { color: #888888 } /* Generic.Output */ +.highlight .gp { color: #555555 } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #aaaaaa } /* Generic.Subheading */ +.highlight .gt { color: #aa0000 } /* Generic.Traceback */ +.highlight .kc { font-weight: bold } /* Keyword.Constant */ +.highlight .kd { font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */ +.highlight .m { color: #009999 } /* Literal.Number */ +.highlight .s { color: #bb8844 } /* Literal.String */ +.highlight .na { color: #008080 } /* Name.Attribute */ +.highlight .nb { color: #999999 } /* Name.Builtin */ +.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */ +.highlight .no { color: #008080 } /* Name.Constant */ +.highlight .ni { color: #800080 } /* Name.Entity */ +.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */ +.highlight .nn { color: #555555 } /* Name.Namespace */ +.highlight .nt { color: #000080 } /* Name.Tag */ +.highlight .nv { color: #008080 } /* Name.Variable */ +.highlight .ow { font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #009999 } /* Literal.Number.Float */ +.highlight .mh { color: #009999 } /* Literal.Number.Hex */ +.highlight .mi { color: #009999 } /* Literal.Number.Integer */ +.highlight .mo { color: #009999 } /* Literal.Number.Oct */ +.highlight .sb { color: #bb8844 } /* Literal.String.Backtick */ +.highlight .sc { color: #bb8844 } /* Literal.String.Char */ +.highlight .sd { color: #bb8844 } /* Literal.String.Doc */ +.highlight .s2 { color: #bb8844 } /* Literal.String.Double */ +.highlight .se { color: #bb8844 } /* Literal.String.Escape */ +.highlight .sh { color: #bb8844 } /* Literal.String.Heredoc */ +.highlight .si { color: #bb8844 } /* Literal.String.Interpol */ +.highlight .sx { color: #bb8844 } /* Literal.String.Other */ +.highlight .sr { color: #808000 } /* Literal.String.Regex */ +.highlight .s1 { color: #bb8844 } /* Literal.String.Single */ +.highlight .ss { color: #bb8844 } /* Literal.String.Symbol */ +.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #008080 } /* Name.Variable.Class */ +.highlight .vg { color: #008080 } /* Name.Variable.Global */ +.highlight .vi { color: #008080 } /* Name.Variable.Instance */ +.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */ diff --git a/docs/_site/assets/css/pygments/vim.css b/docs/_site/assets/css/pygments/vim.css new file mode 100644 index 0000000..3af4a14 --- /dev/null +++ b/docs/_site/assets/css/pygments/vim.css @@ -0,0 +1,70 @@ +.highlight pre { background-color: #222222 } +.highlight .hll { background-color: #222222 } +.highlight .c { color: #000080 } /* Comment */ +.highlight .err { color: #cccccc; border: 1px solid #FF0000 } /* Error */ +.highlight .g { color: #cccccc } /* Generic */ +.highlight .k { color: #cdcd00 } /* Keyword */ +.highlight .l { color: #cccccc } /* Literal */ +.highlight .n { color: #cccccc } /* Name */ +.highlight .o { color: #3399cc } /* Operator */ +.highlight .x { color: #cccccc } /* Other */ +.highlight .p { color: #cccccc } /* Punctuation */ +.highlight .cm { color: #000080 } /* Comment.Multiline */ +.highlight .cp { color: #000080 } /* Comment.Preproc */ +.highlight .c1 { color: #000080 } /* Comment.Single */ +.highlight .cs { color: #cd0000; font-weight: bold } /* Comment.Special */ +.highlight .gd { color: #cd0000 } /* Generic.Deleted */ +.highlight .ge { color: #cccccc; font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00cd00 } /* Generic.Inserted */ +.highlight .go { color: #808080 } /* Generic.Output */ +.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { color: #cccccc; font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0040D0 } /* Generic.Traceback */ +.highlight .kc { color: #cdcd00 } /* Keyword.Constant */ +.highlight .kd { color: #00cd00 } /* Keyword.Declaration */ +.highlight .kn { color: #cd00cd } /* Keyword.Namespace */ +.highlight .kp { color: #cdcd00 } /* Keyword.Pseudo */ +.highlight .kr { color: #cdcd00 } /* Keyword.Reserved */ +.highlight .kt { color: #00cd00 } /* Keyword.Type */ +.highlight .ld { color: #cccccc } /* Literal.Date */ +.highlight .m { color: #cd00cd } /* Literal.Number */ +.highlight .s { color: #cd0000 } /* Literal.String */ +.highlight .na { color: #cccccc } /* Name.Attribute */ +.highlight .nb { color: #cd00cd } /* Name.Builtin */ +.highlight .nc { color: #00cdcd } /* Name.Class */ +.highlight .no { color: #cccccc } /* Name.Constant */ +.highlight .nd { color: #cccccc } /* Name.Decorator */ +.highlight .ni { color: #cccccc } /* Name.Entity */ +.highlight .ne { color: #666699; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #cccccc } /* Name.Function */ +.highlight .nl { color: #cccccc } /* Name.Label */ +.highlight .nn { color: #cccccc } /* Name.Namespace */ +.highlight .nx { color: #cccccc } /* Name.Other */ +.highlight .py { color: #cccccc } /* Name.Property */ +.highlight .nt { color: #cccccc } /* Name.Tag */ +.highlight .nv { color: #00cdcd } /* Name.Variable */ +.highlight .ow { color: #cdcd00 } /* Operator.Word */ +.highlight .w { color: #cccccc } /* Text.Whitespace */ +.highlight .mf { color: #cd00cd } /* Literal.Number.Float */ +.highlight .mh { color: #cd00cd } /* Literal.Number.Hex */ +.highlight .mi { color: #cd00cd } /* Literal.Number.Integer */ +.highlight .mo { color: #cd00cd } /* Literal.Number.Oct */ +.highlight .sb { color: #cd0000 } /* Literal.String.Backtick */ +.highlight .sc { color: #cd0000 } /* Literal.String.Char */ +.highlight .sd { color: #cd0000 } /* Literal.String.Doc */ +.highlight .s2 { color: #cd0000 } /* Literal.String.Double */ +.highlight .se { color: #cd0000 } /* Literal.String.Escape */ +.highlight .sh { color: #cd0000 } /* Literal.String.Heredoc */ +.highlight .si { color: #cd0000 } /* Literal.String.Interpol */ +.highlight .sx { color: #cd0000 } /* Literal.String.Other */ +.highlight .sr { color: #cd0000 } /* Literal.String.Regex */ +.highlight .s1 { color: #cd0000 } /* Literal.String.Single */ +.highlight .ss { color: #cd0000 } /* Literal.String.Symbol */ +.highlight .bp { color: #cd00cd } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #00cdcd } /* Name.Variable.Class */ +.highlight .vg { color: #00cdcd } /* Name.Variable.Global */ +.highlight .vi { color: #00cdcd } /* Name.Variable.Instance */ +.highlight .il { color: #cd00cd } /* Literal.Number.Integer.Long */ diff --git a/docs/_site/assets/css/pygments/vs.css b/docs/_site/assets/css/pygments/vs.css new file mode 100644 index 0000000..e1e55d8 --- /dev/null +++ b/docs/_site/assets/css/pygments/vs.css @@ -0,0 +1,33 @@ +.highlight .hll { background-color: #ffffcc } +.highlight .c { color: #008000 } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #0000ff } /* Keyword */ +.highlight .cm { color: #008000 } /* Comment.Multiline */ +.highlight .cp { color: #0000ff } /* Comment.Preproc */ +.highlight .c1 { color: #008000 } /* Comment.Single */ +.highlight .cs { color: #008000 } /* Comment.Special */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gh { font-weight: bold } /* Generic.Heading */ +.highlight .gp { font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { font-weight: bold } /* Generic.Subheading */ +.highlight .kc { color: #0000ff } /* Keyword.Constant */ +.highlight .kd { color: #0000ff } /* Keyword.Declaration */ +.highlight .kn { color: #0000ff } /* Keyword.Namespace */ +.highlight .kp { color: #0000ff } /* Keyword.Pseudo */ +.highlight .kr { color: #0000ff } /* Keyword.Reserved */ +.highlight .kt { color: #2b91af } /* Keyword.Type */ +.highlight .s { color: #a31515 } /* Literal.String */ +.highlight .nc { color: #2b91af } /* Name.Class */ +.highlight .ow { color: #0000ff } /* Operator.Word */ +.highlight .sb { color: #a31515 } /* Literal.String.Backtick */ +.highlight .sc { color: #a31515 } /* Literal.String.Char */ +.highlight .sd { color: #a31515 } /* Literal.String.Doc */ +.highlight .s2 { color: #a31515 } /* Literal.String.Double */ +.highlight .se { color: #a31515 } /* Literal.String.Escape */ +.highlight .sh { color: #a31515 } /* Literal.String.Heredoc */ +.highlight .si { color: #a31515 } /* Literal.String.Interpol */ +.highlight .sx { color: #a31515 } /* Literal.String.Other */ +.highlight .sr { color: #a31515 } /* Literal.String.Regex */ +.highlight .s1 { color: #a31515 } /* Literal.String.Single */ +.highlight .ss { color: #a31515 } /* Literal.String.Symbol */ diff --git a/docs/_site/assets/css/pygments/zenburn.css b/docs/_site/assets/css/pygments/zenburn.css new file mode 100644 index 0000000..287591d --- /dev/null +++ b/docs/_site/assets/css/pygments/zenburn.css @@ -0,0 +1,136 @@ +.highlight code, .highlight pre { +color:#fdce93; +background-color:#3f3f3f; +} + +.highlight .hll { +background-color:#222; +} + +.highlight .err { +color:#e37170; +background-color:#3d3535; +} + +.highlight .k { +color:#f0dfaf; +} + +.highlight .p { +color:#41706f; +} + +.highlight .cs { +color:#cd0000; +font-weight:700; +} + +.highlight .gd { +color:#cd0000; +} + +.highlight .ge { +color:#ccc; +font-style:italic; +} + +.highlight .gr { +color:red; +} + +.highlight .go { +color:gray; +} + +.highlight .gs { +color:#ccc; +font-weight:700; +} + +.highlight .gu { +color:purple; +font-weight:700; +} + +.highlight .gt { +color:#0040D0; +} + +.highlight .kc { +color:#dca3a3; +} + +.highlight .kd { +color:#ffff86; +} + +.highlight .kn { +color:#dfaf8f; +font-weight:700; +} + +.highlight .kp { +color:#cdcf99; +} + +.highlight .kr { +color:#cdcd00; +} + +.highlight .ni { +color:#c28182; +} + +.highlight .ne { +color:#c3bf9f; +font-weight:700; +} + +.highlight .nn { +color:#8fbede; +} + +.highlight .vi { +color:#ffffc7; +} + +.highlight .c,.preview-zenburn .highlight .g,.preview-zenburn .highlight .cm,.preview-zenburn .highlight .cp,.preview-zenburn .highlight .c1 { +color:#7f9f7f; +} + +.highlight .l,.preview-zenburn .highlight .x,.preview-zenburn .highlight .no,.preview-zenburn .highlight .nd,.preview-zenburn .highlight .nl,.preview-zenburn .highlight .nx,.preview-zenburn .highlight .py,.preview-zenburn .highlight .w { +color:#ccc; +} + +.highlight .n,.preview-zenburn .highlight .nv,.preview-zenburn .highlight .vg { +color:#dcdccc; +} + +.highlight .o,.preview-zenburn .highlight .ow { +color:#f0efd0; +} + +.highlight .gh,.preview-zenburn .highlight .gp { +color:#dcdccc; +font-weight:700; +} + +.highlight .gi,.preview-zenburn .highlight .kt { +color:#00cd00; +} + +.highlight .ld,.preview-zenburn .highlight .s,.preview-zenburn .highlight .sb,.preview-zenburn .highlight .sc,.preview-zenburn .highlight .sd,.preview-zenburn .highlight .s2,.preview-zenburn .highlight .se,.preview-zenburn .highlight .sh,.preview-zenburn .highlight .si,.preview-zenburn .highlight .sx,.preview-zenburn .highlight .sr,.preview-zenburn .highlight .s1,.preview-zenburn .highlight .ss { +color:#cc9393; +} + +.highlight .m,.preview-zenburn .highlight .mf,.preview-zenburn .highlight .mh,.preview-zenburn .highlight .mi,.preview-zenburn .highlight .mo,.preview-zenburn .highlight .il { +color:#8cd0d3; +} + +.highlight .na,.preview-zenburn .highlight .nt { +color:#9ac39f; +} + +.highlight .nb,.preview-zenburn .highlight .nc,.preview-zenburn .highlight .nf,.preview-zenburn .highlight .bp,.preview-zenburn .highlight .vc { +color:#efef8f; +} diff --git a/docs/_site/assets/css/spec-style.css b/docs/_site/assets/css/spec-style.css new file mode 100644 index 0000000..513a264 --- /dev/null +++ b/docs/_site/assets/css/spec-style.css @@ -0,0 +1 @@ +@import url("https://fonts.googleapis.com/css?family=Inconsolata");body{font-family:Arial,sans-serif;margin:10% 25% 10% 10%;line-height:1.3}a{color:navy;text-decoration:none}a:visited{color:navy;text-decoration:none}a:hover{text-decoration:underline}pre{font-family:"Inconsolata",monospace;border:2px solid #ddd;padding:1em;margin-left:1em;overflow-x:auto}code{font-family:"Inconsolata",monospace}table{border-collapse:collapse;min-width:50%;margin-left:1em}th,td{border:2px solid #ccc;padding:.5em}th{background-color:#333;color:#fff}table.terms th{display:none}table.terms td{vertical-align:top}table.conventions th{display:none}table.conventions td{vertical-align:top}table.conventions td:first-child{white-space:nowrap}table.nohead th{display:none}table.xyhead th,table.xyhead td:first-child{background-color:#9bbb59}table.xyhead th{color:#000;font-weight:normal}figure.highlight{background-color:#f2f2f2;padding-left:1em;padding-right:1em;border:2px solid #ccc}div.syntax{background-color:#fff;background-image:linear-gradient(90deg, transparent 540px, #abced4 540px, #abced4 542px, transparent 542px),linear-gradient(#ddd .1em, transparent .1em);background-size:100% 1.3em;border-left:2px solid #ddd;border-right:2px solid #ddd;border-bottom:2px solid #ddd;white-space:pre;font-family:"Inconsolata",monospace;font-size:1em;padding-left:1em;margin-left:1em;width:720px} diff --git a/docs/_site/assets/favicon.ico b/docs/_site/assets/favicon.ico new file mode 100644 index 0000000..4ca5dba Binary files /dev/null and b/docs/_site/assets/favicon.ico differ diff --git a/docs/_site/assets/js/ASCIIMathML.js b/docs/_site/assets/js/ASCIIMathML.js new file mode 100644 index 0000000..727111c --- /dev/null +++ b/docs/_site/assets/js/ASCIIMathML.js @@ -0,0 +1,1127 @@ +/* +ASCIIMathML.js +============== +This file contains JavaScript functions to convert ASCII math notation +and (some) LaTeX to Presentation MathML. The conversion is done while the +HTML page loads, and should work with Firefox and other browsers that can +render MathML. + +Just add the next line to your HTML page with this file in the same folder: + + + +Version 2.2 Mar 3, 2014. +Latest version at https://github.com/mathjax/asciimathml +If you use it on a webpage, please send the URL to jipsen@chapman.edu + +Copyright (c) 2014 Peter Jipsen and other ASCIIMathML.js contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ +var asciimath = {}; + +(function(){ +var mathcolor = "blue"; // change it to "" (to inherit) or another color +var mathfontsize = "1em"; // change to e.g. 1.2em for larger math +var mathfontfamily = "serif"; // change to "" to inherit (works in IE) + // or another family (e.g. "arial") +var automathrecognize = false; // writing "amath" on page makes this true +var checkForMathML = true; // check if browser can display MathML +var notifyIfNoMathML = true; // display note at top if no MathML capability +var alertIfNoMathML = false; // show alert box if no MathML capability +var translateOnLoad = true; // set to false to do call translators from js +var translateASCIIMath = true; // false to preserve `..` +var displaystyle = true; // puts limits above and below large operators +var showasciiformulaonhover = true; // helps students learn ASCIIMath +var decimalsign = "."; // change to "," if you like, beware of `(1,2)`! +var AMdelimiter1 = "`", AMescape1 = "\\\\`"; // can use other characters +var AMdocumentId = "wikitext" // PmWiki element containing math (default=body) +var fixphi = true; //false to return to legacy phi/varphi mapping + +/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ + +var isIE = (navigator.appName.slice(0,9)=="Microsoft"); +var noMathML = false, translated = false; + +if (isIE) { // add MathPlayer info to IE webpages + document.write(""); + document.write(""); +} + +// Add a stylesheet, replacing any previous custom stylesheet (adapted from TW) +function setStylesheet(s) { + var id = "AMMLcustomStyleSheet"; + var n = document.getElementById(id); + if(document.createStyleSheet) { + // Test for IE's non-standard createStyleSheet method + if(n) + n.parentNode.removeChild(n); + // This failed without the   + document.getElementsByTagName("head")[0].insertAdjacentHTML("beforeEnd"," "); + } else { + if(n) { + n.replaceChild(document.createTextNode(s),n.firstChild); + } else { + n = document.createElement("style"); + n.type = "text/css"; + n.id = id; + n.appendChild(document.createTextNode(s)); + document.getElementsByTagName("head")[0].appendChild(n); + } + } +} + +setStylesheet("#AMMLcloseDiv \{font-size:0.8em; padding-top:1em; color:#014\}\n#AMMLwarningBox \{position:absolute; width:100%; top:0; left:0; z-index:200; text-align:center; font-size:1em; font-weight:bold; padding:0.5em 0 0.5em 0; color:#ffc; background:#c30\}"); + +function init(){ + var msg, warnings = new Array(); + if (document.getElementById==null){ + alert("This webpage requires a recent browser such as Mozilla Firefox"); + return null; + } + if (checkForMathML && (msg = checkMathML())) warnings.push(msg); + if (warnings.length>0) displayWarnings(warnings); + if (!noMathML) initSymbols(); + return true; +} + +function checkMathML(){ + if (navigator.appName.slice(0,8)=="Netscape") + if (navigator.appVersion.slice(0,1)>="5") noMathML = null; + else noMathML = true; + else if (navigator.appName.slice(0,9)=="Microsoft") + try { + var ActiveX = new ActiveXObject("MathPlayer.Factory.1"); + noMathML = null; + } catch (e) { + noMathML = true; + } + else if (navigator.appName.slice(0,5)=="Opera") + if (navigator.appVersion.slice(0,3)>="9.5") noMathML = null; + else noMathML = true; +//noMathML = true; //uncomment to check + if (noMathML && notifyIfNoMathML) { + var msg = "To view the ASCIIMathML notation use Internet Explorer + MathPlayer or Mozilla Firefox 2.0 or later."; + if (alertIfNoMathML) + alert(msg); + else return msg; + } +} + +function hideWarning(){ + var body = document.getElementsByTagName("body")[0]; + body.removeChild(document.getElementById('AMMLwarningBox')); + body.onclick = null; +} + +function displayWarnings(warnings) { + var i, frag, nd = createElementXHTML("div"); + var body = document.getElementsByTagName("body")[0]; + body.onclick=hideWarning; + nd.id = 'AMMLwarningBox'; + for (i=0; i<", tag:"mo", output:"\u22C9", tex:"ltimes", ttype:CONST}, +{input:"><|", tag:"mo", output:"\u22CA", tex:"rtimes", ttype:CONST}, +{input:"|><|", tag:"mo", output:"\u22C8", tex:"bowtie", ttype:CONST}, +{input:"-:", tag:"mo", output:"\u00F7", tex:"div", ttype:CONST}, +{input:"divide", tag:"mo", output:"-:", tex:null, ttype:DEFINITION}, +{input:"@", tag:"mo", output:"\u2218", tex:"circ", ttype:CONST}, +{input:"o+", tag:"mo", output:"\u2295", tex:"oplus", ttype:CONST}, +{input:"ox", tag:"mo", output:"\u2297", tex:"otimes", ttype:CONST}, +{input:"o.", tag:"mo", output:"\u2299", tex:"odot", ttype:CONST}, +{input:"sum", tag:"mo", output:"\u2211", tex:null, ttype:UNDEROVER}, +{input:"prod", tag:"mo", output:"\u220F", tex:null, ttype:UNDEROVER}, +{input:"^^", tag:"mo", output:"\u2227", tex:"wedge", ttype:CONST}, +{input:"^^^", tag:"mo", output:"\u22C0", tex:"bigwedge", ttype:UNDEROVER}, +{input:"vv", tag:"mo", output:"\u2228", tex:"vee", ttype:CONST}, +{input:"vvv", tag:"mo", output:"\u22C1", tex:"bigvee", ttype:UNDEROVER}, +{input:"nn", tag:"mo", output:"\u2229", tex:"cap", ttype:CONST}, +{input:"nnn", tag:"mo", output:"\u22C2", tex:"bigcap", ttype:UNDEROVER}, +{input:"uu", tag:"mo", output:"\u222A", tex:"cup", ttype:CONST}, +{input:"uuu", tag:"mo", output:"\u22C3", tex:"bigcup", ttype:UNDEROVER}, + +//binary relation symbols +{input:"!=", tag:"mo", output:"\u2260", tex:"ne", ttype:CONST}, +{input:":=", tag:"mo", output:":=", tex:null, ttype:CONST}, +{input:"lt", tag:"mo", output:"<", tex:null, ttype:CONST}, +{input:"<=", tag:"mo", output:"\u2264", tex:"le", ttype:CONST}, +{input:"lt=", tag:"mo", output:"\u2264", tex:"leq", ttype:CONST}, +{input:"gt", tag:"mo", output:">", tex:null, ttype:CONST}, +{input:">=", tag:"mo", output:"\u2265", tex:"ge", ttype:CONST}, +{input:"gt=", tag:"mo", output:"\u2265", tex:"geq", ttype:CONST}, +{input:"-<", tag:"mo", output:"\u227A", tex:"prec", ttype:CONST}, +{input:"-lt", tag:"mo", output:"\u227A", tex:null, ttype:CONST}, +{input:">-", tag:"mo", output:"\u227B", tex:"succ", ttype:CONST}, +{input:"-<=", tag:"mo", output:"\u2AAF", tex:"preceq", ttype:CONST}, +{input:">-=", tag:"mo", output:"\u2AB0", tex:"succeq", ttype:CONST}, +{input:"in", tag:"mo", output:"\u2208", tex:null, ttype:CONST}, +{input:"!in", tag:"mo", output:"\u2209", tex:"notin", ttype:CONST}, +{input:"sub", tag:"mo", output:"\u2282", tex:"subset", ttype:CONST}, +{input:"sup", tag:"mo", output:"\u2283", tex:"supset", ttype:CONST}, +{input:"sube", tag:"mo", output:"\u2286", tex:"subseteq", ttype:CONST}, +{input:"supe", tag:"mo", output:"\u2287", tex:"supseteq", ttype:CONST}, +{input:"-=", tag:"mo", output:"\u2261", tex:"equiv", ttype:CONST}, +{input:"~=", tag:"mo", output:"\u2245", tex:"cong", ttype:CONST}, +{input:"~~", tag:"mo", output:"\u2248", tex:"approx", ttype:CONST}, +{input:"prop", tag:"mo", output:"\u221D", tex:"propto", ttype:CONST}, + +//logical symbols +{input:"and", tag:"mtext", output:"and", tex:null, ttype:SPACE}, +{input:"or", tag:"mtext", output:"or", tex:null, ttype:SPACE}, +{input:"not", tag:"mo", output:"\u00AC", tex:"neg", ttype:CONST}, +{input:"=>", tag:"mo", output:"\u21D2", tex:"implies", ttype:CONST}, +{input:"if", tag:"mo", output:"if", tex:null, ttype:SPACE}, +{input:"<=>", tag:"mo", output:"\u21D4", tex:"iff", ttype:CONST}, +{input:"AA", tag:"mo", output:"\u2200", tex:"forall", ttype:CONST}, +{input:"EE", tag:"mo", output:"\u2203", tex:"exists", ttype:CONST}, +{input:"_|_", tag:"mo", output:"\u22A5", tex:"bot", ttype:CONST}, +{input:"TT", tag:"mo", output:"\u22A4", tex:"top", ttype:CONST}, +{input:"|--", tag:"mo", output:"\u22A2", tex:"vdash", ttype:CONST}, +{input:"|==", tag:"mo", output:"\u22A8", tex:"models", ttype:CONST}, + +//grouping brackets +{input:"(", tag:"mo", output:"(", tex:null, ttype:LEFTBRACKET}, +{input:")", tag:"mo", output:")", tex:null, ttype:RIGHTBRACKET}, +{input:"[", tag:"mo", output:"[", tex:null, ttype:LEFTBRACKET}, +{input:"]", tag:"mo", output:"]", tex:null, ttype:RIGHTBRACKET}, +{input:"{", tag:"mo", output:"{", tex:null, ttype:LEFTBRACKET}, +{input:"}", tag:"mo", output:"}", tex:null, ttype:RIGHTBRACKET}, +{input:"|", tag:"mo", output:"|", tex:null, ttype:LEFTRIGHT}, +//{input:"||", tag:"mo", output:"||", tex:null, ttype:LEFTRIGHT}, +{input:"(:", tag:"mo", output:"\u2329", tex:"langle", ttype:LEFTBRACKET}, +{input:":)", tag:"mo", output:"\u232A", tex:"rangle", ttype:RIGHTBRACKET}, +{input:"<<", tag:"mo", output:"\u2329", tex:null, ttype:LEFTBRACKET}, +{input:">>", tag:"mo", output:"\u232A", tex:null, ttype:RIGHTBRACKET}, +{input:"{:", tag:"mo", output:"{:", tex:null, ttype:LEFTBRACKET, invisible:true}, +{input:":}", tag:"mo", output:":}", tex:null, ttype:RIGHTBRACKET, invisible:true}, + +//miscellaneous symbols +{input:"int", tag:"mo", output:"\u222B", tex:null, ttype:CONST}, +{input:"dx", tag:"mi", output:"{:d x:}", tex:null, ttype:DEFINITION}, +{input:"dy", tag:"mi", output:"{:d y:}", tex:null, ttype:DEFINITION}, +{input:"dz", tag:"mi", output:"{:d z:}", tex:null, ttype:DEFINITION}, +{input:"dt", tag:"mi", output:"{:d t:}", tex:null, ttype:DEFINITION}, +{input:"oint", tag:"mo", output:"\u222E", tex:null, ttype:CONST}, +{input:"del", tag:"mo", output:"\u2202", tex:"partial", ttype:CONST}, +{input:"grad", tag:"mo", output:"\u2207", tex:"nabla", ttype:CONST}, +{input:"+-", tag:"mo", output:"\u00B1", tex:"pm", ttype:CONST}, +{input:"O/", tag:"mo", output:"\u2205", tex:"emptyset", ttype:CONST}, +{input:"oo", tag:"mo", output:"\u221E", tex:"infty", ttype:CONST}, +{input:"aleph", tag:"mo", output:"\u2135", tex:null, ttype:CONST}, +{input:"...", tag:"mo", output:"...", tex:"ldots", ttype:CONST}, +{input:":.", tag:"mo", output:"\u2234", tex:"therefore", ttype:CONST}, +{input:":'", tag:"mo", output:"\u2235", tex:"because", ttype:CONST}, +{input:"/_", tag:"mo", output:"\u2220", tex:"angle", ttype:CONST}, +{input:"/_\\", tag:"mo", output:"\u25B3", tex:"triangle", ttype:CONST}, +{input:"'", tag:"mo", output:"\u2032", tex:"prime", ttype:CONST}, +{input:"tilde", tag:"mover", output:"~", tex:null, ttype:UNARY, acc:true}, +{input:"\\ ", tag:"mo", output:"\u00A0", tex:null, ttype:CONST}, +{input:"frown", tag:"mo", output:"\u2322", tex:null, ttype:CONST}, +{input:"quad", tag:"mo", output:"\u00A0\u00A0", tex:null, ttype:CONST}, +{input:"qquad", tag:"mo", output:"\u00A0\u00A0\u00A0\u00A0", tex:null, ttype:CONST}, +{input:"cdots", tag:"mo", output:"\u22EF", tex:null, ttype:CONST}, +{input:"vdots", tag:"mo", output:"\u22EE", tex:null, ttype:CONST}, +{input:"ddots", tag:"mo", output:"\u22F1", tex:null, ttype:CONST}, +{input:"diamond", tag:"mo", output:"\u22C4", tex:null, ttype:CONST}, +{input:"square", tag:"mo", output:"\u25A1", tex:null, ttype:CONST}, +{input:"|__", tag:"mo", output:"\u230A", tex:"lfloor", ttype:CONST}, +{input:"__|", tag:"mo", output:"\u230B", tex:"rfloor", ttype:CONST}, +{input:"|~", tag:"mo", output:"\u2308", tex:"lceiling", ttype:CONST}, +{input:"~|", tag:"mo", output:"\u2309", tex:"rceiling", ttype:CONST}, +{input:"CC", tag:"mo", output:"\u2102", tex:null, ttype:CONST}, +{input:"NN", tag:"mo", output:"\u2115", tex:null, ttype:CONST}, +{input:"QQ", tag:"mo", output:"\u211A", tex:null, ttype:CONST}, +{input:"RR", tag:"mo", output:"\u211D", tex:null, ttype:CONST}, +{input:"ZZ", tag:"mo", output:"\u2124", tex:null, ttype:CONST}, +{input:"f", tag:"mi", output:"f", tex:null, ttype:UNARY, func:true}, +{input:"g", tag:"mi", output:"g", tex:null, ttype:UNARY, func:true}, + +//standard functions +{input:"lim", tag:"mo", output:"lim", tex:null, ttype:UNDEROVER}, +{input:"Lim", tag:"mo", output:"Lim", tex:null, ttype:UNDEROVER}, +{input:"sin", tag:"mo", output:"sin", tex:null, ttype:UNARY, func:true}, +{input:"cos", tag:"mo", output:"cos", tex:null, ttype:UNARY, func:true}, +{input:"tan", tag:"mo", output:"tan", tex:null, ttype:UNARY, func:true}, +{input:"sinh", tag:"mo", output:"sinh", tex:null, ttype:UNARY, func:true}, +{input:"cosh", tag:"mo", output:"cosh", tex:null, ttype:UNARY, func:true}, +{input:"tanh", tag:"mo", output:"tanh", tex:null, ttype:UNARY, func:true}, +{input:"cot", tag:"mo", output:"cot", tex:null, ttype:UNARY, func:true}, +{input:"sec", tag:"mo", output:"sec", tex:null, ttype:UNARY, func:true}, +{input:"csc", tag:"mo", output:"csc", tex:null, ttype:UNARY, func:true}, +{input:"arcsin", tag:"mo", output:"arcsin", tex:null, ttype:UNARY, func:true}, +{input:"arccos", tag:"mo", output:"arccos", tex:null, ttype:UNARY, func:true}, +{input:"arctan", tag:"mo", output:"arctan", tex:null, ttype:UNARY, func:true}, +{input:"coth", tag:"mo", output:"coth", tex:null, ttype:UNARY, func:true}, +{input:"sech", tag:"mo", output:"sech", tex:null, ttype:UNARY, func:true}, +{input:"csch", tag:"mo", output:"csch", tex:null, ttype:UNARY, func:true}, +{input:"exp", tag:"mo", output:"exp", tex:null, ttype:UNARY, func:true}, +{input:"abs", tag:"mo", output:"abs", tex:null, ttype:UNARY, rewriteleftright:["|","|"]}, +{input:"norm", tag:"mo", output:"norm", tex:null, ttype:UNARY, rewriteleftright:["\u2225","\u2225"]}, +{input:"floor", tag:"mo", output:"floor", tex:null, ttype:UNARY, rewriteleftright:["\u230A","\u230B"]}, +{input:"ceil", tag:"mo", output:"ceil", tex:null, ttype:UNARY, rewriteleftright:["\u2308","\u2309"]}, +{input:"log", tag:"mo", output:"log", tex:null, ttype:UNARY, func:true}, +{input:"ln", tag:"mo", output:"ln", tex:null, ttype:UNARY, func:true}, +{input:"det", tag:"mo", output:"det", tex:null, ttype:UNARY, func:true}, +{input:"dim", tag:"mo", output:"dim", tex:null, ttype:CONST}, +{input:"mod", tag:"mo", output:"mod", tex:null, ttype:CONST}, +{input:"gcd", tag:"mo", output:"gcd", tex:null, ttype:UNARY, func:true}, +{input:"lcm", tag:"mo", output:"lcm", tex:null, ttype:UNARY, func:true}, +{input:"lub", tag:"mo", output:"lub", tex:null, ttype:CONST}, +{input:"glb", tag:"mo", output:"glb", tex:null, ttype:CONST}, +{input:"min", tag:"mo", output:"min", tex:null, ttype:UNDEROVER}, +{input:"max", tag:"mo", output:"max", tex:null, ttype:UNDEROVER}, + +//arrows +{input:"uarr", tag:"mo", output:"\u2191", tex:"uparrow", ttype:CONST}, +{input:"darr", tag:"mo", output:"\u2193", tex:"downarrow", ttype:CONST}, +{input:"rarr", tag:"mo", output:"\u2192", tex:"rightarrow", ttype:CONST}, +{input:"->", tag:"mo", output:"\u2192", tex:"to", ttype:CONST}, +{input:">->", tag:"mo", output:"\u21A3", tex:"rightarrowtail", ttype:CONST}, +{input:"->>", tag:"mo", output:"\u21A0", tex:"twoheadrightarrow", ttype:CONST}, +{input:">->>", tag:"mo", output:"\u2916", tex:"twoheadrightarrowtail", ttype:CONST}, +{input:"|->", tag:"mo", output:"\u21A6", tex:"mapsto", ttype:CONST}, +{input:"larr", tag:"mo", output:"\u2190", tex:"leftarrow", ttype:CONST}, +{input:"harr", tag:"mo", output:"\u2194", tex:"leftrightarrow", ttype:CONST}, +{input:"rArr", tag:"mo", output:"\u21D2", tex:"Rightarrow", ttype:CONST}, +{input:"lArr", tag:"mo", output:"\u21D0", tex:"Leftarrow", ttype:CONST}, +{input:"hArr", tag:"mo", output:"\u21D4", tex:"Leftrightarrow", ttype:CONST}, +//commands with argument +{input:"sqrt", tag:"msqrt", output:"sqrt", tex:null, ttype:UNARY}, +{input:"root", tag:"mroot", output:"root", tex:null, ttype:BINARY}, +{input:"frac", tag:"mfrac", output:"/", tex:null, ttype:BINARY}, +{input:"/", tag:"mfrac", output:"/", tex:null, ttype:INFIX}, +{input:"stackrel", tag:"mover", output:"stackrel", tex:null, ttype:BINARY}, +{input:"overset", tag:"mover", output:"stackrel", tex:null, ttype:BINARY}, +{input:"underset", tag:"munder", output:"stackrel", tex:null, ttype:BINARY}, +{input:"_", tag:"msub", output:"_", tex:null, ttype:INFIX}, +{input:"^", tag:"msup", output:"^", tex:null, ttype:INFIX}, +{input:"hat", tag:"mover", output:"\u005E", tex:null, ttype:UNARY, acc:true}, +{input:"bar", tag:"mover", output:"\u00AF", tex:"overline", ttype:UNARY, acc:true}, +{input:"vec", tag:"mover", output:"\u2192", tex:null, ttype:UNARY, acc:true}, +{input:"dot", tag:"mover", output:".", tex:null, ttype:UNARY, acc:true}, +{input:"ddot", tag:"mover", output:"..", tex:null, ttype:UNARY, acc:true}, +{input:"ul", tag:"munder", output:"\u0332", tex:"underline", ttype:UNARY, acc:true}, +{input:"ubrace", tag:"munder", output:"\u23DF", tex:"underbrace", ttype:UNARYUNDEROVER, acc:true}, +{input:"obrace", tag:"mover", output:"\u23DE", tex:"overbrace", ttype:UNARYUNDEROVER, acc:true}, +{input:"text", tag:"mtext", output:"text", tex:null, ttype:TEXT}, +{input:"mbox", tag:"mtext", output:"mbox", tex:null, ttype:TEXT}, +{input:"color", tag:"mstyle", ttype:BINARY}, +{input:"cancel", tag:"menclose", output:"cancel", tex:null, ttype:UNARY}, +AMquote, +{input:"bb", tag:"mstyle", atname:"mathvariant", atval:"bold", output:"bb", tex:null, ttype:UNARY}, +{input:"mathbf", tag:"mstyle", atname:"mathvariant", atval:"bold", output:"mathbf", tex:null, ttype:UNARY}, +{input:"sf", tag:"mstyle", atname:"mathvariant", atval:"sans-serif", output:"sf", tex:null, ttype:UNARY}, +{input:"mathsf", tag:"mstyle", atname:"mathvariant", atval:"sans-serif", output:"mathsf", tex:null, ttype:UNARY}, +{input:"bbb", tag:"mstyle", atname:"mathvariant", atval:"double-struck", output:"bbb", tex:null, ttype:UNARY, codes:AMbbb}, +{input:"mathbb", tag:"mstyle", atname:"mathvariant", atval:"double-struck", output:"mathbb", tex:null, ttype:UNARY, codes:AMbbb}, +{input:"cc", tag:"mstyle", atname:"mathvariant", atval:"script", output:"cc", tex:null, ttype:UNARY, codes:AMcal}, +{input:"mathcal", tag:"mstyle", atname:"mathvariant", atval:"script", output:"mathcal", tex:null, ttype:UNARY, codes:AMcal}, +{input:"tt", tag:"mstyle", atname:"mathvariant", atval:"monospace", output:"tt", tex:null, ttype:UNARY}, +{input:"mathtt", tag:"mstyle", atname:"mathvariant", atval:"monospace", output:"mathtt", tex:null, ttype:UNARY}, +{input:"fr", tag:"mstyle", atname:"mathvariant", atval:"fraktur", output:"fr", tex:null, ttype:UNARY, codes:AMfrk}, +{input:"mathfrak", tag:"mstyle", atname:"mathvariant", atval:"fraktur", output:"mathfrak", tex:null, ttype:UNARY, codes:AMfrk} +]; + +function compareNames(s1,s2) { + if (s1.input > s2.input) return 1 + else return -1; +} + +var AMnames = []; //list of input symbols + +function initSymbols() { + var i; + var symlen = AMsymbols.length; + for (i=0; i=n where str appears or would be inserted +// assumes arr is sorted + if (n==0) { + var h,m; + n = -1; + h = arr.length; + while (n+1> 1; + if (arr[m]=str +} + +function AMgetSymbol(str) { +//return maximal initial substring of str that appears in names +//return null if there is none + var k = 0; //new pos + var j = 0; //old pos + var mk; //match pos + var st; + var tagst; + var match = ""; + var more = true; + for (var i=1; i<=str.length && more; i++) { + st = str.slice(0,i); //initial substring of length i + j = k; + k = position(AMnames, st, j); + if (k=AMnames[k]; + } + AMpreviousSymbol=AMcurrentSymbol; + if (match!=""){ + AMcurrentSymbol=AMsymbols[mk].ttype; + return AMsymbols[mk]; + } +// if str[0] is a digit or - return maxsubstring of digits.digits + AMcurrentSymbol=CONST; + k = 1; + st = str.slice(0,1); + var integ = true; + while ("0"<=st && st<="9" && k<=str.length) { + st = str.slice(k,k+1); + k++; + } + if (st == decimalsign) { + st = str.slice(k,k+1); + if ("0"<=st && st<="9") { + integ = false; + k++; + while ("0"<=st && st<="9" && k<=str.length) { + st = str.slice(k,k+1); + k++; + } + } + } + if ((integ && k>1) || k>2) { + st = str.slice(0,k-1); + tagst = "mn"; + } else { + k = 2; + st = str.slice(0,1); //take 1 character + tagst = (("A">st || st>"Z") && ("a">st || st>"z")?"mo":"mi"); + } + if (st=="-" && AMpreviousSymbol==INFIX) { + AMcurrentSymbol = INFIX; //trick "/" into recognizing "-" on second parse + return {input:st, tag:tagst, output:st, ttype:UNARY, func:true}; + } + return {input:st, tag:tagst, output:st, ttype:CONST}; +} + +function AMremoveBrackets(node) { + var st; + if (!node.hasChildNodes()) { return; } + if (node.firstChild.hasChildNodes() && (node.nodeName=="mrow" || node.nodeName=="M:MROW")) { + st = node.firstChild.firstChild.nodeValue; + if (st=="(" || st=="[" || st=="{") node.removeChild(node.firstChild); + } + if (node.lastChild.hasChildNodes() && (node.nodeName=="mrow" || node.nodeName=="M:MROW")) { + st = node.lastChild.firstChild.nodeValue; + if (st==")" || st=="]" || st=="}") node.removeChild(node.lastChild); + } +} + +/*Parsing ASCII math expressions with the following grammar +v ::= [A-Za-z] | greek letters | numbers | other constant symbols +u ::= sqrt | text | bb | other unary symbols for font commands +b ::= frac | root | stackrel binary symbols +l ::= ( | [ | { | (: | {: left brackets +r ::= ) | ] | } | :) | :} right brackets +S ::= v | lEr | uS | bSS Simple expression +I ::= S_S | S^S | S_S^S | S Intermediate expression +E ::= IE | I/I Expression +Each terminal symbol is translated into a corresponding mathml node.*/ + +var AMnestingDepth,AMpreviousSymbol,AMcurrentSymbol; + +function AMparseSexpr(str) { //parses str and returns [node,tailstr] + var symbol, node, result, i, st,// rightvert = false, + newFrag = document.createDocumentFragment(); + str = AMremoveCharsAndBlanks(str,0); + symbol = AMgetSymbol(str); //either a token or a bracket or empty + if (symbol == null || symbol.ttype == RIGHTBRACKET && AMnestingDepth > 0) { + return [null,str]; + } + if (symbol.ttype == DEFINITION) { + str = symbol.output+AMremoveCharsAndBlanks(str,symbol.input.length); + symbol = AMgetSymbol(str); + } + switch (symbol.ttype) { case UNDEROVER: + case CONST: + str = AMremoveCharsAndBlanks(str,symbol.input.length); + return [createMmlNode(symbol.tag, //its a constant + document.createTextNode(symbol.output)),str]; + case LEFTBRACKET: //read (expr+) + AMnestingDepth++; + str = AMremoveCharsAndBlanks(str,symbol.input.length); + result = AMparseExpr(str,true); + AMnestingDepth--; + if (typeof symbol.invisible == "boolean" && symbol.invisible) + node = createMmlNode("mrow",result[0]); + else { + node = createMmlNode("mo",document.createTextNode(symbol.output)); + node = createMmlNode("mrow",node); + node.appendChild(result[0]); + } + return [node,result[1]]; + case TEXT: + if (symbol!=AMquote) str = AMremoveCharsAndBlanks(str,symbol.input.length); + if (str.charAt(0)=="{") i=str.indexOf("}"); + else if (str.charAt(0)=="(") i=str.indexOf(")"); + else if (str.charAt(0)=="[") i=str.indexOf("]"); + else if (symbol==AMquote) i=str.slice(1).indexOf("\"")+1; + else i = 0; + if (i==-1) i = str.length; + st = str.slice(1,i); + if (st.charAt(0) == " ") { + node = createMmlNode("mspace"); + node.setAttribute("width","1ex"); + newFrag.appendChild(node); + } + newFrag.appendChild( + createMmlNode(symbol.tag,document.createTextNode(st))); + if (st.charAt(st.length-1) == " ") { + node = createMmlNode("mspace"); + node.setAttribute("width","1ex"); + newFrag.appendChild(node); + } + str = AMremoveCharsAndBlanks(str,i+1); + return [createMmlNode("mrow",newFrag),str]; + case UNARYUNDEROVER: + case UNARY: + str = AMremoveCharsAndBlanks(str,symbol.input.length); + result = AMparseSexpr(str); + if (result[0]==null) return [createMmlNode(symbol.tag, + document.createTextNode(symbol.output)),str]; + if (typeof symbol.func == "boolean" && symbol.func) { // functions hack + st = str.charAt(0); + if (st=="^" || st=="_" || st=="/" || st=="|" || st=="," || + (symbol.input.length==1 && symbol.input.match(/\w/) && st!="(")) { + return [createMmlNode(symbol.tag, + document.createTextNode(symbol.output)),str]; + } else { + node = createMmlNode("mrow", + createMmlNode(symbol.tag,document.createTextNode(symbol.output))); + node.appendChild(result[0]); + return [node,result[1]]; + } + } + AMremoveBrackets(result[0]); + if (symbol.input == "sqrt") { // sqrt + return [createMmlNode(symbol.tag,result[0]),result[1]]; + } else if (typeof symbol.rewriteleftright != "undefined") { // abs, floor, ceil + node = createMmlNode("mrow", createMmlNode("mo",document.createTextNode(symbol.rewriteleftright[0]))); + node.appendChild(result[0]); + node.appendChild(createMmlNode("mo",document.createTextNode(symbol.rewriteleftright[1]))); + return [node,result[1]]; + } else if (symbol.input == "cancel") { // cancel + node = createMmlNode(symbol.tag,result[0]); + node.setAttribute("notation","updiagonalstrike"); + return [node,result[1]]; + } else if (typeof symbol.acc == "boolean" && symbol.acc) { // accent + node = createMmlNode(symbol.tag,result[0]); + node.appendChild(createMmlNode("mo",document.createTextNode(symbol.output))); + return [node,result[1]]; + } else { // font change command + if (!isIE && typeof symbol.codes != "undefined") { + for (i=0; i64 && st.charCodeAt(j)<91) + newst = newst + symbol.codes[st.charCodeAt(j)-65]; + else if (st.charCodeAt(j)>96 && st.charCodeAt(j)<123) + newst = newst + symbol.codes[st.charCodeAt(j)-71]; + else newst = newst + st.charAt(j); + if (result[0].nodeName=="mi") + result[0]=createMmlNode("mo"). + appendChild(document.createTextNode(newst)); + else result[0].replaceChild(createMmlNode("mo"). + appendChild(document.createTextNode(newst)), + result[0].childNodes[i]); + } + } + node = createMmlNode(symbol.tag,result[0]); + node.setAttribute(symbol.atname,symbol.atval); + return [node,result[1]]; + } + case BINARY: + str = AMremoveCharsAndBlanks(str,symbol.input.length); + result = AMparseSexpr(str); + if (result[0]==null) return [createMmlNode("mo", + document.createTextNode(symbol.input)),str]; + AMremoveBrackets(result[0]); + var result2 = AMparseSexpr(result[1]); + if (result2[0]==null) return [createMmlNode("mo", + document.createTextNode(symbol.input)),str]; + AMremoveBrackets(result2[0]); + if (symbol.input=="color") { + if (str.charAt(0)=="{") i=str.indexOf("}"); + else if (str.charAt(0)=="(") i=str.indexOf(")"); + else if (str.charAt(0)=="[") i=str.indexOf("]"); + st = str.slice(1,i); + node = createMmlNode(symbol.tag,result2[0]); + node.setAttribute("mathcolor",st); + return [node,result2[1]]; + } + if (symbol.input=="root" || symbol.output=="stackrel") + newFrag.appendChild(result2[0]); + newFrag.appendChild(result[0]); + if (symbol.input=="frac") newFrag.appendChild(result2[0]); + return [createMmlNode(symbol.tag,newFrag),result2[1]]; + case INFIX: + str = AMremoveCharsAndBlanks(str,symbol.input.length); + return [createMmlNode("mo",document.createTextNode(symbol.output)),str]; + case SPACE: + str = AMremoveCharsAndBlanks(str,symbol.input.length); + node = createMmlNode("mspace"); + node.setAttribute("width","1ex"); + newFrag.appendChild(node); + newFrag.appendChild( + createMmlNode(symbol.tag,document.createTextNode(symbol.output))); + node = createMmlNode("mspace"); + node.setAttribute("width","1ex"); + newFrag.appendChild(node); + return [createMmlNode("mrow",newFrag),str]; + case LEFTRIGHT: +// if (rightvert) return [null,str]; else rightvert = true; + AMnestingDepth++; + str = AMremoveCharsAndBlanks(str,symbol.input.length); + result = AMparseExpr(str,false); + AMnestingDepth--; + st = ""; + if (result[0].lastChild!=null) + st = result[0].lastChild.firstChild.nodeValue; + if (st == "|") { // its an absolute value subterm + node = createMmlNode("mo",document.createTextNode(symbol.output)); + node = createMmlNode("mrow",node); + node.appendChild(result[0]); + return [node,result[1]]; + } else { // the "|" is a \mid so use unicode 2223 (divides) for spacing + node = createMmlNode("mo",document.createTextNode("\u2223")); + node = createMmlNode("mrow",node); + return [node,str]; + } + default: +//alert("default"); + str = AMremoveCharsAndBlanks(str,symbol.input.length); + return [createMmlNode(symbol.tag, //its a constant + document.createTextNode(symbol.output)),str]; + } +} + +function AMparseIexpr(str) { + var symbol, sym1, sym2, node, result, underover; + str = AMremoveCharsAndBlanks(str,0); + sym1 = AMgetSymbol(str); + result = AMparseSexpr(str); + node = result[0]; + str = result[1]; + symbol = AMgetSymbol(str); + if (symbol.ttype == INFIX && symbol.input != "/") { + str = AMremoveCharsAndBlanks(str,symbol.input.length); +// if (symbol.input == "/") result = AMparseIexpr(str); else ... + result = AMparseSexpr(str); + if (result[0] == null) // show box in place of missing argument + result[0] = createMmlNode("mo",document.createTextNode("\u25A1")); + else AMremoveBrackets(result[0]); + str = result[1]; +// if (symbol.input == "/") AMremoveBrackets(node); + underover = (sym1.ttype == UNDEROVER || sym1.ttype == UNARYUNDEROVER); + if (symbol.input == "_") { + sym2 = AMgetSymbol(str); + if (sym2.input == "^") { + str = AMremoveCharsAndBlanks(str,sym2.input.length); + var res2 = AMparseSexpr(str); + AMremoveBrackets(res2[0]); + str = res2[1]; + node = createMmlNode((underover?"munderover":"msubsup"),node); + node.appendChild(result[0]); + node.appendChild(res2[0]); + node = createMmlNode("mrow",node); // so sum does not stretch + } else { + node = createMmlNode((underover?"munder":"msub"),node); + node.appendChild(result[0]); + } + } else if (symbol.input == "^" && underover) { + node = createMmlNode("mover",node); + node.appendChild(result[0]); + } else { + node = createMmlNode(symbol.tag,node); + node.appendChild(result[0]); + } + if (typeof sym1.func != 'undefined' && sym1.func) { + sym2 = AMgetSymbol(str); + if (sym2.ttype != INFIX && sym2.ttype != RIGHTBRACKET) { + result = AMparseIexpr(str); + node = createMmlNode("mrow",node); + node.appendChild(result[0]); + str = result[1]; + } + } + } + return [node,str]; +} + +function AMparseExpr(str,rightbracket) { + var symbol, node, result, i, + newFrag = document.createDocumentFragment(); + do { + str = AMremoveCharsAndBlanks(str,0); + result = AMparseIexpr(str); + node = result[0]; + str = result[1]; + symbol = AMgetSymbol(str); + if (symbol.ttype == INFIX && symbol.input == "/") { + str = AMremoveCharsAndBlanks(str,symbol.input.length); + result = AMparseIexpr(str); + if (result[0] == null) // show box in place of missing argument + result[0] = createMmlNode("mo",document.createTextNode("\u25A1")); + else AMremoveBrackets(result[0]); + str = result[1]; + AMremoveBrackets(node); + node = createMmlNode(symbol.tag,node); + node.appendChild(result[0]); + newFrag.appendChild(node); + symbol = AMgetSymbol(str); + } + else if (node!=undefined) newFrag.appendChild(node); + } while ((symbol.ttype != RIGHTBRACKET && + (symbol.ttype != LEFTRIGHT || rightbracket) + || AMnestingDepth == 0) && symbol!=null && symbol.output!=""); + if (symbol.ttype == RIGHTBRACKET || symbol.ttype == LEFTRIGHT) { +// if (AMnestingDepth > 0) AMnestingDepth--; + var len = newFrag.childNodes.length; + if (len>0 && newFrag.childNodes[len-1].nodeName == "mrow" + && newFrag.childNodes[len-1].lastChild + && newFrag.childNodes[len-1].lastChild.firstChild ) { //matrix + //removed to allow row vectors: //&& len>1 && + //newFrag.childNodes[len-2].nodeName == "mo" && + //newFrag.childNodes[len-2].firstChild.nodeValue == "," + var right = newFrag.childNodes[len-1].lastChild.firstChild.nodeValue; + if (right==")" || right=="]") { + var left = newFrag.childNodes[len-1].firstChild.firstChild.nodeValue; + if (left=="(" && right==")" && symbol.output != "}" || + left=="[" && right=="]") { + var pos = []; // positions of commas + var matrix = true; + var m = newFrag.childNodes.length; + for (i=0; matrix && i1) matrix = pos[i].length == pos[i-2].length; + } + matrix = matrix && (pos.length>1 || pos[0].length>0); + if (matrix) { + var row, frag, n, k, table = document.createDocumentFragment(); + for (i=0; i(-,-,...,-,-) + n = node.childNodes.length; + k = 0; + node.removeChild(node.firstChild); //remove ( + for (j=1; j2) { + newFrag.removeChild(newFrag.firstChild); //remove ) + newFrag.removeChild(newFrag.firstChild); //remove , + } + table.appendChild(createMmlNode("mtr",row)); + } + node = createMmlNode("mtable",table); + if (typeof symbol.invisible == "boolean" && symbol.invisible) node.setAttribute("columnalign","left"); + newFrag.replaceChild(node,newFrag.firstChild); + } + } + } + } + str = AMremoveCharsAndBlanks(str,symbol.input.length); + if (typeof symbol.invisible != "boolean" || !symbol.invisible) { + node = createMmlNode("mo",document.createTextNode(symbol.output)); + newFrag.appendChild(node); + } + } + return [newFrag,str]; +} + +function parseMath(str,latex) { + var frag, node; + AMnestingDepth = 0; + //some basic cleanup for dealing with stuff editors like TinyMCE adds + str = str.replace(/ /g,""); + str = str.replace(/>/g,">"); + str = str.replace(/</g,"<"); + str = str.replace(/(Sin|Cos|Tan|Arcsin|Arccos|Arctan|Sinh|Cosh|Tanh|Cot|Sec|Csc|Log|Ln|Abs)/g, function(v) { return v.toLowerCase(); }); + frag = AMparseExpr(str.replace(/^\s+/g,""),false)[0]; + node = createMmlNode("mstyle",frag); + if (mathcolor != "") node.setAttribute("mathcolor",mathcolor); + if (mathfontfamily != "") node.setAttribute("fontfamily",mathfontfamily); + if (displaystyle) node.setAttribute("displaystyle","true"); + node = createMmlNode("math",node); + if (showasciiformulaonhover) //fixed by djhsu so newline + node.setAttribute("title",str.replace(/\s+/g," "));//does not show in Gecko + return node; +} + +function strarr2docFrag(arr, linebreaks, latex) { + var newFrag=document.createDocumentFragment(); + var expr = false; + for (var i=0; i,\\|!:;'~]|\\.(?!(?:\x20|$))|"+ambigAMtoken+englishAMtoken+simpleAMtoken; + var re = new RegExp("(^|\\s)((("+token+")\\s?)(("+token+secondenglishAMtoken+")\\s?)+)([,.?]?(?=\\s|$))","g"); + str = str.replace(re," `$2`$7"); + var arr = str.split(AMdelimiter1); + var re1 = new RegExp("(^|\\s)([b-zB-HJ-Z+*<>]|"+texcommand+ambigAMtoken+simpleAMtoken+")(\\s|\\n|$)","g"); + var re2 = new RegExp("(^|\\s)([a-z]|"+texcommand+ambigAMtoken+simpleAMtoken+")([,.])","g"); // removed |\d+ for now + for (i=0; i1 || mtch) { + if (!noMathML) { + frg = strarr2docFrag(arr,n.nodeType==8,latex); + var len = frg.childNodes.length; + n.parentNode.replaceChild(frg,n); + return len-1; + } else return 0; + } + } + } else return 0; + } else if (n.nodeName!="math") { + for (i=0; i topOfWindow && + monitoredDOMElements[element].offset < bottomOfWindow) { + $(monitoredDOMElements[element].anchor).addClass("selected"); + $(".autotoc li").not(monitoredDOMElements[element].anchor).removeClass("selected"); + break; + } + } + }); + + + // Default settings + var settings = $.extend({ + toc: "#toc" + },options); + + var toc = $('
    '); + + $(settings.toc).append(toc); + + return this.each(function() { + tocEntry = $('
  • ' + $(this).html() + '
  • '); + tocEntry.data("parentHeading",this); + tocEntry.on("click", function() { + $('html, body').animate({ + scrollTop: $($(this).data("parentHeading")).offset().top - (windowHeight * .2) + }, 750 ); + }); + + $(".autotoc").append(tocEntry); + + monitoredDOMElements.push({ + offset: $(this).offset().top, + anchor: tocEntry + }); + }); + } +}); \ No newline at end of file diff --git a/docs/_site/spec/00.00.00.title.html b/docs/_site/spec/00.00.00.title.html new file mode 100644 index 0000000..3b73c4f --- /dev/null +++ b/docs/_site/spec/00.00.00.title.html @@ -0,0 +1,2 @@ + +

    {{ page.title }}

    diff --git a/docs/_site/spec/00.00.00.title.md b/docs/_site/spec/00.00.00.title.md new file mode 100644 index 0000000..fffa716 --- /dev/null +++ b/docs/_site/spec/00.00.00.title.md @@ -0,0 +1,3 @@ + +# {{ page.title }} +{:.no_toc} diff --git a/docs/_site/spec/00.00.01.version.html b/docs/_site/spec/00.00.01.version.html new file mode 100644 index 0000000..ecfa653 --- /dev/null +++ b/docs/_site/spec/00.00.01.version.html @@ -0,0 +1,3 @@ + +

    __
    +__

    diff --git a/docs/_site/spec/00.00.01.version.md b/docs/_site/spec/00.00.01.version.md new file mode 100644 index 0000000..1796d22 --- /dev/null +++ b/docs/_site/spec/00.00.01.version.md @@ -0,0 +1,3 @@ + +_{{ page.version }}_ +_{{ page.version_date }}_ diff --git a/docs/_site/spec/00.00.02.authors.html b/docs/_site/spec/00.00.02.authors.html new file mode 100644 index 0000000..289d69f --- /dev/null +++ b/docs/_site/spec/00.00.02.authors.html @@ -0,0 +1,4 @@ + +

    Frank Galligan, Google
    +[author]
    +[author]

    diff --git a/docs/_site/spec/00.00.02.authors.md b/docs/_site/spec/00.00.02.authors.md new file mode 100644 index 0000000..2cf7726 --- /dev/null +++ b/docs/_site/spec/00.00.02.authors.md @@ -0,0 +1,4 @@ + +_Frank Galligan, Google +\[author] +\[author]_ diff --git a/docs/_site/spec/00.00.03.last.modified.html b/docs/_site/spec/00.00.03.last.modified.html new file mode 100644 index 0000000..124fa6d --- /dev/null +++ b/docs/_site/spec/00.00.03.last.modified.html @@ -0,0 +1,2 @@ + +

    Last modified: 2017-07-09 18:30:06 -0700

    diff --git a/docs/_site/spec/00.00.03.last.modified.md b/docs/_site/spec/00.00.03.last.modified.md new file mode 100644 index 0000000..092b08c --- /dev/null +++ b/docs/_site/spec/00.00.03.last.modified.md @@ -0,0 +1,2 @@ + +_Last modified: {{ site.time }}_ diff --git a/docs/_site/spec/00.00.04.abstract.html b/docs/_site/spec/00.00.04.abstract.html new file mode 100644 index 0000000..595ec74 --- /dev/null +++ b/docs/_site/spec/00.00.04.abstract.html @@ -0,0 +1,5 @@ + +

    Abstract

    + +

    This document defines the bitstream format and decoding process for the +Draco 3D Data Compression scheme.

    diff --git a/docs/_site/spec/00.00.04.abstract.md b/docs/_site/spec/00.00.04.abstract.md new file mode 100644 index 0000000..2fc4a46 --- /dev/null +++ b/docs/_site/spec/00.00.04.abstract.md @@ -0,0 +1,6 @@ + +## Abstract +{:.no_toc .nocount} + +This document defines the bitstream format and decoding process for the +Draco 3D Data Compression scheme. diff --git a/docs/_site/spec/00.00.05.toc.html b/docs/_site/spec/00.00.05.toc.html new file mode 100644 index 0000000..09409a6 --- /dev/null +++ b/docs/_site/spec/00.00.05.toc.html @@ -0,0 +1,3 @@ + +

    Contents

    + diff --git a/docs/_site/spec/00.00.05.toc.md b/docs/_site/spec/00.00.05.toc.md new file mode 100644 index 0000000..9ce6baf --- /dev/null +++ b/docs/_site/spec/00.00.05.toc.md @@ -0,0 +1,5 @@ + +**Contents** + +* TOC +{:toc} diff --git a/docs/_site/spec/01.00.00.scope.html b/docs/_site/spec/01.00.00.scope.html new file mode 100644 index 0000000..d0e1a2e --- /dev/null +++ b/docs/_site/spec/01.00.00.scope.html @@ -0,0 +1,5 @@ + +

    Scope

    + +

    This document specifies the open-source Draco #D Data Compression bitstream +format and decoding process.

    diff --git a/docs/_site/spec/01.00.00.scope.md b/docs/_site/spec/01.00.00.scope.md new file mode 100644 index 0000000..d17eff9 --- /dev/null +++ b/docs/_site/spec/01.00.00.scope.md @@ -0,0 +1,5 @@ + +## Scope + +This document specifies the open-source Draco #D Data Compression bitstream +format and decoding process. diff --git a/docs/_site/spec/02.00.00.terms.html b/docs/_site/spec/02.00.00.terms.html new file mode 100644 index 0000000..2ecb3a9 --- /dev/null +++ b/docs/_site/spec/02.00.00.terms.html @@ -0,0 +1,19 @@ + +

    Terms and Definitions

    + +

    For the purposes of this document, the following terms and definitions apply:

    + + + + + + + + + + + + + + +
    TermDefinition
      
    diff --git a/docs/_site/spec/02.00.00.terms.md b/docs/_site/spec/02.00.00.terms.md new file mode 100644 index 0000000..cfca0dd --- /dev/null +++ b/docs/_site/spec/02.00.00.terms.md @@ -0,0 +1,8 @@ + +## Terms and Definitions + +For the purposes of this document, the following terms and definitions apply: + +| Term | Definition | +| ------- | ---------------- | +| | | diff --git a/docs/_site/spec/03.00.00.symbols.html b/docs/_site/spec/03.00.00.symbols.html new file mode 100644 index 0000000..550b9e4 --- /dev/null +++ b/docs/_site/spec/03.00.00.symbols.html @@ -0,0 +1,30 @@ + +

    Symbols (and abbreviated terms)

    + +

    DCT: Discrete Cosine Transform

    + +

    FIXME

    + +

    The specification makes use of a number of constant integers. Constants that +relate to the semantics of a particular syntax element are defined in section +7.

    + +

    Additional constants are defined below:

    + + + + + + + + + + + + + + + + +
    Symbol nameValueDescription
    SYMBOL  
    + diff --git a/docs/_site/spec/03.00.00.symbols.md b/docs/_site/spec/03.00.00.symbols.md new file mode 100644 index 0000000..58b42cf --- /dev/null +++ b/docs/_site/spec/03.00.00.symbols.md @@ -0,0 +1,18 @@ + +## Symbols (and abbreviated terms) + +**DCT:** Discrete Cosine Transform + +FIXME + +The specification makes use of a number of constant integers. Constants that +relate to the semantics of a particular syntax element are defined in section +7. + +Additional constants are defined below: + + +| Symbol name | Value | Description | +| ------------------------ |:-----:| ----------- | +| `SYMBOL` | | + diff --git a/docs/_site/spec/04.00.00.conventions.html b/docs/_site/spec/04.00.00.conventions.html new file mode 100644 index 0000000..80fc2b5 --- /dev/null +++ b/docs/_site/spec/04.00.00.conventions.html @@ -0,0 +1,42 @@ +

    Conventions

    + +
      +
    • +

      When bit reading is finished it will always pad the read to the current +byte.

      +
    • +
    • +

      Draco encoded mesh files are comprised of three main sections. This first +section is the header. The second section contains the connectivity data. +The third section contains the attribute data. The header must be decoded +first, then the connectivity section, and then the attribute section.

      +
    • +
    • +

      The Connectivity section is composed of the following sections in order:

      + +
        +
      • +

        Connectivity header

        +
      • +
      • +

        EdgeBreaker symbol buffer

        +
      • +
      • +

        Start face buffer

        +
      • +
      • +

        EdgeBreaker valence header

        +
      • +
      • +

        Context data for the valence prediction

        +
      • +
      • +

        Hole and Split data

        +
      • +
      +
    • +
    • +

      The hole and split data must be decoded before the EdgeBreaker symbols are +decoded.

      +
    • +
    diff --git a/docs/_site/spec/04.00.00.conventions.md b/docs/_site/spec/04.00.00.conventions.md new file mode 100644 index 0000000..767de7c --- /dev/null +++ b/docs/_site/spec/04.00.00.conventions.md @@ -0,0 +1,26 @@ +## Conventions + + * When bit reading is finished it will always pad the read to the current + byte. + + * Draco encoded mesh files are comprised of three main sections. This first + section is the header. The second section contains the connectivity data. + The third section contains the attribute data. The header must be decoded + first, then the connectivity section, and then the attribute section. + + * The Connectivity section is composed of the following sections in order: + + * Connectivity header + + * EdgeBreaker symbol buffer + + * Start face buffer + + * EdgeBreaker valence header + + * Context data for the valence prediction + + * Hole and Split data + + * The hole and split data must be decoded before the EdgeBreaker symbols are + decoded. diff --git a/docs/_site/spec/draco.decoder.html b/docs/_site/spec/draco.decoder.html new file mode 100644 index 0000000..114ff0c --- /dev/null +++ b/docs/_site/spec/draco.decoder.html @@ -0,0 +1,43 @@ +

    Draco Decoder

    + +

    Decode()

    + +
    +Decode() { Type + DecodeHeader() + DecodeConnectivityData() + DecodeAttributeData()} + +
    + +

    DecodeHeader()

    + +
    +DecodeHeader() { Type + draco_string UI8[5] + major_version UI8 + minor_version UI8 + encoder_type UI8 + encoder_method UI8 + flags +} + +
    + +

    DecodeAttributeData()

    + +
    +DecodeAttributeData() { Type + num_attributes_decoders UI8 + for (i = 0; i < num_attributes_decoders; ++i) { + CreateAttributesDecoder(i); + } + for (auto &att_dec : attributes_decoders_) { + att_dec->Initialize(this, point_cloud_) + } + for (i = 0; i < num_attributes_decoders; ++i) { + attributes_decoders_[i]->DecodeAttributesDecoderData(buffer_) + } + DecodeAllAttributes() + OnAttributesDecoded() +
    diff --git a/docs/_site/spec/draco.decoder.md b/docs/_site/spec/draco.decoder.md new file mode 100644 index 0000000..99c8096 --- /dev/null +++ b/docs/_site/spec/draco.decoder.md @@ -0,0 +1,45 @@ +## Draco Decoder + +### Decode() + +
    +Decode() { Type + DecodeHeader() + DecodeConnectivityData() + DecodeAttributeData()} + +
    + + +### DecodeHeader() + +
    +DecodeHeader() { Type + draco_string UI8[5] + major_version UI8 + minor_version UI8 + encoder_type UI8 + encoder_method UI8 + flags +} + +
    + + +### DecodeAttributeData() + +
    +DecodeAttributeData() { Type + num_attributes_decoders UI8 + for (i = 0; i < num_attributes_decoders; ++i) { + CreateAttributesDecoder(i); + } + for (auto &att_dec : attributes_decoders_) { + att_dec->Initialize(this, point_cloud_) + } + for (i = 0; i < num_attributes_decoders; ++i) { + attributes_decoders_[i]->DecodeAttributesDecoderData(buffer_) + } + DecodeAllAttributes() + OnAttributesDecoded() +
    diff --git a/docs/_site/spec/edgebreaker.decoder.html b/docs/_site/spec/edgebreaker.decoder.html new file mode 100644 index 0000000..d5a7db7 --- /dev/null +++ b/docs/_site/spec/edgebreaker.decoder.html @@ -0,0 +1,1556 @@ +

    EdgeBreaker Decoder

    + +

    InitializeDecoder()

    + +
    +InitializeDecoder() { Type + edgebreaker_decoder_type UI8 +} + +
    + +

    DecodeConnectivity()

    + +
    +DecodeConnectivity() { Type + num_new_verts UI32 + num_encoded_vertices UI32 + num_faces UI32 + num_attribute_data I8 + num_encoded_symbols UI32 + num_encoded_split_symbols UI32 + encoded_connectivity_size UI32 + // file pointer must be set to current position + encoded_connectivity_size + hole_and_split_bytes = DecodeHoleAndTopologySplitEvents() + // file pointer must be set to old current position + EdgeBreakerTraversalValence_Start() + DecodeConnectivity(num_symbols) + if (attribute_data_.size() > 0) { + for (ci = 0; ci < corner_table_->num_corners(); ci += 3) { + DecodeAttributeConnectivitiesOnFace(ci) + } + } + for (i = 0; i < corner_table_->num_vertices(); ++i) { + if (is_vert_hole_[i]) { + corner_table_->UpdateVertexToCornerMap(i); + } + } + // Decode attribute connectivity. + for (uint32_t i = 0; i < attribute_data_.size(); ++i) { + attribute_data_[i].connectivity_data.InitEmpty(corner_table_.get()); + for (int32_t c : attribute_data_[i].attribute_seam_corners) { + attribute_data_[i].connectivity_data.AddSeamEdge(c); + } + attribute_data_[i].connectivity_data.RecomputeVertices(nullptr, nullptr); + } + // Preallocate vertex to value mapping + AssignPointsToCorners() +} + +
    + +

    AssignPointsToCorners()

    + +
    +AssignPointsToCorners() { Type + decoder_->mesh()->SetNumFaces(corner_table_->num_faces()); + if (attribute_data_.size() == 0) { + for (f = 0; f < decoder_->mesh()->num_faces(); ++f) { + for (c = 0; c < 3; ++c) { + vert_id = corner_table_->Vertex(3 * f + c); + if (point_id == -1) + point_id = num_points++; + face[c] = point_id; + } + decoder_->mesh()->SetFace(f, face); + } + decoder_->point_cloud()->set_num_points(num_points); + Return true; + } + for (v = 0; v < corner_table_->num_vertices(); ++v) { + c = corner_table_->LeftMostCorner(v); + if (c < 0) + continue; + deduplication_first_corner = c; + if (!is_vert_hole_[v]) { + for (uint32_t i = 0; i < attribute_data_.size(); ++i) { + if (!attribute_data_[i].connectivity_data.IsCornerOnSeam(c)) + continue; + vert_id = attribute_data_[i].connectivity_data.Vertex(c); + act_c = corner_table_->SwingRight(c); + seam_found = false; + while (act_c != c) { + if (attribute_data_[i].connectivity_data.Vertex(act_c) != vert_id) { + deduplication_first_corner = act_c; + seam_found = true; + break; + } + act_c = corner_table_->SwingRight(act_c); + } + if (seam_found) + break; + } + } + c = deduplication_first_corner; + corner_to_point_map[c] = point_to_corner_map.size(); + point_to_corner_map.push_back(c); + prev_c = c; + c = corner_table_->SwingRight(c); + while (c >= 0 && c != deduplication_first_corner) { + attribute_seam = false; + for (uint32_t i = 0; i < attribute_data_.size(); ++i) { + if (attribute_data_[i].connectivity_data.Vertex(c) != + attribute_data_[i].connectivity_data.Vertex(prev_c)) { + attribute_seam = true; + break; + } + } + if (attribute_seam) { + corner_to_point_map[c] = point_to_corner_map.size(); + point_to_corner_map.push_back(c); + } else { + corner_to_point_map[c] = corner_to_point_map[prev_c]; + } + prev_c = c; + c = corner_table_->SwingRight(c); + } + } + for (f = 0; f < decoder_->mesh()->num_faces(); ++f) { + for (c = 0; c < 3; ++c) { + face[c] = corner_to_point_map[3 * f + c]; + } + decoder_->mesh()->SetFace(f, face); + } + decoder_->point_cloud()->set_num_points(point_to_corner_map.size()); +} + +
    + +

    DecodeConnectivity()

    + +
    +DecodeConnectivity(num_symbols) { Type + for (i = 0; i < num_symbols; ++i) { + symbol = TraversalValence_DecodeSymbol() + corner = 3 * num_faces++ + if (symbol == TOPOLOGY_C) { + vertex_x = UpdateCornerTableForSymbolC() + is_vert_hole_[vertex_x] = false; + } else if (symbol == TOPOLOGY_R || symbol == TOPOLOGY_L) { + UpdateCornerTableForSymbolLR() + check_topology_split = true; + } else if (symbol == TOPOLOGY_S) { + HandleSymbolS() + } else if (symbol == TOPOLOGY_E) { + UpdateCornerTableForSymbolE() + check_topology_split = true; + } + active_corner_stack.back() = corner; + traversal_decoder_.NewActiveCornerReached(corner); + if (check_topology_split) { + encoder_symbol_id = num_symbols - symbol_id - 1; + while (true) { + split = IsTopologySplit(encoder_symbol_id, &split_edge, + &encoder_split_symbol_id); + if (!split) { + break; + } + act_top_corner = corner; + if (split_edge == RIGHT_FACE_EDGE) { + new_active_corner = corner_table_->Next(act_top_corner); + } else { + new_active_corner = corner_table_->Previous(act_top_corner); + } + decoder_split_symbol_id = num_symbols - encoder_split_symbol_id - 1; + topology_split_active_corners[decoder_split_symbol_id] = + new_active_corner; + } + } + } + while (active_corner_stack.size() > 0) { + corner = active_corner_stack.pop_back(); + interior_face = traversal_decoder_.DecodeStartFaceConfiguration(); + if (interior_face == true) { + UpdateCornerTableForInteriorFace() + for (ci = 0; ci < 3; ++ci) { + is_vert_hole_[corner_table_->Vertex(new_corner + ci)] = false; + } + init_face_configurations_.push_back(true); + init_corners_.push_back(new_corner); + } else { + init_face_configurations_.push_back(false); + init_corners_.push_back(corner); + } + } + Return num_vertices; +} + +
    + +

    UpdateCornerTableForSymbolC()

    + +
    +UpdateCornerTableForSymbolC(corner) { Type + corner_a = active_corner_stack.back(); + corner_b = corner_table_->Previous(corner_a); + while (corner_table_->Opposite(corner_b) >= 0) { + corner_b = corner_table_->Previous(corner_table_->Opposite(corner_b)); + } + SetOppositeCorners(corner_a, corner + 1); + SetOppositeCorners(corner_b, corner + 2); + vertex_x = corner_table_->Vertex(corner_table_->Next(corner_a)); + corner_table_->MapCornerToVertex(corner, vertex_x); + corner_table_->MapCornerToVertex( + corner + 1, corner_table_->Vertex(corner_table_->Next(corner_b))); + corner_table_->MapCornerToVertex( + corner + 2, corner_table_->Vertex(corner_table_->Previous(corner_a))); + return vertex_x; +} + +
    + +

    UpdateCornerTableForSymbolLR()

    + +
    +UpdateCornerTableForSymbolLR(corner, symbol) { Type + if (symbol == TOPOLOGY_R) { + opp_corner = corner + 2; + } else { + opp_corner = corner + 1; + } + SetOppositeCorners(opp_corner, corner_a); + corner_table_->MapCornerToVertex(opp_corner,num_vertices++); + corner_table_->MapCornerToVertex( + corner_table_->Next(opp_corner), + corner_table_->Vertex(corner_table_->Previous(corner_a))); + corner_table_->MapCornerToVertex( + corner_table_->Previous(opp_corner), + corner_table_->Vertex(corner_table_->Next(corner_a))); +} + +
    + +

    HandleSymbolS()

    + +
    +HandleSymbolS(corner) { Type + corner_b = active_corner_stack.pop_back(); + it = topology_split_active_corners.find(symbol_id); + if (it != topology_split_active_corners.end()) { + active_corner_stack.push_back(it->second); + } + corner_a = active_corner_stack.back(); + SetOppositeCorners(corner_a, corner + 2); + SetOppositeCorners(corner_b, corner + 1); + vertex_p = corner_table_->Vertex(corner_table_->Previous(corner_a)); + corner_table_->MapCornerToVertex(corner, vertex_p); + corner_table_->MapCornerToVertex( + corner + 1, corner_table_->Vertex(corner_table_->Next(corner_a))); + corner_table_->MapCornerToVertex(corner + 2, + corner_table_->Vertex(corner_table_->Previous(corner_b))); + corner_n = corner_table_->Next(corner_b); + vertex_n = corner_table_->Vertex(corner_n); + traversal_decoder_.MergeVertices(vertex_p, vertex_n); + // TraversalValence_MergeVertices + while (corner_n >= 0) { + corner_table_->MapCornerToVertex(corner_n, vertex_p); + corner_n = corner_table_->SwingLeft(corner_n); + } + corner_table_->MakeVertexIsolated(vertex_n); +} + +
    + +

    UpdateCornerTableForSymbolE()

    + +
    +UpdateCornerTableForSymbolE() { Type + corner_table_->MapCornerToVertex(corner, num_vertices++); + corner_table_->MapCornerToVertex(corner + 1, num_vertices++); + corner_table_->MapCornerToVertex(corner + 2, num_vertices++); +} + +
    + +

    UpdateCornerTableForInteriorFace()

    + +
    +UpdateCornerTableForInteriorFace() { Type + corner_b = corner_table_->Previous(corner); + while (corner_table_->Opposite(corner_b) >= 0) { + corner_b = corner_table_->Previous(corner_table_->Opposite(corner_b)); + } + corner_c = corner_table_->Next(corner); + while (corner_table_->Opposite(corner_c) >= 0) { + corner_c = corner_table_->Next(corner_table_->Opposite(corner_c)); + } + face(num_faces++); + corner_table_->MapCornerToVertex( + new_corner, corner_table_->Vertex(corner_table_->Next(corner_b))); + corner_table_->MapCornerToVertex( + new_corner + 1, corner_table_->Vertex(corner_table_->Next(corner_c))); + corner_table_->MapCornerToVertex( + new_corner + 2, corner_table_->Vertex(corner_table_->Next(corner))); +} + +
    + +

    IsTopologySplit()

    + +
    +IsTopologySplit(encoder_symbol_id, *out_face_edge, Type + + *out_encoder_split_symbol_id) { + if (topology_split_data_.size() == 0) + return false; + if (topology_split_data_.back().source_symbol_id != encoder_symbol_id) + return false; + *out_face_edge = topology_split_data_.back().source_edge; + *out_encoder_split_symbol_id = + topology_split_data_.back().split_symbol_id; + topology_split_data_.pop_back(); + return true; +} + +
    + +

    DecodeAttributeConnectivitiesOnFace()

    + +
    +DecodeAttributeConnectivitiesOnFace(corner) { Type + corners[3] = {corner, corner_table_->Next(corner), + corner_table_->Previous(corner)} + for (c = 0; c < 3; ++c) { + opp_corner = corner_table_->Opposite(corners[c]); + if (opp_corner < 0) { + for (uint32_t i = 0; i < attribute_data_.size(); ++i) { + attribute_data_[i].attribute_seam_corners.push_back(corners[c]); + } + continue + } + for (uint32_t i = 0; i < attribute_data_.size(); ++i) { + bool is_seam = traversal_decoder_.DecodeAttributeSeam(i); + if (is_seam) { + attribute_data_[i].attribute_seam_corners.push_back(corners[c]); + } + } + } +} + +
    + +

    SetOppositeCorners()

    + +
    +SetOppositeCorners(corner_0, corner_1) { Type + corner_table_->SetOppositeCorner(corner_0, corner_1); + corner_table_->SetOppositeCorner(corner_1, corner_0); +} + +
    + +

    EdgeBreaker Hole and Topology Split Events

    + +

    DecodeHoleAndTopologySplitEvents()

    + +

    FIXME: Escaping angle brackets

    + +
    +DecodeHoleAndTopologySplitEvents() { Type + num_topologoy_splits UI32 + source_symbol_id = 0 + for (i = 0; i < num_topologoy_splits; ++i) { + DecodeVarint\<UI32\>(&delta) + split_data[i].source_symbol_id = delta + source_symbol_id + DecodeVarint\<UI32\>(&delta) + split_data[i].split_symbol_id = source_symbol_id - delta + } + for (i = 0; i < num_topologoy_splits; ++i) { + split_data[i].split_edge bits1 + split_data[i].source_edge bits1 + } + num_hole_events UI32 + symbol_id = 0 + for (i = 0; i < num_hole_events; ++i) { + DecodeVarint\<UI32\>(&delta) + hole_data[i].symbol_id = delta + symbol_id + } + return bytes_decoded; +} + +
    + +

    CreateAttributesDecoder

    + +

    FIXME: Escaping angle brackets

    + +
    +CreateAttributesDecoder() { Type + att_data_id I8 + decoder_type UI8 + if (att_data_id >= 0) { + attribute_data_[att_data_id].decoder_id = att_decoder_id; + } + traversal_method_encoded UI8 + if (decoder_type == MESH_VERTEX_ATTRIBUTE) { + if (att_data_id < 0) { + encoding_data = &pos_encoding_data_; + } else { + encoding_data = &attribute_data_[att_data_id].encoding_data; + attribute_data_[att_data_id].is_connectivity_used = false; + } + if (traversal_method == MESH_TRAVERSAL_DEPTH_FIRST) { + typedef EdgeBreakerTraverser\<AttProcessor, AttObserver\> AttTraverser; + sequencer = CreateVertexTraversalSequencer\<AttTraverser\>(encoding_data); + } else if (traversal_method == MESH_TRAVERSAL_PREDICTION_DEGREE) { + typedef PredictionDegreeTraverser\<AttProcessor, AttObserver\> AttTraverser; + sequencer = CreateVertexTraversalSequencer\<AttTraverser\>(encoding_data); + } + } else { + // TODO + } + att_controller(new SequentialAttributeDecodersController(std::move(sequencer))) + decoder_->SetAttributesDecoder(att_decoder_id, std::move(att_controller)); +} + +
    + +

    Edgebreaker Traversal Decoder

    + +

    EdgebreakerTraversal_Start()

    + +
    +EdgebreakerTraversal_Start() { Type + size UI64 + symbol_buffer_ size * UI8 + size UI64 + start_face_buffer_ size * UI8 + if (num_attribute_data_ > 0) { + attribute_connectivity_decoders_ = std::unique_ptr<BinaryDecoder[]>( + new BinaryDecoder[num_attribute_data_]); + for (i = 0; i < num_attribute_data_; ++i) { + attribute_connectivity_decoders_[i].StartDecoding() + // RansBitDecoder_StartDecoding + } +} + +
    + +

    Traversal_DecodeSymbol()

    + +
    Traversal_DecodeSymbol() {
    +  symbol_buffer_.DecodeLeastSignificantBits32(1, &symbol);                   bits1
    +  if (symbol != TOPOLOGY_C) {
    +    symbol_buffer_.DecodeLeastSignificantBits32(2, &symbol_suffix);          bits2
    +    symbol |= (symbol_suffix << 1);
    +  }
    +  return symbol
    +}
    +
    +
    + +

    DecodeAttributeSeam()

    + +
    DecodeAttributeSeam(int attribute) {
    +  return attribute_connectivity_decoders_[attribute].DecodeNextBit();
    +}
    +
    +
    + +

    EdgeBreaker Traversal Valence Decoder

    + +

    EdgeBreakerTraversalValence_Start()

    + +
    EdgeBreakerTraversalValence_Start(num_vertices, num_attribute_data) {
    +  out_buffer = EdgebreakerTraversal_Start()
    +  num_split_symbols                                                          I32
    +  mode == 0                                                                  I8
    +  num_vertices_ += num_split_symbols
    +  vertex_valences_ init to 0
    +  vertex_valences_.resize(num_vertices_, 0);
    +  min_valence_ = 2;
    +  max_valence_ = 7;
    +  num_unique_valences = 6 (max_valence_ - min_valence_ + 1)
    +  for (i = 0; i < num_unique_valences; ++i) {
    +    DecodeVarint<UI32>(&num_symbols, out_buffer)
    +    If (num_symbols > 0) {
    +      DecodeSymbols(num_symbols, out_buffer, &context_symbols_[i])
    +    }
    +    context_counters_[i] = num_symbols
    +  }
    +  return out_buffer;
    +}
    +
    +
    + +

    TraversalValence_DecodeSymbol()

    + +
    TraversalValence_DecodeSymbol() {
    +  if (active_context_ != -1) {
    +    symbol_id  = context_symbols_[active_context_]
    +                                                      [--context_counters_[active_context_]]
    +    last_symbol_ = edge_breaker_symbol_to_topology_id[symbol_id]
    +  } else {
    +    last_symbol_ = Traversal_DecodeSymbol()
    +  }
    +  return last_symbol_
    +}
    +
    +
    + +

    TraversalValence_NewActiveCornerReached()

    + +
    TraversalValence_NewActiveCornerReached(corner) {
    +  switch (last_symbol_) {
    +    case TOPOLOGY_C:
    +    case TOPOLOGY_S:
    +      vertex_valences_[ct(next)] += 1;
    +      vertex_valences_[ct(prev)] += 1;
    +      break;
    +    case TOPOLOGY_R:
    +      vertex_valences_[corner] += 1;
    +      vertex_valences_[ct(next)] += 1;
    +      vertex_valences_[ct(prev)] += 2;
    +      break;
    +    case TOPOLOGY_L:
    +      vertex_valences_[corner] += 1;
    +      vertex_valences_[ct(next)] += 2;
    +      vertex_valences_[ct(prev)] += 1;
    +      break;
    +    case TOPOLOGY_E:
    +      vertex_valences_[corner] += 2;
    +      vertex_valences_[ct(next)] += 2;
    +      vertex_valences_[ct(prev)] += 2;
    +      break;
    +  }
    +  valence = vertex_valences_[ct(next)]
    +  valence = max(valence, min_valence_)
    +  valence = min(valence, max_valence_)
    +  active_context_ = (valence - min_valence_);
    +}
    +
    +
    + +

    TraversalValence_MergeVertices()

    + +
    TraversalValence_MergeVertices(dest, source) {
    +  vertex_valences_[dest] += vertex_valences_[source];
    +}
    +
    +
    + +

    Attributes Decoder

    + +

    DecodeAttributesDecoderData()

    + +
    DecodeAttributesDecoderData(buffer) {
    +  num_attributes                                                             I32
    +  point_attribute_ids_.resize(num_attributes);
    +  for (i = 0; i < num_attributes; ++i) {
    +    att_type                                                                 UI8
    +    data_type                                                                UI8
    +    components_count                                                         UI8
    +    normalized                                                               UI8
    +    custom_id                                                                UI16
    +    Initialize GeometryAttribute ga
    +    att_id = pc->AddAttribute(new PointAttribute(ga));
    +    point_attribute_ids_[i] = att_id;
    +}
    +
    +
    + +

    Sequential Attributes Decoders Controller

    + +

    DecodeAttributesDecoderData()

    + +
    DecodeAttributesDecoderData(buffer) {
    +  AttributesDecoder_DecodeAttributesDecoderData(buffer)
    +  sequential_decoders_.resize(num_attributes());
    +  for (i = 0; i < num_attributes(); ++i) {
    +    decoder_type                                                             UI8
    +    sequential_decoders_[i] = CreateSequentialDecoder(decoder_type);
    +    sequential_decoders_[i]->Initialize(decoder(), GetAttributeId(i))
    +}
    +
    +
    + +

    DecodeAttributes()

    + +
    DecodeAttributes(buffer) {
    +  sequencer_->GenerateSequence(&point_ids_)
    +  for (i = 0; i < num_attributes(); ++i) {
    +    pa = decoder()->point_cloud()->attribute(GetAttributeId(i));
    +    sequencer_->UpdatePointToAttributeIndexMapping(pa)
    +  }
    +  for (i = 0; i < num_attributes(); ++i) {
    +    sequential_decoders_[i]->Decode(point_ids_, buffer)
    +    //SequentialAttributeDecoder_Decode()
    +  }
    +}
    +
    +
    + +

    CreateSequentialDecoder()

    + +
    CreateSequentialDecoder(type) {
    +  switch (type) {
    +    case SEQUENTIAL_ATTRIBUTE_ENCODER_GENERIC:
    +      return new SequentialAttributeDecoder()
    +    case SEQUENTIAL_ATTRIBUTE_ENCODER_INTEGER:
    +      return new SequentialIntegerAttributeDecoder()
    +    case SEQUENTIAL_ATTRIBUTE_ENCODER_QUANTIZATION:
    +      return new SequentialQuantizationAttributeDecoder()
    +    case SEQUENTIAL_ATTRIBUTE_ENCODER_NORMALS:
    +      return new SequentialNormalAttributeDecoder()
    +  }
    +}
    +
    +
    + +

    Sequential Attribute Decoder

    + +
    Initialize(...) {
    +  // Init some members
    +}
    +
    +
    + +

    DecodeValues()

    + +
    DecodeValues(const std::vector<PointIndex> &point_ids) {
    +  num_values = point_ids.size();
    +  entry_size = attribute_->byte_stride();
    +  std::unique_ptr<uint8_t[]> value_data_ptr(new uint8_t[entry_size]);
    +  out_byte_pos = 0;
    +  for (i = 0; i < num_values; ++i) {
    +   value_data                                                         UI8 * entry_size
    +    attribute_->buffer()->Write(out_byte_pos, value_data, entry_size);
    +    out_byte_pos += entry_size;
    +  }
    +}
    +
    +
    + +

    Sequential Integer Attribute Decoder

    + +
    Initialize(...) {
    +  SequentialAttributeDecoder_Initialize()
    +}
    +
    +
    + +

    DecodeValues()

    + +
    DecodeValues(point_ids) {
    +  prediction_scheme_method                                                   I8
    +  if (prediction_scheme_method != PREDICTION_NONE) {
    +    prediction_transform_type                                                I8
    +    prediction_scheme_ = CreateIntPredictionScheme(...)
    +  }
    +  if (prediction_scheme_) {
    +  }
    +  DecodeIntegerValues(point_ids)
    +  //SequentialQuantizationAttributeDecoder_DecodeIntegerValues()
    +  //StoreValues()
    +  DequantizeValues(num_values)
    +}
    +
    +
    + +

    DecodeIntegerValues()

    + +
    DecodeIntegerValues(point_ids) {
    +  compressed                                                                 UI8
    +  if (compressed) {
    +    DecodeSymbols(..., values_.data())
    +  } else {
    +  // TODO
    +  }
    +  if (!prediction_scheme_->AreCorrectionsPositive()) {
    +    ConvertSymbolsToSignedInts(...)
    +  }
    +  if (prediction_scheme_) {
    +    prediction_scheme_->DecodePredictionData(buffer)
    +    // DecodeTransformData(buffer)
    +    if (!values_.empty()) {
    +      prediction_scheme_->Decode(values_.data(), &values_[0],
    +                                      values_.size(), num_components, point_ids.data())
    +      // MeshPredictionSchemeParallelogram_Decode()
    +}
    +
    +
    + +

    Sequential Quantization Attribute Decoder

    + +
    Initialize(...) {
    +  SequentialIntegerAttributeDecoder_Initialize()
    +}
    +
    +
    + +

    DecodeIntegerValues()

    + +
    DecodeIntegerValues(point_ids) {
    +  // DecodeQuantizedDataInfo()
    +  num_components = attribute()->components_count();
    +  for (i = 0; i < num_components; ++i) {
    +    min_value_[i]                                                            F32
    +  }
    +  max_value_dif_                                                             F32
    +  quantization_bits_                                                         UI8
    +  SequentialIntegerAttributeDecoder::DecodeIntegerValues()
    +}
    +
    +
    + +

    DequantizeValues()

    + +
    DequantizeValues(num_values) {
    +  max_quantized_value = (1 << (quantization_bits_)) - 1;
    +  num_components = attribute()->components_count();
    +  entry_size = sizeof(float) * num_components;
    +  quant_val_id = 0;
    +  out_byte_pos = 0;
    +  for (i = 0; i < num_values; ++i) {
    +    for (c = 0; c < num_components; ++c) {
    +      value = dequantizer.DequantizeFloat(values()->at(quant_val_id++));
    +      value = value + min_value_[c];
    +      att_val[c] = value;
    +    }
    +    attribute()->buffer()->Write(out_byte_pos, att_val.get(), entry_size);
    +    out_byte_pos += entry_size;
    +  }
    +}
    +
    +
    + +

    Prediction Scheme Transform

    + +

    ComputeOriginalValue()

    + +
    ComputeOriginalValue(const DataTypeT *predicted_vals,
    +                                   const CorrTypeT *corr_vals,
    +                                   DataTypeT *out_original_vals, int val_id) {
    +  for (i = 0; i < num_components_; ++i) {
    +    out_original_vals[i] = predicted_vals[i] + corr_vals[val_id + i];
    +  }
    +}
    +
    +
    + +

    Prediction Scheme Wrap Transform

    + +

    DecodeTransformData()

    + +
    DecodeTransformData(buffer) {
    +  min_value_                                                                 DT
    +  max_value_                                                                 DT
    +}
    +
    +
    + +

    ComputeOriginalValue()

    + +
    ComputeOriginalValue(const DataTypeT *predicted_vals,
    +                                   const CorrTypeT *corr_vals,
    +                                   DataTypeT *out_original_vals, int val_id) {
    +  clamped_vals = ClampPredictedValue(predicted_vals);
    +  ComputeOriginalValue(clamped_vals, corr_vals, out_original_vals, val_id)
    +  // PredictionSchemeTransform_ComputeOriginalValue()
    +  for (i = 0; i < this->num_components(); ++i) {
    +    if (out_original_vals[i] > max_value_) {
    +      out_original_vals[i] -= max_dif_;
    +    } else if (out_original_vals[i] < min_value_) {
    +      out_original_vals[i] += max_dif_;
    +    }
    +}
    +
    +
    + +

    ClampPredictedValue()

    + +
    ClampPredictedValue(const DataTypeT *predicted_val) {
    +  for (i = 0; i < this->num_components(); ++i) {
    +    clamped_value_[i] = min(predicted_val[i], max_value_)
    +    clamped_value_[i] = max(predicted_val[i], min_value_)
    +  }
    +  return &clamped_value_[0];
    +}
    +
    +
    + +

    Mesh Prediction Scheme Parallelogram

    + +

    Decode()

    + +
    Decode(...) {
    +  this->transform().InitializeDecoding(num_components);
    +  // restore the first value
    +  this->transform().ComputeOriginalValue(pred_vals.get(),
    +                                       in_corr, out_data, 0);
    +  // PredictionSchemeWrapTransform_ComputeOriginalValue()
    +  corner_map_size = this->mesh_data().data_to_corner_map()->size();
    +  for (p = 1; p < corner_map_size; ++p) {
    +    corner_id = this->mesh_data().data_to_corner_map()->at(p);
    +    dst_offset = p * num_components;
    +    b= ComputeParallelogramPrediction(p, corner_id, table,
    +                                        *vertex_to_data_map, out_data,
    +                                        num_components, pred_vals.get())
    +    if (!b) {
    +      src_offset = (p - 1) * num_components;
    +      this->transform().ComputeOriginalValue(out_data + src_offset, in_corr,
    +                                             out_data + dst_offset, dst_offset);
    +      // PredictionSchemeWrapTransform_ComputeOriginalValue()
    +    } else {
    +      this->transform().ComputeOriginalValue(pred_vals.get(), in_corr,
    +                                             out_data + dst_offset, dst_offset);
    +      // PredictionSchemeWrapTransform_ComputeOriginalValue()
    +    }
    +  }
    +}
    +
    +
    + +

    MeshPredictionSchemeParallelogramShared

    + +

    ComputeParallelogramPrediction()

    + +
    ComputeParallelogramPrediction(...) {
    +  oci = table->Opposite(ci);
    +  vert_opp = vertex_to_data_map[table->Vertex(ci)];
    +  vert_next = vertex_to_data_map[table->Vertex(table->Next(ci))];
    +  vert_prev = vertex_to_data_map[table->Vertex(table->Previous(ci))];
    +  if (vert_opp < data_entry_id && vert_next < data_entry_id &&
    +      vert_prev < data_entry_id) {
    +    v_opp_off = vert_opp * num_components;
    +    v_next_off = vert_next * num_components;
    +    v_prev_off = vert_prev * num_components;
    +    for (c = 0; c < num_components; ++c) {
    +      out_prediction[c] = (in_data[v_next_off + c] + in_data[v_prev_off + c]) -
    +                          in_data[v_opp_off + c];
    +    }
    +    Return true;
    +  }
    +  return false;
    +}
    +
    +
    + +

    CornerTable Traversal Processor

    + +

    IsFaceVisited()

    + +
    IsFaceVisited(corner_id) {
    +  if (corner_id < 0)
    +    return true
    +  return is_face_visited_[corner_id / 3];
    +}
    +
    +
    + +

    MarkFaceVisited()

    + +
    MarkFaceVisited(face_id) {
    +  is_face_visited_[face_id] = true;
    +}
    +
    +
    + +

    IsVertexVisited()

    + +
    IsVertexVisited(vert_id) {
    +  return is_vertex_visited_[vert_id];
    +}
    +
    +
    + +

    MarkVertexVisited()

    + +
    MarkVertexVisited(vert_id) {
    +  is_vertex_visited_[vert_id] = true;
    +}
    +
    +
    + +

    Mesh Attribute Indices Encoding Observer

    + +

    OnNewVertexVisited()

    + +
    OnNewVertexVisited(vertex, corner) {
    +  point_id = mesh_->face(corner / 3)[corner % 3];
    +  sequencer_->AddPointId(point_id);
    +  // Keep track of visited corners.
    +  encoding_data_->encoded_attribute_value_index_to_corner_map.push_back(corner);
    +  encoding_data_
    +        ->vertex_to_encoded_attribute_value_index_map[vertex] =
    +        encoding_data_->num_values;
    +  encoding_data_->num_values++;
    +}
    +
    +
    + +

    EdgeBreaker Traverser

    + +

    TraverseFromCorner()

    + +
    TraverseFromCorner(corner_id) {
    +  if (processor_.IsFaceVisited(corner_id))
    +    return
    +  corner_traversal_stack_.clear();
    +  corner_traversal_stack_.push_back(corner_id);
    +  next_vert = corner_table_->Vertex(corner_table_->Next(corner_id));
    +  prev_vert = corner_table_->Vertex(corner_table_->Previous(corner_id));
    +  if (!processor_.IsVertexVisited(next_vert)) {
    +    processor_.MarkVertexVisited(next_vert);
    +    traversal_observer_.OnNewVertexVisited(next_vert,
    +                                        corner_table_->Next(corner_id));
    +  }
    +  if (!processor_.IsVertexVisited(prev_vert)) {
    +    processor_.MarkVertexVisited(prev_vert);
    +    traversal_observer_.OnNewVertexVisited(prev_vert,
    +                                        corner_table_->Previous(corner_id));
    +  }
    +  while (!corner_traversal_stack_.empty()) {
    +    corner_id = corner_traversal_stack_.back();
    +    face_id =corner_id / 3;
    +    if (processor_.IsFaceVisited(face_id)) {
    +      corner_traversal_stack_.pop_back();
    +      continue
    +    }
    +    while(true) {
    +      face_id = corner_id / 3;
    +      processor_.MarkFaceVisited(face_id);
    +      traversal_observer_.OnNewFaceVisited(face_id);
    +      vert_id = corner_table_->Vertex(corner_id);
    +      on_boundary = corner_table_->IsOnBoundary(vert_id);
    +      if (!processor_.IsVertexVisited(vert_id)) {
    +        processor_.MarkVertexVisited(vert_id);
    +        traversal_observer_.OnNewVertexVisited(vert_id, corner_id);
    +        if (!on_boundary) {
    +          corner_id = corner_table_->GetRightCorner(corner_id);
    +          continue;
    +        }
    +      }
    +      // The current vertex has been already visited or it was on a boundary.
    +      right_corner_id = corner_table_->GetRightCorner(corner_id);
    +      left_corner_id = corner_table_->GetLeftCorner(corner_id);
    +      right_face_id((right_corner_id < 0 ? -1 : right_corner_id / 3));
    +      left_face_id((left_corner_id < 0 ? -1 : left_corner_id / 3));
    +      if (processor_.IsFaceVisited(right_face_id)) {
    +        if (processor_.IsFaceVisited(left_face_id)) {
    +          corner_traversal_stack_.pop_back();
    +          break; // Break from while(true) loop
    +        } else {
    +          corner_id = left_corner_id;
    +        }
    +      } else {
    +        if (processor_.IsFaceVisited(left_face_id)) {
    +          corner_id = right_corner_id;
    +       } else {
    +          // Split the traversal.
    +          corner_traversal_stack_.back() = left_corner_id;
    +          corner_traversal_stack_.push_back(right_corner_id);
    +          break; // Break from while(true) loop
    +        }
    +      }
    +    }
    +  }
    +}
    +
    +
    + +

    Mesh Traversal Sequencer

    + +

    GenerateSequenceInternal()

    + +
    GenerateSequenceInternal() {
    +  traverser_.OnTraversalStart();
    +   If (corner_order_) {
    +    // TODO
    +  } else {
    +    int32_t num_faces = traverser_.corner_table()->num_faces();
    +    for (i = 0; i < num_faces; ++i) {
    +      ProcessCorner(3 * i)
    +    }
    +  }
    +  traverser_.OnTraversalEnd();
    +}
    +
    +
    + +

    ProcessCorner()

    + +
    ProcessCorner(corner_id) {
    +  traverser_.TraverseFromCorner(corner_id);
    +}
    +
    +
    + +

    UpdatePointToAttributeIndexMapping()

    + +
    UpdatePointToAttributeIndexMapping(PointAttribute *attribute) {
    +  corner_table = traverser_.corner_table();
    +  attribute->SetExplicitMapping(mesh_->num_points());
    +  num_faces = mesh_->num_faces();
    +  num_points = mesh_->num_points();
    +  for (f = 0; f < num_faces; ++f) {
    +    face = mesh_->face(f);
    +    for (p = 0; p < 3; ++p) {
    +      point_id = face[p];
    +      vert_id = corner_table->Vertex(3 * f + p);
    +      att_entry_id(
    +            encoding_data_
    +                ->vertex_to_encoded_attribute_value_index_map[vert_id]);
    +      attribute->SetPointMapEntry(point_id, att_entry_id);
    +    }
    +  }
    +}
    +
    +
    + +

    PointsSequencer

    + +

    AddPointId()

    + +
    AddPointId(point_id) {
    +  out_point_ids_->push_back(point_id);
    +}
    +
    +
    + +

    Corner Table

    + +

    Opposite()

    + +
    Opposite(corner) {
    +  return opposite_corners_[corner];
    +}
    +
    +
    + +

    Next()

    + +
    Next(corner) {
    +  return LocalIndex(++corner) ? corner : corner - 3;
    +}
    +
    +
    + +

    Previous()

    + +
    Previous(corner) {
    +  return LocalIndex(corner) ? corner - 1 : corner + 2;
    +}
    +
    +
    + +

    Vertex()

    + +
    Vertex(corner) {
    +  faces_[Face(corner)][LocalIndex(corner)];
    +}
    +
    +
    + +

    Face()

    + +
    Face(corner) {
    +  return corner / 3;
    +}
    +
    +
    + +

    LocalIndex()

    + +
    LocalIndex(corner) {
    +  return corner % 3;
    +}
    +
    +
    + +

    num_vertices()

    + +
    num_vertices() {
    +  return vertex_corners_.size();
    +}
    +
    +
    + +

    num_corners()

    + +
    num_corners() {
    +  return faces_.size() * 3;
    +}
    +
    +
    + +

    num_faces()

    + +
    num_faces() {
    +  return faces_.size();
    +}
    +
    +
    + +

    bool IsOnBoundary()

    + +
    bool IsOnBoundary(vert) {
    +  corner = LeftMostCorner(vert);
    +  if (SwingLeft(corner) < 0)
    +    return true;
    +  return false;
    +}
    +
    +
    + +

    SwingRight()

    + +
    SwingRight(corner) {
    +  return Previous(Opposite(Previous(corner)));
    +}
    +
    +
    + +

    SwingLeft()

    + +
    SwingLeft(corner) {
    +  return Next(Opposite(Next(corner)));
    +}
    +
    +
    + +

    GetLeftCorner()

    + +
    GetLeftCorner(corner_id) {
    +  if (corner_id < 0)
    +     return kInvalidCornerIndex;
    +  return Opposite(Previous(corner_id));
    +}
    +
    +
    + +

    GetRightCorner()

    + +
    GetRightCorner(corner_id) {
    +  if (corner_id < 0)
    +     return kInvalidCornerIndex;
    +  return Opposite(Next(corner_id));
    +}
    +
    +
    + +

    SetOppositeCorner()

    + +
    SetOppositeCorner(corner_id, pp_corner_id) {
    +  opposite_corners_[corner_id] = opp_corner_id;
    +}
    +
    +
    + +

    MapCornerToVertex()

    + +
    MapCornerToVertex(corner_id, vert_id) {
    +  face = Face(corner_id);
    +  faces_[face][LocalIndex(corner_id)] = vert_id;
    +  if (vert_id >= 0) {
    +    vertex_corners_[vert_id] = corner_id;
    +  }
    +}
    +
    +
    + +

    UpdateVertexToCornerMap()

    + +
    UpdateVertexToCornerMap(vert) {
    +  first_c = vertex_corners_[vert];
    +  if (first_c < 0)
    +    return;
    +  act_c = SwingLeft(first_c);
    +  c = first_c;
    +  while (act_c >= 0 && act_c != first_c) {
    +    c = act_c;
    +    act_c = SwingLeft(act_c);
    +  }
    +  if (act_c != first_c) {
    +    vertex_corners_[vert] = c;
    +  }
    +}
    +
    +
    + +

    LeftMostCorner()

    + +
    LeftMostCorner(v) {
    +  return vertex_corners_[v];
    +}
    +
    +
    + +

    MakeVertexIsolated()

    + +
    MakeVertexIsolated(vert) {
    +  vertex_corners_[vert] = kInvalidCornerIndex;
    +}
    +
    +
    + +

    Mesh Attribute Corner Table

    + +

    bool IsCornerOnSeam()

    + +
    bool IsCornerOnSeam(corner) {
    +  return is_vertex_on_seam_[corner_table_->Vertex(corner)];
    +}
    +
    +
    + +

    AddSeamEdge()

    + +
    AddSeamEdge(c) {
    +  MarkSeam(c)
    +  opp_corner = corner_table_->Opposite(c);
    +  if (opp_corner >= 0) {
    +    no_interior_seams_ = false;
    +    MarkSeam(opp_corner)
    +  }
    +}
    +
    +
    + +

    MarkSeam()

    + +
    MarkSeam(c) {
    +  is_edge_on_seam_[c] = true;
    +  is_vertex_on_seam_[corner_table_->Vertex(corner_table_->Next(c))] = true;
    +  is_vertex_on_seam_[corner_table_->Vertex(corner_table_->Previous(c))
    +                         ] = true;
    +}
    +
    +
    + +

    RecomputeVertices()

    + +
    RecomputeVertices() {
    +  // in code RecomputeVerticesInternal<false>(nullptr, nullptr)
    +  num_new_vertices = 0;
    +  for (v = 0; v < corner_table_->num_vertices(); ++v) {
    +    c = corner_table_->LeftMostCorner(v);
    +    if (c < 0)
    +      continue;
    +    first_vert_id(num_new_vertices++);
    +    vertex_to_attribute_entry_id_map_.push_back(first_vert_id);
    +    first_c = c;
    +    if (is_vertex_on_seam_[v]) {
    +      act_c = SwingLeft(first_c);
    +      while (act_c >= 0) {
    +        first_c = act_c;
    +        act_c = SwingLeft(act_c);
    +      }
    +    }
    +    corner_to_vertex_map_[first_c] =first_vert_id;
    +    vertex_to_left_most_corner_map_.push_back(first_c);
    +    act_c = corner_table_->SwingRight(first_c);
    +    while (act_c >= 0 && act_c != first_c) {
    +      if (is_edge_on_seam_[corner_table_->Next(act_c)]) {
    +        // in code IsCornerOppositeToSeamEdge()
    +        first_vert_id = AttributeValueIndex(num_new_vertices++);
    +        vertex_to_attribute_entry_id_map_.push_back(first_vert_id);
    +        vertex_to_left_most_corner_map_.push_back(act_c);
    +      }
    +      corner_to_vertex_map_[act_c] = first_vert_id;
    +      act_c = corner_table_->SwingRight(act_c);
    +    }
    +  }
    +}
    +
    +
    + +

    Symbol Decoding

    + +

    DecodeSymbols()

    + +
    DecodeSymbols(num_symbols, out_buffer, out_values) {
    +  scheme                                                                     UI8
    +  If (scheme == 0) {
    +    DecodeTaggedSymbols<>(num_symbols, src_buffer, out_values)
    +  } else if (scheme == 1) {
    +    DecodeRawSymbols<>(num_symbols, src_buffer, out_values)
    +  }
    +}
    +
    +
    + +

    DecodeTaggedSymbols()

    + +
    DecodeTaggedSymbols() {
    +  FIXME
    +}
    +
    +
    + +

    DecodeRawSymbols()

    + +
    DecodeRawSymbols() {
    +  max_bit_length                                                             UI8
    +  DecodeRawSymbolsInternal(max_bit_length, out_values)
    +  return symbols
    +}
    +
    +
    + +

    DecodeRawSymbolsInternal()

    + +
    DecodeRawSymbolsInternal(max_bit_length, out_values) {
    +  decoder = CreateRansSymbolDecoder(max_bit_length)
    +  decoder.StartDecoding()
    +  // RansSymbolDecoder_StartDecoding
    +  for (i = 0; i < num_values; ++i) {
    +    out_values[i] = decoder.DecodeSymbol()
    +    // RansSymbolDecoder_DecodeSymbol
    +  }
    +}
    +
    +
    + +

    CreateRansSymbolDecoder()

    + +
    CreateRansSymbolDecoder(max_bit_length) {
    +  rans_precision_bits  = (3 * max_bit_length) / 2;
    +  rans_precision_bits = min(rans_precision_bits, 20)
    +  rans_precision_bits = max(rans_precision_bits, 12)
    +  rans_precision = 1 << rans_precision_bits_;
    +  l_rans_base = rans_precision * 4;
    +  num_symbols_                                                               UI32
    +  for (i = 0; i < num_symbols_; ++i) {
    +    prob_data                                                                UI8
    +    if ((prob_data & 3) == 3) {
    +      offset = prob_data >> 2
    +      for (j = 0; j < offset + 1; ++j) {
    +        probability_table_[i + j] = 0;
    +      }
    +      i += offset;
    +    } else {
    +      prob = prob_data >> 2
    +      for (j = 0; j < token; ++j) {
    +        eb                                                                   UI8
    +        prob = prob | (eb << (8 * (j + 1) - 2)
    +      }
    +      probability_table_[i] = prob;
    +    }
    +  }
    +  rans_build_look_up_table()
    +}
    +
    +
    + +

    RansSymbolDecoder_StartDecoding()

    + +
    RansSymbolDecoder_StartDecoding() {
    +  bytes_encoded                                                              UI64
    +  buffer                                                                     bytes_encoded * UI8
    +  rans_read_init(buffer, bytes_encoded)
    +}
    +
    +
    + +

    RansSymbolDecoder_DecodeSymbol()

    + +
    RansSymbolDecoder_DecodeSymbol() {
    +  ans_.rans_read()
    +}
    +
    +
    + +

    Rans Decoding

    + +

    ans_read_init()

    + +
    ans_read_init(struct AnsDecoder *const ans, const uint8_t *const buf,
    +                       int offset) {
    +  x = buf[offset - 1] >> 6
    +  If (x == 0) {
    +    ans->buf_offset = offset - 1;
    +    ans->state = buf[offset - 1] & 0x3F;
    +  } else if (x == 1) {
    +    ans->buf_offset = offset - 2;
    +    ans->state = mem_get_le16(buf + offset - 2) & 0x3FFF;
    +  } else if (x == 2) {
    +    ans->buf_offset = offset - 3;
    +    ans->state = mem_get_le24(buf + offset - 3) & 0x3FFFFF;
    +  } else if (x == 3) {
    +   // x == 3 implies this byte is a superframe marker
    +    return 1;
    +  }
    +  ans->state += l_base;
    +}
    +
    +
    + +

    int rabs_desc_read()

    + +
    int rabs_desc_read(struct AnsDecoder *ans, AnsP8 p0) {
    +  AnsP8 p = ans_p8_precision - p0;
    +  if (ans->state < l_base) {
    +    ans->state = ans->state * io_base + ans->buf[--ans->buf_offset];
    +  }
    +  x = ans->state;
    +  quot = x / ans_p8_precision;
    +  rem = x % ans_p8_precision;
    +  xn = quot * p;
    +  val = rem < p;
    +  if (val) {
    +    ans->state = xn + rem;
    +  } else {
    +    ans->state = x - xn - p;
    +  }
    +  return val;
    +}
    +
    +
    + +

    rans_read_init()

    + +
    rans_read_init(UI8 *buf, int offset) {
    +  ans_.buf = buf;
    +  x = buf[offset - 1] >> 6
    +  If (x == 0) {
    +    ans_.buf_offset = offset - 1;
    +    ans_.state = buf[offset - 1] & 0x3F;
    +  } else if (x == 1) {
    +    ans_.buf_offset = offset - 2;
    +    ans_.state = mem_get_le16(buf + offset - 2) & 0x3FFF;
    +  } else if (x == 2) {
    +    ans_.buf_offset = offset - 3;
    +    ans_.state = mem_get_le24(buf + offset - 3) & 0x3FFFFF;
    +  } else if (x == 3) {
    +    ans_.buf_offset = offset - 4;
    +    ans_.state = mem_get_le32(buf + offset - 4) & 0x3FFFFFFF;
    +  }
    +  ans_.state += l_rans_base;
    +}
    +
    +
    + +

    rans_build_look_up_table()

    + +
    rans_build_look_up_table() {
    +  cum_prob = 0
    +  act_prob = 0
    +  for (i = 0; i < num_symbols; ++i) {
    +    probability_table_[i].prob = token_probs[i];
    +    probability_table_[i].cum_prob = cum_prob;
    +    cum_prob += token_probs[i];
    +    for (j = act_prob; j < cum_prob; ++j) {
    +      Lut_table_[j] = i
    +    }
    +    act_prob = cum_prob
    +}
    +
    +
    + +

    rans_read()

    + +
    rans_read() {
    +  while (ans_.state < l_rans_base) {
    +    ans_.state = ans_.state * io_base + ans_.buf[--ans_.buf_offset];
    +  }
    +  quo = ans_.state / rans_precision;
    +  rem = ans_.state % rans_precision;
    +  sym = fetch_sym()
    +  ans_.state = quo * sym.prob + rem - sym.cum_prob;
    +  return sym.val;
    +}
    +
    +
    + +

    fetch_sym()

    + +
    fetch_sym() {
    +  symbol = lut_table[rem]
    +  out->val = symbol
    +  out->prob = probability_table_[symbol].prob;
    +  out->cum_prob = probability_table_[symbol].cum_prob;
    +}
    +
    +
    + +

    Rans Bit Decoder

    + +

    RansBitDecoder_StartDecoding()

    + +
    RansBitDecoder_StartDecoding(DecoderBuffer *source_buffer) {
    +  prob_zero_                                                                 UI8
    +  size                                                                       UI32
    +  buffer_                                                                    size * UI8
    +  ans_read_init(&ans_decoder_, buffer_, size)
    +}
    +
    +
    + +

    DecodeNextBit()

    + +
    DecodeNextBit() {
    +  uint8_t bit = rabs_desc_read(&ans_decoder_, prob_zero_);
    +  return bit > 0;
    +}
    +
    +
    + +

    Core Functions

    + +

    DecodeVarint

    + +
    DecodeVarint<IT>() {
    +  If (std::is_unsigned<IT>::value) {
    +    in                                                                       UI8
    +    If (in & (1 << 7)) {
    +      out = DecodeVarint<IT>()
    +      out = (out << 7) | (in & ((1 << 7) - 1))
    +    } else {
    +      typename std::make_unsigned<IT>::type UIT;
    +      out = DecodeVarint<UIT>()
    +      out = ConvertSymbolToSignedInt(out)
    +    }
    +    return out;
    +}
    +
    +
    + +

    ConvertSymbolToSignedInt()

    + +
    ConvertSymbolToSignedInt() {
    +  abs_val = val >> 1
    +  If (val & 1 == 0) {
    +    return abs_val
    +  } else {
    +    signed_val = -abs_val - 1
    +  }
    +  return signed_val
    +}
    +
    +
    + +

    Sequential Decoder

    + +

    decode_connectivity()

    + +
    decode_connectivity() {
    +  num_faces                                                       I32
    +  num_points                                                      I32
    +  connectivity _method                                            UI8
    +  If (connectivity _method == 0) {
    +    // TODO
    +  } else {
    +    loop num_faces {
    +      If (num_points < 256) {
    +        face[]                                                    UI8
    +      } else if (num_points < (1 << 16)) {
    +        face[]                                                    UI16
    +      } else {
    +        face[]                                                    UI32
    +      }
    +    }
    +  }
    +}
    +
    +
    diff --git a/docs/_site/spec/edgebreaker.decoder.md b/docs/_site/spec/edgebreaker.decoder.md new file mode 100644 index 0000000..495901e --- /dev/null +++ b/docs/_site/spec/edgebreaker.decoder.md @@ -0,0 +1,1674 @@ +## EdgeBreaker Decoder + +### InitializeDecoder() + +
    +InitializeDecoder() { Type + edgebreaker_decoder_type UI8 +} + +
    + + +### DecodeConnectivity() + +
    +DecodeConnectivity() { Type + num_new_verts UI32 + num_encoded_vertices UI32 + num_faces UI32 + num_attribute_data I8 + num_encoded_symbols UI32 + num_encoded_split_symbols UI32 + encoded_connectivity_size UI32 + // file pointer must be set to current position + encoded_connectivity_size + hole_and_split_bytes = DecodeHoleAndTopologySplitEvents() + // file pointer must be set to old current position + EdgeBreakerTraversalValence_Start() + DecodeConnectivity(num_symbols) + if (attribute_data_.size() > 0) { + for (ci = 0; ci < corner_table_->num_corners(); ci += 3) { + DecodeAttributeConnectivitiesOnFace(ci) + } + } + for (i = 0; i < corner_table_->num_vertices(); ++i) { + if (is_vert_hole_[i]) { + corner_table_->UpdateVertexToCornerMap(i); + } + } + // Decode attribute connectivity. + for (uint32_t i = 0; i < attribute_data_.size(); ++i) { + attribute_data_[i].connectivity_data.InitEmpty(corner_table_.get()); + for (int32_t c : attribute_data_[i].attribute_seam_corners) { + attribute_data_[i].connectivity_data.AddSeamEdge(c); + } + attribute_data_[i].connectivity_data.RecomputeVertices(nullptr, nullptr); + } + // Preallocate vertex to value mapping + AssignPointsToCorners() +} + +
    + + +### AssignPointsToCorners() + +
    +AssignPointsToCorners() { Type + decoder_->mesh()->SetNumFaces(corner_table_->num_faces()); + if (attribute_data_.size() == 0) { + for (f = 0; f < decoder_->mesh()->num_faces(); ++f) { + for (c = 0; c < 3; ++c) { + vert_id = corner_table_->Vertex(3 * f + c); + if (point_id == -1) + point_id = num_points++; + face[c] = point_id; + } + decoder_->mesh()->SetFace(f, face); + } + decoder_->point_cloud()->set_num_points(num_points); + Return true; + } + for (v = 0; v < corner_table_->num_vertices(); ++v) { + c = corner_table_->LeftMostCorner(v); + if (c < 0) + continue; + deduplication_first_corner = c; + if (!is_vert_hole_[v]) { + for (uint32_t i = 0; i < attribute_data_.size(); ++i) { + if (!attribute_data_[i].connectivity_data.IsCornerOnSeam(c)) + continue; + vert_id = attribute_data_[i].connectivity_data.Vertex(c); + act_c = corner_table_->SwingRight(c); + seam_found = false; + while (act_c != c) { + if (attribute_data_[i].connectivity_data.Vertex(act_c) != vert_id) { + deduplication_first_corner = act_c; + seam_found = true; + break; + } + act_c = corner_table_->SwingRight(act_c); + } + if (seam_found) + break; + } + } + c = deduplication_first_corner; + corner_to_point_map[c] = point_to_corner_map.size(); + point_to_corner_map.push_back(c); + prev_c = c; + c = corner_table_->SwingRight(c); + while (c >= 0 && c != deduplication_first_corner) { + attribute_seam = false; + for (uint32_t i = 0; i < attribute_data_.size(); ++i) { + if (attribute_data_[i].connectivity_data.Vertex(c) != + attribute_data_[i].connectivity_data.Vertex(prev_c)) { + attribute_seam = true; + break; + } + } + if (attribute_seam) { + corner_to_point_map[c] = point_to_corner_map.size(); + point_to_corner_map.push_back(c); + } else { + corner_to_point_map[c] = corner_to_point_map[prev_c]; + } + prev_c = c; + c = corner_table_->SwingRight(c); + } + } + for (f = 0; f < decoder_->mesh()->num_faces(); ++f) { + for (c = 0; c < 3; ++c) { + face[c] = corner_to_point_map[3 * f + c]; + } + decoder_->mesh()->SetFace(f, face); + } + decoder_->point_cloud()->set_num_points(point_to_corner_map.size()); +} + +
    + + +### DecodeConnectivity() + +
    +DecodeConnectivity(num_symbols) { Type + for (i = 0; i < num_symbols; ++i) { + symbol = TraversalValence_DecodeSymbol() + corner = 3 * num_faces++ + if (symbol == TOPOLOGY_C) { + vertex_x = UpdateCornerTableForSymbolC() + is_vert_hole_[vertex_x] = false; + } else if (symbol == TOPOLOGY_R || symbol == TOPOLOGY_L) { + UpdateCornerTableForSymbolLR() + check_topology_split = true; + } else if (symbol == TOPOLOGY_S) { + HandleSymbolS() + } else if (symbol == TOPOLOGY_E) { + UpdateCornerTableForSymbolE() + check_topology_split = true; + } + active_corner_stack.back() = corner; + traversal_decoder_.NewActiveCornerReached(corner); + if (check_topology_split) { + encoder_symbol_id = num_symbols - symbol_id - 1; + while (true) { + split = IsTopologySplit(encoder_symbol_id, &split_edge, + &encoder_split_symbol_id); + if (!split) { + break; + } + act_top_corner = corner; + if (split_edge == RIGHT_FACE_EDGE) { + new_active_corner = corner_table_->Next(act_top_corner); + } else { + new_active_corner = corner_table_->Previous(act_top_corner); + } + decoder_split_symbol_id = num_symbols - encoder_split_symbol_id - 1; + topology_split_active_corners[decoder_split_symbol_id] = + new_active_corner; + } + } + } + while (active_corner_stack.size() > 0) { + corner = active_corner_stack.pop_back(); + interior_face = traversal_decoder_.DecodeStartFaceConfiguration(); + if (interior_face == true) { + UpdateCornerTableForInteriorFace() + for (ci = 0; ci < 3; ++ci) { + is_vert_hole_[corner_table_->Vertex(new_corner + ci)] = false; + } + init_face_configurations_.push_back(true); + init_corners_.push_back(new_corner); + } else { + init_face_configurations_.push_back(false); + init_corners_.push_back(corner); + } + } + Return num_vertices; +} + +
    + + +### UpdateCornerTableForSymbolC() + +
    +UpdateCornerTableForSymbolC(corner) { Type + corner_a = active_corner_stack.back(); + corner_b = corner_table_->Previous(corner_a); + while (corner_table_->Opposite(corner_b) >= 0) { + corner_b = corner_table_->Previous(corner_table_->Opposite(corner_b)); + } + SetOppositeCorners(corner_a, corner + 1); + SetOppositeCorners(corner_b, corner + 2); + vertex_x = corner_table_->Vertex(corner_table_->Next(corner_a)); + corner_table_->MapCornerToVertex(corner, vertex_x); + corner_table_->MapCornerToVertex( + corner + 1, corner_table_->Vertex(corner_table_->Next(corner_b))); + corner_table_->MapCornerToVertex( + corner + 2, corner_table_->Vertex(corner_table_->Previous(corner_a))); + return vertex_x; +} + +
    + + + +### UpdateCornerTableForSymbolLR() + +
    +UpdateCornerTableForSymbolLR(corner, symbol) { Type + if (symbol == TOPOLOGY_R) { + opp_corner = corner + 2; + } else { + opp_corner = corner + 1; + } + SetOppositeCorners(opp_corner, corner_a); + corner_table_->MapCornerToVertex(opp_corner,num_vertices++); + corner_table_->MapCornerToVertex( + corner_table_->Next(opp_corner), + corner_table_->Vertex(corner_table_->Previous(corner_a))); + corner_table_->MapCornerToVertex( + corner_table_->Previous(opp_corner), + corner_table_->Vertex(corner_table_->Next(corner_a))); +} + +
    + + +### HandleSymbolS() + +
    +HandleSymbolS(corner) { Type + corner_b = active_corner_stack.pop_back(); + it = topology_split_active_corners.find(symbol_id); + if (it != topology_split_active_corners.end()) { + active_corner_stack.push_back(it->second); + } + corner_a = active_corner_stack.back(); + SetOppositeCorners(corner_a, corner + 2); + SetOppositeCorners(corner_b, corner + 1); + vertex_p = corner_table_->Vertex(corner_table_->Previous(corner_a)); + corner_table_->MapCornerToVertex(corner, vertex_p); + corner_table_->MapCornerToVertex( + corner + 1, corner_table_->Vertex(corner_table_->Next(corner_a))); + corner_table_->MapCornerToVertex(corner + 2, + corner_table_->Vertex(corner_table_->Previous(corner_b))); + corner_n = corner_table_->Next(corner_b); + vertex_n = corner_table_->Vertex(corner_n); + traversal_decoder_.MergeVertices(vertex_p, vertex_n); + // TraversalValence_MergeVertices + while (corner_n >= 0) { + corner_table_->MapCornerToVertex(corner_n, vertex_p); + corner_n = corner_table_->SwingLeft(corner_n); + } + corner_table_->MakeVertexIsolated(vertex_n); +} + +
    + + +### UpdateCornerTableForSymbolE() + +
    +UpdateCornerTableForSymbolE() { Type + corner_table_->MapCornerToVertex(corner, num_vertices++); + corner_table_->MapCornerToVertex(corner + 1, num_vertices++); + corner_table_->MapCornerToVertex(corner + 2, num_vertices++); +} + +
    + + +### UpdateCornerTableForInteriorFace() + +
    +UpdateCornerTableForInteriorFace() { Type + corner_b = corner_table_->Previous(corner); + while (corner_table_->Opposite(corner_b) >= 0) { + corner_b = corner_table_->Previous(corner_table_->Opposite(corner_b)); + } + corner_c = corner_table_->Next(corner); + while (corner_table_->Opposite(corner_c) >= 0) { + corner_c = corner_table_->Next(corner_table_->Opposite(corner_c)); + } + face(num_faces++); + corner_table_->MapCornerToVertex( + new_corner, corner_table_->Vertex(corner_table_->Next(corner_b))); + corner_table_->MapCornerToVertex( + new_corner + 1, corner_table_->Vertex(corner_table_->Next(corner_c))); + corner_table_->MapCornerToVertex( + new_corner + 2, corner_table_->Vertex(corner_table_->Next(corner))); +} + +
    + + +### IsTopologySplit() + +
    +IsTopologySplit(encoder_symbol_id, *out_face_edge, Type + + *out_encoder_split_symbol_id) { + if (topology_split_data_.size() == 0) + return false; + if (topology_split_data_.back().source_symbol_id != encoder_symbol_id) + return false; + *out_face_edge = topology_split_data_.back().source_edge; + *out_encoder_split_symbol_id = + topology_split_data_.back().split_symbol_id; + topology_split_data_.pop_back(); + return true; +} + +
    + + +### DecodeAttributeConnectivitiesOnFace() + +
    +DecodeAttributeConnectivitiesOnFace(corner) { Type + corners[3] = {corner, corner_table_->Next(corner), + corner_table_->Previous(corner)} + for (c = 0; c < 3; ++c) { + opp_corner = corner_table_->Opposite(corners[c]); + if (opp_corner < 0) { + for (uint32_t i = 0; i < attribute_data_.size(); ++i) { + attribute_data_[i].attribute_seam_corners.push_back(corners[c]); + } + continue + } + for (uint32_t i = 0; i < attribute_data_.size(); ++i) { + bool is_seam = traversal_decoder_.DecodeAttributeSeam(i); + if (is_seam) { + attribute_data_[i].attribute_seam_corners.push_back(corners[c]); + } + } + } +} + +
    + + +### SetOppositeCorners() + +
    +SetOppositeCorners(corner_0, corner_1) { Type + corner_table_->SetOppositeCorner(corner_0, corner_1); + corner_table_->SetOppositeCorner(corner_1, corner_0); +} + +
    + + +## EdgeBreaker Hole and Topology Split Events + +### DecodeHoleAndTopologySplitEvents() + +FIXME: Escaping angle brackets + +
    +DecodeHoleAndTopologySplitEvents() { Type + num_topologoy_splits UI32 + source_symbol_id = 0 + for (i = 0; i < num_topologoy_splits; ++i) { + DecodeVarint\(&delta) + split_data[i].source_symbol_id = delta + source_symbol_id + DecodeVarint\(&delta) + split_data[i].split_symbol_id = source_symbol_id - delta + } + for (i = 0; i < num_topologoy_splits; ++i) { + split_data[i].split_edge bits1 + split_data[i].source_edge bits1 + } + num_hole_events UI32 + symbol_id = 0 + for (i = 0; i < num_hole_events; ++i) { + DecodeVarint\(&delta) + hole_data[i].symbol_id = delta + symbol_id + } + return bytes_decoded; +} + +
    + +### CreateAttributesDecoder + +FIXME: Escaping angle brackets + +
    +CreateAttributesDecoder() { Type + att_data_id I8 + decoder_type UI8 + if (att_data_id >= 0) { + attribute_data_[att_data_id].decoder_id = att_decoder_id; + } + traversal_method_encoded UI8 + if (decoder_type == MESH_VERTEX_ATTRIBUTE) { + if (att_data_id < 0) { + encoding_data = &pos_encoding_data_; + } else { + encoding_data = &attribute_data_[att_data_id].encoding_data; + attribute_data_[att_data_id].is_connectivity_used = false; + } + if (traversal_method == MESH_TRAVERSAL_DEPTH_FIRST) { + typedef EdgeBreakerTraverser\ AttTraverser; + sequencer = CreateVertexTraversalSequencer\(encoding_data); + } else if (traversal_method == MESH_TRAVERSAL_PREDICTION_DEGREE) { + typedef PredictionDegreeTraverser\ AttTraverser; + sequencer = CreateVertexTraversalSequencer\(encoding_data); + } + } else { + // TODO + } + att_controller(new SequentialAttributeDecodersController(std::move(sequencer))) + decoder_->SetAttributesDecoder(att_decoder_id, std::move(att_controller)); +} + +
    + + +## Edgebreaker Traversal Decoder + +### EdgebreakerTraversal_Start() + +
    +EdgebreakerTraversal_Start() { Type + size UI64 + symbol_buffer_ size * UI8 + size UI64 + start_face_buffer_ size * UI8 + if (num_attribute_data_ > 0) { + attribute_connectivity_decoders_ = std::unique_ptr( + new BinaryDecoder[num_attribute_data_]); + for (i = 0; i < num_attribute_data_; ++i) { + attribute_connectivity_decoders_[i].StartDecoding() + // RansBitDecoder_StartDecoding + } +} + +
    + + +### Traversal_DecodeSymbol() + +~~~~~ +Traversal_DecodeSymbol() { + symbol_buffer_.DecodeLeastSignificantBits32(1, &symbol); bits1 + if (symbol != TOPOLOGY_C) { + symbol_buffer_.DecodeLeastSignificantBits32(2, &symbol_suffix); bits2 + symbol |= (symbol_suffix << 1); + } + return symbol +} +~~~~~ + + +### DecodeAttributeSeam() + +~~~~~ +DecodeAttributeSeam(int attribute) { + return attribute_connectivity_decoders_[attribute].DecodeNextBit(); +} +~~~~~ + + +## EdgeBreaker Traversal Valence Decoder + +### EdgeBreakerTraversalValence_Start() + +~~~~~ +EdgeBreakerTraversalValence_Start(num_vertices, num_attribute_data) { + out_buffer = EdgebreakerTraversal_Start() + num_split_symbols I32 + mode == 0 I8 + num_vertices_ += num_split_symbols + vertex_valences_ init to 0 + vertex_valences_.resize(num_vertices_, 0); + min_valence_ = 2; + max_valence_ = 7; + num_unique_valences = 6 (max_valence_ - min_valence_ + 1) + for (i = 0; i < num_unique_valences; ++i) { + DecodeVarint(&num_symbols, out_buffer) + If (num_symbols > 0) { + DecodeSymbols(num_symbols, out_buffer, &context_symbols_[i]) + } + context_counters_[i] = num_symbols + } + return out_buffer; +} +~~~~~ + + + +### TraversalValence_DecodeSymbol() + +~~~~~ +TraversalValence_DecodeSymbol() { + if (active_context_ != -1) { + symbol_id = context_symbols_[active_context_] + [--context_counters_[active_context_]] + last_symbol_ = edge_breaker_symbol_to_topology_id[symbol_id] + } else { + last_symbol_ = Traversal_DecodeSymbol() + } + return last_symbol_ +} +~~~~~ + + + +### TraversalValence_NewActiveCornerReached() + +~~~~~ +TraversalValence_NewActiveCornerReached(corner) { + switch (last_symbol_) { + case TOPOLOGY_C: + case TOPOLOGY_S: + vertex_valences_[ct(next)] += 1; + vertex_valences_[ct(prev)] += 1; + break; + case TOPOLOGY_R: + vertex_valences_[corner] += 1; + vertex_valences_[ct(next)] += 1; + vertex_valences_[ct(prev)] += 2; + break; + case TOPOLOGY_L: + vertex_valences_[corner] += 1; + vertex_valences_[ct(next)] += 2; + vertex_valences_[ct(prev)] += 1; + break; + case TOPOLOGY_E: + vertex_valences_[corner] += 2; + vertex_valences_[ct(next)] += 2; + vertex_valences_[ct(prev)] += 2; + break; + } + valence = vertex_valences_[ct(next)] + valence = max(valence, min_valence_) + valence = min(valence, max_valence_) + active_context_ = (valence - min_valence_); +} +~~~~~ + + + +### TraversalValence_MergeVertices() + +~~~~~ +TraversalValence_MergeVertices(dest, source) { + vertex_valences_[dest] += vertex_valences_[source]; +} +~~~~~ + + +## Attributes Decoder + +### DecodeAttributesDecoderData() + +~~~~~ +DecodeAttributesDecoderData(buffer) { + num_attributes I32 + point_attribute_ids_.resize(num_attributes); + for (i = 0; i < num_attributes; ++i) { + att_type UI8 + data_type UI8 + components_count UI8 + normalized UI8 + custom_id UI16 + Initialize GeometryAttribute ga + att_id = pc->AddAttribute(new PointAttribute(ga)); + point_attribute_ids_[i] = att_id; +} +~~~~~ + + + +## Sequential Attributes Decoders Controller + +### DecodeAttributesDecoderData() + +~~~~~ +DecodeAttributesDecoderData(buffer) { + AttributesDecoder_DecodeAttributesDecoderData(buffer) + sequential_decoders_.resize(num_attributes()); + for (i = 0; i < num_attributes(); ++i) { + decoder_type UI8 + sequential_decoders_[i] = CreateSequentialDecoder(decoder_type); + sequential_decoders_[i]->Initialize(decoder(), GetAttributeId(i)) +} +~~~~~ + + +### DecodeAttributes() + +~~~~~ +DecodeAttributes(buffer) { + sequencer_->GenerateSequence(&point_ids_) + for (i = 0; i < num_attributes(); ++i) { + pa = decoder()->point_cloud()->attribute(GetAttributeId(i)); + sequencer_->UpdatePointToAttributeIndexMapping(pa) + } + for (i = 0; i < num_attributes(); ++i) { + sequential_decoders_[i]->Decode(point_ids_, buffer) + //SequentialAttributeDecoder_Decode() + } +} +~~~~~ + + + +### CreateSequentialDecoder() + +~~~~~ +CreateSequentialDecoder(type) { + switch (type) { + case SEQUENTIAL_ATTRIBUTE_ENCODER_GENERIC: + return new SequentialAttributeDecoder() + case SEQUENTIAL_ATTRIBUTE_ENCODER_INTEGER: + return new SequentialIntegerAttributeDecoder() + case SEQUENTIAL_ATTRIBUTE_ENCODER_QUANTIZATION: + return new SequentialQuantizationAttributeDecoder() + case SEQUENTIAL_ATTRIBUTE_ENCODER_NORMALS: + return new SequentialNormalAttributeDecoder() + } +} +~~~~~ + + +## Sequential Attribute Decoder + +~~~~~ +Initialize(...) { + // Init some members +} +~~~~~ + + +### DecodeValues() + +~~~~~ +DecodeValues(const std::vector &point_ids) { + num_values = point_ids.size(); + entry_size = attribute_->byte_stride(); + std::unique_ptr value_data_ptr(new uint8_t[entry_size]); + out_byte_pos = 0; + for (i = 0; i < num_values; ++i) { + value_data UI8 * entry_size + attribute_->buffer()->Write(out_byte_pos, value_data, entry_size); + out_byte_pos += entry_size; + } +} +~~~~~ + + +## Sequential Integer Attribute Decoder + +~~~~~ +Initialize(...) { + SequentialAttributeDecoder_Initialize() +} +~~~~~ + + +### DecodeValues() + +~~~~~ +DecodeValues(point_ids) { + prediction_scheme_method I8 + if (prediction_scheme_method != PREDICTION_NONE) { + prediction_transform_type I8 + prediction_scheme_ = CreateIntPredictionScheme(...) + } + if (prediction_scheme_) { + } + DecodeIntegerValues(point_ids) + //SequentialQuantizationAttributeDecoder_DecodeIntegerValues() + //StoreValues() + DequantizeValues(num_values) +} +~~~~~ + + +### DecodeIntegerValues() + +~~~~~ +DecodeIntegerValues(point_ids) { + compressed UI8 + if (compressed) { + DecodeSymbols(..., values_.data()) + } else { + // TODO + } + if (!prediction_scheme_->AreCorrectionsPositive()) { + ConvertSymbolsToSignedInts(...) + } + if (prediction_scheme_) { + prediction_scheme_->DecodePredictionData(buffer) + // DecodeTransformData(buffer) + if (!values_.empty()) { + prediction_scheme_->Decode(values_.data(), &values_[0], + values_.size(), num_components, point_ids.data()) + // MeshPredictionSchemeParallelogram_Decode() +} +~~~~~ + + + +## Sequential Quantization Attribute Decoder + +~~~~~ +Initialize(...) { + SequentialIntegerAttributeDecoder_Initialize() +} +~~~~~ + + +### DecodeIntegerValues() + +~~~~~ +DecodeIntegerValues(point_ids) { + // DecodeQuantizedDataInfo() + num_components = attribute()->components_count(); + for (i = 0; i < num_components; ++i) { + min_value_[i] F32 + } + max_value_dif_ F32 + quantization_bits_ UI8 + SequentialIntegerAttributeDecoder::DecodeIntegerValues() +} +~~~~~ + + +### DequantizeValues() + +~~~~~ +DequantizeValues(num_values) { + max_quantized_value = (1 << (quantization_bits_)) - 1; + num_components = attribute()->components_count(); + entry_size = sizeof(float) * num_components; + quant_val_id = 0; + out_byte_pos = 0; + for (i = 0; i < num_values; ++i) { + for (c = 0; c < num_components; ++c) { + value = dequantizer.DequantizeFloat(values()->at(quant_val_id++)); + value = value + min_value_[c]; + att_val[c] = value; + } + attribute()->buffer()->Write(out_byte_pos, att_val.get(), entry_size); + out_byte_pos += entry_size; + } +} +~~~~~ + + + +## Prediction Scheme Transform + +### ComputeOriginalValue() + +~~~~~ +ComputeOriginalValue(const DataTypeT *predicted_vals, + const CorrTypeT *corr_vals, + DataTypeT *out_original_vals, int val_id) { + for (i = 0; i < num_components_; ++i) { + out_original_vals[i] = predicted_vals[i] + corr_vals[val_id + i]; + } +} +~~~~~ + + + +## Prediction Scheme Wrap Transform + +### DecodeTransformData() + +~~~~~ +DecodeTransformData(buffer) { + min_value_ DT + max_value_ DT +} +~~~~~ + + +### ComputeOriginalValue() + +~~~~~ +ComputeOriginalValue(const DataTypeT *predicted_vals, + const CorrTypeT *corr_vals, + DataTypeT *out_original_vals, int val_id) { + clamped_vals = ClampPredictedValue(predicted_vals); + ComputeOriginalValue(clamped_vals, corr_vals, out_original_vals, val_id) + // PredictionSchemeTransform_ComputeOriginalValue() + for (i = 0; i < this->num_components(); ++i) { + if (out_original_vals[i] > max_value_) { + out_original_vals[i] -= max_dif_; + } else if (out_original_vals[i] < min_value_) { + out_original_vals[i] += max_dif_; + } +} +~~~~~ + + +### ClampPredictedValue() + +~~~~~ +ClampPredictedValue(const DataTypeT *predicted_val) { + for (i = 0; i < this->num_components(); ++i) { + clamped_value_[i] = min(predicted_val[i], max_value_) + clamped_value_[i] = max(predicted_val[i], min_value_) + } + return &clamped_value_[0]; +} +~~~~~ + + + +## Mesh Prediction Scheme Parallelogram + +### Decode() + +~~~~~ +Decode(...) { + this->transform().InitializeDecoding(num_components); + // restore the first value + this->transform().ComputeOriginalValue(pred_vals.get(), + in_corr, out_data, 0); + // PredictionSchemeWrapTransform_ComputeOriginalValue() + corner_map_size = this->mesh_data().data_to_corner_map()->size(); + for (p = 1; p < corner_map_size; ++p) { + corner_id = this->mesh_data().data_to_corner_map()->at(p); + dst_offset = p * num_components; + b= ComputeParallelogramPrediction(p, corner_id, table, + *vertex_to_data_map, out_data, + num_components, pred_vals.get()) + if (!b) { + src_offset = (p - 1) * num_components; + this->transform().ComputeOriginalValue(out_data + src_offset, in_corr, + out_data + dst_offset, dst_offset); + // PredictionSchemeWrapTransform_ComputeOriginalValue() + } else { + this->transform().ComputeOriginalValue(pred_vals.get(), in_corr, + out_data + dst_offset, dst_offset); + // PredictionSchemeWrapTransform_ComputeOriginalValue() + } + } +} +~~~~~ + + +MeshPredictionSchemeParallelogramShared + +### ComputeParallelogramPrediction() + +~~~~~ +ComputeParallelogramPrediction(...) { + oci = table->Opposite(ci); + vert_opp = vertex_to_data_map[table->Vertex(ci)]; + vert_next = vertex_to_data_map[table->Vertex(table->Next(ci))]; + vert_prev = vertex_to_data_map[table->Vertex(table->Previous(ci))]; + if (vert_opp < data_entry_id && vert_next < data_entry_id && + vert_prev < data_entry_id) { + v_opp_off = vert_opp * num_components; + v_next_off = vert_next * num_components; + v_prev_off = vert_prev * num_components; + for (c = 0; c < num_components; ++c) { + out_prediction[c] = (in_data[v_next_off + c] + in_data[v_prev_off + c]) - + in_data[v_opp_off + c]; + } + Return true; + } + return false; +} +~~~~~ + + + +## CornerTable Traversal Processor + + +### IsFaceVisited() + +~~~~~ +IsFaceVisited(corner_id) { + if (corner_id < 0) + return true + return is_face_visited_[corner_id / 3]; +} +~~~~~ + + +### MarkFaceVisited() + +~~~~~ +MarkFaceVisited(face_id) { + is_face_visited_[face_id] = true; +} +~~~~~ + + +### IsVertexVisited() + +~~~~~ +IsVertexVisited(vert_id) { + return is_vertex_visited_[vert_id]; +} +~~~~~ + + +### MarkVertexVisited() + +~~~~~ +MarkVertexVisited(vert_id) { + is_vertex_visited_[vert_id] = true; +} +~~~~~ + + +## Mesh Attribute Indices Encoding Observer + +### OnNewVertexVisited() + +~~~~~ +OnNewVertexVisited(vertex, corner) { + point_id = mesh_->face(corner / 3)[corner % 3]; + sequencer_->AddPointId(point_id); + // Keep track of visited corners. + encoding_data_->encoded_attribute_value_index_to_corner_map.push_back(corner); + encoding_data_ + ->vertex_to_encoded_attribute_value_index_map[vertex] = + encoding_data_->num_values; + encoding_data_->num_values++; +} +~~~~~ + + +## EdgeBreaker Traverser + +### TraverseFromCorner() + +~~~~~ +TraverseFromCorner(corner_id) { + if (processor_.IsFaceVisited(corner_id)) + return + corner_traversal_stack_.clear(); + corner_traversal_stack_.push_back(corner_id); + next_vert = corner_table_->Vertex(corner_table_->Next(corner_id)); + prev_vert = corner_table_->Vertex(corner_table_->Previous(corner_id)); + if (!processor_.IsVertexVisited(next_vert)) { + processor_.MarkVertexVisited(next_vert); + traversal_observer_.OnNewVertexVisited(next_vert, + corner_table_->Next(corner_id)); + } + if (!processor_.IsVertexVisited(prev_vert)) { + processor_.MarkVertexVisited(prev_vert); + traversal_observer_.OnNewVertexVisited(prev_vert, + corner_table_->Previous(corner_id)); + } + while (!corner_traversal_stack_.empty()) { + corner_id = corner_traversal_stack_.back(); + face_id =corner_id / 3; + if (processor_.IsFaceVisited(face_id)) { + corner_traversal_stack_.pop_back(); + continue + } + while(true) { + face_id = corner_id / 3; + processor_.MarkFaceVisited(face_id); + traversal_observer_.OnNewFaceVisited(face_id); + vert_id = corner_table_->Vertex(corner_id); + on_boundary = corner_table_->IsOnBoundary(vert_id); + if (!processor_.IsVertexVisited(vert_id)) { + processor_.MarkVertexVisited(vert_id); + traversal_observer_.OnNewVertexVisited(vert_id, corner_id); + if (!on_boundary) { + corner_id = corner_table_->GetRightCorner(corner_id); + continue; + } + } + // The current vertex has been already visited or it was on a boundary. + right_corner_id = corner_table_->GetRightCorner(corner_id); + left_corner_id = corner_table_->GetLeftCorner(corner_id); + right_face_id((right_corner_id < 0 ? -1 : right_corner_id / 3)); + left_face_id((left_corner_id < 0 ? -1 : left_corner_id / 3)); + if (processor_.IsFaceVisited(right_face_id)) { + if (processor_.IsFaceVisited(left_face_id)) { + corner_traversal_stack_.pop_back(); + break; // Break from while(true) loop + } else { + corner_id = left_corner_id; + } + } else { + if (processor_.IsFaceVisited(left_face_id)) { + corner_id = right_corner_id; + } else { + // Split the traversal. + corner_traversal_stack_.back() = left_corner_id; + corner_traversal_stack_.push_back(right_corner_id); + break; // Break from while(true) loop + } + } + } + } +} +~~~~~ + + +## Mesh Traversal Sequencer + +### GenerateSequenceInternal() + +~~~~~ +GenerateSequenceInternal() { + traverser_.OnTraversalStart(); + If (corner_order_) { + // TODO + } else { + int32_t num_faces = traverser_.corner_table()->num_faces(); + for (i = 0; i < num_faces; ++i) { + ProcessCorner(3 * i) + } + } + traverser_.OnTraversalEnd(); +} +~~~~~ + + +### ProcessCorner() + +~~~~~ +ProcessCorner(corner_id) { + traverser_.TraverseFromCorner(corner_id); +} +~~~~~ + + +### UpdatePointToAttributeIndexMapping() + +~~~~~ +UpdatePointToAttributeIndexMapping(PointAttribute *attribute) { + corner_table = traverser_.corner_table(); + attribute->SetExplicitMapping(mesh_->num_points()); + num_faces = mesh_->num_faces(); + num_points = mesh_->num_points(); + for (f = 0; f < num_faces; ++f) { + face = mesh_->face(f); + for (p = 0; p < 3; ++p) { + point_id = face[p]; + vert_id = corner_table->Vertex(3 * f + p); + att_entry_id( + encoding_data_ + ->vertex_to_encoded_attribute_value_index_map[vert_id]); + attribute->SetPointMapEntry(point_id, att_entry_id); + } + } +} +~~~~~ + + +PointsSequencer + +### AddPointId() + +~~~~~ +AddPointId(point_id) { + out_point_ids_->push_back(point_id); +} +~~~~~ + + + +## Corner Table + +### Opposite() + +~~~~~ +Opposite(corner) { + return opposite_corners_[corner]; +} +~~~~~ + + +### Next() + +~~~~~ +Next(corner) { + return LocalIndex(++corner) ? corner : corner - 3; +} +~~~~~ + + +### Previous() + +~~~~~ +Previous(corner) { + return LocalIndex(corner) ? corner - 1 : corner + 2; +} +~~~~~ + + +### Vertex() + +~~~~~ +Vertex(corner) { + faces_[Face(corner)][LocalIndex(corner)]; +} +~~~~~ + + +### Face() + +~~~~~ +Face(corner) { + return corner / 3; +} +~~~~~ + + +### LocalIndex() + +~~~~~ +LocalIndex(corner) { + return corner % 3; +} +~~~~~ + + +### num_vertices() + +~~~~~ +num_vertices() { + return vertex_corners_.size(); +} +~~~~~ + + +### num_corners() + +~~~~~ +num_corners() { + return faces_.size() * 3; +} +~~~~~ + + +### num_faces() + +~~~~~ +num_faces() { + return faces_.size(); +} +~~~~~ + + +### bool IsOnBoundary() + +~~~~~ +bool IsOnBoundary(vert) { + corner = LeftMostCorner(vert); + if (SwingLeft(corner) < 0) + return true; + return false; +} +~~~~~ + + + +### SwingRight() + +~~~~~ +SwingRight(corner) { + return Previous(Opposite(Previous(corner))); +} +~~~~~ + + +### SwingLeft() + +~~~~~ +SwingLeft(corner) { + return Next(Opposite(Next(corner))); +} +~~~~~ + + +### GetLeftCorner() + +~~~~~ +GetLeftCorner(corner_id) { + if (corner_id < 0) + return kInvalidCornerIndex; + return Opposite(Previous(corner_id)); +} +~~~~~ + + +### GetRightCorner() + +~~~~~ +GetRightCorner(corner_id) { + if (corner_id < 0) + return kInvalidCornerIndex; + return Opposite(Next(corner_id)); +} +~~~~~ + + +### SetOppositeCorner() + +~~~~~ +SetOppositeCorner(corner_id, pp_corner_id) { + opposite_corners_[corner_id] = opp_corner_id; +} +~~~~~ + + + +### MapCornerToVertex() + +~~~~~ +MapCornerToVertex(corner_id, vert_id) { + face = Face(corner_id); + faces_[face][LocalIndex(corner_id)] = vert_id; + if (vert_id >= 0) { + vertex_corners_[vert_id] = corner_id; + } +} +~~~~~ + + +### UpdateVertexToCornerMap() + +~~~~~ +UpdateVertexToCornerMap(vert) { + first_c = vertex_corners_[vert]; + if (first_c < 0) + return; + act_c = SwingLeft(first_c); + c = first_c; + while (act_c >= 0 && act_c != first_c) { + c = act_c; + act_c = SwingLeft(act_c); + } + if (act_c != first_c) { + vertex_corners_[vert] = c; + } +} +~~~~~ + + + +### LeftMostCorner() + +~~~~~ +LeftMostCorner(v) { + return vertex_corners_[v]; +} +~~~~~ + + +### MakeVertexIsolated() + +~~~~~ +MakeVertexIsolated(vert) { + vertex_corners_[vert] = kInvalidCornerIndex; +} +~~~~~ + + + +## Mesh Attribute Corner Table + +### bool IsCornerOnSeam() + +~~~~~ +bool IsCornerOnSeam(corner) { + return is_vertex_on_seam_[corner_table_->Vertex(corner)]; +} +~~~~~ + + +### AddSeamEdge() + +~~~~~ +AddSeamEdge(c) { + MarkSeam(c) + opp_corner = corner_table_->Opposite(c); + if (opp_corner >= 0) { + no_interior_seams_ = false; + MarkSeam(opp_corner) + } +} +~~~~~ + + +### MarkSeam() + +~~~~~ +MarkSeam(c) { + is_edge_on_seam_[c] = true; + is_vertex_on_seam_[corner_table_->Vertex(corner_table_->Next(c))] = true; + is_vertex_on_seam_[corner_table_->Vertex(corner_table_->Previous(c)) + ] = true; +} +~~~~~ + + +### RecomputeVertices() + +~~~~~ +RecomputeVertices() { + // in code RecomputeVerticesInternal(nullptr, nullptr) + num_new_vertices = 0; + for (v = 0; v < corner_table_->num_vertices(); ++v) { + c = corner_table_->LeftMostCorner(v); + if (c < 0) + continue; + first_vert_id(num_new_vertices++); + vertex_to_attribute_entry_id_map_.push_back(first_vert_id); + first_c = c; + if (is_vertex_on_seam_[v]) { + act_c = SwingLeft(first_c); + while (act_c >= 0) { + first_c = act_c; + act_c = SwingLeft(act_c); + } + } + corner_to_vertex_map_[first_c] =first_vert_id; + vertex_to_left_most_corner_map_.push_back(first_c); + act_c = corner_table_->SwingRight(first_c); + while (act_c >= 0 && act_c != first_c) { + if (is_edge_on_seam_[corner_table_->Next(act_c)]) { + // in code IsCornerOppositeToSeamEdge() + first_vert_id = AttributeValueIndex(num_new_vertices++); + vertex_to_attribute_entry_id_map_.push_back(first_vert_id); + vertex_to_left_most_corner_map_.push_back(act_c); + } + corner_to_vertex_map_[act_c] = first_vert_id; + act_c = corner_table_->SwingRight(act_c); + } + } +} +~~~~~ + + + + +## Symbol Decoding + +### DecodeSymbols() + +~~~~~ +DecodeSymbols(num_symbols, out_buffer, out_values) { + scheme UI8 + If (scheme == 0) { + DecodeTaggedSymbols<>(num_symbols, src_buffer, out_values) + } else if (scheme == 1) { + DecodeRawSymbols<>(num_symbols, src_buffer, out_values) + } +} +~~~~~ + + +### DecodeTaggedSymbols() + +~~~~~ +DecodeTaggedSymbols() { + FIXME +} +~~~~~ + + + +### DecodeRawSymbols() + +~~~~~ +DecodeRawSymbols() { + max_bit_length UI8 + DecodeRawSymbolsInternal(max_bit_length, out_values) + return symbols +} +~~~~~ + + + +### DecodeRawSymbolsInternal() + +~~~~~ +DecodeRawSymbolsInternal(max_bit_length, out_values) { + decoder = CreateRansSymbolDecoder(max_bit_length) + decoder.StartDecoding() + // RansSymbolDecoder_StartDecoding + for (i = 0; i < num_values; ++i) { + out_values[i] = decoder.DecodeSymbol() + // RansSymbolDecoder_DecodeSymbol + } +} +~~~~~ + + +### CreateRansSymbolDecoder() + +~~~~~ +CreateRansSymbolDecoder(max_bit_length) { + rans_precision_bits = (3 * max_bit_length) / 2; + rans_precision_bits = min(rans_precision_bits, 20) + rans_precision_bits = max(rans_precision_bits, 12) + rans_precision = 1 << rans_precision_bits_; + l_rans_base = rans_precision * 4; + num_symbols_ UI32 + for (i = 0; i < num_symbols_; ++i) { + prob_data UI8 + if ((prob_data & 3) == 3) { + offset = prob_data >> 2 + for (j = 0; j < offset + 1; ++j) { + probability_table_[i + j] = 0; + } + i += offset; + } else { + prob = prob_data >> 2 + for (j = 0; j < token; ++j) { + eb UI8 + prob = prob | (eb << (8 * (j + 1) - 2) + } + probability_table_[i] = prob; + } + } + rans_build_look_up_table() +} +~~~~~ + + +### RansSymbolDecoder_StartDecoding() + +~~~~~ +RansSymbolDecoder_StartDecoding() { + bytes_encoded UI64 + buffer bytes_encoded * UI8 + rans_read_init(buffer, bytes_encoded) +} +~~~~~ + + + +### RansSymbolDecoder_DecodeSymbol() + +~~~~~ +RansSymbolDecoder_DecodeSymbol() { + ans_.rans_read() +} +~~~~~ + + +## Rans Decoding + +### ans_read_init() + +~~~~~ +ans_read_init(struct AnsDecoder *const ans, const uint8_t *const buf, + int offset) { + x = buf[offset - 1] >> 6 + If (x == 0) { + ans->buf_offset = offset - 1; + ans->state = buf[offset - 1] & 0x3F; + } else if (x == 1) { + ans->buf_offset = offset - 2; + ans->state = mem_get_le16(buf + offset - 2) & 0x3FFF; + } else if (x == 2) { + ans->buf_offset = offset - 3; + ans->state = mem_get_le24(buf + offset - 3) & 0x3FFFFF; + } else if (x == 3) { + // x == 3 implies this byte is a superframe marker + return 1; + } + ans->state += l_base; +} +~~~~~ + + + +### int rabs_desc_read() + +~~~~~ +int rabs_desc_read(struct AnsDecoder *ans, AnsP8 p0) { + AnsP8 p = ans_p8_precision - p0; + if (ans->state < l_base) { + ans->state = ans->state * io_base + ans->buf[--ans->buf_offset]; + } + x = ans->state; + quot = x / ans_p8_precision; + rem = x % ans_p8_precision; + xn = quot * p; + val = rem < p; + if (val) { + ans->state = xn + rem; + } else { + ans->state = x - xn - p; + } + return val; +} +~~~~~ + + + +### rans_read_init() + +~~~~~ +rans_read_init(UI8 *buf, int offset) { + ans_.buf = buf; + x = buf[offset - 1] >> 6 + If (x == 0) { + ans_.buf_offset = offset - 1; + ans_.state = buf[offset - 1] & 0x3F; + } else if (x == 1) { + ans_.buf_offset = offset - 2; + ans_.state = mem_get_le16(buf + offset - 2) & 0x3FFF; + } else if (x == 2) { + ans_.buf_offset = offset - 3; + ans_.state = mem_get_le24(buf + offset - 3) & 0x3FFFFF; + } else if (x == 3) { + ans_.buf_offset = offset - 4; + ans_.state = mem_get_le32(buf + offset - 4) & 0x3FFFFFFF; + } + ans_.state += l_rans_base; +} +~~~~~ + + + + +### rans_build_look_up_table() + +~~~~~ +rans_build_look_up_table() { + cum_prob = 0 + act_prob = 0 + for (i = 0; i < num_symbols; ++i) { + probability_table_[i].prob = token_probs[i]; + probability_table_[i].cum_prob = cum_prob; + cum_prob += token_probs[i]; + for (j = act_prob; j < cum_prob; ++j) { + Lut_table_[j] = i + } + act_prob = cum_prob +} +~~~~~ + + + +### rans_read() + +~~~~~ +rans_read() { + while (ans_.state < l_rans_base) { + ans_.state = ans_.state * io_base + ans_.buf[--ans_.buf_offset]; + } + quo = ans_.state / rans_precision; + rem = ans_.state % rans_precision; + sym = fetch_sym() + ans_.state = quo * sym.prob + rem - sym.cum_prob; + return sym.val; +} +~~~~~ + + +### fetch_sym() + +~~~~~ +fetch_sym() { + symbol = lut_table[rem] + out->val = symbol + out->prob = probability_table_[symbol].prob; + out->cum_prob = probability_table_[symbol].cum_prob; +} +~~~~~ + + + +## Rans Bit Decoder + +### RansBitDecoder_StartDecoding() + +~~~~~ +RansBitDecoder_StartDecoding(DecoderBuffer *source_buffer) { + prob_zero_ UI8 + size UI32 + buffer_ size * UI8 + ans_read_init(&ans_decoder_, buffer_, size) +} +~~~~~ + + +### DecodeNextBit() + +~~~~~ +DecodeNextBit() { + uint8_t bit = rabs_desc_read(&ans_decoder_, prob_zero_); + return bit > 0; +} +~~~~~ + + +## Core Functions + +### DecodeVarint + +~~~~~ +DecodeVarint() { + If (std::is_unsigned::value) { + in UI8 + If (in & (1 << 7)) { + out = DecodeVarint() + out = (out << 7) | (in & ((1 << 7) - 1)) + } else { + typename std::make_unsigned::type UIT; + out = DecodeVarint() + out = ConvertSymbolToSignedInt(out) + } + return out; +} +~~~~~ + + + +### ConvertSymbolToSignedInt() + +~~~~~ +ConvertSymbolToSignedInt() { + abs_val = val >> 1 + If (val & 1 == 0) { + return abs_val + } else { + signed_val = -abs_val - 1 + } + return signed_val +} +~~~~~ + + + +Sequential Decoder + +### decode_connectivity() + +~~~~~ +decode_connectivity() { + num_faces I32 + num_points I32 + connectivity _method UI8 + If (connectivity _method == 0) { + // TODO + } else { + loop num_faces { + If (num_points < 256) { + face[] UI8 + } else if (num_points < (1 << 16)) { + face[] UI16 + } else { + face[] UI32 + } + } + } +} +~~~~~ diff --git a/docs/_site/spec/index.html b/docs/_site/spec/index.html new file mode 100644 index 0000000..05d03ed --- /dev/null +++ b/docs/_site/spec/index.html @@ -0,0 +1,1927 @@ + + + + + Draco Bitstream Specification (Draft) + + + + + + +

    Draco Bitstream Specification (Draft)

    + +

    Version 1,2
    +Released 2017-xx-xx

    + +

    Frank Galligan, Google
    +[author]
    +[author]

    + +

    Last modified: 2017-07-09 18:30:06 -0700

    + +

    Abstract

    + +

    This document defines the bitstream format and decoding process for the +Draco 3D Data Compression scheme.

    + +

    Contents

    + + + +

    Scope

    + +

    This document specifies the open-source Draco #D Data Compression bitstream +format and decoding process.

    + +

    Terms and Definitions

    + +

    For the purposes of this document, the following terms and definitions apply:

    + + + + + + + + + + + + + + +
    TermDefinition
      
    + +

    Symbols (and abbreviated terms)

    + +

    DCT: Discrete Cosine Transform

    + +

    FIXME

    + +

    The specification makes use of a number of constant integers. Constants that +relate to the semantics of a particular syntax element are defined in section +7.

    + +

    Additional constants are defined below:

    + + + + + + + + + + + + + + + + +
    Symbol nameValueDescription
    SYMBOL  
    + +

    Conventions

    + +
      +
    • +

      When bit reading is finished it will always pad the read to the current +byte.

      +
    • +
    • +

      Draco encoded mesh files are comprised of three main sections. This first +section is the header. The second section contains the connectivity data. +The third section contains the attribute data. The header must be decoded +first, then the connectivity section, and then the attribute section.

      +
    • +
    • +

      The Connectivity section is composed of the following sections in order:

      + +
        +
      • +

        Connectivity header

        +
      • +
      • +

        EdgeBreaker symbol buffer

        +
      • +
      • +

        Start face buffer

        +
      • +
      • +

        EdgeBreaker valence header

        +
      • +
      • +

        Context data for the valence prediction

        +
      • +
      • +

        Hole and Split data

        +
      • +
      +
    • +
    • +

      The hole and split data must be decoded before the EdgeBreaker symbols are +decoded.

      +
    • +
    + +

    Draco Decoder

    + +

    Decode()

    + +
    +Decode() { Type + DecodeHeader() + DecodeConnectivityData() + DecodeAttributeData()} + +
    + +

    DecodeHeader()

    + +
    +DecodeHeader() { Type + draco_string UI8[5] + major_version UI8 + minor_version UI8 + encoder_type UI8 + encoder_method UI8 + flags +} + +
    + +

    DecodeAttributeData()

    + +
    +DecodeAttributeData() { Type + num_attributes_decoders UI8 + for (i = 0; i < num_attributes_decoders; ++i) { + CreateAttributesDecoder(i); + } + for (auto &att_dec : attributes_decoders_) { + att_dec->Initialize(this, point_cloud_) + } + for (i = 0; i < num_attributes_decoders; ++i) { + attributes_decoders_[i]->DecodeAttributesDecoderData(buffer_) + } + DecodeAllAttributes() + OnAttributesDecoded() +
    + +

    Mesh Decoder

    + +

    DecodeConnectivityData()

    + +
    +DecodeConnectivityData() Type + InitializeDecoder() + DecodeConnectivity() +} + +
    + +

    EdgeBreaker Decoder

    + +

    InitializeDecoder()

    + +
    +InitializeDecoder() { Type + edgebreaker_decoder_type UI8 +} + +
    + +

    DecodeConnectivity()

    + +
    +DecodeConnectivity() { Type + num_new_verts UI32 + num_encoded_vertices UI32 + num_faces UI32 + num_attribute_data I8 + num_encoded_symbols UI32 + num_encoded_split_symbols UI32 + encoded_connectivity_size UI32 + // file pointer must be set to current position + encoded_connectivity_size + hole_and_split_bytes = DecodeHoleAndTopologySplitEvents() + // file pointer must be set to old current position + EdgeBreakerTraversalValence_Start() + DecodeConnectivity(num_symbols) + if (attribute_data_.size() > 0) { + for (ci = 0; ci < corner_table_->num_corners(); ci += 3) { + DecodeAttributeConnectivitiesOnFace(ci) + } + } + for (i = 0; i < corner_table_->num_vertices(); ++i) { + if (is_vert_hole_[i]) { + corner_table_->UpdateVertexToCornerMap(i); + } + } + // Decode attribute connectivity. + for (uint32_t i = 0; i < attribute_data_.size(); ++i) { + attribute_data_[i].connectivity_data.InitEmpty(corner_table_.get()); + for (int32_t c : attribute_data_[i].attribute_seam_corners) { + attribute_data_[i].connectivity_data.AddSeamEdge(c); + } + attribute_data_[i].connectivity_data.RecomputeVertices(nullptr, nullptr); + } + // Preallocate vertex to value mapping + AssignPointsToCorners() +} + +
    + +

    AssignPointsToCorners()

    + +
    +AssignPointsToCorners() { Type + decoder_->mesh()->SetNumFaces(corner_table_->num_faces()); + if (attribute_data_.size() == 0) { + for (f = 0; f < decoder_->mesh()->num_faces(); ++f) { + for (c = 0; c < 3; ++c) { + vert_id = corner_table_->Vertex(3 * f + c); + if (point_id == -1) + point_id = num_points++; + face[c] = point_id; + } + decoder_->mesh()->SetFace(f, face); + } + decoder_->point_cloud()->set_num_points(num_points); + Return true; + } + for (v = 0; v < corner_table_->num_vertices(); ++v) { + c = corner_table_->LeftMostCorner(v); + if (c < 0) + continue; + deduplication_first_corner = c; + if (!is_vert_hole_[v]) { + for (uint32_t i = 0; i < attribute_data_.size(); ++i) { + if (!attribute_data_[i].connectivity_data.IsCornerOnSeam(c)) + continue; + vert_id = attribute_data_[i].connectivity_data.Vertex(c); + act_c = corner_table_->SwingRight(c); + seam_found = false; + while (act_c != c) { + if (attribute_data_[i].connectivity_data.Vertex(act_c) != vert_id) { + deduplication_first_corner = act_c; + seam_found = true; + break; + } + act_c = corner_table_->SwingRight(act_c); + } + if (seam_found) + break; + } + } + c = deduplication_first_corner; + corner_to_point_map[c] = point_to_corner_map.size(); + point_to_corner_map.push_back(c); + prev_c = c; + c = corner_table_->SwingRight(c); + while (c >= 0 && c != deduplication_first_corner) { + attribute_seam = false; + for (uint32_t i = 0; i < attribute_data_.size(); ++i) { + if (attribute_data_[i].connectivity_data.Vertex(c) != + attribute_data_[i].connectivity_data.Vertex(prev_c)) { + attribute_seam = true; + break; + } + } + if (attribute_seam) { + corner_to_point_map[c] = point_to_corner_map.size(); + point_to_corner_map.push_back(c); + } else { + corner_to_point_map[c] = corner_to_point_map[prev_c]; + } + prev_c = c; + c = corner_table_->SwingRight(c); + } + } + for (f = 0; f < decoder_->mesh()->num_faces(); ++f) { + for (c = 0; c < 3; ++c) { + face[c] = corner_to_point_map[3 * f + c]; + } + decoder_->mesh()->SetFace(f, face); + } + decoder_->point_cloud()->set_num_points(point_to_corner_map.size()); +} + +
    + +

    DecodeConnectivity()

    + +
    +DecodeConnectivity(num_symbols) { Type + for (i = 0; i < num_symbols; ++i) { + symbol = TraversalValence_DecodeSymbol() + corner = 3 * num_faces++ + if (symbol == TOPOLOGY_C) { + vertex_x = UpdateCornerTableForSymbolC() + is_vert_hole_[vertex_x] = false; + } else if (symbol == TOPOLOGY_R || symbol == TOPOLOGY_L) { + UpdateCornerTableForSymbolLR() + check_topology_split = true; + } else if (symbol == TOPOLOGY_S) { + HandleSymbolS() + } else if (symbol == TOPOLOGY_E) { + UpdateCornerTableForSymbolE() + check_topology_split = true; + } + active_corner_stack.back() = corner; + traversal_decoder_.NewActiveCornerReached(corner); + if (check_topology_split) { + encoder_symbol_id = num_symbols - symbol_id - 1; + while (true) { + split = IsTopologySplit(encoder_symbol_id, &split_edge, + &encoder_split_symbol_id); + if (!split) { + break; + } + act_top_corner = corner; + if (split_edge == RIGHT_FACE_EDGE) { + new_active_corner = corner_table_->Next(act_top_corner); + } else { + new_active_corner = corner_table_->Previous(act_top_corner); + } + decoder_split_symbol_id = num_symbols - encoder_split_symbol_id - 1; + topology_split_active_corners[decoder_split_symbol_id] = + new_active_corner; + } + } + } + while (active_corner_stack.size() > 0) { + corner = active_corner_stack.pop_back(); + interior_face = traversal_decoder_.DecodeStartFaceConfiguration(); + if (interior_face == true) { + UpdateCornerTableForInteriorFace() + for (ci = 0; ci < 3; ++ci) { + is_vert_hole_[corner_table_->Vertex(new_corner + ci)] = false; + } + init_face_configurations_.push_back(true); + init_corners_.push_back(new_corner); + } else { + init_face_configurations_.push_back(false); + init_corners_.push_back(corner); + } + } + Return num_vertices; +} + +
    + +

    UpdateCornerTableForSymbolC()

    + +
    +UpdateCornerTableForSymbolC(corner) { Type + corner_a = active_corner_stack.back(); + corner_b = corner_table_->Previous(corner_a); + while (corner_table_->Opposite(corner_b) >= 0) { + corner_b = corner_table_->Previous(corner_table_->Opposite(corner_b)); + } + SetOppositeCorners(corner_a, corner + 1); + SetOppositeCorners(corner_b, corner + 2); + vertex_x = corner_table_->Vertex(corner_table_->Next(corner_a)); + corner_table_->MapCornerToVertex(corner, vertex_x); + corner_table_->MapCornerToVertex( + corner + 1, corner_table_->Vertex(corner_table_->Next(corner_b))); + corner_table_->MapCornerToVertex( + corner + 2, corner_table_->Vertex(corner_table_->Previous(corner_a))); + return vertex_x; +} + +
    + +

    UpdateCornerTableForSymbolLR()

    + +
    +UpdateCornerTableForSymbolLR(corner, symbol) { Type + if (symbol == TOPOLOGY_R) { + opp_corner = corner + 2; + } else { + opp_corner = corner + 1; + } + SetOppositeCorners(opp_corner, corner_a); + corner_table_->MapCornerToVertex(opp_corner,num_vertices++); + corner_table_->MapCornerToVertex( + corner_table_->Next(opp_corner), + corner_table_->Vertex(corner_table_->Previous(corner_a))); + corner_table_->MapCornerToVertex( + corner_table_->Previous(opp_corner), + corner_table_->Vertex(corner_table_->Next(corner_a))); +} + +
    + +

    HandleSymbolS()

    + +
    +HandleSymbolS(corner) { Type + corner_b = active_corner_stack.pop_back(); + it = topology_split_active_corners.find(symbol_id); + if (it != topology_split_active_corners.end()) { + active_corner_stack.push_back(it->second); + } + corner_a = active_corner_stack.back(); + SetOppositeCorners(corner_a, corner + 2); + SetOppositeCorners(corner_b, corner + 1); + vertex_p = corner_table_->Vertex(corner_table_->Previous(corner_a)); + corner_table_->MapCornerToVertex(corner, vertex_p); + corner_table_->MapCornerToVertex( + corner + 1, corner_table_->Vertex(corner_table_->Next(corner_a))); + corner_table_->MapCornerToVertex(corner + 2, + corner_table_->Vertex(corner_table_->Previous(corner_b))); + corner_n = corner_table_->Next(corner_b); + vertex_n = corner_table_->Vertex(corner_n); + traversal_decoder_.MergeVertices(vertex_p, vertex_n); + // TraversalValence_MergeVertices + while (corner_n >= 0) { + corner_table_->MapCornerToVertex(corner_n, vertex_p); + corner_n = corner_table_->SwingLeft(corner_n); + } + corner_table_->MakeVertexIsolated(vertex_n); +} + +
    + +

    UpdateCornerTableForSymbolE()

    + +
    +UpdateCornerTableForSymbolE() { Type + corner_table_->MapCornerToVertex(corner, num_vertices++); + corner_table_->MapCornerToVertex(corner + 1, num_vertices++); + corner_table_->MapCornerToVertex(corner + 2, num_vertices++); +} + +
    + +

    UpdateCornerTableForInteriorFace()

    + +
    +UpdateCornerTableForInteriorFace() { Type + corner_b = corner_table_->Previous(corner); + while (corner_table_->Opposite(corner_b) >= 0) { + corner_b = corner_table_->Previous(corner_table_->Opposite(corner_b)); + } + corner_c = corner_table_->Next(corner); + while (corner_table_->Opposite(corner_c) >= 0) { + corner_c = corner_table_->Next(corner_table_->Opposite(corner_c)); + } + face(num_faces++); + corner_table_->MapCornerToVertex( + new_corner, corner_table_->Vertex(corner_table_->Next(corner_b))); + corner_table_->MapCornerToVertex( + new_corner + 1, corner_table_->Vertex(corner_table_->Next(corner_c))); + corner_table_->MapCornerToVertex( + new_corner + 2, corner_table_->Vertex(corner_table_->Next(corner))); +} + +
    + +

    IsTopologySplit()

    + +
    +IsTopologySplit(encoder_symbol_id, *out_face_edge, Type + + *out_encoder_split_symbol_id) { + if (topology_split_data_.size() == 0) + return false; + if (topology_split_data_.back().source_symbol_id != encoder_symbol_id) + return false; + *out_face_edge = topology_split_data_.back().source_edge; + *out_encoder_split_symbol_id = + topology_split_data_.back().split_symbol_id; + topology_split_data_.pop_back(); + return true; +} + +
    + +

    DecodeAttributeConnectivitiesOnFace()

    + +
    +DecodeAttributeConnectivitiesOnFace(corner) { Type + corners[3] = {corner, corner_table_->Next(corner), + corner_table_->Previous(corner)} + for (c = 0; c < 3; ++c) { + opp_corner = corner_table_->Opposite(corners[c]); + if (opp_corner < 0) { + for (uint32_t i = 0; i < attribute_data_.size(); ++i) { + attribute_data_[i].attribute_seam_corners.push_back(corners[c]); + } + continue + } + for (uint32_t i = 0; i < attribute_data_.size(); ++i) { + bool is_seam = traversal_decoder_.DecodeAttributeSeam(i); + if (is_seam) { + attribute_data_[i].attribute_seam_corners.push_back(corners[c]); + } + } + } +} + +
    + +

    SetOppositeCorners()

    + +
    +SetOppositeCorners(corner_0, corner_1) { Type + corner_table_->SetOppositeCorner(corner_0, corner_1); + corner_table_->SetOppositeCorner(corner_1, corner_0); +} + +
    + +

    EdgeBreaker Hole and Topology Split Events

    + +

    DecodeHoleAndTopologySplitEvents()

    + +

    FIXME: Escaping angle brackets

    + +
    +DecodeHoleAndTopologySplitEvents() { Type + num_topologoy_splits UI32 + source_symbol_id = 0 + for (i = 0; i < num_topologoy_splits; ++i) { + DecodeVarint\<UI32\>(&delta) + split_data[i].source_symbol_id = delta + source_symbol_id + DecodeVarint\<UI32\>(&delta) + split_data[i].split_symbol_id = source_symbol_id - delta + } + for (i = 0; i < num_topologoy_splits; ++i) { + split_data[i].split_edge bits1 + split_data[i].source_edge bits1 + } + num_hole_events UI32 + symbol_id = 0 + for (i = 0; i < num_hole_events; ++i) { + DecodeVarint\<UI32\>(&delta) + hole_data[i].symbol_id = delta + symbol_id + } + return bytes_decoded; +} + +
    + +

    CreateAttributesDecoder

    + +

    FIXME: Escaping angle brackets

    + +
    +CreateAttributesDecoder() { Type + att_data_id I8 + decoder_type UI8 + if (att_data_id >= 0) { + attribute_data_[att_data_id].decoder_id = att_decoder_id; + } + traversal_method_encoded UI8 + if (decoder_type == MESH_VERTEX_ATTRIBUTE) { + if (att_data_id < 0) { + encoding_data = &pos_encoding_data_; + } else { + encoding_data = &attribute_data_[att_data_id].encoding_data; + attribute_data_[att_data_id].is_connectivity_used = false; + } + if (traversal_method == MESH_TRAVERSAL_DEPTH_FIRST) { + typedef EdgeBreakerTraverser\<AttProcessor, AttObserver\> AttTraverser; + sequencer = CreateVertexTraversalSequencer\<AttTraverser\>(encoding_data); + } else if (traversal_method == MESH_TRAVERSAL_PREDICTION_DEGREE) { + typedef PredictionDegreeTraverser\<AttProcessor, AttObserver\> AttTraverser; + sequencer = CreateVertexTraversalSequencer\<AttTraverser\>(encoding_data); + } + } else { + // TODO + } + att_controller(new SequentialAttributeDecodersController(std::move(sequencer))) + decoder_->SetAttributesDecoder(att_decoder_id, std::move(att_controller)); +} + +
    + +

    Edgebreaker Traversal Decoder

    + +

    EdgebreakerTraversal_Start()

    + +
    +EdgebreakerTraversal_Start() { Type + size UI64 + symbol_buffer_ size * UI8 + size UI64 + start_face_buffer_ size * UI8 + if (num_attribute_data_ > 0) { + attribute_connectivity_decoders_ = std::unique_ptr<BinaryDecoder[]>( + new BinaryDecoder[num_attribute_data_]); + for (i = 0; i < num_attribute_data_; ++i) { + attribute_connectivity_decoders_[i].StartDecoding() + // RansBitDecoder_StartDecoding + } +} + +
    + +

    Traversal_DecodeSymbol()

    + +
    Traversal_DecodeSymbol() {
    +  symbol_buffer_.DecodeLeastSignificantBits32(1, &symbol);                   bits1
    +  if (symbol != TOPOLOGY_C) {
    +    symbol_buffer_.DecodeLeastSignificantBits32(2, &symbol_suffix);          bits2
    +    symbol |= (symbol_suffix << 1);
    +  }
    +  return symbol
    +}
    +
    +
    + +

    DecodeAttributeSeam()

    + +
    DecodeAttributeSeam(int attribute) {
    +  return attribute_connectivity_decoders_[attribute].DecodeNextBit();
    +}
    +
    +
    + +

    EdgeBreaker Traversal Valence Decoder

    + +

    EdgeBreakerTraversalValence_Start()

    + +
    EdgeBreakerTraversalValence_Start(num_vertices, num_attribute_data) {
    +  out_buffer = EdgebreakerTraversal_Start()
    +  num_split_symbols                                                          I32
    +  mode == 0                                                                  I8
    +  num_vertices_ += num_split_symbols
    +  vertex_valences_ init to 0
    +  vertex_valences_.resize(num_vertices_, 0);
    +  min_valence_ = 2;
    +  max_valence_ = 7;
    +  num_unique_valences = 6 (max_valence_ - min_valence_ + 1)
    +  for (i = 0; i < num_unique_valences; ++i) {
    +    DecodeVarint<UI32>(&num_symbols, out_buffer)
    +    If (num_symbols > 0) {
    +      DecodeSymbols(num_symbols, out_buffer, &context_symbols_[i])
    +    }
    +    context_counters_[i] = num_symbols
    +  }
    +  return out_buffer;
    +}
    +
    +
    + +

    TraversalValence_DecodeSymbol()

    + +
    TraversalValence_DecodeSymbol() {
    +  if (active_context_ != -1) {
    +    symbol_id  = context_symbols_[active_context_]
    +                                                      [--context_counters_[active_context_]]
    +    last_symbol_ = edge_breaker_symbol_to_topology_id[symbol_id]
    +  } else {
    +    last_symbol_ = Traversal_DecodeSymbol()
    +  }
    +  return last_symbol_
    +}
    +
    +
    + +

    TraversalValence_NewActiveCornerReached()

    + +
    TraversalValence_NewActiveCornerReached(corner) {
    +  switch (last_symbol_) {
    +    case TOPOLOGY_C:
    +    case TOPOLOGY_S:
    +      vertex_valences_[ct(next)] += 1;
    +      vertex_valences_[ct(prev)] += 1;
    +      break;
    +    case TOPOLOGY_R:
    +      vertex_valences_[corner] += 1;
    +      vertex_valences_[ct(next)] += 1;
    +      vertex_valences_[ct(prev)] += 2;
    +      break;
    +    case TOPOLOGY_L:
    +      vertex_valences_[corner] += 1;
    +      vertex_valences_[ct(next)] += 2;
    +      vertex_valences_[ct(prev)] += 1;
    +      break;
    +    case TOPOLOGY_E:
    +      vertex_valences_[corner] += 2;
    +      vertex_valences_[ct(next)] += 2;
    +      vertex_valences_[ct(prev)] += 2;
    +      break;
    +  }
    +  valence = vertex_valences_[ct(next)]
    +  valence = max(valence, min_valence_)
    +  valence = min(valence, max_valence_)
    +  active_context_ = (valence - min_valence_);
    +}
    +
    +
    + +

    TraversalValence_MergeVertices()

    + +
    TraversalValence_MergeVertices(dest, source) {
    +  vertex_valences_[dest] += vertex_valences_[source];
    +}
    +
    +
    + +

    Attributes Decoder

    + +

    DecodeAttributesDecoderData()

    + +
    DecodeAttributesDecoderData(buffer) {
    +  num_attributes                                                             I32
    +  point_attribute_ids_.resize(num_attributes);
    +  for (i = 0; i < num_attributes; ++i) {
    +    att_type                                                                 UI8
    +    data_type                                                                UI8
    +    components_count                                                         UI8
    +    normalized                                                               UI8
    +    custom_id                                                                UI16
    +    Initialize GeometryAttribute ga
    +    att_id = pc->AddAttribute(new PointAttribute(ga));
    +    point_attribute_ids_[i] = att_id;
    +}
    +
    +
    + +

    Sequential Attributes Decoders Controller

    + +

    DecodeAttributesDecoderData()

    + +
    DecodeAttributesDecoderData(buffer) {
    +  AttributesDecoder_DecodeAttributesDecoderData(buffer)
    +  sequential_decoders_.resize(num_attributes());
    +  for (i = 0; i < num_attributes(); ++i) {
    +    decoder_type                                                             UI8
    +    sequential_decoders_[i] = CreateSequentialDecoder(decoder_type);
    +    sequential_decoders_[i]->Initialize(decoder(), GetAttributeId(i))
    +}
    +
    +
    + +

    DecodeAttributes()

    + +
    DecodeAttributes(buffer) {
    +  sequencer_->GenerateSequence(&point_ids_)
    +  for (i = 0; i < num_attributes(); ++i) {
    +    pa = decoder()->point_cloud()->attribute(GetAttributeId(i));
    +    sequencer_->UpdatePointToAttributeIndexMapping(pa)
    +  }
    +  for (i = 0; i < num_attributes(); ++i) {
    +    sequential_decoders_[i]->Decode(point_ids_, buffer)
    +    //SequentialAttributeDecoder_Decode()
    +  }
    +}
    +
    +
    + +

    CreateSequentialDecoder()

    + +
    CreateSequentialDecoder(type) {
    +  switch (type) {
    +    case SEQUENTIAL_ATTRIBUTE_ENCODER_GENERIC:
    +      return new SequentialAttributeDecoder()
    +    case SEQUENTIAL_ATTRIBUTE_ENCODER_INTEGER:
    +      return new SequentialIntegerAttributeDecoder()
    +    case SEQUENTIAL_ATTRIBUTE_ENCODER_QUANTIZATION:
    +      return new SequentialQuantizationAttributeDecoder()
    +    case SEQUENTIAL_ATTRIBUTE_ENCODER_NORMALS:
    +      return new SequentialNormalAttributeDecoder()
    +  }
    +}
    +
    +
    + +

    Sequential Attribute Decoder

    + +
    Initialize(...) {
    +  // Init some members
    +}
    +
    +
    + +

    DecodeValues()

    + +
    DecodeValues(const std::vector<PointIndex> &point_ids) {
    +  num_values = point_ids.size();
    +  entry_size = attribute_->byte_stride();
    +  std::unique_ptr<uint8_t[]> value_data_ptr(new uint8_t[entry_size]);
    +  out_byte_pos = 0;
    +  for (i = 0; i < num_values; ++i) {
    +   value_data                                                         UI8 * entry_size
    +    attribute_->buffer()->Write(out_byte_pos, value_data, entry_size);
    +    out_byte_pos += entry_size;
    +  }
    +}
    +
    +
    + +

    Sequential Integer Attribute Decoder

    + +
    Initialize(...) {
    +  SequentialAttributeDecoder_Initialize()
    +}
    +
    +
    + +

    DecodeValues()

    + +
    DecodeValues(point_ids) {
    +  prediction_scheme_method                                                   I8
    +  if (prediction_scheme_method != PREDICTION_NONE) {
    +    prediction_transform_type                                                I8
    +    prediction_scheme_ = CreateIntPredictionScheme(...)
    +  }
    +  if (prediction_scheme_) {
    +  }
    +  DecodeIntegerValues(point_ids)
    +  //SequentialQuantizationAttributeDecoder_DecodeIntegerValues()
    +  //StoreValues()
    +  DequantizeValues(num_values)
    +}
    +
    +
    + +

    DecodeIntegerValues()

    + +
    DecodeIntegerValues(point_ids) {
    +  compressed                                                                 UI8
    +  if (compressed) {
    +    DecodeSymbols(..., values_.data())
    +  } else {
    +  // TODO
    +  }
    +  if (!prediction_scheme_->AreCorrectionsPositive()) {
    +    ConvertSymbolsToSignedInts(...)
    +  }
    +  if (prediction_scheme_) {
    +    prediction_scheme_->DecodePredictionData(buffer)
    +    // DecodeTransformData(buffer)
    +    if (!values_.empty()) {
    +      prediction_scheme_->Decode(values_.data(), &values_[0],
    +                                      values_.size(), num_components, point_ids.data())
    +      // MeshPredictionSchemeParallelogram_Decode()
    +}
    +
    +
    + +

    Sequential Quantization Attribute Decoder

    + +
    Initialize(...) {
    +  SequentialIntegerAttributeDecoder_Initialize()
    +}
    +
    +
    + +

    DecodeIntegerValues()

    + +
    DecodeIntegerValues(point_ids) {
    +  // DecodeQuantizedDataInfo()
    +  num_components = attribute()->components_count();
    +  for (i = 0; i < num_components; ++i) {
    +    min_value_[i]                                                            F32
    +  }
    +  max_value_dif_                                                             F32
    +  quantization_bits_                                                         UI8
    +  SequentialIntegerAttributeDecoder::DecodeIntegerValues()
    +}
    +
    +
    + +

    DequantizeValues()

    + +
    DequantizeValues(num_values) {
    +  max_quantized_value = (1 << (quantization_bits_)) - 1;
    +  num_components = attribute()->components_count();
    +  entry_size = sizeof(float) * num_components;
    +  quant_val_id = 0;
    +  out_byte_pos = 0;
    +  for (i = 0; i < num_values; ++i) {
    +    for (c = 0; c < num_components; ++c) {
    +      value = dequantizer.DequantizeFloat(values()->at(quant_val_id++));
    +      value = value + min_value_[c];
    +      att_val[c] = value;
    +    }
    +    attribute()->buffer()->Write(out_byte_pos, att_val.get(), entry_size);
    +    out_byte_pos += entry_size;
    +  }
    +}
    +
    +
    + +

    Prediction Scheme Transform

    + +

    ComputeOriginalValue()

    + +
    ComputeOriginalValue(const DataTypeT *predicted_vals,
    +                                   const CorrTypeT *corr_vals,
    +                                   DataTypeT *out_original_vals, int val_id) {
    +  for (i = 0; i < num_components_; ++i) {
    +    out_original_vals[i] = predicted_vals[i] + corr_vals[val_id + i];
    +  }
    +}
    +
    +
    + +

    Prediction Scheme Wrap Transform

    + +

    DecodeTransformData()

    + +
    DecodeTransformData(buffer) {
    +  min_value_                                                                 DT
    +  max_value_                                                                 DT
    +}
    +
    +
    + +

    ComputeOriginalValue()

    + +
    ComputeOriginalValue(const DataTypeT *predicted_vals,
    +                                   const CorrTypeT *corr_vals,
    +                                   DataTypeT *out_original_vals, int val_id) {
    +  clamped_vals = ClampPredictedValue(predicted_vals);
    +  ComputeOriginalValue(clamped_vals, corr_vals, out_original_vals, val_id)
    +  // PredictionSchemeTransform_ComputeOriginalValue()
    +  for (i = 0; i < this->num_components(); ++i) {
    +    if (out_original_vals[i] > max_value_) {
    +      out_original_vals[i] -= max_dif_;
    +    } else if (out_original_vals[i] < min_value_) {
    +      out_original_vals[i] += max_dif_;
    +    }
    +}
    +
    +
    + +

    ClampPredictedValue()

    + +
    ClampPredictedValue(const DataTypeT *predicted_val) {
    +  for (i = 0; i < this->num_components(); ++i) {
    +    clamped_value_[i] = min(predicted_val[i], max_value_)
    +    clamped_value_[i] = max(predicted_val[i], min_value_)
    +  }
    +  return &clamped_value_[0];
    +}
    +
    +
    + +

    Mesh Prediction Scheme Parallelogram

    + +

    Decode()

    + +
    Decode(...) {
    +  this->transform().InitializeDecoding(num_components);
    +  // restore the first value
    +  this->transform().ComputeOriginalValue(pred_vals.get(),
    +                                       in_corr, out_data, 0);
    +  // PredictionSchemeWrapTransform_ComputeOriginalValue()
    +  corner_map_size = this->mesh_data().data_to_corner_map()->size();
    +  for (p = 1; p < corner_map_size; ++p) {
    +    corner_id = this->mesh_data().data_to_corner_map()->at(p);
    +    dst_offset = p * num_components;
    +    b= ComputeParallelogramPrediction(p, corner_id, table,
    +                                        *vertex_to_data_map, out_data,
    +                                        num_components, pred_vals.get())
    +    if (!b) {
    +      src_offset = (p - 1) * num_components;
    +      this->transform().ComputeOriginalValue(out_data + src_offset, in_corr,
    +                                             out_data + dst_offset, dst_offset);
    +      // PredictionSchemeWrapTransform_ComputeOriginalValue()
    +    } else {
    +      this->transform().ComputeOriginalValue(pred_vals.get(), in_corr,
    +                                             out_data + dst_offset, dst_offset);
    +      // PredictionSchemeWrapTransform_ComputeOriginalValue()
    +    }
    +  }
    +}
    +
    +
    + +

    MeshPredictionSchemeParallelogramShared

    + +

    ComputeParallelogramPrediction()

    + +
    ComputeParallelogramPrediction(...) {
    +  oci = table->Opposite(ci);
    +  vert_opp = vertex_to_data_map[table->Vertex(ci)];
    +  vert_next = vertex_to_data_map[table->Vertex(table->Next(ci))];
    +  vert_prev = vertex_to_data_map[table->Vertex(table->Previous(ci))];
    +  if (vert_opp < data_entry_id && vert_next < data_entry_id &&
    +      vert_prev < data_entry_id) {
    +    v_opp_off = vert_opp * num_components;
    +    v_next_off = vert_next * num_components;
    +    v_prev_off = vert_prev * num_components;
    +    for (c = 0; c < num_components; ++c) {
    +      out_prediction[c] = (in_data[v_next_off + c] + in_data[v_prev_off + c]) -
    +                          in_data[v_opp_off + c];
    +    }
    +    Return true;
    +  }
    +  return false;
    +}
    +
    +
    + +

    CornerTable Traversal Processor

    + +

    IsFaceVisited()

    + +
    IsFaceVisited(corner_id) {
    +  if (corner_id < 0)
    +    return true
    +  return is_face_visited_[corner_id / 3];
    +}
    +
    +
    + +

    MarkFaceVisited()

    + +
    MarkFaceVisited(face_id) {
    +  is_face_visited_[face_id] = true;
    +}
    +
    +
    + +

    IsVertexVisited()

    + +
    IsVertexVisited(vert_id) {
    +  return is_vertex_visited_[vert_id];
    +}
    +
    +
    + +

    MarkVertexVisited()

    + +
    MarkVertexVisited(vert_id) {
    +  is_vertex_visited_[vert_id] = true;
    +}
    +
    +
    + +

    Mesh Attribute Indices Encoding Observer

    + +

    OnNewVertexVisited()

    + +
    OnNewVertexVisited(vertex, corner) {
    +  point_id = mesh_->face(corner / 3)[corner % 3];
    +  sequencer_->AddPointId(point_id);
    +  // Keep track of visited corners.
    +  encoding_data_->encoded_attribute_value_index_to_corner_map.push_back(corner);
    +  encoding_data_
    +        ->vertex_to_encoded_attribute_value_index_map[vertex] =
    +        encoding_data_->num_values;
    +  encoding_data_->num_values++;
    +}
    +
    +
    + +

    EdgeBreaker Traverser

    + +

    TraverseFromCorner()

    + +
    TraverseFromCorner(corner_id) {
    +  if (processor_.IsFaceVisited(corner_id))
    +    return
    +  corner_traversal_stack_.clear();
    +  corner_traversal_stack_.push_back(corner_id);
    +  next_vert = corner_table_->Vertex(corner_table_->Next(corner_id));
    +  prev_vert = corner_table_->Vertex(corner_table_->Previous(corner_id));
    +  if (!processor_.IsVertexVisited(next_vert)) {
    +    processor_.MarkVertexVisited(next_vert);
    +    traversal_observer_.OnNewVertexVisited(next_vert,
    +                                        corner_table_->Next(corner_id));
    +  }
    +  if (!processor_.IsVertexVisited(prev_vert)) {
    +    processor_.MarkVertexVisited(prev_vert);
    +    traversal_observer_.OnNewVertexVisited(prev_vert,
    +                                        corner_table_->Previous(corner_id));
    +  }
    +  while (!corner_traversal_stack_.empty()) {
    +    corner_id = corner_traversal_stack_.back();
    +    face_id =corner_id / 3;
    +    if (processor_.IsFaceVisited(face_id)) {
    +      corner_traversal_stack_.pop_back();
    +      continue
    +    }
    +    while(true) {
    +      face_id = corner_id / 3;
    +      processor_.MarkFaceVisited(face_id);
    +      traversal_observer_.OnNewFaceVisited(face_id);
    +      vert_id = corner_table_->Vertex(corner_id);
    +      on_boundary = corner_table_->IsOnBoundary(vert_id);
    +      if (!processor_.IsVertexVisited(vert_id)) {
    +        processor_.MarkVertexVisited(vert_id);
    +        traversal_observer_.OnNewVertexVisited(vert_id, corner_id);
    +        if (!on_boundary) {
    +          corner_id = corner_table_->GetRightCorner(corner_id);
    +          continue;
    +        }
    +      }
    +      // The current vertex has been already visited or it was on a boundary.
    +      right_corner_id = corner_table_->GetRightCorner(corner_id);
    +      left_corner_id = corner_table_->GetLeftCorner(corner_id);
    +      right_face_id((right_corner_id < 0 ? -1 : right_corner_id / 3));
    +      left_face_id((left_corner_id < 0 ? -1 : left_corner_id / 3));
    +      if (processor_.IsFaceVisited(right_face_id)) {
    +        if (processor_.IsFaceVisited(left_face_id)) {
    +          corner_traversal_stack_.pop_back();
    +          break; // Break from while(true) loop
    +        } else {
    +          corner_id = left_corner_id;
    +        }
    +      } else {
    +        if (processor_.IsFaceVisited(left_face_id)) {
    +          corner_id = right_corner_id;
    +       } else {
    +          // Split the traversal.
    +          corner_traversal_stack_.back() = left_corner_id;
    +          corner_traversal_stack_.push_back(right_corner_id);
    +          break; // Break from while(true) loop
    +        }
    +      }
    +    }
    +  }
    +}
    +
    +
    + +

    Mesh Traversal Sequencer

    + +

    GenerateSequenceInternal()

    + +
    GenerateSequenceInternal() {
    +  traverser_.OnTraversalStart();
    +   If (corner_order_) {
    +    // TODO
    +  } else {
    +    int32_t num_faces = traverser_.corner_table()->num_faces();
    +    for (i = 0; i < num_faces; ++i) {
    +      ProcessCorner(3 * i)
    +    }
    +  }
    +  traverser_.OnTraversalEnd();
    +}
    +
    +
    + +

    ProcessCorner()

    + +
    ProcessCorner(corner_id) {
    +  traverser_.TraverseFromCorner(corner_id);
    +}
    +
    +
    + +

    UpdatePointToAttributeIndexMapping()

    + +
    UpdatePointToAttributeIndexMapping(PointAttribute *attribute) {
    +  corner_table = traverser_.corner_table();
    +  attribute->SetExplicitMapping(mesh_->num_points());
    +  num_faces = mesh_->num_faces();
    +  num_points = mesh_->num_points();
    +  for (f = 0; f < num_faces; ++f) {
    +    face = mesh_->face(f);
    +    for (p = 0; p < 3; ++p) {
    +      point_id = face[p];
    +      vert_id = corner_table->Vertex(3 * f + p);
    +      att_entry_id(
    +            encoding_data_
    +                ->vertex_to_encoded_attribute_value_index_map[vert_id]);
    +      attribute->SetPointMapEntry(point_id, att_entry_id);
    +    }
    +  }
    +}
    +
    +
    + +

    PointsSequencer

    + +

    AddPointId()

    + +
    AddPointId(point_id) {
    +  out_point_ids_->push_back(point_id);
    +}
    +
    +
    + +

    Corner Table

    + +

    Opposite()

    + +
    Opposite(corner) {
    +  return opposite_corners_[corner];
    +}
    +
    +
    + +

    Next()

    + +
    Next(corner) {
    +  return LocalIndex(++corner) ? corner : corner - 3;
    +}
    +
    +
    + +

    Previous()

    + +
    Previous(corner) {
    +  return LocalIndex(corner) ? corner - 1 : corner + 2;
    +}
    +
    +
    + +

    Vertex()

    + +
    Vertex(corner) {
    +  faces_[Face(corner)][LocalIndex(corner)];
    +}
    +
    +
    + +

    Face()

    + +
    Face(corner) {
    +  return corner / 3;
    +}
    +
    +
    + +

    LocalIndex()

    + +
    LocalIndex(corner) {
    +  return corner % 3;
    +}
    +
    +
    + +

    num_vertices()

    + +
    num_vertices() {
    +  return vertex_corners_.size();
    +}
    +
    +
    + +

    num_corners()

    + +
    num_corners() {
    +  return faces_.size() * 3;
    +}
    +
    +
    + +

    num_faces()

    + +
    num_faces() {
    +  return faces_.size();
    +}
    +
    +
    + +

    bool IsOnBoundary()

    + +
    bool IsOnBoundary(vert) {
    +  corner = LeftMostCorner(vert);
    +  if (SwingLeft(corner) < 0)
    +    return true;
    +  return false;
    +}
    +
    +
    + +

    SwingRight()

    + +
    SwingRight(corner) {
    +  return Previous(Opposite(Previous(corner)));
    +}
    +
    +
    + +

    SwingLeft()

    + +
    SwingLeft(corner) {
    +  return Next(Opposite(Next(corner)));
    +}
    +
    +
    + +

    GetLeftCorner()

    + +
    GetLeftCorner(corner_id) {
    +  if (corner_id < 0)
    +     return kInvalidCornerIndex;
    +  return Opposite(Previous(corner_id));
    +}
    +
    +
    + +

    GetRightCorner()

    + +
    GetRightCorner(corner_id) {
    +  if (corner_id < 0)
    +     return kInvalidCornerIndex;
    +  return Opposite(Next(corner_id));
    +}
    +
    +
    + +

    SetOppositeCorner()

    + +
    SetOppositeCorner(corner_id, pp_corner_id) {
    +  opposite_corners_[corner_id] = opp_corner_id;
    +}
    +
    +
    + +

    MapCornerToVertex()

    + +
    MapCornerToVertex(corner_id, vert_id) {
    +  face = Face(corner_id);
    +  faces_[face][LocalIndex(corner_id)] = vert_id;
    +  if (vert_id >= 0) {
    +    vertex_corners_[vert_id] = corner_id;
    +  }
    +}
    +
    +
    + +

    UpdateVertexToCornerMap()

    + +
    UpdateVertexToCornerMap(vert) {
    +  first_c = vertex_corners_[vert];
    +  if (first_c < 0)
    +    return;
    +  act_c = SwingLeft(first_c);
    +  c = first_c;
    +  while (act_c >= 0 && act_c != first_c) {
    +    c = act_c;
    +    act_c = SwingLeft(act_c);
    +  }
    +  if (act_c != first_c) {
    +    vertex_corners_[vert] = c;
    +  }
    +}
    +
    +
    + +

    LeftMostCorner()

    + +
    LeftMostCorner(v) {
    +  return vertex_corners_[v];
    +}
    +
    +
    + +

    MakeVertexIsolated()

    + +
    MakeVertexIsolated(vert) {
    +  vertex_corners_[vert] = kInvalidCornerIndex;
    +}
    +
    +
    + +

    Mesh Attribute Corner Table

    + +

    bool IsCornerOnSeam()

    + +
    bool IsCornerOnSeam(corner) {
    +  return is_vertex_on_seam_[corner_table_->Vertex(corner)];
    +}
    +
    +
    + +

    AddSeamEdge()

    + +
    AddSeamEdge(c) {
    +  MarkSeam(c)
    +  opp_corner = corner_table_->Opposite(c);
    +  if (opp_corner >= 0) {
    +    no_interior_seams_ = false;
    +    MarkSeam(opp_corner)
    +  }
    +}
    +
    +
    + +

    MarkSeam()

    + +
    MarkSeam(c) {
    +  is_edge_on_seam_[c] = true;
    +  is_vertex_on_seam_[corner_table_->Vertex(corner_table_->Next(c))] = true;
    +  is_vertex_on_seam_[corner_table_->Vertex(corner_table_->Previous(c))
    +                         ] = true;
    +}
    +
    +
    + +

    RecomputeVertices()

    + +
    RecomputeVertices() {
    +  // in code RecomputeVerticesInternal<false>(nullptr, nullptr)
    +  num_new_vertices = 0;
    +  for (v = 0; v < corner_table_->num_vertices(); ++v) {
    +    c = corner_table_->LeftMostCorner(v);
    +    if (c < 0)
    +      continue;
    +    first_vert_id(num_new_vertices++);
    +    vertex_to_attribute_entry_id_map_.push_back(first_vert_id);
    +    first_c = c;
    +    if (is_vertex_on_seam_[v]) {
    +      act_c = SwingLeft(first_c);
    +      while (act_c >= 0) {
    +        first_c = act_c;
    +        act_c = SwingLeft(act_c);
    +      }
    +    }
    +    corner_to_vertex_map_[first_c] =first_vert_id;
    +    vertex_to_left_most_corner_map_.push_back(first_c);
    +    act_c = corner_table_->SwingRight(first_c);
    +    while (act_c >= 0 && act_c != first_c) {
    +      if (is_edge_on_seam_[corner_table_->Next(act_c)]) {
    +        // in code IsCornerOppositeToSeamEdge()
    +        first_vert_id = AttributeValueIndex(num_new_vertices++);
    +        vertex_to_attribute_entry_id_map_.push_back(first_vert_id);
    +        vertex_to_left_most_corner_map_.push_back(act_c);
    +      }
    +      corner_to_vertex_map_[act_c] = first_vert_id;
    +      act_c = corner_table_->SwingRight(act_c);
    +    }
    +  }
    +}
    +
    +
    + +

    Symbol Decoding

    + +

    DecodeSymbols()

    + +
    DecodeSymbols(num_symbols, out_buffer, out_values) {
    +  scheme                                                                     UI8
    +  If (scheme == 0) {
    +    DecodeTaggedSymbols<>(num_symbols, src_buffer, out_values)
    +  } else if (scheme == 1) {
    +    DecodeRawSymbols<>(num_symbols, src_buffer, out_values)
    +  }
    +}
    +
    +
    + +

    DecodeTaggedSymbols()

    + +
    DecodeTaggedSymbols() {
    +  FIXME
    +}
    +
    +
    + +

    DecodeRawSymbols()

    + +
    DecodeRawSymbols() {
    +  max_bit_length                                                             UI8
    +  DecodeRawSymbolsInternal(max_bit_length, out_values)
    +  return symbols
    +}
    +
    +
    + +

    DecodeRawSymbolsInternal()

    + +
    DecodeRawSymbolsInternal(max_bit_length, out_values) {
    +  decoder = CreateRansSymbolDecoder(max_bit_length)
    +  decoder.StartDecoding()
    +  // RansSymbolDecoder_StartDecoding
    +  for (i = 0; i < num_values; ++i) {
    +    out_values[i] = decoder.DecodeSymbol()
    +    // RansSymbolDecoder_DecodeSymbol
    +  }
    +}
    +
    +
    + +

    CreateRansSymbolDecoder()

    + +
    CreateRansSymbolDecoder(max_bit_length) {
    +  rans_precision_bits  = (3 * max_bit_length) / 2;
    +  rans_precision_bits = min(rans_precision_bits, 20)
    +  rans_precision_bits = max(rans_precision_bits, 12)
    +  rans_precision = 1 << rans_precision_bits_;
    +  l_rans_base = rans_precision * 4;
    +  num_symbols_                                                               UI32
    +  for (i = 0; i < num_symbols_; ++i) {
    +    prob_data                                                                UI8
    +    if ((prob_data & 3) == 3) {
    +      offset = prob_data >> 2
    +      for (j = 0; j < offset + 1; ++j) {
    +        probability_table_[i + j] = 0;
    +      }
    +      i += offset;
    +    } else {
    +      prob = prob_data >> 2
    +      for (j = 0; j < token; ++j) {
    +        eb                                                                   UI8
    +        prob = prob | (eb << (8 * (j + 1) - 2)
    +      }
    +      probability_table_[i] = prob;
    +    }
    +  }
    +  rans_build_look_up_table()
    +}
    +
    +
    + +

    RansSymbolDecoder_StartDecoding()

    + +
    RansSymbolDecoder_StartDecoding() {
    +  bytes_encoded                                                              UI64
    +  buffer                                                                     bytes_encoded * UI8
    +  rans_read_init(buffer, bytes_encoded)
    +}
    +
    +
    + +

    RansSymbolDecoder_DecodeSymbol()

    + +
    RansSymbolDecoder_DecodeSymbol() {
    +  ans_.rans_read()
    +}
    +
    +
    + +

    Rans Decoding

    + +

    ans_read_init()

    + +
    ans_read_init(struct AnsDecoder *const ans, const uint8_t *const buf,
    +                       int offset) {
    +  x = buf[offset - 1] >> 6
    +  If (x == 0) {
    +    ans->buf_offset = offset - 1;
    +    ans->state = buf[offset - 1] & 0x3F;
    +  } else if (x == 1) {
    +    ans->buf_offset = offset - 2;
    +    ans->state = mem_get_le16(buf + offset - 2) & 0x3FFF;
    +  } else if (x == 2) {
    +    ans->buf_offset = offset - 3;
    +    ans->state = mem_get_le24(buf + offset - 3) & 0x3FFFFF;
    +  } else if (x == 3) {
    +   // x == 3 implies this byte is a superframe marker
    +    return 1;
    +  }
    +  ans->state += l_base;
    +}
    +
    +
    + +

    int rabs_desc_read()

    + +
    int rabs_desc_read(struct AnsDecoder *ans, AnsP8 p0) {
    +  AnsP8 p = ans_p8_precision - p0;
    +  if (ans->state < l_base) {
    +    ans->state = ans->state * io_base + ans->buf[--ans->buf_offset];
    +  }
    +  x = ans->state;
    +  quot = x / ans_p8_precision;
    +  rem = x % ans_p8_precision;
    +  xn = quot * p;
    +  val = rem < p;
    +  if (val) {
    +    ans->state = xn + rem;
    +  } else {
    +    ans->state = x - xn - p;
    +  }
    +  return val;
    +}
    +
    +
    + +

    rans_read_init()

    + +
    rans_read_init(UI8 *buf, int offset) {
    +  ans_.buf = buf;
    +  x = buf[offset - 1] >> 6
    +  If (x == 0) {
    +    ans_.buf_offset = offset - 1;
    +    ans_.state = buf[offset - 1] & 0x3F;
    +  } else if (x == 1) {
    +    ans_.buf_offset = offset - 2;
    +    ans_.state = mem_get_le16(buf + offset - 2) & 0x3FFF;
    +  } else if (x == 2) {
    +    ans_.buf_offset = offset - 3;
    +    ans_.state = mem_get_le24(buf + offset - 3) & 0x3FFFFF;
    +  } else if (x == 3) {
    +    ans_.buf_offset = offset - 4;
    +    ans_.state = mem_get_le32(buf + offset - 4) & 0x3FFFFFFF;
    +  }
    +  ans_.state += l_rans_base;
    +}
    +
    +
    + +

    rans_build_look_up_table()

    + +
    rans_build_look_up_table() {
    +  cum_prob = 0
    +  act_prob = 0
    +  for (i = 0; i < num_symbols; ++i) {
    +    probability_table_[i].prob = token_probs[i];
    +    probability_table_[i].cum_prob = cum_prob;
    +    cum_prob += token_probs[i];
    +    for (j = act_prob; j < cum_prob; ++j) {
    +      Lut_table_[j] = i
    +    }
    +    act_prob = cum_prob
    +}
    +
    +
    + +

    rans_read()

    + +
    rans_read() {
    +  while (ans_.state < l_rans_base) {
    +    ans_.state = ans_.state * io_base + ans_.buf[--ans_.buf_offset];
    +  }
    +  quo = ans_.state / rans_precision;
    +  rem = ans_.state % rans_precision;
    +  sym = fetch_sym()
    +  ans_.state = quo * sym.prob + rem - sym.cum_prob;
    +  return sym.val;
    +}
    +
    +
    + +

    fetch_sym()

    + +
    fetch_sym() {
    +  symbol = lut_table[rem]
    +  out->val = symbol
    +  out->prob = probability_table_[symbol].prob;
    +  out->cum_prob = probability_table_[symbol].cum_prob;
    +}
    +
    +
    + +

    Rans Bit Decoder

    + +

    RansBitDecoder_StartDecoding()

    + +
    RansBitDecoder_StartDecoding(DecoderBuffer *source_buffer) {
    +  prob_zero_                                                                 UI8
    +  size                                                                       UI32
    +  buffer_                                                                    size * UI8
    +  ans_read_init(&ans_decoder_, buffer_, size)
    +}
    +
    +
    + +

    DecodeNextBit()

    + +
    DecodeNextBit() {
    +  uint8_t bit = rabs_desc_read(&ans_decoder_, prob_zero_);
    +  return bit > 0;
    +}
    +
    +
    + +

    Core Functions

    + +

    DecodeVarint

    + +
    DecodeVarint<IT>() {
    +  If (std::is_unsigned<IT>::value) {
    +    in                                                                       UI8
    +    If (in & (1 << 7)) {
    +      out = DecodeVarint<IT>()
    +      out = (out << 7) | (in & ((1 << 7) - 1))
    +    } else {
    +      typename std::make_unsigned<IT>::type UIT;
    +      out = DecodeVarint<UIT>()
    +      out = ConvertSymbolToSignedInt(out)
    +    }
    +    return out;
    +}
    +
    +
    + +

    ConvertSymbolToSignedInt()

    + +
    ConvertSymbolToSignedInt() {
    +  abs_val = val >> 1
    +  If (val & 1 == 0) {
    +    return abs_val
    +  } else {
    +    signed_val = -abs_val - 1
    +  }
    +  return signed_val
    +}
    +
    +
    + +

    Sequential Decoder

    + +

    decode_connectivity()

    + +
    decode_connectivity() {
    +  num_faces                                                       I32
    +  num_points                                                      I32
    +  connectivity _method                                            UI8
    +  If (connectivity _method == 0) {
    +    // TODO
    +  } else {
    +    loop num_faces {
    +      If (num_points < 256) {
    +        face[]                                                    UI8
    +      } else if (num_points < (1 << 16)) {
    +        face[]                                                    UI16
    +      } else {
    +        face[]                                                    UI32
    +      }
    +    }
    +  }
    +}
    +
    +
    + + + + + + diff --git a/docs/_site/spec/mesh.decoder.html b/docs/_site/spec/mesh.decoder.html new file mode 100644 index 0000000..d4d0d2a --- /dev/null +++ b/docs/_site/spec/mesh.decoder.html @@ -0,0 +1,11 @@ +

    Mesh Decoder

    + +

    DecodeConnectivityData()

    + +
    +DecodeConnectivityData() Type + InitializeDecoder() + DecodeConnectivity() +} + +
    diff --git a/docs/_site/spec/mesh.decoder.md b/docs/_site/spec/mesh.decoder.md new file mode 100644 index 0000000..c283bea --- /dev/null +++ b/docs/_site/spec/mesh.decoder.md @@ -0,0 +1,11 @@ +## Mesh Decoder + +### DecodeConnectivityData() + +
    +DecodeConnectivityData() Type + InitializeDecoder() + DecodeConnectivity() +} + +
    diff --git a/docs/assets/css/pygments/README.md b/docs/assets/css/pygments/README.md new file mode 100644 index 0000000..83c205a --- /dev/null +++ b/docs/assets/css/pygments/README.md @@ -0,0 +1,23 @@ +# jekyll-pygments-themes + +A set of CSS theme files for Pygments (Python-based code highlighting tool) +created from the original built-in Pygments styles, ready for use with Jekyll. + +## Theme Previews and Custom Theme Builder +- + +## Using Themes Without Jekyll +If you want to use the themes with something other than Jekyll, you may need to +remove or change the CSS style prefix of `.highlight`. + +## Links + +- [Jekyll](http://jekyllrb.com/) ([direct link to code highlighting documentation](http://jekyllrb.com/docs/templates/#code-snippet-highlighting)) +- [Pygments](http://pygments.org) + +## Hacking + +If you want to hack on the site, check out the [gh-pages](https://github.com/jwarby/jekyll-pygments-themes/tree/gh-pages) branch. + +## Acknowledgements +Forked from [richleland/pygments-css](https://github.com/richleland/pygments-css). diff --git a/docs/assets/css/pygments/UNLICENSE.txt b/docs/assets/css/pygments/UNLICENSE.txt new file mode 100644 index 0000000..cf1ab25 --- /dev/null +++ b/docs/assets/css/pygments/UNLICENSE.txt @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/docs/assets/css/pygments/autumn.css b/docs/assets/css/pygments/autumn.css new file mode 100644 index 0000000..a5f3d4c --- /dev/null +++ b/docs/assets/css/pygments/autumn.css @@ -0,0 +1,58 @@ +.highlight .hll { background-color: #ffffcc } +.highlight .c { color: #aaaaaa; font-style: italic } /* Comment */ +.highlight .err { color: #F00000; background-color: #F0A0A0 } /* Error */ +.highlight .k { color: #0000aa } /* Keyword */ +.highlight .cm { color: #aaaaaa; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #4c8317 } /* Comment.Preproc */ +.highlight .c1 { color: #aaaaaa; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #0000aa; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #aa0000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #aa0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00aa00 } /* Generic.Inserted */ +.highlight .go { color: #888888 } /* Generic.Output */ +.highlight .gp { color: #555555 } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #aa0000 } /* Generic.Traceback */ +.highlight .kc { color: #0000aa } /* Keyword.Constant */ +.highlight .kd { color: #0000aa } /* Keyword.Declaration */ +.highlight .kn { color: #0000aa } /* Keyword.Namespace */ +.highlight .kp { color: #0000aa } /* Keyword.Pseudo */ +.highlight .kr { color: #0000aa } /* Keyword.Reserved */ +.highlight .kt { color: #00aaaa } /* Keyword.Type */ +.highlight .m { color: #009999 } /* Literal.Number */ +.highlight .s { color: #aa5500 } /* Literal.String */ +.highlight .na { color: #1e90ff } /* Name.Attribute */ +.highlight .nb { color: #00aaaa } /* Name.Builtin */ +.highlight .nc { color: #00aa00; text-decoration: underline } /* Name.Class */ +.highlight .no { color: #aa0000 } /* Name.Constant */ +.highlight .nd { color: #888888 } /* Name.Decorator */ +.highlight .ni { color: #800000; font-weight: bold } /* Name.Entity */ +.highlight .nf { color: #00aa00 } /* Name.Function */ +.highlight .nn { color: #00aaaa; text-decoration: underline } /* Name.Namespace */ +.highlight .nt { color: #1e90ff; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #aa0000 } /* Name.Variable */ +.highlight .ow { color: #0000aa } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #009999 } /* Literal.Number.Float */ +.highlight .mh { color: #009999 } /* Literal.Number.Hex */ +.highlight .mi { color: #009999 } /* Literal.Number.Integer */ +.highlight .mo { color: #009999 } /* Literal.Number.Oct */ +.highlight .sb { color: #aa5500 } /* Literal.String.Backtick */ +.highlight .sc { color: #aa5500 } /* Literal.String.Char */ +.highlight .sd { color: #aa5500 } /* Literal.String.Doc */ +.highlight .s2 { color: #aa5500 } /* Literal.String.Double */ +.highlight .se { color: #aa5500 } /* Literal.String.Escape */ +.highlight .sh { color: #aa5500 } /* Literal.String.Heredoc */ +.highlight .si { color: #aa5500 } /* Literal.String.Interpol */ +.highlight .sx { color: #aa5500 } /* Literal.String.Other */ +.highlight .sr { color: #009999 } /* Literal.String.Regex */ +.highlight .s1 { color: #aa5500 } /* Literal.String.Single */ +.highlight .ss { color: #0000aa } /* Literal.String.Symbol */ +.highlight .bp { color: #00aaaa } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #aa0000 } /* Name.Variable.Class */ +.highlight .vg { color: #aa0000 } /* Name.Variable.Global */ +.highlight .vi { color: #aa0000 } /* Name.Variable.Instance */ +.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */ diff --git a/docs/assets/css/pygments/borland.css b/docs/assets/css/pygments/borland.css new file mode 100644 index 0000000..2e98c79 --- /dev/null +++ b/docs/assets/css/pygments/borland.css @@ -0,0 +1,46 @@ +.highlight .hll { background-color: #ffffcc } +.highlight .c { color: #008800; font-style: italic } /* Comment */ +.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ +.highlight .k { color: #000080; font-weight: bold } /* Keyword */ +.highlight .cm { color: #008800; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #008080 } /* Comment.Preproc */ +.highlight .c1 { color: #008800; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #008800; font-weight: bold } /* Comment.Special */ +.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #aa0000 } /* Generic.Error */ +.highlight .gh { color: #999999 } /* Generic.Heading */ +.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ +.highlight .go { color: #888888 } /* Generic.Output */ +.highlight .gp { color: #555555 } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #aaaaaa } /* Generic.Subheading */ +.highlight .gt { color: #aa0000 } /* Generic.Traceback */ +.highlight .kc { color: #000080; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #000080; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #000080; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #000080; font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { color: #000080; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #000080; font-weight: bold } /* Keyword.Type */ +.highlight .m { color: #0000FF } /* Literal.Number */ +.highlight .s { color: #0000FF } /* Literal.String */ +.highlight .na { color: #FF0000 } /* Name.Attribute */ +.highlight .nt { color: #000080; font-weight: bold } /* Name.Tag */ +.highlight .ow { font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #0000FF } /* Literal.Number.Float */ +.highlight .mh { color: #0000FF } /* Literal.Number.Hex */ +.highlight .mi { color: #0000FF } /* Literal.Number.Integer */ +.highlight .mo { color: #0000FF } /* Literal.Number.Oct */ +.highlight .sb { color: #0000FF } /* Literal.String.Backtick */ +.highlight .sc { color: #800080 } /* Literal.String.Char */ +.highlight .sd { color: #0000FF } /* Literal.String.Doc */ +.highlight .s2 { color: #0000FF } /* Literal.String.Double */ +.highlight .se { color: #0000FF } /* Literal.String.Escape */ +.highlight .sh { color: #0000FF } /* Literal.String.Heredoc */ +.highlight .si { color: #0000FF } /* Literal.String.Interpol */ +.highlight .sx { color: #0000FF } /* Literal.String.Other */ +.highlight .sr { color: #0000FF } /* Literal.String.Regex */ +.highlight .s1 { color: #0000FF } /* Literal.String.Single */ +.highlight .ss { color: #0000FF } /* Literal.String.Symbol */ +.highlight .il { color: #0000FF } /* Literal.Number.Integer.Long */ diff --git a/docs/assets/css/pygments/bw.css b/docs/assets/css/pygments/bw.css new file mode 100644 index 0000000..632756b --- /dev/null +++ b/docs/assets/css/pygments/bw.css @@ -0,0 +1,34 @@ +.highlight .hll { background-color: #ffffcc } +.highlight .c { font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { font-weight: bold } /* Keyword */ +.highlight .cm { font-style: italic } /* Comment.Multiline */ +.highlight .c1 { font-style: italic } /* Comment.Single */ +.highlight .cs { font-style: italic } /* Comment.Special */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gh { font-weight: bold } /* Generic.Heading */ +.highlight .gp { font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { font-weight: bold } /* Generic.Subheading */ +.highlight .kc { font-weight: bold } /* Keyword.Constant */ +.highlight .kd { font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { font-weight: bold } /* Keyword.Namespace */ +.highlight .kr { font-weight: bold } /* Keyword.Reserved */ +.highlight .s { font-style: italic } /* Literal.String */ +.highlight .nc { font-weight: bold } /* Name.Class */ +.highlight .ni { font-weight: bold } /* Name.Entity */ +.highlight .ne { font-weight: bold } /* Name.Exception */ +.highlight .nn { font-weight: bold } /* Name.Namespace */ +.highlight .nt { font-weight: bold } /* Name.Tag */ +.highlight .ow { font-weight: bold } /* Operator.Word */ +.highlight .sb { font-style: italic } /* Literal.String.Backtick */ +.highlight .sc { font-style: italic } /* Literal.String.Char */ +.highlight .sd { font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { font-style: italic } /* Literal.String.Double */ +.highlight .se { font-weight: bold; font-style: italic } /* Literal.String.Escape */ +.highlight .sh { font-style: italic } /* Literal.String.Heredoc */ +.highlight .si { font-weight: bold; font-style: italic } /* Literal.String.Interpol */ +.highlight .sx { font-style: italic } /* Literal.String.Other */ +.highlight .sr { font-style: italic } /* Literal.String.Regex */ +.highlight .s1 { font-style: italic } /* Literal.String.Single */ +.highlight .ss { font-style: italic } /* Literal.String.Symbol */ diff --git a/docs/assets/css/pygments/colorful.css b/docs/assets/css/pygments/colorful.css new file mode 100644 index 0000000..e5abd69 --- /dev/null +++ b/docs/assets/css/pygments/colorful.css @@ -0,0 +1,61 @@ +.highlight .hll { background-color: #ffffcc } +.highlight .c { color: #808080 } /* Comment */ +.highlight .err { color: #F00000; background-color: #F0A0A0 } /* Error */ +.highlight .k { color: #008000; font-weight: bold } /* Keyword */ +.highlight .o { color: #303030 } /* Operator */ +.highlight .cm { color: #808080 } /* Comment.Multiline */ +.highlight .cp { color: #507090 } /* Comment.Preproc */ +.highlight .c1 { color: #808080 } /* Comment.Single */ +.highlight .cs { color: #cc0000; font-weight: bold } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #808080 } /* Generic.Output */ +.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0040D0 } /* Generic.Traceback */ +.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #003080; font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #303090; font-weight: bold } /* Keyword.Type */ +.highlight .m { color: #6000E0; font-weight: bold } /* Literal.Number */ +.highlight .s { background-color: #fff0f0 } /* Literal.String */ +.highlight .na { color: #0000C0 } /* Name.Attribute */ +.highlight .nb { color: #007020 } /* Name.Builtin */ +.highlight .nc { color: #B00060; font-weight: bold } /* Name.Class */ +.highlight .no { color: #003060; font-weight: bold } /* Name.Constant */ +.highlight .nd { color: #505050; font-weight: bold } /* Name.Decorator */ +.highlight .ni { color: #800000; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #F00000; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #0060B0; font-weight: bold } /* Name.Function */ +.highlight .nl { color: #907000; font-weight: bold } /* Name.Label */ +.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #007000 } /* Name.Tag */ +.highlight .nv { color: #906030 } /* Name.Variable */ +.highlight .ow { color: #000000; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #6000E0; font-weight: bold } /* Literal.Number.Float */ +.highlight .mh { color: #005080; font-weight: bold } /* Literal.Number.Hex */ +.highlight .mi { color: #0000D0; font-weight: bold } /* Literal.Number.Integer */ +.highlight .mo { color: #4000E0; font-weight: bold } /* Literal.Number.Oct */ +.highlight .sb { background-color: #fff0f0 } /* Literal.String.Backtick */ +.highlight .sc { color: #0040D0 } /* Literal.String.Char */ +.highlight .sd { color: #D04020 } /* Literal.String.Doc */ +.highlight .s2 { background-color: #fff0f0 } /* Literal.String.Double */ +.highlight .se { color: #606060; font-weight: bold; background-color: #fff0f0 } /* Literal.String.Escape */ +.highlight .sh { background-color: #fff0f0 } /* Literal.String.Heredoc */ +.highlight .si { background-color: #e0e0e0 } /* Literal.String.Interpol */ +.highlight .sx { color: #D02000; background-color: #fff0f0 } /* Literal.String.Other */ +.highlight .sr { color: #000000; background-color: #fff0ff } /* Literal.String.Regex */ +.highlight .s1 { background-color: #fff0f0 } /* Literal.String.Single */ +.highlight .ss { color: #A06000 } /* Literal.String.Symbol */ +.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #306090 } /* Name.Variable.Class */ +.highlight .vg { color: #d07000; font-weight: bold } /* Name.Variable.Global */ +.highlight .vi { color: #3030B0 } /* Name.Variable.Instance */ +.highlight .il { color: #0000D0; font-weight: bold } /* Literal.Number.Integer.Long */ diff --git a/docs/assets/css/pygments/default.css b/docs/assets/css/pygments/default.css new file mode 100644 index 0000000..8070f2f --- /dev/null +++ b/docs/assets/css/pygments/default.css @@ -0,0 +1,61 @@ +.highlight .hll { background-color: #ffffcc } +.highlight .c { color: #408080; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #008000; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #BC7A00 } /* Comment.Preproc */ +.highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #408080; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #808080 } /* Generic.Output */ +.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0040D0 } /* Generic.Traceback */ +.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #008000 } /* Keyword.Pseudo */ +.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #B00040 } /* Keyword.Type */ +.highlight .m { color: #666666 } /* Literal.Number */ +.highlight .s { color: #BA2121 } /* Literal.String */ +.highlight .na { color: #7D9029 } /* Name.Attribute */ +.highlight .nb { color: #008000 } /* Name.Builtin */ +.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.highlight .no { color: #880000 } /* Name.Constant */ +.highlight .nd { color: #AA22FF } /* Name.Decorator */ +.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #0000FF } /* Name.Function */ +.highlight .nl { color: #A0A000 } /* Name.Label */ +.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #19177C } /* Name.Variable */ +.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #666666 } /* Literal.Number.Float */ +.highlight .mh { color: #666666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666666 } /* Literal.Number.Oct */ +.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ +.highlight .sc { color: #BA2121 } /* Literal.String.Char */ +.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #BA2121 } /* Literal.String.Double */ +.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ +.highlight .sx { color: #008000 } /* Literal.String.Other */ +.highlight .sr { color: #BB6688 } /* Literal.String.Regex */ +.highlight .s1 { color: #BA2121 } /* Literal.String.Single */ +.highlight .ss { color: #19177C } /* Literal.String.Symbol */ +.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #19177C } /* Name.Variable.Class */ +.highlight .vg { color: #19177C } /* Name.Variable.Global */ +.highlight .vi { color: #19177C } /* Name.Variable.Instance */ +.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ diff --git a/docs/assets/css/pygments/emacs.css b/docs/assets/css/pygments/emacs.css new file mode 100644 index 0000000..489c0ad --- /dev/null +++ b/docs/assets/css/pygments/emacs.css @@ -0,0 +1,61 @@ +.highlight .hll { background-color: #ffffcc } +.highlight .c { color: #008800; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #AA22FF; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .cm { color: #008800; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #008800 } /* Comment.Preproc */ +.highlight .c1 { color: #008800; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #008800; font-weight: bold } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #808080 } /* Generic.Output */ +.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0040D0 } /* Generic.Traceback */ +.highlight .kc { color: #AA22FF; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #AA22FF; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #AA22FF; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #AA22FF } /* Keyword.Pseudo */ +.highlight .kr { color: #AA22FF; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #00BB00; font-weight: bold } /* Keyword.Type */ +.highlight .m { color: #666666 } /* Literal.Number */ +.highlight .s { color: #BB4444 } /* Literal.String */ +.highlight .na { color: #BB4444 } /* Name.Attribute */ +.highlight .nb { color: #AA22FF } /* Name.Builtin */ +.highlight .nc { color: #0000FF } /* Name.Class */ +.highlight .no { color: #880000 } /* Name.Constant */ +.highlight .nd { color: #AA22FF } /* Name.Decorator */ +.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #00A000 } /* Name.Function */ +.highlight .nl { color: #A0A000 } /* Name.Label */ +.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #B8860B } /* Name.Variable */ +.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #666666 } /* Literal.Number.Float */ +.highlight .mh { color: #666666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666666 } /* Literal.Number.Oct */ +.highlight .sb { color: #BB4444 } /* Literal.String.Backtick */ +.highlight .sc { color: #BB4444 } /* Literal.String.Char */ +.highlight .sd { color: #BB4444; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #BB4444 } /* Literal.String.Double */ +.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #BB4444 } /* Literal.String.Heredoc */ +.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ +.highlight .sx { color: #008000 } /* Literal.String.Other */ +.highlight .sr { color: #BB6688 } /* Literal.String.Regex */ +.highlight .s1 { color: #BB4444 } /* Literal.String.Single */ +.highlight .ss { color: #B8860B } /* Literal.String.Symbol */ +.highlight .bp { color: #AA22FF } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #B8860B } /* Name.Variable.Class */ +.highlight .vg { color: #B8860B } /* Name.Variable.Global */ +.highlight .vi { color: #B8860B } /* Name.Variable.Instance */ +.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ diff --git a/docs/assets/css/pygments/friendly.css b/docs/assets/css/pygments/friendly.css new file mode 100644 index 0000000..846e048 --- /dev/null +++ b/docs/assets/css/pygments/friendly.css @@ -0,0 +1,61 @@ +.highlight .hll { background-color: #ffffcc } +.highlight .c { color: #60a0b0; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #007020; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .cm { color: #60a0b0; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #007020 } /* Comment.Preproc */ +.highlight .c1 { color: #60a0b0; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #60a0b0; background-color: #fff0f0 } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #808080 } /* Generic.Output */ +.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0040D0 } /* Generic.Traceback */ +.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #007020 } /* Keyword.Pseudo */ +.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #902000 } /* Keyword.Type */ +.highlight .m { color: #40a070 } /* Literal.Number */ +.highlight .s { color: #4070a0 } /* Literal.String */ +.highlight .na { color: #4070a0 } /* Name.Attribute */ +.highlight .nb { color: #007020 } /* Name.Builtin */ +.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ +.highlight .no { color: #60add5 } /* Name.Constant */ +.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ +.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #007020 } /* Name.Exception */ +.highlight .nf { color: #06287e } /* Name.Function */ +.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ +.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #bb60d5 } /* Name.Variable */ +.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #40a070 } /* Literal.Number.Float */ +.highlight .mh { color: #40a070 } /* Literal.Number.Hex */ +.highlight .mi { color: #40a070 } /* Literal.Number.Integer */ +.highlight .mo { color: #40a070 } /* Literal.Number.Oct */ +.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ +.highlight .sc { color: #4070a0 } /* Literal.String.Char */ +.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #4070a0 } /* Literal.String.Double */ +.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ +.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ +.highlight .sx { color: #c65d09 } /* Literal.String.Other */ +.highlight .sr { color: #235388 } /* Literal.String.Regex */ +.highlight .s1 { color: #4070a0 } /* Literal.String.Single */ +.highlight .ss { color: #517918 } /* Literal.String.Symbol */ +.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ +.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ +.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ +.highlight .il { color: #40a070 } /* Literal.Number.Integer.Long */ diff --git a/docs/assets/css/pygments/fruity.css b/docs/assets/css/pygments/fruity.css new file mode 100644 index 0000000..9152350 --- /dev/null +++ b/docs/assets/css/pygments/fruity.css @@ -0,0 +1,70 @@ +.highlight pre { background-color: #333; } +.highlight .hll { background-color: #333333 } +.highlight .c { color: #008800; font-style: italic; background-color: #0f140f } /* Comment */ +.highlight .err { color: #ffffff } /* Error */ +.highlight .g { color: #ffffff } /* Generic */ +.highlight .k { color: #fb660a; font-weight: bold } /* Keyword */ +.highlight .l { color: #ffffff } /* Literal */ +.highlight .n { color: #ffffff } /* Name */ +.highlight .o { color: #ffffff } /* Operator */ +.highlight .x { color: #ffffff } /* Other */ +.highlight .p { color: #ffffff } /* Punctuation */ +.highlight .cm { color: #008800; font-style: italic; background-color: #0f140f } /* Comment.Multiline */ +.highlight .cp { color: #ff0007; font-weight: bold; font-style: italic; background-color: #0f140f } /* Comment.Preproc */ +.highlight .c1 { color: #008800; font-style: italic; background-color: #0f140f } /* Comment.Single */ +.highlight .cs { color: #008800; font-style: italic; background-color: #0f140f } /* Comment.Special */ +.highlight .gd { color: #ffffff } /* Generic.Deleted */ +.highlight .ge { color: #ffffff } /* Generic.Emph */ +.highlight .gr { color: #ffffff } /* Generic.Error */ +.highlight .gh { color: #ffffff; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #ffffff } /* Generic.Inserted */ +.highlight .go { color: #444444; background-color: #222222 } /* Generic.Output */ +.highlight .gp { color: #ffffff } /* Generic.Prompt */ +.highlight .gs { color: #ffffff } /* Generic.Strong */ +.highlight .gu { color: #ffffff; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #ffffff } /* Generic.Traceback */ +.highlight .kc { color: #fb660a; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #fb660a; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #fb660a; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #fb660a } /* Keyword.Pseudo */ +.highlight .kr { color: #fb660a; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #cdcaa9; font-weight: bold } /* Keyword.Type */ +.highlight .ld { color: #ffffff } /* Literal.Date */ +.highlight .m { color: #0086f7; font-weight: bold } /* Literal.Number */ +.highlight .s { color: #0086d2 } /* Literal.String */ +.highlight .na { color: #ff0086; font-weight: bold } /* Name.Attribute */ +.highlight .nb { color: #ffffff } /* Name.Builtin */ +.highlight .nc { color: #ffffff } /* Name.Class */ +.highlight .no { color: #0086d2 } /* Name.Constant */ +.highlight .nd { color: #ffffff } /* Name.Decorator */ +.highlight .ni { color: #ffffff } /* Name.Entity */ +.highlight .ne { color: #ffffff } /* Name.Exception */ +.highlight .nf { color: #ff0086; font-weight: bold } /* Name.Function */ +.highlight .nl { color: #ffffff } /* Name.Label */ +.highlight .nn { color: #ffffff } /* Name.Namespace */ +.highlight .nx { color: #ffffff } /* Name.Other */ +.highlight .py { color: #ffffff } /* Name.Property */ +.highlight .nt { color: #fb660a; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #fb660a } /* Name.Variable */ +.highlight .ow { color: #ffffff } /* Operator.Word */ +.highlight .w { color: #888888 } /* Text.Whitespace */ +.highlight .mf { color: #0086f7; font-weight: bold } /* Literal.Number.Float */ +.highlight .mh { color: #0086f7; font-weight: bold } /* Literal.Number.Hex */ +.highlight .mi { color: #0086f7; font-weight: bold } /* Literal.Number.Integer */ +.highlight .mo { color: #0086f7; font-weight: bold } /* Literal.Number.Oct */ +.highlight .sb { color: #0086d2 } /* Literal.String.Backtick */ +.highlight .sc { color: #0086d2 } /* Literal.String.Char */ +.highlight .sd { color: #0086d2 } /* Literal.String.Doc */ +.highlight .s2 { color: #0086d2 } /* Literal.String.Double */ +.highlight .se { color: #0086d2 } /* Literal.String.Escape */ +.highlight .sh { color: #0086d2 } /* Literal.String.Heredoc */ +.highlight .si { color: #0086d2 } /* Literal.String.Interpol */ +.highlight .sx { color: #0086d2 } /* Literal.String.Other */ +.highlight .sr { color: #0086d2 } /* Literal.String.Regex */ +.highlight .s1 { color: #0086d2 } /* Literal.String.Single */ +.highlight .ss { color: #0086d2 } /* Literal.String.Symbol */ +.highlight .bp { color: #ffffff } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #fb660a } /* Name.Variable.Class */ +.highlight .vg { color: #fb660a } /* Name.Variable.Global */ +.highlight .vi { color: #fb660a } /* Name.Variable.Instance */ +.highlight .il { color: #0086f7; font-weight: bold } /* Literal.Number.Integer.Long */ diff --git a/docs/assets/css/pygments/github.css b/docs/assets/css/pygments/github.css new file mode 100644 index 0000000..5c45e67 --- /dev/null +++ b/docs/assets/css/pygments/github.css @@ -0,0 +1,61 @@ +.highlight .hll { background-color: #ffffcc } +.highlight .c { color: #999988; font-style: italic } /* Comment */ +.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ +.highlight .k { color: #000000; font-weight: bold } /* Keyword */ +.highlight .o { color: #000000; font-weight: bold } /* Operator */ +.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #999999; font-weight: bold; font-style: italic } /* Comment.Preproc */ +.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ +.highlight .ge { color: #000000; font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #aa0000 } /* Generic.Error */ +.highlight .gh { color: #999999 } /* Generic.Heading */ +.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ +.highlight .go { color: #888888 } /* Generic.Output */ +.highlight .gp { color: #555555 } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #aaaaaa } /* Generic.Subheading */ +.highlight .gt { color: #aa0000 } /* Generic.Traceback */ +.highlight .kc { color: #000000; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #000000; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #000000; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #000000; font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { color: #000000; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */ +.highlight .m { color: #009999 } /* Literal.Number */ +.highlight .s { color: #d01040 } /* Literal.String */ +.highlight .na { color: #008080 } /* Name.Attribute */ +.highlight .nb { color: #0086B3 } /* Name.Builtin */ +.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */ +.highlight .no { color: #008080 } /* Name.Constant */ +.highlight .nd { color: #3c5d5d; font-weight: bold } /* Name.Decorator */ +.highlight .ni { color: #800080 } /* Name.Entity */ +.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */ +.highlight .nl { color: #990000; font-weight: bold } /* Name.Label */ +.highlight .nn { color: #555555 } /* Name.Namespace */ +.highlight .nt { color: #000080 } /* Name.Tag */ +.highlight .nv { color: #008080 } /* Name.Variable */ +.highlight .ow { color: #000000; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #009999 } /* Literal.Number.Float */ +.highlight .mh { color: #009999 } /* Literal.Number.Hex */ +.highlight .mi { color: #009999 } /* Literal.Number.Integer */ +.highlight .mo { color: #009999 } /* Literal.Number.Oct */ +.highlight .sb { color: #d01040 } /* Literal.String.Backtick */ +.highlight .sc { color: #d01040 } /* Literal.String.Char */ +.highlight .sd { color: #d01040 } /* Literal.String.Doc */ +.highlight .s2 { color: #d01040 } /* Literal.String.Double */ +.highlight .se { color: #d01040 } /* Literal.String.Escape */ +.highlight .sh { color: #d01040 } /* Literal.String.Heredoc */ +.highlight .si { color: #d01040 } /* Literal.String.Interpol */ +.highlight .sx { color: #d01040 } /* Literal.String.Other */ +.highlight .sr { color: #009926 } /* Literal.String.Regex */ +.highlight .s1 { color: #d01040 } /* Literal.String.Single */ +.highlight .ss { color: #990073 } /* Literal.String.Symbol */ +.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #008080 } /* Name.Variable.Class */ +.highlight .vg { color: #008080 } /* Name.Variable.Global */ +.highlight .vi { color: #008080 } /* Name.Variable.Instance */ +.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */ diff --git a/docs/assets/css/pygments/manni.css b/docs/assets/css/pygments/manni.css new file mode 100644 index 0000000..d5bc47e --- /dev/null +++ b/docs/assets/css/pygments/manni.css @@ -0,0 +1,61 @@ +.highlight .hll { background-color: #ffffcc } +.highlight .c { color: #0099FF; font-style: italic } /* Comment */ +.highlight .err { color: #AA0000; background-color: #FFAAAA } /* Error */ +.highlight .k { color: #006699; font-weight: bold } /* Keyword */ +.highlight .o { color: #555555 } /* Operator */ +.highlight .cm { color: #0099FF; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #009999 } /* Comment.Preproc */ +.highlight .c1 { color: #0099FF; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #0099FF; font-weight: bold; font-style: italic } /* Comment.Special */ +.highlight .gd { background-color: #FFCCCC; border: 1px solid #CC0000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #003300; font-weight: bold } /* Generic.Heading */ +.highlight .gi { background-color: #CCFFCC; border: 1px solid #00CC00 } /* Generic.Inserted */ +.highlight .go { color: #AAAAAA } /* Generic.Output */ +.highlight .gp { color: #000099; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #003300; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #99CC66 } /* Generic.Traceback */ +.highlight .kc { color: #006699; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #006699; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #006699; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #006699 } /* Keyword.Pseudo */ +.highlight .kr { color: #006699; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #007788; font-weight: bold } /* Keyword.Type */ +.highlight .m { color: #FF6600 } /* Literal.Number */ +.highlight .s { color: #CC3300 } /* Literal.String */ +.highlight .na { color: #330099 } /* Name.Attribute */ +.highlight .nb { color: #336666 } /* Name.Builtin */ +.highlight .nc { color: #00AA88; font-weight: bold } /* Name.Class */ +.highlight .no { color: #336600 } /* Name.Constant */ +.highlight .nd { color: #9999FF } /* Name.Decorator */ +.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #CC0000; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #CC00FF } /* Name.Function */ +.highlight .nl { color: #9999FF } /* Name.Label */ +.highlight .nn { color: #00CCFF; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #330099; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #003333 } /* Name.Variable */ +.highlight .ow { color: #000000; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #FF6600 } /* Literal.Number.Float */ +.highlight .mh { color: #FF6600 } /* Literal.Number.Hex */ +.highlight .mi { color: #FF6600 } /* Literal.Number.Integer */ +.highlight .mo { color: #FF6600 } /* Literal.Number.Oct */ +.highlight .sb { color: #CC3300 } /* Literal.String.Backtick */ +.highlight .sc { color: #CC3300 } /* Literal.String.Char */ +.highlight .sd { color: #CC3300; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #CC3300 } /* Literal.String.Double */ +.highlight .se { color: #CC3300; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #CC3300 } /* Literal.String.Heredoc */ +.highlight .si { color: #AA0000 } /* Literal.String.Interpol */ +.highlight .sx { color: #CC3300 } /* Literal.String.Other */ +.highlight .sr { color: #33AAAA } /* Literal.String.Regex */ +.highlight .s1 { color: #CC3300 } /* Literal.String.Single */ +.highlight .ss { color: #FFCC33 } /* Literal.String.Symbol */ +.highlight .bp { color: #336666 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #003333 } /* Name.Variable.Class */ +.highlight .vg { color: #003333 } /* Name.Variable.Global */ +.highlight .vi { color: #003333 } /* Name.Variable.Instance */ +.highlight .il { color: #FF6600 } /* Literal.Number.Integer.Long */ diff --git a/docs/assets/css/pygments/monokai.css b/docs/assets/css/pygments/monokai.css new file mode 100644 index 0000000..5ce9493 --- /dev/null +++ b/docs/assets/css/pygments/monokai.css @@ -0,0 +1,66 @@ +.highlight pre, pre.highlight { background-color: #272822; } +.highlight code { color: #fff; } +.highlight .hll { background-color: #272822; } +.highlight .c { color: #75715e } /* Comment */ +.highlight .err { color: #960050; background-color: #1e0010 } /* Error */ +.highlight .k { color: #66d9ef } /* Keyword */ +.highlight .l { color: #ae81ff } /* Literal */ +.highlight .n { color: #f8f8f2 } /* Name */ +.highlight .o { color: #f92672 } /* Operator */ +.highlight .p { color: #f8f8f2 } /* Punctuation */ +.highlight .cm { color: #75715e } /* Comment.Multiline */ +.highlight .cp { color: #75715e } /* Comment.Preproc */ +.highlight .c1 { color: #75715e } /* Comment.Single */ +.highlight .cs { color: #75715e } /* Comment.Special */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .kc { color: #66d9ef } /* Keyword.Constant */ +.highlight .kd { color: #66d9ef } /* Keyword.Declaration */ +.highlight .kn { color: #f92672 } /* Keyword.Namespace */ +.highlight .kp { color: #66d9ef } /* Keyword.Pseudo */ +.highlight .kr { color: #66d9ef } /* Keyword.Reserved */ +.highlight .kt { color: #66d9ef } /* Keyword.Type */ +.highlight .ld { color: #e6db74 } /* Literal.Date */ +.highlight .m { color: #ae81ff } /* Literal.Number */ +.highlight .s { color: #e6db74 } /* Literal.String */ +.highlight .na { color: #a6e22e } /* Name.Attribute */ +.highlight .nb { color: #f8f8f2 } /* Name.Builtin */ +.highlight .nc { color: #a6e22e } /* Name.Class */ +.highlight .no { color: #66d9ef } /* Name.Constant */ +.highlight .nd { color: #a6e22e } /* Name.Decorator */ +.highlight .ni { color: #f8f8f2 } /* Name.Entity */ +.highlight .ne { color: #a6e22e } /* Name.Exception */ +.highlight .nf { color: #a6e22e } /* Name.Function */ +.highlight .nl { color: #f8f8f2 } /* Name.Label */ +.highlight .nn { color: #f8f8f2 } /* Name.Namespace */ +.highlight .nx { color: #a6e22e } /* Name.Other */ +.highlight .py { color: #f8f8f2 } /* Name.Property */ +.highlight .nt { color: #f92672 } /* Name.Tag */ +.highlight .nv { color: #f8f8f2 } /* Name.Variable */ +.highlight .ow { color: #f92672 } /* Operator.Word */ +.highlight .w { color: #f8f8f2 } /* Text.Whitespace */ +.highlight .mf { color: #ae81ff } /* Literal.Number.Float */ +.highlight .mh { color: #ae81ff } /* Literal.Number.Hex */ +.highlight .mi { color: #ae81ff } /* Literal.Number.Integer */ +.highlight .mo { color: #ae81ff } /* Literal.Number.Oct */ +.highlight .sb { color: #e6db74 } /* Literal.String.Backtick */ +.highlight .sc { color: #e6db74 } /* Literal.String.Char */ +.highlight .sd { color: #e6db74 } /* Literal.String.Doc */ +.highlight .s2 { color: #e6db74 } /* Literal.String.Double */ +.highlight .se { color: #ae81ff } /* Literal.String.Escape */ +.highlight .sh { color: #e6db74 } /* Literal.String.Heredoc */ +.highlight .si { color: #e6db74 } /* Literal.String.Interpol */ +.highlight .sx { color: #e6db74 } /* Literal.String.Other */ +.highlight .sr { color: #e6db74 } /* Literal.String.Regex */ +.highlight .s1 { color: #e6db74 } /* Literal.String.Single */ +.highlight .ss { color: #e6db74 } /* Literal.String.Symbol */ +.highlight .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #f8f8f2 } /* Name.Variable.Class */ +.highlight .vg { color: #f8f8f2 } /* Name.Variable.Global */ +.highlight .vi { color: #f8f8f2 } /* Name.Variable.Instance */ +.highlight .il { color: #ae81ff } /* Literal.Number.Integer.Long */ + +.highlight .gh { } /* Generic Heading & Diff Header */ +.highlight .gu { color: #75715e; } /* Generic.Subheading & Diff Unified/Comment? */ +.highlight .gd { color: #f92672; } /* Generic.Deleted & Diff Deleted */ +.highlight .gi { color: #a6e22e; } /* Generic.Inserted & Diff Inserted */ diff --git a/docs/assets/css/pygments/murphy.css b/docs/assets/css/pygments/murphy.css new file mode 100644 index 0000000..482d46b --- /dev/null +++ b/docs/assets/css/pygments/murphy.css @@ -0,0 +1,61 @@ +.highlight .hll { background-color: #ffffcc } +.highlight .c { color: #606060; font-style: italic } /* Comment */ +.highlight .err { color: #F00000; background-color: #F0A0A0 } /* Error */ +.highlight .k { color: #208090; font-weight: bold } /* Keyword */ +.highlight .o { color: #303030 } /* Operator */ +.highlight .cm { color: #606060; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #507090 } /* Comment.Preproc */ +.highlight .c1 { color: #606060; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #c00000; font-weight: bold; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #808080 } /* Generic.Output */ +.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0040D0 } /* Generic.Traceback */ +.highlight .kc { color: #208090; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #208090; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #208090; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #0080f0; font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { color: #208090; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #6060f0; font-weight: bold } /* Keyword.Type */ +.highlight .m { color: #6000E0; font-weight: bold } /* Literal.Number */ +.highlight .s { background-color: #e0e0ff } /* Literal.String */ +.highlight .na { color: #000070 } /* Name.Attribute */ +.highlight .nb { color: #007020 } /* Name.Builtin */ +.highlight .nc { color: #e090e0; font-weight: bold } /* Name.Class */ +.highlight .no { color: #50e0d0; font-weight: bold } /* Name.Constant */ +.highlight .nd { color: #505050; font-weight: bold } /* Name.Decorator */ +.highlight .ni { color: #800000 } /* Name.Entity */ +.highlight .ne { color: #F00000; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #50e0d0; font-weight: bold } /* Name.Function */ +.highlight .nl { color: #907000; font-weight: bold } /* Name.Label */ +.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #007000 } /* Name.Tag */ +.highlight .nv { color: #003060 } /* Name.Variable */ +.highlight .ow { color: #000000; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #6000E0; font-weight: bold } /* Literal.Number.Float */ +.highlight .mh { color: #005080; font-weight: bold } /* Literal.Number.Hex */ +.highlight .mi { color: #6060f0; font-weight: bold } /* Literal.Number.Integer */ +.highlight .mo { color: #4000E0; font-weight: bold } /* Literal.Number.Oct */ +.highlight .sb { background-color: #e0e0ff } /* Literal.String.Backtick */ +.highlight .sc { color: #8080F0 } /* Literal.String.Char */ +.highlight .sd { color: #D04020 } /* Literal.String.Doc */ +.highlight .s2 { background-color: #e0e0ff } /* Literal.String.Double */ +.highlight .se { color: #606060; font-weight: bold; background-color: #e0e0ff } /* Literal.String.Escape */ +.highlight .sh { background-color: #e0e0ff } /* Literal.String.Heredoc */ +.highlight .si { background-color: #e0e0e0 } /* Literal.String.Interpol */ +.highlight .sx { color: #f08080; background-color: #e0e0ff } /* Literal.String.Other */ +.highlight .sr { color: #000000; background-color: #e0e0ff } /* Literal.String.Regex */ +.highlight .s1 { background-color: #e0e0ff } /* Literal.String.Single */ +.highlight .ss { color: #f0c080 } /* Literal.String.Symbol */ +.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #c0c0f0 } /* Name.Variable.Class */ +.highlight .vg { color: #f08040 } /* Name.Variable.Global */ +.highlight .vi { color: #a0a0f0 } /* Name.Variable.Instance */ +.highlight .il { color: #6060f0; font-weight: bold } /* Literal.Number.Integer.Long */ diff --git a/docs/assets/css/pygments/native.css b/docs/assets/css/pygments/native.css new file mode 100644 index 0000000..eac4a78 --- /dev/null +++ b/docs/assets/css/pygments/native.css @@ -0,0 +1,70 @@ +.highlight pre { background-color: #404040 } +.highlight .hll { background-color: #404040 } +.highlight .c { color: #999999; font-style: italic } /* Comment */ +.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ +.highlight .g { color: #d0d0d0 } /* Generic */ +.highlight .k { color: #6ab825; font-weight: bold } /* Keyword */ +.highlight .l { color: #d0d0d0 } /* Literal */ +.highlight .n { color: #d0d0d0 } /* Name */ +.highlight .o { color: #d0d0d0 } /* Operator */ +.highlight .x { color: #d0d0d0 } /* Other */ +.highlight .p { color: #d0d0d0 } /* Punctuation */ +.highlight .cm { color: #999999; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #cd2828; font-weight: bold } /* Comment.Preproc */ +.highlight .c1 { color: #999999; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #e50808; font-weight: bold; background-color: #520000 } /* Comment.Special */ +.highlight .gd { color: #d22323 } /* Generic.Deleted */ +.highlight .ge { color: #d0d0d0; font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #d22323 } /* Generic.Error */ +.highlight .gh { color: #ffffff; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #589819 } /* Generic.Inserted */ +.highlight .go { color: #cccccc } /* Generic.Output */ +.highlight .gp { color: #aaaaaa } /* Generic.Prompt */ +.highlight .gs { color: #d0d0d0; font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #ffffff; text-decoration: underline } /* Generic.Subheading */ +.highlight .gt { color: #d22323 } /* Generic.Traceback */ +.highlight .kc { color: #6ab825; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #6ab825; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #6ab825; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #6ab825 } /* Keyword.Pseudo */ +.highlight .kr { color: #6ab825; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #6ab825; font-weight: bold } /* Keyword.Type */ +.highlight .ld { color: #d0d0d0 } /* Literal.Date */ +.highlight .m { color: #3677a9 } /* Literal.Number */ +.highlight .s { color: #ed9d13 } /* Literal.String */ +.highlight .na { color: #bbbbbb } /* Name.Attribute */ +.highlight .nb { color: #24909d } /* Name.Builtin */ +.highlight .nc { color: #447fcf; text-decoration: underline } /* Name.Class */ +.highlight .no { color: #40ffff } /* Name.Constant */ +.highlight .nd { color: #ffa500 } /* Name.Decorator */ +.highlight .ni { color: #d0d0d0 } /* Name.Entity */ +.highlight .ne { color: #bbbbbb } /* Name.Exception */ +.highlight .nf { color: #447fcf } /* Name.Function */ +.highlight .nl { color: #d0d0d0 } /* Name.Label */ +.highlight .nn { color: #447fcf; text-decoration: underline } /* Name.Namespace */ +.highlight .nx { color: #d0d0d0 } /* Name.Other */ +.highlight .py { color: #d0d0d0 } /* Name.Property */ +.highlight .nt { color: #6ab825; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #40ffff } /* Name.Variable */ +.highlight .ow { color: #6ab825; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #666666 } /* Text.Whitespace */ +.highlight .mf { color: #3677a9 } /* Literal.Number.Float */ +.highlight .mh { color: #3677a9 } /* Literal.Number.Hex */ +.highlight .mi { color: #3677a9 } /* Literal.Number.Integer */ +.highlight .mo { color: #3677a9 } /* Literal.Number.Oct */ +.highlight .sb { color: #ed9d13 } /* Literal.String.Backtick */ +.highlight .sc { color: #ed9d13 } /* Literal.String.Char */ +.highlight .sd { color: #ed9d13 } /* Literal.String.Doc */ +.highlight .s2 { color: #ed9d13 } /* Literal.String.Double */ +.highlight .se { color: #ed9d13 } /* Literal.String.Escape */ +.highlight .sh { color: #ed9d13 } /* Literal.String.Heredoc */ +.highlight .si { color: #ed9d13 } /* Literal.String.Interpol */ +.highlight .sx { color: #ffa500 } /* Literal.String.Other */ +.highlight .sr { color: #ed9d13 } /* Literal.String.Regex */ +.highlight .s1 { color: #ed9d13 } /* Literal.String.Single */ +.highlight .ss { color: #ed9d13 } /* Literal.String.Symbol */ +.highlight .bp { color: #24909d } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #40ffff } /* Name.Variable.Class */ +.highlight .vg { color: #40ffff } /* Name.Variable.Global */ +.highlight .vi { color: #40ffff } /* Name.Variable.Instance */ +.highlight .il { color: #3677a9 } /* Literal.Number.Integer.Long */ diff --git a/docs/assets/css/pygments/pastie.css b/docs/assets/css/pygments/pastie.css new file mode 100644 index 0000000..538bdc6 --- /dev/null +++ b/docs/assets/css/pygments/pastie.css @@ -0,0 +1,60 @@ +.highlight .hll { background-color: #ffffcc } +.highlight .c { color: #888888 } /* Comment */ +.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ +.highlight .k { color: #008800; font-weight: bold } /* Keyword */ +.highlight .cm { color: #888888 } /* Comment.Multiline */ +.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ +.highlight .c1 { color: #888888 } /* Comment.Single */ +.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ +.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #aa0000 } /* Generic.Error */ +.highlight .gh { color: #303030 } /* Generic.Heading */ +.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ +.highlight .go { color: #888888 } /* Generic.Output */ +.highlight .gp { color: #555555 } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #606060 } /* Generic.Subheading */ +.highlight .gt { color: #aa0000 } /* Generic.Traceback */ +.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #008800 } /* Keyword.Pseudo */ +.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ +.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ +.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ +.highlight .na { color: #336699 } /* Name.Attribute */ +.highlight .nb { color: #003388 } /* Name.Builtin */ +.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ +.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ +.highlight .nd { color: #555555 } /* Name.Decorator */ +.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ +.highlight .nl { color: #336699; font-style: italic } /* Name.Label */ +.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ +.highlight .py { color: #336699; font-weight: bold } /* Name.Property */ +.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #336699 } /* Name.Variable */ +.highlight .ow { color: #008800 } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ +.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ +.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ +.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ +.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ +.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ +.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ +.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ +.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ +.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ +.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ +.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ +.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ +.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ +.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ +.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #336699 } /* Name.Variable.Class */ +.highlight .vg { color: #dd7700 } /* Name.Variable.Global */ +.highlight .vi { color: #3333bb } /* Name.Variable.Instance */ +.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */ diff --git a/docs/assets/css/pygments/perldoc.css b/docs/assets/css/pygments/perldoc.css new file mode 100644 index 0000000..50516f2 --- /dev/null +++ b/docs/assets/css/pygments/perldoc.css @@ -0,0 +1,58 @@ +.highlight .hll { background-color: #ffffcc } +.highlight .c { color: #228B22 } /* Comment */ +.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ +.highlight .k { color: #8B008B; font-weight: bold } /* Keyword */ +.highlight .cm { color: #228B22 } /* Comment.Multiline */ +.highlight .cp { color: #1e889b } /* Comment.Preproc */ +.highlight .c1 { color: #228B22 } /* Comment.Single */ +.highlight .cs { color: #8B008B; font-weight: bold } /* Comment.Special */ +.highlight .gd { color: #aa0000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #aa0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00aa00 } /* Generic.Inserted */ +.highlight .go { color: #888888 } /* Generic.Output */ +.highlight .gp { color: #555555 } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #aa0000 } /* Generic.Traceback */ +.highlight .kc { color: #8B008B; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #8B008B; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #8B008B; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #8B008B; font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { color: #8B008B; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #a7a7a7; font-weight: bold } /* Keyword.Type */ +.highlight .m { color: #B452CD } /* Literal.Number */ +.highlight .s { color: #CD5555 } /* Literal.String */ +.highlight .na { color: #658b00 } /* Name.Attribute */ +.highlight .nb { color: #658b00 } /* Name.Builtin */ +.highlight .nc { color: #008b45; font-weight: bold } /* Name.Class */ +.highlight .no { color: #00688B } /* Name.Constant */ +.highlight .nd { color: #707a7c } /* Name.Decorator */ +.highlight .ne { color: #008b45; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #008b45 } /* Name.Function */ +.highlight .nn { color: #008b45; text-decoration: underline } /* Name.Namespace */ +.highlight .nt { color: #8B008B; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #00688B } /* Name.Variable */ +.highlight .ow { color: #8B008B } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #B452CD } /* Literal.Number.Float */ +.highlight .mh { color: #B452CD } /* Literal.Number.Hex */ +.highlight .mi { color: #B452CD } /* Literal.Number.Integer */ +.highlight .mo { color: #B452CD } /* Literal.Number.Oct */ +.highlight .sb { color: #CD5555 } /* Literal.String.Backtick */ +.highlight .sc { color: #CD5555 } /* Literal.String.Char */ +.highlight .sd { color: #CD5555 } /* Literal.String.Doc */ +.highlight .s2 { color: #CD5555 } /* Literal.String.Double */ +.highlight .se { color: #CD5555 } /* Literal.String.Escape */ +.highlight .sh { color: #1c7e71; font-style: italic } /* Literal.String.Heredoc */ +.highlight .si { color: #CD5555 } /* Literal.String.Interpol */ +.highlight .sx { color: #cb6c20 } /* Literal.String.Other */ +.highlight .sr { color: #1c7e71 } /* Literal.String.Regex */ +.highlight .s1 { color: #CD5555 } /* Literal.String.Single */ +.highlight .ss { color: #CD5555 } /* Literal.String.Symbol */ +.highlight .bp { color: #658b00 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #00688B } /* Name.Variable.Class */ +.highlight .vg { color: #00688B } /* Name.Variable.Global */ +.highlight .vi { color: #00688B } /* Name.Variable.Instance */ +.highlight .il { color: #B452CD } /* Literal.Number.Integer.Long */ diff --git a/docs/assets/css/pygments/tango.css b/docs/assets/css/pygments/tango.css new file mode 100644 index 0000000..bfd3803 --- /dev/null +++ b/docs/assets/css/pygments/tango.css @@ -0,0 +1,69 @@ +.highlight .hll { background-color: #ffffcc } +.highlight .c { color: #8f5902; font-style: italic } /* Comment */ +.highlight .err { color: #a40000; border: 1px solid #ef2929 } /* Error */ +.highlight .g { color: #000000 } /* Generic */ +.highlight .k { color: #204a87; font-weight: bold } /* Keyword */ +.highlight .l { color: #000000 } /* Literal */ +.highlight .n { color: #000000 } /* Name */ +.highlight .o { color: #ce5c00; font-weight: bold } /* Operator */ +.highlight .x { color: #000000 } /* Other */ +.highlight .p { color: #000000; font-weight: bold } /* Punctuation */ +.highlight .cm { color: #8f5902; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #8f5902; font-style: italic } /* Comment.Preproc */ +.highlight .c1 { color: #8f5902; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #8f5902; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #a40000 } /* Generic.Deleted */ +.highlight .ge { color: #000000; font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #ef2929 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #000000; font-style: italic } /* Generic.Output */ +.highlight .gp { color: #8f5902 } /* Generic.Prompt */ +.highlight .gs { color: #000000; font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #a40000; font-weight: bold } /* Generic.Traceback */ +.highlight .kc { color: #204a87; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #204a87; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #204a87; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #204a87; font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { color: #204a87; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #204a87; font-weight: bold } /* Keyword.Type */ +.highlight .ld { color: #000000 } /* Literal.Date */ +.highlight .m { color: #0000cf; font-weight: bold } /* Literal.Number */ +.highlight .s { color: #4e9a06 } /* Literal.String */ +.highlight .na { color: #c4a000 } /* Name.Attribute */ +.highlight .nb { color: #204a87 } /* Name.Builtin */ +.highlight .nc { color: #000000 } /* Name.Class */ +.highlight .no { color: #000000 } /* Name.Constant */ +.highlight .nd { color: #5c35cc; font-weight: bold } /* Name.Decorator */ +.highlight .ni { color: #ce5c00 } /* Name.Entity */ +.highlight .ne { color: #cc0000; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #000000 } /* Name.Function */ +.highlight .nl { color: #f57900 } /* Name.Label */ +.highlight .nn { color: #000000 } /* Name.Namespace */ +.highlight .nx { color: #000000 } /* Name.Other */ +.highlight .py { color: #000000 } /* Name.Property */ +.highlight .nt { color: #204a87; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #000000 } /* Name.Variable */ +.highlight .ow { color: #204a87; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #f8f8f8; text-decoration: underline } /* Text.Whitespace */ +.highlight .mf { color: #0000cf; font-weight: bold } /* Literal.Number.Float */ +.highlight .mh { color: #0000cf; font-weight: bold } /* Literal.Number.Hex */ +.highlight .mi { color: #0000cf; font-weight: bold } /* Literal.Number.Integer */ +.highlight .mo { color: #0000cf; font-weight: bold } /* Literal.Number.Oct */ +.highlight .sb { color: #4e9a06 } /* Literal.String.Backtick */ +.highlight .sc { color: #4e9a06 } /* Literal.String.Char */ +.highlight .sd { color: #8f5902; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #4e9a06 } /* Literal.String.Double */ +.highlight .se { color: #4e9a06 } /* Literal.String.Escape */ +.highlight .sh { color: #4e9a06 } /* Literal.String.Heredoc */ +.highlight .si { color: #4e9a06 } /* Literal.String.Interpol */ +.highlight .sx { color: #4e9a06 } /* Literal.String.Other */ +.highlight .sr { color: #4e9a06 } /* Literal.String.Regex */ +.highlight .s1 { color: #4e9a06 } /* Literal.String.Single */ +.highlight .ss { color: #4e9a06 } /* Literal.String.Symbol */ +.highlight .bp { color: #3465a4 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #000000 } /* Name.Variable.Class */ +.highlight .vg { color: #000000 } /* Name.Variable.Global */ +.highlight .vi { color: #000000 } /* Name.Variable.Instance */ +.highlight .il { color: #0000cf; font-weight: bold } /* Literal.Number.Integer.Long */ diff --git a/docs/assets/css/pygments/trac.css b/docs/assets/css/pygments/trac.css new file mode 100644 index 0000000..851ba3c --- /dev/null +++ b/docs/assets/css/pygments/trac.css @@ -0,0 +1,59 @@ +.highlight .hll { background-color: #ffffcc } +.highlight .c { color: #999988; font-style: italic } /* Comment */ +.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ +.highlight .k { font-weight: bold } /* Keyword */ +.highlight .o { font-weight: bold } /* Operator */ +.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */ +.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #aa0000 } /* Generic.Error */ +.highlight .gh { color: #999999 } /* Generic.Heading */ +.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ +.highlight .go { color: #888888 } /* Generic.Output */ +.highlight .gp { color: #555555 } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #aaaaaa } /* Generic.Subheading */ +.highlight .gt { color: #aa0000 } /* Generic.Traceback */ +.highlight .kc { font-weight: bold } /* Keyword.Constant */ +.highlight .kd { font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */ +.highlight .m { color: #009999 } /* Literal.Number */ +.highlight .s { color: #bb8844 } /* Literal.String */ +.highlight .na { color: #008080 } /* Name.Attribute */ +.highlight .nb { color: #999999 } /* Name.Builtin */ +.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */ +.highlight .no { color: #008080 } /* Name.Constant */ +.highlight .ni { color: #800080 } /* Name.Entity */ +.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */ +.highlight .nn { color: #555555 } /* Name.Namespace */ +.highlight .nt { color: #000080 } /* Name.Tag */ +.highlight .nv { color: #008080 } /* Name.Variable */ +.highlight .ow { font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #009999 } /* Literal.Number.Float */ +.highlight .mh { color: #009999 } /* Literal.Number.Hex */ +.highlight .mi { color: #009999 } /* Literal.Number.Integer */ +.highlight .mo { color: #009999 } /* Literal.Number.Oct */ +.highlight .sb { color: #bb8844 } /* Literal.String.Backtick */ +.highlight .sc { color: #bb8844 } /* Literal.String.Char */ +.highlight .sd { color: #bb8844 } /* Literal.String.Doc */ +.highlight .s2 { color: #bb8844 } /* Literal.String.Double */ +.highlight .se { color: #bb8844 } /* Literal.String.Escape */ +.highlight .sh { color: #bb8844 } /* Literal.String.Heredoc */ +.highlight .si { color: #bb8844 } /* Literal.String.Interpol */ +.highlight .sx { color: #bb8844 } /* Literal.String.Other */ +.highlight .sr { color: #808000 } /* Literal.String.Regex */ +.highlight .s1 { color: #bb8844 } /* Literal.String.Single */ +.highlight .ss { color: #bb8844 } /* Literal.String.Symbol */ +.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #008080 } /* Name.Variable.Class */ +.highlight .vg { color: #008080 } /* Name.Variable.Global */ +.highlight .vi { color: #008080 } /* Name.Variable.Instance */ +.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */ diff --git a/docs/assets/css/pygments/vim.css b/docs/assets/css/pygments/vim.css new file mode 100644 index 0000000..3af4a14 --- /dev/null +++ b/docs/assets/css/pygments/vim.css @@ -0,0 +1,70 @@ +.highlight pre { background-color: #222222 } +.highlight .hll { background-color: #222222 } +.highlight .c { color: #000080 } /* Comment */ +.highlight .err { color: #cccccc; border: 1px solid #FF0000 } /* Error */ +.highlight .g { color: #cccccc } /* Generic */ +.highlight .k { color: #cdcd00 } /* Keyword */ +.highlight .l { color: #cccccc } /* Literal */ +.highlight .n { color: #cccccc } /* Name */ +.highlight .o { color: #3399cc } /* Operator */ +.highlight .x { color: #cccccc } /* Other */ +.highlight .p { color: #cccccc } /* Punctuation */ +.highlight .cm { color: #000080 } /* Comment.Multiline */ +.highlight .cp { color: #000080 } /* Comment.Preproc */ +.highlight .c1 { color: #000080 } /* Comment.Single */ +.highlight .cs { color: #cd0000; font-weight: bold } /* Comment.Special */ +.highlight .gd { color: #cd0000 } /* Generic.Deleted */ +.highlight .ge { color: #cccccc; font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00cd00 } /* Generic.Inserted */ +.highlight .go { color: #808080 } /* Generic.Output */ +.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { color: #cccccc; font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0040D0 } /* Generic.Traceback */ +.highlight .kc { color: #cdcd00 } /* Keyword.Constant */ +.highlight .kd { color: #00cd00 } /* Keyword.Declaration */ +.highlight .kn { color: #cd00cd } /* Keyword.Namespace */ +.highlight .kp { color: #cdcd00 } /* Keyword.Pseudo */ +.highlight .kr { color: #cdcd00 } /* Keyword.Reserved */ +.highlight .kt { color: #00cd00 } /* Keyword.Type */ +.highlight .ld { color: #cccccc } /* Literal.Date */ +.highlight .m { color: #cd00cd } /* Literal.Number */ +.highlight .s { color: #cd0000 } /* Literal.String */ +.highlight .na { color: #cccccc } /* Name.Attribute */ +.highlight .nb { color: #cd00cd } /* Name.Builtin */ +.highlight .nc { color: #00cdcd } /* Name.Class */ +.highlight .no { color: #cccccc } /* Name.Constant */ +.highlight .nd { color: #cccccc } /* Name.Decorator */ +.highlight .ni { color: #cccccc } /* Name.Entity */ +.highlight .ne { color: #666699; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #cccccc } /* Name.Function */ +.highlight .nl { color: #cccccc } /* Name.Label */ +.highlight .nn { color: #cccccc } /* Name.Namespace */ +.highlight .nx { color: #cccccc } /* Name.Other */ +.highlight .py { color: #cccccc } /* Name.Property */ +.highlight .nt { color: #cccccc } /* Name.Tag */ +.highlight .nv { color: #00cdcd } /* Name.Variable */ +.highlight .ow { color: #cdcd00 } /* Operator.Word */ +.highlight .w { color: #cccccc } /* Text.Whitespace */ +.highlight .mf { color: #cd00cd } /* Literal.Number.Float */ +.highlight .mh { color: #cd00cd } /* Literal.Number.Hex */ +.highlight .mi { color: #cd00cd } /* Literal.Number.Integer */ +.highlight .mo { color: #cd00cd } /* Literal.Number.Oct */ +.highlight .sb { color: #cd0000 } /* Literal.String.Backtick */ +.highlight .sc { color: #cd0000 } /* Literal.String.Char */ +.highlight .sd { color: #cd0000 } /* Literal.String.Doc */ +.highlight .s2 { color: #cd0000 } /* Literal.String.Double */ +.highlight .se { color: #cd0000 } /* Literal.String.Escape */ +.highlight .sh { color: #cd0000 } /* Literal.String.Heredoc */ +.highlight .si { color: #cd0000 } /* Literal.String.Interpol */ +.highlight .sx { color: #cd0000 } /* Literal.String.Other */ +.highlight .sr { color: #cd0000 } /* Literal.String.Regex */ +.highlight .s1 { color: #cd0000 } /* Literal.String.Single */ +.highlight .ss { color: #cd0000 } /* Literal.String.Symbol */ +.highlight .bp { color: #cd00cd } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #00cdcd } /* Name.Variable.Class */ +.highlight .vg { color: #00cdcd } /* Name.Variable.Global */ +.highlight .vi { color: #00cdcd } /* Name.Variable.Instance */ +.highlight .il { color: #cd00cd } /* Literal.Number.Integer.Long */ diff --git a/docs/assets/css/pygments/vs.css b/docs/assets/css/pygments/vs.css new file mode 100644 index 0000000..e1e55d8 --- /dev/null +++ b/docs/assets/css/pygments/vs.css @@ -0,0 +1,33 @@ +.highlight .hll { background-color: #ffffcc } +.highlight .c { color: #008000 } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #0000ff } /* Keyword */ +.highlight .cm { color: #008000 } /* Comment.Multiline */ +.highlight .cp { color: #0000ff } /* Comment.Preproc */ +.highlight .c1 { color: #008000 } /* Comment.Single */ +.highlight .cs { color: #008000 } /* Comment.Special */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gh { font-weight: bold } /* Generic.Heading */ +.highlight .gp { font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { font-weight: bold } /* Generic.Subheading */ +.highlight .kc { color: #0000ff } /* Keyword.Constant */ +.highlight .kd { color: #0000ff } /* Keyword.Declaration */ +.highlight .kn { color: #0000ff } /* Keyword.Namespace */ +.highlight .kp { color: #0000ff } /* Keyword.Pseudo */ +.highlight .kr { color: #0000ff } /* Keyword.Reserved */ +.highlight .kt { color: #2b91af } /* Keyword.Type */ +.highlight .s { color: #a31515 } /* Literal.String */ +.highlight .nc { color: #2b91af } /* Name.Class */ +.highlight .ow { color: #0000ff } /* Operator.Word */ +.highlight .sb { color: #a31515 } /* Literal.String.Backtick */ +.highlight .sc { color: #a31515 } /* Literal.String.Char */ +.highlight .sd { color: #a31515 } /* Literal.String.Doc */ +.highlight .s2 { color: #a31515 } /* Literal.String.Double */ +.highlight .se { color: #a31515 } /* Literal.String.Escape */ +.highlight .sh { color: #a31515 } /* Literal.String.Heredoc */ +.highlight .si { color: #a31515 } /* Literal.String.Interpol */ +.highlight .sx { color: #a31515 } /* Literal.String.Other */ +.highlight .sr { color: #a31515 } /* Literal.String.Regex */ +.highlight .s1 { color: #a31515 } /* Literal.String.Single */ +.highlight .ss { color: #a31515 } /* Literal.String.Symbol */ diff --git a/docs/assets/css/pygments/zenburn.css b/docs/assets/css/pygments/zenburn.css new file mode 100644 index 0000000..287591d --- /dev/null +++ b/docs/assets/css/pygments/zenburn.css @@ -0,0 +1,136 @@ +.highlight code, .highlight pre { +color:#fdce93; +background-color:#3f3f3f; +} + +.highlight .hll { +background-color:#222; +} + +.highlight .err { +color:#e37170; +background-color:#3d3535; +} + +.highlight .k { +color:#f0dfaf; +} + +.highlight .p { +color:#41706f; +} + +.highlight .cs { +color:#cd0000; +font-weight:700; +} + +.highlight .gd { +color:#cd0000; +} + +.highlight .ge { +color:#ccc; +font-style:italic; +} + +.highlight .gr { +color:red; +} + +.highlight .go { +color:gray; +} + +.highlight .gs { +color:#ccc; +font-weight:700; +} + +.highlight .gu { +color:purple; +font-weight:700; +} + +.highlight .gt { +color:#0040D0; +} + +.highlight .kc { +color:#dca3a3; +} + +.highlight .kd { +color:#ffff86; +} + +.highlight .kn { +color:#dfaf8f; +font-weight:700; +} + +.highlight .kp { +color:#cdcf99; +} + +.highlight .kr { +color:#cdcd00; +} + +.highlight .ni { +color:#c28182; +} + +.highlight .ne { +color:#c3bf9f; +font-weight:700; +} + +.highlight .nn { +color:#8fbede; +} + +.highlight .vi { +color:#ffffc7; +} + +.highlight .c,.preview-zenburn .highlight .g,.preview-zenburn .highlight .cm,.preview-zenburn .highlight .cp,.preview-zenburn .highlight .c1 { +color:#7f9f7f; +} + +.highlight .l,.preview-zenburn .highlight .x,.preview-zenburn .highlight .no,.preview-zenburn .highlight .nd,.preview-zenburn .highlight .nl,.preview-zenburn .highlight .nx,.preview-zenburn .highlight .py,.preview-zenburn .highlight .w { +color:#ccc; +} + +.highlight .n,.preview-zenburn .highlight .nv,.preview-zenburn .highlight .vg { +color:#dcdccc; +} + +.highlight .o,.preview-zenburn .highlight .ow { +color:#f0efd0; +} + +.highlight .gh,.preview-zenburn .highlight .gp { +color:#dcdccc; +font-weight:700; +} + +.highlight .gi,.preview-zenburn .highlight .kt { +color:#00cd00; +} + +.highlight .ld,.preview-zenburn .highlight .s,.preview-zenburn .highlight .sb,.preview-zenburn .highlight .sc,.preview-zenburn .highlight .sd,.preview-zenburn .highlight .s2,.preview-zenburn .highlight .se,.preview-zenburn .highlight .sh,.preview-zenburn .highlight .si,.preview-zenburn .highlight .sx,.preview-zenburn .highlight .sr,.preview-zenburn .highlight .s1,.preview-zenburn .highlight .ss { +color:#cc9393; +} + +.highlight .m,.preview-zenburn .highlight .mf,.preview-zenburn .highlight .mh,.preview-zenburn .highlight .mi,.preview-zenburn .highlight .mo,.preview-zenburn .highlight .il { +color:#8cd0d3; +} + +.highlight .na,.preview-zenburn .highlight .nt { +color:#9ac39f; +} + +.highlight .nb,.preview-zenburn .highlight .nc,.preview-zenburn .highlight .nf,.preview-zenburn .highlight .bp,.preview-zenburn .highlight .vc { +color:#efef8f; +} diff --git a/docs/assets/css/spec-style.sass b/docs/assets/css/spec-style.sass new file mode 100644 index 0000000..b7b71c6 --- /dev/null +++ b/docs/assets/css/spec-style.sass @@ -0,0 +1,99 @@ +--- +--- +/* + * style.sass + */ +@import url('https://fonts.googleapis.com/css?family=Inconsolata') + +$monofont: 'Inconsolata', monospace +$gridcolor: #ddd +$gridweight: 2px + +body + font-family: Arial, sans-serif + margin: 10% 25% 10% 10% + line-height: 1.3 + +a + color: navy + text-decoration: none + &:visited + color: navy + text-decoration: none + &:hover + text-decoration: underline + +pre + font-family: $monofont + border: $gridweight solid $gridcolor + //background-color: #f7f7f7 + padding: 1em + margin-left: 1em + overflow-x: auto + +code + //color: #060 + //background-color: #f2f2f2 + font-family: $monofont + +table + border-collapse: collapse + min-width: 50% + margin-left: 1em + +th, td + border: $gridweight solid #ccc + padding: .5em + +th + background-color: #333 + color: #fff + +table.terms + th + display: none + td + vertical-align: top + +table.conventions + th + display: none + td + vertical-align: top + td:first-child + white-space: nowrap + +table.nohead + th + display: none + +table.xyhead + th, td:first-child + background-color: #9bbb59 + th + color: #000 + font-weight: normal + +figure.highlight + background-color: #f2f2f2 + padding-left: 1em + padding-right: 1em + border: $gridweight solid #ccc + +div.syntax + //background-color: $gridcolor + //background-image: linear-gradient(transparent 50%, rgba(255,255,255,.5) 50%) + //background-size: 40px 40px + background-color: #fff + background-image: linear-gradient(90deg, transparent 540px, #abced4 540px, #abced4 542px, transparent 542px), linear-gradient($gridcolor .1em, transparent .1em) + background-size: 100% 1.3em + border-left: $gridweight solid $gridcolor + border-right: $gridweight solid $gridcolor + border-bottom: $gridweight solid $gridcolor + white-space: pre + font-family: $monofont + font-size: 1em + padding-left: 1em + margin-left: 1em + width: 720px + //overflow: auto diff --git a/docs/assets/favicon.ico b/docs/assets/favicon.ico new file mode 100644 index 0000000..4ca5dba Binary files /dev/null and b/docs/assets/favicon.ico differ diff --git a/docs/assets/js/ASCIIMathML.js b/docs/assets/js/ASCIIMathML.js new file mode 100644 index 0000000..727111c --- /dev/null +++ b/docs/assets/js/ASCIIMathML.js @@ -0,0 +1,1127 @@ +/* +ASCIIMathML.js +============== +This file contains JavaScript functions to convert ASCII math notation +and (some) LaTeX to Presentation MathML. The conversion is done while the +HTML page loads, and should work with Firefox and other browsers that can +render MathML. + +Just add the next line to your HTML page with this file in the same folder: + + + +Version 2.2 Mar 3, 2014. +Latest version at https://github.com/mathjax/asciimathml +If you use it on a webpage, please send the URL to jipsen@chapman.edu + +Copyright (c) 2014 Peter Jipsen and other ASCIIMathML.js contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ +var asciimath = {}; + +(function(){ +var mathcolor = "blue"; // change it to "" (to inherit) or another color +var mathfontsize = "1em"; // change to e.g. 1.2em for larger math +var mathfontfamily = "serif"; // change to "" to inherit (works in IE) + // or another family (e.g. "arial") +var automathrecognize = false; // writing "amath" on page makes this true +var checkForMathML = true; // check if browser can display MathML +var notifyIfNoMathML = true; // display note at top if no MathML capability +var alertIfNoMathML = false; // show alert box if no MathML capability +var translateOnLoad = true; // set to false to do call translators from js +var translateASCIIMath = true; // false to preserve `..` +var displaystyle = true; // puts limits above and below large operators +var showasciiformulaonhover = true; // helps students learn ASCIIMath +var decimalsign = "."; // change to "," if you like, beware of `(1,2)`! +var AMdelimiter1 = "`", AMescape1 = "\\\\`"; // can use other characters +var AMdocumentId = "wikitext" // PmWiki element containing math (default=body) +var fixphi = true; //false to return to legacy phi/varphi mapping + +/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ + +var isIE = (navigator.appName.slice(0,9)=="Microsoft"); +var noMathML = false, translated = false; + +if (isIE) { // add MathPlayer info to IE webpages + document.write(""); + document.write(""); +} + +// Add a stylesheet, replacing any previous custom stylesheet (adapted from TW) +function setStylesheet(s) { + var id = "AMMLcustomStyleSheet"; + var n = document.getElementById(id); + if(document.createStyleSheet) { + // Test for IE's non-standard createStyleSheet method + if(n) + n.parentNode.removeChild(n); + // This failed without the   + document.getElementsByTagName("head")[0].insertAdjacentHTML("beforeEnd"," "); + } else { + if(n) { + n.replaceChild(document.createTextNode(s),n.firstChild); + } else { + n = document.createElement("style"); + n.type = "text/css"; + n.id = id; + n.appendChild(document.createTextNode(s)); + document.getElementsByTagName("head")[0].appendChild(n); + } + } +} + +setStylesheet("#AMMLcloseDiv \{font-size:0.8em; padding-top:1em; color:#014\}\n#AMMLwarningBox \{position:absolute; width:100%; top:0; left:0; z-index:200; text-align:center; font-size:1em; font-weight:bold; padding:0.5em 0 0.5em 0; color:#ffc; background:#c30\}"); + +function init(){ + var msg, warnings = new Array(); + if (document.getElementById==null){ + alert("This webpage requires a recent browser such as Mozilla Firefox"); + return null; + } + if (checkForMathML && (msg = checkMathML())) warnings.push(msg); + if (warnings.length>0) displayWarnings(warnings); + if (!noMathML) initSymbols(); + return true; +} + +function checkMathML(){ + if (navigator.appName.slice(0,8)=="Netscape") + if (navigator.appVersion.slice(0,1)>="5") noMathML = null; + else noMathML = true; + else if (navigator.appName.slice(0,9)=="Microsoft") + try { + var ActiveX = new ActiveXObject("MathPlayer.Factory.1"); + noMathML = null; + } catch (e) { + noMathML = true; + } + else if (navigator.appName.slice(0,5)=="Opera") + if (navigator.appVersion.slice(0,3)>="9.5") noMathML = null; + else noMathML = true; +//noMathML = true; //uncomment to check + if (noMathML && notifyIfNoMathML) { + var msg = "To view the ASCIIMathML notation use Internet Explorer + MathPlayer or Mozilla Firefox 2.0 or later."; + if (alertIfNoMathML) + alert(msg); + else return msg; + } +} + +function hideWarning(){ + var body = document.getElementsByTagName("body")[0]; + body.removeChild(document.getElementById('AMMLwarningBox')); + body.onclick = null; +} + +function displayWarnings(warnings) { + var i, frag, nd = createElementXHTML("div"); + var body = document.getElementsByTagName("body")[0]; + body.onclick=hideWarning; + nd.id = 'AMMLwarningBox'; + for (i=0; i<", tag:"mo", output:"\u22C9", tex:"ltimes", ttype:CONST}, +{input:"><|", tag:"mo", output:"\u22CA", tex:"rtimes", ttype:CONST}, +{input:"|><|", tag:"mo", output:"\u22C8", tex:"bowtie", ttype:CONST}, +{input:"-:", tag:"mo", output:"\u00F7", tex:"div", ttype:CONST}, +{input:"divide", tag:"mo", output:"-:", tex:null, ttype:DEFINITION}, +{input:"@", tag:"mo", output:"\u2218", tex:"circ", ttype:CONST}, +{input:"o+", tag:"mo", output:"\u2295", tex:"oplus", ttype:CONST}, +{input:"ox", tag:"mo", output:"\u2297", tex:"otimes", ttype:CONST}, +{input:"o.", tag:"mo", output:"\u2299", tex:"odot", ttype:CONST}, +{input:"sum", tag:"mo", output:"\u2211", tex:null, ttype:UNDEROVER}, +{input:"prod", tag:"mo", output:"\u220F", tex:null, ttype:UNDEROVER}, +{input:"^^", tag:"mo", output:"\u2227", tex:"wedge", ttype:CONST}, +{input:"^^^", tag:"mo", output:"\u22C0", tex:"bigwedge", ttype:UNDEROVER}, +{input:"vv", tag:"mo", output:"\u2228", tex:"vee", ttype:CONST}, +{input:"vvv", tag:"mo", output:"\u22C1", tex:"bigvee", ttype:UNDEROVER}, +{input:"nn", tag:"mo", output:"\u2229", tex:"cap", ttype:CONST}, +{input:"nnn", tag:"mo", output:"\u22C2", tex:"bigcap", ttype:UNDEROVER}, +{input:"uu", tag:"mo", output:"\u222A", tex:"cup", ttype:CONST}, +{input:"uuu", tag:"mo", output:"\u22C3", tex:"bigcup", ttype:UNDEROVER}, + +//binary relation symbols +{input:"!=", tag:"mo", output:"\u2260", tex:"ne", ttype:CONST}, +{input:":=", tag:"mo", output:":=", tex:null, ttype:CONST}, +{input:"lt", tag:"mo", output:"<", tex:null, ttype:CONST}, +{input:"<=", tag:"mo", output:"\u2264", tex:"le", ttype:CONST}, +{input:"lt=", tag:"mo", output:"\u2264", tex:"leq", ttype:CONST}, +{input:"gt", tag:"mo", output:">", tex:null, ttype:CONST}, +{input:">=", tag:"mo", output:"\u2265", tex:"ge", ttype:CONST}, +{input:"gt=", tag:"mo", output:"\u2265", tex:"geq", ttype:CONST}, +{input:"-<", tag:"mo", output:"\u227A", tex:"prec", ttype:CONST}, +{input:"-lt", tag:"mo", output:"\u227A", tex:null, ttype:CONST}, +{input:">-", tag:"mo", output:"\u227B", tex:"succ", ttype:CONST}, +{input:"-<=", tag:"mo", output:"\u2AAF", tex:"preceq", ttype:CONST}, +{input:">-=", tag:"mo", output:"\u2AB0", tex:"succeq", ttype:CONST}, +{input:"in", tag:"mo", output:"\u2208", tex:null, ttype:CONST}, +{input:"!in", tag:"mo", output:"\u2209", tex:"notin", ttype:CONST}, +{input:"sub", tag:"mo", output:"\u2282", tex:"subset", ttype:CONST}, +{input:"sup", tag:"mo", output:"\u2283", tex:"supset", ttype:CONST}, +{input:"sube", tag:"mo", output:"\u2286", tex:"subseteq", ttype:CONST}, +{input:"supe", tag:"mo", output:"\u2287", tex:"supseteq", ttype:CONST}, +{input:"-=", tag:"mo", output:"\u2261", tex:"equiv", ttype:CONST}, +{input:"~=", tag:"mo", output:"\u2245", tex:"cong", ttype:CONST}, +{input:"~~", tag:"mo", output:"\u2248", tex:"approx", ttype:CONST}, +{input:"prop", tag:"mo", output:"\u221D", tex:"propto", ttype:CONST}, + +//logical symbols +{input:"and", tag:"mtext", output:"and", tex:null, ttype:SPACE}, +{input:"or", tag:"mtext", output:"or", tex:null, ttype:SPACE}, +{input:"not", tag:"mo", output:"\u00AC", tex:"neg", ttype:CONST}, +{input:"=>", tag:"mo", output:"\u21D2", tex:"implies", ttype:CONST}, +{input:"if", tag:"mo", output:"if", tex:null, ttype:SPACE}, +{input:"<=>", tag:"mo", output:"\u21D4", tex:"iff", ttype:CONST}, +{input:"AA", tag:"mo", output:"\u2200", tex:"forall", ttype:CONST}, +{input:"EE", tag:"mo", output:"\u2203", tex:"exists", ttype:CONST}, +{input:"_|_", tag:"mo", output:"\u22A5", tex:"bot", ttype:CONST}, +{input:"TT", tag:"mo", output:"\u22A4", tex:"top", ttype:CONST}, +{input:"|--", tag:"mo", output:"\u22A2", tex:"vdash", ttype:CONST}, +{input:"|==", tag:"mo", output:"\u22A8", tex:"models", ttype:CONST}, + +//grouping brackets +{input:"(", tag:"mo", output:"(", tex:null, ttype:LEFTBRACKET}, +{input:")", tag:"mo", output:")", tex:null, ttype:RIGHTBRACKET}, +{input:"[", tag:"mo", output:"[", tex:null, ttype:LEFTBRACKET}, +{input:"]", tag:"mo", output:"]", tex:null, ttype:RIGHTBRACKET}, +{input:"{", tag:"mo", output:"{", tex:null, ttype:LEFTBRACKET}, +{input:"}", tag:"mo", output:"}", tex:null, ttype:RIGHTBRACKET}, +{input:"|", tag:"mo", output:"|", tex:null, ttype:LEFTRIGHT}, +//{input:"||", tag:"mo", output:"||", tex:null, ttype:LEFTRIGHT}, +{input:"(:", tag:"mo", output:"\u2329", tex:"langle", ttype:LEFTBRACKET}, +{input:":)", tag:"mo", output:"\u232A", tex:"rangle", ttype:RIGHTBRACKET}, +{input:"<<", tag:"mo", output:"\u2329", tex:null, ttype:LEFTBRACKET}, +{input:">>", tag:"mo", output:"\u232A", tex:null, ttype:RIGHTBRACKET}, +{input:"{:", tag:"mo", output:"{:", tex:null, ttype:LEFTBRACKET, invisible:true}, +{input:":}", tag:"mo", output:":}", tex:null, ttype:RIGHTBRACKET, invisible:true}, + +//miscellaneous symbols +{input:"int", tag:"mo", output:"\u222B", tex:null, ttype:CONST}, +{input:"dx", tag:"mi", output:"{:d x:}", tex:null, ttype:DEFINITION}, +{input:"dy", tag:"mi", output:"{:d y:}", tex:null, ttype:DEFINITION}, +{input:"dz", tag:"mi", output:"{:d z:}", tex:null, ttype:DEFINITION}, +{input:"dt", tag:"mi", output:"{:d t:}", tex:null, ttype:DEFINITION}, +{input:"oint", tag:"mo", output:"\u222E", tex:null, ttype:CONST}, +{input:"del", tag:"mo", output:"\u2202", tex:"partial", ttype:CONST}, +{input:"grad", tag:"mo", output:"\u2207", tex:"nabla", ttype:CONST}, +{input:"+-", tag:"mo", output:"\u00B1", tex:"pm", ttype:CONST}, +{input:"O/", tag:"mo", output:"\u2205", tex:"emptyset", ttype:CONST}, +{input:"oo", tag:"mo", output:"\u221E", tex:"infty", ttype:CONST}, +{input:"aleph", tag:"mo", output:"\u2135", tex:null, ttype:CONST}, +{input:"...", tag:"mo", output:"...", tex:"ldots", ttype:CONST}, +{input:":.", tag:"mo", output:"\u2234", tex:"therefore", ttype:CONST}, +{input:":'", tag:"mo", output:"\u2235", tex:"because", ttype:CONST}, +{input:"/_", tag:"mo", output:"\u2220", tex:"angle", ttype:CONST}, +{input:"/_\\", tag:"mo", output:"\u25B3", tex:"triangle", ttype:CONST}, +{input:"'", tag:"mo", output:"\u2032", tex:"prime", ttype:CONST}, +{input:"tilde", tag:"mover", output:"~", tex:null, ttype:UNARY, acc:true}, +{input:"\\ ", tag:"mo", output:"\u00A0", tex:null, ttype:CONST}, +{input:"frown", tag:"mo", output:"\u2322", tex:null, ttype:CONST}, +{input:"quad", tag:"mo", output:"\u00A0\u00A0", tex:null, ttype:CONST}, +{input:"qquad", tag:"mo", output:"\u00A0\u00A0\u00A0\u00A0", tex:null, ttype:CONST}, +{input:"cdots", tag:"mo", output:"\u22EF", tex:null, ttype:CONST}, +{input:"vdots", tag:"mo", output:"\u22EE", tex:null, ttype:CONST}, +{input:"ddots", tag:"mo", output:"\u22F1", tex:null, ttype:CONST}, +{input:"diamond", tag:"mo", output:"\u22C4", tex:null, ttype:CONST}, +{input:"square", tag:"mo", output:"\u25A1", tex:null, ttype:CONST}, +{input:"|__", tag:"mo", output:"\u230A", tex:"lfloor", ttype:CONST}, +{input:"__|", tag:"mo", output:"\u230B", tex:"rfloor", ttype:CONST}, +{input:"|~", tag:"mo", output:"\u2308", tex:"lceiling", ttype:CONST}, +{input:"~|", tag:"mo", output:"\u2309", tex:"rceiling", ttype:CONST}, +{input:"CC", tag:"mo", output:"\u2102", tex:null, ttype:CONST}, +{input:"NN", tag:"mo", output:"\u2115", tex:null, ttype:CONST}, +{input:"QQ", tag:"mo", output:"\u211A", tex:null, ttype:CONST}, +{input:"RR", tag:"mo", output:"\u211D", tex:null, ttype:CONST}, +{input:"ZZ", tag:"mo", output:"\u2124", tex:null, ttype:CONST}, +{input:"f", tag:"mi", output:"f", tex:null, ttype:UNARY, func:true}, +{input:"g", tag:"mi", output:"g", tex:null, ttype:UNARY, func:true}, + +//standard functions +{input:"lim", tag:"mo", output:"lim", tex:null, ttype:UNDEROVER}, +{input:"Lim", tag:"mo", output:"Lim", tex:null, ttype:UNDEROVER}, +{input:"sin", tag:"mo", output:"sin", tex:null, ttype:UNARY, func:true}, +{input:"cos", tag:"mo", output:"cos", tex:null, ttype:UNARY, func:true}, +{input:"tan", tag:"mo", output:"tan", tex:null, ttype:UNARY, func:true}, +{input:"sinh", tag:"mo", output:"sinh", tex:null, ttype:UNARY, func:true}, +{input:"cosh", tag:"mo", output:"cosh", tex:null, ttype:UNARY, func:true}, +{input:"tanh", tag:"mo", output:"tanh", tex:null, ttype:UNARY, func:true}, +{input:"cot", tag:"mo", output:"cot", tex:null, ttype:UNARY, func:true}, +{input:"sec", tag:"mo", output:"sec", tex:null, ttype:UNARY, func:true}, +{input:"csc", tag:"mo", output:"csc", tex:null, ttype:UNARY, func:true}, +{input:"arcsin", tag:"mo", output:"arcsin", tex:null, ttype:UNARY, func:true}, +{input:"arccos", tag:"mo", output:"arccos", tex:null, ttype:UNARY, func:true}, +{input:"arctan", tag:"mo", output:"arctan", tex:null, ttype:UNARY, func:true}, +{input:"coth", tag:"mo", output:"coth", tex:null, ttype:UNARY, func:true}, +{input:"sech", tag:"mo", output:"sech", tex:null, ttype:UNARY, func:true}, +{input:"csch", tag:"mo", output:"csch", tex:null, ttype:UNARY, func:true}, +{input:"exp", tag:"mo", output:"exp", tex:null, ttype:UNARY, func:true}, +{input:"abs", tag:"mo", output:"abs", tex:null, ttype:UNARY, rewriteleftright:["|","|"]}, +{input:"norm", tag:"mo", output:"norm", tex:null, ttype:UNARY, rewriteleftright:["\u2225","\u2225"]}, +{input:"floor", tag:"mo", output:"floor", tex:null, ttype:UNARY, rewriteleftright:["\u230A","\u230B"]}, +{input:"ceil", tag:"mo", output:"ceil", tex:null, ttype:UNARY, rewriteleftright:["\u2308","\u2309"]}, +{input:"log", tag:"mo", output:"log", tex:null, ttype:UNARY, func:true}, +{input:"ln", tag:"mo", output:"ln", tex:null, ttype:UNARY, func:true}, +{input:"det", tag:"mo", output:"det", tex:null, ttype:UNARY, func:true}, +{input:"dim", tag:"mo", output:"dim", tex:null, ttype:CONST}, +{input:"mod", tag:"mo", output:"mod", tex:null, ttype:CONST}, +{input:"gcd", tag:"mo", output:"gcd", tex:null, ttype:UNARY, func:true}, +{input:"lcm", tag:"mo", output:"lcm", tex:null, ttype:UNARY, func:true}, +{input:"lub", tag:"mo", output:"lub", tex:null, ttype:CONST}, +{input:"glb", tag:"mo", output:"glb", tex:null, ttype:CONST}, +{input:"min", tag:"mo", output:"min", tex:null, ttype:UNDEROVER}, +{input:"max", tag:"mo", output:"max", tex:null, ttype:UNDEROVER}, + +//arrows +{input:"uarr", tag:"mo", output:"\u2191", tex:"uparrow", ttype:CONST}, +{input:"darr", tag:"mo", output:"\u2193", tex:"downarrow", ttype:CONST}, +{input:"rarr", tag:"mo", output:"\u2192", tex:"rightarrow", ttype:CONST}, +{input:"->", tag:"mo", output:"\u2192", tex:"to", ttype:CONST}, +{input:">->", tag:"mo", output:"\u21A3", tex:"rightarrowtail", ttype:CONST}, +{input:"->>", tag:"mo", output:"\u21A0", tex:"twoheadrightarrow", ttype:CONST}, +{input:">->>", tag:"mo", output:"\u2916", tex:"twoheadrightarrowtail", ttype:CONST}, +{input:"|->", tag:"mo", output:"\u21A6", tex:"mapsto", ttype:CONST}, +{input:"larr", tag:"mo", output:"\u2190", tex:"leftarrow", ttype:CONST}, +{input:"harr", tag:"mo", output:"\u2194", tex:"leftrightarrow", ttype:CONST}, +{input:"rArr", tag:"mo", output:"\u21D2", tex:"Rightarrow", ttype:CONST}, +{input:"lArr", tag:"mo", output:"\u21D0", tex:"Leftarrow", ttype:CONST}, +{input:"hArr", tag:"mo", output:"\u21D4", tex:"Leftrightarrow", ttype:CONST}, +//commands with argument +{input:"sqrt", tag:"msqrt", output:"sqrt", tex:null, ttype:UNARY}, +{input:"root", tag:"mroot", output:"root", tex:null, ttype:BINARY}, +{input:"frac", tag:"mfrac", output:"/", tex:null, ttype:BINARY}, +{input:"/", tag:"mfrac", output:"/", tex:null, ttype:INFIX}, +{input:"stackrel", tag:"mover", output:"stackrel", tex:null, ttype:BINARY}, +{input:"overset", tag:"mover", output:"stackrel", tex:null, ttype:BINARY}, +{input:"underset", tag:"munder", output:"stackrel", tex:null, ttype:BINARY}, +{input:"_", tag:"msub", output:"_", tex:null, ttype:INFIX}, +{input:"^", tag:"msup", output:"^", tex:null, ttype:INFIX}, +{input:"hat", tag:"mover", output:"\u005E", tex:null, ttype:UNARY, acc:true}, +{input:"bar", tag:"mover", output:"\u00AF", tex:"overline", ttype:UNARY, acc:true}, +{input:"vec", tag:"mover", output:"\u2192", tex:null, ttype:UNARY, acc:true}, +{input:"dot", tag:"mover", output:".", tex:null, ttype:UNARY, acc:true}, +{input:"ddot", tag:"mover", output:"..", tex:null, ttype:UNARY, acc:true}, +{input:"ul", tag:"munder", output:"\u0332", tex:"underline", ttype:UNARY, acc:true}, +{input:"ubrace", tag:"munder", output:"\u23DF", tex:"underbrace", ttype:UNARYUNDEROVER, acc:true}, +{input:"obrace", tag:"mover", output:"\u23DE", tex:"overbrace", ttype:UNARYUNDEROVER, acc:true}, +{input:"text", tag:"mtext", output:"text", tex:null, ttype:TEXT}, +{input:"mbox", tag:"mtext", output:"mbox", tex:null, ttype:TEXT}, +{input:"color", tag:"mstyle", ttype:BINARY}, +{input:"cancel", tag:"menclose", output:"cancel", tex:null, ttype:UNARY}, +AMquote, +{input:"bb", tag:"mstyle", atname:"mathvariant", atval:"bold", output:"bb", tex:null, ttype:UNARY}, +{input:"mathbf", tag:"mstyle", atname:"mathvariant", atval:"bold", output:"mathbf", tex:null, ttype:UNARY}, +{input:"sf", tag:"mstyle", atname:"mathvariant", atval:"sans-serif", output:"sf", tex:null, ttype:UNARY}, +{input:"mathsf", tag:"mstyle", atname:"mathvariant", atval:"sans-serif", output:"mathsf", tex:null, ttype:UNARY}, +{input:"bbb", tag:"mstyle", atname:"mathvariant", atval:"double-struck", output:"bbb", tex:null, ttype:UNARY, codes:AMbbb}, +{input:"mathbb", tag:"mstyle", atname:"mathvariant", atval:"double-struck", output:"mathbb", tex:null, ttype:UNARY, codes:AMbbb}, +{input:"cc", tag:"mstyle", atname:"mathvariant", atval:"script", output:"cc", tex:null, ttype:UNARY, codes:AMcal}, +{input:"mathcal", tag:"mstyle", atname:"mathvariant", atval:"script", output:"mathcal", tex:null, ttype:UNARY, codes:AMcal}, +{input:"tt", tag:"mstyle", atname:"mathvariant", atval:"monospace", output:"tt", tex:null, ttype:UNARY}, +{input:"mathtt", tag:"mstyle", atname:"mathvariant", atval:"monospace", output:"mathtt", tex:null, ttype:UNARY}, +{input:"fr", tag:"mstyle", atname:"mathvariant", atval:"fraktur", output:"fr", tex:null, ttype:UNARY, codes:AMfrk}, +{input:"mathfrak", tag:"mstyle", atname:"mathvariant", atval:"fraktur", output:"mathfrak", tex:null, ttype:UNARY, codes:AMfrk} +]; + +function compareNames(s1,s2) { + if (s1.input > s2.input) return 1 + else return -1; +} + +var AMnames = []; //list of input symbols + +function initSymbols() { + var i; + var symlen = AMsymbols.length; + for (i=0; i=n where str appears or would be inserted +// assumes arr is sorted + if (n==0) { + var h,m; + n = -1; + h = arr.length; + while (n+1> 1; + if (arr[m]=str +} + +function AMgetSymbol(str) { +//return maximal initial substring of str that appears in names +//return null if there is none + var k = 0; //new pos + var j = 0; //old pos + var mk; //match pos + var st; + var tagst; + var match = ""; + var more = true; + for (var i=1; i<=str.length && more; i++) { + st = str.slice(0,i); //initial substring of length i + j = k; + k = position(AMnames, st, j); + if (k=AMnames[k]; + } + AMpreviousSymbol=AMcurrentSymbol; + if (match!=""){ + AMcurrentSymbol=AMsymbols[mk].ttype; + return AMsymbols[mk]; + } +// if str[0] is a digit or - return maxsubstring of digits.digits + AMcurrentSymbol=CONST; + k = 1; + st = str.slice(0,1); + var integ = true; + while ("0"<=st && st<="9" && k<=str.length) { + st = str.slice(k,k+1); + k++; + } + if (st == decimalsign) { + st = str.slice(k,k+1); + if ("0"<=st && st<="9") { + integ = false; + k++; + while ("0"<=st && st<="9" && k<=str.length) { + st = str.slice(k,k+1); + k++; + } + } + } + if ((integ && k>1) || k>2) { + st = str.slice(0,k-1); + tagst = "mn"; + } else { + k = 2; + st = str.slice(0,1); //take 1 character + tagst = (("A">st || st>"Z") && ("a">st || st>"z")?"mo":"mi"); + } + if (st=="-" && AMpreviousSymbol==INFIX) { + AMcurrentSymbol = INFIX; //trick "/" into recognizing "-" on second parse + return {input:st, tag:tagst, output:st, ttype:UNARY, func:true}; + } + return {input:st, tag:tagst, output:st, ttype:CONST}; +} + +function AMremoveBrackets(node) { + var st; + if (!node.hasChildNodes()) { return; } + if (node.firstChild.hasChildNodes() && (node.nodeName=="mrow" || node.nodeName=="M:MROW")) { + st = node.firstChild.firstChild.nodeValue; + if (st=="(" || st=="[" || st=="{") node.removeChild(node.firstChild); + } + if (node.lastChild.hasChildNodes() && (node.nodeName=="mrow" || node.nodeName=="M:MROW")) { + st = node.lastChild.firstChild.nodeValue; + if (st==")" || st=="]" || st=="}") node.removeChild(node.lastChild); + } +} + +/*Parsing ASCII math expressions with the following grammar +v ::= [A-Za-z] | greek letters | numbers | other constant symbols +u ::= sqrt | text | bb | other unary symbols for font commands +b ::= frac | root | stackrel binary symbols +l ::= ( | [ | { | (: | {: left brackets +r ::= ) | ] | } | :) | :} right brackets +S ::= v | lEr | uS | bSS Simple expression +I ::= S_S | S^S | S_S^S | S Intermediate expression +E ::= IE | I/I Expression +Each terminal symbol is translated into a corresponding mathml node.*/ + +var AMnestingDepth,AMpreviousSymbol,AMcurrentSymbol; + +function AMparseSexpr(str) { //parses str and returns [node,tailstr] + var symbol, node, result, i, st,// rightvert = false, + newFrag = document.createDocumentFragment(); + str = AMremoveCharsAndBlanks(str,0); + symbol = AMgetSymbol(str); //either a token or a bracket or empty + if (symbol == null || symbol.ttype == RIGHTBRACKET && AMnestingDepth > 0) { + return [null,str]; + } + if (symbol.ttype == DEFINITION) { + str = symbol.output+AMremoveCharsAndBlanks(str,symbol.input.length); + symbol = AMgetSymbol(str); + } + switch (symbol.ttype) { case UNDEROVER: + case CONST: + str = AMremoveCharsAndBlanks(str,symbol.input.length); + return [createMmlNode(symbol.tag, //its a constant + document.createTextNode(symbol.output)),str]; + case LEFTBRACKET: //read (expr+) + AMnestingDepth++; + str = AMremoveCharsAndBlanks(str,symbol.input.length); + result = AMparseExpr(str,true); + AMnestingDepth--; + if (typeof symbol.invisible == "boolean" && symbol.invisible) + node = createMmlNode("mrow",result[0]); + else { + node = createMmlNode("mo",document.createTextNode(symbol.output)); + node = createMmlNode("mrow",node); + node.appendChild(result[0]); + } + return [node,result[1]]; + case TEXT: + if (symbol!=AMquote) str = AMremoveCharsAndBlanks(str,symbol.input.length); + if (str.charAt(0)=="{") i=str.indexOf("}"); + else if (str.charAt(0)=="(") i=str.indexOf(")"); + else if (str.charAt(0)=="[") i=str.indexOf("]"); + else if (symbol==AMquote) i=str.slice(1).indexOf("\"")+1; + else i = 0; + if (i==-1) i = str.length; + st = str.slice(1,i); + if (st.charAt(0) == " ") { + node = createMmlNode("mspace"); + node.setAttribute("width","1ex"); + newFrag.appendChild(node); + } + newFrag.appendChild( + createMmlNode(symbol.tag,document.createTextNode(st))); + if (st.charAt(st.length-1) == " ") { + node = createMmlNode("mspace"); + node.setAttribute("width","1ex"); + newFrag.appendChild(node); + } + str = AMremoveCharsAndBlanks(str,i+1); + return [createMmlNode("mrow",newFrag),str]; + case UNARYUNDEROVER: + case UNARY: + str = AMremoveCharsAndBlanks(str,symbol.input.length); + result = AMparseSexpr(str); + if (result[0]==null) return [createMmlNode(symbol.tag, + document.createTextNode(symbol.output)),str]; + if (typeof symbol.func == "boolean" && symbol.func) { // functions hack + st = str.charAt(0); + if (st=="^" || st=="_" || st=="/" || st=="|" || st=="," || + (symbol.input.length==1 && symbol.input.match(/\w/) && st!="(")) { + return [createMmlNode(symbol.tag, + document.createTextNode(symbol.output)),str]; + } else { + node = createMmlNode("mrow", + createMmlNode(symbol.tag,document.createTextNode(symbol.output))); + node.appendChild(result[0]); + return [node,result[1]]; + } + } + AMremoveBrackets(result[0]); + if (symbol.input == "sqrt") { // sqrt + return [createMmlNode(symbol.tag,result[0]),result[1]]; + } else if (typeof symbol.rewriteleftright != "undefined") { // abs, floor, ceil + node = createMmlNode("mrow", createMmlNode("mo",document.createTextNode(symbol.rewriteleftright[0]))); + node.appendChild(result[0]); + node.appendChild(createMmlNode("mo",document.createTextNode(symbol.rewriteleftright[1]))); + return [node,result[1]]; + } else if (symbol.input == "cancel") { // cancel + node = createMmlNode(symbol.tag,result[0]); + node.setAttribute("notation","updiagonalstrike"); + return [node,result[1]]; + } else if (typeof symbol.acc == "boolean" && symbol.acc) { // accent + node = createMmlNode(symbol.tag,result[0]); + node.appendChild(createMmlNode("mo",document.createTextNode(symbol.output))); + return [node,result[1]]; + } else { // font change command + if (!isIE && typeof symbol.codes != "undefined") { + for (i=0; i64 && st.charCodeAt(j)<91) + newst = newst + symbol.codes[st.charCodeAt(j)-65]; + else if (st.charCodeAt(j)>96 && st.charCodeAt(j)<123) + newst = newst + symbol.codes[st.charCodeAt(j)-71]; + else newst = newst + st.charAt(j); + if (result[0].nodeName=="mi") + result[0]=createMmlNode("mo"). + appendChild(document.createTextNode(newst)); + else result[0].replaceChild(createMmlNode("mo"). + appendChild(document.createTextNode(newst)), + result[0].childNodes[i]); + } + } + node = createMmlNode(symbol.tag,result[0]); + node.setAttribute(symbol.atname,symbol.atval); + return [node,result[1]]; + } + case BINARY: + str = AMremoveCharsAndBlanks(str,symbol.input.length); + result = AMparseSexpr(str); + if (result[0]==null) return [createMmlNode("mo", + document.createTextNode(symbol.input)),str]; + AMremoveBrackets(result[0]); + var result2 = AMparseSexpr(result[1]); + if (result2[0]==null) return [createMmlNode("mo", + document.createTextNode(symbol.input)),str]; + AMremoveBrackets(result2[0]); + if (symbol.input=="color") { + if (str.charAt(0)=="{") i=str.indexOf("}"); + else if (str.charAt(0)=="(") i=str.indexOf(")"); + else if (str.charAt(0)=="[") i=str.indexOf("]"); + st = str.slice(1,i); + node = createMmlNode(symbol.tag,result2[0]); + node.setAttribute("mathcolor",st); + return [node,result2[1]]; + } + if (symbol.input=="root" || symbol.output=="stackrel") + newFrag.appendChild(result2[0]); + newFrag.appendChild(result[0]); + if (symbol.input=="frac") newFrag.appendChild(result2[0]); + return [createMmlNode(symbol.tag,newFrag),result2[1]]; + case INFIX: + str = AMremoveCharsAndBlanks(str,symbol.input.length); + return [createMmlNode("mo",document.createTextNode(symbol.output)),str]; + case SPACE: + str = AMremoveCharsAndBlanks(str,symbol.input.length); + node = createMmlNode("mspace"); + node.setAttribute("width","1ex"); + newFrag.appendChild(node); + newFrag.appendChild( + createMmlNode(symbol.tag,document.createTextNode(symbol.output))); + node = createMmlNode("mspace"); + node.setAttribute("width","1ex"); + newFrag.appendChild(node); + return [createMmlNode("mrow",newFrag),str]; + case LEFTRIGHT: +// if (rightvert) return [null,str]; else rightvert = true; + AMnestingDepth++; + str = AMremoveCharsAndBlanks(str,symbol.input.length); + result = AMparseExpr(str,false); + AMnestingDepth--; + st = ""; + if (result[0].lastChild!=null) + st = result[0].lastChild.firstChild.nodeValue; + if (st == "|") { // its an absolute value subterm + node = createMmlNode("mo",document.createTextNode(symbol.output)); + node = createMmlNode("mrow",node); + node.appendChild(result[0]); + return [node,result[1]]; + } else { // the "|" is a \mid so use unicode 2223 (divides) for spacing + node = createMmlNode("mo",document.createTextNode("\u2223")); + node = createMmlNode("mrow",node); + return [node,str]; + } + default: +//alert("default"); + str = AMremoveCharsAndBlanks(str,symbol.input.length); + return [createMmlNode(symbol.tag, //its a constant + document.createTextNode(symbol.output)),str]; + } +} + +function AMparseIexpr(str) { + var symbol, sym1, sym2, node, result, underover; + str = AMremoveCharsAndBlanks(str,0); + sym1 = AMgetSymbol(str); + result = AMparseSexpr(str); + node = result[0]; + str = result[1]; + symbol = AMgetSymbol(str); + if (symbol.ttype == INFIX && symbol.input != "/") { + str = AMremoveCharsAndBlanks(str,symbol.input.length); +// if (symbol.input == "/") result = AMparseIexpr(str); else ... + result = AMparseSexpr(str); + if (result[0] == null) // show box in place of missing argument + result[0] = createMmlNode("mo",document.createTextNode("\u25A1")); + else AMremoveBrackets(result[0]); + str = result[1]; +// if (symbol.input == "/") AMremoveBrackets(node); + underover = (sym1.ttype == UNDEROVER || sym1.ttype == UNARYUNDEROVER); + if (symbol.input == "_") { + sym2 = AMgetSymbol(str); + if (sym2.input == "^") { + str = AMremoveCharsAndBlanks(str,sym2.input.length); + var res2 = AMparseSexpr(str); + AMremoveBrackets(res2[0]); + str = res2[1]; + node = createMmlNode((underover?"munderover":"msubsup"),node); + node.appendChild(result[0]); + node.appendChild(res2[0]); + node = createMmlNode("mrow",node); // so sum does not stretch + } else { + node = createMmlNode((underover?"munder":"msub"),node); + node.appendChild(result[0]); + } + } else if (symbol.input == "^" && underover) { + node = createMmlNode("mover",node); + node.appendChild(result[0]); + } else { + node = createMmlNode(symbol.tag,node); + node.appendChild(result[0]); + } + if (typeof sym1.func != 'undefined' && sym1.func) { + sym2 = AMgetSymbol(str); + if (sym2.ttype != INFIX && sym2.ttype != RIGHTBRACKET) { + result = AMparseIexpr(str); + node = createMmlNode("mrow",node); + node.appendChild(result[0]); + str = result[1]; + } + } + } + return [node,str]; +} + +function AMparseExpr(str,rightbracket) { + var symbol, node, result, i, + newFrag = document.createDocumentFragment(); + do { + str = AMremoveCharsAndBlanks(str,0); + result = AMparseIexpr(str); + node = result[0]; + str = result[1]; + symbol = AMgetSymbol(str); + if (symbol.ttype == INFIX && symbol.input == "/") { + str = AMremoveCharsAndBlanks(str,symbol.input.length); + result = AMparseIexpr(str); + if (result[0] == null) // show box in place of missing argument + result[0] = createMmlNode("mo",document.createTextNode("\u25A1")); + else AMremoveBrackets(result[0]); + str = result[1]; + AMremoveBrackets(node); + node = createMmlNode(symbol.tag,node); + node.appendChild(result[0]); + newFrag.appendChild(node); + symbol = AMgetSymbol(str); + } + else if (node!=undefined) newFrag.appendChild(node); + } while ((symbol.ttype != RIGHTBRACKET && + (symbol.ttype != LEFTRIGHT || rightbracket) + || AMnestingDepth == 0) && symbol!=null && symbol.output!=""); + if (symbol.ttype == RIGHTBRACKET || symbol.ttype == LEFTRIGHT) { +// if (AMnestingDepth > 0) AMnestingDepth--; + var len = newFrag.childNodes.length; + if (len>0 && newFrag.childNodes[len-1].nodeName == "mrow" + && newFrag.childNodes[len-1].lastChild + && newFrag.childNodes[len-1].lastChild.firstChild ) { //matrix + //removed to allow row vectors: //&& len>1 && + //newFrag.childNodes[len-2].nodeName == "mo" && + //newFrag.childNodes[len-2].firstChild.nodeValue == "," + var right = newFrag.childNodes[len-1].lastChild.firstChild.nodeValue; + if (right==")" || right=="]") { + var left = newFrag.childNodes[len-1].firstChild.firstChild.nodeValue; + if (left=="(" && right==")" && symbol.output != "}" || + left=="[" && right=="]") { + var pos = []; // positions of commas + var matrix = true; + var m = newFrag.childNodes.length; + for (i=0; matrix && i1) matrix = pos[i].length == pos[i-2].length; + } + matrix = matrix && (pos.length>1 || pos[0].length>0); + if (matrix) { + var row, frag, n, k, table = document.createDocumentFragment(); + for (i=0; i(-,-,...,-,-) + n = node.childNodes.length; + k = 0; + node.removeChild(node.firstChild); //remove ( + for (j=1; j2) { + newFrag.removeChild(newFrag.firstChild); //remove ) + newFrag.removeChild(newFrag.firstChild); //remove , + } + table.appendChild(createMmlNode("mtr",row)); + } + node = createMmlNode("mtable",table); + if (typeof symbol.invisible == "boolean" && symbol.invisible) node.setAttribute("columnalign","left"); + newFrag.replaceChild(node,newFrag.firstChild); + } + } + } + } + str = AMremoveCharsAndBlanks(str,symbol.input.length); + if (typeof symbol.invisible != "boolean" || !symbol.invisible) { + node = createMmlNode("mo",document.createTextNode(symbol.output)); + newFrag.appendChild(node); + } + } + return [newFrag,str]; +} + +function parseMath(str,latex) { + var frag, node; + AMnestingDepth = 0; + //some basic cleanup for dealing with stuff editors like TinyMCE adds + str = str.replace(/ /g,""); + str = str.replace(/>/g,">"); + str = str.replace(/</g,"<"); + str = str.replace(/(Sin|Cos|Tan|Arcsin|Arccos|Arctan|Sinh|Cosh|Tanh|Cot|Sec|Csc|Log|Ln|Abs)/g, function(v) { return v.toLowerCase(); }); + frag = AMparseExpr(str.replace(/^\s+/g,""),false)[0]; + node = createMmlNode("mstyle",frag); + if (mathcolor != "") node.setAttribute("mathcolor",mathcolor); + if (mathfontfamily != "") node.setAttribute("fontfamily",mathfontfamily); + if (displaystyle) node.setAttribute("displaystyle","true"); + node = createMmlNode("math",node); + if (showasciiformulaonhover) //fixed by djhsu so newline + node.setAttribute("title",str.replace(/\s+/g," "));//does not show in Gecko + return node; +} + +function strarr2docFrag(arr, linebreaks, latex) { + var newFrag=document.createDocumentFragment(); + var expr = false; + for (var i=0; i,\\|!:;'~]|\\.(?!(?:\x20|$))|"+ambigAMtoken+englishAMtoken+simpleAMtoken; + var re = new RegExp("(^|\\s)((("+token+")\\s?)(("+token+secondenglishAMtoken+")\\s?)+)([,.?]?(?=\\s|$))","g"); + str = str.replace(re," `$2`$7"); + var arr = str.split(AMdelimiter1); + var re1 = new RegExp("(^|\\s)([b-zB-HJ-Z+*<>]|"+texcommand+ambigAMtoken+simpleAMtoken+")(\\s|\\n|$)","g"); + var re2 = new RegExp("(^|\\s)([a-z]|"+texcommand+ambigAMtoken+simpleAMtoken+")([,.])","g"); // removed |\d+ for now + for (i=0; i1 || mtch) { + if (!noMathML) { + frg = strarr2docFrag(arr,n.nodeType==8,latex); + var len = frg.childNodes.length; + n.parentNode.replaceChild(frg,n); + return len-1; + } else return 0; + } + } + } else return 0; + } else if (n.nodeName!="math") { + for (i=0; i topOfWindow && + monitoredDOMElements[element].offset < bottomOfWindow) { + $(monitoredDOMElements[element].anchor).addClass("selected"); + $(".autotoc li").not(monitoredDOMElements[element].anchor).removeClass("selected"); + break; + } + } + }); + + + // Default settings + var settings = $.extend({ + toc: "#toc" + },options); + + var toc = $('
      '); + + $(settings.toc).append(toc); + + return this.each(function() { + tocEntry = $('
    • ' + $(this).html() + '
    • '); + tocEntry.data("parentHeading",this); + tocEntry.on("click", function() { + $('html, body').animate({ + scrollTop: $($(this).data("parentHeading")).offset().top - (windowHeight * .2) + }, 750 ); + }); + + $(".autotoc").append(tocEntry); + + monitoredDOMElements.push({ + offset: $(this).offset().top, + anchor: tocEntry + }); + }); + } +}); \ No newline at end of file diff --git a/docs/spec/00.00.00.title.md b/docs/spec/00.00.00.title.md new file mode 100644 index 0000000..fffa716 --- /dev/null +++ b/docs/spec/00.00.00.title.md @@ -0,0 +1,3 @@ + +# {{ page.title }} +{:.no_toc} diff --git a/docs/spec/00.00.01.version.md b/docs/spec/00.00.01.version.md new file mode 100644 index 0000000..1796d22 --- /dev/null +++ b/docs/spec/00.00.01.version.md @@ -0,0 +1,3 @@ + +_{{ page.version }}_ +_{{ page.version_date }}_ diff --git a/docs/spec/00.00.02.authors.md b/docs/spec/00.00.02.authors.md new file mode 100644 index 0000000..2cf7726 --- /dev/null +++ b/docs/spec/00.00.02.authors.md @@ -0,0 +1,4 @@ + +_Frank Galligan, Google +\[author] +\[author]_ diff --git a/docs/spec/00.00.03.last.modified.md b/docs/spec/00.00.03.last.modified.md new file mode 100644 index 0000000..092b08c --- /dev/null +++ b/docs/spec/00.00.03.last.modified.md @@ -0,0 +1,2 @@ + +_Last modified: {{ site.time }}_ diff --git a/docs/spec/00.00.04.abstract.md b/docs/spec/00.00.04.abstract.md new file mode 100644 index 0000000..2fc4a46 --- /dev/null +++ b/docs/spec/00.00.04.abstract.md @@ -0,0 +1,6 @@ + +## Abstract +{:.no_toc .nocount} + +This document defines the bitstream format and decoding process for the +Draco 3D Data Compression scheme. diff --git a/docs/spec/00.00.05.toc.md b/docs/spec/00.00.05.toc.md new file mode 100644 index 0000000..9ce6baf --- /dev/null +++ b/docs/spec/00.00.05.toc.md @@ -0,0 +1,5 @@ + +**Contents** + +* TOC +{:toc} diff --git a/docs/spec/01.00.00.scope.md b/docs/spec/01.00.00.scope.md new file mode 100644 index 0000000..d17eff9 --- /dev/null +++ b/docs/spec/01.00.00.scope.md @@ -0,0 +1,5 @@ + +## Scope + +This document specifies the open-source Draco #D Data Compression bitstream +format and decoding process. diff --git a/docs/spec/02.00.00.terms.md b/docs/spec/02.00.00.terms.md new file mode 100644 index 0000000..cfca0dd --- /dev/null +++ b/docs/spec/02.00.00.terms.md @@ -0,0 +1,8 @@ + +## Terms and Definitions + +For the purposes of this document, the following terms and definitions apply: + +| Term | Definition | +| ------- | ---------------- | +| | | diff --git a/docs/spec/03.00.00.symbols.md b/docs/spec/03.00.00.symbols.md new file mode 100644 index 0000000..58b42cf --- /dev/null +++ b/docs/spec/03.00.00.symbols.md @@ -0,0 +1,18 @@ + +## Symbols (and abbreviated terms) + +**DCT:** Discrete Cosine Transform + +FIXME + +The specification makes use of a number of constant integers. Constants that +relate to the semantics of a particular syntax element are defined in section +7. + +Additional constants are defined below: + + +| Symbol name | Value | Description | +| ------------------------ |:-----:| ----------- | +| `SYMBOL` | | + diff --git a/docs/spec/04.00.00.conventions.md b/docs/spec/04.00.00.conventions.md new file mode 100644 index 0000000..767de7c --- /dev/null +++ b/docs/spec/04.00.00.conventions.md @@ -0,0 +1,26 @@ +## Conventions + + * When bit reading is finished it will always pad the read to the current + byte. + + * Draco encoded mesh files are comprised of three main sections. This first + section is the header. The second section contains the connectivity data. + The third section contains the attribute data. The header must be decoded + first, then the connectivity section, and then the attribute section. + + * The Connectivity section is composed of the following sections in order: + + * Connectivity header + + * EdgeBreaker symbol buffer + + * Start face buffer + + * EdgeBreaker valence header + + * Context data for the valence prediction + + * Hole and Split data + + * The hole and split data must be decoded before the EdgeBreaker symbols are + decoded. diff --git a/docs/spec/draco.decoder.md b/docs/spec/draco.decoder.md new file mode 100644 index 0000000..99c8096 --- /dev/null +++ b/docs/spec/draco.decoder.md @@ -0,0 +1,45 @@ +## Draco Decoder + +### Decode() + +
      +Decode() { Type + DecodeHeader() + DecodeConnectivityData() + DecodeAttributeData()} + +
      + + +### DecodeHeader() + +
      +DecodeHeader() { Type + draco_string UI8[5] + major_version UI8 + minor_version UI8 + encoder_type UI8 + encoder_method UI8 + flags +} + +
      + + +### DecodeAttributeData() + +
      +DecodeAttributeData() { Type + num_attributes_decoders UI8 + for (i = 0; i < num_attributes_decoders; ++i) { + CreateAttributesDecoder(i); + } + for (auto &att_dec : attributes_decoders_) { + att_dec->Initialize(this, point_cloud_) + } + for (i = 0; i < num_attributes_decoders; ++i) { + attributes_decoders_[i]->DecodeAttributesDecoderData(buffer_) + } + DecodeAllAttributes() + OnAttributesDecoded() +
      diff --git a/docs/spec/edgebreaker.decoder.md b/docs/spec/edgebreaker.decoder.md new file mode 100644 index 0000000..495901e --- /dev/null +++ b/docs/spec/edgebreaker.decoder.md @@ -0,0 +1,1674 @@ +## EdgeBreaker Decoder + +### InitializeDecoder() + +
      +InitializeDecoder() { Type + edgebreaker_decoder_type UI8 +} + +
      + + +### DecodeConnectivity() + +
      +DecodeConnectivity() { Type + num_new_verts UI32 + num_encoded_vertices UI32 + num_faces UI32 + num_attribute_data I8 + num_encoded_symbols UI32 + num_encoded_split_symbols UI32 + encoded_connectivity_size UI32 + // file pointer must be set to current position + encoded_connectivity_size + hole_and_split_bytes = DecodeHoleAndTopologySplitEvents() + // file pointer must be set to old current position + EdgeBreakerTraversalValence_Start() + DecodeConnectivity(num_symbols) + if (attribute_data_.size() > 0) { + for (ci = 0; ci < corner_table_->num_corners(); ci += 3) { + DecodeAttributeConnectivitiesOnFace(ci) + } + } + for (i = 0; i < corner_table_->num_vertices(); ++i) { + if (is_vert_hole_[i]) { + corner_table_->UpdateVertexToCornerMap(i); + } + } + // Decode attribute connectivity. + for (uint32_t i = 0; i < attribute_data_.size(); ++i) { + attribute_data_[i].connectivity_data.InitEmpty(corner_table_.get()); + for (int32_t c : attribute_data_[i].attribute_seam_corners) { + attribute_data_[i].connectivity_data.AddSeamEdge(c); + } + attribute_data_[i].connectivity_data.RecomputeVertices(nullptr, nullptr); + } + // Preallocate vertex to value mapping + AssignPointsToCorners() +} + +
      + + +### AssignPointsToCorners() + +
      +AssignPointsToCorners() { Type + decoder_->mesh()->SetNumFaces(corner_table_->num_faces()); + if (attribute_data_.size() == 0) { + for (f = 0; f < decoder_->mesh()->num_faces(); ++f) { + for (c = 0; c < 3; ++c) { + vert_id = corner_table_->Vertex(3 * f + c); + if (point_id == -1) + point_id = num_points++; + face[c] = point_id; + } + decoder_->mesh()->SetFace(f, face); + } + decoder_->point_cloud()->set_num_points(num_points); + Return true; + } + for (v = 0; v < corner_table_->num_vertices(); ++v) { + c = corner_table_->LeftMostCorner(v); + if (c < 0) + continue; + deduplication_first_corner = c; + if (!is_vert_hole_[v]) { + for (uint32_t i = 0; i < attribute_data_.size(); ++i) { + if (!attribute_data_[i].connectivity_data.IsCornerOnSeam(c)) + continue; + vert_id = attribute_data_[i].connectivity_data.Vertex(c); + act_c = corner_table_->SwingRight(c); + seam_found = false; + while (act_c != c) { + if (attribute_data_[i].connectivity_data.Vertex(act_c) != vert_id) { + deduplication_first_corner = act_c; + seam_found = true; + break; + } + act_c = corner_table_->SwingRight(act_c); + } + if (seam_found) + break; + } + } + c = deduplication_first_corner; + corner_to_point_map[c] = point_to_corner_map.size(); + point_to_corner_map.push_back(c); + prev_c = c; + c = corner_table_->SwingRight(c); + while (c >= 0 && c != deduplication_first_corner) { + attribute_seam = false; + for (uint32_t i = 0; i < attribute_data_.size(); ++i) { + if (attribute_data_[i].connectivity_data.Vertex(c) != + attribute_data_[i].connectivity_data.Vertex(prev_c)) { + attribute_seam = true; + break; + } + } + if (attribute_seam) { + corner_to_point_map[c] = point_to_corner_map.size(); + point_to_corner_map.push_back(c); + } else { + corner_to_point_map[c] = corner_to_point_map[prev_c]; + } + prev_c = c; + c = corner_table_->SwingRight(c); + } + } + for (f = 0; f < decoder_->mesh()->num_faces(); ++f) { + for (c = 0; c < 3; ++c) { + face[c] = corner_to_point_map[3 * f + c]; + } + decoder_->mesh()->SetFace(f, face); + } + decoder_->point_cloud()->set_num_points(point_to_corner_map.size()); +} + +
      + + +### DecodeConnectivity() + +
      +DecodeConnectivity(num_symbols) { Type + for (i = 0; i < num_symbols; ++i) { + symbol = TraversalValence_DecodeSymbol() + corner = 3 * num_faces++ + if (symbol == TOPOLOGY_C) { + vertex_x = UpdateCornerTableForSymbolC() + is_vert_hole_[vertex_x] = false; + } else if (symbol == TOPOLOGY_R || symbol == TOPOLOGY_L) { + UpdateCornerTableForSymbolLR() + check_topology_split = true; + } else if (symbol == TOPOLOGY_S) { + HandleSymbolS() + } else if (symbol == TOPOLOGY_E) { + UpdateCornerTableForSymbolE() + check_topology_split = true; + } + active_corner_stack.back() = corner; + traversal_decoder_.NewActiveCornerReached(corner); + if (check_topology_split) { + encoder_symbol_id = num_symbols - symbol_id - 1; + while (true) { + split = IsTopologySplit(encoder_symbol_id, &split_edge, + &encoder_split_symbol_id); + if (!split) { + break; + } + act_top_corner = corner; + if (split_edge == RIGHT_FACE_EDGE) { + new_active_corner = corner_table_->Next(act_top_corner); + } else { + new_active_corner = corner_table_->Previous(act_top_corner); + } + decoder_split_symbol_id = num_symbols - encoder_split_symbol_id - 1; + topology_split_active_corners[decoder_split_symbol_id] = + new_active_corner; + } + } + } + while (active_corner_stack.size() > 0) { + corner = active_corner_stack.pop_back(); + interior_face = traversal_decoder_.DecodeStartFaceConfiguration(); + if (interior_face == true) { + UpdateCornerTableForInteriorFace() + for (ci = 0; ci < 3; ++ci) { + is_vert_hole_[corner_table_->Vertex(new_corner + ci)] = false; + } + init_face_configurations_.push_back(true); + init_corners_.push_back(new_corner); + } else { + init_face_configurations_.push_back(false); + init_corners_.push_back(corner); + } + } + Return num_vertices; +} + +
      + + +### UpdateCornerTableForSymbolC() + +
      +UpdateCornerTableForSymbolC(corner) { Type + corner_a = active_corner_stack.back(); + corner_b = corner_table_->Previous(corner_a); + while (corner_table_->Opposite(corner_b) >= 0) { + corner_b = corner_table_->Previous(corner_table_->Opposite(corner_b)); + } + SetOppositeCorners(corner_a, corner + 1); + SetOppositeCorners(corner_b, corner + 2); + vertex_x = corner_table_->Vertex(corner_table_->Next(corner_a)); + corner_table_->MapCornerToVertex(corner, vertex_x); + corner_table_->MapCornerToVertex( + corner + 1, corner_table_->Vertex(corner_table_->Next(corner_b))); + corner_table_->MapCornerToVertex( + corner + 2, corner_table_->Vertex(corner_table_->Previous(corner_a))); + return vertex_x; +} + +
      + + + +### UpdateCornerTableForSymbolLR() + +
      +UpdateCornerTableForSymbolLR(corner, symbol) { Type + if (symbol == TOPOLOGY_R) { + opp_corner = corner + 2; + } else { + opp_corner = corner + 1; + } + SetOppositeCorners(opp_corner, corner_a); + corner_table_->MapCornerToVertex(opp_corner,num_vertices++); + corner_table_->MapCornerToVertex( + corner_table_->Next(opp_corner), + corner_table_->Vertex(corner_table_->Previous(corner_a))); + corner_table_->MapCornerToVertex( + corner_table_->Previous(opp_corner), + corner_table_->Vertex(corner_table_->Next(corner_a))); +} + +
      + + +### HandleSymbolS() + +
      +HandleSymbolS(corner) { Type + corner_b = active_corner_stack.pop_back(); + it = topology_split_active_corners.find(symbol_id); + if (it != topology_split_active_corners.end()) { + active_corner_stack.push_back(it->second); + } + corner_a = active_corner_stack.back(); + SetOppositeCorners(corner_a, corner + 2); + SetOppositeCorners(corner_b, corner + 1); + vertex_p = corner_table_->Vertex(corner_table_->Previous(corner_a)); + corner_table_->MapCornerToVertex(corner, vertex_p); + corner_table_->MapCornerToVertex( + corner + 1, corner_table_->Vertex(corner_table_->Next(corner_a))); + corner_table_->MapCornerToVertex(corner + 2, + corner_table_->Vertex(corner_table_->Previous(corner_b))); + corner_n = corner_table_->Next(corner_b); + vertex_n = corner_table_->Vertex(corner_n); + traversal_decoder_.MergeVertices(vertex_p, vertex_n); + // TraversalValence_MergeVertices + while (corner_n >= 0) { + corner_table_->MapCornerToVertex(corner_n, vertex_p); + corner_n = corner_table_->SwingLeft(corner_n); + } + corner_table_->MakeVertexIsolated(vertex_n); +} + +
      + + +### UpdateCornerTableForSymbolE() + +
      +UpdateCornerTableForSymbolE() { Type + corner_table_->MapCornerToVertex(corner, num_vertices++); + corner_table_->MapCornerToVertex(corner + 1, num_vertices++); + corner_table_->MapCornerToVertex(corner + 2, num_vertices++); +} + +
      + + +### UpdateCornerTableForInteriorFace() + +
      +UpdateCornerTableForInteriorFace() { Type + corner_b = corner_table_->Previous(corner); + while (corner_table_->Opposite(corner_b) >= 0) { + corner_b = corner_table_->Previous(corner_table_->Opposite(corner_b)); + } + corner_c = corner_table_->Next(corner); + while (corner_table_->Opposite(corner_c) >= 0) { + corner_c = corner_table_->Next(corner_table_->Opposite(corner_c)); + } + face(num_faces++); + corner_table_->MapCornerToVertex( + new_corner, corner_table_->Vertex(corner_table_->Next(corner_b))); + corner_table_->MapCornerToVertex( + new_corner + 1, corner_table_->Vertex(corner_table_->Next(corner_c))); + corner_table_->MapCornerToVertex( + new_corner + 2, corner_table_->Vertex(corner_table_->Next(corner))); +} + +
      + + +### IsTopologySplit() + +
      +IsTopologySplit(encoder_symbol_id, *out_face_edge, Type + + *out_encoder_split_symbol_id) { + if (topology_split_data_.size() == 0) + return false; + if (topology_split_data_.back().source_symbol_id != encoder_symbol_id) + return false; + *out_face_edge = topology_split_data_.back().source_edge; + *out_encoder_split_symbol_id = + topology_split_data_.back().split_symbol_id; + topology_split_data_.pop_back(); + return true; +} + +
      + + +### DecodeAttributeConnectivitiesOnFace() + +
      +DecodeAttributeConnectivitiesOnFace(corner) { Type + corners[3] = {corner, corner_table_->Next(corner), + corner_table_->Previous(corner)} + for (c = 0; c < 3; ++c) { + opp_corner = corner_table_->Opposite(corners[c]); + if (opp_corner < 0) { + for (uint32_t i = 0; i < attribute_data_.size(); ++i) { + attribute_data_[i].attribute_seam_corners.push_back(corners[c]); + } + continue + } + for (uint32_t i = 0; i < attribute_data_.size(); ++i) { + bool is_seam = traversal_decoder_.DecodeAttributeSeam(i); + if (is_seam) { + attribute_data_[i].attribute_seam_corners.push_back(corners[c]); + } + } + } +} + +
      + + +### SetOppositeCorners() + +
      +SetOppositeCorners(corner_0, corner_1) { Type + corner_table_->SetOppositeCorner(corner_0, corner_1); + corner_table_->SetOppositeCorner(corner_1, corner_0); +} + +
      + + +## EdgeBreaker Hole and Topology Split Events + +### DecodeHoleAndTopologySplitEvents() + +FIXME: Escaping angle brackets + +
      +DecodeHoleAndTopologySplitEvents() { Type + num_topologoy_splits UI32 + source_symbol_id = 0 + for (i = 0; i < num_topologoy_splits; ++i) { + DecodeVarint\(&delta) + split_data[i].source_symbol_id = delta + source_symbol_id + DecodeVarint\(&delta) + split_data[i].split_symbol_id = source_symbol_id - delta + } + for (i = 0; i < num_topologoy_splits; ++i) { + split_data[i].split_edge bits1 + split_data[i].source_edge bits1 + } + num_hole_events UI32 + symbol_id = 0 + for (i = 0; i < num_hole_events; ++i) { + DecodeVarint\(&delta) + hole_data[i].symbol_id = delta + symbol_id + } + return bytes_decoded; +} + +
      + +### CreateAttributesDecoder + +FIXME: Escaping angle brackets + +
      +CreateAttributesDecoder() { Type + att_data_id I8 + decoder_type UI8 + if (att_data_id >= 0) { + attribute_data_[att_data_id].decoder_id = att_decoder_id; + } + traversal_method_encoded UI8 + if (decoder_type == MESH_VERTEX_ATTRIBUTE) { + if (att_data_id < 0) { + encoding_data = &pos_encoding_data_; + } else { + encoding_data = &attribute_data_[att_data_id].encoding_data; + attribute_data_[att_data_id].is_connectivity_used = false; + } + if (traversal_method == MESH_TRAVERSAL_DEPTH_FIRST) { + typedef EdgeBreakerTraverser\ AttTraverser; + sequencer = CreateVertexTraversalSequencer\(encoding_data); + } else if (traversal_method == MESH_TRAVERSAL_PREDICTION_DEGREE) { + typedef PredictionDegreeTraverser\ AttTraverser; + sequencer = CreateVertexTraversalSequencer\(encoding_data); + } + } else { + // TODO + } + att_controller(new SequentialAttributeDecodersController(std::move(sequencer))) + decoder_->SetAttributesDecoder(att_decoder_id, std::move(att_controller)); +} + +
      + + +## Edgebreaker Traversal Decoder + +### EdgebreakerTraversal_Start() + +
      +EdgebreakerTraversal_Start() { Type + size UI64 + symbol_buffer_ size * UI8 + size UI64 + start_face_buffer_ size * UI8 + if (num_attribute_data_ > 0) { + attribute_connectivity_decoders_ = std::unique_ptr( + new BinaryDecoder[num_attribute_data_]); + for (i = 0; i < num_attribute_data_; ++i) { + attribute_connectivity_decoders_[i].StartDecoding() + // RansBitDecoder_StartDecoding + } +} + +
      + + +### Traversal_DecodeSymbol() + +~~~~~ +Traversal_DecodeSymbol() { + symbol_buffer_.DecodeLeastSignificantBits32(1, &symbol); bits1 + if (symbol != TOPOLOGY_C) { + symbol_buffer_.DecodeLeastSignificantBits32(2, &symbol_suffix); bits2 + symbol |= (symbol_suffix << 1); + } + return symbol +} +~~~~~ + + +### DecodeAttributeSeam() + +~~~~~ +DecodeAttributeSeam(int attribute) { + return attribute_connectivity_decoders_[attribute].DecodeNextBit(); +} +~~~~~ + + +## EdgeBreaker Traversal Valence Decoder + +### EdgeBreakerTraversalValence_Start() + +~~~~~ +EdgeBreakerTraversalValence_Start(num_vertices, num_attribute_data) { + out_buffer = EdgebreakerTraversal_Start() + num_split_symbols I32 + mode == 0 I8 + num_vertices_ += num_split_symbols + vertex_valences_ init to 0 + vertex_valences_.resize(num_vertices_, 0); + min_valence_ = 2; + max_valence_ = 7; + num_unique_valences = 6 (max_valence_ - min_valence_ + 1) + for (i = 0; i < num_unique_valences; ++i) { + DecodeVarint(&num_symbols, out_buffer) + If (num_symbols > 0) { + DecodeSymbols(num_symbols, out_buffer, &context_symbols_[i]) + } + context_counters_[i] = num_symbols + } + return out_buffer; +} +~~~~~ + + + +### TraversalValence_DecodeSymbol() + +~~~~~ +TraversalValence_DecodeSymbol() { + if (active_context_ != -1) { + symbol_id = context_symbols_[active_context_] + [--context_counters_[active_context_]] + last_symbol_ = edge_breaker_symbol_to_topology_id[symbol_id] + } else { + last_symbol_ = Traversal_DecodeSymbol() + } + return last_symbol_ +} +~~~~~ + + + +### TraversalValence_NewActiveCornerReached() + +~~~~~ +TraversalValence_NewActiveCornerReached(corner) { + switch (last_symbol_) { + case TOPOLOGY_C: + case TOPOLOGY_S: + vertex_valences_[ct(next)] += 1; + vertex_valences_[ct(prev)] += 1; + break; + case TOPOLOGY_R: + vertex_valences_[corner] += 1; + vertex_valences_[ct(next)] += 1; + vertex_valences_[ct(prev)] += 2; + break; + case TOPOLOGY_L: + vertex_valences_[corner] += 1; + vertex_valences_[ct(next)] += 2; + vertex_valences_[ct(prev)] += 1; + break; + case TOPOLOGY_E: + vertex_valences_[corner] += 2; + vertex_valences_[ct(next)] += 2; + vertex_valences_[ct(prev)] += 2; + break; + } + valence = vertex_valences_[ct(next)] + valence = max(valence, min_valence_) + valence = min(valence, max_valence_) + active_context_ = (valence - min_valence_); +} +~~~~~ + + + +### TraversalValence_MergeVertices() + +~~~~~ +TraversalValence_MergeVertices(dest, source) { + vertex_valences_[dest] += vertex_valences_[source]; +} +~~~~~ + + +## Attributes Decoder + +### DecodeAttributesDecoderData() + +~~~~~ +DecodeAttributesDecoderData(buffer) { + num_attributes I32 + point_attribute_ids_.resize(num_attributes); + for (i = 0; i < num_attributes; ++i) { + att_type UI8 + data_type UI8 + components_count UI8 + normalized UI8 + custom_id UI16 + Initialize GeometryAttribute ga + att_id = pc->AddAttribute(new PointAttribute(ga)); + point_attribute_ids_[i] = att_id; +} +~~~~~ + + + +## Sequential Attributes Decoders Controller + +### DecodeAttributesDecoderData() + +~~~~~ +DecodeAttributesDecoderData(buffer) { + AttributesDecoder_DecodeAttributesDecoderData(buffer) + sequential_decoders_.resize(num_attributes()); + for (i = 0; i < num_attributes(); ++i) { + decoder_type UI8 + sequential_decoders_[i] = CreateSequentialDecoder(decoder_type); + sequential_decoders_[i]->Initialize(decoder(), GetAttributeId(i)) +} +~~~~~ + + +### DecodeAttributes() + +~~~~~ +DecodeAttributes(buffer) { + sequencer_->GenerateSequence(&point_ids_) + for (i = 0; i < num_attributes(); ++i) { + pa = decoder()->point_cloud()->attribute(GetAttributeId(i)); + sequencer_->UpdatePointToAttributeIndexMapping(pa) + } + for (i = 0; i < num_attributes(); ++i) { + sequential_decoders_[i]->Decode(point_ids_, buffer) + //SequentialAttributeDecoder_Decode() + } +} +~~~~~ + + + +### CreateSequentialDecoder() + +~~~~~ +CreateSequentialDecoder(type) { + switch (type) { + case SEQUENTIAL_ATTRIBUTE_ENCODER_GENERIC: + return new SequentialAttributeDecoder() + case SEQUENTIAL_ATTRIBUTE_ENCODER_INTEGER: + return new SequentialIntegerAttributeDecoder() + case SEQUENTIAL_ATTRIBUTE_ENCODER_QUANTIZATION: + return new SequentialQuantizationAttributeDecoder() + case SEQUENTIAL_ATTRIBUTE_ENCODER_NORMALS: + return new SequentialNormalAttributeDecoder() + } +} +~~~~~ + + +## Sequential Attribute Decoder + +~~~~~ +Initialize(...) { + // Init some members +} +~~~~~ + + +### DecodeValues() + +~~~~~ +DecodeValues(const std::vector &point_ids) { + num_values = point_ids.size(); + entry_size = attribute_->byte_stride(); + std::unique_ptr value_data_ptr(new uint8_t[entry_size]); + out_byte_pos = 0; + for (i = 0; i < num_values; ++i) { + value_data UI8 * entry_size + attribute_->buffer()->Write(out_byte_pos, value_data, entry_size); + out_byte_pos += entry_size; + } +} +~~~~~ + + +## Sequential Integer Attribute Decoder + +~~~~~ +Initialize(...) { + SequentialAttributeDecoder_Initialize() +} +~~~~~ + + +### DecodeValues() + +~~~~~ +DecodeValues(point_ids) { + prediction_scheme_method I8 + if (prediction_scheme_method != PREDICTION_NONE) { + prediction_transform_type I8 + prediction_scheme_ = CreateIntPredictionScheme(...) + } + if (prediction_scheme_) { + } + DecodeIntegerValues(point_ids) + //SequentialQuantizationAttributeDecoder_DecodeIntegerValues() + //StoreValues() + DequantizeValues(num_values) +} +~~~~~ + + +### DecodeIntegerValues() + +~~~~~ +DecodeIntegerValues(point_ids) { + compressed UI8 + if (compressed) { + DecodeSymbols(..., values_.data()) + } else { + // TODO + } + if (!prediction_scheme_->AreCorrectionsPositive()) { + ConvertSymbolsToSignedInts(...) + } + if (prediction_scheme_) { + prediction_scheme_->DecodePredictionData(buffer) + // DecodeTransformData(buffer) + if (!values_.empty()) { + prediction_scheme_->Decode(values_.data(), &values_[0], + values_.size(), num_components, point_ids.data()) + // MeshPredictionSchemeParallelogram_Decode() +} +~~~~~ + + + +## Sequential Quantization Attribute Decoder + +~~~~~ +Initialize(...) { + SequentialIntegerAttributeDecoder_Initialize() +} +~~~~~ + + +### DecodeIntegerValues() + +~~~~~ +DecodeIntegerValues(point_ids) { + // DecodeQuantizedDataInfo() + num_components = attribute()->components_count(); + for (i = 0; i < num_components; ++i) { + min_value_[i] F32 + } + max_value_dif_ F32 + quantization_bits_ UI8 + SequentialIntegerAttributeDecoder::DecodeIntegerValues() +} +~~~~~ + + +### DequantizeValues() + +~~~~~ +DequantizeValues(num_values) { + max_quantized_value = (1 << (quantization_bits_)) - 1; + num_components = attribute()->components_count(); + entry_size = sizeof(float) * num_components; + quant_val_id = 0; + out_byte_pos = 0; + for (i = 0; i < num_values; ++i) { + for (c = 0; c < num_components; ++c) { + value = dequantizer.DequantizeFloat(values()->at(quant_val_id++)); + value = value + min_value_[c]; + att_val[c] = value; + } + attribute()->buffer()->Write(out_byte_pos, att_val.get(), entry_size); + out_byte_pos += entry_size; + } +} +~~~~~ + + + +## Prediction Scheme Transform + +### ComputeOriginalValue() + +~~~~~ +ComputeOriginalValue(const DataTypeT *predicted_vals, + const CorrTypeT *corr_vals, + DataTypeT *out_original_vals, int val_id) { + for (i = 0; i < num_components_; ++i) { + out_original_vals[i] = predicted_vals[i] + corr_vals[val_id + i]; + } +} +~~~~~ + + + +## Prediction Scheme Wrap Transform + +### DecodeTransformData() + +~~~~~ +DecodeTransformData(buffer) { + min_value_ DT + max_value_ DT +} +~~~~~ + + +### ComputeOriginalValue() + +~~~~~ +ComputeOriginalValue(const DataTypeT *predicted_vals, + const CorrTypeT *corr_vals, + DataTypeT *out_original_vals, int val_id) { + clamped_vals = ClampPredictedValue(predicted_vals); + ComputeOriginalValue(clamped_vals, corr_vals, out_original_vals, val_id) + // PredictionSchemeTransform_ComputeOriginalValue() + for (i = 0; i < this->num_components(); ++i) { + if (out_original_vals[i] > max_value_) { + out_original_vals[i] -= max_dif_; + } else if (out_original_vals[i] < min_value_) { + out_original_vals[i] += max_dif_; + } +} +~~~~~ + + +### ClampPredictedValue() + +~~~~~ +ClampPredictedValue(const DataTypeT *predicted_val) { + for (i = 0; i < this->num_components(); ++i) { + clamped_value_[i] = min(predicted_val[i], max_value_) + clamped_value_[i] = max(predicted_val[i], min_value_) + } + return &clamped_value_[0]; +} +~~~~~ + + + +## Mesh Prediction Scheme Parallelogram + +### Decode() + +~~~~~ +Decode(...) { + this->transform().InitializeDecoding(num_components); + // restore the first value + this->transform().ComputeOriginalValue(pred_vals.get(), + in_corr, out_data, 0); + // PredictionSchemeWrapTransform_ComputeOriginalValue() + corner_map_size = this->mesh_data().data_to_corner_map()->size(); + for (p = 1; p < corner_map_size; ++p) { + corner_id = this->mesh_data().data_to_corner_map()->at(p); + dst_offset = p * num_components; + b= ComputeParallelogramPrediction(p, corner_id, table, + *vertex_to_data_map, out_data, + num_components, pred_vals.get()) + if (!b) { + src_offset = (p - 1) * num_components; + this->transform().ComputeOriginalValue(out_data + src_offset, in_corr, + out_data + dst_offset, dst_offset); + // PredictionSchemeWrapTransform_ComputeOriginalValue() + } else { + this->transform().ComputeOriginalValue(pred_vals.get(), in_corr, + out_data + dst_offset, dst_offset); + // PredictionSchemeWrapTransform_ComputeOriginalValue() + } + } +} +~~~~~ + + +MeshPredictionSchemeParallelogramShared + +### ComputeParallelogramPrediction() + +~~~~~ +ComputeParallelogramPrediction(...) { + oci = table->Opposite(ci); + vert_opp = vertex_to_data_map[table->Vertex(ci)]; + vert_next = vertex_to_data_map[table->Vertex(table->Next(ci))]; + vert_prev = vertex_to_data_map[table->Vertex(table->Previous(ci))]; + if (vert_opp < data_entry_id && vert_next < data_entry_id && + vert_prev < data_entry_id) { + v_opp_off = vert_opp * num_components; + v_next_off = vert_next * num_components; + v_prev_off = vert_prev * num_components; + for (c = 0; c < num_components; ++c) { + out_prediction[c] = (in_data[v_next_off + c] + in_data[v_prev_off + c]) - + in_data[v_opp_off + c]; + } + Return true; + } + return false; +} +~~~~~ + + + +## CornerTable Traversal Processor + + +### IsFaceVisited() + +~~~~~ +IsFaceVisited(corner_id) { + if (corner_id < 0) + return true + return is_face_visited_[corner_id / 3]; +} +~~~~~ + + +### MarkFaceVisited() + +~~~~~ +MarkFaceVisited(face_id) { + is_face_visited_[face_id] = true; +} +~~~~~ + + +### IsVertexVisited() + +~~~~~ +IsVertexVisited(vert_id) { + return is_vertex_visited_[vert_id]; +} +~~~~~ + + +### MarkVertexVisited() + +~~~~~ +MarkVertexVisited(vert_id) { + is_vertex_visited_[vert_id] = true; +} +~~~~~ + + +## Mesh Attribute Indices Encoding Observer + +### OnNewVertexVisited() + +~~~~~ +OnNewVertexVisited(vertex, corner) { + point_id = mesh_->face(corner / 3)[corner % 3]; + sequencer_->AddPointId(point_id); + // Keep track of visited corners. + encoding_data_->encoded_attribute_value_index_to_corner_map.push_back(corner); + encoding_data_ + ->vertex_to_encoded_attribute_value_index_map[vertex] = + encoding_data_->num_values; + encoding_data_->num_values++; +} +~~~~~ + + +## EdgeBreaker Traverser + +### TraverseFromCorner() + +~~~~~ +TraverseFromCorner(corner_id) { + if (processor_.IsFaceVisited(corner_id)) + return + corner_traversal_stack_.clear(); + corner_traversal_stack_.push_back(corner_id); + next_vert = corner_table_->Vertex(corner_table_->Next(corner_id)); + prev_vert = corner_table_->Vertex(corner_table_->Previous(corner_id)); + if (!processor_.IsVertexVisited(next_vert)) { + processor_.MarkVertexVisited(next_vert); + traversal_observer_.OnNewVertexVisited(next_vert, + corner_table_->Next(corner_id)); + } + if (!processor_.IsVertexVisited(prev_vert)) { + processor_.MarkVertexVisited(prev_vert); + traversal_observer_.OnNewVertexVisited(prev_vert, + corner_table_->Previous(corner_id)); + } + while (!corner_traversal_stack_.empty()) { + corner_id = corner_traversal_stack_.back(); + face_id =corner_id / 3; + if (processor_.IsFaceVisited(face_id)) { + corner_traversal_stack_.pop_back(); + continue + } + while(true) { + face_id = corner_id / 3; + processor_.MarkFaceVisited(face_id); + traversal_observer_.OnNewFaceVisited(face_id); + vert_id = corner_table_->Vertex(corner_id); + on_boundary = corner_table_->IsOnBoundary(vert_id); + if (!processor_.IsVertexVisited(vert_id)) { + processor_.MarkVertexVisited(vert_id); + traversal_observer_.OnNewVertexVisited(vert_id, corner_id); + if (!on_boundary) { + corner_id = corner_table_->GetRightCorner(corner_id); + continue; + } + } + // The current vertex has been already visited or it was on a boundary. + right_corner_id = corner_table_->GetRightCorner(corner_id); + left_corner_id = corner_table_->GetLeftCorner(corner_id); + right_face_id((right_corner_id < 0 ? -1 : right_corner_id / 3)); + left_face_id((left_corner_id < 0 ? -1 : left_corner_id / 3)); + if (processor_.IsFaceVisited(right_face_id)) { + if (processor_.IsFaceVisited(left_face_id)) { + corner_traversal_stack_.pop_back(); + break; // Break from while(true) loop + } else { + corner_id = left_corner_id; + } + } else { + if (processor_.IsFaceVisited(left_face_id)) { + corner_id = right_corner_id; + } else { + // Split the traversal. + corner_traversal_stack_.back() = left_corner_id; + corner_traversal_stack_.push_back(right_corner_id); + break; // Break from while(true) loop + } + } + } + } +} +~~~~~ + + +## Mesh Traversal Sequencer + +### GenerateSequenceInternal() + +~~~~~ +GenerateSequenceInternal() { + traverser_.OnTraversalStart(); + If (corner_order_) { + // TODO + } else { + int32_t num_faces = traverser_.corner_table()->num_faces(); + for (i = 0; i < num_faces; ++i) { + ProcessCorner(3 * i) + } + } + traverser_.OnTraversalEnd(); +} +~~~~~ + + +### ProcessCorner() + +~~~~~ +ProcessCorner(corner_id) { + traverser_.TraverseFromCorner(corner_id); +} +~~~~~ + + +### UpdatePointToAttributeIndexMapping() + +~~~~~ +UpdatePointToAttributeIndexMapping(PointAttribute *attribute) { + corner_table = traverser_.corner_table(); + attribute->SetExplicitMapping(mesh_->num_points()); + num_faces = mesh_->num_faces(); + num_points = mesh_->num_points(); + for (f = 0; f < num_faces; ++f) { + face = mesh_->face(f); + for (p = 0; p < 3; ++p) { + point_id = face[p]; + vert_id = corner_table->Vertex(3 * f + p); + att_entry_id( + encoding_data_ + ->vertex_to_encoded_attribute_value_index_map[vert_id]); + attribute->SetPointMapEntry(point_id, att_entry_id); + } + } +} +~~~~~ + + +PointsSequencer + +### AddPointId() + +~~~~~ +AddPointId(point_id) { + out_point_ids_->push_back(point_id); +} +~~~~~ + + + +## Corner Table + +### Opposite() + +~~~~~ +Opposite(corner) { + return opposite_corners_[corner]; +} +~~~~~ + + +### Next() + +~~~~~ +Next(corner) { + return LocalIndex(++corner) ? corner : corner - 3; +} +~~~~~ + + +### Previous() + +~~~~~ +Previous(corner) { + return LocalIndex(corner) ? corner - 1 : corner + 2; +} +~~~~~ + + +### Vertex() + +~~~~~ +Vertex(corner) { + faces_[Face(corner)][LocalIndex(corner)]; +} +~~~~~ + + +### Face() + +~~~~~ +Face(corner) { + return corner / 3; +} +~~~~~ + + +### LocalIndex() + +~~~~~ +LocalIndex(corner) { + return corner % 3; +} +~~~~~ + + +### num_vertices() + +~~~~~ +num_vertices() { + return vertex_corners_.size(); +} +~~~~~ + + +### num_corners() + +~~~~~ +num_corners() { + return faces_.size() * 3; +} +~~~~~ + + +### num_faces() + +~~~~~ +num_faces() { + return faces_.size(); +} +~~~~~ + + +### bool IsOnBoundary() + +~~~~~ +bool IsOnBoundary(vert) { + corner = LeftMostCorner(vert); + if (SwingLeft(corner) < 0) + return true; + return false; +} +~~~~~ + + + +### SwingRight() + +~~~~~ +SwingRight(corner) { + return Previous(Opposite(Previous(corner))); +} +~~~~~ + + +### SwingLeft() + +~~~~~ +SwingLeft(corner) { + return Next(Opposite(Next(corner))); +} +~~~~~ + + +### GetLeftCorner() + +~~~~~ +GetLeftCorner(corner_id) { + if (corner_id < 0) + return kInvalidCornerIndex; + return Opposite(Previous(corner_id)); +} +~~~~~ + + +### GetRightCorner() + +~~~~~ +GetRightCorner(corner_id) { + if (corner_id < 0) + return kInvalidCornerIndex; + return Opposite(Next(corner_id)); +} +~~~~~ + + +### SetOppositeCorner() + +~~~~~ +SetOppositeCorner(corner_id, pp_corner_id) { + opposite_corners_[corner_id] = opp_corner_id; +} +~~~~~ + + + +### MapCornerToVertex() + +~~~~~ +MapCornerToVertex(corner_id, vert_id) { + face = Face(corner_id); + faces_[face][LocalIndex(corner_id)] = vert_id; + if (vert_id >= 0) { + vertex_corners_[vert_id] = corner_id; + } +} +~~~~~ + + +### UpdateVertexToCornerMap() + +~~~~~ +UpdateVertexToCornerMap(vert) { + first_c = vertex_corners_[vert]; + if (first_c < 0) + return; + act_c = SwingLeft(first_c); + c = first_c; + while (act_c >= 0 && act_c != first_c) { + c = act_c; + act_c = SwingLeft(act_c); + } + if (act_c != first_c) { + vertex_corners_[vert] = c; + } +} +~~~~~ + + + +### LeftMostCorner() + +~~~~~ +LeftMostCorner(v) { + return vertex_corners_[v]; +} +~~~~~ + + +### MakeVertexIsolated() + +~~~~~ +MakeVertexIsolated(vert) { + vertex_corners_[vert] = kInvalidCornerIndex; +} +~~~~~ + + + +## Mesh Attribute Corner Table + +### bool IsCornerOnSeam() + +~~~~~ +bool IsCornerOnSeam(corner) { + return is_vertex_on_seam_[corner_table_->Vertex(corner)]; +} +~~~~~ + + +### AddSeamEdge() + +~~~~~ +AddSeamEdge(c) { + MarkSeam(c) + opp_corner = corner_table_->Opposite(c); + if (opp_corner >= 0) { + no_interior_seams_ = false; + MarkSeam(opp_corner) + } +} +~~~~~ + + +### MarkSeam() + +~~~~~ +MarkSeam(c) { + is_edge_on_seam_[c] = true; + is_vertex_on_seam_[corner_table_->Vertex(corner_table_->Next(c))] = true; + is_vertex_on_seam_[corner_table_->Vertex(corner_table_->Previous(c)) + ] = true; +} +~~~~~ + + +### RecomputeVertices() + +~~~~~ +RecomputeVertices() { + // in code RecomputeVerticesInternal(nullptr, nullptr) + num_new_vertices = 0; + for (v = 0; v < corner_table_->num_vertices(); ++v) { + c = corner_table_->LeftMostCorner(v); + if (c < 0) + continue; + first_vert_id(num_new_vertices++); + vertex_to_attribute_entry_id_map_.push_back(first_vert_id); + first_c = c; + if (is_vertex_on_seam_[v]) { + act_c = SwingLeft(first_c); + while (act_c >= 0) { + first_c = act_c; + act_c = SwingLeft(act_c); + } + } + corner_to_vertex_map_[first_c] =first_vert_id; + vertex_to_left_most_corner_map_.push_back(first_c); + act_c = corner_table_->SwingRight(first_c); + while (act_c >= 0 && act_c != first_c) { + if (is_edge_on_seam_[corner_table_->Next(act_c)]) { + // in code IsCornerOppositeToSeamEdge() + first_vert_id = AttributeValueIndex(num_new_vertices++); + vertex_to_attribute_entry_id_map_.push_back(first_vert_id); + vertex_to_left_most_corner_map_.push_back(act_c); + } + corner_to_vertex_map_[act_c] = first_vert_id; + act_c = corner_table_->SwingRight(act_c); + } + } +} +~~~~~ + + + + +## Symbol Decoding + +### DecodeSymbols() + +~~~~~ +DecodeSymbols(num_symbols, out_buffer, out_values) { + scheme UI8 + If (scheme == 0) { + DecodeTaggedSymbols<>(num_symbols, src_buffer, out_values) + } else if (scheme == 1) { + DecodeRawSymbols<>(num_symbols, src_buffer, out_values) + } +} +~~~~~ + + +### DecodeTaggedSymbols() + +~~~~~ +DecodeTaggedSymbols() { + FIXME +} +~~~~~ + + + +### DecodeRawSymbols() + +~~~~~ +DecodeRawSymbols() { + max_bit_length UI8 + DecodeRawSymbolsInternal(max_bit_length, out_values) + return symbols +} +~~~~~ + + + +### DecodeRawSymbolsInternal() + +~~~~~ +DecodeRawSymbolsInternal(max_bit_length, out_values) { + decoder = CreateRansSymbolDecoder(max_bit_length) + decoder.StartDecoding() + // RansSymbolDecoder_StartDecoding + for (i = 0; i < num_values; ++i) { + out_values[i] = decoder.DecodeSymbol() + // RansSymbolDecoder_DecodeSymbol + } +} +~~~~~ + + +### CreateRansSymbolDecoder() + +~~~~~ +CreateRansSymbolDecoder(max_bit_length) { + rans_precision_bits = (3 * max_bit_length) / 2; + rans_precision_bits = min(rans_precision_bits, 20) + rans_precision_bits = max(rans_precision_bits, 12) + rans_precision = 1 << rans_precision_bits_; + l_rans_base = rans_precision * 4; + num_symbols_ UI32 + for (i = 0; i < num_symbols_; ++i) { + prob_data UI8 + if ((prob_data & 3) == 3) { + offset = prob_data >> 2 + for (j = 0; j < offset + 1; ++j) { + probability_table_[i + j] = 0; + } + i += offset; + } else { + prob = prob_data >> 2 + for (j = 0; j < token; ++j) { + eb UI8 + prob = prob | (eb << (8 * (j + 1) - 2) + } + probability_table_[i] = prob; + } + } + rans_build_look_up_table() +} +~~~~~ + + +### RansSymbolDecoder_StartDecoding() + +~~~~~ +RansSymbolDecoder_StartDecoding() { + bytes_encoded UI64 + buffer bytes_encoded * UI8 + rans_read_init(buffer, bytes_encoded) +} +~~~~~ + + + +### RansSymbolDecoder_DecodeSymbol() + +~~~~~ +RansSymbolDecoder_DecodeSymbol() { + ans_.rans_read() +} +~~~~~ + + +## Rans Decoding + +### ans_read_init() + +~~~~~ +ans_read_init(struct AnsDecoder *const ans, const uint8_t *const buf, + int offset) { + x = buf[offset - 1] >> 6 + If (x == 0) { + ans->buf_offset = offset - 1; + ans->state = buf[offset - 1] & 0x3F; + } else if (x == 1) { + ans->buf_offset = offset - 2; + ans->state = mem_get_le16(buf + offset - 2) & 0x3FFF; + } else if (x == 2) { + ans->buf_offset = offset - 3; + ans->state = mem_get_le24(buf + offset - 3) & 0x3FFFFF; + } else if (x == 3) { + // x == 3 implies this byte is a superframe marker + return 1; + } + ans->state += l_base; +} +~~~~~ + + + +### int rabs_desc_read() + +~~~~~ +int rabs_desc_read(struct AnsDecoder *ans, AnsP8 p0) { + AnsP8 p = ans_p8_precision - p0; + if (ans->state < l_base) { + ans->state = ans->state * io_base + ans->buf[--ans->buf_offset]; + } + x = ans->state; + quot = x / ans_p8_precision; + rem = x % ans_p8_precision; + xn = quot * p; + val = rem < p; + if (val) { + ans->state = xn + rem; + } else { + ans->state = x - xn - p; + } + return val; +} +~~~~~ + + + +### rans_read_init() + +~~~~~ +rans_read_init(UI8 *buf, int offset) { + ans_.buf = buf; + x = buf[offset - 1] >> 6 + If (x == 0) { + ans_.buf_offset = offset - 1; + ans_.state = buf[offset - 1] & 0x3F; + } else if (x == 1) { + ans_.buf_offset = offset - 2; + ans_.state = mem_get_le16(buf + offset - 2) & 0x3FFF; + } else if (x == 2) { + ans_.buf_offset = offset - 3; + ans_.state = mem_get_le24(buf + offset - 3) & 0x3FFFFF; + } else if (x == 3) { + ans_.buf_offset = offset - 4; + ans_.state = mem_get_le32(buf + offset - 4) & 0x3FFFFFFF; + } + ans_.state += l_rans_base; +} +~~~~~ + + + + +### rans_build_look_up_table() + +~~~~~ +rans_build_look_up_table() { + cum_prob = 0 + act_prob = 0 + for (i = 0; i < num_symbols; ++i) { + probability_table_[i].prob = token_probs[i]; + probability_table_[i].cum_prob = cum_prob; + cum_prob += token_probs[i]; + for (j = act_prob; j < cum_prob; ++j) { + Lut_table_[j] = i + } + act_prob = cum_prob +} +~~~~~ + + + +### rans_read() + +~~~~~ +rans_read() { + while (ans_.state < l_rans_base) { + ans_.state = ans_.state * io_base + ans_.buf[--ans_.buf_offset]; + } + quo = ans_.state / rans_precision; + rem = ans_.state % rans_precision; + sym = fetch_sym() + ans_.state = quo * sym.prob + rem - sym.cum_prob; + return sym.val; +} +~~~~~ + + +### fetch_sym() + +~~~~~ +fetch_sym() { + symbol = lut_table[rem] + out->val = symbol + out->prob = probability_table_[symbol].prob; + out->cum_prob = probability_table_[symbol].cum_prob; +} +~~~~~ + + + +## Rans Bit Decoder + +### RansBitDecoder_StartDecoding() + +~~~~~ +RansBitDecoder_StartDecoding(DecoderBuffer *source_buffer) { + prob_zero_ UI8 + size UI32 + buffer_ size * UI8 + ans_read_init(&ans_decoder_, buffer_, size) +} +~~~~~ + + +### DecodeNextBit() + +~~~~~ +DecodeNextBit() { + uint8_t bit = rabs_desc_read(&ans_decoder_, prob_zero_); + return bit > 0; +} +~~~~~ + + +## Core Functions + +### DecodeVarint + +~~~~~ +DecodeVarint() { + If (std::is_unsigned::value) { + in UI8 + If (in & (1 << 7)) { + out = DecodeVarint() + out = (out << 7) | (in & ((1 << 7) - 1)) + } else { + typename std::make_unsigned::type UIT; + out = DecodeVarint() + out = ConvertSymbolToSignedInt(out) + } + return out; +} +~~~~~ + + + +### ConvertSymbolToSignedInt() + +~~~~~ +ConvertSymbolToSignedInt() { + abs_val = val >> 1 + If (val & 1 == 0) { + return abs_val + } else { + signed_val = -abs_val - 1 + } + return signed_val +} +~~~~~ + + + +Sequential Decoder + +### decode_connectivity() + +~~~~~ +decode_connectivity() { + num_faces I32 + num_points I32 + connectivity _method UI8 + If (connectivity _method == 0) { + // TODO + } else { + loop num_faces { + If (num_points < 256) { + face[] UI8 + } else if (num_points < (1 << 16)) { + face[] UI16 + } else { + face[] UI32 + } + } + } +} +~~~~~ diff --git a/docs/spec/index.md b/docs/spec/index.md new file mode 100644 index 0000000..b94da7f --- /dev/null +++ b/docs/spec/index.md @@ -0,0 +1,32 @@ +--- +layout: spec +title: Draco Bitstream Specification (Draft) +version: Version 1,2 +version_date: Released 2017-xx-xx +--- + +{% include_relative 00.00.00.title.md %} +{% include_relative 00.00.01.version.md %} +{% include_relative 00.00.02.authors.md %} +{% include_relative 00.00.03.last.modified.md %} +{% include_relative 00.00.04.abstract.md %} +{% include_relative 00.00.05.toc.md %} + +{% include_relative 01.00.00.scope.md %} + +{% include_relative 02.00.00.terms.md %} + +{% include_relative 03.00.00.symbols.md %} + +{% include_relative 04.00.00.conventions.md %} + +{% include_relative draco.decoder.md %} + +{% include_relative mesh.decoder.md %} + +{% include_relative edgebreaker.decoder.md %} + + +{% comment %} +{% include_relative 99.00.01.testing.md %} +{% endcomment %} diff --git a/docs/spec/mesh.decoder.md b/docs/spec/mesh.decoder.md new file mode 100644 index 0000000..c283bea --- /dev/null +++ b/docs/spec/mesh.decoder.md @@ -0,0 +1,11 @@ +## Mesh Decoder + +### DecodeConnectivityData() + +
      +DecodeConnectivityData() Type + InitializeDecoder() + DecodeConnectivity() +} + +