From d27e3b15a95ce0204854935ae85b6e95261acab7 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 23 Dec 2011 02:22:38 +0100 Subject: [PATCH] clarify the handling of specific output operation modes (e.g. number of channels) --- doc/devel/uml/fig151685.png | Bin 26732 -> 26030 bytes src/proc/play/output-slot.cpp | 26 ++++---- src/proc/play/output-slot.hpp | 62 +++++++++++++----- src/proc/play/play-service.cpp | 2 +- src/proc/play/render-configurator.cpp | 2 +- .../proc/play/diagnostic-output-slot.hpp | 29 ++++++-- uml/lumiera/151685.diagram | 38 +++++------ uml/lumiera/5.session | 4 +- uml/lumiera/lumiera.prj | 2 +- wiki/renderengine.html | 22 +++++-- 10 files changed, 126 insertions(+), 61 deletions(-) diff --git a/doc/devel/uml/fig151685.png b/doc/devel/uml/fig151685.png index a84679ddfc3db15f873cd102bc00ff9f97c7f5a9..77b41e4461a4ee43906885387f508dac49cac77f 100644 GIT binary patch literal 26030 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�-fon6zG88rnVjl+J&diJA3X`Yg;anK#PJf5d#zKQwCH-cJe=kW|#8qZUQ?;IJ_(ip8YwEpQ5`zpT zFYaSY@`9_4`-s(`kR!E>JA*D){YT&{UpJ^ShHjb>B-4n<{tohZig`+JLtr86#>zx; zMIyob{QF9zk8S~9P%O6&;$sMK&pO@;|J{Lbr`!8Hpo80*!I!+eb3(pceZK4hxc(g* zo9+{P;~M3JK@{%}-<6e1QIBL8b|>vWkV=yhxNPjzab)2WRQdwtasEJPa|x0DP|Uvm zom87a_1>-vum#$jnbB?}C6!1Zf^2a4XfxfuO0^Q6RVAa-WR{d1f3NKGa0*c>a4H!d zR-fL@T5mtG9}C}?5z6Cc6&jJPrIIu6{5bM4Oq? zcviKv$3BRgRv++gcmhL07)pkL;fAJ`mhbs7O8Kp_IJsvK(MNHg{i7ErNuZDXcz!xX zI@CcaP#-1qEGU}uZCH<1*ZUmS-g25CPLISDN6VxeFuKUdN{gn59p2v*GT%)FQ$Tey zJH(<-%ewBq0mvy8A*x%23hWC@OEn+WDttl0b8>T(cGKST&ZlyC@9duym35UhSv5D* zoup)B1mbW-`N|qPG|#;gcF7?%DdaXMbEF3c5ZZ+W@T{7>juBCl#M}Gw&eRb_5XB#GCzXQv6<6^SU}Gzsex<)_OZvUdb_W>}A#OqQa2ywB?nSDSkl-kjSDZPu9fDafpgAxpg(n1f;f&kGt$zg7F?=jW&1-R+DK z&XAD;d!FWEP{C8h!OtW%y=x-fC)}m~u>P6R#8hS5c5=~`eVfe9&T*k|foek8+u0xC zyKiO9TDBTHm46AC0zWosK?yIft)|Aqj!pKg32Jld*rpFYhAu3Oy0(3j=EA6X7rq_ac=KBnl;W?wyaqiATf2G)%HdhS|gxUsWYFKs&9SYNJP z?By0&A8!w7Sv}|%izXpWhsU3B-FkzrbGAG^M0rp8eJ0e3$SgEyNaTa}3kkE>ncfES zV!nG^MQ*ErZTk4WqnvC95llg4z?it2WNK0_9MS4Z4H z?9wf)%fY)n<5ch-C(|3A_J=+xwit!2(eO`CGnYs6>3|Q>&zU-hHJc6{mwG8{LYVP2 zBj)Clktub_vxBxjH{!75`=JHP%0uTrPFFn{^#e|z*tnvRLj9|Uw=Jf%vQ4!9;2j6j zS}cc0Jl|B0H=G}Q;nE5zs3}->w=8rFU~nBh;@hO9dCxCe*HBy>7Z6}jW;kV_58Xsp zzC)FgH{t!-jrLPE&7GEQAYiQr3m+- z5exEdEUE#81GHB9>t3JHjz17z7N++bdzQG<8Sf{2nJMD@#mFil!6(LNqjYX&xN57INMEe01b1?yW2Akmah2_5~8q7MIwVZ*ISG%q~-O$wo2l zS9`f6xpZ9BHyA!R6A94MAt)`UMy z>b?B7m5#@h>5q>Vxz4zAf>h!ot~C!s!-mH5zeGej<2Wly4JMyS8yZ%`t6(SX=`>a? zQT;D+l{Da9>*MU5QD63UR??H)hx+;i?ph`xD;!o|MddH`wmgXjLbU;rnUAv45wNu8 z?(E&p>@y{n0=f;KxXXgU^+bOCAcc9061#3$)F2=%>^_|Lla?!wNt^+@H(eL^!?5}*Nt=+kGi}f}K zFNhZvolu(fimIx?hO#$p`oK7=!QM#sNlO+5^QFTr6*kyH1$KGpxa9*o(4Ov3x&9V& zWf60jySC8S-JSo6#H4=vkoC0=wA zZry4Fl2N2YDT5dfFR!?RF}5od2%Ym$b63|liO5O;&g1RUSetx+sYBKHW z=h!GBQsc?*0^bl+oa|;khXxN%9ag3rEyX?F18Vn&;Laj3c_&tO$1*fhZ#;W$p3cJ^ z+t*XCB<*|V00&crD!{*igp?J#IRy{d#2ib4Mldd?B>|W4lfscTRr~qn z@xTx&Dm5`@gvVJ;yr(|$i-a$Zj-MM0%1L_dtYJ!$)ZWIFT1Z?10_ z*;&(%!|7CX>-MRYqO6jgBPN<*y*^g_y*^YV#U^BfHhpQ#PS{nD=gtN}i1BL;!*^T!v|e-#(&%mp(;4rG7&nTBQhKxn*1_e>vU# zO#EF8Vo(|wSJ7?n8|GIfyy_JoeuBKzlJeDd#Q#wTd4MZt-&IX*P@$V81=oW3@yTBp zIX2BY=~%!LO~@cT*VUlOR~G5lE;XPCEQ~?xEa@Wh62Q5BbQqMU>HQ=ZE`mYOeUM$9 zCB1-Be1= zj^6@we|76EJQ;4IH38@6y}VOX90;Y*5_Y@&lT^;XK#iLjLP~T(!fO2k78-0c#Vfe?>zs}N7 z8T>iuJf+j9>H4h;4#1KBMK%UJcKS8gM*kE_b1T`1yp72Oa-AfnI7&e)$GZL_2m71b zXkOsxxbr(q0K7n>7)0IX?nDnIAzOo<=V{VuNn%6Rx}{EJAF>DOD!o|~;~>>Ge6L#T z4h`d5n{C=tic!{+*fu%ysI*&I#rxb>*&exXn@)8?_3y>-f2wJBzo&cw zMA5lm3~sJ3FlN~<)9%!;q^+yRtEBINUp&VSk4f_QoEYr7uJZJNJ9$?q=I}Wlyc_$| zi`*E<|04MvH<-i6Sxe#62=`QMu54QD6#k=10QpW&-?RFCpKygQt?|ma@W?sgA!T|b z{X^r~m2~BVGabj1{9!6tN6`gAN+NCIu8wXACwxRmm3O7m4|z4$d=@YE245e6PZIJ6G$7Rlw7Wi|ZQ&wME@VX1{w| zhF^jbxm{?8h(fLqscGixxO~5zbt(hlvX%Zdw%vm2$X1MIK)rW~2ip*)+RH$o^%#S4IW(YhCGmt@y*=e?!< zqy*l$$-{`LY{#&)O+U1t*&Z+P>?AQc$WAm-f*rm0d?BS-qi)4rhhv zxbthL@~VSC6v=~V(>etMawT%Cv`2@r$pS;&BWJd(?~RsUJm34gJN*zB90&R%K2$VF zyArUut*_S1&g9Ii=xWVkInb8{A6q+&}3iu-=pg+fxpz|GKX`x z9@7$s^8-P!dRIYhFGteHQzbasER}0?YEe=Shb4)>uj+d8-R*F$Zn6_cnc^hM>2B?) zAp>u$I3Izl!>zYT4|@jsXGDFi!NHV~jbV8DSEi!hCaR@N6%)Z!ytf4jkRHZu8NBw&_5w{{?3HuR_HpB|lHC z){=*>^V9+vy-ufregzG1WvTkWVMOY358>9g^{aW7v)zTf$Gm;&B`K z4S^7;Ui?SEMZ_#%2!K*@abK)6Q@K>%L$q5jy1FdLYe8B5^lzcm*`@|&9C&30DlcW|%;P%wVD6S)3jq)6B3Y`_~|zG#b>sYT>5}iv4c2Fj2X76mVH(Y|L@7 zH&Rws%|*Z9tb&8noc?(N?>q&Qy#15Fl@%Q_Hr2bu>iGgqO{9X7p)WYvM9b{2fWZ$w zN%t0>`w?i%XLK)5#mLAc0B8fSYuA*L1&hC~(k-N~NtEdGa%O>bxf#bWRac42dETR_ zkX9&CkWx|MZMAB3?HXq!tCF}fMe@b^AQ)3yYdMfs1?<3Ju`HCp*4r{DHYX>Q1E$#H z=P+*yT!cshVZy=_(?0&Y1EZt6AtBC-i#{D4ZJa8GsyaID6ykExIP{MnzQcL9VXGtE z3a}OG>-^ucvH+`I3`s6*bF{NJklojNMn)b?^cVMqLufFoEPC9l;N=~#_lu0k0afOP zcfW(G59w~)nD9N6w{=ocXU; zU-{Z)1Hbx1C*wIaShA?l%?D1|y94Fr-2wujX2OT;#n7|*J{CQ>IoVWGvkzpu07Sp_ zJzpzBIxRVd7O3aDAjttiu)$J&E{s+^iY4;oc&TD<(H0;l9&WG1Scl)+zaw^c!?xc^ zmIl?-#Q*uDUZjO*6WkAwi%z3boob9`dK6O4S{WVQj9`^@sBA zTF#ZJA;l#;q4M0qRpplXXHG6I5&$vR*mT9*ASOOpFZ%~r78c$Ju>k6lprAG%{5g2P ztmS$&!~p6^)6o1`SXnW)p2W?yd)aTf+S;HuCY+29H%D;iz{$s~Q{z*LXLyKzKrR6R zArDWxbk6gwLG5iN7Kk6Q)o2)HC@5*@b}xY9j2bDaIt?Q8|n>ObHAAAk%*$EN?&vHy2N zxcnrMpc7e}MLodTgAAB{mWx~dD}MdwApBpW^WPhAtm~=f@L+B=1<*mra~Wmn(x2B!|q`N!b!tcHJ z_r3AQdtBM8gdWQ3g1nYS>~ z)o{e=5gN>e2*O&M9;*q$+MvlhdPLyF>Fmfj|Gs04X#bs+o$aFU^D&Eq4iQSv!x7Kr zCXaGG-JS32hL>uBo{>n{L(niS_Mm1=!uY zcLf9lGBPs8;07xW)lUQOX_Z+Fh7)sD*iIccT`nNmS5MD32lXd#G!GARJ$m$rnR&CQ za`t?)v_E)tqSPFpPT?LJ8WFFJrlH}Zn2F|QYDUJc{{B}d+cPZ7xM;{bbq9T?d%vlv zsIGTzuA_osRD&NL%X)cx3p`Zt@Tj?bTalo(p3ahr20^(vxK1p4Jc`oNT2-$zq-Z>L zfBA=ng-OxWc%ALPLBU8Uva_?Jiq8G^?e%1trCism#;Z0H{1Diyy1ll~l2MB*gcnD8#x;LTJ!ws&>O(BP2?x!7z^SA&x^G|bM-)K^z)^*zz)VRjxMP+Sa%zaNX{ zivrocT@k03x3@3O$)Us5($N_k8&e@Q8xj%}L^8jB{o37tH{uO82VqBqhX;2|PuJz= zhX%U|&kpA(hDa$YDpKMEyH?x(4pgGIv9s&z?k+7Y^)&R+`oIw+MI-38`z!s)Tdart z-`w_$CZ^b9sFK=eXH&bE@CIjUT?+~dLOLcU+;@Ndkp8nxOibAD>hwKXGB?B8Yr@Bk z4_`%q#2E$%V;Y ztLr1v(a{kL3(Hdp2}UNSm7c`mTGyS~de838e(qNtd>)6ZU@Ix%%qC8caDVgW4H!XM zxrBkrS97T%o_H_B#l>A*Dx#vILPA2avL16qX7Jc{PRHRtIRvW(c8b1jwbif%=5B8i z9|iyG^yY#QEUM_>R-=z`ae;w>oYdmAM46~+ZyVA4DxP2|RQiynznRds0 z6%*W6gCLn8wuP^ONprGID5~*3G!S2PK5T@;^Kf* z94`|Uf`0l#5_exyBSVmL5bHg#W|fE#!QB3@-JKU!w3tb&{)Raalz#`|T^n8q=SRJO z$R9@bv3e*F^gi%EzrFP##&M&UkC2$8VWxED%S0)ks>Xp%Put2^YwK2bSIuCX(c^~nVA{>(NX*4RDVy$X<{%ZS2Z&M9nX>SMP&Ihg>4}=1Ud1B`wvik{HXS-vA$<= za$&sK*>y)$x9)UKP3083 zed`%eYTUZ0SSf@cabocFpJ7q-73SsX)$)2>y1{eleSL5E6jSTYSJD*0uFJ??A*DtJ zMnK>*oCDw652eafD>yFEOx|e}>o&5dRnRrG6RmzVmq*B|8=rO)B}R_(LRz}D)cn$N z_<0oB1zV>e8gf$rM&;2eN1hJfE3w8Xw>qm%@9u62*DF&5$j?O_%6LXDoJ&QeqrUh!RD@K>cyTrxICN zrr}|@Trz*5>rU$OGA%4N{sa|Q#P^yImzZc3ckt@MS6%gTCg=5{R9tE4R+g;p?LfrM zX+lC;=xb$+y7(+x5o z8v?>Rg0-o!{hq|$?zpY}gNs~G*U#_Y7f)5P(NeL&pNNXSYH9P?_J)^* zxPV0&-RlY1XU}Bnov^NBk%8*%@rYfvhQ_sFvi&ta5Me()>eirtX&DcgCBRm3gq}JS2`Jf$9T;Tx9%w+fuMmG z1BkaN9sMcv*N!l-t%-3Q{K6ea+=4lRxXMoo4H8Gmz(4|@`hS(^Et5$wN+}Sa^aD!2 z0Zlh7u;!h}oxqhteoZ*y|JYdsWM+DT86Pdr#^!5d#OX7VyZYjDrq~sC9@*oSF3oOR{3(a>;dh!k&DMMXp1rG2AMeZmZ#JW1RKhYSow43J&!u;5HC z^&}e5$`O&^fakBCr>tNBfH8D&zpGVOw}K_DOx%L&S6XUox`c1$g@jMsk(l{*B(`%(@l)SP9-EX*S>-TjvW_gR_n_4QJ#a7lZZWir`|Iv zAu=4F&L=cpy!os;a86*eC>HV_x47#GTVo5cNX~HXw~LgxiNXN(^!dluIl38_Xgo;E^9> z+p^?f-j_VFJrfohnyr{N>wkm*DG8xbif`?mc?Ap^q{hUkI5;>25l&4{gQY%o>;yrN zB_M?L^?tFN=>~71pk`?~x!9Nnv))gjJPL(n>eqXu2)mb5SG#w-e*{z2))w?WcVc6M zgDgKh*FT}Vu(8oS|9WV6I3&1x$-~VJ_Uzf&*%^m>OK525o40S5RyzCo^s8P!I+&c9 zNeKouN?m<@jzWr{&*dpW)cDBA;>HFk35mz?=EU-{nf;5REF_2?_s)wqpKwE9ot>Qw z3=D#Tg2UPJ-5njPv-P#fhaARjU%q^~N5uYe{F@;t%qmMtNQB+kare$H7Z(?^vuUxh zqdGb|Krwf4b_r@35GLH*-N7~C;)by8YT-knl-(<%fZ3XqccHG zLPBC@YC6;4eQ~kVXi)1?l#{bk=YH^zj7&#%XB-0qO2+}Kg<6#Bc6=9FLJA9+_qP8GB8oO;`juPVdUFuh z+c(e4<1)BL*SXo*JNo(>JWsa$kx)f%E*&*A#&UD%`S>bFhi)q?W@cp-6)>hZGp=(0 zD5Qc1Us9r+uW4?+($&>L7&$r~fEq38p@5N%jWAfVZ{8pxAt6y&v5-OHAz)DknD?J@ znSUJ~8}mF|m6m7KKStdeRPZp5lM}xpvU^JA6T;SK5Ck7@P-Ea&JUEnH@GZce@?sz^PZZVZ2Pn6 zg9lqzH{IJSuW&wIY^<2fKUkzw2`1Iz^78T8uq3Y^8X6iHq~pCkFfWSB%3?_d2C&}V z!33dnetzD}%nTd`R_1$iT~@{oZUbz5e0%^MUHWl*Y!z5X>lTi+cPx($jjS?Lh`Mt-MNBXxCsFE1xk(~p%WC6|}p zmX=yM3RiWmJNtwL60o(k2|7jntK}r@gmOXOi>)M(@~uZ{$OQIX`&)M!<0U0`Iy%O4 zPpf}P$67&(naBgY7XAb1JUq@!>YI6adA2q-`32TC9E$e#)j2uTx5#5;j1TXHq2WX@ z?pIspFBqfiAldTZOIv)8knv*R{-q0v3mM{Msq?$-Hl;t|MaA-}bF+VG?aGWASbhNA`a{8tC*NLb3h*)9)5uKu1DS6eCo$rvJW5BX&)E$^v(V-bKR&b7krF_ zJ1RE9l%=F-~l{xx~xqqVaPk4?u!ehEYHBS?HEW2&UUa@;C; z-?>9O<&)qYiRL?)7UOHscZ~TPFOA`RDD!DBQt;0L4eOzHwdUd5x?(fqqQ(<}e@UIVQcXf8s z3b=nPiR@$k&EQjOH*?(@mh-+PGo>pZ;PEotR9M~vWW@PGt+c%}XYUJbPV6)S_**q) z<>Hq=)IstnFFz8yu9CJw>9hZR{kR-P7q7$Vx^1SY*dB^L`|j>jYU(Q!6&O|YNLR9Q zYpR&9UR`)jOpN>r%j8`MN8qJc6 zcqI12g*<5y{@2*O;pv>ETCiwG}EK0oiwekkS>06yvMfnUm* zlQx&6+}d!SuckHe`OBA&e@e)MLhHb{Pj607Kd1OgtD>YfB12Z_dPLe8RaMDn@;ko< z=6b?esu^fZbnW-NvFOYuO7wbrdzG19cd-si!;nxLBw#f)H4CI^s-bSCeeMSp>`aa_ z518_r3Ad0TKUP0Tg6ZDF@tfnV3z({w*3spe!G|O{xtg8nY8o!bsT3h>2gk51^tG{$Jl0afx6@@Y(2 zE)VWN-^bK7hQH|qbfreBzRXxqJ?5-Pxs!|t(Ie{-4fynkJmsmq*CImF^%V{BGXpii z7R_~QUe}4GGw}oexos%j1xH-mGk1_=+9DK!R_}o#!jR?IrQlRvTkjJUs5wy((Uf{H z;!D>T&dX95`JUyP6+zJAcWwnG$T2O(w^C(q@HD^LBFAbJ9TLYv#z}`Jgpvhkk6X5I ztTY^NQ7`Mgf#;0lDgG9Bpb-p2v;loa(Gq1-raO>0I9WGC0mDLoq-uM^BWQpTjS`9- zxc`W>JiQ*_&xau@Q|@OS0uMh?K;lQB^f`sI+J(LsPUcS)2WZ|30Rj2@&FVrnT4(dT zB@UGS92D1O;tcY*dXCJHAC^Cam~N^!ci(>*6;h&h!+ZRFZtvK#QUF1WsQ*Q(k@ffQP!oi4Ij__8O!dgIhP6t|*VFh6Msl8A)>Kt_ zYiaS(U~G2CbOQvf=K_P2?7>|Kjsti)oa6f_QzggeYhK<~t`YdOqL@5Lu+&tpCu4o7 zGn@`zbR-{OLFx1${E%&SM9a#{zj2-OuFc5UTOI7a<;dP)5ZY}F8Y@@Y&HDIIfT$>u z@p^3t&dhQJKzv|;Ej>ftx8lU?0-?4MCkf5*I~hu=OAnsG3e>kui}^ufxjdfQF*jZ6 zjBDmrkV~x_YHETjrZH&1XE!HHQ6byg@p*f-+wAV`U5`n+ytcl6z1w_7aIiVyXtdI2 zOv>BS-7$XpJ4&ECe&_mlN=2uV+-Il$dsEX+Q&U^gCl@gd7HUyZuMSg?w0UXm(&FaA!N$VxD3@L>B)^Iu+zNh?hr9DJU@U_UJOH!^ z#J*{CTyb!(vzoARcXth@=XVQFOf3Ej^4_^~4l4sWsXvwW`1q=7`oqcW)LuIU_NSzz zM5CFRt&m)EMSLBdf?8LK3U#a)QPVCo&kG+=p#$JlyI6-Hz5(j#bZRm|r{e1Bv!;Lz zW`dRdCE*Mux6{|zHoSb52(Z{>ula@6Ie>K+7mQBMH;!S4KQ-E~Pd`&JZ9JEdXk%-< zzq~?cGg0CPI7&|T0qV?)lbga^H|Cs&w0asE@$UYp;t1k&fGiT1Jf9Cb$j;upxil}$ z$av!I{d?+FqwlZp)y^BsQl??S39<36E6v!Ab`}=Uh_cffcg8X=8cleGx7S)8?^EZq_*E`IobMnjaO?qZvZ0p z_7WxHFtUH%*1yGc5HLNng7d=Ic(^BV<9VdltIhGOQZw)8ph`W-Rx}u1VAZwj1ixC0 zO-%CiYz-BGsj8`o7`Nr5C|N@T+*Vw7Bw~!v!F{ z2>jaUX0LN|U7w$yKj-CG{P{N%ynYn^+4{WFxV?SNYIoakzj7B-U z%z5Luy7{=q0qMqDBXR8*6%$TJ3L$a;U&CbWXVaNhyqNYJYfKi z`A=0u8^8MA=!;!B9W3|4qNU25)-(bFPS!U_lv5R4OVi`m+@7?!HwuSnNEe_%B`z)`LjKz+hj35~^tRGrzvKH}l)KJq!XH z9*#AA9i5xsQAt+T8-P(e*%%A!G`5p?ehK5&iX`*I;)AK%; zoA@@5n%5=!Knf;dcu?nVpsAzdbv!Z6W$u&6Znzpvopycto0f|4Hn^@)&yM}bxB+Nn z%03!FydYN|qeXV%;0(ZnqAWnET918QT3+sAcydgbZ)Ra<_Z1GmrK(AXe`;9!{unh1 z`|u(3(bI>)0BcP4^dtnMqszRSVZ^}HQ-s-6fSS18#K+qD;LRK5y{Y~Ec2F+jM1TH_ z8DsQn4qjGP(kgKW%PSz*$=NxvrehgELi10^4#X8OU?UdOH9L5=c%GC zIzK#aXlQtdMJFPX5)3$ZUVvWx{QL}?10N6&aJpxH{@flx%4gaY%VpljE~JnqI@8^4 z4P>8^2XVay+S-hX2FEyZn4dEgi9Do)E)phuzz#}XiyQ)V;cY^F@}GBvMHp@ zF>RV{porIzxaCs|zb@lP1O5`=KWS;Em=Ee^<~uJ-YuDD+ILXjqi-26}jM1PF{)Ia@ zoWmn6os%O^Di7nci$x1)T3%kRs}tMYEHuT4E{d{A^+&pxYw%7BW@IWzz{SR<5Vf?i zp`vnh#OIxo(v28Zcn@;oWZ7V;`70ds09x7^*KOSoiPc+uDX4%?!os@RnY&S`>)x6= z(bL_$UsVXDf8;Jjk)XkQOh=dV)ug5kO(L7hv7fEq7RwQ&h}(_YV8*+c6Si z;@vanBtA)wN5NTHT2dV~U0wMCjzQ23~&m zYdF~!F%sldNIqp?>}vFmCxps^%+rC76YXhfV`P~ zm~=We;8S5-(^bWlUklEghZT(h{(j;d=AW;@BT<>zSq?S1=gynu}Mif z)@uu7WDg&*8Z(uL;}Ev)^3`2e4;ADcN-7Ktt~@CeDE-+dVsUn${u%$-;Ci*{`ueO`_qAo|GV@e& zQU#s6#>OhMv(4Hg$%^h@R)RpYxoJZ|L4l8tFDu&(7|N*Cw|C_J=>;GMbc0|`VWHe5 zz8EFtuZ7kymIER3+^IiFJ>5#+Fiv=clCMq+WC}uYXiyz+NkAOUH~8}(1G_8YpbQf?2O{Bs&%#fB zQqrX75uxNfjFU}GuR7ibgL3C&Q{a)gyIgU_Vl+~L1)^U`ItEhuRZD?A3DGK-qTlXG zlwSGzO^8OO$NYW*Tj@Jm!w2$^5;*`7EGkYseUF~rk@-kjExh~&MaS0W{Blq7nQH9K zQn&l##}7ajY-#KJQ2H+01_f~N-$H4jT(sLS8ms@FE-`&#X}PpJk0EUo-2+r9HaLop z&#S;7MS3RB*x0iDfUK({jVo+1uggX0h?JS|{r%?bY#YM(Z{y=yAKVija|cLd1hrpw zNQq6Lvlm#jwIFkxnQ9D%M~O{F$Aj^71}w|~r$B*yUsB~W7aoN(UENJ5Cnsi>-h?4g zNJdBdE1illy_9CjV9@b@|K7f}^+X^!!L-|jhmX(r_7&;`xV@(^2xemUk#64_>Md()@${|N0f__CDzW^z@4>H|FW<`}+O* z>PA|&yNU4=l#V{~Yps;zI9NA1vg?C)EYEPy_rkWsk4HOS;X@cq@6&wg9xqXqhAv<1 z?5uxr{RC_=2Tc#W}km&7wwaupYrMZ+1 zicd&`#a1+5;zO!&jCXKGx=v^_Q3vj5ej$ZM-h|%4p*g4zSw$#&5|-xJg0s#fb`u%Z zk7`o^3>u=p+v?}W$48`5Z;{)=F(Aw-GyjQwN9HB94x+Hwh)1HkBK+UeT+hM|p-J(+ zm509{jST*7@8?e@0)VpKGajUTYLTl@aY}CXft_$;z=x&zeEI^1^ErH}t-Y`|@3*se zBpo0|MZ{5=AwUbPqSKssfUv5&pjplHC1RZm?rGrVE?<0m$_;4nh zP=uWC7a)qkbJE3BAG`{9GJXBNg_gQHA=v$g!fn7e(Uz^~b4^C;-4%-q&@os_`T42c z+3cS67u)7Alb7jf@viOTRiwBq`VYrTb3*F98-uXZa9#i~4g4aYq*6W9gtpR$j41)r zGgfB#S?tVYF7$yX$jabYL&NYw1BxH_Ojf?hi2 zI#&d!G^rPZB2-VjrEye9s6_%Q62W$BPZi~X_)cNVtn5cfzB;IGUb?zqt&wxwg3 zjWrx=&#^V?vb%1#G&Pm5H42xR$uHFIG}OPELkB9roR23X$KGKgS5jjAq${%@uX1`s zY^xE&WWWn0rS)}^=di%QJ1#EjfM(vQ=TqY)O*5!;Klo8>92EX=jkQ*d2CucHg^o7$ zYf+K!ky?T8jprU9WVyJiKTEbh6s@DBw}@5s5lEU0Ze1wUum9vuMo2i;Afe5s`*|{p zXVWQtrfe~0AQJv0VldAjJUy}|6NQS#WV*~Ux!#j2^Rp{(DP+m!NSnS-_M@r2_#dW; zv|x6{yC6G+)EJTE6cv4Jya_HVD+luBR7F-?tm^o<-0)8_V=KW&%rY|L(58yIvT8UWegL>vS*N~UBnQ+VzkXlwjSz20Ci21l&Umm$1G>q5qIG-PKC(u06IrrVWa04F(uialAYr~E2f?nMZ>G&=l zb)5)?mWM0G^YZio1%)Dhj2$?WnVHSR(~dqF?P99M0(c|}N^4eD(a*7V6MSfu$W7rM z^qFb9Q0($GE6>q~qN1Pi2CU&Bch8sNn+^||-l9qZ9BRY~c$iQ+N>B&IPg+@8x*VT%Z zaw^|S(SYLwVN=ARQ`S6pbaeFg_69+HDgi4!rEJkPmKml%iDFEt|Lfm%WqoDkg{>{% z_Zr#z-41ME-DIL(ryzU_i-_Rk;Q@3x>#hN-qQpT)MFkku{rd6@(O=xb6)-3!op=TY23SEc zsi_Ju00;m^1@1-gRnt`JJ_{ByK~j*I{TQEOz`9{nFTl_|d4dq%ox*FY{rvfz1AN`T z!8fVww126_3wYP(8*mVs<~w8PTwGkhaDvK_m6f%)xESWN&~lfIECqv*)oZVn5LC>M zsr<#iBU1s=!_?Fi6n@G_fcqQGeesz_MNUr6q}%YH*bHFm=;&xmOG|Zib)XGjU7gG& z(m&Y*jz}-j8{jzuSXf_Q-^a%Xn9{Vgw17?F`ubvL?5p0!+M2+tSz%xu932vx&j&`c zNl<5&0Ei3F$IpQQb}Fi-sVN=BogIvyBO_%%qy+%ySr~zIcF?%&2<9d2zrM18kXhYU;wwweiX-p#a zU(MKJPA)DDPHT8Evv313s{Fh>tzx49Re^tL+LwC3`xq32iYvg+&+d%FL{DGkyrFJk zL5~aI@8qO5Z<0I=oEY4{h{xe67~PcQotf{UDb(=)y_ahCRrk>rK_7lNGQm| zL-6MqpP;~m*Fi5QSqcG3$V&elfFcJVnm(pYHPgRGdhF}a^^kk@29ucceQ;YO*?uQo z#=hbszLVqm=6GJ41PwK{`q%TvZ&Agf(8X(QsW7+hSu2N*L9bRenU3(hTfTD3_C$dLYvXslE#j9mF49hWk3Y?)z(r(rZh^QP~(;R=d%>tSels)$_ z_4>_7IoKLbsn!qr8`+raGz{jdOr+m8-k`Bonru(^va-5>KU`+v(S_fX=#zz9xuP_# zF5R~#%jc;jYh=yzzkP4~hcT)rh89y+y4nvy)CRWSvb)2$lyoA@x0_t@pUA=g+Rxql zcN^yNGdnxhg9Wg*KLkjbje-f|sup~-GiM+i6cd~vkPKFYLzf{|J}?dQ91nMPh9ow3 z8WmUAOi)#K4h*~o^-#&mxVE65nXylFchsXu^7@{Yu@s?`6W=W0B+9#w zj`K}NYz?FmRO{pLyOg1!+h?aspc*W@uVBlPt#E-zITogQu5eP*RojkpfW0r08}+FCZDO<-?2}GmD$bs zC@MbAEa zF0j{rgZ2JAO@4Vf8=G7e%qMj<5jrYz`1#uKr_ptGw{K6u@Bp!VVnS$q({AMa;md!w zO;D;~f-(yf!3=#~7suX>eoL*nYPj#QhG-AmEL+-&=TfYlh_6B7d;NW_Lp&a(=YB zdRkHiVKKp%^z@;mQcv z`AaeZ8qcTv5n??*lF_1E!yKfo?7cMP2(c%?5k>ZEUC=L>nYoANGb*G7@IXf&#)nUn zBRNq5F^+#!2P*rd1Z_FB^<4@zlH;fH|2*pg0h*}>vbdU)IAjkztRr=ld3o}>b|FgR z!mnlt;f;2UFQ53iY2#)yB6MWzRhsa;X+-fW#6qJC4eQQYM(I?rt??4*2XlOHm0V5@ z5pwolMM!@}#vTELkoTJ-v{)-gz)RepTJN8@!5o+;1BzK35vVL1Nt@DS1w~rk7EniY zxWJ6`4`y;DP4ZW*KkS0kZ`SaI`qK>gYx|{`#&FECnReHPXBPp+?w0+RrI8CJ@X8o&ktarn!yA ziUzuO{W;}hXtLcS>q@;YbvRkc}roapad?D|G5s@^OmI*-e_-^CuQc+as z)fDc4(~g=DfW?T0fDG(R6MwT0fkJu?K3q}QR_%M^J2X@RoYk234riwC1P?DMYPB;v zDUs=MN2t^}<%|^4nf6M4z#itGQus6LWJT}hvnT0YGavT7wM?eW3NteV6f6xLJk!@q zBxHE3XsXd|@BW8`s1cqc1SRj)sX&728Z6C9J1j#2L3*7FBs5@36&kZR-3{O}^IBgM z5PS59n%SmV=M~HKX6Y4771TNWZY)*fVh=3VV*`h$Q2e4(L`uYD3*~}odxv_O> zDJDb#AeWv!Ng-awKi1LOs_>_aq~{+B6Tt3Y2nO()y=WkTGD9f@C>MT=io?>!gBRn) zbjCw3uyOYw8bFE>)r)p=|G$1$Ld`Yv|1%_WBpFe&^*`CnR=(l?TM__MTBvzGF@{2gegYc7r+%5Y@QRsj1t5 z;~pLw1?3y=;9oQ~&8?rAj~BfqN*MtCy3dTA>Ay*oHRy*nOk6RYixBGLF>{AXkCf`txKXo zCh9XZnL|TeYr|u1?$0>79nb@szJ0@tp@To8t4>9O@Jnqbz5=)FZQM)${Mp#T0{r_F*4nz1ni>f+v9*0+ zFee4umu$Sf6tq@tN=;^k6;&iioMoo!1=W3YU~C5>t&7VjFftV6r{d#+0_4yVv$L>< zp?aC1`A5dwQukR#MgtJ9fcQWO#4D9N33dc>)%S=9?@W4Xfwxy7_a1Z^AIGeiwGHST z35ii4JM|`V6@xATAPSfi(+hijP9&ZJ1Q9r@mZqCx{<}OC$rQn(QuxmPr%#h)LYX0; z%GJn1kJddN9v;4n;qZphVudgE7#T-1LPZo)i0osg{+N2b)s&rbfxScZW56@qS2Wn+ zl+k*RUts^{KIn>pl(+x|3rK$)+V5|b%enl-Pwx&)l+B~o*Ti^vkpF420VV|Q+WW{H z&;SXD1~*Sjf^@nKM;|~Pz@Y+(BLo*fM1VJiCeceL5L$L=Wc<{DpL%ca%&+%&Yj(zb zy6Ob*=z?qFfOylL7BwS#_lK*D*7bOS6)kn2tiHL&CbQvM)AJ&cm{?5qBkheQTN&tg z5q$vs5x}fvG4cPMwTvSJ)9rf4m*VX7w-)G$3J5R_3_MrP>J(E)O}hhGJOCYQn6=BF z+yoPQ#LNP|w6r`}xF1blnzwfO1_c3_)Bxs;p~LpQIwS{q84zW8r4g=6}eK@R9 z!XPidLdcpt^f}1>WcxXI%AoZD<;{U?T%EC@VRlZAkY@#aaZ>8yq#bV%G(Ai@6sqL# z;(+En<4B5|%eCPcxyO%XYu)UpnBa$_K%L@P69wN8f35FeZMpU&FH|~}8Mo+Ka*CDA z2}RdR2^W||EGDilqCz@4JD+pf_ow0uxsp$PGt__H)<)smqt)QW7t?3v+TA(Px-u3r z_AFLzqI9K2!+`8+yEf{pZph7cEf*lEd@i=~igd6WPxN0J&bt~K{{Hvwn%QGxcTZ1+ zzxUIa#5u8^K@~zIuCAX8D8mIlCcx9U!cnib^Z|$5dTAX5C0(I$%9)Z z#1vjP6c!Am>z$<~W`&;a+NZD|Ka4^D91uGeSLO_da^#2&U(NLo4TWnVNizmaY|OZd zQBxryT>*lz2N5-l5cPP|5(w-&^UZXy5x|N9&S$0;d&-AdL}Ui=ZBZ0rLcZ7Mz!zXM z^9lIiiL9+L>@9(<#B*m0n4wU61mA--XYX1`_^RIh;Hzq@;K`?^Zd@_8NjW|6C|^CR4zfp?3G7?F|i>Dm*EMJYbo(yw1x4FCU(E-gP=A!*yuLMYR0ibc`m+#A>XG->~ zjnD%SQov6HfkZ|O(0io68J*UVF%11el?pMQB8gV5ih>;L=8hia-=Vrf${y6(bl(aj z!T20!JtED!gwP0y52AnQKn?T;=P5Wx9XCr#TZr0bI!{6^8VD-dB;q(mXcj1`NRI+F zWq9VpFjU|1x)=s$uz_BVbnh}jKgyQdR-~=WEd=C8zywwP<{Co@7mYIb&*A8$HtxLW zx_h6U8_>b&5oJt%?{A3Yu}FXedTBlfD>pb2o6>G+(W}%UEAs2tZ+UA5zuO|v(I*LS z$vg*mZm|1coJ796u$|d*ZhATvoZQdruj?XvD6V?omIl=I)`?Pec!LbA(&t*MuCuMv zQq93(s=HIziwFVPiKCOk#d@^xg^@f2sp_I)XZ9#4QV7~p;fvrz9}HwH$e)CUj^07V z2PICZL5WE<{MEgnm=wUeJ=Wd!!j5A5oGH40Ak^T=highhbANfU5F3-F!KdEX8VyPx z9q>h9%zUdunX0OOygp~(lgiW{HMVz_q>yH3W1;zL=_osm0(5bdJB_hsDDlrVH?wg% zNVuJTE-CpaEls8)0)}lB2i!=4j!rzm{f>SWZ6zg_jnVS~B`Qv%(hY0tkkya=NFldn zCywr0tKhIO6+0Ambu36#3l$ZI`tmA<&+cAm$eHIom_lT6VxlU!4xkA>ejMD}8yP|( zN_ZuwCnAy|K2Yq8q(m)u=tqQTGOu!b$?f6^TG~FKDWL7!H`Cc!*|zXb5myD?{$M}I z`)M<_m)F9ZHx;)B@USC$Z&Q`l02p3jTvSuNm%{#o zjZ?YKV{~M7)&FTAdlu-JfXA`c1Ib6zfC3P;XuiG^WC4gj%uCIF?w!SXUo6aj1lObY z`7KiLfTHNx*+?FE*pGF;Dp6`iCrH5vvB}ok%;4jd@ca^o#LAO~ORr4cqST*prj;c_ zLp?=>1hzBUfF9KtYST_U{ihdTSm?I%2{;T=_%VK~nVT;^bGI-4eA|+(slzuq#uehA z-Yc!Kg7j(pO$jvAEoGukIyCBomK1F zz0J?b&Q3>de3ALA#i;Y^B?tyk3PPCW6(PZ}73%+0Ul0yZlq zRVJ?pU~>l15SYYi+Lg#<4!Y-4fC({e)=93-~7M20&PO_)reE(|9AQ(p*y`=<0d`ut44?+3lazzK_5NkY(F5 z_6~lQJoCD)c3erQ48kHaDxJ7E-YO_8JUl+`>+h!n4I99!1%lw}{5+uM8Okx@yC0w- zgSK{9Y-(!X%7G$q)(s5&0)oWK3L!bUzPfr`Z0yK_`kvc3wPa)mxkjkT3tiUAygUX` z(bV9&x;kxPp3Y07f72XVpM+Ok1GPe~YjdJh1FpZdvy%p(+sX=%X71izFG_jviuF+Hw$-EOBw&OUwz#?3Q%C=woPVcHiOz(Li*>vA zye_Gvq~vlyefGLJ*nhkTp@g2Q=FdwIK>L=vySr^?KN0`ymp~u7?GzXF zz1GdY{s8(MD{ZIRRt~ndwsZ>JbtDL2pkF=(-Iy|#mXgx1*DMOW8=@9fsT8LzlW9=0SZqc;4cRYe+#hWVE3nq zT0G_DIOiYx5eU(Le~ZaFaw)s`GfF@3!G8s``4^)Qv<{OsGqjLXj9^UbkoAeXE&2Qy zyGA0Fq_y~&M`c;f-u-zqf-MbRh<>&|G7Anw5_$Fp=cW(G*C1CfG>&_w5hw0@09H#2 z4rn<7?IZ&xB?g!!bN8*HGrPz-A*-Sp4&)kkNF4JQAD{S&r9pV)E&fcQjC<2J5J`lH zfb2)x+<(ilCX>YJ{GG zA`O@NxrvF%tuQ1I)(RAEw9;;Cczt#ci8XzT@<84s`O}vKcl>BKav6Mu$zP2YY602O z`{<`e$SUyZf-YKn;LHULq8BGS25M?Y%So?*%MG-$3i9*YOjmKRv*VlyKo96v#4L3h z1aI5f+2T@DMeP@0v>ue18Bc?NcJ4LwMf&REgbw)b!ob^Ea=v`Q0k0-FB7Ie7f4Djr zSp?m2gq#ZHqNVy8D`IaSlYU`I$%l{!+OlhNjW?j*F=32JLI0u1fr$0_{w63MM~Gdk7|`YtfB%rb-Uz#^Kij!aFh3k}V{r#*f49MDOIl$Px;o?8+Tg8^Pup{{t9jInE$2@ay;_hZyYqm6cXSMuMT@g(&VU}ri`QD6 zEbY}qC0vP;k}5-d*Yfpiva~s1I!O|{igi24-qc?pQICza(fgKO8zSv(yOmAh%RKME z7Z_A~k3zrqw*WR7$$fn4S~#e|qe7}Z56t-R@f$m&3N#F6{@{QTHrDO=nc9t~PwAe) zzHE)-0-gWk0VV~-ays$dy8!|M;5RwXB^#HwS)EY?ch9N)AV0#=va)HQ{b_0@00*r& zB@uYr4cH_kBwoM%79EY7)(`MtX??vnn8z_UA2syP#u~4kk2kfJ)ODyI#o-k&v)Ec$ z5V1_8_8YOxl*@wd-jm(ku<#y1hcBc_^+t0I`CVP0cD?{_)(9td9)LeZ&Ejf-Oi-kjF@ z7Tci4WC1Rxrg!NHM0<~r<>f&^54*p##KTLoxcsv~`9fdRqYNC_Vf$gsjs6SV1FFLq zMITXTD^ukU{LdJ3#^3GkN}8GiV|noELdH{NjdUcq7d<8oyL_-O;E{ zJgeRZIj|@i`AvZtg3LkJZ?sO(V&HUlHwp=HG)>s@rG*p>e($f8NP~y_;@_%H{96QN zz@j(VKP&orZ=qSIav8|FaQojaC~*Y$V`pm0MS(Lpe0=kKa&jM-sIalA)^~n==jEc# z4E=x?^yq1D$Ny8>cLz23b?XLDiJ}lisrbfqIGLMYNZL5iSKqy(fZ zRXT`tLQn*x_ugxO&>{44Hs`zN&Ye5ooSAd)KQO#xzgb!D-m5-Wasrw|Z*IK8udedBZ(cOMl$FJQl-87toRX5)qK<_@byxR{a3Xq>P+Gw|G073%$4G{X~rELu8~$M^-9#}CifCOiyd24!=3mv^kb_J##HUxMOojBO7rD=`9FmSb{x0CggS1N!BpSMURP*3Jl%4~ zg$wuzKudimQM>dhI0>9+7j1)Er$>qtPtxI`CHzm7d2`H@1z^HDEiFa12?LUY*+w;U zq~uFZYgFi;ac!ABv5r&ktmXY65EVphFTeG=;YN0LyeB{1*%I|jbQMelT0I^^*S z5TrK^bqAH&Vlihk!9qjjD{0+xrO93_kmrzeg#iYg@SB}4(cZ7>vh4gL?*#_Op<|7) zo`i*kwx<)+TKq*t5#{ycbw8xxPBjdkEY8oBDFPkN)T3K0E`@OHpbtkMQv`BB))L&Dq)5?Js7fdq zBi$(HS3PgXS|@HCAWyigMdO@5Rublv_`Uc${_+roCBq*2P%%i+Woxy!K(-=1IGh9B zs!;N&+SA2nbY@wP)dYP_l}yP&_;Z=-yavRiW6%+w;0)>WlSpvb7Q=&#DpS4dYvt`9i* za7p4(jylMQZ?=4+{Q9?uFF|5hH})mq@@>N0LLzok#Xk7a0;jn4iCVXveG^}-MdvN6 zn$k}@IB6f>>;tvdl^Di5ZZ`T=Rwuh#$Led$Oowk})9(a{l>3wxOk2ygCd4c}Y;$88 zKYY<@nHVjMt-wnH&Jde^3Q=kA#Jz%lN!zw}W2}s0$U6JA%8E#?{Zdt^x;}qy8fHc4 zyY+Y9GJ3{_fzlf~Jm-N>801;F;?p}<;XEgIHB|Fp3fkYUK{`hpIAee`!=+&7SEzjLy zj4uW@yS?0JuOJVFJ9Z@}N}AUDn>8%f9;7YKaG42PI|w<;-DM{(0WGM*N&UNw9IZ@DZ|_Wk?LTp7s);hBqiTC1tJ1pa z6Hl8%diS<62a1bF>Mp<8dYO}Q?pAV&qvO8gRBAPfkl)Ws+bu<@UK{4_OOhgm)Iv7+O4 zc{H(*f3KR;v}|J_uYrs=KZ$?A+tsz#ZEC@!_Iu&EjCHQA89eYuK9^k^_42CzCwI}B z>bm6E*Or!Uf|5SX(&wUauG4Kay{iv!*BJY7?) zZ&6I_WYITDDw?=I&Gwz`5^RA07!uWTTing}d^kN21|CyWsN2N2KO@6YxwVkz#$UNbP#O``-Ku zud36(OOffu^yq&?98NyXof4nU#x^Z8(K1m<`5qlS?&i*%VI9SEP-@ zyvs_xa4*bXQ=PqdK9p{EE_>=`Gv1S}z&wG`u?ygtXe}Gf8M#H!&=HSQ{<+ls3sC>{ zw6t`tM`DquieX2m?eX!~8mmW2nI+u6P8J$BS|4U8_j2eWLg0@cT{w$-Y>LQ{5Jxf* z`yn+W8RX5PsIiJ@V_%P+rJfx8;6$Zo+4z;X()NKlCcQ!Z5PZo3l3o&4tUpvZq5a^s z*gt6qt$kL9Ot$=j7TNv>x(GV zCoJQOA{hC;j^${@B_%QZw9Y#*MEBSFp01Z6EelMrHP(9Cuc|5NpBD-Oz_?r+i62Cc0z zj~=zGufutGNSY%|H1$1AaO2Bvlb zypk8OLC1%T*;(OxY-h)tGi8#VCq>x~YokV5*=z*{G-K5+eMBS|#gl2~bLj4VDjgG3 z@tdAMYRPQmOylBWV)Dqgovw;hF(Iq{^@>E{f~hj(Zq)r~KyAgQZXEd;CTgvX<R9&Qh~u6b)}?lu0ohawF09uX!6y!v{5lcapmuN(aRJzbYzRW>6rRGdB=2}F0rkNshH@7}HNC~z%(eIuM1<&HZ3496IhSHn)`WS~1(wcIxa_ya!*dMBo$Fk0EVD;U5`)Nc)Ntm^PULpy0RME7i? z0S#}sCTgJ0G4oko?qbIs>oTQ^c3>w0VdhP{Zcce?Ga5=hMhWa|lb8b7T`{prrh(R#<`%lO7jmV7>CoZSq5`-P7SZNsJ3V3zYT< zJ6^+?IZWkx=b}C1cNx)9{Jbn*@ymU2K``laZ$)Uy>yE;Z5Wn$p|GhPzAQ%{OwX|Co zav|9j)l*a)T%RB%A*rdV7HeDB0|?9u6;)N20}?i``M)`wdQzt=d90Ld_j0u(RtIdq zjAkgqExXPhflnCAZK7=8oY!j`VHaO+n@9#Px0{&C_%KAkE3DvqC6)m$I0&YuCM2Nn z^66cy4)?i9dgq785Z`CC-@&gAtSFdQ#vC7BU`LXL>P?ggZfWi8j zn(k++u&bENa*9}KE)`*oKZdGuaUA8nYHQ-ut!1F1@?PoB1RGB6@i6~uRWO1+cjd+k z#$hgn+n{c=!am+PMhdsR?I`ZNH1D;M3FaWNTG_EGadr1V9{WALkXt}NRES_2$I}Ct zOVQ*#<6gK5%x|R#Y#1mTtaKp3b#Pi9B{cI#57cvx z+;!(6;e$mu5W9zJWoyQ??k0+0hkx8Jv`(kWJ?9_e{+$uc@f(`al0q0K%p)B}h(SPW zU}?wdz{ib#q7zhBX|sufzvqJt3-$&CanyM@0bl4y8jRN~>hw83U9=rbX=~M|rW&X= zsPG>jPmz@cmW{Kml^S3ZG!0h=DoX}$hgH{PH292F?AuPARek>4v9+}&?waqjfDZTd z#gN{p*3;Z}>`FNYGa+R~wT_@U)m!5h+?6ok)y>k8{@b!kxF^w!{u1>0op@EV6}I}9 zpP9Jy4#{*StH0|kTBdpk+R&CdE-+hmF{wTskf1rtg3UXCf2dBP^8z@0ULT&uE!L$q$eu8B?? zHH-x^oc8gE=?iIEYiJS%xPu~q(E=Im{@GDp8o#ex@Yzo{dq>sK&n?!{qa+$FJlr6p zq3_9mp{f}LOWU9R)l9+QF2q+Ho0pdur?+}U7;q7d4PlZnFa2Sx1-t}X6hCvUP-INt zhl~_p2wzb8utm*2QiDKD`M@KG@X->1+A(ct;sZ0=_VZ;~NHOt+%I(qwDesBaSKnlT zOryS#5_eOAmofEv+i}C;zXG|5+L=W(z`6kNe~8~N+TRdA$LFo9@j`#b+2Vuf?#ckp zt{lCO{AQughF9+D#QH;skPUqSGG(9B0&-pky6mE!yD5~Bwmbs{(?3lhxqWNePhR;1!j;EKSs)fON_Jbi5c>tOFS=yQ$I8MQroN8 zO+us{Vy_{C25&$B36@{N?~wOY=1>yIvjEzjVqG8w!h4u#Ac)q?2WSLBdsRg7IVDhX z{rAd8zr|oIe%H2$Nc&-IML&U#A%0eTX=Xj(J`k-m&fkcw+gF~!*QrQD11tr(ZUSwa zQit4(4T4{X_|eTYK~-e^ARK>`XiYhQuxA&y|H7&$*v=pc*6%ciydOy;{rw}pffubj zYMNBU>b*?V9w;WaX<#J#wgblLJMTcVT&V^a#rgAeqD>7?M{(Hgz$A02W|#Flmx{jVN8iKTx)fz+yt)m=W=t9 zXCOIJVimkyYnzEEN&y<_#Zz(cy5t;sZh0h?K62$%JinE-=HrRaM4cpy!5vtgw<oo^ZsYJ-vyO*GN4fo7v z(4Ow>Z@cEKQ;LX?-?fNkB`+^8mllN@>Z@?YKj8-taI6uEObBR~V#-*jO`bu~dhZ7n zPG07Jcs7IJycwt%DQTOt?)P$iZW+jOxUJl1VOb3ucYI8x$W}HlN?+O%vtHF71G=`z z*NaK*%0_Vs#RA{H7e8>Z&HbrT0k9sW2)|;clrYI4*dfhMCi9Ntb|5SzOhTybL0im9 zSmAo%4Ila^vfor>Xhe7`geOMlP1<=ediu&9O6<+$Q#+p_5GcjPcLY>Oc_D{VYp88Z zSlnVZ46C$C&&Wn-0%1fqiHuHa1m6r!|K1|2#%Yq#(skR)h`{B$rc;uSon2krxH-6@ zTy^@HAb#=FOi+A}rF$yaDcc{>E_Pzk0zhtAE zXZ6Lv3j$e4BmGaa4*@2vj1O$g>t@d-2FtHNXqkzA&yGwpk~FobYVHTPOv&GX=qUR6 zz0!){|9;-CH$)AQxepwvO*LvG4+%gmw}9F6mcItDGU{fK|LqYj%v!zaIEmR7a2^m- z?@Q26%@W|++=aOW?&iY!K#uaCHXI2x$pd5m90H;a4=K}G4^~zg2!u=SKAr#W#WILr z;{y@7&rGVog+Pk$>0eytkZ7{na?iTySD;}D?G3nklZ7jB(OwOK@V{z63~9Re>R%VZ zRHwyuGh5gcJL{ueodxO#+!(C&K(=`^IY?0rI)>1C zdDsEd_G{AO(%rM7p0%nOLGBevD zy9OpHH?}4xQF=Mrjg9xq0MBMZ8Q_53IX%Wk#mD>X+gUvy_Eu{44IsrDgUlSNaX13N z{I;WR0}?k`0AJzjmME0CIBAMR{7$dRx0SHHy}gy88dvUHh}vDv;a>rHLMHaZpUYo& z;2u8Qp{my@GCN^ur)n7`?|eI7o?WF?g#wK>o`T zNGtH#AyrBM5F2MO2f=!Jei_xAb&S=dz-HGfDn!L8{&_onQ0tMN$-P1>Vt1Pie)lf% z$!U!sa&Y=!i|q7R8oy?=0hsDW%570yDPZnxN26lCKSu=-;xI?t@H=IH*O?NrOtg>lnJ7-6cfG#3D@Ue0{4Xm56yWEBd0bD)T z;Gmo|@QO|CdWw|Ko4F=1>}t0Xrb)ECxi;1Z24X!Aw{@hk;b7o4GLn~#9i?w*xLt(m z7?jW(EAI$`(b2uAs|(BUdblep{u6|z;K5B)_q*UVB_&qc6A1g{jQS7It@ZWmMVRtO ze8paCqn&7mfBsFPwK|(-R3}TaAI@kH>*fA$GBh$cn<^9xEXRzNB{wvj3Xy?Fw=w2s zajK8Xc|9<&=mYpAWREtHH9dH5a@>!ZWsuKXSW@>g3RsKH;aw?sZAh;lHDVhjw0Z~>^ KlP^S=`u_)cmFs~3 diff --git a/src/proc/play/output-slot.cpp b/src/proc/play/output-slot.cpp index e93acb278..87eaf5051 100644 --- a/src/proc/play/output-slot.cpp +++ b/src/proc/play/output-slot.cpp @@ -38,14 +38,6 @@ namespace play { - namespace { // hidden local details of the service implementation.... - - } // (End) hidden service impl details - - - - - OutputSlot::~OutputSlot() { } // emit VTables here.... @@ -68,15 +60,26 @@ namespace play { } - /** */ + /** claim this OutputSlot for active use as output sink(s). + * At any point, a given slot can only be used for a single + * ongoing output process (which may serve several channels though). + * The assumption is for the OutputSlot to be picked through a query + * to some OutputManater, so the parameters (resolution, sample rate...) + * should be suited for the intended use. Thus no additional configuration + * is necessary. + * @return Allocation representing the "connected state" from the client's POV. + * The client may retrieve the effectively required Timings from there, + * as well as the actual output sinks, ready for use. + * @remarks calls back into #buildState, where the concrete OutputSlot + * is expected to provide a private Connection implementation, + * subclassing OutputSlot::Allocation + */ OutputSlot::Allocation& OutputSlot::allocate() { if (!isFree()) throw error::Logic ("Attempt to open/allocate an OutputSlot already in use."); - UNIMPLEMENTED ("internal interface to determine the number of channel-connections"); - state_.reset (this->buildState()); return *state_; } @@ -110,7 +113,6 @@ namespace play { connection.discard(data2emit); } - diff --git a/src/proc/play/output-slot.hpp b/src/proc/play/output-slot.hpp index 8c7dd9c86..860232b1f 100644 --- a/src/proc/play/output-slot.hpp +++ b/src/proc/play/output-slot.hpp @@ -26,9 +26,39 @@ ** using this concept allows to separate and abstract the data calculation and the organisation ** of playback and rendering from the specifics of the actual output sink. Actual output ** possibilities can be added and removed dynamically from various components (backend, GUI), - ** all using the same resolution and mapping mechanisms + ** all using the same resolution and mapping mechanisms ** - ** @see diagnostic-output-slot.hpp ////TODO + ** Each OutputSlot is an unique and distinguishable entity. It corresponds explicitly to an + ** external output, or a group of such outputs (e.g. left and right sound card output channels), + ** or an output file or similar capability accepting media content. Initially, an output slot + ** needs to be provided, configured and registered, using an implementation suitable for the + ** kind of media data to be output (sound, video) and also suitable for the special circumstances + ** of the output capability (render a file, display video in a GUI widget, send video to some + ** full screen display, establish a Jack port, just use some kind of "sound out"). An output + ** slot is always limited to a single kind of media, and to a single connection unit, but + ** this connection may still be comprised of multiple channels + ** (e.g. stereoscopic video, multichannel sound). + ** + ** In order to be usable as output sink, an output slot needs to be \em allocated: At any time, + ** there may be only a single client using a given output slot this way. To stress this point: + ** output slots don't provide any kind of inherent mixing capability; any adaptation, mixing, + ** overlaying and sharing needs to be done within the nodes network producing the output data + ** to be fed into the slot. (in special cases, some external output capabilities — e.g. the + ** Jack audio connection system — may still provide additional mixing capabilities, + ** but that's beyond the scope of the Lumiera application) + ** + ** Once allocated, the output slot returns a set of concrete sink handles (one for each + ** physical channel expecting data). The calculating process feeds its results into those handles. + ** Size and other characteristics of the data frames are assumed to be suitable, which typically + ** won't be verified at that level anymore. Besides that, the allocation of an output slot reveals + ** detailed timing expectations. The client is required to comply to these timings when \em emitting + ** data — he's even required to provide a current time specification, alongside with the data. + ** Based on this information, the output slot has the ability to handle timing failures gracefully; + ** the concrete output slot implementation is expected to provide some kind of de-click or + ** de-flicker facility, which kicks in automatically when a timing failure is detected. + ** + ** @see OutputSlotProtocol_test + ** @see diagnostic-output-slot.hpp */ @@ -42,25 +72,18 @@ #include "proc/engine/buffer-provider.hpp" #include "proc/play/timings.hpp" #include "lib/iter-source.hpp" -//#include "lib/sync.hpp" #include #include -//#include -//#include -//#include namespace proc { namespace play { - + using proc::engine::BuffHandle; using proc::engine::BufferProvider; using lib::time::TimeValue; -//using std::string; - -//using std::vector; -//using std::tr1::shared_ptr; + using boost::scoped_ptr; @@ -71,10 +94,16 @@ namespace play { - /******************************************************************** + /******************************************************************************** * Interface: Generic output sink. - * - * @todo write type comment + * An OutputSlot represents the possibility to send data through multiple + * channels to some kind of external sink (video in GUI window, video full screen, + * sound, Jack, rendering to file). Clients are expected to retrieve a suitably + * preconfigured implementation from some OutputManager instance. An OutputSlot + * needs to be \em claimed for output by invoking #allocate, which returns a + * representation of the connection state. This operation is exclusive. + * The actual \link DataSink output sinks \endlink can be retrieved + * through the Allocation object returned from there. */ class OutputSlot : boost::noncopyable @@ -87,6 +116,9 @@ namespace play { scoped_ptr state_; + /** build the \em connected state, + * based on the existing configuration + * within this concrete OutputSlot */ virtual ConnectionState* buildState() =0; @@ -133,7 +165,7 @@ namespace play { public: BuffHandle lockBufferFor(FrameID); - void emit(FrameID, BuffHandle const&, TimeValue currentTime = Time::MAX); ///////////////TICKET #855 + void emit(FrameID, BuffHandle const&, TimeValue currentTime = Time::ANYTIME); }; diff --git a/src/proc/play/play-service.cpp b/src/proc/play/play-service.cpp index 5ddb4fe3f..0674fd934 100644 --- a/src/proc/play/play-service.cpp +++ b/src/proc/play/play-service.cpp @@ -179,7 +179,7 @@ namespace play { Play::Controller PlayService::connect (ModelPorts dataGenerators, POutputManager outputPossibilities) { - Timings playbackTimings; /////////////////////////////////////////////////////////////TODO + Timings playbackTimings; //////////////////////////////////////////////////////////////////////TICKET #875 return pTable_->establishProcess( PlayProcess::initiate(dataGenerators, diff --git a/src/proc/play/render-configurator.cpp b/src/proc/play/render-configurator.cpp index 42fc31a37..ee0552dfe 100644 --- a/src/proc/play/render-configurator.cpp +++ b/src/proc/play/render-configurator.cpp @@ -107,7 +107,7 @@ namespace play { Timings nominalTimings = activeOutputConnection.getTimingConstraints() .constrainedBy(playbackTimings_); - return EngineService::instance().calculate(port, nominalTimings, activeOutputConnection, renderQuality_); + return EngineService::instance().calculate (port, nominalTimings, activeOutputConnection, renderQuality_); } diff --git a/tests/components/proc/play/diagnostic-output-slot.hpp b/tests/components/proc/play/diagnostic-output-slot.hpp index 4a6f758d2..ff948d814 100644 --- a/tests/components/proc/play/diagnostic-output-slot.hpp +++ b/tests/components/proc/play/diagnostic-output-slot.hpp @@ -227,20 +227,39 @@ namespace play { /******************************************************************** * Helper for unit tests: Mock output sink. - * - * @todo write type comment + * Complete implementation of the OutputSlot interface, with some + * additional stipulations to support unit testing. + * - the implementation uses a special protocol output buffer, + * which stores each "frame" in memory for later investigation + * - the output data in the buffers handed over from client + * actually hold an TestFrame instance + * - the maximum number of channels and the maximum number + * of acceptable frames is limited to 5 and 100. + * @warning any Captured (test) data from all individual instances + * remains in memory until shutdown of the current executable */ class DiagnosticOutputSlot : public OutputSlot { static const uint MAX_CHANNELS = 5; - + + /** @note a real OutputSlot implementation + * would rely on some kind of embedded + * configuration here */ + uint + getOutputChannelCount() + { + return MAX_CHANNELS; + } + + /** hook into the OutputSlot frontend */ ConnectionState* buildState() { - return new SimulatedOutputSequences(MAX_CHANNELS); + return new SimulatedOutputSequences( + getOutputChannelCount()); } /** @internal is self-managed and non-copyable. @@ -254,7 +273,7 @@ namespace play { accessSequence (uint channel) { REQUIRE (!isFree(), "diagnostic OutputSlot not (yet) connected"); - REQUIRE (channel <= MAX_CHANNELS); + REQUIRE (channel <= getOutputChannelCount()); return static_cast (*state_).at(channel); } diff --git a/uml/lumiera/151685.diagram b/uml/lumiera/151685.diagram index 359efa5c4..19335767f 100644 --- a/uml/lumiera/151685.diagram +++ b/uml/lumiera/151685.diagram @@ -2,64 +2,64 @@ format 74 classcanvas 128005 class_ref 176133 // OutputSlot draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default - xyz 157.7 37 2000 + xyz 155.04 38.2 2000 end fragment 128261 "output management" - xyzwh 123 14 1990 244 292 + xyzwh 126.62 17.82 1990 240 288 end classcanvas 129029 class_ref 185221 // Allocation draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default - xyz 260 126 2005 + xyz 247.02 129.02 2005 end classcanvas 129541 class_ref 178565 // DataSink draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default - xyz 14 191 2005 + xyz 13.16 194.12 2005 end classcanvas 129925 class_ref 185349 // Connection draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default - xyz 443 184 2000 + xyz 419.32 189.12 2000 end classcanvas 130309 class_ref 185477 // OutputSlotImpl draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default color green - xyz 149 422 2000 + xyz 149.12 420.84 2000 end classcanvas 130565 class_ref 185605 // ConnectionState draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default - xyz 261 250 2000 + xyz 249.88 248.84 2000 end classcanvas 130949 class_ref 185733 // ConcreteConnection draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default color lightgreen - xyz 432 357 2000 + xyz 408.32 358 2000 end classcanvas 131205 class_ref 185861 // ConnectionStateManager draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default - xyz 240 351 2000 + xyz 228.88 351 2000 end classcanvas 132613 class_ref 178693 // BufferProvider draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default - xyz 534 456 2000 + xyz 484.36 459.64 2000 end fragment 132997 "concrete output driver" - xyzwh 123 309 1995 508 205 + xyzwh 126.68 309.48 1995 464 204 end note 133125 "Client front-end" - xyzwh 15 270 2000 75 43 + xyzwh 15.36 270.88 2000 75 43 note 133381 "Knowledge specific to this external output and driver" - xyzwh 564 338 2000 129 57 + xyzwh 536.04 322.88 2000 138 58 relationcanvas 129157 relation_ref 212485 // decenter_begin 726 - from ref 128005 z 2006 stereotype "<>" xyz 229 73 3000 to point 227 82 - line 132485 z 2006 to point 295 82 + from ref 128005 z 2006 stereotype "<>" xyz 230 72 3000 to point 227.72 82.12 + line 132485 z 2006 to point 294.96 83.12 line 132357 z 2006 to ref 129029 no_role_a no_role_b no_multiplicity_a no_multiplicity_b end relationcanvas 129669 relation_ref 212613 // geometry HV - from ref 129029 z 2006 stereotype "<>" xyz 70 155 3000 to point 52 153 + from ref 129029 z 2006 stereotype "<>" xyz 65 158 3000 to point 51 155 line 130821 z 2006 to ref 129541 no_role_a no_role_b no_multiplicity_a no_multiplicity_b @@ -67,7 +67,7 @@ end line 130053 ---+ decenter_end 876 from ref 129029 z 2006 to ref 128005 relationcanvas 130181 relation_ref 212741 // - from ref 129541 z 2006 stereotype "<>" xyz 92 206 3000 to ref 129925 + from ref 129541 z 2006 stereotype "<>" xyz 188 210 3000 to ref 129925 no_role_a no_role_b no_multiplicity_a no_multiplicity_b end @@ -99,13 +99,13 @@ end relationcanvas 131845 relation_ref 213637 // geometry HV decenter_end 197 - from ref 130309 z 2001 to point 264 438 + from ref 130309 z 2001 to point 252 433 line 132101 z 2001 to ref 131205 no_role_a no_role_b no_multiplicity_a no_multiplicity_b end relationcanvas 132741 relation_ref 213765 // - from ref 130949 z 2001 to point 574 423 + from ref 130949 z 2001 to point 524.68 414 line 133253 z 2001 to ref 132613 no_role_a no_role_b no_multiplicity_a no_multiplicity_b diff --git a/uml/lumiera/5.session b/uml/lumiera/5.session index eff2c4d90..0d5cb5160 100644 --- a/uml/lumiera/5.session +++ b/uml/lumiera/5.session @@ -5,13 +5,13 @@ diagrams objectdiagram_ref 138885 // ModelAssetRelations 730 488 100 4 0 0 classdiagram_ref 143877 // Player Entities - 663 648 100 4 0 0 + 663 654 100 4 0 0 objectdiagram_ref 144005 // Play Process Structure 562 424 100 4 0 0 sequencediagram_ref 145157 // output data exchange 586 416 100 4 0 0 active classdiagram_ref 151685 // Player Output - 723 654 100 4 0 0 + 643 590 92 4 0 0 end show_stereotypes selected diff --git a/uml/lumiera/lumiera.prj b/uml/lumiera/lumiera.prj index b8b727236..341a05212 100644 --- a/uml/lumiera/lumiera.prj +++ b/uml/lumiera/lumiera.prj @@ -1,6 +1,6 @@ format 74 "lumiera" - revision 73 + revision 74 modified_by 5 "hiv" cpp_root_dir "../../src/" diff --git a/wiki/renderengine.html b/wiki/renderengine.html index a3d7da184..9b27ae55f 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -3362,7 +3362,7 @@ While actually data frames are //pulled,// on a conceptual level data is assumed As both of these specifications are given by [[Pipe]]-~IDs, the actual designation information may be reduced. Much can be infered from the circumstances, because any pipe includes a StreamType, and an output designation for an incompatible stream type is irrelevant. (e.g. and audio output when the pipe currently in question deals with video) -
+
//writing down some thoughts//
 
 * ruled out the system outputs as OutputDesignation.
@@ -3397,6 +3397,12 @@ The relation between the central OutputDirector and the peripheral OutputManager
 
 For a viewer widget in the GUI this yields exactly the expeted behaviour, but in other cases, e.g. for sound output, we need more general, more globally scoped output slots. In these cases, when a local mapping is absent, the query for output resolution is passed on up to the  OutputDirector, drawing on the collection of globally available output slots for that specific kind of media.
 {{red{open question 11/11: is it possible to retrieve a slot from another peripheral node?}}}
+
+!!!output modes
+Most output connections and drivers embody some kind of //operation mode:// Display is characterised by resolution and colour depth, sound by number of channels and sampling rate, amongst others. There might be a mismatch with the output expectations represented by [[output designations|OutputDesignation]] within the model. Nontheless we limit those actual operation modes strictly to the OutputManager realm. They should not leak out into the model within the session.
+In practice, this decision might turn out to be rather rigid, but some additional mechanisms allow for more flexibility
+* when [[connecting|ViewerPlayConnection]] timeline to viewer and output, stream type conversions may be added automatically or manually
+* since resolution of an output designation into an OutputSlot is initiated by querying an output manager, this query might include additional constraints, which //some// (not all) concrete output implementations might evaluate to provide an more suitably configured output slot variant.
 
@@ -3416,7 +3422,7 @@ Note that an OutputSlot acts as a unit for registration and also for allocating The //registration//&nbsp; of an output slot installs a functor or association rule, which later on allows to claim and connect up to a preconfigured number of channels. This allocation or usage of a slot is exclusive (i.e. only a single client at a time can allocate a slot, even if not using all the possible channels). Each output manager instance may or may not be configured with a //fall-back rule:// when no association or mapping can be established locally, the connection request might be passed down to the global OutputDirector. Again, we can expect this to be the standard behaviour for sound, while video likely will rather be handled locally, e.g. within a GUI widget (but we're not bound to configure it exactly this way)
-
+
An output mapping serves to //resolve//&nbsp; [[output designations|OutputDesignation]].
 
 !Mapping situations
@@ -3428,7 +3434,7 @@ The //registration//&nbsp; of an output slot installs a functor or associati
 :Thus, in this case we resolve similar to a bus connection, possibly overridden by already pre-existing or predefined connections.
 ;switch board
 :a viewer might receive multiple outputs and overlays, necessitating a user operated control to select what's actually to be displayed
-:Thus, in this case we need a backwards resolution at the lower end of the output network, to connect to the model port as defined by this viewer SwitchBoard
+:Thus, in this case we need a backwards resolution at the lower end of the output network, to connect to the model port as selected through the viewer's SwitchBoard
 ;global pipes or virtual media
 :when binding a Sequence as Timeline or VirtualClip, a mapping from output designations used within the Sequence to virtual channels or global pipes is required
 :Thus, in this case we need to associate output designations with ~Pipe-IDs encountered in the context according to some rules &mdash; again maybe overridden by pre-existing connections
@@ -3443,12 +3449,12 @@ All these mapping steps are listed here, because they exhibit a common pattern.
 * there is an //unconnected//&nbsp; state.
 
 !Implementation notes
-Thus the mapping is a copyable value object, based on a associative array. It may be attached to a model object and persisted alongside. The mapping is assumed to run a defaults query when necessary. To allow for that, it should be configured with a query template (string). Frequently, special //default pipe// markers will be used at places where no distinct pipe-ID is specified explicitly. Besides that, invocations might supply additional predicates (e.g. {{{ord(2)}}} to point at "the second stream of this kind") thereby hinting the defaults resolution. Moreover, the mapping needs a way to retrieve the set of possible results, allowing to filter the results of the rules based default. Mappings might be defined explicitly. Instead of storing a //bottom value,// an {{{isDefined()}}} predicate might be preferable.
+Thus the mapping is a copyable value object, using an associative array. It may be attached to a model object and persisted alongside. The mapping is assumed to run a defaults query when necessary. To allow for that, it should be configured with a query template (string). Frequently, special //default pipe// markers will be used at places where no distinct pipe-ID is specified explicitly. Besides that, invocations might supply additional predicates (e.g. {{{ord(2)}}} to point at "the second stream of this kind") thereby hinting the defaults resolution. Moreover, the mapping needs a way to retrieve the set of possible results, allowing to filter the results of the rules based default. Mappings might be defined explicitly. Instead of storing a //bottom value,// an {{{isDefined()}}} predicate might be preferable.
 
 First and foremost, mapping can be seen as a //functional abstraction.// As it's used at implementation level, encapsulation of detail types in't the primary concern, so it's a candidate for generic programming: For each of those use cases outlined above, a distinct mapping type is created by instantiating the {{{OutputMapping<DEF>}}} template with a specifically tailored definition context ({{{DEF}}}), which takes on the role of a strategy. Individual instances of this concrete mapping type may be default created and copied freely. This instantiation process includes picking up the concrete result type and building a functor object for resolving on the fly. Thus, in the way typical for generic programming, the more involved special details are moved out of sight, while being still in scope for the purpose of inlining. But there //is// a concern better to be encapsulated and concealed at the usage site, namely accessing the rules system. Thus mapping leads itself to the frequently used implementation pattern where there is a generic frontend as header, calling into opaque functions embedded within a separate compilation unit.
 
-
+
Within the Lumiera player and output subsystem, actually sending data to an external output requires to allocate an ''output slot''
 This is the central metaphor for the organisation of actual (system level) outputs; using this concept allows to separate and abstract the data calculation and the organisation of playback and rendering from the specifics of the actual output sink. Actual output possibilities (video in GUI window, video fullscreen, sound, Jack, rendering to file) can be added and removed dynamically from various components (backend, GUI), all using the same resolution and mapping mechanisms (&rarr; OutputManagement)
 
@@ -3468,6 +3474,9 @@ Besides the sink handles, allocation of an output slot defines some timing const
 
 The assumption is for the client to have elaborate timing capabilities at his disposal. More specifically, the client is assumed to be a job running within the engine scheduler and thus can be configured to run //after// another job has finished, and to run within certain time limits. Thus the client is able to provide a //current nominal time// -- which is suitably close to the actual wall clock time. The output slot implementation can be written such as to work out from this time specification if the call is timely or overdue -- and react accordingly.
 
+!!!output modes
+some concrete output connections and drivers embody a specific operation mode (e.g. sample rate or number of channels). The decision and setup of these operational configuration is initiated together with the [[resolution|OutputMapping]] of an OutputDesignation within the OutputManager, finally leading to an output slot (reference), which can be assumed to be suitably configured, before the client allocates this slot for active use. Moreover, an individual output sink (corresponding to a single channel) may just remain unused -- until there is an {{{emit()}}} call and successful data handover, this channel will just feature silence or remain black. (More flexible system, e.g. Jack, allow to generate an arbitrary number of output pins -- Lumiera will support this by allowing to set up additional output slots and attach this information to the current session &rarr; SessionConfigurationAttachment)
+
 !!!Lifecycle and storage
 The concrete OutputSlot implementation is owned and managed by the facility actually providing the output possibility in question. For example, the GUI provides viewer widgets, while some sound output backend provides sound ports. The associated OutputSlot implementation object is required to stay alive as long as it's registered with some OutputManager. It needs to be de-registered explicitly prior to destruction -- and this deregistration may block until all clients using this slot did terminate. Beyond that, an output slot implementation is expected to handle all kinds of failures gracefully -- preferably just emitting a signal (callback functor).
 {{red{TODO 7/11: Deregistration is an unsolved problem....}}}
@@ -5368,6 +5377,9 @@ The Session object is a singleton &mdash; actually it is a »~PImpl«-Facade
 &rarr; see [[relation of timeline, sequences and objects|TimelineSequences]]
 
+
+
While the core of the persistent session state corresponds just to the HighLevelModel, there is additionaly attached state, annotations and specific bindings, which allow to connect the session model to the local application configuration on each system. A typical example would be the actual output channels, connections and drivers to use on a specific system. In a Studio setup, these setup and wiring might be quite complex, it may be specific to just a single project, and the user might want to work on the same project on different systems. This explains why we can't just embody these configuration information right into the actual model.
+
Querying and retrieving objects within the session model is always bound to a [[scope|PlacementScope]]. When using the //dedicated API,// this scope is immediately defined by the object used to issue the query, like e.g. when searching the contents of a track. But when using the //generic API,// this scope is rather implicit, because in this case a (stateful) QueryFocus object is used to invoke the queries. Somewhat in-between, the top-level session API itself exposes dedicated query functions working on the whole-session scope (model root).
 Based on the PlacementIndex, the treelike scope structure can be explored efficiently; each Placement attached to the session knows its parent scope. But any additional filtering currently is implemented on top of this basic scope exploration, which obviously may degenerate when searching large scopes and models. Filtering may happen implicitly; all scope queries are parametrised to a specific kind of MObject, while the PlacementIndex deals with all kinds of {{{Placement<MObject>}}} uniformly. Thus, more specifically typed queries automatically have to apply a type filter based on the RTTI of the discovered placements. The plan is later to add specialised sub-indices and corresponding specific query functions to speed up the most frequently used kinds of queries.