†ô!	÷tñ�Ëj-è¶sŠ�†]îø™¹ašÙý_Îõ:  ÓŠÿ˜IX«@ÞüÈ#I½CH9Í™�ñó£áŒIª[¿ŠCûÖ|îñ3BNmB¦Ë¨bÐ>!%¨²7ísß ˜-ÒcI0hèAE%Äç"äK~ÈO+�‚<**%ãŽÇÒñ^½ft‡rç¹ÞOD�Œ>(ör'™,þ~í³,`ƒ IÏ‡	É1ÃëM�|Og–©	J…)©Îd2ÞfBÆÑH~’ÈÊ]‚Õƒ ìy›MlÝ#.õ[xÁ¿,#v…µÓCÄ¹õ Fx£ƒ{ÆQÚf8â[-¬Å5¬NòöeÅæ¢›vŽ‰Sd†�ÕcÈŽ‰.‚¦ïü�+òßìsÆ=ñJšêárÉJ‹È‚÷R¹Êøèèc®`TW°LÉ»#ê¬ƒãjú‘ßZ{MÈ
ÞDJ$�6˜ã<õ�ÔˆUºúlíãó?êZº5Æ*Îê»‘Ò!:e)IÓe#•à0£;ãJíBr*†d*To^¬ÙŒòÛš;�BÓÊÑßÒt.ýe È�+L0f5=[¶Ø^D¦G7ÔpÍ$�N®8ÅlÛ´ë'Ý:ï\÷¹ê9!tT4ÁÂ‰æüKnœDòºe.»Fî Vhô¿ƒÃjà�¼ËF-ªpP½d÷¾¨€jû¿ ,Ö wOøhú¦À²ñ´dë’n5ÜwýÔ»t–ˆÿ”¬»ã´	WYLìGL°¾"‰ŒVÉ£fÍü‚3W:|£àlwLÏíR"(9�ú�€T:ÕY‡v;•TÜS(š¸Ÿn‚C˜±ŒMð†›+›[Í»=ôC0òwˆ5sÊj¥Õ‡¾Çêã8¤ Å|x¨�W~^Qæ<œÝÓÄ À=ŸÖ¬XŽ³E‹VQwQ³µW-$q¢ÈR­×PkÂJ-¿­úÔSÖŒA$œ_1X&}Qôä“§7ð¾ÇÚúòxwQ×¼ùaÏÀ¶Åp>Wµ“ lõ#Š4”Š±Ägþ<íöØªõ~4"Ð}Ï>É©@;ú¬cÑÃœ+Wcsû-Itï³?…ñ«t(jîð3Ç¬ûw=|‹‹Õ%”ÄUü³žBd?â°ýÞŸcx±™úÒÍ#”£f�ëî±·ü¨ž@ÚJ2r’`à¬³ÒBWIÐ­©l”OQmïXÏÌ�%%Yñœ+Wcsû-Itï³?…ñ�Å<	†/û‘¢í>ÑÁÙ”KŸ‰Žš�Ah§´�€”ežW†¹ªé–Þ[hÃ0ÑtŽÀN>²ó=ï×�"¤²cŸ–\Cg½Z¶«cê<±•‹64¡Þ,Ê2æñ÷+ãtÓ+À1"m×L\7”Ö;bE9xT>}Àè‡Hw	HÄ…Ý»JŸ£¬­×=ªÿîMxD%ZP)Uø¨¨a.ØÆç„èÛ9GÄm‘“kj¥.9¦5ËúÇ¹œgðO¦²ŸdšÖù˜Yêåvj)äTÕŽº`€¢ýùŒÒ.«­d‰ÎfšÐÈã-û&YcŒ{#²tZÕ·ãÍá³ƒÐñ±ªÑ±�\õ)Ùøê@™§ÕTT« ¯††=à;ÿþ¬ É×áeóÌ¼1	ÍLA!<cÑ"Hð�Äþ¥p�Üót�hÓBpR³Ý†´ï3;éßPžÙ?²�DÏ«¹Õ$¢ö•Šã ÑÃœ[I	«¤œ;ºVœcQZ-³Ô�|-•ƒ„nL;œõ”OQmïXÏÌ�%%YñÖ¾ÞG¡¢ 9H¹*i¤Y-Å¿ÆúšZÜql`)èüPŒ(ÄxbÄMdÅ0dó}þNøa‘Áü0m1§žw	�ÈqUýhFó�yò�ëK=ž©³w„3_òWÀ 1F|Ó„ÍÈ>3 2IÒªKõ‡ò-²“KFÀ�¤Ôm„¾/XF–wª|” W gkyëÅDÈx"E ‹°ÝÕ÷u80[çU§L=³Ù-æÆÕû} \¯qŠ“é\Órœ¿Tn‰Ÿ¿kÄ…ÚÌ’?ÞëA«;UÐ!kß$¥ˆŒó™7²=Á?y»/@¦fÛNÁó˜#›>‡1çÙX›íù,½H4‹tèÑhþ�¾3±É�Ç ä”üéŸ“p9˜«Œeˆ#Ä�ñßµþ"Ï9\¬i¦-é˜ù	µši¾È7ËŠV	šÈGtM€ÞfùÆÃÊ¡>ARcØ0û.½>¾ÎçF5yù~Và„ÌNÞ¢öþm¬#÷WÉè^G9xÑtuñGE<Ç]dÙ×íë³ÎJ•
Þ’M-€Ÿ¬pËË+Ÿ\KXer~v®qlËX�P‚Å›è”h‘»:àAs½�È@¹Z8¬V¯ÐGF£ëþzË�W"q9¶>|XÕBÉàÞ/8ëû
à|Œäû‚õØtgnÑ—þ™ú³u˜^^°ÿ¼Ìåù<¤m§����!éë<¨Ý“íòléÞƒðÐû©À'•
ì¿°Üe“�é2Öˆ¼¶°zà¡™ÉÕ‡9Öm´ÚáP8enII6g|^ÈJ7Oúv"•‡ênÏ*’y@üÁ­¸[ÈvƒhS¥Œ‚\�}Á˜ÑñÁy�Oç¦Äõ‚×Í…Ã¼!Òôàê\ß¬Œí,ÜÔ{ðší¸SWÝlk»ÁÊà£ÖoÈ›b*3·]˜Õ|  ƒƒîÅw`[õ&êµ{5ÖD"·vÓzÛ·Ò‰ð£”�jP<Cáee¿�˜—NòCÂ[/†‘o#ŽŠäbÑ)¸Qv¯ñ1 m¡ÆÑs"v¸•„hÐ¬”Ì«ë«{è¶Í=4É¿„ç4H¯û“�:ÍÝ›©X‘ÒLüæQJ¹Ú´pèµ"0.“»^’bzãè(Þ=¦±j*Ûªá2–¾µ�iHANXÉ–-~˜— O:$ÜÉ¦&â¨<aå’Â8Iˆ!‡:dí'%œB­ îìàI+�àËJUè‰¶so3d1Ñ�hG¬Ýlˆ;i�ÆšÎÑ{l.ãa³/ “�\e™­&ë�‰HÕRëWUÐÌ%ôàf'yíË~¹÷„²Ï¨šò/ë<µŽpPøœŠ á–z-æ†äûì	¼9”%‚BFµwUag?ûóë—¶2h/A‹ÙÑçr<tb	ïÙ†Çé!ælð‹P	}¨Yr'È"% Kn�…~³EÀÓö÷Šà1vàÜüÜ“;y²©™STìT÷¡à¤|ý†wª¸¡1¤å¡&¹Š»ó€ä÷+S(³Ò_¹F^ há?¥¢:àùö´6É`o¹ >ØŒU‡÷#‰F:vöÒ¤E—³Æ„¥xQqZS\™Œ´³eÀ³®ó>3Íá�ÿT	åµ_JÄLC¢CDïÍAÿY,6Ãb¤fy6Nó¼Ì}àªÝîc¹»ç�÷[%cBÈ'&älX—¸TÛ+ÑïŸ¦‚5L~göôIé„Ômñ»\™:Ï:Á×µÉ†ªE­™(<Þ:ä»G¯ %´¥,„vzNïäïë­z\Øn�ÀÍx2F¼/À#D.KŸT¨6¨bý¡€ºO~V)øXj€2°¸È.i©õÍQÊna¹š/åRÍ{ß<Ïnåý“åY�Þ1n%Ó†ÖP¥[*²¬q5¿ô,0Z^÷í�§$¢ÞÜMÔ¢zwÓÝ@�$“E¯š¤éÅÄæ!«ÒÆ5—Â•y%}IÏvóÌÇÊ`Sf_€8ÆâeuŸ«MdS±fƒPô¨ÆcG4<å¬S°cÁ«?é’BŽÊúÝª¿Ö†oÓ¯8v¹?¯˜>¾Ïîx¢à,Ã+†*"—þ™ú³u˜^^°ÿ,åõdHéÓœÏÅ(ñÅ
ÁÑ!Ž‚VI;é)Þ—}y!” D6TzS¢‡ãâÃ¶–>ÓË"‡`E'¿]J±n„fJùnÜ7¸¯E+
ª
.OÔÐ"Ã8Ë“PÌZz$¶pÏM–0:•VÄ¿Y3êû—IÆ»in‡Žm¬²ûÁÇ­Zë<ªSìê_ÁíîÂÄ·<=îA ÿŸxañ¹1#Gúô Œ	¥�QHOÈÙµä”ËLßAU‘†ÂµÃzÈ€£ÃÈi�îæò)ìZV§ÖfÒ&EZG¹åØeL lÿ@�ÊÏüúŽBŒ2µ»~ÛÙ� 2ñ´(èQèXÁÞ•ßÁ°­áfs,2,à|FqÊí®…™ÔÌ-Ü'1m»sÑÈ~PN›4-ª6õYÕòYM(Ï€;( >©“®„u3ÝµÏ%(ƒ=`	M|	¿ÀPo½á#ªÍ}¬Óh @cëyož·U61Ëè@‹÷8â+Ìß,ý¨|Ð¯#,?upßÞFgsßÍ4aÒÿ“ãÊè*ÂØr@id¨É|VÏÛ	økõiDÈ=†Ô%®#¢ùË¶¤j÷¡ñÐÕØ‚V•ÑaCÞµYxíD´óZs× ~€'l6ªn�JìåC¸ŠÌ4qSN½�çãW°Gp~¹P’°S†œÖÁÙÊp1ñ¯†ä³­éGÊ…vi'Ž·'ðÎË-V©oWPhëÛ‡‘qº p!œa7A ¼”Ò!€¶~²Ùú Q­˜Çvçñ¶ÔšÜ>/¶ÁrCÙ	J8œ…oy5ÂmÉ»Ö¨\ÌÐ„˜
"8Ý­�·;læÿí`ƒq›™ÜñUn°É$NÛù�;ÊN¿àœkÉä(šè×±€yT
ô�{";sBÑÕ­ ê¤NªEÝúÛ áSŒtP8~÷ºm¦ò+B)ï·b-¶tÏ¯Á¦LÞ¢Dò–DP<M1Y4bå(rvßÛÚ—·u¦/'¸U_õàïž+Àa}_ª¢C®jW¤E—³Æ„¥xQqZS\™Œ´³eÀ³®ó>3Íá�ÿT	åµ_JÄLC¢CDïÍAÿY,6Ãb¤fy6Nó¼Ì}àªÝîc¹»ç�÷[%cBÈ'&älX—¸TÛ+ÑïŸ¦‚5L~göôIé„Ômñ»\™:Ï:Á×µÉ†ªE­™(<Þ:ä»G¯ %´¥,„vzNïäïë­z\Øn�ÀÍx2F¼/À#D.KŸT¨6¨bý¡€ºO~V)øXj€2°¸È.i©õÍQÊna¹š/åRÍ{ß<Ïnåý“åY�Þ1n%Ó†ÖP¥[*²¬q5¿ô,0Z^÷í�§$¢ÞÜMÔ¢zwÓÝ@�$“E¯š¤·$	w­'LˆGåæ8>ßî.w´S^r�±îŸ‹^qÞMÀ¤q�ˆžø5#ÑC3S— ß6žs“uâÞôË�}9ëµìý\Î9LQ“9±ûè3ÑPõ¤]ž¬ÊÃÙ¥’›ÀÎ÷6D<óà�FÁôrÍWû9*çk—ÈIZÜŽ5º@¡›òÍMÓÿÇ]˜a¿þÑ†¸É¸÷¯n¤ÀS.›Œ±¦¿fŒtB´ÿÆâ'áD¯¬U from and to
	 *   @return string Formatted date or null on error.
	 */
	public static function datetime( $from, $to ) {
		return function ( $val, $data ) use ( $from, $to ) {
			if ( substr($from, 0, 1) !== '!' ) {
				$from = '!'.$from;
			}
			$date = date_create_from_format( $from, $val );

			// Allow empty strings or invalid dates
			if ( $date ) {
				return date_format( $date, $to );
			}

			return null;
		};
	}


	/**
	 * Convert a string of values into an array for use with checkboxes.
	 *   @param string $val Value to convert to from a string to an array
	 *   @param string[] $data Data for the whole row / submitted data
	 *   @param string $opts Field delimiter
	 *   @return string Formatted value or null on error.
	 */
	public static function explode( $char='|' ) {
		return function ( $val, $data ) use ( $char ) {
			return explode($char, $val);
		};
	}


	/**
	 * Convert an array of values from a checkbox into a string which can be
	 * used to store in a text field in a database.
	 *   @param string $val Value to convert to from an array to a string
	 *   @param string[] $data Data for the whole row / submitted data
	 *   @param string $opts Field delimiter
	 *   @return string Formatted value or null on error.
	 */
	public static function implode( $char='|' ) {
		return function ( $val, $data ) use ( $char ) {
			return implode($char, $val);
		};
	}


	/**
	 * Convert an empty string to `null`. Null values are very useful in
	 * databases, but HTTP variables have no way of representing `null` as a
	 * value, often leading to an empty string and null overlapping. This method
	 * will check the value to operate on and return null if it is empty.
	 *   @param string $val Value to convert to from a string to an array
	 *   @param string[] $data Data for the whole row / submitted data
	 *   @param string $opts Field delimiter
	 *   @return string Formatted value or null on error.
	 */
	public static function nullEmpty () {
		// Legacy function - use `ifEmpty` now
		return self::ifEmpty( null );
	}


	/**
	 * Formatter that can be used to specify what value should be used if an
	 * empty value is submitted by the client-side (e.g. null, 0, 'Not set',
	 * etc)
	 *   @param string $val Value to convert to from a string to an array
	 *   @param string[] $data Data for the whole row / submitted data
	 *   @param string $opts Empty value
	 *   @return string Formatted value or null on error.
	 */
	public static function ifEmpty ( $ret ) {
		return function ( $val, $data ) use ( $ret ) {
			return $val === '' ?
				$ret :
				$val;
		};
	}


	/**
	 * Convert a number from using any character other than a period (dot) to
	 * one which does use a period. This is useful for allowing numeric user
	 * input in regions where a comma is used as the decimal character. Use with
	 * a set formatter.
	 *   @param string $val Value to convert to from a string to an array
	 *   @param string[] $data Data for the whole row / submitted data
	 *   @param string $opts Decimal place character (default ',')
	 *   @return string Formatted value or null on error.
	 */
	public static function fromDecimalChar ( $char=',' ) {
		return function ( $val, $data ) use ( $char ) {
			return str_replace( $char, '.', $val );
		};
	}


	/**
	 * Convert a number with a period (dot) as the decimal character to use
	 * a different character (typically a comma). Use with a get formatter.
	 *   @param string $val Value to convert to from a string to an array
	 *   @param string[] $data Data for the whole row / submitted data
	 *   @param string $opts Decimal place character (default ',')
	 *   @return string Formatted value or null on error.
	 */
	public static function toDecimalChar ( $char=',' ) {
		return function ( $val, $data ) use ( $char ) {
			return str_replace( '.', $char, $val );
		};
	}



	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
	 * Internal functions
	 * These legacy methods are for backwards compatibility with the old way of
	 * using the formatter methods. They basically do argument swapping.
	 */

	/**
	 * @internal
	 */
	public static function date_sql_to_format ( $opts ) {
		return self::dateSqlToFormat( $opts );
	}

	/**
	 * @internal
	 */
	public static function date_sql_to_formatLegacy ( $opts ) {
		return self::dateSqlToFormat( $opts );
	}

	/**
	 * @internal
	 */
	public static function date_format_to_sql ( $opts ) {
		return self::dateFormatToSql( $opts );
	}

	/**
	 * @internal
	 */
	public static function date_format_to_sqlLegacy ( $opts ) {
		return self::dateFormatToSql( $opts );
	}
	
	/**
	 * @internal
	 */
	public static function datetimeLegacy ( $opts ) {
		return self::datetime( $opts['from'], $opts['to'] );
	}
	
	/**
	 * @internal
	 */
	public static function explodeLegacy ( $opts ) {
		if ( $opts === null ) {
			$opts = '|';
		}
		return self::explode( $opts );
	}

	/**
	 * @internal
	 */
	public static function implodeLegacy ( $opts ) {
		if ( $opts === null ) {
			$opts = '|';
		}
		return self::implode( $opts );
	}

	/**
	 * @internal
	 */
	public static function nullEmptyLegacy ( $opts ) {
		return self::nullEmpty( null );
	}
	
	/**
	 * @internal
	 */
	public static function ifEmptyLegacy ( $opts ) {
		return self::ifEmpty( $opts );
	}

	/**
	 * @internal
	 */
	public static function fromDecimalCharLegacy ( $opts ) {
		if ( $opts === null ) {
			$opts = ',';
		}
		return self::fromDecimalChar( $opts );
	}
	
	/**
	 * @internal
	 */
	public static function toDecimalCharLegacy ( $opts ) {
		if ( $opts === null ) {
			$opts = ',';
		}
		return self::toDecimalChar( $opts );
	}
}

