From c910e904334fda44e5b6773b060d220bfd6d2623 Mon Sep 17 00:00:00 2001 From: John Dennis Date: Sun, 2 Nov 2014 11:49:11 -0500 Subject: remove pdf --- doc/mapping.pdf | 8750 ------------------------------------------------------- 1 file changed, 8750 deletions(-) delete mode 100644 doc/mapping.pdf diff --git a/doc/mapping.pdf b/doc/mapping.pdf deleted file mode 100644 index 139c5b7..0000000 --- a/doc/mapping.pdf +++ /dev/null @@ -1,8750 +0,0 @@ -%PDF-1.4 -%“Œ‹ž ReportLab Generated PDF document http://www.reportlab.com -1 0 obj -<< /F1 2 0 R /F2 3 0 R /F3 10 0 R /F4 12 0 R /F5 15 0 R /F6 33 0 R >> -endobj -2 0 obj -<< /BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font >> -endobj -3 0 obj -<< /BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font >> -endobj -4 0 obj -<< /Contents 139 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 138 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> - /Type /Page >> -endobj -5 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 32 0 R /XYZ 62.69291 260.8236 0 ] /Rect [ 270.9115 753.7736 316.0541 765.7736 ] /Subtype /Link /Type /Annot >> -endobj -6 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 30 0 R /XYZ 62.69291 488.8236 0 ] /Rect [ 155.916 729.7736 211.1376 741.7736 ] /Subtype /Link /Type /Annot >> -endobj -7 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 11 0 R /XYZ 277.9078 281.6969 0 ] /Rect [ 62.69291 519.7736 105.3066 531.7736 ] /Subtype /Link /Type /Annot >> -endobj -8 0 obj -<< /BitsPerComponent 8 /ColorSpace /DeviceRGB /Filter [ /ASCII85Decode /FlateDecode ] /Height 350 /Length 25648 /SMask 9 0 R - /Subtype /Image /Type /XObject /Width 800 >> -stream -Gb"/l$(O`Os2Ua7N3W;d7!9kLKHa"1f"T7,7&X'%0n^hL=9^RK@9-lpdSH]Uos9l<<(`=POBpPkR5$Mm'D)6QTBFL>c&C?"^!Ak)I,;'qbNh4`gb\-Mo6JXUo;j;k%0-A.zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz!!#9%&N;uLGla!KTP"6)!#hPij5oCan)rj[7+ma")Ut_9Y$!7^H9qS-NVo*/(D7B8"jf%*!!']/MXgB0V-NV2]mCt/$p!t5MR7N@A-gm[Dp]'%)srTc"?[I`)#sYeG%9p)0)(n;!+G,BP7/I;A/IaTP"6)!.%K_.,Nh;T`P+q`c'!o1/^D"dmrVSk[":]"8!!%!5K8@Cf7'JiDlQ`\^*[h5p)n`dm8)*%fdI1)#sYeG,V!-(&!#&,9nM^5u?YJg4>gr!!$\&NDTukk^PD18-L":@on1eTP"6)!1n_EO)KXh[IQ.Dj[MN@Oi)g"FakcH?_D$3!!(_M_gleg].,a*LJe5,JVh`*_ZE1jcbMkn"ot#,[4Y9.F3VZ])_QWP0ur,"3^UDrZ(PLOXjF_C90HWbqt#A7^=_tlUAnHh,P5e&F=S%*?l/b>r#u@SaZdK+?+@7IZW7gaPbl"@R+HZHR#gH]FBIAn;,EA[YW-`sTk\k=.p>$TpA'W$FRK.ukhrK&b3-cOd/d,![j8NgRfajYHCicqn'VM@cE1?$p<.Bp^##5B[5)7soP?m:$Pi_M=bM/<>:quB.IO3VHZ&`r`GHnol+V?C=.rj,2al_(cP6D^rOHC*Z6Qur!Bo0Qh6I1a=:i'Q1oO9p(&k4Ac+A)T21Z._Xk^"O'-lJta^:mGriW37J)&u@g$_DL7/'Ie>_m:Z!W];+h,rAgCZPnQe[AURh7$)96?F_:CIB6:9[VmgkGqU]81k9r[PPL[$NRCL_I`_H?1V+)CY+"MR"stWX.)6uj]0V?hWT#RZ!s28I0_u?%h%S=!+9,dbPDGcXERHZE3Sd!#P%kkUcd``%noP=0E$OPhKleYOeU`'cHa\[9qZ.*@0&Ln!6g@?g%b9`jiYoA5@=0Z"*qZ`q'bu`Np-L<1&iH`B?\MpntB^F@0&Ln!6gABh0epsnXF]Np_cN.$5NHHmmo+;rs6q`p[[%DAW-!F#P(,Dnr]iHUg321k+H/>hVKshLFQ;&**p2aHF=Y+cnb[;eDt4)`X?-laD_rAWc?L(p88!nX^"\#sI2Tcn2sroDsqPt[d!d'+E(@,+$n4<@1>@%!)/BUO)KXh[B@Mf](ol)#AIG@DRZcSFakd#B.T7-TP'?u+[#o-bR<6,I!pB/"8^o&5,*ZD.pDS\JHNKu'?Dtqa[a]68@+DL!pEPXHV+V0MMbA&da3*[%(W/0@1(2TK9Q"ot#,+U83MXZnY8J"FZ_d*D7qWp*G;\pF%LmdC2IM8f#toPAS"VIomZfb&8k8qS%iE]F5[G&(?\DR#p)d>_UY/=DQlBA6le4Tb].Mn7#,j^"u5'KKPlQE+HC7XD+H_a`M>hVGbd`;j9R@**d!4kg`Fl59S0?CYpkP`ktCr4M)Hh&=eAe[AW(G0O5KWHV/"EolPfWg0Uf"pSOB+Nn07HiuUe(/*p1!+9-=^\QB^>rt#*GlIX:GSZeAY[fqLSo'B3oaCgS0A561ka&(B"G*VXA3PU:D2T_5$iht7a@E\XP5,B0[Omfp1B>5'+s2dsCIPiKl4ZC\7)\O&p;Z2iMIjibF9mQ:1Ch1EUlH3OA:)Y<*dRis[J[W(3B=hYUd(=oj,;t^!pf3VCjK9qp+V+R#-%j-8bdNpiDVJEGC50EEV4^$)U7ZBk`Hq>.a-67"4^Ya?V/k\?p$1(Ce>SM1s43;W8*Hin8K1l/S2`g3bLM*oeQ>Vn!!#r-dX6/#AFNY^GO?G1E+%"`4dRd,R_`@=Ct[7hmEnEGD:YeVRnqRW=>(cXGk)oVk>eQ`'eNV]pYUHJ&+@.V=)r?PU.'udp[6k>>IU8uTT^a!d`+qH0!/BhEmUIF?+P+q3csSg?+\V3s8Mn6>[6(MYJ3j0J,/2m`^(dn,JX-D]B.5&pZ^.^Pi&rg?hu3tp$+urqY`[r_;s@p%/Xm0Jt3%7lQ:2^S6U5M%V-&^%^ATP9s;5?G0dbL,\[)c'pY1d@u?lcdkNe0-B;#nfFjpNZC3)mFmh3OMK_%qe]hi^OH,"2f;<\T8XHZs37#le&Ie3BARpsSJ*AGS3(r_i5(%1qs:XGBs("!eZ)Ug2/6+jrr#F:&J5W?+H79s])Vd,l)h4#a"CN#K`7g?@efHOiSibeEGe4dph]OH:#j-XG*[0-?T#cd_RNe#30Br)Tq'7BbmuR8]tV).T%@WD]S,qWb*iq_r^4^4#:KB:jU\F6CgPp(J,Cn5fSiO2?kOkiQmY=1)hqVCK.HKqo`X3V!!"'o)=u8#j6Ws!<2e_;C$WJ,hRcYbTZ+-A50EEV4]B]$hKpo4Y\cFt8sO/I]!ZkMd\TSYIItoc:H_-1VaZLZC=;"iX&iB)>1Klfa(!#FeZ2bI4mV:aB:lm7m^qAgSjS8CV+H.oFm;rdcXl.?k09AsZtN=uoG$E0PuDO2jKBVSr,H6DPUTNnD(MFSoF(^R2.k'&2ik;[HMHHS.9.7(23k,ln5nbp7ld0R#O;-:?[nmc)aAeadI]8+a:KF8+6W;1Lf:3HeYl>Til$]!)cKX4Sp^+NQX>30?4S)>R(Q7]mAh-&eX84+kV)r2kF]a0_dEB3_[lCj:I"fR[dW"^PQ&1)ac\LU.f]Rj,GrXS"bO(qHN3s<99^hj8`\IWJ(J,bWU7lkeX6t_[OR[OG1"TSOJ`,tgR5]HEuPg9-tl/Ume-gtbq^2W$tWD]QZ6UNYG+#IY-mFntoS2jNM=uC=pIJA"Y$KQpFj_Yf!if5!6D&]&l).=L5-7$Ap"*R"rncMgPq#c`<2^AAV7(%1=6._s2fDIgFQh'pmJ?X2^]4:[rVH28I=8)F<3KVVj2R'n48]fn!9=H-jWiB>R$^DZG26fi5'+Dke2%*?]HA:c2'TP*"g8Nd.UbR=!(D6[V8Jt?h;-1qZH0JCL;[`+F*#^Wp2QII\j^q:d3fbR6C,O!gh=AmHF!:teiA6UUQO.^.?@S&]b!6biAO_q@65(]ACM^A$)!&-(I8%-C"q$;;T/XFmB!5Q5i+5%E&js0*C[THGR!!)VRrQV6dp$/^^MaA63HMIhm[Omfp1B>5'jPu7'm#5huk()ll#FGqUJcu-V(>ZGY?nug32@"@(4MYLk(+]I$ZKT$9!L'3]YW8BRk5cns[pT4:Q::Q8%@@R[K$=>P57]Fc\ciHAYUmA(DnooI(2OKErcs%9cn/?"J7[,VHNPT^[pX8BpWiq8L2Og/!%a&rgD_ga\cnQ*\pkc/13!+8rOhqin*cn3lid/EP9PG)3b!!"OEq[NkTKPn3[N:($YQjMS`"TVXBh01hd-?Q:GB6=/?^eErm.fdB-ke=q81SJ$T3MZHf!bOd.=oeV(7e[o5QjMS`bo,?P&24d/eHu;\1:lpn^bk8@C9Gq^,6?8d>H.Z'l_F>@#L%a:S`U^D^Cr:+\oe>[YWfYeF2.qB(24i:rDN_1TNe2l!5"p$D?i9Bh=AcG\plEldHHlD!5Mq)^?5OC7CP2HKC7V*GV6S8#lq1M\o2r2'@Er)r1j.U".k'0eU^tn3T)up!");R5HOFM@f`tQjK9gJ^*XW7BA!!(XQ(_6TH!!%P$"o\i/!&R&%i@H4uG2_P:5Zf9;qH&$366Hj8NuM\Di1Yt.*)oar8@*LW.1(R07VFGR#R$k%K@=ohpP!3o:I/6l%Dl[FI.]i/.EHY8mMhB"%u##f9'O63#!^f_Sjh]NjSF<5/f/5kJO"l1_9oq!b([S;QqAjLWKZ^O-;GtCkpgR]"UT@%9`,^qIV7q=n.CU^1;?QNdiHP7Z12d`>LF7+,R>pZ6k7&a#mQo&O-cmVh%)U&-uK1HLdn#bj"mI:39/U\-3Mgl]mR#hQY&CjKXc%R@_PBb`k1=u$A&Po+E@t!37u67#7<0qLb%r"cEISJcVh%)U&.!s3_OQW23&OWdVDQQ>3eA#(Vf1\&e-MZTX]W@JAEXe.=(*/b3#*WsEK'NhA>Q"hC*];01XWiu+\H",,8+HG0%_C@($3ek)@-HIJZs2T1@H2X`0?92.8suY"ANU!P4^i'\Bi;Cc8g3)otLLd_+?*$HYXN2ZZNo_dV(b$*X7++bK:,sp^cSJ"1PXqBWQalDu%dg0F5TgUD]18)Z_6[^r<=Gef7%'o$=eD!c9=17Q32LXfkhKIRaJfm^rlP[0R4H=mo=4NQ/OC`-@2k^tQgJde]R4fY;e"B8dj7YE(.kbTMtVi$Jn$e]-d'r/,1A@plU9FB7-U2(32LXfka^5e3@/uR/9g%A=7L;rqgj$QQ7KNjjF5G$()LRUB18CA8t:qWk@_&.*naRVGHY[X?.?$mdBpJugJCT-+AufT4K@;YU&?eZ"WJ^m&oc;m@5SQbN:e@f9D6.B'Plc9?:QV:0rkV\p=35HB!EZ8,*7g&F$KF*c-d*caIWg#fem(u?Pj#=:,m5j=iNIL.%!&cuo$iI`(H>d9o3m49');a.BW3S6J5#A4UD&0ouOsNM`UFtX;\:f7.:?*e2X%k^j\8/034DdU/3#*qeF\c2^9qrZ-=8qgO1qp(,"Z(Wf:m"(3DZ@SO<9g+DrMsQA&Jf25+Z9"Tj"Y@jlCEs&FK$b$679ParNSBZm.%WA9`;6;NlI2k5_D1h#qG=ZU!tQ:ncs-A*4^`W#RZT'8fN3+]NX)_Dua/pt=F6[K&ENSfti_Q/93%Li^9naZ&FT_-ZP(5WfNEG.QG7/he68:i*iOuT.JK\6HR[Vr+1X-n![IsT:/C(eMAi!$^WnQ1oMm]q%m?P)Njo[lQ#Q5i^F3hg.[C?SC+UHGl6uF;=520k:O&np6.o*1.[9J83?,T@ASLGm2N>GMbFho>fA`^-H2jOY*n']`U-`I/Z_qImKL.Q-)Gim0HC)7*F/?G6%8<_S0Z1>#@i#$M3#,i^'h,AKW17Od7sXWf)3L6c\_"^*OMFa+u_e3,UqGPcNq\soPEiLjaS:6JC6WXaR.*T2_[7PX]Od=\WTjl3%l5V.'6Eg:Qo(;)4sG*>f*nfYE$b<(aV\.o?f\t?qP'/aO_fHGMp^[?59.7JOKqCr#2BcnE2=I7Z0m8KU5aUcAFO.>I9%VP=4IK,X2nb8^Z[H7T^n.B=g\#[27U_R,2Pu*JML8GI]a\]tQ2LZ%=8JG=qCP1iPO>X8iaY+G.TTf1i^o\@9)CHH=Y!9rqDSaBaSiM][V=s-?^(;Cs7R5b=nsT%88i3,4[a1>j@:DISe9NZkh5C_1s4Y<+$:o@os!&2NEW?)Mmcu[c#$UJeg\..MWZ-b+$(H8#_1r.Ukt(TpoD=Ma5F!^Ns[NnY?]@Ba\C-U]Y2#0&*$N1ArML\$=BFkbSC)C2JPH2Q\PJtn,`q0*m"q=[WuQ<+nU^A^i4OufPBO%PN/f]^J[i::7fFb.k*rXNHGZGU."J>=7O]=^gFX0oYKoF`C]m3VoJ71)-(VJI^oBj)9Q@0lL/nDY\<3TT3Y^.+iaXWqu")"BBLium^_NR(1,^5:&0^>7qZYTUArY2m3eb]oN0r@&gTT&?iK[k1>_W[-+cBF@O4/^15'h-\kUNCm]H_Os-WOPlK[i3B+me:@gJBAW:B7HC4#eN_^%5Rl^W'"(M/K%6r3'=P.kF^48bAE\B\G-Kh6b/-]7fu71L0o>l*<+Z&=[PG9L=#0/'LA`JR.pGW3g_]4pC4cSTpG9Snqn5i*SDgA*<]@-,gc8b2/90j\cAr-TOIMI+YZ[@`V/igb'p?_"MORTp%'07S9hqXU[5MuUh%6E6XSmO69BfsY=%4brbNjB&:AO4:MNTAT-U4eQG/a%XNg=%VtV^oUu?0Y;B\ghE-*=7AaY.pp8PKUJ@cH".]hQ$^$L35`j,4MN!r;KR=`GR9L@"lKheF8%7kFu=`tM5=RmgZ91@(r+@"OLb:<(GT\npX^4B$S>W)08%$6"4CW0%24T'VMkW+7.J,(Iml$S^Y2K*%:Kt3N&esn-'f7kNpfL!?dIf:ekCucs4%Y#QE9N/^*@3cD0$Ls6dPH7S*P@Cm#SU$?hEg@T+b;EcNkLa]6ujq"F;t9,fGMF1&N[.4"FmIAG_YGJM!1(WoA0s/i+co@_dgbZOXS+lo[Ps3%:Q.q[Jm(phB6FE+tAqi=Zo\/X]S*$L=np`=@UUp$KsLN-rZjNLslcPkh.d)I4``4M1d9X2;'Re$0W9Na_D`Z/T4LVg(i+Pj[M6>Ydh=FZri*.kC%g=Y#sm1[aqm`JYG,;OggpQUDVf&5MaRAU\03n14MW\RZRjMgM9.b.AOoDH;br_,Z__o?H-;],o9H^J5B21:-?\TZE>mqV!Bo0bTP#";QER"<$5`7`k$R34f_H;p5MIlh]Hho,]%8tf)n8GnA@+nUgpAq;:*Gip?sT9/J)sGri3-$[J,e8ns"59KiVA7tf;r6=ki,TfpK+J3f<5'%0Fu^7=/R6iFLjFi>o]KqW&L]WA#HeXbCe&$!)"Z6`.rpBCj-li,$L%oN3*6sCtZ]_EeRjBA?Be(7;EW9Eao_eE@?#D/mHH-8K12Ll,[m'G#0!(c0D#+BXH%/k7:\C/p[%Y:>kh5C`Z[h-V&\!@kkOmLsq6`4f&#`KZXJa2AEbNZ_[=k&I51j6dfWg8Zt*m$`t?G%Y(=+/H"$K%qRKqGNPQ,LHf-;06ViPA6@I8S-Sm#m.dk`=1\%K:HLf=N5FJu0DNf$kf'eQX4:EhrpQ.)>BG@+O9_`^[V7/hS02uM'Y@ogVM`g\0JfQ$+0q?]SkD5-kl,ne6@OiE-7MqnS6EW2H8[E7fCK6bK(^g%H=cKis"+"R7/qIE\!V_6TkEs`H>_P(r'"G'%i0Xh'"^]_U#LT%2-1c0aQBQ0foQpl:.2G'8rSG.KOYmgJ[jQ/Ccm'q9ioeo@4FW!MjW(&r%u.I,Vl(!k)o'NK%qVk0qhW0flsUL/E_H8[E7f5oOkT(_jI;7le)B[Q?g";na:cXqk&r6.<5dhmPj2bEiVl*C#9Yc@_paphK!m%ZAh>ese3+DZIL8(fGbO-?q[*S'&./m`\^q?M`810QTK5;4cfp\+i:K?EX]ou%BY`Ptb[KW1\6'n8_G$KiaLe]Y.rr5PZMm0P1."?b\oo%o>O'7l`l#kXXmqE(\\s0Lp=QbV>^4e!J?o98kBH'B7;nFP@_*QsW&0i@j+g!KoIj0HP@M&A(C77%.TPrm+A?O_D:(!h*thR79jmdCPS#*n)dmM90E,N@So5E6GIa)LjN.MK08C*@J&ZZ.pDr-a391iAFAF5OsZRfqG2L@8c*0#WdE\gkqX2HtpXfTis2/?KWhfSIDQO_HR:>Ken]B]C$+ODBR(spr%nts%B3"'fr%=8[9tVG&<>0\e3RBSSCaDWu/aa6E!lb0DMQ^Qm@D`AUBsdYP*081pV8g2EPm]Q2q5Y1fn5o&:LAkr]CVm9::T2ak'Cm0;!W@ok.sBjd!Sq)uj;BG^c"`)2qM;!H`Mu4/IQ*9"^Q%>%ke64\rf[rGGH#gt5,,Y`0n5hB!9i+e5gRf`Por4S>Z:R0\+mV>pgSbUrJk!X/CkZCN@`XK3?0R!0bEZt%/;>3F$kGB*%P?6/pt=FSKA-#O._R2qYDgN]NFne"o3_lDq!u\hOENb5%7ZEXs/9Q9`-Zc;<:"jCIT2R<'2oX;:&Uif*?W12:+/OCaDWu9ra+3YDWRt`+NVchWDQ@FgCJ*LDN\s4+_aLm,(b'E;(70e9(I9GESN38rXLFh+b;Q_YGh$oYFah(EYGFN:*kUnd1T=#O^Y!G(;7\hcteDoT13i;s3?H`]j5c[S;oEl5,&nF>23!iHF>KR1\>K08C.$3'@GXh@XZa1I,7Z#(b!rD&`4$65EFf16E3$3SA]j5'F2P7YM;e]reg+tXW%Nf+7IR,^c_;_e'=WfrMaBsL%jl_X1H%ma"?Lq5G_r7fS7LoF_S1MNegC&KqT165'k&SHKmFJdBh."?\U"S,c;#+sQ4$Q&rW^ua=jR,!h)%'s:#?Ga\[\5i6lGIc9iWnoL3r#%%-=:bO`jaM73YG__V5?pr?Pf?W/sZ4*][k6oiuLKfSF_jt,ZoEAaX66Drg4g7H@U,&eIm2:'@8Q-CaDWuodbsj*Q5>1gk8*rL.-%N5^,)iE8tWP-nN8C*M!Caj\Bj^YEEAi0p/L@M_5Nd<@I+p,t+RbV5VD`Y$&qkc!!!(>JG3ho!GZ:jXPh4JQPF]1)T+3XG_m]9e6_2_Y``44R6b:Gb4s$a@DYq>\Qtpg#o-+=?]`b2=t_LlW]h^WBmXrSK%4Fd?X4M/a^W:E$Y*I"L$^RTU1U%L6EUU%Y7Q`>U?P)2%8bOAh"Dbt!me,Ej;Z&;=rRK1bn5if7O2!a:jKG/+^To[crFg4Ac:8uKjN>m%n*gs5^Q!BsUVeG)7n9KK_NMu1FoZgm<^QV_@BCPUhDf4DaBs?'J#+5Cq5\Ptb"\<]aV@>&\T=Y[ikYjAFN)'P0Rirp7>hp!s8D`QO3#[#qCE8m-+.YWGrjUd6_toJ*#C6S,jc;Y*84lKpgRhFDC?T`O7cdVE.usf3MA\0[8DUk"]tD"$m+C9Sj#ckR,EId)4kf[L8kR7"6\eqF8+V^?o9$Ku8#t?+7)?e4dD:G?Rl"jMkF[69IV[,m/bE?Jn,NBJ?E[J9U5>[[e#"-HFI5(0VJ;0g]01#,]#2XR-]JW`-71qKcpP2=`/,.Fq]_U3o^$1U/6UDq7>la\-<2R\UlQKU@VhhZBsVErBY3-Ul)hGOqS3(/cY\.ArlVQ%X2!AtDdR$cjNB3kr8sJe^An30`]i_>Xm=lZ5FiG#Hg/s)[IMjUJ"8]I1)7f+UIKClergh[S<,C_)TN=?+\s?mlfBGgph?:cC@`N.5TDtVbWeO11^e5TAE179eE;N21)EnNtd:q3%OZ8cC)a@nkj!uj6BE)rKR+0B7Ddgrd9#d!aDm:6'!'Mr;HTOHL!0:Ier\Ng0ULAMljTaAn#7[$PtF#YfBF4:0*OT40>dXK+C.BP,=^c_>^u-!Ik9C0VuOYKMo'a`ReFCD>*>LiSibO]6@=<`5T]@H[E5;f5BZjOX3YdUjA6q;,m0[QS*^drV'71#n.4nSG@WjMC,gUqh'(LMQ0o]X[;.TGWaZ(lYpF)0q`KqGOs?OfBJ'=0GZQiNIbFVY!qh2G(n+L7Q\^^J(%NA;AZaj"O='o@]r&*1hBI/chgP5:+)K]?D:bprdq#?_ebZ8`WU9Z\oeW,-!L6^KcRR!>O[G%`M,F;LKL3/4,tjQ"8Uj0YqO;E;0m:jh5NqI;*e4+X-_Ge7pcA$fhgP6)j1C6j4''&&E8a-hO[c3h.:&26dR;llmN;6$'lQ`Eo((]3bl2HR?(%gD(*d`i\&3Y@3\<4Op5(,KjQVs4A='pCK'ic$XDV^a.gIS:r5_[;K=513&-a?N7kg6"*m7-Ne:tM7^hYGSm0E(&us.N&9YHMlNB$JD"dIt8#pX7)hH0(=GDS(lddd*SoLT6D30'gr^$gmladnd#ZK$is\J!\HK.M;:g,u$>sJkeSWDT:@:OmsQ:d4LCHX)o.Xo6TUY:29=inktVt_>NuX?YY(:9`cPN54QQ)<*>kdX1IIEImll&=u.$Pg-TD.6q+Rf_dANi99h!WVG3Nr??h#2gUM65_afh>ldVmISI%m!:n^3MRP^]?dWR)J9%&qoW,>A6.9!1+:lU+9PGII(WNo2Tgu!V]?+iZ^VX=-5F&1&L2;>TY:O`cO$D_0(Imlh_8lNp!/ZJ4X<=-6l;i.0YM6VQ\W`@S4TDTEM#UnB[@mP.)N+?_tkn"M42#S2cWV:">50]m?[FjKCUdk[5C]W5^<:207nR[@O<%V+[.U)2Bd#Zd1gN83/dmg<\*+$l/_W]8J`SkK`1RgPD6:3@=%f97RX:,J(%+JD$5Je@18)KZ'ba2#)?)IX6qSFuhkq)WIsU5!Q'orYZbN6G4Lm-*^Wu4JGMI0Ce]<]Yk[((Q"7TAEb"!L4*]Pt$ri/np:/k"JhYQs#D_q/=g?n'qJ,\W'IuN6*_dCf,nn'.$b#@r8ZbN4s7F$[9&\Uh+N:L8`DV`g_.d?(?jGr3;Y5;EKOV&HS8NA1@V:^qq,D>;'"6?J).\YoL4c]4dm^Oj?.Xc@Ddh7%#3`EkVX5*&oGUF(!5i&ql=Sg[Zr7/X+1*@f=0OUMjeBNetmBH`oM:U',(T[)W^AUYF;e8jKBsL;1ZkDo:9n)Q!&G'`>;m[c:9@pF>VN_*?QB,)OAi_UG4bQe]LTD+=_@M2JbpJ%ERkeYM[$?G?S&HMMcS`B$H>U3MMtGSc';RZcLsb:SVFJ_7dOqeR1*+WrgU;*]ouW1O3`Mb5?6lImnL*H9H#mW&-N@eaQZ4PuSQ*;6sk/B7H2up+&1gdE.s\nlNj+7P-mODC4uQ6+T4^?+ZD5X9P#'hgUic^S:\k[5sPY^Zs@Mf0^'3A:1gl]mA!'.^/5@V"nYqI5^]+6i.V>(=W%/.[>*s<\6u*8]XhmprRMQeUsrZg4p"@PnYl)Y@>J.Pq?4+I$E?6,C`/T-<1q-7a9&L)Ej?^\hdg.o^bk;$g9tikJ"#4D;PXTo0%Fs6fjF.$\$&`.:@rQ&/*G6NGP5+;WMsgKnHRYrqPHaB>8mF)$hBF:emigq=/s(da736V3;Y5+L+HWA<4*Z)ql9`"#!Dn[j(a(DYg@Q+J!FI?#s[e8@R?_DblQGQ"oj/E'_A)[>2N&S"?2LeNa*3@r*ND^%0;rBfV0fb0aSD7nD(nhWX=0L(56X]QnSk6)s>#G%Z;i@JlB/'pa.C(#@3dD4aS@a2^]@Ud@YAr]6l!N5#EQ^bl&UYJ:&\l&t2ZIn@k[E7Ko;J[9"8;Vm9=.b(a&j6?[4Qln5mpuo?8.l]OBUeJ_NFRZ8p'7A_q>"/,,[ablBo=%5R2V(G;dcTn8`Om5ZSEQ$L"#YM=V"q$-i@ZS@6M!kLW\Z8qDUcu]2R1hfk0OsSklDm-Xh1,JE$n5o#ZrX*0@nr_0WI/%ZHSar+#?TrGeJFd8@9EFboNZ:(=g^@g]@O=ZZkd^8(i3,6^pa_FHa@F$<5gR5<^gD@Fn5g_oOH4pWJ=_=WJA:Yki3,Ch+JU@U%"S<,("T4Nt"+LK["8N4)$0W7/$2?$s#6"s?#P&J2'$rG='(Ato%K$s^%cejB-(nmY-/bsh)u(qF*QUad8jL_<9#+eZ2Xjcj4-5MRQ%5HWQ%6X?CuDK^Fr:$gP0?E3c_\B[$\,"Fr;/"U?GFBb=WP)`FXr;GD8bLq,.]l!UEtKNlh#Ssf-G@O.f!arM"hYZaQc%:^e1R%K(;uO?,Xt=`(.MNb+S[_L6:I3pa_ora'Tj1nlO/S?We;4O2eOA+e:S7/a+LH#)Y9*`/c.RfW'=@`8paX)!.MHjcP?_2#$-=.Y%j#gfMTlV.V?FJrYrXIZ7F%(]uR/04GNgbY0$07>.C9@\hHdQc5,STM/tE<[1]7RR4*&5MXNZ__o:Ntrb?[nnPh[Af\N:`?/jh3idj21ICG,]WX-3"[4@&:j[>*_7.o;&[BeeP1=tN/KSP8$Br[F1GF%>`Um[qXQn%rgeGFoZIhfmLDf+8%/;>sP0mX5c4q.j7=sk>9V!J-@eo_\,5VTY@ecO9.Y=kOhm33+7kckdr\.TYH&%/0I+1g-]uh)-i"roBEl^%G^_UBH'%WP&_pdt4e"L*B7&pS\nmDUIMrA2=mC:Z;s]^g[,o7r_I"'7?PO[VilQgPAY:PK^3\7A2V?b3Lts5EY7F;?-`;g]dI:4Tj-m_D\O\!j&ZLoP@[ouNh1DV*Cu`$;PS0pGZN0[$'=].A"ql@>dpPu4scsYm2Ug=mPQ$o]HiRdZW"uBC=2`_0!h>VW\:!)ijs3*;:CS9c$4'Okp<6/q0C+P"?0J^,tGD(kH:OtL[mS8H8]\,ch>k0Xn!Ic:SY]MZ^qCdc/rb?>;>(?1%ciq0?fQ2YK08<(aQg5b3^7GC,4Fk:?9M,qa/5PE,fp03'KbNO5Y0kJ)u")rRFM[10PrWnX+Ln=416J8op8nW^sB=6&r](Is!;oqZljkiSgG6a,,eNGpqL+J\8);#U)Ic5b[amb3`9=X=jRYJHT$">GOpAk!6YW&7S"0ubneHj6Y2XON;fne%FmOcPMtQW#g'P)R/7irM;hUijiq'\d'IEgHFB`Cn#=O)rA4jDDPZHODVQ?pmg\gEhHXF_nnh\aGMOseig[u-n*l?FYq)(;e\N]o@$io0KB)0;:A:"F3VC9s\IeSk#!)T]6F]RE'c3T4nn`3V\hI>hNoUJlF"r^.b%G;]4XU+B&&F\[S"N:A(f@lM?ORL(qML>[Z^muj(mX*:Xuo^>PVB3q(M?VL_IJ5$&Ogp\XqO6HkE8KIiX^D,aGm$:9bj\ps!XA-[g1*m^sgqMT1GTuSttZKZ&U]j4>p/M5=s-1j!bq0ggn5g$>#P_l$:`kSp^](Rm!EW]BQjl<=\DoiM*hWceV"U.q3Z4mM>`(ClDX`5cbkTioOZi2N8>Ra)^Ld:-&+7:cNg%A!,bmR(*\NNeF5*X!$Bj!5KnVql<0FBUh%$-^#^mq.OqM]EFP#*6$"hPA:)8N+30qj)PkcZGa@%E>/!,+J,DB5EmMsdoE8\]eG!*@oS=W!*#%i?feR5h&YJ%6.^q8/>]%C4a;JaQ!Cm8J,0ok"9.1C*i\_$SX$sgj2QkC>T_FA=>JK(+W(KU6rrWri#*"KYMOZne[VkMW,$^>.Fc:dN"A^,L3458P,K7(kQlgU(WoA8Qf4;ZtU6!&iE&X?M1=B',:)o-kMTCijjqt#K*YD7)'1R6a&a7:6tf4;$)X3"D8fnOgemg]ipVrRMc.tU:B/!N7+-bfhW(tD#=41GQ7IST&E?J4]OX>l96/5+(7LoE.oN)L]C=,*8ZisSaU<E'%a4#`fG+5]ij$H:sT`lM.F;iB@sUo<'/fIN4VZ/Wrn6T_nGVn;NW\@i00*S>V/6^gL(;.B;r/asqlX2lH,7bVps6g$A`&gJ-!'Ds,Jr)D6p5oK84N$=CQcQZAX%mHUTH4B#bU=ME?JjEO"o29:Zmd0Q?7s%f#l&17]i:#U1)J)t\Rs0dhHnrLF2K)9*)7*&B`j1#DRQbZ4#^R^7$K'_8W)o_IpmNn+sMFY5#.aj>K@bWm4lPQ5[]OA>FmQDV)p[&O+Ti#rH[1(Ic_S_!Y'4!7@[WLof^<=t@^)t?fWGo79%[c$/M$H_S3Y?XR[F-oCl?WKr%'3(r\dOL+aXFnR`'K><)!ER*mRE1T:*O[qh4;UUdVsf%W:IZ:Zb9b?b$Y:'@uk"fk)XF&LP7G+%-s`/^K8nik/Nm+[NM#X!*^)icq7Y5+RI:d7)h@T>a&S.l,FTJp?hfh8-T8&*"TI\SDP`\P[a4nDI-pLb9HK27dtgbEC$ZYo:O%Le@*\M;76@?j[_)A)VeG=8=7Ajs-I9AWhG**:#T=6rdf[q2"Zj3/mOC0*HU069rk?e+;B13OGE5M^"pf8+U@]3.<;-0K_,Li-,hndP]J$H*0L[e*14`7Gc*%.j*8/XVU=2T:R@YjBKlpgpjO's*20OeO0[ipF]?KHp[i24MGP[:N*!PB+3@B6d'GS2HFAm+CR*r,IMsgJFhO`BY]1(5X%bnHXL=*%Ig#?]DKMT&dr5eOaY*$QNg'%M/&u-Z\Z<`Nc0--h'94@Wie+Cn_E&>RV\%-cMfiI:UQIYn8gHpM(9JEn15;i#a5fPrLVgtoEr!#SEjiiF?nTE?qbhP_\so[l&reS6W9Zn(Niq;@R>L-rr[$/nfe;NmdnQl"G47oi5(cX*G%4;T8$"Vd.;0And.;9q&q_>=gq%FF`8gk\_8uFW]H(Dj,pl5'>rsid^h1(.R",r1UmU.D$_c6^[iG'O/Z0]e@F@TPo(lSi;Qq,j./uqW7r&PVPl![gJFnt5^ne2ccnR\PTbC069*,AfOLm64YP)j8sV8jO8[Xtg/dmShLQ#rAag5>'%f@=/7OV0HAkoPCX[So(4bZN&n1IN#ALCO2:>\*]a/$_?YqiT^:;_mo[1:]uil3YTDj=%B0HJ#70OVmL?;GaL#U@JD?_/Z_C$oeB3qYcUN]/h8rJQc;XWADbAV]kHinVsQudE:C^_@2t'"3+DnuK^$CaRd/lR:OduH\Ys:`+kH;Er,p:%$cPBWQ4)p0g3PAOPXG=^\0lGpk*]f\K_$1CrSbC#a54r)UQ/+02CifKWRKO6;%e)SDn3r'9a:ACGB1C9@Z)`Y8sgqEZ?SC8#e;cmN%D=+0fmGFo0q_+$SdZ$)KB%&#X_];S?Jo3X];1@[T$f4G0mQA"+%D[Sr]K?7h'?j\^H0C`^'96S[7U%a:[c/j1+jWA@+Tcn^O$ieY\1'`aOV5Lt<693k+7MP&fJeeR25TY,b#t]UX.Tk3`.>[D01'49-qnhfgZ@^qI&5uI9.'&W;m5[L#gb:el?mZ"+!WW3#!!!00r"T23!!#:#!e1@R!!!!qYeXTHz'J/`Tz!!Nc.'`\46!'n@%Ig#fP!!#j"^g@*B!!'f'L`<#a]NgIk^*Wg[!!(f/>e8_6hp9VALpA="25jBQ?*dQGoRd'8)u2'=0+0iQpaZ=E!!!]IA1DtTI*"H5>jpOj!CI?F[N]SE0,]@"dTa'\m7'0AdYGVF!<<*"TKnV$b,7Ob>3fe=A[YU,K6F#\kp+cc,4JY6!!!#/8Q:J<\$pQp5l[nTRrW#A<7&q_&c/0>\dRK#zE0HAF.T3eGWmHRW4"KKe&(8M_+M,H*.>ijg+?!O_ps47+8rB=t%/DZTm'F_Pf$31&+Qk+[2^W6FCEbV\j%>uCie>,jQm!#3,dU@:q!`5!BegUS!!+6]nDgD_PjU1CC,A$OleLO[LnF$-5qC=TL>-BK6DSZAS!!"?2aCbnCZLOr%qbDRoG9$*]k8aF8`GHnol1P1oIa_6!.a6!M6^En<]QVFeCEI.W)R>Rn2,H^97PL#=\IQd!4WTraoqbF!'D'[4+B,lj3'*aHq_6!V8$cs]N+@Q[9j+"TmHCsYZLl*!5Qi(Em[*rk)4/k]tJd%kqM8-SeP_<.[;GU0$j+Qre_1f[;m#0mdC;L%/^h?!!#j":mUbIp0JIPEAQa7547as]6NjTh;8Ft#P]eL!!&\-nac6#;Rg\[/J`d(QK#m(N#ADfH[pJFIg#fP!#.CZ%WqI=p'qPqT;SqrZnm-Kf>j6%e^^^%Fajp`:Z/DV!!!!8+llb,"uU/WE^h5>f!nK2@RZ3L>L;`P?NC-,!%pTL9OAlK[4YM@J0A'umS4_cXd0D8H$am^le3'Ug+<=&'`\46i$+]_-cVC:.p0Z]b@[!e1@R!!'M7bPS>\jiU;d1s&/khn=@qrCTS?*-'Br>mgKE!!!#W,2fYB#5B\K!!!"0`jYk]a,V0-LCW_*[HiJP'+tojN9s]M?m*"4(Mt$QH?>,b24f=OVm8Zrp^>"%7oldi2k*:UGpI\V>bm+IR,Ig#fP!._/TTte0ZjbggfIq3)cZ)(0a2GZL/'YW_f^OPqAeMA<._M&@p;,NlFFaE,27pji`u0>Pe$YfgUA\#roBC@kP\$5H0t..Pb^5LIK9.p(<'=d/hhXB74J@qEfIJ\M6d!!'foYe7`nL=F`&4aZm-^3hs4>=X_qh7Im7Z-JWon%\nJEbCR;Ig#fP!4W:rq^\-;d&gFN!!'g`d@I=hq9Z6H!!!#7e'X_eJbdZp=TAF%^sg]%X+C)nX]YW(!5R(2SZ@>;d&gFN!!'g`d@I=hq9Z6H!!!#7"R&V4^eErm.f]PL?k.9kCg\T3WtbU7!&+Yh1H$p#]%%,f!!&Agh&.0!$/K>"!!!#CJaSI+9S75^!WW3#AjU^u#3J1[:&t=p!&L<1DZ^ZG>GM6!!.amlS\9SEUKa;i!!%OPd@J1+kFu1M!!!"LM:%m6JL@0rPlLdaJEbIPb^g"m>DrO^!.^omS_/L*F:/W[!!'5Y](8%'2nB_/!!!#O)Vmj_j<*43!<<*"zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz!!#8Krsu!q.Ok~>endstream -endobj -9 0 obj -<< /BitsPerComponent 8 /ColorSpace /DeviceGray /Decode [ 0 1 ] /Filter [ /ASCII85Decode /FlateDecode ] /Height 350 /Length 9862 - /Subtype /Image /Type /XObject /Width 800 >> -stream -Gb"0WH!D'Vrs/$8Ep^^2_CdCK/0H,B#^E"uW-BD?TVCP![i$Z-H/T?MC8Q7Z=^!.#ifS[_/+:V5YDcBN%*^$c>>oG7bq+eGrT<&4]:[cIcSD]es*PmZ)W%ZgcS!Dbs8=#>zzzzzzzzzzzz!!!"$Weco3XK;&Y#bdf;pE#_ZbqY:M.S/M/NR]Ufufo[0%tf^](M?!]s>j\s,5GrhX[aL&mO(Pj=OrbYj2'2t8DoJ)bsf^](MX,QV,b5Y:8Sm`r;ELD^:ncG59*b-KiQ$o7ED[oRLmH?8.H+guD:8H+a])LaPZ.H%ALS:#f,Sfu/Utf%/DJLB`%?jALkM)OI1,G'(!seIRZ0'-jru5UO1KVKjV<>t,:&<%;>/1IK'=9H>>_-N/e2ncG5\d[K^Us-p4)?pCk_6dsK(]*2A'lk0J0fCr0%?/s1!h#MO=7k1=;6(COWPmG?WHit^+4@eeVWRWRo\&Po,Zf/-kA&Q$9/M@Z]pAG?^F7oA*-3lHp:#b(W\<%@OG$[)7T+Jd.?`h8#M:dgoFq,UAur[Q->hm+/6mcACu0i.b*n#T*d^lcZ:X#D.rC`/].\'>uYj=IY]F+OKkI(R6H(%Ep&hZqI8[o06r+Bot:&s5;1&i]J;U[$Tg"F*r7%G]KjJgk%3\.iQ5A070JdtbG)7bU<3js/?0d:qNB,sG%Eru1$&R*U?bhguGR/[6a5m-b3jTB?\/$0YTJ+>%f\E6o`LiT_Z)lCrP7:qiI;uUITY1q9@+3cM6%enb6qk!2D8O_$Y71604N*4AAgAZ@`o-i`&98Xb6qk!2D8O_$Y71604N*4AAgAZ@`o-i`&98Xb6qk!2D8O_$Y71604N*4AAgAZ@`o-i`&98Xb6qk!2D8O_$Y1f'??iuPT\/f:)%2lLgj^-a:2KY\(L(2g@mT^+@ZUnCuXF-]`3+lhQ11ant96+(gD3Jj*cJX\4ZR57h)"Ys+Zei(ab3.'3aNJ`Y_2g!9^l*KNc[:o*YA[GRNjR%ZmkKKGYIcS;?:,.k?FDbiI`;"eK.dtKCI"YeFG?uE0cATA0WH%Y?DB.CkBu#NZY>1XN0k]peq6ZMJpPmi^djL0*.4$uO1K`VY!OF(t1I3foE,op9rOApVTCEoCMb`4.YiQ5Xmskb_F$SPBfHRC"L&M$Rrt_N_UTR/hLp&("1OMNCeP4plGNu$(Y6Y$`ia6CcCu.k7I:''R:32VD9fdZ!uUp1)g_2>MXhV-8Fo!,kUNZIpgFW+[`4`3+YqdIXMj@Fbl"a&+]=60l/e-mY>NIrpU"#;>#1Y$\[.A\Xg[TdD\Hh(tpr1[U&'64aJIKl:m=G8VmcD>ro?PBbhcNn*R,U1><8ukJ^DG^]'[WW-\C("Ys-F?d.kJ$FSG`=2/0gdhX[?gU:nTTjoHRFR7AJI9`7Bd8?%"%K*lpS5nq!.C7ha\f[fk]6cIY@6="N(W\<%_S2\cQ-@&=p]lP,75S]se\"=-4^'\'C=]b3G\Bp(YEt`bUI&#SEb]td9TjVsFrmCCnXC?9=Qs0ho`O76m\TL_#RkGb&fO6'd#a@I#5."(P+VTQM^$P,h0n-613;amHYWuY24Kj5t0-QX';j^#WmI#VmRjon)+J[)JdP=T5)AnDlPW\=\=i#n@XR;&q.g2)k0MeVab>=ZCs21G,u+oT3\'4YfjB.oB0)6G]KjX)WB-8iH@U,"c,npYTkaMf"_(LJJ_%Keg&/!SNPE-A'@ZlRa\\UrkC/dR07__eB+'+j!;&TBC+!>3"b2jj/d3SJrujQm2rZ:(naQIeMa7hKpOfagVE'X16VU.PX'oj^P!=9^rV$;jrUcje>nS(0_%sr>n0_anI]Zo!o7BfN)87t9X8gb$cjcslLFlF4M;d2ZEaIkio",smDME)$8aQ--afK65_"D*i+dL.i'M>2ojiFd@4MFmMg.eDA.M_=%QE.a-/7_'=ojHMtG>L=]Bq/I6Zs$O[D;<5(Jl''n[4X)W)CJ%OK:He7^*(;D6R#I-S=I!)*a[]GI=-/7g:Wj:"eg,2nYtjAjl*(ZG1-ChZ&f,ts$+TU:+B=+3P0Ugp%8h$C_.<9OC+W/b4C3]]*/Es#Rp4sXm>6:m%fk=fn'LZO2'N1`l#h]Y[LX%j/1(qRQ#0$V_>dBFZHDVRd4m,'G8nMd,2l2X&d@P\"sY7+#^QD4^>[J"%+9%7E:EnnBog(Wu%UUk0KV^4>+X_e4&'F[Uo'!QYQ0UAabQ/Y&.usZcJ4n?SD,MOV5KJ)Hh1j>(p/GjW>0XeS<%RH^,m'AS!/6Q1oJsH''K3I`p>8I%.G-^'XAYb7aB[d'$g65.u8cn(b'G<-XM>QWDAf(/LTmehd84G#s^j/^,H7?ee^[qU\(Xb:8Or*5d\e#PhMXD_mGRPaN^KXXk`9lH>qm%3I?uDdq>.kf@0*Y2%529:1/jI70$s5t&n!`IDZYrX>*1bi$Al^[SN;h_pddR3jS`/0s]M1M9CR3bcI`;1nc=kg2)ZJ^.Pre3C-%M[AcTKEZV,(D("5=B1E$3Q1;6@?s89jVR;:>YAFI("1@`jHn#/snABBV/&d;r9H)JY(T=p-Y]tnIFnlb]3V3bCA5Ai':`D3e[f0f&>@Zc[7SrcV#brb59*NhsT72A*_.b=`7&0*=s;3))$ti\R#b:o2<__nfC$lo1t.Us72(B+"`s>@;&PDdi]a7UYK1CITSE)E,sDRELoA6Q/>.qd4\eqKP1t3?)\u"@9tEd;Vq!KB29Vq5Od39lW:_ZAQ3]jjrlcE-TV&)Q4X#![kP`$m[fgh6WRr%Ael.48'SFrYc23?][;b^+`3tX/n&KMCB7KEEcp?0,)kDt&kH-YDk3r6,?3M2B8Qr3\>He3a3rkfOfQ:r7JMhZ]Q[CD8WTGB&-I/h3??h\JG]4Cc:?L=0ehiGjl\:=Q:b+Cf+H1Ah(*P"h@^XSb?LU5A+kZ5GL3j5im<6U5l27=X1-EqZCa2nh@h$q:+sp$%OHn1FhHa7eOCduR5HB8u.K;a:!S>]B")cnA@r;bc1IK4=S56/3e*rt*C%fgM2#66^T"+V?e!Pf0=:B]U1IK4?)rS%@_;>U3O%mTkNs0jM&*mrl+$=4%0k4qE2pZ_8SWTcq=KV9(:r:#oRIQIAHm>!"LPb5jn?ZS57W#lmsjfPI01HaPts86%-T'oo;U34>7fB.Reji\l]0&O>A\>Z41m,-,:*WC4UAU:2ccnC*c7cWn4Ar'Vor8b]]bGPm>hN7F,bC/)'W@r3T4R,ARp)*_mg_Cq"3ILD7ot-8+(D`?"4d#AF&$;Y'UmP.MN*V-?%=*rQ]\rC[[%t5$chfXRSijN(h6InOokrBW^8I(kE):oVLUW.:H"G9J)gC^7?LZ"[qi;d_.Fb!2&fObE8R^SA-]]-p&n7/Oo&N@cnf"^ES=ar('GhKJIW4K8q-uX*?b9k&W*X<[#C'u'"RCiVKA,.r;,"HMBc3?)56!P@oS'>)n(`E6Sk/Q3C7H)4u2H4FZq\cAbJ0o"WkhHJt)#4ki@/G\A)`L$OMX]3f5nQPWS5/BRm%n%kc3J%p$kk3]eT$n%2r&+t!an*Z`.[r:*8H/lo(lQhji^NoG%XkS&]f6F-gI&pfHnDX>X\$'-k3.>hmk*>OF)q#t>;*>Gt@/[=7QTMbB6CN*l*]7NFaph_E4*:*o_=*_n>eS.I8`iFt^3tbdbQ6P2Fnq!$Ffe%_G8s#Y9K044]Gmg9g%LN<4]V+VUXr-kg,\$Mu.T/q8W`/.h-S2bNZjJgU@c5%P+nK'pW1[h.Jk6k$,qsh:h+0Sj-D03OQbo>qQSX=lU&Z-Xn16mcA?t=*OJCLP+hTblkoA0:m3;@"_01V*'HK+"b;ljftVIGk3U;PY7=3_CDp/RX-2-Bedn`Xj&n%:7Ai=:a3T,`l_D,;>IX(to':5/qgLbN/e8sdr$+oG+(f-G_#>Fis7Vqc^\VusmTmGJmbD6`SND&`g:_.fQXB2K?K9kU9tl>_PP=!dn%\gAkLPWnZfY%(h7n;1G^u-e;CYX1oH3S6l%5D3M18sPX#&li?2e9X\rE3Z[<:6e?YnW)F4[SNFO:W?p@+FQ/2/@9bX]nkL<[kj)bdqr-CY.XKrb0ge/)Phpq7H*-AS#EkNVVOWQbW:oMNo8-YOTo1k9DL8c'u'B,WDobRcY>(QBCX1`2$Pk@@Hh!8q9:%57p'sNY_caQmal9cG]sV8I]X_t)R6>?:X:4,D5OuIQQotAE6+skJ2@fHRE)t-6O08]M#C?KV@kSsrI_h/oEEs7T%3.:kjfrO']_^?Xa]#'39qTFo:(?o1daP*hR653CCD1"lT/LTBfWer,&/[KPgpj`]Y=q2f!r;Y>A7b#s:7XLe6<`Z16%'D-[V?`?n&8TsliakH<,Jl+AI>irbX@i.1h*qnG[tJ,]NO"qF6CN4d0b^Ron5C/!Dk_hJRBklW6I26[M+R>29MFf@OO,5dHhVD`]67V)2BMbU?+Y:GefB#BI/PoUb8;Mum+J.\f1t^BURQuAq0BSdPg$`MRlZ.;YLn;+gXrb7d.'6ID;@[b/Of::e@Kd=Co^Sk0eHU!ZW[oJJ%fL;Q8-HR@-:9+P#fuNNGTCD*Rutj/1dN"M)hk2@E^H\kVXW[?NPM0CtltY63^-9OPmnSIig=&(UZjf[BgUL*c+'nJk0DZQ'8Q*c,6TbO&"m(lg)U^Vj%,4r-\0ZUoK_H?34?>n?e8X'343of@/R+7I@%88_A=perT*JfLt<98k17gZ\saBX.+Z%V5fU&c'8f8=$pW?I6@`!LS5jeL=f.p;Ai,6c%/3%',!@\ZV[8Q2j]kBWlaoY.$[Ekp$E=#*r:If28mMcf%,jm&+JI\]9_U`og?e/UJ5kmKWN5CL9M]'AnqJ;^W=OUInfkiZ83qW4/s6/.#A8k5]'P`A"'YW%&M>,Gfn/sZ4!t32D`nAcr1C;b0Ce!#QX(BIK4=S56/3e*rt*C%fgM2#66^T"+V?e!OYBb8pXN=H:e=$9;3M)4+q0OY:M.S/M/NR]Ug"\f;e$>e-7runPmtpndI^r,)1Ps`QKZTf!BNm1<D$g]b.ke-ckthE)0!G''ojHXPk7K<$\[ilRGreh'ZO>g'HK_OTNJRQ;Cq'Cl:!%:ErhI\0/H8ZR'ZoFKHnZ@u9VQ52dU,8^K6Sldh[+_^5V0'Zf;#YB3n]#9B,+EI(1m%-+8Z7U#aeOY:%bHdCdN6A(70fAPn./F]'YD^eX^'o&29<4U71@E1sCtN>"M:(fa@b1]l=m9k:e^qbTaa)VLB5n/gI)QG>:`<_I'*:WJ"^+Pf1S]ck)ns*n5@9V)@q@r6.2W?[YAQ^q\(;9pJ9r3Cp:_)3<)4#9)B5^[;Ha\hoAHnOC[8d"*?UDf#`kd+qc73FYAW7-7R,#%:cTnB1.EV+";.0L^g?K-5ct5!0(c],g;n7AtaX;;ci(Z0/pR#0:)c$O6Rihah3Z#n+B$g5j(3I1PDJOuDA+rfb$e-ZNY!G91A_d94i\GHFgNpW>n@)SF6Vp0NK5`pB,X'?@kPOrPP['c,`0F`]l5^c\\,+7Ql<"?(!9f<+e_@ACk;QoKBV[-=rbQ9KH^CZA>`VY!OF(t1I3H2F:ugY5o,+(,n)XddSC^OqTmaDAH:1LY6!6I=-`tJB:s!DpXm]QJ/HY5\Q@KG$P`,p[(1!AakeTe/4]2W.2QGM;:527YM*CH+HsnYL!e64n]>@S]&@l`BtFYg,M.%?0?)gH7&@N9oiUPM$`]X3jal\(*;Q*mAa2BgFKr8!;!F(s$CBP;lI*q](ulRS$n,eh6pVd%NRXYU18rgmGlp-MN3Q&D;aUEk,`#F+4snNGqf2)0-G9];\1&N^lYdV-;C8([tpnOMrmm]RPkWd%1;UtEcZD'aJpj7kQdK+Q2UiZ08POuQd.6,0W8DNBGaH16UHADe?A'$m@i&aojBEpkQdK1Q2UhoCG1r'*Aq#E:N%>GYFiRZ4c9%3q<<"X?LFuAC)-"7k#G[uM-Q`p;EJZ"h;(4V4K7?!md?rpd4jsL9::+iG?1KF$L3FEg`/+LMbT($M=D*d2.IQLom5=]gO',11V)-%Ym%oVAr8k%.ukM^jN5T2T3V$km3PjR;UYZ)qojhJ2pU=*Es+k[Nm\=NiYtrZibtioi)r(4Zu'(:DJ\LPsl8\/:m!k?%HW#qO@Nczzzzzzzzzz!!!;nrrHe?D+=~>endstream -endobj -10 0 obj -<< /BaseFont /Helvetica-Oblique /Encoding /WinAnsiEncoding /Name /F3 /Subtype /Type1 /Type /Font >> -endobj -11 0 obj -<< /Annots [ 5 0 R 6 0 R 7 0 R ] /Contents 140 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 138 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] /XObject << /FormXob.12938940ef036783ae43d04dbfa3ae60 8 0 R >> >> /Rotate 0 - /Trans << >> /Type /Page >> -endobj -12 0 obj -<< /BaseFont /Courier /Encoding /WinAnsiEncoding /Name /F4 /Subtype /Type1 /Type /Font >> -endobj -13 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 11 0 R /XYZ 277.9078 281.6969 0 ] /Rect [ 334.6308 537.7736 377.2747 549.7736 ] /Subtype /Link /Type /Annot >> -endobj -14 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 27 0 R /XYZ 62.69291 768.5236 0 ] /Rect [ 108.8329 465.7736 235.5429 477.7736 ] /Subtype /Link /Type /Annot >> -endobj -15 0 obj -<< /BaseFont /Courier-Bold /Encoding /WinAnsiEncoding /Name /F5 /Subtype /Type1 /Type /Font >> -endobj -16 0 obj -<< /Annots [ 13 0 R 14 0 R ] /Contents 141 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 138 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 - /Trans << >> /Type /Page >> -endobj -17 0 obj -<< /Contents 142 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 138 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> - /Type /Page >> -endobj -18 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 16 0 R /XYZ 62.69291 211.0236 0 ] /Rect [ 142.7229 384.7736 259.9929 396.7736 ] /Subtype /Link /Type /Annot >> -endobj -19 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 16 0 R /XYZ 62.69291 211.0236 0 ] /Rect [ 82.18163 217.5736 199.5091 229.5736 ] /Subtype /Link /Type /Annot >> -endobj -20 0 obj -<< /Annots [ 18 0 R 19 0 R ] /Contents 143 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 138 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 - /Trans << >> /Type /Page >> -endobj -21 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 80 0 R /XYZ 62.69291 768.0236 0 ] /Rect [ 146.4635 575.5736 165.8604 587.5736 ] /Subtype /Link /Type /Annot >> -endobj -22 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 80 0 R /XYZ 62.69291 267.4772 0 ] /Rect [ 494.7827 563.5736 530.6387 575.5736 ] /Subtype /Link /Type /Annot >> -endobj -23 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 27 0 R /XYZ 62.69291 293.8236 0 ] /Rect [ 374.5352 521.5736 415.7146 533.5736 ] /Subtype /Link /Type /Annot >> -endobj -24 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 27 0 R /XYZ 62.69291 293.8236 0 ] /Rect [ 359.0861 509.5736 400.3222 521.5736 ] /Subtype /Link /Type /Annot >> -endobj -25 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 27 0 R /XYZ 62.69291 293.8236 0 ] /Rect [ 452.5015 497.5736 494.2327 509.5736 ] /Subtype /Link /Type /Annot >> -endobj -26 0 obj -<< /Annots [ 21 0 R 22 0 R 23 0 R 24 0 R 25 0 R ] /Contents 144 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 138 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 - /Trans << >> /Type /Page >> -endobj -27 0 obj -<< /Contents 145 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 138 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> - /Type /Page >> -endobj -28 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 55 0 R /XYZ 62.69291 364.9236 0 ] /Rect [ 158.3554 401.3736 185.741 413.3736 ] /Subtype /Link /Type /Annot >> -endobj -29 0 obj -<< /Annots [ 28 0 R ] /Contents 146 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 138 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 - /Trans << >> /Type /Page >> -endobj -30 0 obj -<< /Contents 147 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 138 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> - /Type /Page >> -endobj -31 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 34 0 R /XYZ 62.69291 450.6236 0 ] /Rect [ 62.69291 741.7736 152.0372 753.7736 ] /Subtype /Link /Type /Annot >> -endobj -32 0 obj -<< /Annots [ 31 0 R ] /Contents 148 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 138 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 - /Trans << >> /Type /Page >> -endobj -33 0 obj -<< /BaseFont /Helvetica-BoldOblique /Encoding /WinAnsiEncoding /Name /F6 /Subtype /Type1 /Type /Font >> -endobj -34 0 obj -<< /Contents 149 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 138 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> - /Type /Page >> -endobj -35 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 80 0 R /XYZ 62.69291 768.0236 0 ] /Rect [ 438.6533 132.1736 458.1057 144.1736 ] /Subtype /Link /Type /Annot >> -endobj -36 0 obj -<< /Annots [ 35 0 R ] /Contents 150 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 138 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 - /Trans << >> /Type /Page >> -endobj -37 0 obj -<< /Contents 151 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 138 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> - /Type /Page >> -endobj -38 0 obj -<< /Contents 152 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 138 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> - /Type /Page >> -endobj -39 0 obj -<< /Contents 153 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 138 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> - /Type /Page >> -endobj -40 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 62 0 R /XYZ 62.69291 290.0772 0 ] /Rect [ 316.1194 122.9736 367.0881 134.9736 ] /Subtype /Link /Type /Annot >> -endobj -41 0 obj -<< /Annots [ 40 0 R ] /Contents 154 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 138 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 - /Trans << >> /Type /Page >> -endobj -42 0 obj -<< /Contents 155 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 138 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> - /Type /Page >> -endobj -43 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 60 0 R /XYZ 62.69291 591.0236 0 ] /Rect [ 85.69291 302.1736 532.5827 314.1736 ] /Subtype /Link /Type /Annot >> -endobj -44 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 62 0 R /XYZ 62.69291 768.0236 0 ] /Rect [ 85.69291 284.1736 532.5827 296.1736 ] /Subtype /Link /Type /Annot >> -endobj -45 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 62 0 R /XYZ 62.69291 290.0772 0 ] /Rect [ 85.69291 266.1736 532.5827 278.1736 ] /Subtype /Link /Type /Annot >> -endobj -46 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 63 0 R /XYZ 62.69291 694.4772 0 ] /Rect [ 85.69291 248.1736 532.5827 260.1736 ] /Subtype /Link /Type /Annot >> -endobj -47 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 63 0 R /XYZ 62.69291 451.9307 0 ] /Rect [ 85.69291 230.1736 532.5827 242.1736 ] /Subtype /Link /Type /Annot >> -endobj -48 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 63 0 R /XYZ 62.69291 197.3843 0 ] /Rect [ 85.69291 212.1736 532.5827 224.1736 ] /Subtype /Link /Type /Annot >> -endobj -49 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 66 0 R /XYZ 62.69291 318.2772 0 ] /Rect [ 85.69291 194.1736 532.5827 206.1736 ] /Subtype /Link /Type /Annot >> -endobj -50 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 68 0 R /XYZ 62.69291 653.4772 0 ] /Rect [ 85.69291 176.1736 532.5827 188.1736 ] /Subtype /Link /Type /Annot >> -endobj -51 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 68 0 R /XYZ 62.69291 343.9307 0 ] /Rect [ 85.69291 158.1736 532.5827 170.1736 ] /Subtype /Link /Type /Annot >> -endobj -52 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 69 0 R /XYZ 62.69291 694.4772 0 ] /Rect [ 85.69291 140.1736 532.5827 152.1736 ] /Subtype /Link /Type /Annot >> -endobj -53 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 69 0 R /XYZ 62.69291 204.5307 0 ] /Rect [ 85.69291 122.1736 532.5827 134.1736 ] /Subtype /Link /Type /Annot >> -endobj -54 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 75 0 R /XYZ 62.69291 727.6772 0 ] /Rect [ 85.69291 104.1736 532.5827 116.1736 ] /Subtype /Link /Type /Annot >> -endobj -55 0 obj -<< /Annots [ 43 0 R 44 0 R 45 0 R 46 0 R 47 0 R 48 0 R 49 0 R 50 0 R 51 0 R 52 0 R - 53 0 R 54 0 R ] /Contents 156 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 138 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 - /Trans << >> /Type /Page >> -endobj -56 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 74 0 R /XYZ 62.69291 715.6772 0 ] /Rect [ 85.69291 750.7736 532.5827 762.7736 ] /Subtype /Link /Type /Annot >> -endobj -57 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 74 0 R /XYZ 62.69291 225.7307 0 ] /Rect [ 85.69291 732.7736 532.5827 744.7736 ] /Subtype /Link /Type /Annot >> -endobj -58 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 80 0 R /XYZ 62.69291 768.0236 0 ] /Rect [ 85.69291 714.7736 532.5827 726.7736 ] /Subtype /Link /Type /Annot >> -endobj -59 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 80 0 R /XYZ 62.69291 267.4772 0 ] /Rect [ 85.69291 696.7736 532.5827 708.7736 ] /Subtype /Link /Type /Annot >> -endobj -60 0 obj -<< /Annots [ 56 0 R 57 0 R 58 0 R 59 0 R ] /Contents 157 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 138 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 - /Trans << >> /Type /Page >> -endobj -61 0 obj -<< /A << /S /URI /Type /Action /URI (mailto:jane@example.com) >> /Border [ 0 0 0 ] /Rect [ 220.6129 102.8272 309.1229 114.8272 ] /Subtype /Link /Type /Annot >> -endobj -62 0 obj -<< /Annots [ 61 0 R ] /Contents 158 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 138 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 - /Trans << >> /Type /Page >> -endobj -63 0 obj -<< /Contents 159 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 138 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> - /Type /Page >> -endobj -64 0 obj -<< /A << /S /URI /Type /Action /URI (mailto:user@domain) >> /Border [ 0 0 0 ] /Rect [ 220.4912 582.7736 282.8812 594.7736 ] /Subtype /Link /Type /Annot >> -endobj -65 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 63 0 R /XYZ 62.69291 197.3843 0 ] /Rect [ 487.4727 138.0272 520.9127 150.0272 ] /Subtype /Link /Type /Annot >> -endobj -66 0 obj -<< /Annots [ 64 0 R 65 0 R ] /Contents 160 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 138 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 - /Trans << >> /Type /Page >> -endobj -67 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 63 0 R /XYZ 62.69291 197.3843 0 ] /Rect [ 442.6147 492.2272 476.6807 504.2272 ] /Subtype /Link /Type /Annot >> -endobj -68 0 obj -<< /Annots [ 67 0 R ] /Contents 161 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 138 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 - /Trans << >> /Type /Page >> -endobj -69 0 obj -<< /Contents 162 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 138 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> - /Type /Page >> -endobj -70 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 69 0 R /XYZ 62.69291 694.4772 0 ] /Rect [ 197.1929 753.7736 223.8629 765.7736 ] /Subtype /Link /Type /Annot >> -endobj -71 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 69 0 R /XYZ 62.69291 694.4772 0 ] /Rect [ 401.1829 753.7736 427.8529 765.7736 ] /Subtype /Link /Type /Annot >> -endobj -72 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 74 0 R /XYZ 62.69291 715.6772 0 ] /Rect [ 199.4129 107.4807 209.9729 119.4807 ] /Subtype /Link /Type /Annot >> -endobj -73 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 74 0 R /XYZ 62.69291 715.6772 0 ] /Rect [ 410.0829 107.4807 420.6429 119.4807 ] /Subtype /Link /Type /Annot >> -endobj -74 0 obj -<< /Annots [ 70 0 R 71 0 R 72 0 R 73 0 R ] /Contents 163 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 138 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 - /Trans << >> /Type /Page >> -endobj -75 0 obj -<< /Contents 164 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 138 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> - /Type /Page >> -endobj -76 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 74 0 R /XYZ 62.69291 715.6772 0 ] /Rect [ 177.2584 637.7736 188.2523 649.7736 ] /Subtype /Link /Type /Annot >> -endobj -77 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 75 0 R /XYZ 62.69291 727.6772 0 ] /Rect [ 200.3562 637.7736 242.47 649.7736 ] /Subtype /Link /Type /Annot >> -endobj -78 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 74 0 R /XYZ 62.69291 715.6772 0 ] /Rect [ 177.2584 138.2272 188.2523 150.2272 ] /Subtype /Link /Type /Annot >> -endobj -79 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 75 0 R /XYZ 62.69291 727.6772 0 ] /Rect [ 200.3562 138.2272 242.47 150.2272 ] /Subtype /Link /Type /Annot >> -endobj -80 0 obj -<< /Annots [ 76 0 R 77 0 R 78 0 R 79 0 R ] /Contents 165 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 138 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 - /Trans << >> /Type /Page >> -endobj -81 0 obj -<< /Contents 166 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 138 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> - /Type /Page >> -endobj -82 0 obj -<< /Outlines 84 0 R /PageLabels 167 0 R /PageMode /UseNone /Pages 138 0 R /Type /Catalog >> -endobj -83 0 obj -<< /Author () /CreationDate (D:20141102111551+05'00') /Creator (\(unspecified\)) /Keywords () /Producer (ReportLab PDF Library - www.reportlab.com) /Subject (\(unspecified\)) - /Title () >> -endobj -84 0 obj -<< /Count 73 /First 85 0 R /Last 107 0 R /Type /Outlines >> -endobj -85 0 obj -<< /Count 3 /Dest [ 4 0 R /XYZ 62.69291 765.0236 0 ] /First 86 0 R /Last 88 0 R /Next 89 0 R /Parent 84 0 R - /Title (Introduction) >> -endobj -86 0 obj -<< /Dest [ 11 0 R /XYZ 62.69291 681.0236 0 ] /Next 87 0 R /Parent 85 0 R /Title (Implementation Status) >> -endobj -87 0 obj -<< /Dest [ 11 0 R /XYZ 62.69291 555.0236 0 ] /Next 88 0 R /Parent 85 0 R /Prev 86 0 R /Title (General Data Flow) >> -endobj -88 0 obj -<< /Dest [ 16 0 R /XYZ 62.69291 597.0236 0 ] /Parent 85 0 R /Prev 87 0 R /Title (Example Assertion Transformation) >> -endobj -89 0 obj -<< /Count 1 /Dest [ 26 0 R /XYZ 62.69291 715.8236 0 ] /First 90 0 R /Last 90 0 R /Next 91 0 R /Parent 84 0 R - /Prev 85 0 R /Title (Operation Model) >> -endobj -90 0 obj -<< /Dest [ 26 0 R /XYZ 62.69291 454.8236 0 ] /Parent 89 0 R /Title (Pseudo Code Illustrating Operational Model) >> -endobj -91 0 obj -<< /Count 7 /Dest [ 27 0 R /XYZ 62.69291 765.0236 0 ] /First 92 0 R /Last 98 0 R /Next 99 0 R /Parent 84 0 R - /Prev 89 0 R /Title (Structure Of Rule Definitions) >> -endobj -92 0 obj -<< /Dest [ 27 0 R /XYZ 62.69291 290.8236 0 ] /Next 93 0 R /Parent 91 0 R /Title (Mapping) >> -endobj -93 0 obj -<< /Dest [ 29 0 R /XYZ 62.69291 478.6236 0 ] /Next 94 0 R /Parent 91 0 R /Prev 92 0 R /Title (Syntax) >> -endobj -94 0 obj -<< /Dest [ 30 0 R /XYZ 62.69291 485.8236 0 ] /Next 95 0 R /Parent 91 0 R /Prev 93 0 R /Title (Data Types) >> -endobj -95 0 obj -<< /Dest [ 30 0 R /XYZ 62.69291 191.8236 0 ] /Next 96 0 R /Parent 91 0 R /Prev 94 0 R /Title (Rule Debugging and Documentation) >> -endobj -96 0 obj -<< /Count 1 /Dest [ 32 0 R /XYZ 62.69291 257.8236 0 ] /First 97 0 R /Last 97 0 R /Next 98 0 R /Parent 91 0 R - /Prev 95 0 R /Title (Variables) >> -endobj -97 0 obj -<< /Dest [ 34 0 R /XYZ 62.69291 528.6236 0 ] /Parent 96 0 R /Title (Escaping) >> -endobj -98 0 obj -<< /Dest [ 34 0 R /XYZ 62.69291 447.6236 0 ] /Parent 91 0 R /Prev 96 0 R /Title (Reserved Variables) >> -endobj -99 0 obj -<< /Count 6 /Dest [ 36 0 R /XYZ 62.69291 765.0236 0 ] /First 100 0 R /Last 105 0 R /Next 106 0 R /Parent 84 0 R - /Prev 91 0 R /Title (Examples) >> -endobj -100 0 obj -<< /Dest [ 36 0 R /XYZ 62.69291 732.0236 0 ] /Next 101 0 R /Parent 99 0 R /Title (Split a fully qualified username into user and realm components) >> -endobj -101 0 obj -<< /Dest [ 37 0 R /XYZ 62.69291 691.8236 0 ] /Next 102 0 R /Parent 99 0 R /Prev 100 0 R /Title (Build a set of roles based on group membership) >> -endobj -102 0 obj -<< /Dest [ 38 0 R /XYZ 62.69291 193.4236 0 ] /Next 103 0 R /Parent 99 0 R /Prev 101 0 R /Title (White list certain users and grant them specific roles) >> -endobj -103 0 obj -<< /Dest [ 41 0 R /XYZ 62.69291 765.0236 0 ] /Next 104 0 R /Parent 99 0 R /Prev 102 0 R /Title (Black list certain users) >> -endobj -104 0 obj -<< /Dest [ 41 0 R /XYZ 62.69291 158.2236 0 ] /Next 105 0 R /Parent 99 0 R /Prev 103 0 R /Title (Format Strings and/or Concatenate Strings) >> -endobj -105 0 obj -<< /Dest [ 42 0 R /XYZ 62.69291 225.0236 0 ] /Parent 99 0 R /Prev 104 0 R /Title (Make associative array lookups case insensitive) >> -endobj -106 0 obj -<< /Dest [ 55 0 R /XYZ 62.69291 361.4236 0 ] /Next 107 0 R /Parent 84 0 R /Prev 99 0 R /Title (Verbs) >> -endobj -107 0 obj -<< /Count 30 /Dest [ 60 0 R /XYZ 62.69291 621.0236 0 ] /First 108 0 R /Last 136 0 R /Parent 84 0 R /Prev 106 0 R - /Title (Verb Definitions) >> -endobj -108 0 obj -<< /Count 1 /Dest [ 60 0 R /XYZ 62.69291 588.0236 0 ] /First 109 0 R /Last 109 0 R /Next 110 0 R /Parent 107 0 R - /Title (set) >> -endobj -109 0 obj -<< /Dest [ 60 0 R /XYZ 62.69291 460.0236 0 ] /Parent 108 0 R /Title (Examples:) >> -endobj -110 0 obj -<< /Count 1 /Dest [ 62 0 R /XYZ 62.69291 765.0236 0 ] /First 111 0 R /Last 111 0 R /Next 112 0 R /Parent 107 0 R - /Prev 108 0 R /Title (length) >> -endobj -111 0 obj -<< /Dest [ 62 0 R /XYZ 62.69291 544.0236 0 ] /Parent 110 0 R /Title (Examples:) >> -endobj -112 0 obj -<< /Count 1 /Dest [ 62 0 R /XYZ 62.69291 287.0772 0 ] /First 113 0 R /Last 113 0 R /Next 114 0 R /Parent 107 0 R - /Prev 110 0 R /Title (interpolate) >> -endobj -113 0 obj -<< /Dest [ 62 0 R /XYZ 62.69291 147.0772 0 ] /Parent 112 0 R /Title (Examples:) >> -endobj -114 0 obj -<< /Count 1 /Dest [ 63 0 R /XYZ 62.69291 691.4772 0 ] /First 115 0 R /Last 115 0 R /Next 116 0 R /Parent 107 0 R - /Prev 112 0 R /Title (append) >> -endobj -115 0 obj -<< /Dest [ 63 0 R /XYZ 62.69291 563.4772 0 ] /Parent 114 0 R /Title (Examples:) >> -endobj -116 0 obj -<< /Count 1 /Dest [ 63 0 R /XYZ 62.69291 448.9307 0 ] /First 117 0 R /Last 117 0 R /Next 118 0 R /Parent 107 0 R - /Prev 114 0 R /Title (unique) >> -endobj -117 0 obj -<< /Dest [ 63 0 R /XYZ 62.69291 308.9307 0 ] /Parent 116 0 R /Title (Examples:) >> -endobj -118 0 obj -<< /Count 1 /Dest [ 63 0 R /XYZ 62.69291 194.3843 0 ] /First 119 0 R /Last 119 0 R /Next 120 0 R /Parent 107 0 R - /Prev 116 0 R /Title (regexp) >> -endobj -119 0 obj -<< /Dest [ 66 0 R /XYZ 62.69291 615.0236 0 ] /Parent 118 0 R /Title (Examples:) >> -endobj -120 0 obj -<< /Count 1 /Dest [ 66 0 R /XYZ 62.69291 315.2772 0 ] /First 121 0 R /Last 121 0 R /Next 122 0 R /Parent 107 0 R - /Prev 118 0 R /Title (regexp_replace) >> -endobj -121 0 obj -<< /Dest [ 68 0 R /XYZ 62.69291 765.0236 0 ] /Parent 120 0 R /Title (Examples:) >> -endobj -122 0 obj -<< /Count 1 /Dest [ 68 0 R /XYZ 62.69291 650.4772 0 ] /First 123 0 R /Last 123 0 R /Next 124 0 R /Parent 107 0 R - /Prev 120 0 R /Title (split) >> -endobj -123 0 obj -<< /Dest [ 68 0 R /XYZ 62.69291 467.4772 0 ] /Parent 122 0 R /Title (Examples:) >> -endobj -124 0 obj -<< /Count 1 /Dest [ 68 0 R /XYZ 62.69291 340.9307 0 ] /First 125 0 R /Last 125 0 R /Next 126 0 R /Parent 107 0 R - /Prev 122 0 R /Title (join) >> -endobj -125 0 obj -<< /Dest [ 68 0 R /XYZ 62.69291 169.9307 0 ] /Parent 124 0 R /Title (Examples:) >> -endobj -126 0 obj -<< /Count 1 /Dest [ 69 0 R /XYZ 62.69291 691.4772 0 ] /First 127 0 R /Last 127 0 R /Next 128 0 R /Parent 107 0 R - /Prev 124 0 R /Title (lower) >> -endobj -127 0 obj -<< /Dest [ 69 0 R /XYZ 62.69291 446.4772 0 ] /Parent 126 0 R /Title (Examples:) >> -endobj -128 0 obj -<< /Dest [ 69 0 R /XYZ 62.69291 201.5307 0 ] /Next 129 0 R /Parent 107 0 R /Prev 126 0 R /Title (upper) >> -endobj -129 0 obj -<< /Count 1 /Dest [ 74 0 R /XYZ 62.69291 712.6772 0 ] /First 130 0 R /Last 130 0 R /Next 131 0 R /Parent 107 0 R - /Prev 128 0 R /Title (in) >> -endobj -130 0 obj -<< /Dest [ 74 0 R /XYZ 62.69291 479.6772 0 ] /Parent 129 0 R /Title (Examples:) >> -endobj -131 0 obj -<< /Dest [ 74 0 R /XYZ 62.69291 222.7307 0 ] /Next 132 0 R /Parent 107 0 R /Prev 129 0 R /Title (not_in) >> -endobj -132 0 obj -<< /Count 1 /Dest [ 75 0 R /XYZ 62.69291 724.6772 0 ] /First 133 0 R /Last 133 0 R /Next 134 0 R /Parent 107 0 R - /Prev 131 0 R /Title (compare) >> -endobj -133 0 obj -<< /Dest [ 75 0 R /XYZ 62.69291 235.6772 0 ] /Parent 132 0 R /Title (Examples:) >> -endobj -134 0 obj -<< /Count 1 /Dest [ 80 0 R /XYZ 62.69291 765.0236 0 ] /First 135 0 R /Last 135 0 R /Next 136 0 R /Parent 107 0 R - /Prev 132 0 R /Title (exit) >> -endobj -135 0 obj -<< /Dest [ 80 0 R /XYZ 62.69291 391.0236 0 ] /Parent 134 0 R /Title (Examples:) >> -endobj -136 0 obj -<< /Count 1 /Dest [ 80 0 R /XYZ 62.69291 264.4772 0 ] /First 137 0 R /Last 137 0 R /Parent 107 0 R /Prev 134 0 R - /Title (continue) >> -endobj -137 0 obj -<< /Dest [ 81 0 R /XYZ 62.69291 621.0236 0 ] /Parent 136 0 R /Title (Examples:) >> -endobj -138 0 obj -<< /Count 28 /Kids [ 4 0 R 11 0 R 16 0 R 17 0 R 20 0 R 26 0 R 27 0 R 29 0 R 30 0 R 32 0 R - 34 0 R 36 0 R 37 0 R 38 0 R 39 0 R 41 0 R 42 0 R 55 0 R 60 0 R 62 0 R - 63 0 R 66 0 R 68 0 R 69 0 R 74 0 R 75 0 R 80 0 R 81 0 R ] /Type /Pages >> -endobj -139 0 obj -<< /Length 9118 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 744.0236 cm -q -BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Introduction) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 666.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 62 Tm /F1 10 Tf 12 TL 3.09832 Tw (A need shared by many applications is the ability to authenticate a user and then bind a set of) Tj T* 0 Tw .363735 Tw (permissions to the user which indicate what actions the user is permitted to perform \(i.e. authorization\). A) Tj T* 0 Tw .317126 Tw (LocalSystem may have implemented it's own authentication and authorization and now wishes to utilize a) Tj T* 0 Tw 1.045366 Tw (federated Identity Provider \(IdP\). Typically the IdP provides an assertion with information describing the) Tj T* 0 Tw 1.041235 Tw (authenticated user. The goal is to transform the IdP assertion into a LocalSystem token. In it's simplest) Tj T* 0 Tw (terms this is a data transformation which might include:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 660.0236 cm -Q -q -1 0 0 1 62.69291 660.0236 cm -Q -q -1 0 0 1 62.69291 648.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (renaming of data items) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 642.0236 cm -Q -q -1 0 0 1 62.69291 630.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (conversion to a different format) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 624.0236 cm -Q -q -1 0 0 1 62.69291 612.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (deletion of data) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 606.0236 cm -Q -q -1 0 0 1 62.69291 594.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (addition of data) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 588.0236 cm -Q -q -1 0 0 1 62.69291 576.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (reorganization of data) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 576.0236 cm -Q -q -1 0 0 1 62.69291 558.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (There are many ways such a transformation could be implemented:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 552.0236 cm -Q -q -1 0 0 1 62.69291 552.0236 cm -Q -q -1 0 0 1 62.69291 540.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (1.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Custom site specific code) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 534.0236 cm -Q -q -1 0 0 1 62.69291 522.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (2.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Scripts written in a scripting language) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 516.0236 cm -Q -q -1 0 0 1 62.69291 504.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (3.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (XSLT) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 498.0236 cm -Q -q -1 0 0 1 62.69291 486.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (4.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Rule based transforms) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 486.0236 cm -Q -q -1 0 0 1 62.69291 468.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (We also desire these goals for the transformation.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 462.0236 cm -Q -q -1 0 0 1 62.69291 462.0236 cm -Q -q -1 0 0 1 62.69291 450.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (1.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Site administrator configurable) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 444.0236 cm -Q -q -1 0 0 1 62.69291 432.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (2.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Secure) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 426.0236 cm -Q -q -1 0 0 1 62.69291 414.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (3.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Simple) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 408.0236 cm -Q -q -1 0 0 1 62.69291 396.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (4.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Extensible) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 390.0236 cm -Q -q -1 0 0 1 62.69291 378.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (5.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Efficient) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 378.0236 cm -Q -q -1 0 0 1 62.69291 348.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 1.294987 Tw (Implementation choice 1, custom written code fails goals 1, 3 and 4, an admin cannot adapt it, it's not) Tj T* 0 Tw (simple, and it's likely to be difficult to extend.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 234.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 98 Tm /F1 10 Tf 12 TL 1.607318 Tw (Implementation choice 2, script based transformations have a lot of appeal. Because one has at their) Tj T* 0 Tw 2.25811 Tw (disposal the full power of an actual programming language there are virtually no limitations. If it's a) Tj T* 0 Tw 1.021235 Tw (popular scripting language an administrator is likely to already know the language and might be able to) Tj T* 0 Tw .343516 Tw (program a new transformation or at a minimum tweak an existing script. Forking out to a script interpreter) Tj T* 0 Tw 2.779983 Tw (is inefficient, but it's now possible to embed script interpreters in the existing application. However) Tj T* 0 Tw .01436 Tw (sandboxing the execution of a script such that it cannot perform malicious operations is difficult. One could) Tj T* 0 Tw 2.200651 Tw (run a separate script process to provide sandboxing but this introduces the vagaries of managing a) Tj T* 0 Tw .257126 Tw (subordinate process and inter-process communication. Therefore scripts either fail goals 1 or 5, secure or) Tj T* 0 Tw (efficient \(depending on whether the interpreter is embedded or not\).) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 204.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 2.236098 Tw (Implementation choice 3, XSLT fails goals 3 and 4, it is not simple, it may not have the necessary) Tj T* 0 Tw (features, and extending XSLT is difficult.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 138.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 50 Tm /F1 10 Tf 12 TL .492126 Tw (Implementation choice 4, rules based transformations offers the best combination of features to meet the) Tj T* 0 Tw 1.12784 Tw (goals. Site administrators can understand rules and edit them. There are no sandboxing concerns, rule) Tj T* 0 Tw .633516 Tw (evaluation can be crafted to be secure. With careful design the rule syntax can easily be extended. Rule) Tj T* 0 Tw .775984 Tw (execution should be efficient because it's implemented in a native library loaded into the application and) Tj T* 0 Tw (does not depend on forking out to a separate process or using inter-process communication.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 96.02362 cm -q -BT 1 0 0 1 0 26 Tm .044431 Tw 12 TL /F1 10 Tf 0 0 0 rg (We describe a rule based system which offers much of the power and flexibility of a scripting language but ) Tj T* 0 Tw .69561 Tw (without it's downsides. The rules are written much like a scripting language where you can call functions ) Tj T* 0 Tw 1.681751 Tw (\(e.g. verbs\) and perform simple branching logic based on the result of a prior verb. Variables can be) Tj T* 0 Tw ET -Q -Q -q -1 0 0 1 56.69291 56.69291 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 234.8349 0 Td (-1-) Tj T* -234.8349 0 Td ET -Q -Q - -endstream -endobj -140 0 obj -<< /Length 5289 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 693.0236 cm -q -BT 1 0 0 1 0 62 Tm .682651 Tw 12 TL /F1 10 Tf 0 0 0 rg (assigned and referenced. As described in the ) Tj 0 0 .501961 rg (Variables ) Tj 0 0 0 rg (section a variable may be scalar, an associative) Tj T* 0 Tw .813735 Tw (array \(key/value\), or an indexed array \(ordered list\). A number of different data types are supported and) Tj T* 0 Tw .655777 Tw (are described in the ) Tj 0 0 .501961 rg (Data Types ) Tj 0 0 0 rg (section. Because the rules are written in JSON it should be easy for an) Tj T* 0 Tw .348651 Tw (administrator to understand and JSON provides the ability load site specific hardcoded data the rules can) Tj T* 0 Tw 1.552927 Tw (utilize. For example white lists, black lists, valid groups, invalid groups, etc. are all easy to express in) Tj T* 0 Tw (JSON.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 663.0236 cm -q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Implementation Status) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 633.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 4.236647 Tw (The Mapping Rule Processor described in this document currently has implmentations in these) Tj T* 0 Tw (languages:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 627.0236 cm -Q -q -1 0 0 1 62.69291 627.0236 cm -Q -q -1 0 0 1 62.69291 615.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Java) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 609.0236 cm -Q -q -1 0 0 1 62.69291 597.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Python) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 597.0236 cm -Q -q -1 0 0 1 62.69291 567.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 1.52686 Tw (An application simply needs to load the implementation and invoke it's entry points. It is expected the) Tj T* 0 Tw (rules will reside in site specific configuration files.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 537.0236 cm -q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (General Data Flow) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 495.0236 cm -q -BT 1 0 0 1 0 26 Tm .18686 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (Figure 1. ) Tj 0 0 0 rg (illustrates the processing inside the application when it needs to authenticate a user and provide) Tj T* 0 Tw 4.125984 Tw (a LocalSystem token identifying the user, providing attributes bound to the user, and a set of) Tj T* 0 Tw (authorizations for the actions the user is permitted to perform \(e.g. roles\).) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 489.0236 cm -Q -q -1 0 0 1 62.69291 264.6969 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 21 cm -q -457.8898 0 0 200.3268 0 0 cm -/FormXob.12938940ef036783ae43d04dbfa3ae60 Do -Q -Q -q -1 0 0 1 6 3 cm -q -BT 1 0 0 1 0 2 Tm 209.2149 0 Td 12 TL /F3 10 Tf 0 0 0 rg (Figure 1.) Tj T* -209.2149 0 Td ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 264.6969 cm -Q -q -1 0 0 1 62.69291 258.6969 cm -Q -q -1 0 0 1 62.69291 231.6969 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 15 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 39.69937 0 Td (Step 1:) Tj T* -39.69937 0 Td ET -Q -Q -q -1 0 0 1 91.03937 3 cm -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 2.352533 Tw (A federated Identity Provider \(IdP\) is asked to authenticate a user and provide) Tj T* 0 Tw (additional information \(attributes\) concerning the user.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 192.6969 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 27 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 39.69937 0 Td (Step 2:) Tj T* -39.69937 0 Td ET -Q -Q -q -1 0 0 1 91.03937 3 cm -q -0 0 0 rg -BT 1 0 0 1 0 26 Tm /F1 10 Tf 12 TL 1.860036 Tw (Upon successful authentication the IdP provides an assertion for the user which) Tj T* 0 Tw 5.492039 Tw (also contains extra information \(attributes\) bound to the user \(e.g. group) Tj T* 0 Tw (membership, authorizations, etc.\)) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 99.69685 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 81 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 39.69937 0 Td (Step 3:) Tj T* -39.69937 0 Td ET -Q -Q -q -1 0 0 1 91.03937 57 cm -q -0 0 0 rg -BT 1 0 0 1 0 26 Tm /F1 10 Tf 12 TL 4.068366 Tw (The mapper is invoked to transform the external IdP assertion into a local) Tj T* 0 Tw 3.138933 Tw (representation. The transformation occurs according to the rules and mapping) Tj T* 0 Tw (templates loaded into the rule processor.) Tj T* ET -Q -Q -q -1 0 0 1 91.03937 3 cm -q -0 0 0 rg -BT 1 0 0 1 0 38 Tm /F1 10 Tf 12 TL .292338 Tw (The Mapping Rule Processor is designed to accept a JSON object \(set of key/value) Tj T* 0 Tw .707171 Tw (pairs\) as input and emit a different JSON object as output. Thus the Mappgin Rule) Tj T* 0 Tw 1.381039 Tw (Processor effectively operates as a transformation engine on key/value pairs with) Tj T* 0 Tw (the ability to add or delete key/value pairs.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 56.69291 56.69291 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 234.8349 0 Td (-2-) Tj T* -234.8349 0 Td ET -Q -Q - -endstream -endobj -141 0 obj -<< /Length 7582 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 726.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 27 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 31.35937 0 Td (Step 3.1:) Tj T* -31.35937 0 Td ET -Q -Q -q -1 0 0 1 91.03937 3 cm -q -0 0 0 rg -BT 1 0 0 1 0 26 Tm /F1 10 Tf 12 TL 2.0186 Tw (The input assertion is rewritten as a JSON object in the format required by the) Tj T* 0 Tw .039199 Tw (Mapping Rule Processor. The JSON assertion is then passed into the Mapping Rule) Tj T* 0 Tw (Processor.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 651.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 63 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 31.35937 0 Td (Step 3.2:) Tj T* -31.35937 0 Td ET -Q -Q -q -1 0 0 1 91.03937 3 cm -q -BT 1 0 0 1 0 62 Tm 1.105039 Tw 12 TL /F1 10 Tf 0 0 0 rg (The Mapping Rule Processor identified as ) Tj /F4 10 Tf 0 0 0 rg (IdPMapper ) Tj /F1 10 Tf 0 0 0 rg (evaluates the input JSON) Tj T* 0 Tw 2.00003 Tw (assertion in the context of the mapping rules defined for the site deployment. If) Tj T* 0 Tw .971569 Tw /F4 10 Tf 0 0 0 rg (IdPMapper ) Tj /F1 10 Tf 0 0 0 rg (is able to successfully transform the input it will return a JSON object) Tj T* 0 Tw .152885 Tw (which is called the ) Tj /F3 10 Tf (mapped ) Tj /F1 10 Tf (result. If the input JSON assertion is not compatible with) Tj T* 0 Tw 1.618492 Tw (the site specific rules loaded into the ) Tj /F4 10 Tf 0 0 0 rg (IdPMapper ) Tj /F1 10 Tf 0 0 0 rg (then NULL is returned by the) Tj T* 0 Tw /F4 10 Tf 0 0 0 rg (IdPMapper) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 624.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 15 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 31.35937 0 Td (Step 3.3:) Tj T* -31.35937 0 Td ET -Q -Q -q -1 0 0 1 91.03937 3 cm -q -BT 1 0 0 1 0 14 Tm 1.272039 Tw 12 TL /F1 10 Tf 0 0 0 rg (If the mapping was successful the ) Tj /F4 10 Tf 0 0 0 rg (IdPMapper ) Tj /F1 10 Tf 0 0 0 rg (returns the transformed assertion) Tj T* 0 Tw (as a JSON object.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 609.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 39.69937 0 Td (Step 4:) Tj T* -39.69937 0 Td ET -Q -Q -q -1 0 0 1 91.03937 3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The mapped JSON object is converted for use in the local system.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 579.0236 cm -q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Example Assertion Transformation) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 465.0236 cm -q -BT 1 0 0 1 0 98 Tm .382209 Tw 12 TL /F1 10 Tf 0 0 0 rg (A federated IdP supplies metadata in a form unique to the IdP. This is called an assertion. That assertion) Tj T* 0 Tw .652126 Tw (must be transformed into a format and data understood by LocalSystem. More importantly that assertion) Tj T* 0 Tw .201984 Tw (needs to yield ) Tj /F3 10 Tf (authorization roles specific to LocalSystem) Tj /F1 10 Tf (. In ) Tj 0 0 .501961 rg (Figure 1. ) Tj 0 0 0 rg (Step 3.2 the ) Tj /F4 10 Tf 0 0 0 rg (IdPMapper ) Tj /F1 10 Tf 0 0 0 rg (provides) Tj T* 0 Tw 2.02936 Tw (the transformation from an external IdP assertion to a LocalSystem specific token. It does this via a) Tj T* 0 Tw 1.726412 Tw (Mapping Rule Processor which reads a site specific set of transformation rules. These mapping rules) Tj T* 0 Tw .50061 Tw (define how to transform the external IdP assertion into a LocalSystem token. The mapping rules also are) Tj T* 0 Tw 1.578735 Tw (responsible for validating the external IdP assertion to make sure it is consistent with the site specific) Tj T* 0 Tw 1.719318 Tw (requirements. The operation of the Mapping Rule Processor and the syntax of the mapping rules are) Tj T* 0 Tw (defined in ) Tj 0 0 .501961 rg (Structure Of Rule Definitions) Tj 0 0 0 rg (.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 423.0236 cm -q -BT 1 0 0 1 0 26 Tm .700574 Tw 12 TL /F1 10 Tf 0 0 0 rg (Below is an example mapping rule which might be loaded into the Mapping Rule Processor to support a) Tj T* 0 Tw 2.347674 Tw (fictional FOOBAR application. The IdP provides assertions using the ) Tj /F4 10 Tf 0 0 0 rg (REMOTE_USER ) Tj /F1 10 Tf 0 0 0 rg (CGI style. It is) Tj T* 0 Tw (assumed there are two LocalSystem roles which may be assigned:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 407.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F5 10 Tf 12 TL (user) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 392.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (A role granting standard permissions for normal FOOBAR users.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 376.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F5 10 Tf 12 TL (admin) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 361.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (A special role granting full FOOBAR administrative permissions.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 331.0236 cm -q -BT 1 0 0 1 0 14 Tm .087633 Tw 12 TL /F1 10 Tf 0 0 0 rg (In this example assigning the ) Tj /F4 10 Tf 0 0 0 rg (user ) Tj /F1 10 Tf 0 0 0 rg (and ) Tj /F4 10 Tf 0 0 0 rg (admin ) Tj /F1 10 Tf 0 0 0 rg (roles will be based on group membership in the following) Tj T* 0 Tw (groups:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 315.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F5 10 Tf 12 TL (foobar_users) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 300.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Members of this group are normal FOOBAR users with restricted permissions.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 284.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F5 10 Tf 12 TL (foobar_admin) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 269.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Members of this group are FOOBAR administrators with permission to perform all operations.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 215.0236 cm -q -BT 1 0 0 1 0 38 Tm 4.288443 Tw 12 TL /F1 10 Tf 0 0 0 rg (Granting of the ) Tj /F4 10 Tf 0 0 0 rg (user ) Tj /F1 10 Tf 0 0 0 rg (and/or ) Tj /F4 10 Tf 0 0 0 rg (admin ) Tj /F1 10 Tf 0 0 0 rg (roles based on membership in the ) Tj /F4 10 Tf 0 0 0 rg (foobar_users ) Tj /F1 10 Tf 0 0 0 rg (and) Tj T* 0 Tw 1.387126 Tw /F4 10 Tf 0 0 0 rg (foobar_admin ) Tj /F1 10 Tf 0 0 0 rg (is illustrated in the follow mapping rule example which also extracts the user principal) Tj T* 0 Tw .275984 Tw (and domain information in the preferred format for the site \(e.g. usernames are lowercase without domain) Tj T* 0 Tw (suffixes and the domain is uppercase and supplied separately\).) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 197.0236 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Mapping Rule Example 1.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 91.82362 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 96 re B* -Q -q -BT 1 0 0 1 0 74 Tm 12 TL /F4 10 Tf 0 0 0 rg (1 [) Tj T* (2 {"mapping": {"ClientId": "$client_id",) Tj T* (3 "UserId": "$user_id",) Tj T* (4 "User": "$username",) Tj T* (5 "Domain": "$domain",) Tj T* (6 "roles": "$roles",) Tj T* (7 },) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 56.69291 56.69291 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 234.8349 0 Td (-3-) Tj T* -234.8349 0 Td ET -Q -Q - -endstream -endobj -142 0 obj -<< /Length 5287 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 307.8236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 516 456 re B* -Q -q -BT 1 0 0 1 0 434 Tm 12 TL /F4 10 Tf 0 0 0 rg (8 "statement_blocks": [) Tj T* (9 [) Tj T* (10 ["set", "$groups", []],) Tj T* (11 ["set", "$roles", []]) Tj T* (12 ],) Tj T* (13 [) Tj T* (14 ["in", "REMOTE_USER", "$assertion"],) Tj T* (15 ["exit", "rule_fails", "if_not_success"],) Tj T* (16 ["regexp", "$assertion[REMOTE_USER]", "\(?) Tj (<) Tj (username) Tj (>) Tj (\\\\w+\)@\(?) Tj (<) Tj (domain) Tj (>) Tj (.+\)"],) Tj T* (17 ["exit", "rule_fails", "if_not_success"],) Tj T* (18 ["lower", "$username", "$regexp_map[username]"],) Tj T* (19 ["upper", "$domain", "$regexp_map[domain]"],) Tj T* (20 ],) Tj T* (21 [) Tj T* (22 ["in", "REMOTE_USER_GROUPS", "$assertion"],) Tj T* (23 ["exit", "rule_fails", "if_not_success"],) Tj T* (24 ["split", "$groups", "$assertion[REMOTE_USER_GROUPS]", ":"],) Tj T* (25 ],) Tj T* (26 [) Tj T* (27 ["in", "foobar_users", "$groups"],) Tj T* (28 ["continue", "if_not_success"],) Tj T* (29 ["append", "$roles", "user"],) Tj T* (30 ],) Tj T* (31 [) Tj T* (32 ["in", "foobar_admin", "$groups"],) Tj T* (33 ["continue", "if_not_success"],) Tj T* (34 ["append", "$roles", "admin"]) Tj T* (35 ],) Tj T* (36 [) Tj T* (37 ["unique", "$roles", "$roles"],) Tj T* (38 ["length", "$n_roles", "$roles"],) Tj T* (39 ["compare", "$n_roles", ") Tj (>) Tj (", 0],) Tj T* (40 ["exit", "rule_fails", "if_not_success"],) Tj T* (41 ],) Tj T* (42 ]) Tj T* (43 }) Tj T* (44 ]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 293.8236 cm -Q -q -1 0 0 1 62.69291 230.8236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 51 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 40.80937 0 Td (Line 1:) Tj T* -40.80937 0 Td ET -Q -Q -q -1 0 0 1 91.03937 3 cm -q -BT 1 0 0 1 0 50 Tm 1.466494 Tw 12 TL /F1 10 Tf 0 0 0 rg (Starts a list of rules. In this example only 1 rule is defined. Each rule is a JSON) Tj T* 0 Tw 2.652039 Tw (object containing a ) Tj /F4 10 Tf 0 0 0 rg (mapping ) Tj /F1 10 Tf 0 0 0 rg (and a required list of ) Tj /F4 10 Tf 0 0 0 rg (statement_blocks) Tj /F1 10 Tf 0 0 0 rg (. The) Tj T* 0 Tw .21815 Tw /F4 10 Tf 0 0 0 rg (mapping ) Tj /F1 10 Tf 0 0 0 rg (may either be specified inside a rule as it is here or may be referenced by) Tj T* 0 Tw .190023 Tw (name in a table of mappings \(this is easier to manage if you have a large number of) Tj T* 0 Tw (rules and small number of mappings\).) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 179.8236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 39 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 26.35937 0 Td (Lines 2-7:) Tj T* -26.35937 0 Td ET -Q -Q -q -1 0 0 1 91.03937 3 cm -q -BT 1 0 0 1 0 38 Tm .409199 Tw 12 TL /F1 10 Tf 0 0 0 rg (Defines the JSON mapped result. Each key maps to LocalSystem token. The value) Tj T* 0 Tw 2.0586 Tw (is a rule variable whose value will be substituted if the rule succeeds. Thus for) Tj T* 0 Tw 1.521699 Tw (example the LocalSystem token value ) Tj /F4 10 Tf 0 0 0 rg (User ) Tj /F1 10 Tf 0 0 0 rg (will be assigned the value from the) Tj T* 0 Tw /F4 10 Tf 0 0 0 rg ($username ) Tj /F1 10 Tf 0 0 0 rg (rule variable.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 164.8236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 40.80937 0 Td (Line 8:) Tj T* -40.80937 0 Td ET -Q -Q -q -1 0 0 1 91.03937 3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Begins the list of statement blocks. A statement must be contained inside a block.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 125.8236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 27 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 20.79937 0 Td (Lines 9-12:) Tj T* -20.79937 0 Td ET -Q -Q -q -1 0 0 1 91.03937 3 cm -q -BT 1 0 0 1 0 26 Tm 2.080033 Tw 12 TL /F1 10 Tf 0 0 0 rg (The first block usually initializes variables that will be referenced later. Here we) Tj T* 0 Tw .854581 Tw (initialize ) Tj /F4 10 Tf 0 0 0 rg ($groups ) Tj /F1 10 Tf 0 0 0 rg (and ) Tj /F4 10 Tf 0 0 0 rg ($roles ) Tj /F1 10 Tf 0 0 0 rg (to empty arrays. These arrays may be appended) Tj T* 0 Tw (to in later blocks and may be referenced in the final ) Tj /F4 10 Tf 0 0 0 rg (mapping ) Tj /F1 10 Tf 0 0 0 rg (output.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 98.82362 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 15 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 15.23937 0 Td (Lines 13-20:) Tj T* -15.23937 0 Td ET -Q -Q -q -1 0 0 1 91.03937 3 cm -q -BT 1 0 0 1 0 14 Tm .151699 Tw 12 TL /F1 10 Tf 0 0 0 rg (This block sets the user and domain information based on ) Tj /F4 10 Tf 0 0 0 rg (REMOTE_USER ) Tj /F1 10 Tf 0 0 0 rg (and exits) Tj T* 0 Tw (the rule if ) Tj /F4 10 Tf 0 0 0 rg (REMOTE_USER ) Tj /F1 10 Tf 0 0 0 rg (is not defined.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 56.69291 56.69291 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 234.8349 0 Td (-4-) Tj T* -234.8349 0 Td ET -Q -Q - -endstream -endobj -143 0 obj -<< /Length 8284 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 738.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 15 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 15.23937 0 Td (Lines 14-15:) Tj T* -15.23937 0 Td ET -Q -Q -q -1 0 0 1 91.03937 3 cm -q -BT 1 0 0 1 0 14 Tm .965028 Tw 12 TL /F1 10 Tf 0 0 0 rg (This test is critical, it assures ) Tj /F4 10 Tf 0 0 0 rg (REMOTE_USER ) Tj /F1 10 Tf 0 0 0 rg (is defined in the assertion, if not the) Tj T* 0 Tw (rule is skipped because we depend on ) Tj /F4 10 Tf 0 0 0 rg (REMOTE_USER) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 687.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 39 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 15.23937 0 Td (Lines 16-17:) Tj T* -15.23937 0 Td ET -Q -Q -q -1 0 0 1 91.03937 3 cm -q -BT 1 0 0 1 0 38 Tm .629039 Tw 12 TL /F1 10 Tf 0 0 0 rg (Performs a regular expression match against ) Tj /F4 10 Tf 0 0 0 rg (REMOTE_USER ) Tj /F1 10 Tf 0 0 0 rg (to split the username) Tj T* 0 Tw 2.770945 Tw (from the domain. The regular expression uses named groups, in this instance) Tj T* 0 Tw 3.041699 Tw /F4 10 Tf 0 0 0 rg (username ) Tj /F1 10 Tf 0 0 0 rg (and ) Tj /F4 10 Tf 0 0 0 rg (domain) Tj /F1 10 Tf 0 0 0 rg (. If the regular expression does not match the rule is) Tj T* 0 Tw (skipped.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 624.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 51 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 15.23937 0 Td (Lines 18-19:) Tj T* -15.23937 0 Td ET -Q -Q -q -1 0 0 1 91.03937 3 cm -q -BT 1 0 0 1 0 50 Tm .317533 Tw 12 TL /F1 10 Tf 0 0 0 rg (These lines reference the previous result of the regular expression match which are) Tj T* 0 Tw 1.167309 Tw (stored in the special variable ) Tj /F4 10 Tf 0 0 0 rg ($regexp_map) Tj /F1 10 Tf 0 0 0 rg (. The username is converted to lower) Tj T* 0 Tw 1.531569 Tw (case and stored in ) Tj /F4 10 Tf 0 0 0 rg ($username ) Tj /F1 10 Tf 0 0 0 rg (and the domain is converted to upper case and) Tj T* 0 Tw 4.828366 Tw (stored in ) Tj /F4 10 Tf 0 0 0 rg ($domain) Tj /F1 10 Tf 0 0 0 rg (. The choice of case is purely by convention and site) Tj T* 0 Tw (requirements.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 609.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 15.23937 0 Td (Lines 21-35:) Tj T* -15.23937 0 Td ET -Q -Q -q -1 0 0 1 91.03937 3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (These 3 blocks assign roles based on group membership.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 546.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 51 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 15.23937 0 Td (Lines 21-25:) Tj T* -15.23937 0 Td ET -Q -Q -q -1 0 0 1 91.03937 3 cm -q -BT 1 0 0 1 0 50 Tm 2.764581 Tw 12 TL /F1 10 Tf 0 0 0 rg (Assures ) Tj /F4 10 Tf 0 0 0 rg (REMOTE_USER_GROUPS ) Tj /F1 10 Tf 0 0 0 rg (is defined in the assertion; if not, the rule is) Tj T* 0 Tw 1.040039 Tw (skipped. ) Tj /F4 10 Tf 0 0 0 rg (REMOTE_USER_GROUPS ) Tj /F1 10 Tf 0 0 0 rg (is colon separated list of group names. In order) Tj T* 0 Tw .149039 Tw (to operate on the individual group names appearing in ) Tj /F4 10 Tf 0 0 0 rg (REMOTE_USER_GROUPS ) Tj /F1 10 Tf 0 0 0 rg (line) Tj T* 0 Tw 1.525742 Tw (24 splits the string on the colon separator and stores the result in the ) Tj /F4 10 Tf 0 0 0 rg ($groups) Tj T* 0 Tw /F1 10 Tf 0 0 0 rg (array.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 519.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 15 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 15.23937 0 Td (Lines 27-30:) Tj T* -15.23937 0 Td ET -Q -Q -q -1 0 0 1 91.03937 3 cm -q -BT 1 0 0 1 0 14 Tm 1.0536 Tw 12 TL /F1 10 Tf 0 0 0 rg (This block assigns the ) Tj /F4 10 Tf 0 0 0 rg (user ) Tj /F1 10 Tf 0 0 0 rg (role if the user is a member of the ) Tj /F4 10 Tf 0 0 0 rg (foobar_users) Tj T* 0 Tw /F1 10 Tf 0 0 0 rg (group.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 492.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 15 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 15.23937 0 Td (Lines 31-35:) Tj T* -15.23937 0 Td ET -Q -Q -q -1 0 0 1 91.03937 3 cm -q -BT 1 0 0 1 0 14 Tm .625028 Tw 12 TL /F1 10 Tf 0 0 0 rg (This block assigns the ) Tj /F4 10 Tf 0 0 0 rg (admin ) Tj /F1 10 Tf 0 0 0 rg (role if the user is a member of the ) Tj /F4 10 Tf 0 0 0 rg (foobar_admin) Tj T* 0 Tw /F1 10 Tf 0 0 0 rg (group.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 441.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 39 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 15.23937 0 Td (Lines 36-41:) Tj T* -15.23937 0 Td ET -Q -Q -q -1 0 0 1 91.03937 3 cm -q -BT 1 0 0 1 0 38 Tm .77336 Tw 12 TL /F1 10 Tf 0 0 0 rg (This block performs final clean up actions for the rule. First it assures there are no) Tj T* 0 Tw 1.995415 Tw (duplicates in the ) Tj /F4 10 Tf 0 0 0 rg ($roles ) Tj /F1 10 Tf 0 0 0 rg (array by calling the ) Tj /F4 10 Tf 0 0 0 rg (unique ) Tj /F1 10 Tf 0 0 0 rg (function. Then it gets a) Tj T* 0 Tw .778847 Tw (count of how many items are in the ) Tj /F4 10 Tf 0 0 0 rg ($roles ) Tj /F1 10 Tf 0 0 0 rg (array and tests to see if it's empty. If) Tj T* 0 Tw (there are no roles assigned the rule is skipped.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 402.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 27 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 35.24937 0 Td (Line 43:) Tj T* -35.24937 0 Td ET -Q -Q -q -1 0 0 1 91.03937 3 cm -q -0 0 0 rg -BT 1 0 0 1 0 26 Tm /F1 10 Tf 12 TL .549494 Tw (This is the end of the rule. If we reach the end of the rule it succeeds. When a rule) Tj T* 0 Tw 2.446699 Tw (succeeds the mapping associated with the rule is looked up. Any rule variable) Tj T* 0 Tw (appearing in the mapping is substituted with its value.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 384.0236 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Using the rules in ) Tj 0 0 .501961 rg (Mapping Rule Example 1. ) Tj 0 0 0 rg (and following example assertion in JSON format:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 366.0236 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Assertion Example 1.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 248.8236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 108 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 86 Tm /F4 10 Tf 12 TL ({) Tj T* ( "REMOTE_USER": "TestUser@example.com",) Tj T* ( "REMOTE_AUTH_TYPE": "Negotiate",) Tj T* ( "REMOTE_USER_GROUPS": "foobar_users:foobar_admin",) Tj T* ( "REMOTE_USER_EMAIL": "test.user@example.com",) Tj T* ( "REMOTE_USER_FIRSTNAME": "Test",) Tj T* ( "REMOTE_USER_LASTNAME": "User") Tj T* (}) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 192.8236 cm -q -BT 1 0 0 1 0 38 Tm .488735 Tw 12 TL /F1 10 Tf 0 0 0 rg (Then the mapper will return the following mapped JSON document. This is the ) Tj /F4 10 Tf 0 0 0 rg (mapping ) Tj /F1 10 Tf 0 0 0 rg (defined on line) Tj T* 0 Tw .01436 Tw (2 of ) Tj 0 0 .501961 rg (Mapping Rule Example 1. ) Tj 0 0 0 rg (with the variables substituted after the rule successfully executed. Note any) Tj T* 0 Tw 1.152927 Tw (valid JSON data type can be returned, in this example the ) Tj /F4 10 Tf 0 0 0 rg (null ) Tj /F1 10 Tf 0 0 0 rg (value is returned for ) Tj /F4 10 Tf 0 0 0 rg (ClientId ) Tj /F1 10 Tf 0 0 0 rg (and) Tj T* 0 Tw /F4 10 Tf 0 0 0 rg (UserId) Tj /F1 10 Tf 0 0 0 rg (, normal strings for ) Tj /F4 10 Tf 0 0 0 rg (User ) Tj /F1 10 Tf 0 0 0 rg (and ) Tj /F4 10 Tf 0 0 0 rg (Domain ) Tj /F1 10 Tf 0 0 0 rg (and an array of strings for the ) Tj /F4 10 Tf 0 0 0 rg (roles ) Tj /F1 10 Tf 0 0 0 rg (value.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 174.8236 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Mapped Result Example 1.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 93.62362 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 72 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 50 Tm /F4 10 Tf 12 TL ({) Tj T* ( "ClientId": null,) Tj T* ( "UserId": null,) Tj T* ( "User": "testuser",) Tj T* ( "Domain": "EXAMPLE.COM",) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 56.69291 56.69291 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 234.8349 0 Td (-5-) Tj T* -234.8349 0 Td ET -Q -Q - -endstream -endobj -144 0 obj -<< /Length 4099 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 727.8236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 36 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F4 10 Tf 12 TL ( "roles": ["user", "admin"]) Tj T* (}) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 694.8236 cm -q -BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Operation Model) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 616.8236 cm -q -0 0 0 rg -BT 1 0 0 1 0 62 Tm /F1 10 Tf 12 TL .846654 Tw (The assertions from an IdP are stored in an associative array. A sequence of rules are applied, the first) Tj T* 0 Tw 1.787485 Tw (rule which returns success is considered a match. During the execution of each rule values from the) Tj T* 0 Tw .406457 Tw (assertion can be tested and transformed with the results selectively stored in variables local to the rule. If) Tj T* 0 Tw .466235 Tw (the rule succeeds an associative array of mapped values is returned. The mapped values are taken from) Tj T* 0 Tw 2.23686 Tw (the local variables set during the rule execution. The definition of the rules and mapped results are) Tj T* 0 Tw (expressed in JSON notation.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 538.8236 cm -q -BT 1 0 0 1 0 62 Tm 2.359431 Tw 12 TL /F1 10 Tf 0 0 0 rg (A rule is somewhat akin to a function in a programming language. It starts execution with a set of) Tj T* 0 Tw 2.936647 Tw (predefined local variables. It executes statements which are grouped together in blocks. Execution) Tj T* 0 Tw 1.05686 Tw (continues until an ) Tj 0 0 .501961 rg (exit ) Tj 0 0 0 rg (statement returning a success/fail result is executed or until the last statement is) Tj T* 0 Tw 1.943984 Tw (reached which implies success. The remaining statements in a block may be skipped via a ) Tj 0 0 .501961 rg (continue) Tj T* 0 Tw 2.04881 Tw 0 0 0 rg (statement which tests a condition, this is equivalent to an "if" control flow of logic in a programming) Tj T* 0 Tw (language.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 484.8236 cm -q -BT 1 0 0 1 0 38 Tm .04936 Tw 12 TL /F1 10 Tf 0 0 0 rg (Rule execution continues until a rule returns success. Each rule has a ) Tj 0 0 .501961 rg (mapping ) Tj 0 0 0 rg (associative array bound to) Tj T* 0 Tw .106098 Tw (it which is a template for the transformed result. Upon success the ) Tj 0 0 .501961 rg (mapping ) Tj 0 0 0 rg (template for the rule is loaded) Tj T* 0 Tw .601163 Tw (and the local variables from the successful rule are used to populate the values in the ) Tj 0 0 .501961 rg (mapping ) Tj 0 0 0 rg (template) Tj T* 0 Tw (yielding the final mapped result.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 466.8236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (If no rules returns success authentication fails.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 436.8236 cm -q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Pseudo Code Illustrating Operational Model) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 115.6236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 312 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 290 Tm /F4 10 Tf 12 TL (mapped = null) Tj T* (foreach rule in rules {) Tj T* ( result = null) Tj T* ( initialize rule.variables with pre-defined values) Tj T* T* ( foreach block in rule.statement_blocks {) Tj T* ( for statement in block.statements {) Tj T* ( if statement.verb is exit {) Tj T* ( result = exit.status) Tj T* ( break) Tj T* ( }) Tj T* ( elif statement.verb is continue {) Tj T* ( break) Tj T* ( }) Tj T* ( }) Tj T* ( if result {) Tj T* ( break) Tj T* ( }) Tj T* ( if result == null {) Tj T* ( result = success) Tj T* ( }) Tj T* (if result == success {) Tj T* ( mapped = rule.mapping\(rule.variables\)) Tj T* (}) Tj T* (return mapped) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 56.69291 56.69291 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 234.8349 0 Td (-6-) Tj T* -234.8349 0 Td ET -Q -Q - -endstream -endobj -145 0 obj -<< /Length 3697 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 744.0236 cm -q -BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Structure Of Rule Definitions) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 702.0236 cm -q -BT 1 0 0 1 0 26 Tm .599431 Tw 12 TL /F1 10 Tf 0 0 0 rg (Rules are loaded by the rule processor via a JSON document called a rule definition. A definition has an) Tj T* 0 Tw .258876 Tw /F3 10 Tf (optional ) Tj /F1 10 Tf (set of mapping templates and a list of rules. Each rule has specifies a mapping template and has) Tj T* 0 Tw (a list of statement blocks. Each statement block has a list of statements.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 684.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (In pseudo-JSON \(JSON does not have comments, the ... ellipsis is a place holder\):) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 302.8236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 372 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 350 Tm /F4 10 Tf 12 TL ({) Tj T* ( "mappings": {) Tj T* ( "template1": "{...}",) Tj T* ( "template2": "{...}") Tj T* ( },) Tj T* ( "rules": [) Tj T* ( { # Rule 0. A rule has a mapping or a mapping name) Tj T* ( # and a list of statement blocks) Tj T* T* ( "mapping": {...},) Tj T* ( # -OR-) Tj T* ( "mapping_name": "template1",) Tj T* T* ( "statement_blocks": [) Tj T* ( [ # Block 0) Tj T* ( [statement 0]) Tj T* ( [statement 1]) Tj T* ( ],) Tj T* ( [ # Block 1) Tj T* ( [statement 0]) Tj T* ( [statement 1]) Tj T* ( ],) Tj T* T* ( ]) Tj T* ( },) Tj T* ( { # Rule 1 ...) Tj T* ( }) Tj T* ( ]) Tj T* T* (}) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 272.8236 cm -q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Mapping) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 218.8236 cm -q -0 0 0 rg -BT 1 0 0 1 0 38 Tm /F1 10 Tf 12 TL .504104 Tw (A mapping template is used to produce the final associative array of name/value pairs. The template is a) Tj T* 0 Tw .788988 Tw (JSON Object. The value in a name/value pair can be a constant or a variable. If the template value is a) Tj T* 0 Tw 1.525542 Tw (variable the value of the variable is retrieved from the set of local variables bound to the rule thereby) Tj T* 0 Tw (replacing it in the final result.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 200.8236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (For example given this mapping template and rule variables in JSON:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 182.8236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (template:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 101.6236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 72 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 50 Tm /F4 10 Tf 12 TL ({) Tj T* ( "organization": "BigCorp.com",) Tj T* ( "user: "$subject",) Tj T* ( "roles": "$roles") Tj T* (}) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 56.69291 56.69291 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 234.8349 0 Td (-7-) Tj T* -234.8349 0 Td ET -Q -Q - -endstream -endobj -146 0 obj -<< /Length 5083 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 753.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (local variables:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 683.8236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 60 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 38 Tm /F4 10 Tf 12 TL ({) Tj T* ( "subject": "Sally",) Tj T* ( "roles": ["user", "admin"]) Tj T* (}) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 663.8236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The final mapped results would be:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 582.6236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 72 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 50 Tm /F4 10 Tf 12 TL ({) Tj T* ( "organization": "BigCorp.com",) Tj T* ( "user: "Sally",) Tj T* ( "roles": ["user", "admin"]) Tj T* (}) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 550.6236 cm -q -BT 1 0 0 1 0 14 Tm .307633 Tw 12 TL /F1 10 Tf 0 0 0 rg (Each rule must bind a mapping template to the rule. The mapping template may either be defined directly) Tj T* 0 Tw (in the rule via the ) Tj /F4 10 Tf 0 0 0 rg (mapping ) Tj /F1 10 Tf 0 0 0 rg (key or referenced by name via the ) Tj /F4 10 Tf 0 0 0 rg (mapping_name ) Tj /F1 10 Tf 0 0 0 rg (key.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 508.6236 cm -q -BT 1 0 0 1 0 26 Tm .185542 Tw 12 TL /F1 10 Tf 0 0 0 rg (If the ) Tj /F4 10 Tf 0 0 0 rg (mapping_name ) Tj /F1 10 Tf 0 0 0 rg (is specified the mapping is looked up in a table of mapping templates bound to the) Tj T* 0 Tw 1.299985 Tw (Rule Processor. Using the name of a mapping template is useful when many rules generate the exact) Tj T* 0 Tw (same template values.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 490.6236 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (If both ) Tj /F4 10 Tf 0 0 0 rg (mapping ) Tj /F1 10 Tf 0 0 0 rg (and ) Tj /F4 10 Tf 0 0 0 rg (mapping_name ) Tj /F1 10 Tf 0 0 0 rg (are defined the locally bound ) Tj /F4 10 Tf 0 0 0 rg (mapping ) Tj /F1 10 Tf 0 0 0 rg (takes precedence.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 460.6236 cm -q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Syntax) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 430.6236 cm -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .977882 Tw (The logic for a rule consists of a sequence of statements grouped in blocks. A statement is similar to a) Tj T* 0 Tw (function call in a programming language.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 376.6236 cm -q -BT 1 0 0 1 0 38 Tm 1.012488 Tw 12 TL /F1 10 Tf 0 0 0 rg (A statement is a list of values the first of which is a verb which defines the operation the statement will) Tj T* 0 Tw .15561 Tw (perform. Think of the ) Tj 0 0 .501961 rg (verbs ) Tj 0 0 0 rg (as function names or operators. Following the verb are parameters which may) Tj T* 0 Tw .628876 Tw (be constants or variables. If the statement assigns a value to a variable left hand side of the assignment) Tj T* 0 Tw (\(lhs\) is always the first parameter following the verb in the list of statement values.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 358.6236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (For example this statement in JSON:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 325.4236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 24 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F4 10 Tf 12 TL (["split", "$groups", "$assertion[Groups]", ":"]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 293.4236 cm -q -BT 1 0 0 1 0 14 Tm .287209 Tw 12 TL /F1 10 Tf 0 0 0 rg (will assign an array to the variable ) Tj /F4 10 Tf 0 0 0 rg ($groups) Tj /F1 10 Tf 0 0 0 rg (. It looks up the string named ) Tj /F4 10 Tf 0 0 0 rg (Groups ) Tj /F1 10 Tf 0 0 0 rg (in the assertion which) Tj T* 0 Tw (is a colon \(:\) separated list of group names splitting that string on the colon character.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 251.4236 cm -q -BT 1 0 0 1 0 26 Tm .598876 Tw 12 TL /F1 10 Tf 0 0 0 rg (Statements ) Tj /F2 10 Tf (must ) Tj /F1 10 Tf (be grouped together in blocks. Therefore a rule is a sequence of blocks and block is a) Tj T* 0 Tw .864692 Tw (sequence of statements. The purpose of blocks is allow for crude flow of control logic. For example this) Tj T* 0 Tw (JSON rule has 4 blocks.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 98.22362 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 144 re B* -Q -q -BT 1 0 0 1 0 122 Tm 12 TL /F4 10 Tf 0 0 0 rg ([) Tj T* ( [) Tj T* ( ["set", $user, ""],) Tj T* ( ["set", $roles, []]) Tj T* ( ],) Tj T* ( [) Tj T* ( ["in", "UserName", "$assertion"],) Tj T* ( ["continue", "if_not_success"],) Tj T* ( ["set", "$user", "$assertion[UserName"],) Tj T* ( ],) Tj T* ( [) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 56.69291 56.69291 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 234.8349 0 Td (-8-) Tj T* -234.8349 0 Td ET -Q -Q - -endstream -endobj -147 0 obj -<< /Length 8967 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 619.8236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 144 re B* -Q -q -BT 1 0 0 1 0 122 Tm 12 TL /F4 10 Tf 0 0 0 rg ( ["in", "subject", "$assertion"],) Tj T* ( ["continue", "if_not_success"],) Tj T* ( ["set", "$user", "$assertion[subject]"],) Tj T* ( ],) Tj T* ( [) Tj T* ( ["length", "$temp", "$user"],) Tj T* ( ["compare", "$temp", ") Tj (>) Tj (", 0],) Tj T* ( ["exit", "rule_fails", "if_not_success"]) Tj T* ( ["append" "$roles", "unprivileged"]) Tj T* ( ]) Tj T* (]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 575.8236 cm -q -BT 1 0 0 1 0 26 Tm 1.695542 Tw 12 TL /F1 10 Tf 0 0 0 rg (The rule will succeed if either ) Tj /F4 10 Tf 0 0 0 rg (UserName ) Tj /F1 10 Tf 0 0 0 rg (or ) Tj /F4 10 Tf 0 0 0 rg (subject ) Tj /F1 10 Tf 0 0 0 rg (is defined in the assertion and if so the local) Tj T* 0 Tw .11832 Tw (variable ) Tj /F4 10 Tf 0 0 0 rg ($user ) Tj /F1 10 Tf 0 0 0 rg (will be set to the value found in the assertion and the "unprivileged" role will be appended) Tj T* 0 Tw (to the roles array.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 497.8236 cm -q -BT 1 0 0 1 0 62 Tm 3.211235 Tw 12 TL /F1 10 Tf 0 0 0 rg (The first block performs initialization. The second block tests to see if the assertion has the key) Tj T* 0 Tw .59186 Tw /F4 10 Tf 0 0 0 rg (UserName ) Tj /F1 10 Tf 0 0 0 rg (if not execution continues at the next block otherwise the value of UserName in the assertion) Tj T* 0 Tw .62528 Tw (is copied into the variable ) Tj /F4 10 Tf 0 0 0 rg ($user) Tj /F1 10 Tf 0 0 0 rg (. The third block performs a similar operation looking for a ) Tj /F4 10 Tf 0 0 0 rg (subject ) Tj /F1 10 Tf 0 0 0 rg (in) Tj T* 0 Tw .907988 Tw (the assertion. The fourth block checks to see if the ) Tj /F4 10 Tf 0 0 0 rg ($user ) Tj /F1 10 Tf 0 0 0 rg (variable is empty, if it is empty the rule fails) Tj T* 0 Tw 1.347765 Tw (because it didn't find either a ) Tj /F4 10 Tf 0 0 0 rg (UserName ) Tj /F1 10 Tf 0 0 0 rg (nor a ) Tj /F4 10 Tf 0 0 0 rg (subject ) Tj /F1 10 Tf 0 0 0 rg (in the assertion. If ) Tj /F4 10 Tf 0 0 0 rg ($user ) Tj /F1 10 Tf 0 0 0 rg (is not empty the) Tj T* 0 Tw ("unprivileged" role is appended and the rule succeeds.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 467.8236 cm -q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Data Types) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 389.8236 cm -q -0 0 0 rg -BT 1 0 0 1 0 62 Tm /F1 10 Tf 12 TL .304198 Tw (There are 7 supported types which equate to the types available in JSON. At the time of this writing there) Tj T* 0 Tw .569985 Tw (are 2 implementations of this Mapping specification, one in Python and one in Java. This table illustrates) Tj T* 0 Tw 1.090651 Tw (how each data type is represented. The first two columns are definitions from an abstract specification.) Tj T* 0 Tw 4.106412 Tw (The JSON column enumerates the data type JSON supports. The Mapping column lists the 7) Tj T* 0 Tw .214983 Tw (enumeration names used by the Mapping implemenation in each language. The following columns list the) Tj T* 0 Tw (concrete data type used in that language.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 383.8236 cm -Q -q -1 0 0 1 62.69291 203.8236 cm -1 1 1 rg -n 0 180 469.8898 -18 re f* -.878431 .878431 .878431 rg -n 0 162 469.8898 -18 re f* -1 1 1 rg -n 0 144 469.8898 -18 re f* -.878431 .878431 .878431 rg -n 0 126 469.8898 -18 re f* -1 1 1 rg -n 0 108 469.8898 -18 re f* -.878431 .878431 .878431 rg -n 0 90 469.8898 -18 re f* -1 1 1 rg -n 0 72 469.8898 -18 re f* -.878431 .878431 .878431 rg -n 0 54 469.8898 -18 re f* -1 1 1 rg -n 0 36 469.8898 -18 re f* -.878431 .878431 .878431 rg -n 0 18 469.8898 -18 re f* -.960784 .960784 .862745 rg -n 0 180 469.8898 -18 re f* -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 165 cm -q -.960784 .960784 .862745 rg -n 0 0 68.7623 12 re f* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 21.04615 0 Td (JSON) Tj T* -21.04615 0 Td ET -Q -Q -q -1 0 0 1 86.7623 165 cm -q -.960784 .960784 .862745 rg -n 0 0 76.10433 12 re f* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 18.87717 0 Td (Mapping) Tj T* -18.87717 0 Td ET -Q -Q -q -1 0 0 1 174.8666 165 cm -q -.960784 .960784 .862745 rg -n 0 0 134.8406 12 re f* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 51.85528 0 Td (Python) Tj T* -51.85528 0 Td ET -Q -Q -q -1 0 0 1 321.7072 165 cm -q -.960784 .960784 .862745 rg -n 0 0 142.1826 12 re f* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.53129 0 Td (Java) Tj T* -60.53129 0 Td ET -Q -Q -0 0 0 rg -q -1 0 0 1 6 147 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (object) Tj T* ET -Q -Q -q -1 0 0 1 86.7623 147 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (MAP) Tj T* ET -Q -Q -q -1 0 0 1 174.8666 147 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (dict) Tj T* ET -Q -Q -q -1 0 0 1 321.7072 147 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Map) Tj (<) Tj (String, Object) Tj (>) Tj T* ET -Q -Q -q -1 0 0 1 6 129 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (array) Tj T* ET -Q -Q -q -1 0 0 1 86.7623 129 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (ARRAY) Tj T* ET -Q -Q -q -1 0 0 1 174.8666 129 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (list) Tj T* ET -Q -Q -q -1 0 0 1 321.7072 129 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (List) Tj (<) Tj (Object) Tj (>) Tj T* ET -Q -Q -q -1 0 0 1 6 111 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (string) Tj T* ET -Q -Q -q -1 0 0 1 86.7623 111 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (STRING) Tj T* ET -Q -Q -q -1 0 0 1 174.8666 111 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (unicode \(Python 2\)) Tj T* ET -Q -Q -q -1 0 0 1 321.7072 111 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (String) Tj T* ET -Q -Q -q -1 0 0 1 174.8666 93 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (str \(Python 3\)) Tj T* ET -Q -Q -q -1 0 0 1 6 75 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (number) Tj T* ET -Q -Q -q -1 0 0 1 86.7623 75 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (INTEGER) Tj T* ET -Q -Q -q -1 0 0 1 174.8666 75 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (int) Tj T* ET -Q -Q -q -1 0 0 1 321.7072 75 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Long) Tj T* ET -Q -Q -q -1 0 0 1 86.7623 57 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (REAL) Tj T* ET -Q -Q -q -1 0 0 1 174.8666 57 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (float) Tj T* ET -Q -Q -q -1 0 0 1 321.7072 57 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Double) Tj T* ET -Q -Q -q -1 0 0 1 6 39 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (true) Tj T* ET -Q -Q -q -1 0 0 1 86.7623 39 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (BOOLEAN) Tj T* ET -Q -Q -q -1 0 0 1 174.8666 39 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (bool) Tj T* ET -Q -Q -q -1 0 0 1 321.7072 39 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Boolean) Tj T* ET -Q -Q -q -1 0 0 1 6 21 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (false) Tj T* ET -Q -Q -q -1 0 0 1 6 3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (null) Tj T* ET -Q -Q -q -1 0 0 1 86.7623 3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (NULL) Tj T* ET -Q -Q -q -1 0 0 1 174.8666 3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (None) Tj T* ET -Q -Q -q -1 0 0 1 321.7072 3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (null) Tj T* ET -Q -Q -q -1 J -1 j -0 0 0 RG -.25 w -n 0 162 m 469.8898 162 l S -n 0 144 m 469.8898 144 l S -n 0 126 m 469.8898 126 l S -n 168.8666 108 m 315.7072 108 l S -n 0 90 m 469.8898 90 l S -n 80.7623 72 m 469.8898 72 l S -n 0 54 m 469.8898 54 l S -n 0 36 m 80.7623 36 l S -n 0 18 m 469.8898 18 l S -n 80.7623 0 m 80.7623 180 l S -n 168.8666 0 m 168.8666 180 l S -n 315.7072 0 m 315.7072 180 l S -n 0 180 m 469.8898 180 l S -n 0 0 m 469.8898 0 l S -n 0 0 m 0 180 l S -n 469.8898 0 m 469.8898 180 l S -Q -Q -q -1 0 0 1 62.69291 203.8236 cm -Q -q -1 0 0 1 62.69291 173.8236 cm -q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Rule Debugging and Documentation) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 107.8236 cm -q -0 0 0 rg -BT 1 0 0 1 0 50 Tm /F1 10 Tf 12 TL .061654 Tw (If the rule processor reports an error or if you're debugging your rules by enabling DEBUG log tracing then) Tj T* 0 Tw 1.278876 Tw (you must be able to correlate the reported statement to where it appears in your rule JSON source. A) Tj T* 0 Tw 2.16936 Tw (message will always identify a statement by the rule number, block number within that rule and the) Tj T* 0 Tw .417126 Tw (statement number within that block. However once your rules become moderately complex it will become) Tj T* 0 Tw (increasingly difficult to identify a statement by counting rules, blocks and statements.) Tj T* ET -Q -Q -q -1 0 0 1 56.69291 56.69291 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 234.8349 0 Td (-9-) Tj T* -234.8349 0 Td ET -Q -Q - -endstream -endobj -148 0 obj -<< /Length 5236 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 729.0236 cm -q -BT 1 0 0 1 0 26 Tm 1.766303 Tw 12 TL /F1 10 Tf 0 0 0 rg (A better approach is to tag rules and blocks with a name or other identifying string. You can set the) Tj T* 0 Tw 2.094269 Tw 0 0 .501961 rg (Reserved Variables) Tj 0 0 0 rg ( ) Tj /F4 10 Tf 0 0 0 rg (rule_name ) Tj /F1 10 Tf 0 0 0 rg (and ) Tj /F4 10 Tf 0 0 0 rg (block_name ) Tj /F1 10 Tf 0 0 0 rg (to a string of your choice. These strings will be) Tj T* 0 Tw (reported in all messages along with the rule, block and statement numbers.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 675.0236 cm -q -BT 1 0 0 1 0 38 Tm .720651 Tw 12 TL /F1 10 Tf 0 0 0 rg (JSON does not permit comments, as such you cannot include explanatory comments next to your rules,) Tj T* 0 Tw 1.895697 Tw (blocks and statements in the JSON source. The ) Tj /F4 10 Tf 0 0 0 rg (rule_name ) Tj /F1 10 Tf 0 0 0 rg (and ) Tj /F4 10 Tf 0 0 0 rg (block_name ) Tj /F1 10 Tf 0 0 0 rg (can serve a similar) Tj T* 0 Tw .55436 Tw (purpose. By putting assignments to these variables as the first statement in a block you'll both document) Tj T* 0 Tw (your rules and be able to identify specific statements in log messages.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 645.0236 cm -q -BT 1 0 0 1 0 14 Tm 2.807126 Tw 12 TL /F1 10 Tf 0 0 0 rg (During rule execution the ) Tj /F4 10 Tf 0 0 0 rg (rule_name ) Tj /F1 10 Tf 0 0 0 rg (and ) Tj /F4 10 Tf 0 0 0 rg (block_name ) Tj /F1 10 Tf 0 0 0 rg (are initialized to the empty string at the) Tj T* 0 Tw (beginning of each rule and block respectively.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 615.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .19832 Tw (The above example is augmented to include this information. The rule name is set in the first statement in) Tj T* 0 Tw (the first block.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 269.8236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 528 336 re B* -Q -q -BT 1 0 0 1 0 314 Tm 12 TL /F4 10 Tf 0 0 0 rg ([) Tj T* ( [) Tj T* ( ["set", "$rule_name", "Must have UserName or subject"],) Tj T* ( ["set", "block_name", "Initialization"],) Tj T* ( ["set", $user, ""],) Tj T* ( ["set", $roles, []]) Tj T* ( ],) Tj T* ( [) Tj T* ( ["set", "block_name", "Test for UserName, set $user"],) Tj T* ( ["in", "UserName", "$assertion"],) Tj T* ( ["continue", "if_not_success"],) Tj T* ( ["set", "$user", "$assertion[UserName"],) Tj T* ( ],) Tj T* ( [) Tj T* ( ["set", "block_name", "Test for subject, set $user"],) Tj T* ( ["in", "subject", "$assertion"],) Tj T* ( ["continue", "if_not_success"],) Tj T* ( ["set", "$user", "$assertion[subject]"],) Tj T* ( ],) Tj T* ( [) Tj T* ( ["set", "block_name", "If not $user fail, else append unprivileged to roles"],) Tj T* ( ["length", "$temp", "$user"],) Tj T* ( ["compare", "$temp", ") Tj (>) Tj (", 0],) Tj T* ( ["exit", "rule_fails", "if_not_success"]) Tj T* ( ["append" "$roles", "unprivileged"]) Tj T* ( ]) Tj T* (]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 239.8236 cm -q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Variables) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 185.8236 cm -q -0 0 0 rg -BT 1 0 0 1 0 38 Tm /F1 10 Tf 12 TL .137765 Tw (Variables always begin with a dollar sign \($\) and are followed by an identifier which is any alpha character) Tj T* 0 Tw 3.269982 Tw (followed by zero or more alphanumeric or underscore characters. The variable may optionally be) Tj T* 0 Tw 1.757984 Tw (delimited with braces \({}\) to separate the variable from surrounding text. Three types of variables are) Tj T* 0 Tw (supported:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 179.8236 cm -Q -q -1 0 0 1 62.69291 179.8236 cm -Q -q -1 0 0 1 62.69291 167.8236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (scalar) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 161.8236 cm -Q -q -1 0 0 1 62.69291 149.8236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (array \(indexed by zero based integer\)) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 143.8236 cm -Q -q -1 0 0 1 62.69291 131.8236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (associative array \(indexed by string\)) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 131.8236 cm -Q -q -1 0 0 1 62.69291 101.8236 cm -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .113516 Tw (Both arrays and associative arrays use square brackets \([]\) to specify a member of the array. Examples of) Tj T* 0 Tw (variable usage:) Tj T* ET -Q -Q -q -1 0 0 1 56.69291 56.69291 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 232.0549 0 Td (-10-) Tj T* -232.0549 0 Td ET -Q -Q - -endstream -endobj -149 0 obj -<< /Length 6068 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 679.8236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 84 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 62 Tm /F4 10 Tf 12 TL ($name) Tj T* (${name}) Tj T* ($groups[0]) Tj T* (${groups[0]}) Tj T* ($properties[key]) Tj T* (${properties[key]}) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 623.8236 cm -q -BT 1 0 0 1 0 38 Tm .001163 Tw 12 TL /F1 10 Tf 0 0 0 rg (An array or an associative array may be referenced by it's base name \(omitting the indexing brackets\). For) Tj T* 0 Tw 5.84748 Tw (example the associative array array named "properties" is referenced using it's base name) Tj T* 0 Tw .301318 Tw /F4 10 Tf 0 0 0 rg ($properties ) Tj /F1 10 Tf 0 0 0 rg (but if you want to access a member of the "properties" associative array named "duration") Tj T* 0 Tw (you would do this ) Tj /F4 10 Tf 0 0 0 rg ($properties[duration]) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 593.8236 cm -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 1.059986 Tw (This is not a general purpose language with full expression syntax. Only one level of variable lookup is) Tj T* 0 Tw (supported. Therefore compound references like this) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 560.6236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 24 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F4 10 Tf 12 TL ($properties[$groups[2]]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 540.6236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (will not work.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 513.6236 cm -q -BT 1 0 0 1 0 2.5 Tm 15 TL /F6 12.5 Tf 0 0 0 rg (Escaping) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 459.6236 cm -q -BT 1 0 0 1 0 38 Tm .461894 Tw 12 TL /F1 10 Tf 0 0 0 rg (If you need to include a dollar sign in a string \(where it is immediately followed by either an identifier or a) Tj T* 0 Tw .196654 Tw (brace and identifier\) and do not want to have it be interpreted as representing a variable you must escape) Tj T* 0 Tw 2.522651 Tw (the dollar sign with a backslash, for example "$amount" is interpreted as the variable ) Tj /F4 10 Tf 0 0 0 rg (amount ) Tj /F1 10 Tf 0 0 0 rg (but) Tj T* 0 Tw ("\\$amount" is interpreted as the string "$amount" .) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 429.6236 cm -q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Reserved Variables) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 411.6236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (A rule has the following reserved variables:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 395.6236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (assertion) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 380.6236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The current assertion values from the federated IdP. It is a dictionary of key/value pairs.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 364.6236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (regexp_array) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 325.6236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 26 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 26 Tm /F1 10 Tf 12 TL .276651 Tw (The regular expression groups from the last successful regexp match indexed by number. Group 0 is) Tj T* 0 Tw .690697 Tw (the entire match. Groups 1..n are the corresponding parenthesized group counting from the left. For) Tj T* 0 Tw (example regexp_array[1] is the first group.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 309.6236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (regexp_map) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 294.6236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The regular expression groups from the last successful regexp match indexed by group name.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 278.6236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (rule_number) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 263.6236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The zero based index of the currently executing rule.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 247.6236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (rule_name) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 232.6236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The name of the currently executing rule. If the rule name has not been set it will be the empty string.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 216.6236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (block_number) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 201.6236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The zero based index of the currently executing block within the currently executing rule.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 185.6236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (block_name) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 158.6236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 14 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 1.094198 Tw (The name of the currently executing block. If the block name has not been set it will be the empty) Tj T* 0 Tw (string.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 142.6236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (statement_number) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 127.6236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The zero based index of the currently executing statement within the currently executing block.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 56.69291 56.69291 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 232.0549 0 Td (-11-) Tj T* -232.0549 0 Td ET -Q -Q - -endstream -endobj -150 0 obj -<< /Length 6055 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 744.0236 cm -q -BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Examples) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 714.0236 cm -q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Split a fully qualified username into user and realm components) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 648.0236 cm -q -BT 1 0 0 1 0 50 Tm 2.38311 Tw 12 TL /F1 10 Tf 0 0 0 rg (It's common for some IdP's to return a fully qualified username \(e.g. principal or subject\). The fully) Tj T* 0 Tw 2.834983 Tw (qualified username is the concatenation of the user name, separator and realm name. A common) Tj T* 0 Tw .239318 Tw (separator is the @ character. In this example lets say the fully qualified username is ) Tj /F4 10 Tf 0 0 0 rg (bob@example.com) Tj T* 0 Tw .731751 Tw /F1 10 Tf 0 0 0 rg (and you want to return the user and realm as independent values in your mapped result. The username) Tj T* 0 Tw (appears in the assertion as the value ) Tj /F4 10 Tf 0 0 0 rg (Principal) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 618.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .569398 Tw (Our strategy will be to use a regular expression identify the user and realm components and then assign) Tj T* 0 Tw (them to local variables which will then populate the mapped result.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 600.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The mapping in JSON is:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 530.8236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 60 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 38 Tm /F4 10 Tf 12 TL ({) Tj T* ( "user": "$username",) Tj T* ( "realm": "$domain") Tj T* (}) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 510.8236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The assertion in JSON is:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 453.6236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 48 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 26 Tm /F4 10 Tf 12 TL ({) Tj T* ( "Principal": "bob@example.com") Tj T* (}) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 433.6236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Our rule is:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 292.4236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 492 132 re B* -Q -q -BT 1 0 0 1 0 110 Tm 12 TL /F4 10 Tf 0 0 0 rg ([) Tj T* ( [) Tj T* ( ["in", "Principal", "assertion"],) Tj T* ( ["exit", "rule_fails", "if_not_success"],) Tj T* ( ["regexp", "$assertion[Principal]", \(?P) Tj (<) Tj (username) Tj (>) Tj (\\\\w+\)@\(?P) Tj (<) Tj (domain) Tj (>) Tj (.+\)"],) Tj T* ( ["set", "$username", "$regexp_map[username]"],) Tj T* ( ["set", "$domain", "$regexp_map[domain]"],) Tj T* ( ["exit, "rule_succeeds", "always"]) Tj T* ( ]) Tj T* (]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 272.4236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Rule explanation:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 254.4236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Block 0:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 248.4236 cm -Q -q -1 0 0 1 62.69291 248.4236 cm -Q -q -1 0 0 1 62.69291 236.4236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (1.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Test if the assertion contains a Principal value.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 230.4236 cm -Q -q -1 0 0 1 62.69291 218.4236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (2.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Abort the rule if the assertion does not contain a Principal value.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 212.4236 cm -Q -q -1 0 0 1 62.69291 188.4236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 9 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (3.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 1.867126 Tw (Apply a regular expression the the Principal value. Use named groupings for the username and) Tj T* 0 Tw (domain components for clarity.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 182.4236 cm -Q -q -1 0 0 1 62.69291 170.4236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (4.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Assign the regexp group username to the $username local variable.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 164.4236 cm -Q -q -1 0 0 1 62.69291 152.4236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (5.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Assign the regexp group domain to the $domain local variable.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 146.4236 cm -Q -q -1 0 0 1 62.69291 122.4236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 9 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (6.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -BT 1 0 0 1 0 14 Tm 1.112339 Tw 12 TL /F1 10 Tf 0 0 0 rg (Exit the rule, apply the mapping, return the mapped values. Note, an explicit ) Tj 0 0 .501961 rg (exit ) Tj 0 0 0 rg (is not required if) Tj T* 0 Tw (there are no further statements in the rule, as is the case here.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 122.4236 cm -Q -q -1 0 0 1 62.69291 104.4236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The mapped result in JSON is:) Tj T* ET -Q -Q -q -1 0 0 1 56.69291 56.69291 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 232.0549 0 Td (-12-) Tj T* -232.0549 0 Td ET -Q -Q - -endstream -endobj -151 0 obj -<< /Length 3622 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 703.8236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 60 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 38 Tm /F4 10 Tf 12 TL ({) Tj T* ( "user": "bob",) Tj T* ( "realm": "example.com") Tj T* (}) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 673.8236 cm -q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Build a set of roles based on group membership) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 607.8236 cm -q -BT 1 0 0 1 0 50 Tm .028409 Tw 12 TL /F1 10 Tf 0 0 0 rg (Often one wants to grant roles to a user based on their membership in certain groups. In this example let's) Tj T* 0 Tw .518221 Tw (say the assertion contains a ) Tj /F4 10 Tf 0 0 0 rg (Groups ) Tj /F1 10 Tf 0 0 0 rg (value which is a colon separated list of group names. Our strategy) Tj T* 0 Tw .064274 Tw (is to split the ) Tj /F4 10 Tf 0 0 0 rg (Groups ) Tj /F1 10 Tf 0 0 0 rg (assertion value into an array of group names. Then we'll test if a specific group is in) Tj T* 0 Tw .555898 Tw (the groups array, if it is we'll add a role. Finally if no roles have been mapped we fail. Users in the group) Tj T* 0 Tw ("student" will get the role "unprivileged" and users in the group "helpdesk" will get the role "admin".) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 589.8236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The mapping in JSON is:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 532.6236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 48 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 26 Tm /F4 10 Tf 12 TL ({) Tj T* ( "roles": "$roles",) Tj T* (}) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 512.6236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The assertion in JSON is:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 455.4236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 48 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 26 Tm /F4 10 Tf 12 TL ({) Tj T* ( "Groups": "student:helpdesk") Tj T* (}) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 435.4236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Our rule is:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 114.2236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 312 re B* -Q -q -BT 1 0 0 1 0 290 Tm 12 TL /F4 10 Tf 0 0 0 rg ([) Tj T* ( [) Tj T* ( ["in", "Groups", "assertion"],) Tj T* ( ["exit", "rule_fails", "if_not_success"],) Tj T* ( ["set", "$roles", []],) Tj T* ( ["split", "$groups", "$assertion[Groups]", ":"],) Tj T* ( ],) Tj T* ( [) Tj T* ( ["in", "student", "$groups"],) Tj T* ( ["continue", "if_not_success"],) Tj T* ( ["append", "$roles", "unprivileged"]) Tj T* ( ],) Tj T* ( [) Tj T* ( ["in", "helpdesk", "$groups"],) Tj T* ( ["continue", "if_not_success"],) Tj T* ( ["append", "$roles", "admin"]) Tj T* ( ],) Tj T* ( [) Tj T* ( ["unique", "$roles", "$roles"],) Tj T* ( ["length", "$temp", "roles"],) Tj T* ( ["compare", $temp", ") Tj (>) Tj (", 0],) Tj T* ( ["exit", "rule_fails", "if_not_success"]) Tj T* ( ]) Tj T* T* (]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 94.22362 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Rule explanation:) Tj T* ET -Q -Q -q -1 0 0 1 56.69291 56.69291 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 232.0549 0 Td (-13-) Tj T* -232.0549 0 Td ET -Q -Q - -endstream -endobj -152 0 obj -<< /Length 8175 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 753.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Block 0) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 747.0236 cm -Q -q -1 0 0 1 62.69291 747.0236 cm -Q -q -1 0 0 1 62.69291 735.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (1.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Test if the assertion contains a Groups value.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 729.0236 cm -Q -q -1 0 0 1 62.69291 717.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (2.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Abort the rule if the assertion does not contain a Groups value.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 711.0236 cm -Q -q -1 0 0 1 62.69291 699.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (3.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Initialize the $roles variable to an empty array.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 693.0236 cm -Q -q -1 0 0 1 62.69291 681.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (4.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Split the colon separated list of group names into an array of individual group names) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 681.0236 cm -Q -q -1 0 0 1 62.69291 663.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Block 1) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 657.0236 cm -Q -q -1 0 0 1 62.69291 657.0236 cm -Q -q -1 0 0 1 62.69291 645.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (1.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Test if "student" is in the $groups array) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 639.0236 cm -Q -q -1 0 0 1 62.69291 627.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (2.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Exit the block if it's not.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 621.0236 cm -Q -q -1 0 0 1 62.69291 609.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (3.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Append "unprivileged" to the $roles array) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 609.0236 cm -Q -q -1 0 0 1 62.69291 591.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Block 2) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 585.0236 cm -Q -q -1 0 0 1 62.69291 585.0236 cm -Q -q -1 0 0 1 62.69291 573.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (1.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Test if "helpdesk" is in the $groups array) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 567.0236 cm -Q -q -1 0 0 1 62.69291 555.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (2.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Exit the block if it's not.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 549.0236 cm -Q -q -1 0 0 1 62.69291 537.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (3.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Append "admin" to the $roles array) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 537.0236 cm -Q -q -1 0 0 1 62.69291 519.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Block 3) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 513.0236 cm -Q -q -1 0 0 1 62.69291 513.0236 cm -Q -q -1 0 0 1 62.69291 489.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 9 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (1.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .91528 Tw (Strip any duplicate roles that might have been appended to the $roles array to assure each role is) Tj T* 0 Tw (unique.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 483.0236 cm -Q -q -1 0 0 1 62.69291 471.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (2.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Count how many members are in the $roles array, assign the length to the $temp variable.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 465.0236 cm -Q -q -1 0 0 1 62.69291 453.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (3.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Test to see if the $roles array had any members.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 447.0236 cm -Q -q -1 0 0 1 62.69291 435.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (4.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Fail if no roles had been assigned.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 435.0236 cm -Q -q -1 0 0 1 62.69291 417.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The mapped result in JSON is:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 359.8236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 48 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 26 Tm /F4 10 Tf 12 TL ({) Tj T* ( "roles": ["unprivileged", "admin"]) Tj T* (}) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 315.8236 cm -q -0 0 0 rg -BT 1 0 0 1 0 26 Tm /F1 10 Tf 12 TL .258735 Tw (However, suppose whatever is receiving your mapped results is not expecting an array of roles. Instead it) Tj T* 0 Tw .136654 Tw (expects a comma separated list in a string. To accomplish this add the following statement as the last one) Tj T* 0 Tw (in the final block:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 282.6236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 24 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F4 10 Tf 12 TL (["join", "$roles", "$roles", ","]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 262.6236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Then the mapped result will be:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 205.4236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 48 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 26 Tm /F4 10 Tf 12 TL ({) Tj T* ( "roles": "unprivileged,admin"]) Tj T* (}) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 175.4236 cm -q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (White list certain users and grant them specific roles) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 133.4236 cm -q -0 0 0 rg -BT 1 0 0 1 0 26 Tm /F1 10 Tf 12 TL 1.326412 Tw (Suppose you have certain users you always want to unconditionally accept and authorize with specific) Tj T* 0 Tw 1.323735 Tw (roles. For example if the user is "head_of_IT" then assign her the "user" and "admin" roles. Otherwise) Tj T* 0 Tw (keep processing. The list of white listed users is hard-coded into the rule.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 115.4236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The mapping in JSON is:) Tj T* ET -Q -Q -q -1 0 0 1 56.69291 56.69291 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 232.0549 0 Td (-14-) Tj T* -232.0549 0 Td ET -Q -Q - -endstream -endobj -153 0 obj -<< /Length 5659 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 703.8236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 60 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 38 Tm /F4 10 Tf 12 TL ({) Tj T* ( "user": $user,) Tj T* ( "roles": "$roles",) Tj T* (}) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 683.8236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The assertion in JSON is:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 626.6236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 48 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 26 Tm /F4 10 Tf 12 TL ({) Tj T* ( "UserName": "head_of_IT") Tj T* (}) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 606.6236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Our rule in JSON is:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 417.4236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 480 180 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 158 Tm /F4 10 Tf 12 TL ([) Tj T* ( [) Tj T* ( ["in", "UserName", "assertion"],) Tj T* ( ["exit", "rule_fails", "if_not_success"],) Tj T* ( ["in", "$assertion[UserName]", ["head_of_IT", "head_of_Engineering"]],) Tj T* ( ["continue", "if_not_success"],) Tj T* ( ["set", "$user", "$assertion[UserName"]) Tj T* ( ["set", "$roles", ["user", "admin"]],) Tj T* ( ["exit", "rule_succeeds", "always"]) Tj T* ( ],) Tj T* ( [) Tj T* ( ...) Tj T* ( ]) Tj T* (]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 397.4236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Rule explanation:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 379.4236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Block 0) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 373.4236 cm -Q -q -1 0 0 1 62.69291 373.4236 cm -Q -q -1 0 0 1 62.69291 361.4236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (1.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Test if the assertion contains a UserName value.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 355.4236 cm -Q -q -1 0 0 1 62.69291 343.4236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (2.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Abort the rule if the assertion does not contain a UserName value.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 337.4236 cm -Q -q -1 0 0 1 62.69291 325.4236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (3.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Test if the user is in the hardcoded list of white listed users.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 319.4236 cm -Q -q -1 0 0 1 62.69291 307.4236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (4.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (If the user isn't in the white listed array then exit the block and continue execution at the next block.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 301.4236 cm -Q -q -1 0 0 1 62.69291 289.4236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (5.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Set the $user local variable to $assertion[UserName]) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 283.4236 cm -Q -q -1 0 0 1 62.69291 271.4236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (6.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Set the $roles local variable to the hardcoded array containing "user" and "admin") Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 265.4236 cm -Q -q -1 0 0 1 62.69291 253.4236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (7.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (We're done, unconditionally exit and return the mapped result.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 253.4236 cm -Q -q -1 0 0 1 62.69291 235.4236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Block 1) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 229.4236 cm -Q -q -1 0 0 1 62.69291 229.4236 cm -Q -q -1 0 0 1 62.69291 217.4236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (1.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Further processing) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 217.4236 cm -Q -q -1 0 0 1 62.69291 199.4236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The mapped result in JSON is:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 130.2236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 60 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 38 Tm /F4 10 Tf 12 TL ({) Tj T* ( "user": "head_of_IT",) Tj T* ( "roles": ["users", "admin"]) Tj T* (}) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 56.69291 56.69291 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 232.0549 0 Td (-15-) Tj T* -232.0549 0 Td ET -Q -Q - -endstream -endobj -154 0 obj -<< /Length 5457 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 747.0236 cm -q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Black list certain users) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 705.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 26 Tm /F1 10 Tf 12 TL .56881 Tw (Suppose you have certain users you always want to unconditionally deny access to by placing them in a) Tj T* 0 Tw 1.411654 Tw (black list. In this example the user "BlackHat" will try to gain access. The black list includes the users) Tj T* 0 Tw ("BlackHat" and "Spook".) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 687.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The mapping in JSON is:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 617.8236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 60 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 38 Tm /F4 10 Tf 12 TL ({) Tj T* ( "user": $user,) Tj T* ( "roles": "$roles",) Tj T* (}) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 597.8236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The assertion in JSON is:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 540.6236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 48 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 26 Tm /F4 10 Tf 12 TL ({) Tj T* ( "UserName": "BlackHat") Tj T* (}) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 520.6236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Our rule in JSON is:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 367.4236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 144 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 122 Tm /F4 10 Tf 12 TL ([) Tj T* ( [) Tj T* ( ["in", "UserName", "assertion"],) Tj T* ( ["exit", "rule_fails", "if_not_success"],) Tj T* ( ["in", "$assertion[UserName]", ["BlackHat", "Spook"]],) Tj T* ( ["exit", "rule_fails", "if_success"]) Tj T* ( ],) Tj T* ( [) Tj T* ( ...) Tj T* ( ]) Tj T* (]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 347.4236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Rule explanation:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 329.4236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Block 0) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 323.4236 cm -Q -q -1 0 0 1 62.69291 323.4236 cm -Q -q -1 0 0 1 62.69291 311.4236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (1.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Test if the assertion contains a UserName value.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 305.4236 cm -Q -q -1 0 0 1 62.69291 293.4236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (2.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Abort the rule if the assertion does not contain a UserName value.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 287.4236 cm -Q -q -1 0 0 1 62.69291 275.4236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (3.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Test if the user is in the hard-coded list of black listed users.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 269.4236 cm -Q -q -1 0 0 1 62.69291 257.4236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (4.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (If the test succeeds then immediately abort and return failure.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 257.4236 cm -Q -q -1 0 0 1 62.69291 239.4236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Block 1) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 233.4236 cm -Q -q -1 0 0 1 62.69291 233.4236 cm -Q -q -1 0 0 1 62.69291 221.4236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (1.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Further processing) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 221.4236 cm -Q -q -1 0 0 1 62.69291 203.4236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The mapped result in JSON is:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 170.2236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 24 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F4 10 Tf 12 TL (Null) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 140.2236 cm -q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Format Strings and/or Concatenate Strings) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 98.22362 cm -q -BT 1 0 0 1 0 26 Tm 1.498651 Tw 12 TL /F1 10 Tf 0 0 0 rg (You can replace variables in a format string using the ) Tj 0 0 .501961 rg (interpolate ) Tj 0 0 0 rg (verb. String concatenation is trivially) Tj T* 0 Tw 1.745868 Tw (placing two variables adjacent to one another in a format string. Suppose you want to form an email) Tj T* 0 Tw (address from the username and domain in an assertion.) Tj T* ET -Q -Q -q -1 0 0 1 56.69291 56.69291 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 232.0549 0 Td (-16-) Tj T* -232.0549 0 Td ET -Q -Q - -endstream -endobj -155 0 obj -<< /Length 4434 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 753.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The mapping in JSON is:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 695.8236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 48 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 26 Tm /F4 10 Tf 12 TL ({) Tj T* ( "email": $email,) Tj T* (}) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 675.8236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The assertion in JSON is:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 606.6236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 60 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 38 Tm /F4 10 Tf 12 TL ({) Tj T* ( "UserName": "Bob",) Tj T* ( "Domain": "example.com") Tj T* (}) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 586.6236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Our rule in JSON is:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 505.4236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 474 72 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 50 Tm /F4 10 Tf 12 TL ([) Tj T* ( [) Tj T* ( ["interpolate", "$email", "$assertion[UserName]@$assertion[Domain]"],) Tj T* ( ]) Tj T* (]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 485.4236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Rule explanation:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 467.4236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Block 0) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 461.4236 cm -Q -q -1 0 0 1 62.69291 461.4236 cm -Q -q -1 0 0 1 62.69291 437.4236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 9 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (1.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 8.205976 Tw (Replace the variable $assertion[UserName] with it's value and replace the variable) Tj T* 0 Tw ($assertion[Domain] with it's value.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 437.4236 cm -Q -q -1 0 0 1 62.69291 419.4236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The mapped result in JSON is:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 362.2236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 48 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 26 Tm /F4 10 Tf 12 TL ({) Tj T* ( "email": "Bob@example.com",) Tj T* (}) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 318.2236 cm -q -0 0 0 rg -BT 1 0 0 1 0 26 Tm /F1 10 Tf 12 TL .667984 Tw (Note, sometimes it's necessary to utilize braces to separate variables from surrounding text by using the) Tj T* 0 Tw .39811 Tw (brace notation. This can also make the format string more readable. Using braces to delimit variables the) Tj T* 0 Tw (above would be:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 237.0236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 498 72 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 50 Tm /F4 10 Tf 12 TL ([) Tj T* ( [) Tj T* ( ["interpolate", "$email", "${assertion[UserName]}@${assertion[Domain]}"],) Tj T* ( ]) Tj T* (]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 207.0236 cm -q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Make associative array lookups case insensitive) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 165.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 26 Tm /F1 10 Tf 12 TL 2.917126 Tw (Many systems treat field names as case insensitive. By default associative array indexing is case) Tj T* 0 Tw .627356 Tw (sensitive. The solution is to lower case all the keys in an associative array and then only use lower case) Tj T* 0 Tw (indices. Suppose you want the assertion associative array to be case insensitive.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 147.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The mapping in JSON is:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 89.82362 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 48 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 26 Tm /F4 10 Tf 12 TL ({) Tj T* ( "user": $user,) Tj T* (}) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 56.69291 56.69291 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 232.0549 0 Td (-17-) Tj T* -232.0549 0 Td ET -Q -Q - -endstream -endobj -156 0 obj -<< /Length 7739 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 753.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The assertion in JSON is:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 695.8236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 48 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 26 Tm /F4 10 Tf 12 TL ({) Tj T* ( "UserName": "Bob") Tj T* (}) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 675.8236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Our rule in JSON is:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 558.6236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 108 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 86 Tm /F4 10 Tf 12 TL ([) Tj T* ( [) Tj T* ( ["lower", "$assertion", "$assertion"],) Tj T* ( ["in", "username", "assertion"],) Tj T* ( ["exit", "rule_fails", "if_not_success"],) Tj T* ( ["set", "$user", "$assertion[username"]) Tj T* ( ]) Tj T* (]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 538.6236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Rule explanation:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 520.6236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Block 0) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 514.6236 cm -Q -q -1 0 0 1 62.69291 514.6236 cm -Q -q -1 0 0 1 62.69291 502.6236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (1.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Lower case all the keys in the assertion associative array.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 496.6236 cm -Q -q -1 0 0 1 62.69291 484.6236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (2.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Test if the assertion contains a username value.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 478.6236 cm -Q -q -1 0 0 1 62.69291 466.6236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (3.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Abort the rule if the assertion does not contain a username value.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 460.6236 cm -Q -q -1 0 0 1 62.69291 448.6236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (4.) Tj T* -5.66 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Assign the username value in the assertion to $user) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 448.6236 cm -Q -q -1 0 0 1 62.69291 430.6236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The mapped result in JSON is:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 373.4236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 48 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 26 Tm /F4 10 Tf 12 TL ({) Tj T* ( "user": "Bob",) Tj T* (}) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 340.4236 cm -q -BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Verbs) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 322.4236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The following verbs are supported:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 316.4236 cm -Q -q -1 0 0 1 62.69291 316.4236 cm -Q -q -1 0 0 1 62.69291 304.4236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 .501961 rg -0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (set) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 298.4236 cm -Q -q -1 0 0 1 62.69291 286.4236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 .501961 rg -0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (length) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 280.4236 cm -Q -q -1 0 0 1 62.69291 268.4236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 .501961 rg -0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (interpolate) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 262.4236 cm -Q -q -1 0 0 1 62.69291 250.4236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 .501961 rg -0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (append) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 244.4236 cm -Q -q -1 0 0 1 62.69291 232.4236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 .501961 rg -0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (unique) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 226.4236 cm -Q -q -1 0 0 1 62.69291 214.4236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 .501961 rg -0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (regexp) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 208.4236 cm -Q -q -1 0 0 1 62.69291 196.4236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 .501961 rg -0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (regexp_replace) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 190.4236 cm -Q -q -1 0 0 1 62.69291 178.4236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 .501961 rg -0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (split) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 172.4236 cm -Q -q -1 0 0 1 62.69291 160.4236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 .501961 rg -0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (join) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 154.4236 cm -Q -q -1 0 0 1 62.69291 142.4236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 .501961 rg -0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (lower) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 136.4236 cm -Q -q -1 0 0 1 62.69291 124.4236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 .501961 rg -0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (upper) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 118.4236 cm -Q -q -1 0 0 1 62.69291 106.4236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 .501961 rg -0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (compare) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 100.4236 cm -Q -q -1 0 0 1 56.69291 56.69291 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 232.0549 0 Td (-18-) Tj T* -232.0549 0 Td ET -Q -Q - -endstream -endobj -157 0 obj -<< /Length 6506 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 753.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 .501961 rg -0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (in) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 747.0236 cm -Q -q -1 0 0 1 62.69291 735.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 .501961 rg -0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (not_in) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 729.0236 cm -Q -q -1 0 0 1 62.69291 717.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 .501961 rg -0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (exit) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 711.0236 cm -Q -q -1 0 0 1 62.69291 699.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 .501961 rg -0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (continue) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 699.0236 cm -Q -q -1 0 0 1 62.69291 633.0236 cm -q -BT 1 0 0 1 0 50 Tm .753876 Tw 12 TL /F1 10 Tf 0 0 0 rg (Some verbs have a side effects. A verb may set a boolean success/fail result which may then be tested) Tj T* 0 Tw .428988 Tw (with a subsequent verb. For example the ) Tj /F4 10 Tf 0 0 0 rg (fail ) Tj /F1 10 Tf 0 0 0 rg (verb can be used to indicate the rule fails if a prior result) Tj T* 0 Tw .029318 Tw (is either ) Tj /F4 10 Tf 0 0 0 rg (success ) Tj /F1 10 Tf 0 0 0 rg (or ) Tj /F4 10 Tf 0 0 0 rg (not_success) Tj /F1 10 Tf 0 0 0 rg (. The ) Tj /F4 10 Tf 0 0 0 rg (regexp ) Tj /F1 10 Tf 0 0 0 rg (verb which performs a regular expression search on a) Tj T* 0 Tw .726412 Tw (string stores the regular expression sub-matches as a side effect in the variables ) Tj /F4 10 Tf 0 0 0 rg ($regexp_array ) Tj /F1 10 Tf 0 0 0 rg (and) Tj T* 0 Tw /F4 10 Tf 0 0 0 rg ($regexp_map) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 600.0236 cm -q -BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Verb Definitions) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 570.0236 cm -q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (set) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 552.0236 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F4 10 Tf 0 0 0 rg (set) Tj ( ) Tj ($variable) Tj ( ) Tj (value) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 536.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL ($variable) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 521.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The variable being assigned \(i.e. lhs\)) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 505.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (value) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 490.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The value to assign to the variable \(i.e. rhs\). The value may be another variable or a constant.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 472.0236 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 0 rg (set ) Tj /F1 10 Tf (assigns a value to a variable, in other words it's an assignment statement.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 445.0236 cm -q -BT 1 0 0 1 0 2.5 Tm 15 TL /F6 12.5 Tf 0 0 0 rg (Examples:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 427.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Initialize a variable to an empty array.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 393.8236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 24 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F4 10 Tf 12 TL (["set", "$groups", []]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 373.8236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Initialize a variable to an empty associative array.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 340.6236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 24 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F4 10 Tf 12 TL (["set", "$groups", {}]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 320.6236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Assign a string.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 287.4236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 24 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F4 10 Tf 12 TL (["set", "$version", "1.2.3"]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 267.4236 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Copy the ) Tj /F4 10 Tf 0 0 0 rg (UserName ) Tj /F1 10 Tf 0 0 0 rg (value from the assertion to a temporary variable.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 234.2236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 24 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F4 10 Tf 12 TL (["set", "$temp", "$assertion[UserName]"],) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 214.2236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Get the 2nd item in an array \(array indexing is zero based\)) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 181.0236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 24 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F4 10 Tf 12 TL (["set", "$group", "$groups[1]"]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 161.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Set the associative array entry "IdP" to "kdc.example.com".) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 127.8236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 24 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F4 10 Tf 12 TL (["set", "$metadata[IdP]", "kdc.example.com""]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 91.47717 cm -n 0 14.17323 m 469.8898 14.17323 l S -Q -q -1 0 0 1 56.69291 56.69291 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 232.0549 0 Td (-19-) Tj T* -232.0549 0 Td ET -Q -Q - -endstream -endobj -158 0 obj -<< /Length 6125 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 747.0236 cm -q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (length) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 729.0236 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F4 10 Tf 0 0 0 rg (length) Tj ( ) Tj ($variable) Tj ( ) Tj (value) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 713.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL ($variable) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 698.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The variable which receives the length value) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 682.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (value) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 667.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The value whose length is to be determined. May be one of array, associative array, or string.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 649.0236 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 0 rg (length ) Tj /F1 10 Tf (computes the number of items in the value. How this is done depends upon the type of value:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 633.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (array) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 618.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The length is the number of items in the array.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 602.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (associative array) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 587.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The length is the number of key/value pairs in the associative array.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 571.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (string) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 556.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (The length is the number of ) Tj /F3 10 Tf (characters ) Tj /F1 10 Tf (\(not octets\) in the string.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 529.0236 cm -q -BT 1 0 0 1 0 2.5 Tm 15 TL /F6 12.5 Tf 0 0 0 rg (Examples:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 499.0236 cm -q -BT 1 0 0 1 0 14 Tm 2.338651 Tw 12 TL /F1 10 Tf 0 0 0 rg (Count how many items are in the ) Tj /F4 10 Tf 0 0 0 rg ($groups ) Tj /F1 10 Tf 0 0 0 rg (array and assign that value to the ) Tj /F4 10 Tf 0 0 0 rg ($groups_length) Tj T* 0 Tw /F1 10 Tf 0 0 0 rg (variable.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 465.8236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 24 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F4 10 Tf 12 TL (["length", "$groups_length", "$groups"]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 433.8236 cm -q -BT 1 0 0 1 0 14 Tm .752485 Tw 12 TL /F1 10 Tf 0 0 0 rg (Count how many key/value pairs are in the ) Tj /F4 10 Tf 0 0 0 rg ($assertion ) Tj /F1 10 Tf 0 0 0 rg (associative array and assign that value to the) Tj T* 0 Tw /F4 10 Tf 0 0 0 rg ($num_assertion_values ) Tj /F1 10 Tf 0 0 0 rg (variable.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 400.6236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 24 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F4 10 Tf 12 TL (["length", "$num_assertion_values", "$assertion"]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 368.6236 cm -q -BT 1 0 0 1 0 14 Tm 7.268443 Tw 12 TL /F1 10 Tf 0 0 0 rg (Count how many characters are in the assertion's UserName and assign the value to) Tj T* 0 Tw /F4 10 Tf 0 0 0 rg ($username_length) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 335.4236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 24 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F4 10 Tf 12 TL (["length", "$user_name_length", "$assertion[UserName]"]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 299.0772 cm -n 0 14.17323 m 469.8898 14.17323 l S -Q -q -1 0 0 1 62.69291 269.0772 cm -q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (interpolate) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 251.0772 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F4 10 Tf 0 0 0 rg (interpolate) Tj ( ) Tj ($variable) Tj ( ) Tj (string) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 235.0772 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL ($variable) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 220.0772 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (This variable is assigned the result of the interpolation.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 204.0772 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (string) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 189.0772 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (A string containing references to variables which will be replaced in the string.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 159.0772 cm -q -BT 1 0 0 1 0 14 Tm 1.30881 Tw 12 TL /F2 10 Tf 0 0 0 rg (interpolate ) Tj /F1 10 Tf (replaces each occurrence of a variable in a string with it's value. The result is assigned to) Tj T* 0 Tw ($variable.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 132.0772 cm -q -BT 1 0 0 1 0 2.5 Tm 15 TL /F6 12.5 Tf 0 0 0 rg (Examples:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 102.0772 cm -q -BT 1 0 0 1 0 14 Tm 1.557633 Tw 12 TL /F1 10 Tf 0 0 0 rg (Form an email address given the username and domain. If the username is "jane" and the domain is) Tj T* 0 Tw ("example.com" then $email will be ") Tj 0 0 .501961 rg (jane@example.com) Tj 0 0 0 rg (") Tj T* ET -Q -Q -q -1 0 0 1 56.69291 56.69291 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 232.0549 0 Td (-20-) Tj T* -232.0549 0 Td ET -Q -Q - -endstream -endobj -159 0 obj -<< /Length 5390 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 739.8236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 24 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F4 10 Tf 12 TL (["interpolate", "$email", "${username}@${domain}"]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 703.4772 cm -n 0 14.17323 m 469.8898 14.17323 l S -Q -q -1 0 0 1 62.69291 673.4772 cm -q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (append) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 655.4772 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F4 10 Tf 0 0 0 rg (append) Tj ( ) Tj ($variable) Tj ( ) Tj (value) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 639.4772 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL ($variable) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 624.4772 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (This variable ) Tj /F2 10 Tf (must ) Tj /F1 10 Tf (be an array. It is modified in place by appending ) Tj /F4 10 Tf 0 0 0 rg (value ) Tj /F1 10 Tf 0 0 0 rg (to the end of the array.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 608.4772 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (value) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 593.4772 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The value to append to the end of the array.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 575.4772 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 0 rg (append ) Tj /F1 10 Tf (adds a value to end of an array.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 548.4772 cm -q -BT 1 0 0 1 0 2.5 Tm 15 TL /F6 12.5 Tf 0 0 0 rg (Examples:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 530.4772 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Append the role "qa_test" to the roles list.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 497.2772 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 24 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F4 10 Tf 12 TL (["append", "$roles", "qa_test"]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 460.9307 cm -n 0 14.17323 m 469.8898 14.17323 l S -Q -q -1 0 0 1 62.69291 430.9307 cm -q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (unique) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 412.9307 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F4 10 Tf 0 0 0 rg (unique) Tj ( ) Tj ($variable) Tj ( ) Tj (value) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 396.9307 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL ($variable) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 381.9307 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (This variable is assigned the unique values in the ) Tj /F4 10 Tf 0 0 0 rg (value ) Tj /F1 10 Tf 0 0 0 rg (array.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 365.9307 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (value) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 350.9307 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (An array of values. ) Tj /F2 10 Tf (must ) Tj /F1 10 Tf (be an array.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 320.9307 cm -q -BT 1 0 0 1 0 14 Tm 1.099986 Tw 12 TL /F2 10 Tf 0 0 0 rg (unique ) Tj /F1 10 Tf (builds an array of unique values in ) Tj /F4 10 Tf 0 0 0 rg (value ) Tj /F1 10 Tf 0 0 0 rg (by stripping out duplicates and assigns the array of) Tj T* 0 Tw (unique values to ) Tj /F4 10 Tf 0 0 0 rg ($variable) Tj /F1 10 Tf 0 0 0 rg (. The order of items in the ) Tj /F4 10 Tf 0 0 0 rg (value ) Tj /F1 10 Tf 0 0 0 rg (array are preserved.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 293.9307 cm -q -BT 1 0 0 1 0 2.5 Tm 15 TL /F6 12.5 Tf 0 0 0 rg (Examples:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 275.9307 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL ($one_of_a_kind will be assigned ["a", "b"]) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 242.7307 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 24 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F4 10 Tf 12 TL (["unique", "$one_of_a_kind", ["a", "b", "a"]]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 206.3843 cm -n 0 14.17323 m 469.8898 14.17323 l S -Q -q -1 0 0 1 62.69291 176.3843 cm -q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (regexp) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 158.3843 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F4 10 Tf 0 0 0 rg (regexp) Tj ( ) Tj (string) Tj ( ) Tj (pattern) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 142.3843 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (string) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 127.3843 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The string the regular expression pattern is applied to.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 111.3843 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (pattern) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 96.38425 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The regular expression pattern.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 56.69291 56.69291 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 232.0549 0 Td (-21-) Tj T* -232.0549 0 Td ET -Q -Q - -endstream -endobj -160 0 obj -<< /Length 6206 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 741.0236 cm -q -BT 1 0 0 1 0 14 Tm 1.098443 Tw 12 TL /F2 10 Tf 0 0 0 rg (regexp ) Tj /F1 10 Tf (performs a regular expression match against ) Tj /F4 10 Tf 0 0 0 rg (string) Tj /F1 10 Tf 0 0 0 rg (. The regular expression pattern syntax is) Tj T* 0 Tw (defined by the regular expression implementation of the language this API is written in.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 699.0236 cm -q -BT 1 0 0 1 0 26 Tm 2.001412 Tw 12 TL /F1 10 Tf 0 0 0 rg (Pattern groups are a convenient way to select sub-matches. Pattern groups may accessed by either) Tj T* 0 Tw .952485 Tw (group number or group name. After a successful regular expression match the groups are stored in the) Tj T* 0 Tw (special variables ) Tj /F4 10 Tf 0 0 0 rg ($regexp_array ) Tj /F1 10 Tf 0 0 0 rg (and ) Tj /F4 10 Tf 0 0 0 rg ($regexp_map) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 657.0236 cm -q -BT 1 0 0 1 0 26 Tm .150651 Tw 12 TL /F4 10 Tf 0 0 0 rg ($regexp_array ) Tj /F1 10 Tf 0 0 0 rg (is used to access the groups by numerical index. Groups are numbered by counting the) Tj T* 0 Tw 2.123318 Tw (left parenthesis group delimiter starting at 1. Group 0 is the entire match. ) Tj /F4 10 Tf 0 0 0 rg ($regexp_array ) Tj /F1 10 Tf 0 0 0 rg (is valid) Tj T* 0 Tw (irregardless of whether you used named groups or not.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 627.0236 cm -q -BT 1 0 0 1 0 14 Tm 1.219985 Tw 12 TL /F4 10 Tf 0 0 0 rg ($regexp_map ) Tj /F1 10 Tf 0 0 0 rg (is used to access the groups by name. ) Tj /F4 10 Tf 0 0 0 rg ($regexp_map ) Tj /F1 10 Tf 0 0 0 rg (is only valid if you used named) Tj T* 0 Tw (groups in the pattern.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 600.0236 cm -q -BT 1 0 0 1 0 2.5 Tm 15 TL /F6 12.5 Tf 0 0 0 rg (Examples:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 534.0236 cm -q -BT 1 0 0 1 0 50 Tm .59832 Tw 12 TL /F1 10 Tf 0 0 0 rg (Many user names are of the form ") Tj 0 0 .501961 rg (user@domain) Tj 0 0 0 rg (", to split the username from the domain and to be able) Tj T* 0 Tw 2.444985 Tw (to work with those values independently use a regular expression and then assign the results to a) Tj T* 0 Tw .340574 Tw (variable. In this example there are two regular expression groups, the first group is the username and the) Tj T* 0 Tw 1.974104 Tw (second group is the domain. In the first example we use named groups and then access the match) Tj T* 0 Tw (information in the special variable ) Tj /F4 10 Tf 0 0 0 rg ($regexp_map ) Tj /F1 10 Tf 0 0 0 rg (via the name of the group.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 464.8236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 60 re B* -Q -q -BT 1 0 0 1 0 38 Tm 12 TL /F4 10 Tf 0 0 0 rg (["regexp", "$assertion[UserName]", "\(?P) Tj (<) Tj (username) Tj (>) Tj (\\\\w+\)@\(?P) Tj (<) Tj (domain) Tj (>) Tj (.+\)"],) Tj T* (["continue", "if_not_success"],) Tj T* (["set", "$username", "$regexp_map[username]"],) Tj T* (["set", "$domain", "$regexp_map[domain]"],) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 432.8236 cm -q -BT 1 0 0 1 0 14 Tm .429985 Tw 12 TL /F1 10 Tf 0 0 0 rg (This is exactly equivalent but uses numbered groups instead of named groups. In this instance the group) Tj T* 0 Tw (matches are stored in the special variable ) Tj /F4 10 Tf 0 0 0 rg ($regexp_array ) Tj /F1 10 Tf 0 0 0 rg (and accessed by numerical index.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 363.6236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 60 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 38 Tm /F4 10 Tf 12 TL (["regexp", "$assertion[UserName]", "\(\\\\w+\)@\(.+\)"],) Tj T* (["continue", "if_not_success"],) Tj T* (["set", "$username", "$regexp_array[1]"],) Tj T* (["set", "$domain", "$regexp_array[2]"],) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 327.2772 cm -n 0 14.17323 m 469.8898 14.17323 l S -Q -q -1 0 0 1 62.69291 297.2772 cm -q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (regexp_replace) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 279.2772 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F4 10 Tf 0 0 0 rg (regexp_replace) Tj ( ) Tj ($variable) Tj ( ) Tj (string) Tj ( ) Tj (pattern) Tj ( ) Tj (replacement) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 263.2772 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL ($variable) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 248.2772 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The variable which receives result of the replacement.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 232.2772 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (string) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 217.2772 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The string to perform the replacement on.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 201.2772 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (pattern) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 186.2772 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The regular expression pattern.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 170.2772 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (replacement) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 155.2772 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The replacement specification.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 125.2772 cm -q -BT 1 0 0 1 0 14 Tm .08998 Tw 12 TL /F2 10 Tf 0 0 0 rg (regexp_replace ) Tj /F1 10 Tf (replaces each occurrence of ) Tj /F4 10 Tf 0 0 0 rg (pattern ) Tj /F1 10 Tf 0 0 0 rg (in ) Tj /F4 10 Tf 0 0 0 rg ($string ) Tj /F1 10 Tf 0 0 0 rg (with ) Tj /F4 10 Tf 0 0 0 rg (replacement) Tj /F1 10 Tf 0 0 0 rg (. See ) Tj 0 0 .501961 rg (regexp ) Tj 0 0 0 rg (for) Tj T* 0 Tw (details of using regular expressions.) Tj T* ET -Q -Q -q -1 0 0 1 56.69291 56.69291 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 232.0549 0 Td (-22-) Tj T* -232.0549 0 Td ET -Q -Q - -endstream -endobj -161 0 obj -<< /Length 5909 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 750.0236 cm -q -BT 1 0 0 1 0 2.5 Tm 15 TL /F6 12.5 Tf 0 0 0 rg (Examples:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 732.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Convert hyphens in a name to underscores.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 698.8236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 24 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F4 10 Tf 12 TL (["regexp_replace", "$name", "$name", "-", "_"]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 662.4772 cm -n 0 14.17323 m 469.8898 14.17323 l S -Q -q -1 0 0 1 62.69291 632.4772 cm -q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (split) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 614.4772 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F4 10 Tf 0 0 0 rg (split) Tj ( ) Tj ($variable) Tj ( ) Tj (string) Tj ( ) Tj (pattern) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 598.4772 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL ($variable) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 583.4772 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (This variable is assigned an array containing the split items.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 567.4772 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (string) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 552.4772 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The string to split into separate items.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 536.4772 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (pattern) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 521.4772 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The regular expression pattern used to split the string.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 479.4772 cm -q -BT 1 0 0 1 0 26 Tm 1.24686 Tw 12 TL /F2 10 Tf 0 0 0 rg (split ) Tj /F1 10 Tf (splits ) Tj /F4 10 Tf 0 0 0 rg (string ) Tj /F1 10 Tf 0 0 0 rg (into separate pieces and assigns the result to ) Tj /F4 10 Tf 0 0 0 rg ($variable ) Tj /F1 10 Tf 0 0 0 rg (as an array of pieces.) Tj T* 0 Tw .715984 Tw (The split occurs wherever the regular expression ) Tj /F4 10 Tf 0 0 0 rg (pattern ) Tj /F1 10 Tf 0 0 0 rg (occurs in ) Tj /F4 10 Tf 0 0 0 rg (string) Tj /F1 10 Tf 0 0 0 rg (. See ) Tj 0 0 .501961 rg (regexp ) Tj 0 0 0 rg (for details of) Tj T* 0 Tw (using regular expressions.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 452.4772 cm -q -BT 1 0 0 1 0 2.5 Tm 15 TL /F6 12.5 Tf 0 0 0 rg (Examples:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 422.4772 cm -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .074431 Tw (Split a list of groups separated by a colon \(:\) into an array of individual group names. If $assertion[Groups]) Tj T* 0 Tw (contained the string "user:admin" then $group_list will set to ["user", "admin"].) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 389.2772 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 24 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F4 10 Tf 12 TL (["split", "$group_list", "$assertion[Groups]", ":"]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 352.9307 cm -n 0 14.17323 m 469.8898 14.17323 l S -Q -q -1 0 0 1 62.69291 322.9307 cm -q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (join) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 304.9307 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F4 10 Tf 0 0 0 rg (join) Tj ( ) Tj ($variable) Tj ( ) Tj (array) Tj ( ) Tj (join_string) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 288.9307 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL ($variable) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 273.9307 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (This variable is assigned the string result of the join operation.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 257.9307 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (array) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 242.9307 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (An array of string items to be joined together with ) Tj /F4 10 Tf 0 0 0 rg ($join_string) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 226.9307 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (join_string) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 211.9307 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (The string inserted between each element in ) Tj /F4 10 Tf 0 0 0 rg (array) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 181.9307 cm -q -BT 1 0 0 1 0 14 Tm .074987 Tw 12 TL /F2 10 Tf 0 0 0 rg (join ) Tj /F1 10 Tf (accepts an array of strings and produces a single string where each element in the array is separated) Tj T* 0 Tw (by ) Tj /F4 10 Tf 0 0 0 rg (join_string) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 154.9307 cm -q -BT 1 0 0 1 0 2.5 Tm 15 TL /F6 12.5 Tf 0 0 0 rg (Examples:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 112.9307 cm -q -BT 1 0 0 1 0 26 Tm .817488 Tw 12 TL /F1 10 Tf 0 0 0 rg (Convert a list of group names into a single string where each group name is separated by a colon \(:\). If) Tj T* 0 Tw 1.533059 Tw (the array ) Tj /F4 10 Tf 0 0 0 rg ($group_list ) Tj /F1 10 Tf 0 0 0 rg (is ["user", "admin"] and the ) Tj /F4 10 Tf 0 0 0 rg (join_string ) Tj /F1 10 Tf 0 0 0 rg (is ":" then the ) Tj /F4 10 Tf 0 0 0 rg ($group_string) Tj T* 0 Tw /F1 10 Tf 0 0 0 rg (variable will be set to "user:admin".) Tj T* ET -Q -Q -q -1 0 0 1 56.69291 56.69291 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 232.0549 0 Td (-23-) Tj T* -232.0549 0 Td ET -Q -Q - -endstream -endobj -162 0 obj -<< /Length 6038 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 739.8236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 24 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F4 10 Tf 12 TL (["join", "$group_string", "$groups", ":"]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 703.4772 cm -n 0 14.17323 m 469.8898 14.17323 l S -Q -q -1 0 0 1 62.69291 673.4772 cm -q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (lower) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 655.4772 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F4 10 Tf 0 0 0 rg (lower) Tj ( ) Tj ($variable) Tj ( ) Tj (value) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 639.4772 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL ($variable) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 624.4772 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (This variable is assigned the result of the lower operation.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 608.4772 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (value) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 593.4772 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The value to lower case, may be either a string, array, or associative array.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 575.4772 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 0 rg (lower ) Tj /F1 10 Tf (lower cases the input value. The input value may be one of the following types:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 559.4772 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (string) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 544.4772 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The string is lower cased.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 528.4772 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (array) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 501.4772 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 14 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 1.242619 Tw (Each member of the array must be a string, the result is an array with the items replaced by their) Tj T* 0 Tw (lower case value.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 485.4772 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (associative array) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 458.4772 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 14 Tm T* ET -q -1 0 0 1 20 0 cm -q -BT 1 0 0 1 0 14 Tm 2.587485 Tw 12 TL /F1 10 Tf 0 0 0 rg (Each key in the associative array is lower cased. The values associated with the key are ) Tj /F2 10 Tf (not) Tj T* 0 Tw /F1 10 Tf (modified.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 431.4772 cm -q -BT 1 0 0 1 0 2.5 Tm 15 TL /F6 12.5 Tf 0 0 0 rg (Examples:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 413.4772 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Lookup ) Tj /F4 10 Tf 0 0 0 rg (UserName ) Tj /F1 10 Tf 0 0 0 rg (in the assertion and set the variable ) Tj /F4 10 Tf 0 0 0 rg ($username ) Tj /F1 10 Tf 0 0 0 rg (to it's lower case value.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 380.2772 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 24 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F4 10 Tf 12 TL (["lower", "$username", "$assertion[UserName]"],) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 348.2772 cm -q -BT 1 0 0 1 0 14 Tm .416457 Tw 12 TL /F1 10 Tf 0 0 0 rg (Set each member of the ) Tj /F4 10 Tf 0 0 0 rg ($groups ) Tj /F1 10 Tf 0 0 0 rg (array to it's lower case value. If ) Tj /F4 10 Tf 0 0 0 rg ($groups ) Tj /F1 10 Tf 0 0 0 rg (was ["User", "Admin"] then) Tj T* 0 Tw /F4 10 Tf 0 0 0 rg ($groups ) Tj /F1 10 Tf 0 0 0 rg (will become ["user", "admin"].) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 315.0772 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 24 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F4 10 Tf 12 TL (["lower", "$groups", "$groups"],) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 283.0772 cm -q -BT 1 0 0 1 0 14 Tm .065868 Tw 12 TL /F1 10 Tf 0 0 0 rg (To enable case insensitive lookup's in an associative array lower case each key in the associative array. If) Tj T* 0 Tw /F4 10 Tf 0 0 0 rg ($assertion ) Tj /F1 10 Tf 0 0 0 rg (was {"UserName": "JoeUser"} then ) Tj /F4 10 Tf 0 0 0 rg ($assertion ) Tj /F1 10 Tf 0 0 0 rg (will become {"username": "JoeUser"}) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 249.8772 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 24 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F4 10 Tf 12 TL (["lower", "$assertion", $assertion"]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 213.5307 cm -n 0 14.17323 m 469.8898 14.17323 l S -Q -q -1 0 0 1 62.69291 183.5307 cm -q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (upper) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 165.5307 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F4 10 Tf 0 0 0 rg (upper) Tj ( ) Tj ($variable) Tj ( ) Tj (value) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 149.5307 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL ($variable) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 134.5307 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (This variable is assigned the result of the upper operation.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 118.5307 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (value) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 103.5307 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The value to upper case, may be either a string, array, or associative array.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 56.69291 56.69291 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 232.0549 0 Td (-24-) Tj T* -232.0549 0 Td ET -Q -Q - -endstream -endobj -163 0 obj -<< /Length 6022 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 753.0236 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 0 rg (upper ) Tj /F1 10 Tf (is exactly analogous to ) Tj 0 0 .501961 rg (lower ) Tj 0 0 0 rg (except the values are upper cased, see ) Tj 0 0 .501961 rg (lower ) Tj 0 0 0 rg (for details.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 724.6772 cm -n 0 14.17323 m 469.8898 14.17323 l S -Q -q -1 0 0 1 62.69291 694.6772 cm -q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (in) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 676.6772 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F4 10 Tf 0 0 0 rg (in) Tj ( ) Tj (member) Tj ( ) Tj (collection) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 660.6772 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (member) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 645.6772 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The value whose membership is being tested.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 629.6772 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (collection) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 614.6772 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (A collection of members. May be string, array or associative array.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 584.6772 cm -q -BT 1 0 0 1 0 14 Tm 1.200542 Tw 12 TL /F2 10 Tf 0 0 0 rg (in ) Tj /F1 10 Tf (tests to see if ) Tj /F4 10 Tf 0 0 0 rg (member ) Tj /F1 10 Tf 0 0 0 rg (is a member of ) Tj /F4 10 Tf 0 0 0 rg (collection) Tj /F1 10 Tf 0 0 0 rg (. The membership test depends on the type of) Tj T* 0 Tw (collection, the following are supported:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 568.6772 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (array) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 553.6772 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (If any item in the array is equal to ) Tj /F4 10 Tf 0 0 0 rg (member ) Tj /F1 10 Tf 0 0 0 rg (then the result is success.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 537.6772 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (associative array) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 522.6772 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (If the associative array contains a key equal to ) Tj /F4 10 Tf 0 0 0 rg (member ) Tj /F1 10 Tf 0 0 0 rg (then the result is success.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 506.6772 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (string) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 491.6772 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (If the string contains a sub-string equal to ) Tj /F4 10 Tf 0 0 0 rg (member ) Tj /F1 10 Tf 0 0 0 rg (then the result is success.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 464.6772 cm -q -BT 1 0 0 1 0 2.5 Tm 15 TL /F6 12.5 Tf 0 0 0 rg (Examples:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 446.6772 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Test to see if the assertion contains a UserName value.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 401.4772 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 36 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F4 10 Tf 12 TL (["in", "UserName", "$assertion"]) Tj T* (["continue", "if_not_success"]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 381.4772 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Test to see if a group is one of "user" or "admin".) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 336.2772 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 36 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F4 10 Tf 12 TL (["in", "$group", ["user", "admin"]]) Tj T* (["continue", "if_not_success"]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 316.2772 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Test to see if the sub-string "BigCorp" is in the assertion's ) Tj /F4 10 Tf 0 0 0 rg (Provider ) Tj /F1 10 Tf 0 0 0 rg (value.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 271.0772 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 36 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F4 10 Tf 12 TL (["in", "BigCorp", "$assertion[Provider]"]) Tj T* (["continue", "if_not_success"]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 234.7307 cm -n 0 14.17323 m 469.8898 14.17323 l S -Q -q -1 0 0 1 62.69291 204.7307 cm -q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (not_in) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 186.7307 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F4 10 Tf 0 0 0 rg (in) Tj ( ) Tj (member) Tj ( ) Tj (collection) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 170.7307 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (member) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 155.7307 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The value whose membership is being tested.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 139.7307 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (collection) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 124.7307 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (A collection of members. May be string, array or associative array.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 106.7307 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 0 rg (not_in ) Tj /F1 10 Tf (is exactly analogous to ) Tj 0 0 .501961 rg (in ) Tj 0 0 0 rg (except the sense of the test is reversed. See ) Tj 0 0 .501961 rg (in ) Tj 0 0 0 rg (for details.) Tj T* ET -Q -Q -q -1 0 0 1 56.69291 56.69291 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 232.0549 0 Td (-25-) Tj T* -232.0549 0 Td ET -Q -Q - -endstream -endobj -164 0 obj -<< /Length 11031 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 736.6772 cm -n 0 14.17323 m 469.8898 14.17323 l S -Q -q -1 0 0 1 62.69291 706.6772 cm -q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (compare) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 688.6772 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F4 10 Tf 0 0 0 rg (compare) Tj ( ) Tj (left) Tj ( ) Tj (operator) Tj ( ) Tj (right) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 672.6772 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (left) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 657.6772 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The left hand value of the binary operator.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 641.6772 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (operator) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 626.6772 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The binary operator used for comparing left to right.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 610.6772 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (right) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 595.6772 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The right hand value of the binary operator.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 565.6772 cm -q -BT 1 0 0 1 0 14 Tm 2.41061 Tw 12 TL /F2 10 Tf 0 0 0 rg (compare ) Tj /F1 10 Tf (compares the left value to the right value according the operator and sets success if the) Tj T* 0 Tw (comparison evaluates to True. The following relational operators are supported.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 559.6772 cm -Q -q -1 0 0 1 62.69291 433.6772 cm -1 1 1 rg -n 0 126 469.8898 -18 re f* -.878431 .878431 .878431 rg -n 0 108 469.8898 -18 re f* -1 1 1 rg -n 0 90 469.8898 -18 re f* -.878431 .878431 .878431 rg -n 0 72 469.8898 -18 re f* -1 1 1 rg -n 0 54 469.8898 -18 re f* -.878431 .878431 .878431 rg -n 0 36 469.8898 -18 re f* -1 1 1 rg -n 0 18 469.8898 -18 re f* -.960784 .960784 .862745 rg -n 0 126 469.8898 -18 re f* -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 111 cm -q -.960784 .960784 .862745 rg -n 0 0 130.3908 12 re f* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 45.46542 0 Td (Operator) Tj T* -45.46542 0 Td ET -Q -Q -q -1 0 0 1 148.3908 111 cm -q -.960784 .960784 .862745 rg -n 0 0 315.4989 12 re f* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 132.7445 0 Td (Description) Tj T* -132.7445 0 Td ET -Q -Q -0 0 0 rg -q -1 0 0 1 6 93 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (==) Tj T* ET -Q -Q -q -1 0 0 1 148.3908 93 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (equal) Tj T* ET -Q -Q -q -1 0 0 1 6 75 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (!=) Tj T* ET -Q -Q -q -1 0 0 1 148.3908 75 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (not equal) Tj T* ET -Q -Q -q -1 0 0 1 6 57 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (<) Tj T* ET -Q -Q -q -1 0 0 1 148.3908 57 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (less than) Tj T* ET -Q -Q -q -1 0 0 1 6 39 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (<) Tj (=) Tj T* ET -Q -Q -q -1 0 0 1 148.3908 39 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (less than or equal) Tj T* ET -Q -Q -q -1 0 0 1 6 21 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (>) Tj T* ET -Q -Q -q -1 0 0 1 148.3908 21 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (greater than) Tj T* ET -Q -Q -q -1 0 0 1 6 3 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (>) Tj (=) Tj T* ET -Q -Q -q -1 0 0 1 148.3908 3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (greater than or equal) Tj T* ET -Q -Q -q -1 J -1 j -0 0 0 RG -.25 w -n 0 108 m 469.8898 108 l S -n 0 90 m 469.8898 90 l S -n 0 72 m 469.8898 72 l S -n 0 54 m 469.8898 54 l S -n 0 36 m 469.8898 36 l S -n 0 18 m 469.8898 18 l S -n 142.3908 0 m 142.3908 126 l S -n 0 126 m 469.8898 126 l S -n 0 0 m 469.8898 0 l S -n 0 0 m 0 126 l S -n 469.8898 0 m 469.8898 126 l S -Q -Q -q -1 0 0 1 62.69291 433.6772 cm -Q -q -1 0 0 1 62.69291 379.6772 cm -q -BT 1 0 0 1 0 38 Tm .320542 Tw 12 TL /F1 10 Tf 0 0 0 rg (The left and right hand sides of the comparison operator ) Tj /F3 10 Tf (must ) Tj /F1 10 Tf (be the same type, no type conversions are) Tj T* 0 Tw 2.43784 Tw (performed. Not all combinations of operator and type are supported. The table below illustrates the) Tj T* 0 Tw 1.126651 Tw (supported combinations. Essentially you can test for equality or inequality on any type. But only strings) Tj T* 0 Tw (and numbers support the magnitude relational operators.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 373.6772 cm -Q -q -1 0 0 1 62.69291 247.6772 cm -1 1 1 rg -n 0 126 469.8898 -18 re f* -.878431 .878431 .878431 rg -n 0 108 469.8898 -18 re f* -1 1 1 rg -n 0 90 469.8898 -18 re f* -.878431 .878431 .878431 rg -n 0 72 469.8898 -18 re f* -1 1 1 rg -n 0 54 469.8898 -18 re f* -.878431 .878431 .878431 rg -n 0 36 469.8898 -18 re f* -1 1 1 rg -n 0 18 469.8898 -18 re f* -.960784 .960784 .862745 rg -n 0 126 469.8898 -18 re f* -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 111 cm -q -.960784 .960784 .862745 rg -n 0 0 67.64233 12 re f* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 14.09117 0 Td (Operator) Tj T* -14.09117 0 Td ET -Q -Q -q -1 0 0 1 85.64233 111 cm -q -.960784 .960784 .862745 rg -n 0 0 51.71387 12 re f* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 6.966933 0 Td (STRING) Tj T* -6.966933 0 Td ET -Q -Q -q -1 0 0 1 149.3562 111 cm -q -.960784 .960784 .862745 rg -n 0 0 59.6781 12 re f* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 7.61405 0 Td (INTEGER) Tj T* -7.61405 0 Td ET -Q -Q -q -1 0 0 1 221.0343 111 cm -q -.960784 .960784 .862745 rg -n 0 0 35.7854 12 re f* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 4.8327 0 Td (REAL) Tj T* -4.8327 0 Td ET -Q -Q -q -1 0 0 1 268.8197 111 cm -q -.960784 .960784 .862745 rg -n 0 0 59.6781 12 re f* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66405 0 Td (BOOLEAN) Tj T* -5.66405 0 Td ET -Q -Q -q -1 0 0 1 340.4978 111 cm -q -.960784 .960784 .862745 rg -n 0 0 27.82117 12 re f* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 3.075583 0 Td (MAP) Tj T* -3.075583 0 Td ET -Q -Q -q -1 0 0 1 380.319 111 cm -q -.960784 .960784 .862745 rg -n 0 0 35.7854 12 re f* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 7.3327 0 Td (LIST) Tj T* -7.3327 0 Td ET -Q -Q -q -1 0 0 1 428.1044 111 cm -q -.960784 .960784 .862745 rg -n 0 0 35.7854 12 re f* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.1127 0 Td (NULL) Tj T* -5.1127 0 Td ET -Q -Q -0 0 0 rg -q -1 0 0 1 6 93 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (==) Tj T* ET -Q -Q -q -1 0 0 1 85.64233 93 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (X) Tj T* ET -Q -Q -q -1 0 0 1 149.3562 93 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (X) Tj T* ET -Q -Q -q -1 0 0 1 221.0343 93 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (X) Tj T* ET -Q -Q -q -1 0 0 1 268.8197 93 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (X) Tj T* ET -Q -Q -q -1 0 0 1 340.4978 93 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (X) Tj T* ET -Q -Q -q -1 0 0 1 380.319 93 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (X) Tj T* ET -Q -Q -q -1 0 0 1 428.1044 93 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (X) Tj T* ET -Q -Q -q -1 0 0 1 6 75 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (!=) Tj T* ET -Q -Q -q -1 0 0 1 85.64233 75 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (X) Tj T* ET -Q -Q -q -1 0 0 1 149.3562 75 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (X) Tj T* ET -Q -Q -q -1 0 0 1 221.0343 75 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (X) Tj T* ET -Q -Q -q -1 0 0 1 268.8197 75 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (X) Tj T* ET -Q -Q -q -1 0 0 1 340.4978 75 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (X) Tj T* ET -Q -Q -q -1 0 0 1 380.319 75 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (X) Tj T* ET -Q -Q -q -1 0 0 1 428.1044 75 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (X) Tj T* ET -Q -Q -q -1 0 0 1 6 57 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (<) Tj T* ET -Q -Q -q -1 0 0 1 85.64233 57 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (X) Tj T* ET -Q -Q -q -1 0 0 1 149.3562 57 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (X) Tj T* ET -Q -Q -q -1 0 0 1 221.0343 57 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (X) Tj T* ET -Q -Q -q -1 0 0 1 6 39 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (<) Tj (=) Tj T* ET -Q -Q -q -1 0 0 1 85.64233 39 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (X) Tj T* ET -Q -Q -q -1 0 0 1 149.3562 39 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (X) Tj T* ET -Q -Q -q -1 0 0 1 221.0343 39 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (X) Tj T* ET -Q -Q -q -1 0 0 1 6 21 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (>) Tj T* ET -Q -Q -q -1 0 0 1 85.64233 21 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (X) Tj T* ET -Q -Q -q -1 0 0 1 149.3562 21 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (X) Tj T* ET -Q -Q -q -1 0 0 1 221.0343 21 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (X) Tj T* ET -Q -Q -q -1 0 0 1 6 3 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (>) Tj (=) Tj T* ET -Q -Q -q -1 0 0 1 85.64233 3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (X) Tj T* ET -Q -Q -q -1 0 0 1 149.3562 3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (X) Tj T* ET -Q -Q -q -1 0 0 1 221.0343 3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (X) Tj T* ET -Q -Q -q -1 J -1 j -0 0 0 RG -.25 w -n 0 108 m 469.8898 108 l S -n 0 90 m 469.8898 90 l S -n 0 72 m 469.8898 72 l S -n 0 54 m 469.8898 54 l S -n 0 36 m 469.8898 36 l S -n 0 18 m 469.8898 18 l S -n 79.64233 0 m 79.64233 126 l S -n 143.3562 0 m 143.3562 126 l S -n 215.0343 0 m 215.0343 126 l S -n 262.8197 0 m 262.8197 126 l S -n 334.4978 0 m 334.4978 126 l S -n 374.319 0 m 374.319 126 l S -n 422.1044 0 m 422.1044 126 l S -n 0 126 m 469.8898 126 l S -n 0 0 m 469.8898 0 l S -n 0 0 m 0 126 l S -n 469.8898 0 m 469.8898 126 l S -Q -Q -q -1 0 0 1 62.69291 247.6772 cm -Q -q -1 0 0 1 62.69291 220.6772 cm -q -BT 1 0 0 1 0 2.5 Tm 15 TL /F6 12.5 Tf 0 0 0 rg (Examples:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 202.6772 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Test to see if the ) Tj /F4 10 Tf 0 0 0 rg ($groups ) Tj /F1 10 Tf 0 0 0 rg (array has at least 2 members) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 157.4772 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 36 re B* -Q -q -BT 1 0 0 1 0 14 Tm 12 TL /F4 10 Tf 0 0 0 rg (["length", "$group_length", "$groups"],) Tj T* (["compare", "$group_length", ") Tj (>) Tj (=", 2]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 121.1307 cm -n 0 14.17323 m 469.8898 14.17323 l S -Q -q -1 0 0 1 56.69291 56.69291 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 232.0549 0 Td (-26-) Tj T* -232.0549 0 Td ET -Q -Q - -endstream -endobj -165 0 obj -<< /Length 6843 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 747.0236 cm -q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (exit) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 729.0236 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F4 10 Tf 0 0 0 rg (exit) Tj ( ) Tj (status) Tj ( ) Tj (criteria) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 713.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (status) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 698.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The result for the rule.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 682.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (criteria) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 667.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The criteria upon which will cause the rule will be immediately exited with a failed status.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 625.0236 cm -q -BT 1 0 0 1 0 26 Tm 1.094431 Tw 12 TL /F2 10 Tf 0 0 0 rg (exit ) Tj /F1 10 Tf (causes the rule being executed to immediately exit and a rule result if the specified criteria is met.) Tj T* 0 Tw .433876 Tw (Statement verbs such as ) Tj 0 0 .501961 rg (in ) Tj 0 0 0 rg (or ) Tj 0 0 .501961 rg (compare ) Tj 0 0 0 rg (set the result status which may be tested with the ) Tj /F4 10 Tf 0 0 0 rg (success ) Tj /F1 10 Tf 0 0 0 rg (and) Tj T* 0 Tw /F4 10 Tf 0 0 0 rg (not_success ) Tj /F1 10 Tf 0 0 0 rg (criteria.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 607.0236 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (The exit ) Tj /F4 10 Tf 0 0 0 rg (status ) Tj /F1 10 Tf 0 0 0 rg (may be one of:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 591.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (rule_fails) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 576.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The rule has failed and no mapping will occur.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 560.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (rule_succeeds) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 545.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The rule succeeded and the mapping will be applied.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 527.0236 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F4 10 Tf 0 0 0 rg (criteria ) Tj /F1 10 Tf 0 0 0 rg (may be one of:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 511.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (if_success) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 496.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (If current result status is success then exit with ) Tj /F4 10 Tf 0 0 0 rg (status) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 480.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (if_not_success) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 465.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (If current result status is not success then exit with ) Tj /F4 10 Tf 0 0 0 rg (status) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 449.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (always) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 434.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Unconditionally exit with ) Tj /F4 10 Tf 0 0 0 rg (status) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 418.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (never) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 403.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Effectively a no-op. Useful for debugging.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 376.0236 cm -q -BT 1 0 0 1 0 2.5 Tm 15 TL /F6 12.5 Tf 0 0 0 rg (Examples:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 358.0236 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (The rule requires ) Tj /F4 10 Tf 0 0 0 rg (UserName ) Tj /F1 10 Tf 0 0 0 rg (to be in the assertion.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 312.8236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 36 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F4 10 Tf 12 TL (["in", "UserName", "$assertion"]) Tj T* (["exit", "rule_fails", "if_not_success"]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 276.4772 cm -n 0 14.17323 m 469.8898 14.17323 l S -Q -q -1 0 0 1 62.69291 246.4772 cm -q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (continue) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 228.4772 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F4 10 Tf 0 0 0 rg (continue) Tj ( ) Tj (criteria) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 212.4772 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (criteria) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 197.4772 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (The criteria which causes the remainder of the ) Tj /F3 10 Tf (block ) Tj /F1 10 Tf (to be skipped.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 155.4772 cm -q -BT 1 0 0 1 0 26 Tm .277356 Tw 12 TL /F2 10 Tf 0 0 0 rg (continue ) Tj /F1 10 Tf (is used to control execution for statement blocks. It mirrors in a crude way the ) Tj /F3 10 Tf 0 0 0 rg (if ) Tj /F1 10 Tf 0 0 0 rg (expression in a) Tj T* 0 Tw .112485 Tw (procedural language. ) Tj /F4 10 Tf 0 0 0 rg (continue ) Tj /F1 10 Tf 0 0 0 rg (does ) Tj /F3 10 Tf (not ) Tj /F1 10 Tf (affect the success or failure of a rule, rather it controls whether) Tj T* 0 Tw (subsequent statements in a block are executed or not. Control continues at the next statement block.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 125.4772 cm -q -BT 1 0 0 1 0 14 Tm .433876 Tw 12 TL /F1 10 Tf 0 0 0 rg (Statement verbs such as ) Tj 0 0 .501961 rg (in ) Tj 0 0 0 rg (or ) Tj 0 0 .501961 rg (compare ) Tj 0 0 0 rg (set the result status which may be tested with the ) Tj /F4 10 Tf 0 0 0 rg (success ) Tj /F1 10 Tf 0 0 0 rg (and) Tj T* 0 Tw /F4 10 Tf 0 0 0 rg (not_success ) Tj /F1 10 Tf 0 0 0 rg (criteria.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 107.4772 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The criteria may be one of:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 91.47717 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (if_success) Tj T* ET -Q -Q -q -1 0 0 1 56.69291 56.69291 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 232.0549 0 Td (-27-) Tj T* -232.0549 0 Td ET -Q -Q - -endstream -endobj -166 0 obj -<< /Length 3107 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 738.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 14 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 1.22936 Tw (If current result status is success then exit the statement block and continue execution at the next) Tj T* 0 Tw (statement block.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 722.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (if_not_success) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 695.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 14 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .175868 Tw (If current result status is not success then exit the statement block and continue execution at the next) Tj T* 0 Tw (statement block.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 679.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (always) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 664.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Immediately exit the statement block and continue execution at the next statement block.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 648.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (never) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 633.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Effectively a no-op. Useful for debugging. Execution continues at the next statement.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 606.0236 cm -q -BT 1 0 0 1 0 2.5 Tm 15 TL /F6 12.5 Tf 0 0 0 rg (Examples:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 588.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The following pseudo code:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 482.8236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 96 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 74 Tm /F4 10 Tf 12 TL (roles = [];) Tj T* (if \("Groups" in assertion\) {) Tj T* ( groups = assertion["Groups"].split\(":"\);) Tj T* ( if \("qa_test" in groups\) {) Tj T* ( roles.append\("tester"\);) Tj T* ( }) Tj T* (}) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 462.8236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (could be implemented this way:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 333.6236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 120 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 98 Tm /F4 10 Tf 12 TL ([) Tj T* ( ["set", "$roles", []],) Tj T* ( ["in", "Groups", "$assertion"],) Tj T* ( ["continue", "if_not_success"],) Tj T* ( ["split" "$groups", $assertion[Groups]", ":"],) Tj T* ( ["in", "qa_test", "$groups"],) Tj T* ( ["continue", "if_not_success"],) Tj T* ( ["append", "$roles", "tester"]) Tj T* (]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 56.69291 56.69291 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 232.0549 0 Td (-28-) Tj T* -232.0549 0 Td ET -Q -Q - -endstream -endobj -167 0 obj -<< /Nums [ 0 168 0 R 1 169 0 R 2 170 0 R 3 171 0 R 4 172 0 R - 5 173 0 R 6 174 0 R 7 175 0 R 8 176 0 R 9 177 0 R - 10 178 0 R 11 179 0 R 12 180 0 R 13 181 0 R 14 182 0 R - 15 183 0 R 16 184 0 R 17 185 0 R 18 186 0 R 19 187 0 R - 20 188 0 R 21 189 0 R 22 190 0 R 23 191 0 R 24 192 0 R - 25 193 0 R 26 194 0 R 27 195 0 R ] >> -endobj -168 0 obj -<< /S /D /St 1 >> -endobj -169 0 obj -<< /S /D /St 2 >> -endobj -170 0 obj -<< /S /D /St 3 >> -endobj -171 0 obj -<< /S /D /St 4 >> -endobj -172 0 obj -<< /S /D /St 5 >> -endobj -173 0 obj -<< /S /D /St 6 >> -endobj -174 0 obj -<< /S /D /St 7 >> -endobj -175 0 obj -<< /S /D /St 8 >> -endobj -176 0 obj -<< /S /D /St 9 >> -endobj -177 0 obj -<< /S /D /St 10 >> -endobj -178 0 obj -<< /S /D /St 11 >> -endobj -179 0 obj -<< /S /D /St 12 >> -endobj -180 0 obj -<< /S /D /St 13 >> -endobj -181 0 obj -<< /S /D /St 14 >> -endobj -182 0 obj -<< /S /D /St 15 >> -endobj -183 0 obj -<< /S /D /St 16 >> -endobj -184 0 obj -<< /S /D /St 17 >> -endobj -185 0 obj -<< /S /D /St 18 >> -endobj -186 0 obj -<< /S /D /St 19 >> -endobj -187 0 obj -<< /S /D /St 20 >> -endobj -188 0 obj -<< /S /D /St 21 >> -endobj -189 0 obj -<< /S /D /St 22 >> -endobj -190 0 obj -<< /S /D /St 23 >> -endobj -191 0 obj -<< /S /D /St 24 >> -endobj -192 0 obj -<< /S /D /St 25 >> -endobj -193 0 obj -<< /S /D /St 26 >> -endobj -194 0 obj -<< /S /D /St 27 >> -endobj -195 0 obj -<< /S /D /St 28 >> -endobj -xref -0 196 -0000000000 65535 f -0000000075 00000 n -0000000163 00000 n -0000000273 00000 n -0000000388 00000 n -0000000599 00000 n -0000000770 00000 n -0000000940 00000 n -0000001111 00000 n -0000026970 00000 n -0000037046 00000 n -0000037165 00000 n -0000037470 00000 n -0000037579 00000 n -0000037751 00000 n -0000037923 00000 n -0000038037 00000 n -0000038275 00000 n -0000038487 00000 n -0000038659 00000 n -0000038831 00000 n -0000039069 00000 n -0000039241 00000 n -0000039413 00000 n -0000039585 00000 n -0000039757 00000 n -0000039929 00000 n -0000040188 00000 n -0000040400 00000 n -0000040571 00000 n -0000040802 00000 n -0000041014 00000 n -0000041186 00000 n -0000041417 00000 n -0000041540 00000 n -0000041752 00000 n -0000041924 00000 n -0000042155 00000 n -0000042367 00000 n -0000042579 00000 n -0000042791 00000 n -0000042963 00000 n -0000043194 00000 n -0000043406 00000 n -0000043578 00000 n -0000043750 00000 n -0000043922 00000 n -0000044094 00000 n -0000044266 00000 n -0000044438 00000 n -0000044610 00000 n -0000044782 00000 n -0000044954 00000 n -0000045126 00000 n -0000045298 00000 n -0000045470 00000 n -0000045782 00000 n -0000045954 00000 n -0000046126 00000 n -0000046298 00000 n -0000046470 00000 n -0000046722 00000 n -0000046901 00000 n -0000047132 00000 n -0000047344 00000 n -0000047518 00000 n -0000047690 00000 n -0000047928 00000 n -0000048100 00000 n -0000048331 00000 n -0000048543 00000 n -0000048715 00000 n -0000048887 00000 n -0000049059 00000 n -0000049231 00000 n -0000049483 00000 n -0000049695 00000 n -0000049867 00000 n -0000050037 00000 n -0000050209 00000 n -0000050379 00000 n -0000050631 00000 n -0000050843 00000 n -0000050954 00000 n -0000051165 00000 n -0000051244 00000 n -0000051400 00000 n -0000051526 00000 n -0000051661 00000 n -0000051798 00000 n -0000051971 00000 n -0000052105 00000 n -0000052292 00000 n -0000052404 00000 n -0000052528 00000 n -0000052656 00000 n -0000052806 00000 n -0000052973 00000 n -0000053073 00000 n -0000053196 00000 n -0000053365 00000 n -0000053535 00000 n -0000053702 00000 n -0000053877 00000 n -0000054022 00000 n -0000054184 00000 n -0000054338 00000 n -0000054463 00000 n -0000054629 00000 n -0000054782 00000 n -0000054885 00000 n -0000055055 00000 n -0000055158 00000 n -0000055333 00000 n -0000055436 00000 n -0000055606 00000 n -0000055709 00000 n -0000055879 00000 n -0000055982 00000 n -0000056152 00000 n -0000056255 00000 n -0000056433 00000 n -0000056536 00000 n -0000056705 00000 n -0000056808 00000 n -0000056976 00000 n -0000057079 00000 n -0000057248 00000 n -0000057351 00000 n -0000057478 00000 n -0000057644 00000 n -0000057747 00000 n -0000057875 00000 n -0000058046 00000 n -0000058149 00000 n -0000058317 00000 n -0000058420 00000 n -0000058578 00000 n -0000058681 00000 n -0000058943 00000 n -0000068119 00000 n -0000073466 00000 n -0000081106 00000 n -0000086451 00000 n -0000094793 00000 n -0000098950 00000 n -0000102705 00000 n -0000107846 00000 n -0000116871 00000 n -0000122165 00000 n -0000128291 00000 n -0000134404 00000 n -0000138084 00000 n -0000146317 00000 n -0000152034 00000 n -0000157549 00000 n -0000162041 00000 n -0000169838 00000 n -0000176402 00000 n -0000182585 00000 n -0000188033 00000 n -0000194297 00000 n -0000200264 00000 n -0000206360 00000 n -0000212440 00000 n -0000223530 00000 n -0000230431 00000 n -0000233596 00000 n -0000233950 00000 n -0000233988 00000 n -0000234026 00000 n -0000234064 00000 n -0000234102 00000 n -0000234140 00000 n -0000234178 00000 n -0000234216 00000 n -0000234254 00000 n -0000234292 00000 n -0000234331 00000 n -0000234370 00000 n -0000234409 00000 n -0000234448 00000 n -0000234487 00000 n -0000234526 00000 n -0000234565 00000 n -0000234604 00000 n -0000234643 00000 n -0000234682 00000 n -0000234721 00000 n -0000234760 00000 n -0000234799 00000 n -0000234838 00000 n -0000234877 00000 n -0000234916 00000 n -0000234955 00000 n -0000234994 00000 n -trailer -<< /ID - % ReportLab generated PDF document -- digest (http://www.reportlab.com) - [(\232\310\351\341{\201\026\211\227\020\263\243\343>\213\037) (\232\310\351\341{\201\026\211\227\020\263\243\343>\213\037)] - /Info 83 0 R /Root 82 0 R /Size 196 >> -startxref -235033 -%%EOF -- cgit