JFIF  H H (ICC_PROFILE   0 mntrRGB XYZ acsp   - desc trXYZ d gXYZ x bXYZ  rTRC  (gTRC  (bTRC  (wtpt  cprt  بV7eudakt!Q ,*RGPQNČzŬb 5666p z"c83''Mq6Gitql@90.ۚAcN|li:9蠃p/^ZnLx84v;[#$ nh'c32o8Ɛ5KAv*_?nX?pyֆ̈́#z23F0Oe> {Gu.V (C'h/o%>x1X r:(>}{ycX8b]U:dOMsVAp'Z3'3E-ybj:>jOvUw#2cl~@gFCjțbz ^:-tdfj{XTh8aUM^+dAl"(KK m1$$ XKKqržoqg V FF#pG~:]֦!!Ң:pC+ AzӬ].t`='h_/} @L\,x㌼z԰+J-v+Y['8' % X q=[4Sj~4ݢ#dʂēRL5kX؊>l:t\baBA\Q38( ө:&$ 'L#d{qH>*5;jDo ˷YmԈ*[9*5tUf%3= GUW\'AR_W4_P պ -|4RFJZv0d[ˠzJ|PU8;鯌 'VcL,κ>*eb)f,0"j1 1v՘;bJ++COz7%>NU,=z\cEVK>Ic7} .jHn;^觱GHI HVǂO:ߊ{mSV?K|@ AiAT`2j 1~K8’$ ~]=9ឦG *9EMּm5Xf9Qĸ}i D%+t+;F: v:-&h_rD|! Ә;Zl븂':C&ҀaeKkm6 uT".}J&\ hciB2B+T7t?EPþЌmAF\lc2ЊABmE,cն\QJ]d5 `O Y@8?lx#KiI&Ri1fR2f1N%_g*TӨ??N:}+לɀh٭qL,ʈBrcuBmz ̢TV^ 뙏8' ufUX3㓏>NG:/;Hp饕B1K /%iɫ VQ%:_ -1oL?Roa\i^F|W*Na)P X#y㯨z+Cح\вjirm*dWҡQbBȨi'%NEb?'[h=`OiU϶u nR}GW4fVJmiR~J|l%m'%"LW V27NsXb?_={s}ij4Ý=SNjxFV"ԎI(E)]ӝЖm[4 m`5-7Wf󪥎bZKa#Vb%KY5T$y`46̼p C7HM'l{Oi +Pw~j,S5T4(FԨ;A`*HJTPgt(6/cg5U1@Qb8Y!rBzOQKF+6v%=~XDPpWc_-:߈#c坣CW1:^Q 06Ӭq@ Dj$ UW$?9F\cSM5=2>hב\,()JBk; J#j徻W(p=oQD #UMhU*Fc ?N=nF5Ӑ12w05Z뀩4ڣ霅uC1y%nJ8Ԑ*crR 9W=H9,A׻,.ZFb QEGVNs, q';OMmbtNVqOw*֙kPѬ؈XJIӯEWok+R{%j; Yx 7&&,LԜYbw"lI(*`۹F AS- #$413)Qpڤ3RxOJ$cP]viuq {kyN.- B,@󪳪ڸAor%X0UNb9 򍕑7)*233|Rnb@q|EUý$!7&["XOy ~ƓtADhP]mG파9p=ԜZ]ӭሎOeyq !bI GU:5~FoL ST[е$]$g*w]!;m@ޠ&IUڬ{҄բ-.SmҒ` vU"oL;'5s"W)@äL1i}^Y5$+Pv0o HU @ȓsQM)?M\4Q $2;g WJ/NwFJGD: y όMfW!QUZ%azҳDK_XhM^rԝ^!d'<#ﴛO{/F?+$ Y' wg'$ljGAH7l4xѶc}I*esg~;ͤt@B2iB'9C a8fTR: %NO@ m3sv w .@濾 ,FYrT0mUW_v>>d[A6ڊx:YTLHvӺ!nSD}>[mET0_,'C]pjVᅷPDZ[-V0`>}ܟpmֻ2O6O*ݹXHSN(J /+1՟#(P*gEO#w&j6?;ڡ)+U]l\/{莄*I/9<'$'#'yt/&-\\WPL`/p9qa'e¨E] fAAEYnGtm,ϮwXT>AaN#FjŵjQFdq^<H?yJ܃2*3 T4ЧH**W;(ꭽ¾Pf=eyA4FJ6{e]JqOCf#3SJf iMM\ iT$rG8$9>2:M)Q#NKe&"E8.z<mHk?#t˒A]; G0H:f!i! j{1m}o7u;$99Ӱ\ncz:zALq޶wyKT<4X,'!Y;Ͱ6q GM~_~܂}t>(zl}:r L9 fe}.-R*<`c6oܛ=prҽGB)nQ%)s*&i΍%—Zb{m[NNkbwBw Q*dF HP iܛ; aV68j}\eIGI'͔B;yA :^bn-m#@S6ˎr ;~cmƻgU:X6G%[gc{]c4)fpsgY˅>*"1}2<175)]V5)kdkM~`΂:{4nGPTTb   뎱϶w FFᓂG8>zF_H9_rDl:ҶH5Z!Bj.yk}erb:SOT]!ǎ?n:HεZsyztn[7NZ#UQO$.J#]Cr#YX9c<'$z 9 .$$PnDSn 2u5X g\ ?|Aᬰⶵ >>bE)Cb-ruMc׺*,\)`^m ge\k.۫8گoK1gWMpU޻zI=EErz:#6--/Wm\z8מ0x tA_c?Ծc^MژIMyO>l0ċ}t7[\ʲ9̜m_a[姯rְjP\kx1'CdmvF70e+m-]a?ݝKuSMUm 8f Yb!)2Z.UD \~:ܽ8zR̪Kcbs&ߦ1$, w\gc3F$iU#<`:I4{w.2aQ$EXNo?Gm NN rE$#Jn҉!AH'zePzRog8u(tJP߁Z.pÐ͢Aռ65Xsyvm 6RW7W;|0 >OүG@ٳ<>omԼ()kZJlK,F 4)snOQ{u㌏= Ao,ծ?eKBzG 6e6 f|CU _4C[j͕M8,%emM8\ cv COwTGi _94BDf%'ns8MPc&-y"8R_j 3a+z+N 9QlDQ40E VۋrH2I_YO',:뿉WNHvﵐ0B}na*E zUbN#0e"f.Q H5"-HVn=+ # Eiy- v8=g`o[ 鼛2.D^QeB ؅qϿRC~ B+Jۍ8 4*ӖΝ1R BI\ 1[0 I9y)Y " 7]6qg\ vP  s= Ѭ֕)פE< c`ϷU9W,: ?y1hsU(T ge/룮JA]|4aZVAIeIhBI!l$3![qHnw\7R{oM/ִ>5& gwjFE dc@K:V&W/k+=Yk[ @fU5zzmFȖH,[ n-dc wd[z"g4ϘRr0`B8_; #$^Zo5KZYKj GY%s"!a[9I2TF-w#a]˒Itٮei_FpVЧ૱W3eCi7 "}HApG>h֝5i T٧- '`dX1AF$$ޙ_Z]ڷTC Uy JGO} >A"5a> ZUR -Z\9 jrWݖQRݳ*ļ]$ڵXq=/w z\II#{ӭl^;F_R쵎[ָ[gKKͰoQ )W녕іs*kuzŨQde`WU_KLE~"g r<2GyއL(-VY -Z(IU0 |\;8C mhl:̄DkYHOk|:*DY tsس |zrO;񍃌sT31=jwyШ^nZHm_G̮0W󿓹S;_$mٛIDV=f-H}U]HA*vԶ3\Wh*I#$@6x^OZC&JU 16 XD*if&BDGFYYP[KLX uX .Z hq Ghb8M#Mqt\c> aT 00=㎨ʕGQԪR,ĜI9zӦJO3Rn`C5܊@QO1N.ؔ"I\YÖĐHdL\}IP~jm$ y; :ZGZVJv =&*UF#``R`*S+p\=) ҭ9k̮Ršx0'**ԑLkɺk+zJb#:|MZ ?j$ݼ &X)$6FY6ѕ/; J*nlC*ų_ ԕ{_6:\47ڷs4RmĊ=z *ʪXT[]5Bl#a-˙bv8@H|Rwe9A%5&M%Z02TN)&&GfM 儀oŒM;=.//k~ E"a9/3y,>lj>ZXy&εYP&h gec<``]!}i'c KQulFIʓ_\T58(+cJq~ [dgmm/`Xڙhtkq ו$"c[PVY[uɜ&#몵"ȾqC"ÜȔ!<Mj8u-dx*gϫtTLdKlaWڭ\~|7u`h(w֋cL=˼=FvcGs}зUBSМ;FI;Q$8+V|[CS쮙1%YP Q% LVVK+&,cIb]Vyi ~h?yF4"5As-F ݆x55P&E:W@f;}Gy^]U ITki 1 d﫠*cNh' cؗYnsL:b?H :kM~@8#Iqɔ~:f]P*i]H'fjhxTҗ1O:^t$1]UXz&tODT>(^s&3#N_/x-䬦? ~vU-W$4'ӎvRG|jySW?u4(1 G[ِ22jʎhrmoյشgRͮ%ϟѬ9 oR  n-&F-@hgY_qN;"2 !KJ  šA^, "aG8`=14=5Mqk>U@UT :RgjrKF.O$I9'=i}._ Default page
  • Your IP: 216.73.217.122
  • Server IP: 36.95.219.150
  • Server: Linux unisda-1 6.8.4-2-pve #1 SMP PREEMPT_DYNAMIC PMX 6.8.4-2 (2024-04-10T17:36Z) x86_64
  • Server Software: Apache/2.4.52 (Ubuntu)
  • PHP Version: 7.4.33
  • Buat File | Buat Folder
Edit File: filterlib.php
', '', ''); } else { // Set an empty default list. $filterignoretagsopen = array(); $filterignoretagsclose = array(); } // Add the user defined ignore tags to the default list. if ( is_array($ignoretagsopen) ) { foreach ($ignoretagsopen as $open) { $filterignoretagsopen[] = $open; } foreach ($ignoretagsclose as $close) { $filterignoretagsclose[] = $close; } } // Double up some magic chars to avoid "accidental matches". $text = preg_replace('/([#*%])/', '\1\1', $text); // Remove everything enclosed by the ignore tags from $text. filter_save_ignore_tags($text, $filterignoretagsopen, $filterignoretagsclose, $ignoretags); // Remove tags from $text. filter_save_tags($text, $tags); // Prepare the limit for preg_match calls. if (!empty($CFG->filtermatchonepertext) || !empty($CFG->filtermatchoneperpage)) { $pregreplacelimit = 1; } else { $pregreplacelimit = -1; // No limit. } // Time to cycle through each phrase to be linked. foreach ($linkarray as $key => $linkobject) { if ($linkobject->workregexp === null) { // This is the case if, when preparing the phrases for filtering, // we decided that this was not a suitable phrase to match. continue; } // If $CFG->filtermatchoneperpage, avoid previously matched linked phrases. if (!empty($CFG->filtermatchoneperpage) && isset($usedphrases[$linkobject->workregexp])) { continue; } // Do our highlighting. $resulttext = preg_replace_callback($linkobject->workregexp, function ($matches) use ($linkobject) { if ($linkobject->workreplacementphrase === null) { filter_prepare_phrase_for_replacement($linkobject); } return str_replace('$1', $matches[1], $linkobject->workreplacementphrase); }, $text, $pregreplacelimit); // If the text has changed we have to look for links again. if ($resulttext != $text) { $text = $resulttext; // Remove everything enclosed by the ignore tags from $text. filter_save_ignore_tags($text, $filterignoretagsopen, $filterignoretagsclose, $ignoretags); // Remove tags from $text. filter_save_tags($text, $tags); // If $CFG->filtermatchoneperpage, save linked phrases to request. if (!empty($CFG->filtermatchoneperpage)) { $usedphrases[$linkobject->workregexp] = 1; } } } // Rebuild the text with all the excluded areas. if (!empty($tags)) { $text = str_replace(array_keys($tags), $tags, $text); } if (!empty($ignoretags)) { $ignoretags = array_reverse($ignoretags); // Reversed so "progressive" str_replace() will solve some nesting problems. $text = str_replace(array_keys($ignoretags), $ignoretags, $text); } // Remove the protective doubleups. $text = preg_replace('/([#*%])(\1)/', '\1', $text); // Add missing javascript for popus. $text = filter_add_javascript($text); return $text; } /** * Prepare a list of link for processing with {@link filter_phrases()}. * * @param filterobject[] $linkarray the links that will be passed to filter_phrases(). * @return filterobject[] the updated list of links with necessary pre-processing done. */ function filter_prepare_phrases_for_filtering(array $linkarray) { // Time to cycle through each phrase to be linked. foreach ($linkarray as $linkobject) { // Set some defaults if certain properties are missing. // Properties may be missing if the filterobject class has not been used to construct the object. if (empty($linkobject->phrase)) { continue; } // Avoid integers < 1000 to be linked. See bug 1446. $intcurrent = intval($linkobject->phrase); if (!empty($intcurrent) && strval($intcurrent) == $linkobject->phrase && $intcurrent < 1000) { continue; } // Strip tags out of the phrase. $linkobject->workregexp = strip_tags($linkobject->phrase); if (!$linkobject->casesensitive) { $linkobject->workregexp = core_text::strtolower($linkobject->workregexp); } // Double up chars that might cause a false match -- the duplicates will // be cleared up before returning to the user. $linkobject->workregexp = preg_replace('/([#*%])/', '\1\1', $linkobject->workregexp); // Quote any regular expression characters and the delimiter in the work phrase to be searched. $linkobject->workregexp = preg_quote($linkobject->workregexp, '/'); // If we ony want to match entire words then add \b assertions. However, only // do this if the first or last thing in the phrase to match is a word character. if ($linkobject->fullmatch) { if (preg_match('~^\w~', $linkobject->workregexp)) { $linkobject->workregexp = '\b' . $linkobject->workregexp; } if (preg_match('~\w$~', $linkobject->workregexp)) { $linkobject->workregexp = $linkobject->workregexp . '\b'; } } $linkobject->workregexp = '/(' . $linkobject->workregexp . ')/s'; if (!$linkobject->casesensitive) { $linkobject->workregexp .= 'iu'; } } return $linkarray; } /** * Fill in the remaining ->work... fields, that would be needed to replace the phrase. * * @param filterobject $linkobject the link object on which to set additional fields. */ function filter_prepare_phrase_for_replacement(filterobject $linkobject) { if ($linkobject->replacementcallback !== null) { list($linkobject->hreftagbegin, $linkobject->hreftagend, $linkobject->replacementphrase) = call_user_func_array($linkobject->replacementcallback, $linkobject->replacementcallbackdata); } if (!isset($linkobject->hreftagbegin) or !isset($linkobject->hreftagend)) { $linkobject->hreftagbegin = 'hreftagend = ''; } // Double up chars to protect true duplicates // be cleared up before returning to the user. $hreftagbeginmangled = preg_replace('/([#*%])/', '\1\1', $linkobject->hreftagbegin); // Set the replacement phrase properly. if ($linkobject->replacementphrase) { // We have specified a replacement phrase. $linkobject->workreplacementphrase = strip_tags($linkobject->replacementphrase); } else { // The replacement is the original phrase as matched below. $linkobject->workreplacementphrase = '$1'; } $linkobject->workreplacementphrase = $hreftagbeginmangled . $linkobject->workreplacementphrase . $linkobject->hreftagend; } /** * Remove duplicate from a list of {@link filterobject}. * * @param filterobject[] $linkarray a list of filterobject. * @return filterobject[] the same list, but with dupicates removed. */ function filter_remove_duplicates($linkarray) { $concepts = array(); // Keep a record of concepts as we cycle through. $lconcepts = array(); // A lower case version for case insensitive. $cleanlinks = array(); foreach ($linkarray as $key => $filterobject) { if ($filterobject->casesensitive) { $exists = in_array($filterobject->phrase, $concepts); } else { $exists = in_array(core_text::strtolower($filterobject->phrase), $lconcepts); } if (!$exists) { $cleanlinks[] = $filterobject; $concepts[] = $filterobject->phrase; $lconcepts[] = core_text::strtolower($filterobject->phrase); } } return $cleanlinks; } /** * Extract open/lose tags and their contents to avoid being processed by filters. * Useful to extract pieces of code like ... tags. It returns the text * converted with some <#xTEXTFILTER_EXCL_SEPARATORx#> codes replacing the extracted text. Such extracted * texts are returned in the ignoretags array (as values), with codes as keys. * * @param string $text the text that we are filtering (in/out) * @param array $filterignoretagsopen an array of open tags to start searching * @param array $filterignoretagsclose an array of close tags to end searching * @param array $ignoretags an array of saved strings useful to rebuild the original text (in/out) **/ function filter_save_ignore_tags(&$text, $filterignoretagsopen, $filterignoretagsclose, &$ignoretags) { // Remove everything enclosed by the ignore tags from $text. foreach ($filterignoretagsopen as $ikey => $opentag) { $closetag = $filterignoretagsclose[$ikey]; // Form regular expression. $opentag = str_replace('/', '\/', $opentag); // Delimit forward slashes. $closetag = str_replace('/', '\/', $closetag); // Delimit forward slashes. $pregexp = '/'.$opentag.'(.*?)'.$closetag.'/is'; preg_match_all($pregexp, $text, $listofignores); foreach (array_unique($listofignores[0]) as $key => $value) { $prefix = (string) (count($ignoretags) + 1); $ignoretags['<#'.$prefix.TEXTFILTER_EXCL_SEPARATOR.$key.'#>'] = $value; } if (!empty($ignoretags)) { $text = str_replace($ignoretags, array_keys($ignoretags), $text); } } } /** * Extract tags (any text enclosed by < and > to avoid being processed by filters. * It returns the text converted with some <%xTEXTFILTER_EXCL_SEPARATORx%> codes replacing the extracted text. Such extracted * texts are returned in the tags array (as values), with codes as keys. * * @param string $text the text that we are filtering (in/out) * @param array $tags an array of saved strings useful to rebuild the original text (in/out) **/ function filter_save_tags(&$text, &$tags) { preg_match_all('/<([^#%*].*?)>/is', $text, $listofnewtags); foreach (array_unique($listofnewtags[0]) as $ntkey => $value) { $prefix = (string)(count($tags) + 1); $tags['<%'.$prefix.TEXTFILTER_EXCL_SEPARATOR.$ntkey.'%>'] = $value; } if (!empty($tags)) { $text = str_replace($tags, array_keys($tags), $text); } } /** * Add missing openpopup javascript to HTML files. * * @param string $text * @return string */ function filter_add_javascript($text) { global $CFG; if (stripos($text, '') === false) { return $text; // This is not a html file. } if (strpos($text, 'onclick="return openpopup') === false) { return $text; // No popup - no need to add javascript. } $js = " "; if (stripos($text, '') !== false) { // Try to add it into the head element. $text = str_ireplace('', $js.'', $text); return $text; } // Last chance - try adding head element. return preg_replace("//is", "\\0".$js.'', $text); }