diff --git a/core/modules/layout/config/display.bound.admin_master.yml b/core/modules/layout/config/display.bound.admin_master.yml new file mode 100644 index 0000000..5b33c5f --- /dev/null +++ b/core/modules/layout/config/display.bound.admin_master.yml @@ -0,0 +1,41 @@ +id: admin_master +label: Default admin layout +layout: static_layout:layout__two-col +layoutSettings: { } +blockInfo: + block.ikwqqmzh: + region: first + weight: '100' + region-type: content + block.pasmpbio: + region: first + weight: '200' + region-type: content + block.hiuobsyq: + region: first + weight: '300' + region-type: content + block.aduoefgo: + region: second + weight: '100' + region-type: aside + block.cefddxxz: + region: second + weight: '200' + region-type: aside + block.fvurzags: + region: second + weight: '300' + region-type: aside + block.cwycrmwm: + region: second + weight: '400' + region-type: aside + block.nrinfrbu: + region: second + weight: '500' + region-type: aside + block.hhqpbxal: + region: second + weight: '600' + region-type: aside diff --git a/core/modules/layout/config/display.bound.front_master.yml b/core/modules/layout/config/display.bound.front_master.yml new file mode 100644 index 0000000..fe9c371 --- /dev/null +++ b/core/modules/layout/config/display.bound.front_master.yml @@ -0,0 +1,37 @@ +id: front_master +label: Default layout +layout: static_layout:layout__two-col +layoutSettings: { } +blockInfo: + block.nnadgxph: + region: first + weight: '100' + region-type: content + block.xytwvpdi: + region: first + weight: '200' + region-type: content + block.xzcwrtdy: + region: first + weight: '300' + region-type: content + block.miqumptd: + region: first + weight: '400' + region-type: content + block.htgrsglh: + region: second + weight: '100' + region-type: aside + block.scxwxgon: + region: second + weight: '200' + region-type: aside + block.fqcxgrof: + region: second + weight: '300' + region-type: aside + block.ebrcmkge: + region: second + weight: '400' + region-type: aside diff --git a/core/modules/layout/gear_fff.png b/core/modules/layout/gear_fff.png new file mode 100644 index 0000000..dfd4aae --- /dev/null +++ b/core/modules/layout/gear_fff.png @@ -0,0 +1,238 @@ +PNG + + IHDR sBIT|d pHYs  ~tEXtCreation Time11/14/121tEXtSoftwareAdobe Fireworks CS6輲VprVWxMKQτ "h 2&bpZq,E\s74غB?@]Aĥx RP:~˜{0dsO| e +i'l%84M9=ZdYQm omMo ?h# +!^4{?8.O9OLq'U}[Vk=N9_˴kk91oI_8ۉK8U:o%/uyos%>9{G6ᐝd58f)kc[C앵؝ᑃdG.Fpҁ.V<`3}s޲,BP&=S%}ةؗDǾ^)й!h 9$G@5[Ua:*8>Ybx>$i&&xNDL2a^A6㘹 wРj#9&| +3i9102mHIGoE#hXX}@dY\}\|6 qnG&0W puK41['@VEo 0fKcӘ +ˡC|:QfDG):*V +*3橤c&{-pG+ޯIPP.Pd"џ1}b^9\.yW&;SvBy "IYKRft+`H3 'eO|^<̯cWVnA^\UwJT؛Cެַ'gC8Az^9NrADa&;'ޚIw bX AcBX)B|6K1B>Cȿޣ&{3 %`L3ӌ4S#L7imB!z;sPM`KKV9uوA5Fۣk^hzMJF*[bDܴ@M@V$ٵbgU9D&Fbպl9Ťkr\_T0RJRl]!{sYk܀`!e`~cl6]t5[wqf3:\)RF]I,mrD,Lg6 `G*'j1|Z+FcJqGe>b,@d@u8#F&eF׈D ؄Dr&A٥CV`OxN:d%i\bEV~D8ZS+x1!@"ґf(*&'O{?Tp1{'[س&/Y ѲBzppvH@Go)Wאr 3i/3iӛ S NN%8p~Fٺ0*D瞐\g&nׄj1:㘺*LHļEq*Eds"M̥x=E6f׍}Zxjo-VaA~O N ܥ0fĔlQD`aEXvXV˰9泀yf.Bj謃isЮ ˋ'/3̔t&|&X+/h&dA51U#8 +^WyV0;lyN_f2kϨVx2XYI*0ɮT5DmU\)xSc3q>sA;i}g(y -2{u t"uN:eʹ|\BTyFRafGOJ=?"D*":}Ȧ_bCi}n]_H6{1}n32bXU钝]_k/uy:$K[ {YMoH@(7 V%|e=}nǾ5o%0h"1q*='cc%N`SNvAvz LƈgIK\8gkFKl)ΟԜ_k>1LS8:HvzL Ži`ڈYd)ΟԜ_icZ1m =L^9~y٤D{z,K㎥k.gb3iB\+aJ:v{yRöY|qE+nXXw -\V<^qzL[2-;]"WsgyRp?#N10:0eoG^^6I|Ds}Nڼzǡ]v4to3RQV#i] ' mإUmx-rUd(wEWy]0*Uvѭز採ѹaqOd +|Ub7bDU?Kܟs[dO."ʖ/7, mvaZLksLƄ-+o50 <qe aZ'xw VwR$lƟgAj Taw>My@)_HnogV+G%⣬;jw[~òTҹ~ї94SE +ŋd]qCЊtZF˫E&YΥΞǡ=s!KZ2p!U¶##Uݿ%y^s9TC/%ps/D+ʯA2]̓E7ӅW椯-*uTe? +q:q@#h=GÆGmGFzKO-;*E_!qbku1Ҡ^֕wFO;t{Nkѧ O̮-y[`3~n??= +5ʒs?oz{mFe|G8ù^J1=^pźE*DrQZ'Q ³gl{C]BlzNb΅pŢ? _෕b$gճ;6r!?aVs<&3;@޲@Hj^ q9ɹ Wx!=Gr k-]W3Z$g↌UT4{Л7䩗.ؒwКgb{*nK8"?xEupQyLI>l+/Vb'OzMwnas 3i/=ѝmFA6.ZKg;[gΝusV@ߑ(,kBw YQ"aj;ruCȼ~P;Ǣs=Rc% Hmط:cG7to^mD]" k 'ՖE"IؿQ~;펏?]o/fdUq}v?*4q*i>,}Y+z;{K{r$ֻo{lw \e6jت˨ݩUUfB_~U\sJ.ʯ QIx_p+.z?+~f[w0F[Ҝ8 +{>^ol}ۇsM?X>\?/R4WT8 X]CK޿>[J)8 +~@G=b@S +b3EW Xc)IhK_so틒 W\9} Ya CJ/fj1"IYi$5?%YXP\䑕H*$ZIx{!)o%;ݖOO^c >+y6'V"pNRPF|9~_8q\m6GM^Vę◳5l&~Y f[ '`kYT?LvYZpkț{q\,^уWT }O"kld5}5]ƈjؾCqx=Bƪ_]QPyFЖ+jvyY_H>]j+,(F,UX;WwVv_-6&FrhMk|nSmކ $YNה^K+}~i ,r~i$e5C2wWz=rрOIIsQMzrdaAߐ|qLP?daN@ ]޸,|ҟ{kpwh8HΆWW[2Qd$fшfрV4 x\9"ц'8 gj$oz5(tm=֏ Yfkͽxdʼɝ<=0x̭oO/#!!߀o**iק2x&)r.mVU tߡ]{5g)6M߶t%9vqvqʾ=ߧx ;1t@Ss}=)};>@"{LՆd$P#-"^x8n)OEC6;X#Fpj1ZS~tsoSw?b't=آ-6XmīChƻ{32D>? d\0+hF44فY8l՘"&#Pe +MNOǫ/[/A~'}q]Qq't6>'GA?}lkzݴZUڳx{wvr[knnk|`2&cpL;::{',8:M/~pBʣwx{pɆqN|_wkNq/iߏ"7įy<|Jd0Ǎ1(6ߣ잎CԷ /u u7az(x5ZLz5Df`ky#Q^ؖڞβTPM64|hB3I HL#GQ1kԪoU ҷ?ݰkEF8q3|녁LQj Ќہ9N jۏ-'=BZ:ܾe{5}/S"ߵ\>(\~خ%zVlPEKcvѳm7 e. 6?b7AiPl>{{~+*uMAOVWE۱9|TRSiXV B 1eXS oӷhŮc؅nӘ~;jݘ]6 ̆ -9aؙb>8 X\ *8t(vř㌦ą`k ^? ܜGn̨zUOq(02ľNr*7 C~Adg$A,UD0U18 HCVnTJlc< +++Pj9V^V8H[.F<Ê,!h(g$m,5y0YŠKUhyA=>- VγqQ,V[.mTjN,\X%XzmʨFg2?LZ)7647V몈q9 E'c4NmQ!:h 8sM@+}U/#TZNaD gQrubqyS~8ogD;Ige*d[Z~I;,TW +ÖFj{;̩Mypp΁:8N SEzgQ68LBя5p޳! JPiv@eO>K,^Bk(,1vz'hc(9we}HeޕT"\>g>}!+;q^3õJbbXCIL!iLKy&X W+GH ?&qj@\Q!KTw95NIBnlIB!I$a4Dpe^b +EW1Q\RUES%,*Z5RB8$ *D"*yObrٍՓ !-ѕ ㈃Ɇ0j"zh (Z hHbݜa )i R/H1YÂQrfy  r&b*5L +DefIky8 .Jq5LAzf29B-Riԥ W"szyϭy-7kź |C/וٵXp/N!#TD$$Ļ{ wY5wGG9[mdb[]p fp|ɎَjCN!X;÷ _Z)>Үx NgՋ)]:Lq)g]?!8k8A7 v{5]>9;zIysz>elћ[ew_zppaHiJ/ރ>;HCNLh`D F`Cvr:{Հ/3SϷ+#3szO &t%xC׵@jRq%ua9 !!1t3t +98bØND p Ky;X +Z3v̡tI (AI L'61sb7+g=?/^,]#6Z566$JַdtfbBLX5v +.t r+ +(&wi [|=d+Y IQQ,EZSĉV*ن +Qjj7#|%:$bR>΍3*FAݤFm=v%b" ]xƾs}`oƀDW1e|Gm+$Ssxܶq )&ziqcaIeqIabr^tĹ5Kp\5Y.fhlYmqiyx@fKcӘ +ˡ;w]n&f"Y0Qdbh +ZC+` ~*n̰ۈbPP.Pd"џ1}b^9\.yW&;SvB?iIYKRft+`H3 'eO|^<̯cWVnA^\UwJTcqr61/'q~hs&;'ޚIw bX AcBX)B|6K1B>Cȿo^o G <63|ӌ4c0͔~0CͯroPM`KKV9uوA5F+?'cQ#-1"nZB J TFEӊZ3*7 +M%*Īu*r5I&g帾$aJ$\pe]!{sYk܀`!e`~$EWu'`6ɕR,Jm$Е6(gY8XNrt(a# xxrç% OjM"cH055qڂ׈d ֈ1`p`H$ (8 +L IXsZ-שX60_*7λJ<y {{:t$Jɉ#$&e?~ &liIKChoPkn5[5dk_#7K{LZ#T7S>|Q\tPtM3@۩$gΘhU\p$q|sS"5ZpPE1ܢ?DzC^?q]mten>i;U -!}aEib"=EW-y);A|,NVͤ蓛rƀ*:=˫@>~gOM '4̪7Һ<6+cKic +.5-D23/&ڨV}ܶż$M9JNY +l7XS9#:ocN3g//z40SFәTbeO,T*x鶟^X X4R8}E ?Z`e%8'RPJ | TŃrQL-Q9T5ϷH4-kӑrAJ;mf`ꤖ7jCq RU*ZcH]s=}*NIXN|D!~`&dKѥY;cu]s  pNZ<Ȯ4\[c1b 6I3s)kgl~hM1qg\;]ic +7R^ΟԜ_i!cZ1L091-bL:Gi;]4+/8TwhX1ciܱt ,\|6_q|v=v%]IǮ5u/O +Qs6k9/|qe=-.~şˊ+ΟԜ_iKƴeǴKb,O +qdIõ2BҴ{Ck3鑯hIW8Ky·cƀ]*wj$k4 в2VZ}"* Fr[e.[1C3:7=Д^OOTV,eW=ī^.5smj] ?b?X¿*[߰4d;مk 3͝3:Į^ 4z$NPq/dTJiెka3ԛ[JQxo^\9mp$_Rjq~{\*7U|"EYVC @m SIJڦE_ҬN%)\/򓍚w +C+i-γ:Td9:{΅K/ojifĒ…T rTVwxwwC}ĉJz :WXW ?]JөKB9F6? pyehOߢ QdI9ϝ7=&*#N/ÞlE=+KO!e+;Y³>!.z!] z6Y=|N ~s z)NBbџOw WJh^1@~C+'柰GݏJwg+Yf?| +NoX=p 5}zD[z}+<^K~╖C-Yܐ*{XߕF~zRÅ';hf37} T ޿)?x5oQy#YIβ-"K=խ=\F+n__zT|5ŧ O G[_m8em&4)׷T7Vї鋣f?T]OH@@ڎ=/{'XP|NտG +4[{B} {^Boѓ{p=ʆM }*U[E +,ƭ`ycF}z>9W<3%unJV\:r{N c[:E^e%*΂Z əm~AGuǽi{{Z*U%DWU 'JJ=ggv~t_:|a_| E{cde{w!vo5]oH͉>d,G#];hc䯀JD_p+.zy+r1n}~^p2!gY*6(ie>;fj* -X)IhK_s틒 \9} Y0'6=K'pň$|daAGV"%h%a톤뗀v[?U>yU6 |:n9GISrVy|u9~}nr'Y1,`;YEhը?nC(~9 !UByF"$#%x:[4S~;~8tFME%T/$D!fKsR*Œx85$9Ǹ1\^JN"_zHb滩u~X*7y-={ ̯֙}B'BygoܣqdgnpdlM0CtOO0d)w{zlOq0/mJ1K8d6QAGZ:ѽ 'p:"S [x.`ElvGx?0_b6?:qp;ڧ)^mN1p{Eg[mxbt^X}u|4f&>%Wн!\w7#7 b>;i LiY|\n 4ӈ/@)!@mxX4]ld¸}{pvp9`qMr9|N\G-Ar?}h`|u0V!m'4Nq>No.0)\;~W)nQ51`OI}<$zp9 l>D}+YNݏ]ׁPwY0~ߋȉW$2yGDzY4b[j{;ښSC6X` $Sj&"M3vqD^NZAS:V0H +wG6u~ 3F@3bo:냨n?8 +t# + ~h9hZr^֔8LiPN?|r~ƶ/sa~YqA-E϶0 +,G۔w؊=TЏ#Ay߲B}e-45=Z_ijLmQIM_bUZ5A?0r8_lccMGN"bMc +xucv|L632׶A`g +C׋ ~`q%r <ӡo۱dg3nB5x(B7,rs +1V=Cuø +:gvu, AI TvTTLt26 M[R)9U(XRrn@ZyZ me+vH|\V+,UXָba;?d!+.-7W,$tZ9BeG]Xϲ^nYP";9Hs=c\K`)Zqfl"p3aja, ܌[aЮ"dC_NUl;l$$~w@";)F@DmJRrSN&76fAT+~ @}%zv==V=[W3XNg)H +hѧljUm-z?A/n5[mmVJ{p_(0|wMiє6Я?C%`.QAmkBSx]N0QʫajohlU&fnÃsfd,>Op3]E1T яjV2ڃ-p uyGpodl`d/e>v +9]Aݩ6ٞGÃT{1H QlH':iуŏpa'D:__CEymkBT8x횉m0]HI!)$FR?6c>>~sm+vuՑνYu8uN?WP>1JsWiV_uKEϸ/rˆ_gKW]ױEYcl,[TYHT}xL#}A GV7^}>iҞ-i;}LJX&TP3T#ߨgJl e'=?͘ona|7>?ǐU%;/mN/IfQփz{G}?v✽3X~j{zTAO^ʰ>?sy|G)P׻gI@XjjgiЃ`0 `0 ?ϟ|:seQ3|ӧO|:2|.};7eGFO6_Qv]T]^ˮg{>pjzkuo{yye?{-x/ D:3D&򈼹e^Hyi#/OGzϪ߯_~ +:sMe#M3Y#=2 QЙ[\s=E8}E>GȩT ڲTg-}VfoSVwzV}./>~!?U1<#}=F[ ~QڋBN..+푹^edLo+[\-k dW(}6q$#?z6Bөi?L7!3O_Q}Пuo[=tkȋM!'}/Ƈdr2_Cﲨ: `0 :8o=+8-4}۞cĥXdq{bUq©ήm!ƶg*ΪU\z[GA=^+ru{LV U?)V>ғ)x|Yҁgi\yi^cUo*= !TY?rfgWsʽVn*VX#=Fϫ+[F~yH\L~[O҇h5ݵTow|Sfӟ+);F;:x )/OS yUo2e)Ve3'wgGg=J^`0  +ľu kU,Ksؑ5nY,bXw{ w&3QהNQev ]ƷgcH˞i{A3I8hwduwUIWq8I>+@pQşGcZ\ƪUߝ]/:3d;ɫ:gB9R|GW~w2;fzt|+i5nΟgZY|<1NyŬ|E7k?z/k><=Α}N΅>uWydʬdz `0 *\?W8GY:Dgcg< 2+'W6qn؟{ru"wU쏘~c#T?+y{Q,,^qF/Xv8.֩g3}ȸOP ~n%hUG4(_sn|W}Tg&x^c,Fѭ+ <#+}/Uw8BRh_|33!mr\7U9m({ѝpvew[xG]߱?g;,nҽow8]וb?OV=Z_#ve?vN_WrYLo;1g9pV^G~>[_vNOS3 `0Q[ veO\k^8֔v<Zbz\Opbn$~}oz3ј mK vU]^iNWA#x딫jt q :E= z%օq)CcYEqyRG-+u (K\hP'*^ء^q=m=y|Kvūe\rȊ4={W1;=ݷxp;o@>ȘT\Ԏ+C=*ɫ|GJOCW]x1.ﵠ9_Eб Vq)v(ʑ}[GwǺ{-oSdו_˞׃2;iT&w*w:g׭SOsj%Z[~_˯d֮+w]7 `0]kIu+eL]ւoA^;=GR?v쯱;<y o$N1紈=:ߥPVu< <&3KyC/4r)i=*/|Ύ^]QNН1qGw>ù{ ?Kv:A}E:_n+{u=rq͓̳]>>d}+|L01`0 leg:׺񶊝`W,3O?]\9P~[kOWiGc~)-<w.3q}'vuw$Vnv(r52S;Wk_Kϔ8B/hEՠ'9w?K;x:x<|@cϽVyc@ۖSw8Bq]=2lBe6V}eR( VeZT4ade2ޒ+nYBTqSߔ<[&=f[|szP)G}{Zׅ3n7jpWwftEw[ǽ;`l? `0 `0 `{~i`oLy>uoi\qK|}7Svu9G쯿c¾#>,jow{ՆݲL=mW2u_8دjo?kD߱mw>#}E:OۡO;y`$j?tU_mkBTsxځ @FhGpGpFpFqH=;OxkvmX*}\_q\>߇ǹ+!f4cӶ>saTڧ?Oլ}MΏ&w|-%_Xm9-׽^i٪nXg?WO@p~_<)el-Лz2IY +mkBT~x흍8 FSHI!)$FRHnw HYx3ꇤsaaaaxIǏ'U{o_ھgW9 o'GW {>~Jlo߾)*/N\ϱov[iZ_ձaJΝ/:6O- 92b?Tlk%?_21B sY5>:>c=1Ow y^- ڶ,XzusM#גU]>H_yYv!ۉ_mi Rus]Xm_g)YY)m]y,m z1aaaxEߓGקo/Y\k6xjgH|yu.\aæM&wk#ϐ$?]Mo\Ⱦ,/ڥQ@~6s?)}, l gX #vQg Bٙ^uのuhm?}{].~}v_J;xogJY]޳@.)oqC?}>@Xߘ'-(W? źvƔOʙRv[K?[A}?-wmՑ}g\=c}M ggg DŽ-B^k_g?F? v0||؎=ǧHPgs/hؑI t~{n^}ZyD5XWvO)"c0vY Z|~_%/,p\ɹyΰZ/;/xs_9?Pܯ5ݻ\[y|č8gʱL{? 0 0 _k3>z_\S |<)b|7aaaxn.ta?l^Cvkؽ#~e)3<3^kdlc&jK+o"e<.ʞ`^(3zu +l+6v<ï k7]/lc[`On}򚄫 G뎱zt^v2)?;Wmr5ocIz?Ozx{&!ez."ѯ 1Gg{+ҏlw<=}GݽFƨ^)zIpG K֜{{e G12ۭqiumf>.}~a? 0 0 [u+7Svq֭y΅ +?ނ}XwŶv?ߩDZۓ-q/?߳=<~#>Fk"qzrQo 9r,nY[;o:)@-`ק-7({߯S@µK9֠ɸ>:n3 +_[_*mtcmC>qSL=<6;ǫsaaa{xˌ\ފpx?0׋#5zяc]x^l򼠕(f:~٣^lin59W~\;?vn6erUbS~v^U O7O(|;+SG4|?f*?rW~2oNٟS9~daևmH6mX[J~s.ym4ٶO|Bd/b5ɿyU? 0 0 0 0 0 0 0.P~*1@G\⟿KrKXs2(ߥ纎J8'>X@▼QQbqwx b)_K|v 1M6kee-2Ǜ59?K^E~9ϱQﱮYF8N?~;:=J<-tĒyNAgC \NXKs)'^Kg\~2}6}Գ)n]Or^j~"{p29w6/.z-v:+M{WJYZ굢`% Ҥl9ힶկ#OUz+U?;sd~vND7*.Y+v:ye;8}~|+ÑޅN9}{Bƞ#txխsXɿkSV/uJ=o G<ջL'L:D]6jfgLz/+ؽ[{rCMYq~[{yy czA;w9zszWHVax3 ף2iTXtXML:com.adobe.xmp + + + + Adobe Fireworks CS6 (Macintosh) + 2012-11-14T20:41:31Z + 2012-11-14T20:43:14Z + + + image/png + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +̷qOIDAT8 0 /Ul@FLp}q I s8T{@bH2l-(K2|R VΉ@]ٷ + x3 +`f]jBv!9|oKg|f?render(); +} + +/** + * Page callback: Presents the display editing form. + * + * @see display_menu() + */ +function layout_master_edit(Display $display) { + drupal_set_title(t('Edit layout @label', array('@label' => $display->label())), PASS_THROUGH); + return entity_get_form($display); +} diff --git a/core/modules/layout/layout.admin.js b/core/modules/layout/layout.admin.js new file mode 100644 index 0000000..aea15c1 --- /dev/null +++ b/core/modules/layout/layout.admin.js @@ -0,0 +1,67 @@ +(function ($, window) { + +"use strict"; + +/** + * Attach display editor functionality. + */ +Drupal.behaviors.displayEditor = { + attach: function (context) { + + function serializeBlocks() { + var regionBlocks = {}; + $('.layout-region', context).each(function() { + var pattern = new RegExp('layout-region-.+'); + var classes = $(this).attr('class').split(' '); + + // Look for the class with the region name. + for (var i = 0; i < classes.length; i++) { + if (pattern.test(classes[i])) { + // Store the block order for this region. + var regionName = classes[i].replace('layout-region-', ''); + regionBlocks[regionName] = []; + var blocks = $(this).find('.region-blocks').sortable('toArray'); + for (var j = 0; j < blocks.length; j++) { + regionBlocks[regionName].push(blocks[j].replace('block-', '')); + }; + break; + } + }; + }); + $('#edit-regions', context).val(JSON.stringify(regionBlocks)); + } + + // Attach click handler to add block button. + $('.region-table .add-block', context).once('display-add-block', function() { + $(this).click(function () { + // Generate a random block title until we can fire blocks as plugins + // in a modal that will give us a machine name and a title to place. + var chars = "abcdefghiklmnopqrstuvwxyz"; + var randomString = ''; + for (var i=0; i < 8; i++) { + var rnum = Math.floor(Math.random() * chars.length); + randomString += chars.substring(rnum,rnum+1); + } + + // Add HTML code for block demonstration. + var block = '
M' + randomString + ' block
'; + $(this).parent().prepend(block); + + serializeBlocks(); + }); + }); + + // Apply drag and drop behavior to all blocks in all regions. + $('.region-blocks', context).once('display-sort-blocks', function() { + $(this).sortable({ + items: '.block', + connectWith: '.connected-sortable', + cursor: 'move', + update: serializeBlocks, + }); + $(this).disableSelection(); + }); + } +}; + +})(jQuery, window); diff --git a/core/modules/layout/layout.module b/core/modules/layout/layout.module index c6ed7ae..e2341b8 100644 --- a/core/modules/layout/layout.module +++ b/core/modules/layout/layout.module @@ -5,10 +5,13 @@ * Manages page layouts for content presentation. */ +use Drupal\layout\Plugin\Core\Entity\Display; + /** * Implements hook_menu(). */ function layout_menu() { + // Layout template demonstration. $items['admin/structure/templates'] = array( 'title' => 'Templates', 'description' => 'Overview of the list of layout templates available.', @@ -25,6 +28,24 @@ function layout_menu() { 'access arguments' => array(4), 'file' => 'layout.admin.inc', ); + + // Master layout editing. + $items['admin/structure/layouts'] = array( + 'title' => 'Layouts', + 'description' => 'Overview of the list of layouts available.', + 'page callback' => 'layout_master_list', + 'access callback' => 'user_access', + 'access arguments' => array('administer layouts'), + 'file' => 'layout.admin.inc', + ); + $items['admin/structure/layouts/manage/%layout_master'] = array( + 'title' => 'Edit layout', + 'page callback' => 'layout_master_edit', + 'page arguments' => array(4), + 'access callback' => 'user_access', + 'access arguments' => array('administer layouts'), + 'file' => 'layout.admin.inc', + ); return $items; } @@ -80,3 +101,50 @@ function layout_theme($existing, $type, $theme, $path) { } return $items; } + +/** + * Entity URI callback. + * + * @param \Drupal\layout\Plugin\Core\Entity\Display $display + * Dispaly configuration entity instance. + * + * @return array + * Entity URI information. + */ +function layout_master_uri(Display $display) { + return array( + 'path' => 'admin/structure/layouts/manage/' . $display->id(), + ); +} + +/** + * Load one display object by its identifier. + * + * @todo Remove once not needed for layout_menu(). + * + * @return \Drupal\layout\Plugin\Core\Entity\Display + * Display configuration entity instance. + */ +function layout_master_load($id) { + return entity_load('display', $id); +} + +/** + * Implements hook_entity_info_alter(). + * + * Add URI callback to Display config entities to support listing API. + */ +function layout_entity_info_alter(&$entity_info) { + $entity_info['display']['uri_callback'] = 'layout_master_uri'; + $entity_info['display']['list_controller_class'] = 'Drupal\layout\DisplayListController'; + $entity_info['display']['form_controller_class']['default'] = 'Drupal\layout\DisplayFormController'; + $entity_info['display']['list_path'] = 'admin/structure/layouts'; + $entity_info['display']['entity_keys']['label'] = 'label'; +} + +/** + * Ajax callback for block placement display switching. + */ +function layout_ajax_block_placement_callback($form, &$form_state) { + return $form['blocks']; +} diff --git a/core/modules/layout/layouts/static/one-col/one-col.tpl.php b/core/modules/layout/layouts/static/one-col/one-col.tpl.php index 61af832..529eb06 100644 --- a/core/modules/layout/layouts/static/one-col/one-col.tpl.php +++ b/core/modules/layout/layouts/static/one-col/one-col.tpl.php @@ -12,7 +12,7 @@ */ ?>
> -
+
diff --git a/core/modules/layout/layouts/static/twocol/two-col.tpl.php b/core/modules/layout/layouts/static/twocol/two-col.tpl.php index 810a052..ab59cac 100644 --- a/core/modules/layout/layouts/static/twocol/two-col.tpl.php +++ b/core/modules/layout/layouts/static/twocol/two-col.tpl.php @@ -14,11 +14,11 @@ */ ?>
> -
+
-
+
diff --git a/core/modules/layout/lib/Drupal/layout/Config/DisplayBase.php b/core/modules/layout/lib/Drupal/layout/Config/DisplayBase.php index afe3229..cac0407 100644 --- a/core/modules/layout/lib/Drupal/layout/Config/DisplayBase.php +++ b/core/modules/layout/lib/Drupal/layout/Config/DisplayBase.php @@ -135,4 +135,22 @@ public function getAllRegionTypes() { } return array_unique($types); } + + /** + * Implements DisplayInterface::export(). + */ + public function export() { + // Start by exporting the public properties. + $class_info = new \ReflectionClass($this); + $properties = array(); + foreach ($class_info->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) { + $name = $property->getName(); + $properties[$name] = $this->$name; + } + + // Now, add protected data - the blockInfo array. + $properties['blockInfo'] = $this->blockInfo; + + return $properties; + } } diff --git a/core/modules/layout/lib/Drupal/layout/Config/DisplayInterface.php b/core/modules/layout/lib/Drupal/layout/Config/DisplayInterface.php index 871aadc..c40e699 100644 --- a/core/modules/layout/lib/Drupal/layout/Config/DisplayInterface.php +++ b/core/modules/layout/lib/Drupal/layout/Config/DisplayInterface.php @@ -50,7 +50,7 @@ * @return array * An array keyed on each block's configuration object name. Each value is * an array of information that determines the placement of the block within - * a layout, including: + * a layout, including but not limited to: * - region: The region in which to display the block (for bound displays * only). * - region-type: The type of region that is most appropriate for the block. @@ -82,4 +82,11 @@ public function mapBlocksToLayout(LayoutInterface $layout); * region types were assigned. */ public function getAllRegionTypes(); + + /** + * Returns this display as an array suitable for permanent storage. + * + * @return array + */ + public function export(); } diff --git a/core/modules/layout/lib/Drupal/layout/Config/DisplayStorageController.php b/core/modules/layout/lib/Drupal/layout/Config/DisplayStorageController.php new file mode 100644 index 0000000..cc86f93 --- /dev/null +++ b/core/modules/layout/lib/Drupal/layout/Config/DisplayStorageController.php @@ -0,0 +1,25 @@ +export(); + } +} diff --git a/core/modules/layout/lib/Drupal/layout/DisplayFormController.php b/core/modules/layout/lib/Drupal/layout/DisplayFormController.php new file mode 100644 index 0000000..eb18b3f --- /dev/null +++ b/core/modules/layout/lib/Drupal/layout/DisplayFormController.php @@ -0,0 +1,177 @@ +get('plugin.manager.layout')->getDefinitions(); + $layout_options = array(); + foreach ($layouts as $key => $layout) { + $layout_options[$key] = $layout['title']; + } + $layout_keys = array_keys($layout_options); + + // Add default values to form_state['values']. + if (!isset($form_state['values'])) { + $form_state['values'] = array(); + } + + // Recreate simple region structure for form communication. + $regions = array(); + $existing_blocks = $display->getAllSortedBlocks(); + foreach ($existing_blocks as $region => $blocks) { + $regions[$region] = array(); + foreach ($blocks as $block_id => $block_info) { + $regions[$region][] = str_replace('block.', '', $block_id); + } + } + $form_state['values'] += array( + 'layout' => isset($display->layout) ? $display->layout : reset($layout_keys), + 'regions' => $regions, + ); + + $form['layout'] = array( + '#type' => 'select', + '#title' => t('Layout'), + '#default_value' => $form_state['values']['layout'], + '#options' => $layout_options, + '#ajax' => array( + 'callback' => 'layout_ajax_block_placement_callback', + 'wrapper' => 'display-blocks', + 'method' => 'replace', + 'effect' => 'fade', + ), + ); + + // To support the Ajax interaction, remap the display to the newly selected + // layout. This will reorganize the blocks as appropriate. + if (!isset($display->layout) || ($form_state['values']['layout'] != $display->layout)) { + $layout = layout_manager()->createInstance($form_state['values']['layout'], array()); + $display->remapToLayout($layout); + } + + // Add block editing interface wrapper for Ajax operation. + $form['blocks'] = array( + '#prefix' => '
', + '#suffix' => '
', + ); + $form['blocks']['demonstration'] = $this->layoutDemonstration($display); + $form['blocks']['regions'] = array( + '#type' => 'textarea', + '#default_value' => drupal_json_encode($form_state['values']['regions']), + ); + + return parent::form($form, $form_state, $display); + } + + /** + * Produces a render array demonstration form of the display. + */ + private function layoutDemonstration(EntityInterface $display) { + + // Render the layout in an admin context with region demonstrations. + $layout = layout_manager()->createInstance($display->layout, array()); + $regions = $layout->getRegions(); + foreach ($regions as $region => $info) { + $region_text = '
' . check_plain($info['label']) . '
'; + $region_text .= '
'; + $existing_blocks = $display->getSortedBlocksByRegion($region); + foreach ($existing_blocks as $block => $placement) { + $region_text .= $this->layoutBlock($block); + } + $region_text .= '
'; + $regions[$region] = $region_text; + } + $build['demonstration'] = array( + '#type' => 'markup', + '#markup' => $layout->renderLayout(TRUE, $regions), + ); + $build['#attached']['css'][] = drupal_get_path('module', 'layout') . '/layout.admin.css'; + $build['#attached']['js'][] = drupal_get_path('module', 'layout') . '/layout.admin.js'; + $build['#attached']['library'][] = array('system', 'jquery.ui.sortable'); + return $build; + } + + /** + * Temporary implementation of block markup generation. + */ + private function layoutBlock($block_id) { + $block_id = str_replace('block.', '', $block_id); + return '
M' . $block_id . ' block
'; + } + + /** + * Overrides Drupal\Core\Entity\EntityFormController::actions(). + */ + protected function actions(array $form, array &$form_state) { + // Only includes a Save action for the entity, no direct Delete button. + return array( + 'submit' => array( + '#value' => t('Save'), + '#validate' => array( + array($this, 'validate'), + ), + '#submit' => array( + array($this, 'submit'), + array($this, 'save'), + ), + ), + ); + } + + /** + * Overrides Drupal\Core\Entity\EntityFormController::save(). + */ + public function save(array $form, array &$form_state) { + + // Create the block information array needed for the display object. + $blockInfo = array(); + $new_blocks = drupal_json_decode($form_state['values']['regions']); + + // Region type information is derived from the selected layout. + $layout_regions = layout_manager()->createInstance($form_state['values']['layout'], array())->getRegions(); + + foreach ($new_blocks as $region => $blocks) { + $weight = 0; + foreach ($blocks as $block) { + $blockInfo['block.' . $block] = array( + 'region' => $region, + // Increase weights by 100 so they are far enough apart for + // page block placement. + 'weight' => ($weight += 100), + 'region-type' => $layout_regions[$region]['type'], + ); + } + } + unset($form_state['values']['regions']); + + // Build and save the new display with the new block information. + $display = $this->getEntity($form_state); + $display->set('blockInfo', $blockInfo); + $display->save(); + + watchdog('display', 'Layout @label saved.', array('@label' => $display->label()), WATCHDOG_NOTICE); + drupal_set_message(t('Layout %label saved.', array('%label' => $display->label()))); + + $form_state['redirect'] = 'admin/structure/layouts'; + } + +} + diff --git a/core/modules/layout/lib/Drupal/layout/DisplayListController.php b/core/modules/layout/lib/Drupal/layout/DisplayListController.php new file mode 100644 index 0000000..b07e7ee --- /dev/null +++ b/core/modules/layout/lib/Drupal/layout/DisplayListController.php @@ -0,0 +1,63 @@ +uri(); + $operations['edit'] = array( + 'title' => t('Edit'), + 'href' => $uri['path'] . '/edit', + 'options' => $uri['options'], + 'weight' => 10, + ); + return $operations; + } + + /** + * Overrides Drupal\Core\Entity\EntityListController::buildHeader(); + */ + public function buildHeader() { + $row['label'] = t('Layout name'); + $row['applied'] = t('Applied to'); + $row['template'] = t('Template'); + $row['operations'] = t('Operations'); + return $row; + } + + /** + * Overrides Drupal\Core\Entity\EntityListController::buildRow(); + */ + public function buildRow(EntityInterface $entity) { + $row['label'] = check_plain($entity->label()); + // @todo: refer back to pages using this display. + $row['applied'] = $entity->id() == 'front_master' ? t('All front end pages (master)') : t('All admin pages (admin master)'); + $layout = drupal_container()->get('plugin.manager.layout')->getDefinition($entity->layout); + $provider_info = system_get_info($layout['provider']['type'], $layout['provider']['provider']); + // Type can either be 'module' or 'theme'. + $provider_text = t('@name @type', array('@name' => $provider_info['name'], '@type' => t($layout['provider']['type']))); + $row['template'] = check_plain($layout['title'] . ' (' . $provider_text . ')'); + $operations = $this->buildOperations($entity); + $row['operations']['data'] = $operations; + return $row; + } + +} diff --git a/core/modules/layout/lib/Drupal/layout/Plugin/Core/Entity/Display.php b/core/modules/layout/lib/Drupal/layout/Plugin/Core/Entity/Display.php index d954832..bd3e52d 100644 --- a/core/modules/layout/lib/Drupal/layout/Plugin/Core/Entity/Display.php +++ b/core/modules/layout/lib/Drupal/layout/Plugin/Core/Entity/Display.php @@ -21,7 +21,7 @@ * id = "display", * label = @Translation("Display"), * module = "layout", - * controller_class = "Drupal\Core\Config\Entity\ConfigStorageController", + * controller_class = "Drupal\layout\Config\DisplayStorageController", * config_prefix = "display.bound", * entity_keys = { * "id" = "id", @@ -117,7 +117,7 @@ protected function sortBlocks() { foreach ($regions as $region_name => &$blocks) { uasort($blocks, 'drupal_sort_weight'); - $this->blocksInRegions[$region_name] = array_keys($blocks); + $this->blocksInRegions[$region_name] = $blocks; } } diff --git a/core/modules/layout/lib/Drupal/layout/Plugin/Core/Entity/UnboundDisplay.php b/core/modules/layout/lib/Drupal/layout/Plugin/Core/Entity/UnboundDisplay.php index 5450e2c..ed7591b 100644 --- a/core/modules/layout/lib/Drupal/layout/Plugin/Core/Entity/UnboundDisplay.php +++ b/core/modules/layout/lib/Drupal/layout/Plugin/Core/Entity/UnboundDisplay.php @@ -24,7 +24,7 @@ * id = "unbound_display", * label = @Translation("Unbound Display"), * module = "layout", - * controller_class = "Drupal\Core\Config\Entity\ConfigStorageController", + * controller_class = "Drupal\layout\Config\DisplayStorageController", * config_prefix = "display.unbound", * entity_keys = { * "id" = "id", diff --git a/core/modules/layout/lib/Drupal/layout/Tests/DisplayInternalLogicTest.php b/core/modules/layout/lib/Drupal/layout/Tests/DisplayInternalLogicTest.php index 07a77bf..16922f8 100644 --- a/core/modules/layout/lib/Drupal/layout/Tests/DisplayInternalLogicTest.php +++ b/core/modules/layout/lib/Drupal/layout/Tests/DisplayInternalLogicTest.php @@ -64,8 +64,13 @@ public function setUp() { */ public function testBlockSorting() { $expected = array( - 'left' => array('block.test_block_3', 'block.test_block_1'), - 'right' => array('block.test_block_2'), + 'left' => array( + 'block.test_block_3' => array('region' => 'left', 'region-type' => 'content', 'weight' => -100), + 'block.test_block_1' => array('region' => 'left', 'region-type' => 'content', 'weight' => 100), + ), + 'right' => array( + 'block.test_block_2' => array('region' => 'right', 'region-type' => 'aside', 'weight' => 0), + ), ); $this->assertIdentical($this->twocol->getSortedBlocksByRegion('left'), $expected['left']); $this->assertIdentical($this->twocol->getSortedBlocksByRegion('right'), $expected['right']); @@ -84,7 +89,11 @@ public function testBlockMapping() { // Remap from twocol to onecol. All blocks are expected to move to the one // and only region and be sorted by their original weights. $expected = array( - 'middle' => array('block.test_block_3', 'block.test_block_2', 'block.test_block_1'), + 'middle' => array( + 'block.test_block_3' => array('region' => 'middle', 'region-type' => 'content', 'weight' => -100), + 'block.test_block_2' => array('region' => 'middle', 'region-type' => 'aside', 'weight' => 0), + 'block.test_block_1' => array('region' => 'middle', 'region-type' => 'content', 'weight' => 100), + ), ); $two_to_one = clone($this->twocol); $two_to_one->remapToLayout($this->onecol->getLayoutInstance()); @@ -94,7 +103,10 @@ public function testBlockMapping() { // region type, and twocol's 'left' region has that type, the blocks are // expected to move to there and be sorted by their original weights. $expected = array( - 'left' => array('block.test_block_2', 'block.test_block_1'), + 'left' => array( + 'block.test_block_2' => array('region' => 'left', 'region-type' => 'content', 'weight' => -100), + 'block.test_block_1' => array('region' => 'left', 'region-type' => 'content', 'weight' => 100), + ), 'right' => array(), ); $one_to_two = clone($this->onecol); @@ -110,8 +122,13 @@ public function testBlockMapping() { // region with that type, so it is expected to be mapped to twocol's // first region, which is 'left'. $expected = array( - 'left' => array('block.test_block_1', 'block.test_block_3'), - 'right' => array('block.test_block_2'), + 'left' => array( + 'block.test_block_1' => array('region-type' => 'content', 'weight' => -100, 'region' => 'left'), + 'block.test_block_3' => array('region-type' => 'nav', 'weight' => 0, 'region' => 'left'), + ), + 'right' => array( + 'block.test_block_2' => array('region-type' => 'aside', 'weight' => -100, 'region' => 'right'), + ), ); $unbound_to_twocol = $this->unbound->generateDisplay($this->twocol->getLayoutInstance(), 'unbound_to_twocol'); $this->assertTrue($unbound_to_twocol instanceof Display, 'Binding the unbound display successfully created a Display object'); diff --git a/core/modules/layout/plus.png b/core/modules/layout/plus.png new file mode 100644 index 0000000..b5544c1 --- /dev/null +++ b/core/modules/layout/plus.png @@ -0,0 +1,204 @@ +PNG + + IHDRasBIT|d pHYs  ~tEXtCreation Time11/14/121tEXtSoftwareAdobe Fireworks CS6輲prVWxMhAHQO"J4T-֞I-ؐ]= < <'O⡞EWnf?fwgM$Iyd;yۼvPm6F^W*ٓ?cdlz^lc#~# r_-_6Vv_3 >t_8[vh=I5FcZuljC>XZmw:sLaeN_+xg׬Nm54>dhIuۨ8{qff9V-8+˞?_(㹴ާ;Dg^L]4+<#yDZ^;wR+eҚk>0'?#8G÷;)7ֳͩ%sOFw$wO&!-cG=^K}GqClx6' 9r=`:ZX"nT{ c>kr--".O>㦞:ӵJz9RYltu=so9ֹ~<ԋ.NH*(8&'ǯD%XiGxfPdUu.ɴs͟i=cǟ=gwĿ_?!/;~=7W|W|W|W|ŗ',~\ůq___o$G |oH?~&]/aψ>C3 ~C5 7Nj}&o:_d <?]u[?h5])rLicJ>%(CH|:ԯ=Դ8lHmkBF)3Q^zC:NKCv?v8ZayXtuMؠC.pü6 G6Ufi?B8\D{4Ϭ? і?!:72fqvs@ ?Z9VsB zGi J6c1| =}Lg !!d2̹3x8a2 ǬsL`xc8 #陡-HšǓPNl%]_z8P7{\Z݊([^y {f}M5V趖ʐ$>@$=pXΰ4ii;tsʠ' ق +5k+]1ȪOg+i1[HeM:*En!FpB6EHTRZ!uL]ibwg0\Ji +*&Yvᣯgf75@NЦH +=K'RoNʫ`3cj;wJxn Hj#9 4ߔB3 ?r=QȀ8d,G$7fYf!w.KcF;A\L0j,!f 3qƬ,'E4'z>ǖΠcN@t/V h,]3r*>tdV +9%2tZ V`] ~{BW1f_ہ*HlbH&ZE( EbR-gh< qG+^k^L] Fg9AOT(Ӌ ie1Yԙq/h>94lW.upU$pF6 \U WHR{c0⤯3pO>W,x51+:i|HP4*FeШ  4*gcʫOϾdB֍({׫uSg8J0bLb0 &Jm42B(9_!4S΋beL͚lPN~.'79k3lfH6v`zMءHaKHj̐e~SvFŢqwtEoYĨu*m>z`,jׇ$T)dJy;f[{,ah\A7 B`}:)ѝ=G +my֕[uqz3y0kB~:Xjx,,n3߇<rH xpb.#b{8d*#\iʘ T:хڔLja2Xm̀ vb:~b%`}q:pL~n%B !yהX>aaOG4CQ4 0))~Qx^RL\Im +[ƈ3+C mӼ FBL<̗cfE-4LО +k88F~}8EgqGE, +5d:CN<)%|)?C@;'}JqE Pz ?'43̝X,f?w`)sgmI51f!POc Zc1Hz/XxprOV '?2 턡MjQsE3S„F荰n/pp66L7"̙m? #öFAIc\lHez@ D؟32y_8rҐQN`,{z֣y\Eu+zAdB!+o!,ej0l1tK@ؐԨaSU_ ㄩs5AG{W86IN+,.jq6̟4|a b acH(.. ѱs}+]gׄl12L'aiZ/h5X)O10dPfU)10/{+ + Czc(in4ԇt:s3{tЅ %f'-]i+d+0*ǜzGG2}P5)q' $Q,lےX>t' =2sFL:zCD:h3j+^`Ev%ދ59hg_h_y^߾o:'M<cQvA>CxsգyWjMW$+R-a0Y4`vc~IVa+ +􂺯6bKJJC-;>IG w"@=(qi.nDL]M ˍrz?ߓ+[$uvq i[E 230iZ'! _٦HEi )0XbkJW@_ DAIS ?2$6MFKq0O +?q)< ~d`oSNV-eb ڒ\R5xu8pDǷN,IҊL2~}ӀGbq( wYD8hN- $51n1zŽa ,mN0E8V!؄*ESNRSUIgU^PPI01xx|7Qg/z{O|Xz+*#I߿i1M}DwCo@~#ߐԨhJ5L|F- +{7&h ,I<2`+N/q E&j4Z7Ld =S@QՒ riMդf1Yn <񯟤\&&Z #`,p')׫ fBkU}.].DzQ>,Inj"m1jVm.6^3^BWk5UA\[S=m0EÔj2Mk`{F?g/~rfLhZh7Y hIFZ5zL^bm)cKyMS{=bINzJj+oBZNaxvGQ(lzi26_~_>{_6뒦MLpEXoMѩ>H`}CXnVZ5Z^x/yZ$l6n5qL6DpIXkTH16G`⊨a*j MG#ԞxAjc4Q04)TaRyʘ%EE)ꮪ-Yu-`h420YQTkTnt7$kޢK嘿U~DoJɥz,0^]"ө3B`ֆWfy'ngNh*3G+{HoF;P?kI E_Uѕ'6p )*Z 5Hy[a; ?5N$3N`bGrkΙi*Pf +ZG:ݽp5)uO/yEz;*w0b% "/?RO_.oriH"Va-/g )h#9i%i؎^lKV[^'KcO&oAy5k(>ŒE~;ܥ;)Y#R+d%#5GZ(|F8$^ނ|`6ICw?jyTKn%~-o@091< .{[[ZN ʟr7º%.w8CJk9zm]st%G ]3ڨf蚡 0m=↓ٹf祳5;\s;i\m;|vjvٹfэ!>W3tfF5C ]P8x~9es^sv5g-vV30tf/C C+jW]st+YyW3&0tf蚡0׵fM`z]5;ac]Λʻkv.zV ]f" ]9{38^yWsv!gw!Dg2kl~p?{!lŢw܉[g޼)pC4o53ZHV{>mt6>|u|]Z?cm{-:\"q㋟3IEEDvg>GKTvmO#h߀3Bfh֬f蚡Xb~ȧ4ƤMb&3pH:g-ϻcTHmΈwM+>¯\{ۆsn ++2 ^³Ή!Oˠ~8_[m-h{W[*hɽŔ,>R{4FHބ_e1i4`GŔ, W1)Ӗ*w'v7?mzN٠kHǐ]!+"wXe匔 +P7q d +Gjv{Eg<+S Z"yk +r};5d)G0%| zx\ϕ_ľRN1eDwL= -^iL]TeT.GE2[l!cIɗtkD{Rҕ-!}v&{̺AK[VY{I_+e*x\oF&JSҬ˂O_)[FGZ*'>)bQJ_)}i%e{ A!Hy9"c}v"a d/A#iX?N Fce!1*X#bi0~7~i\){mEJ>GyxCyh'lsEm\m36Ndk{lO0Ůy\=Yrw]v߅ގڄ7~57MksmpmYw+͊cSBLPO(rZFƍeZY9[ ъ>V|,}梱f]JE؊̷ClRRhMEkpU+Z6pWde|Iygo#ϏOr UKZ6}mh%5aa mH{ SNLbzdEkc FcjUļogs4B=o- ĔuqۘAܘ#N'mUhAz {vY?,*|9)?vFvFb=sC-҇fWHo*e$ī]6c7!k_lP{GOXvJ* ƽs/ $ k"uek SFˬKBpVgÔ6#Qil)F E;տ8hFl5R?W1i(-뿭}.}Ӌ+Q#Q&&iUٕRא͚{ }Amʮ 9 </^>'\\swbOe(!~ +=_ombw;'-BilrV6 v&Į}׏#DK]LE// O7!wcSF)l w7Gs&5NxYv/h'l'lrq5.{Ծe`?b IFw}vp;;: g  yvma0{<`tiS3Vn㵾s.;jo9bsait?:ěXGRgEw~sŃ.d:{B +[.Н~M &ENҚq}%x/?YT6zJ_nz OIFC 8z +GҦ#ΠW1;=]Q +5~ѠQvT3;"'j0"@; Y`6T)* MPM0k\BaD H#ϺsG@Rᅓ!>AĈ.Yr~ :t(an=pG:[v~}||eSn! Rٳg FtmO}8PO<5of|?댟1ԏE3ឝ%}hgz{OQy5>w~$Ogi1M}[pn'9A?x ã.柵)tSgsdjCU8d9>vL4Ԗf@\Սm|mBNH07mT>rxn~AyA%QSX95^Μ꬜YWԚ*lLr6VjPҞ6=R[ٚ6 N킵$9U/8 +UNYUTfD̤S8$x0t?>Emּ{B#YW$ 7CzcH~nqs+$Uvtc_ve W{82sLCFF7`auA=GCDZCF|cиCfvt"?,j5<&g]>ڴȶDSy TeS;&MS.ұsZVM(`jށ*3{!qO>]䐍fmg97`W{HAG{$ aLmfG#=ݏvGX+~5NXt :4l= < `0Paqi?B %n=gVh՟ꏈQ Z3F8F;sZT:dc;OdPz.>Gcq7c:CHg !!dΝ &Uǁ1\8fpcPûC W陡-HšǓPNl%]_z87? +OJVSV3 +Ӿnft[KeH [va, [gXൗ.C7 :{-ȠPK"*@~&H qT$Zb'dSĉj @%u+U;&̰T3X=[젺=cK):MA#.â1| ڌvxX2}#hS'T9^>"&~sR^SYSue@PS[ЍJ!FN9ў(dmHI#3K,Kߎ;e1#ם u.[&Xn5 pg38hdcV@ne|cKg1 a +Scxn+O$]3r*>tdV +9%2tZ V`] ~{BW1f_ہ*HlbH&ZE( EbR-gh< qG+^k^L] Fg9ьDL/.ŬgZRgƁzp0:Ұ'_=ԙ_U^E؀pV1\#)J] +5{#NpJ-Nq +pzOVĬ!AeШ A2hԂ<)>qWW?EFCbY7}v2{`L.e0RۿG{_.i>pDp6ߋ+`14kVdA:p͠#ءHaKHj̐e~SvFŢqwtEoYĨu*m>z`,jׇ$T)dJy;f[{,ah\A7 B`}:){~wrYWn d +6RcgU8X|tva#k4c‰>`VFw\%y.щ]RdeLL\AB|mcDl0Au6fNl;E? Β~i0>).f!N'ҭ~cZ~!D9+1g2@"hБf(JA&E2/ +^w[Oj-4wV"%0FYoZ(n,1Pg1d6+oa0ڞq? | ɂ0<$͘sk_:s& eԐa:KGZ|QG"EsM̅x:7;AIVUۧĈ|H*,{z]Ѻ&PRR} %>BZ7XƖ9N +ttI LHs^w4P$7oq [ay[>".7qHBf-1 NwB_1t)ȇL׹tf22V +ٽyDoދ59hg_h_y^߾o:'M<cQvA>CxsգyWjMW$+R-a0Y4`v`7.[A_* 꾾Նhu:XIiHe'D%sR O5Ln- +K @'x?$#M&@ zVv =S@QՒ riMդf1Yn <񯟤\&&Z #`os^?I^Mh6] sw| ҋ/d9NrsTiUHosi."B}PZM\&I- + +B9lχ)?TݔnZ#3}8ORWڌ mV  ; ;M;H&@ ЋU^M!]k}OrҫURcbmؗ1WѫR]fK Y`\y׽ESg1 8<,N*݁su ]ţ=h7k7w;O/XCz+ځe\+MJm(E ;OxmJZRT(gjgS6*#w"9V*gQ,Hn=92M]= N;Hg/}{G.F=z9Gj~ %mS.-SqIC*,0ZyCc,G +#9i%~)M(vkt:d^򟀿5'*?yL{4Q~ ʫ_C,)}/+. F)-thZ!+..2.'5!]$1Vr^G#IjҼTxo9S5V,?=Œb\7MmoA'S?kQf;Gl+nG8(;oqv~A};[5;\sPafe3tf蚡k.?pv;X~ZOo9es^sv5g#]3tKghkkkfh&+ﴚ7w5;jM[yW3&0tf蚡0׸Mz]5Gq|+jvvW\s׳fM`z]5Caz]ٛʻk.cU=+jW ]3t]ȅgv@wxZ-[o-ń)^[gk`݉[g޼)pC4o53ZHV{>mt3"|Tt!Dkvi]CkD׶#Zs}Ø_:cCИt[Ti?_KTlǺ-zhjB߮-t~)0t0pF~ -ښ5C ]3t+X,CTfrØ][_D;]~jZ︰o=FVW al36qG>46f;qlQH衹=M U<Jh¯ kax%:^PeREROC=(v7 &40_J $9h=4RSC1;FCݛB +k{mm3<csb=ˠ~'/x-j6 +z =E+ӂ1[m!ƴh,HEo=&{qh.Lx#6 Xg +BlD/g H!%^+ej˼VߠVb\8|YI#?e WVT+aORZ볟">zx`͝XRVPDݍ|1+q k/'} O{ "IwbHЖ5JbA /_yL7}d1{Xi1c}E;4pw9$s,)Z.𛒽l"ܽHuʝȷms߬ӘNdoMu)< 17(qVOrVWZdIކ|S;ɨV$43[)o+Ű,`cX@8uCrF}b7@~9;kea'Fy{ȻDZu]X٧>[| &!Ŀ +-V!dkW!V(eyw S$OHBg۱%bwccF%|ٺd6|E`q5Ϸd M"L2R[ao'_zDDtWFſT?_$P"$-K?3~/ڪ~/^U6r.Oy<,fᚅ< *c`gtuϮ=Oyϼ7X{k{ȕĕax| ۣsxvZ]2}v8:}2S N5HҠ?jA|Nvtp63{}zo][xt1; ^9Dž.;~sԌsx}qn=wX&#nvQґOO{xp؅L˝)*о < w~NҚq%x.¿㞃.BO㽤svT3nnz OIFC 8z< nצ~ΚW1;=]#G{*pQGG7SEpj;iSwjwκWȻVX}+ca9%At`']K6 v}v4P")uxᢕ;pK Ss@NcN/qObex>raz}Cɻ}x`\H'&Dip`T2`\]%('9Έ{A C9OϨ/O<-68| 0.#IdӞczhYOs#G]?kiS#φç w4p Ɇs|`™f=i-̀<=) 084>]@E'o;ʩJ-} +tzܢxEmּ{B#YW$ 7CzcH~nqs+$Uvtc_v=8 l)%;_:lpN|G΋k5Gך5)̻4--f``oVҘf[Y^wS܃&W׈+ +*F\_W ~t_.=ruie3s̛mkBSx]N0QʫajohlU&fnÃsfd,>Op3]E1T яjV2ڃ-p uyGpodl`d/e>v +9]Aݩ6ٞGÃT{1H QlH':iуŏpa'D:__CEymkBT8x횉m0]HI!)$FR?6c>>~sm+vuՑνYu8uN?WP>1JsWiV_uKEϸ/rˆ_gKW]ױEYcl,[TYHT}xL#}A GV7^}>iҞ-i;}LJX&TP3T#ߨgJl e'=?͘ona|7>?ǐU%;/mN/IfQփz{G}?v✽3X~j{zTAO^ʰ>?sy|G)P׻gI@XjjgiЃ`0 `0 ?ϟ|:seQ3|ӧO|:2|.};7eGFO6_Qv]T]^ˮg{>pjzkuo{yye?{-x/ D:3D&򈼹e^Hyi#/OGzϪ߯_~ +:sMe#M3Y#=2 QЙ[\s=E8}E>GȩT ڲTg-}VfoSVwzV}./>~!?U1<#}=F[ ~QڋBN..+푹^edLo+[\-k dW(}6q$#?z6Bөi?L7!3O_Q}Пuo[=tkȋM!'}/Ƈdr2_Cﲨ: `0 :8o=+8-4}۞cĥXdq{bUq©ήm!ƶg*ΪU\z[GA=^+ru{LV U?)V>ғ)x|Yҁgi\yi^cUo*= !TY?rfgWsʽVn*VX#=Fϫ+[F~yH\L~[O҇h5ݵTow|Sfӟ+);F;:x )/OS yUo2e)Ve3'wgGg=J^`0  +ľu kU,Ksؑ5nY,bXw{ w&3QהNQev ]ƷgcH˞i{A3I8hwduwUIWq8I>+@pQşGcZ\ƪUߝ]/:3d;ɫ:gB9R|GW~w2;fzt|+i5nΟgZY|<1NyŬ|E7k?z/k><=Α}N΅>uWydʬdz `0 *\?W8GY:Dgcg< 2+'W6qn؟{ru"wU쏘~c#T?+y{Q,,^qF/Xv8.֩g3}ȸOP ~n%hUG4(_sn|W}Tg&x^c,Fѭ+ <#+}/Uw8BRh_|33!mr\7U9m({ѝpvew[xG]߱?g;,nҽow8]וb?OV=Z_#ve?vN_WrYLo;1g9pV^G~>[_vNOS3 `0Q[ veO\k^8֔v<Zbz\Opbn$~}oz3ј mK vU]^iNWA#x딫jt q :E= z%օq)CcYEqyRG-+u (K\hP'*^ء^q=m=y|Kvūe\rȊ4={W1;=ݷxp;o@>ȘT\Ԏ+C=*ɫ|GJOCW]x1.ﵠ9_Eб Vq)v(ʑ}[GwǺ{-oSdו_˞׃2;iT&w*w:g׭SOsj%Z[~_˯d֮+w]7 `0]kIu+eL]ւoA^;=GR?v쯱;<y o$N1紈=:ߥPVu< <&3KyC/4r)i=*/|Ύ^]QNН1qGw>ù{ ?Kv:A}E:_n+{u=rq͓̳]>>d}+|L01`0 leg:׺񶊝`W,3O?]\9P~[kOWiGc~)-<w.3q}'vuw$Vnv(r52S;Wk_Kϔ8B/hEՠ'9w?K;x:x<|@cϽVyc@ۖSw8Bq]=2lBe6V}eR( VeZT4ade2ޒ+nYBTqSߔ<[&=f[|szP)G}{Zׅ3n7jpWwftEw[ǽ;`l? `0 `0 `{~i`oLy>uoi\qK|}7Svu9G쯿c¾#>,jow{ՆݲL=mW2u_8دjo?kD߱mw>#}E:OۡO;y`$j?tU +mkBT~x흍8 FSHI!)$FRHnw HYx3ꇤsaaaaxIǏ'U{o_ھgW9 o'GW {>~Jlo߾)*/N\ϱov[iZ_ձaJΝ/:6O- 92b?Tlk%?_21B sY5>:>c=1Ow y^- ڶ,XzusM#גU]>H_yYv!ۉ_mi Rus]Xm_g)YY)m]y,m z1aaaxEߓGקo/Y\k6xjgH|yu.\aæM&wk#ϐ$?]Mo\Ⱦ,/ڥQ@~6s?)}, l gX #vQg Bٙ^uのuhm?}{].~}v_J;xogJY]޳@.)oqC?}>@Xߘ'-(W? źvƔOʙRv[K?[A}?-wmՑ}g\=c}M ggg DŽ-B^k_g?F? v0||؎=ǧHPgs/hؑI t~{n^}ZyD5XWvO)"c0vY Z|~_%/,p\ɹyΰZ/;/xs_9?Pܯ5ݻ\[y|č8gʱL{? 0 0 _k3>z_\S |<)b|7aaaxn.ta?l^Cvkؽ#~e)3<3^kdlc&jK+o"e<.ʞ`^(3zu +l+6v<ï k7]/lc[`On}򚄫 G뎱zt^v2)?;Wmr5ocIz?Ozx{&!ez."ѯ 1Gg{+ҏlw<=}GݽFƨ^)zIpG K֜{{e G12ۭqiumf>.}~a? 0 0 [u+7Svq֭y΅ +?ނ}XwŶv?ߩDZۓ-q/?߳=<~#>Fk"qzrQo 9r,nY[;o:)@-`ק-7({߯S@µK9֠ɸ>:n3 +_[_*mtcmC>qSL=<6;ǫsaaa{xˌ\ފpx?0׋#5zяc]x^l򼠕(f:~٣^lin59W~\;?vn6erUbS~v^U O7O(|;+SG4|?f*?rW~2oNٟS9~daևmH6mX[J~s.ym4ٶO|Bd/b5ɿyU? 0 0 0 0 0 0 0.P~*1@G\⟿KrKXs2(ߥ纎J8'>X@▼QQbqwx b)_K|v 1M6kee-2Ǜ59?K^E~9ϱQﱮYF8N?~;:=J<-tĒyNAgC \NXKs)'^Kg\~2}6}Գ)n]Or^j~"{p29w6/.z-v:+M{WJYZ굢`% Ҥl9ힶկ#OUz+U?;sd~vND7*.Y+v:ye;8}~|+ÑޅN9}{Bƞ#txխsXɿkSV/uJ=o G<ջL'L:D]6jfgLz/+ؽ[{rCMYq~[{yy czA;w9zszWHVax3 ף2iTXtXML:com.adobe.xmp + + + + Adobe Fireworks CS6 (Macintosh) + 2012-11-14T19:20:21Z + 2012-11-14T19:22:55Z + + + image/png + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +TIDAT8cdVZƈM .Kj_qܹ +bm.5u1000L2%lrrrF\J[RzL1^(IENDB` \ No newline at end of file