�PNG  IHDR22?�� pHYs  �� OiCCPPhotoshop ICC profilexڝSgTS�=���BK���KoR RB���&*! J�!��Q�EEȠ�����Q, � ��!���������{�kּ������>���� �H3Q5� �B�������.@� $p�d!s�#�~<<+"��x� �M��0���B�\���t�8K�@z�B�@F���&S�`�cb�P-`'������{[�!�� e�Dh;��V�EX0fK�9�-0IWfH���� � 0Q��){`�##x��F�W<�+��*x��<�$9E�[-qWW.(�I+6aa�@.�y�2�4���������x����6��_-��"bb���ϫp@�t~��,/��;�m��%�h^ �u��f�@����W�p�~<�5�j>{�-�]c�K'Xt����o��(�h���w��?�G�%�fI�q^D$.Tʳ?�D��*�A��,���� �`6�B$��BB d�r`)��B(�Ͱ*`/�@4�Qh��p.�U�=p�a��(�� A�a!ڈb�X#����!�H�$ ɈQ"K�5H1R�T UH�=r9�\F��;�2����G1���Q=� �C��7�F� �dt1�����r�=�6��Ыhڏ>C�0��3�l0.��B�8, �c˱"� ���V����cϱw�E� 6wB aAHXLXN�H� $4� 7 �Q�'"��K�&���b21�XH,#��/{�C�7$�C2'��I��T��F�nR#�,��4H#���dk�9�, +ȅ����3��!�[ �b@q��S�(R�jJ��4�e�2AU��Rݨ�T5�ZB���R�Q��4u�9̓IK�����hh�i��t�ݕN��W���G���w ��Ljg(�gw��L�Ӌ�T071���oUX*�*|�� �J�&�*/T����ު U�U�T��^S}�FU3S� Ԗ�U��P�SSg�;���g�oT?�~Y��Y�L�OC�Q��_�� c�x,!k ��u�5�&���|v*�����=���9C3J3W�R�f?�q��tN �(���~���)�)�4L�1e\k����X�H�Q�G�6������E�Y��A�J'\'Gg����S�Sݧ �M=:��.�k���Dw�n��^��Lo��y���}/�T�m���G X� $� �<�5qo</���QC]�@C�a�a�ᄑ��<��F�F�i�\�$�m�mƣ&&!&KM�M�RM��)�;L;L���͢�֙5�=1�2��כ߷`ZxZ,����eI��Z�Yn�Z9Y�XUZ]�F���%ֻ�����N�N���gð�ɶ�����ۮ�m�}agbg�Ů��}�}��= ���Z~s�r:V:ޚΜ�?}����/gX���3��)�i�S��Ggg�s�󈋉K��.�>.���Ƚ�Jt�q]�z���������ۯ�6�i�ܟ�4�)�Y3s���C�Q��? ��0k߬~OCO�g��#/c/�W�װ��w��a�>�>r��>�<7�2�Y_�7��ȷ�O�o�_��C#�d�z����%g��A�[��z|!��?:�e����A���AA�������!h�쐭!��Α�i�P~���a�a��~ '���W�?�p�X�1�5w��Cs�D�D�Dޛg1O9�-J5*>�.j<�7�4�?�.fY��X�XIlK9.*�6nl������� �{�/�]py�����.,:�@L�N8��A*��%�w%� y��g"/�6ш�C\*N�H*Mz�쑼5y$�3�,幄'���L Lݛ:��v m2=:�1����qB�!M��g�g�fvˬe����n��/��k���Y- �B��TZ(�*�geWf�͉�9���+��̳�ې7�����ᒶ��KW-X潬j9�������(�x��oʿ�ܔ���Ĺd�f�f���-�[����n �ڴ �V����E�/��(ۻ��C���<��e����;?T�T�T�T6��ݵa��n��{��4���[���>ɾ�UUM�f�e�I���?�������m]�Nmq����#�׹���=TR��+�G�����w- 6 U����#pDy��� �� :�v�{���vg/jB��F�S��[b[�O�>����z�G��499�?r����C�d�&����ˮ/~�����јѡ�򗓿m|������������x31^�V���w�w��O�| (�h���SЧ��������c3-� cHRMz%������u0�`:�o�_�F5IDATx��ytUս�?�;���fN$$��@B�!�k��� -*�gE���j�O�kQ�ʠ`U�B_ �AÐ0%�Ȕ�@r3ޛ;߳��$�@��v����^�s����������$��ߢ !�W��5�̱'-٘������4�>�Rƫ$�G��0U�H}�_ _� #��k�MJ/=�9Du *ڲ�k�PQ;0��j|�*�$�^컂脛y���>�z×� B��� ��(�:$�ʔ_�6��C!B����MVx��a��ζyY����j��ƋY2�9�F�{r��r�딟F��Q��hY6��� x��[l��RC��������nt@��;P��3��� F�w��7��:�P���ɋ'���mj���Bƪ�$�Q�L��y��߷g��\���z����v5�p�v$�v櫻�`6~K �Y�X����,�:��"�o�e0II"(��,������l_�C���/4�+f�E�!q��:����u����c��樼.UE�@� �]K�W���$-�h]�JG���Dz)�`��.�A/ ���mᏣc�3jK� �!�>���$�Q�!�_�? \�C2(E �M$Z I{�U���s�ǣ���=��@Բe ޻��W�����@ �w����}�9v,)��.}*|"�s��di���,���G�]W�AC�������|<����[��ߕ������K�*�G nߴ!��‹��J�!��6(L�a)��Am��������;adf��:�xm��nh�;֦I��(���o�C~ډa?�=��s����h��E������xp����)���_���t��W�����´;8���`dz=(��@@�+,�;�`�fhl��XȌ�3,uI�~z(J����� �ZX�A����H'�À�㜦�82|��a�n�z2��I���� ���EY�h�ε<�0�q�{��C��v�˅��?"@��χ�x�WS+��N�~�KQ�J�8ل�� _.W��� !TU{�����,��"�� �;�������HI S� ��))�o�1�H�D� ���� (� ;����"Ҕ��,���� �F=���O��&�Ph>�`���y��߲ &S��P�<��'��1s�1cĂ�N����2)����@�u��tv��<�+�-&�����h��[!FSG���' � z z0��<����8d&�����E0�,��<��"!P�b4��� �{S�����X����.�囤���T��hEF��X�q0"-<����h���]�Py*����F⩍��@v�˂�Y08�� .q��a��s����(!<̫1�3�L�H��7sYW�`��qtu�\7��?�@�Y�� %Ka�x�GZ�*W�P��y�����N0r9��Z�c�%���q,��k�����!!,��>���IB��� �x1�Xu�Y���v-���ֺ��N������JP��a�2`�e5��w��u;�6�i���̃��(K���ťa��(l51��JL��O'%���]���ٖ뿉!��{*�p+f ���i8��D�ȑ���ܩ�M��V��ӟz��x�7Z�1i}�^͜���6e����x��)u�d�ˏ�V�eG�\�X1�����=n�U'�~Y����L�\,�(d!x ,�:�TW8� M`r���@��r+v�Q0��>^;˴�VbF��('����� �*O��i��j�Ӆ����^�S3&� ���{������.ی�� N;��NU%d0�Ce\r"�C�b��&t7N�7��� �ȪD�[%l�۪�$��'m?�A9tI�9>��NVL ��� 6v~M�����ъ�B���0����9$&=ώm��W�0���L���&��E���f�f��'+�9��hv��7,���M��6�D�&�^� �����8 D֮�����o��k^z��O��hP�8q�5d*��YVq3�{��������#LX4�?��jP=3�~�؅c�ݰ�̱�ұ��8̲��2�G�����j��έ�9��w7���U�X�w�85C��?!I&���o&����L���I#�^�eV�,�^t5�k� �xs˛\��U�8��."���{���ǵ�l4��ݼ�;��r"���G�/~���gJV�N糦��ZZ^k+NN�D��I$�=OE�z����|*�*{��%k���G��>�`9��b;�s���8,�qs��c��.b��q�%�>r��n�R�Ƨ�%�,�A��le#�8���}; 21�0�b�&�QX�f���q�00����$>�h�N�'�a3��A���/�r ��L5�8�GԲ'�����w;��c#�q1���h$*��V^�k��QĽ�b:i������� ����H F#�_���,��]g����Ը����`RUU���� ��"�qD���>-��ϤI�~��3�̴�����NZ[[555�eeek7�m����YF#[��Đ��R��i��L�H�r ��@��J-�Pŝ��_|�-��6y��ks�V�U~��6���w.����(��0A� 4��f��� /���C�xŊ�ٳ����z=6�����rg���mKo��o�/����a�g���?'9%9��P��斓��~���L{�� �H��{AW��B��$����v�1b�&Mb�ر��ر#�0`�`xMBp! )Z�Nmo�mZ�g�}�eذaWTVV ���'99��C5��&�&+5�bT>|8��PUUETT����&���t��~TE%��'������b�tEGG;RSS�S�N�v��ѯ��t����u1@�ޚ"f��͈���r'L�Ph��m��ƌ�74o��`�x�q�P���NRSS�X,�����l&&&��MFFA!-��`��ҷ�n��Yuu�����x<I�LB%����KԒ50�!�3�bz�����ʸKL���;---�l6[��`��������Ȏ;�����egg4��!D�T��jWujyZ��������K����%����p�^���X,6��sV=�ܖ����6�3�X ���4ҿ��A2�&����_k�;d�� �VfOIEND�B`�
Warning: session_start(): Session cannot be started after headers have already been sent in /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php on line 124

Warning: Cannot modify header information - headers already sent by (output started at /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php:1) in /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php on line 130

Warning: Cannot modify header information - headers already sent by (output started at /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php:1) in /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php on line 131

Warning: Cannot modify header information - headers already sent by (output started at /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php:1) in /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php on line 132

Warning: Cannot modify header information - headers already sent by (output started at /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php:1) in /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php on line 133

Warning: Cannot modify header information - headers already sent by (output started at /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php:1) in /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php on line 134

Warning: Cannot modify header information - headers already sent by (output started at /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php:1) in /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php on line 135

Warning: Cannot modify header information - headers already sent by (output started at /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php:1) in /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php on line 547

Warning: Cannot modify header information - headers already sent by (output started at /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php:1) in /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php on line 548

Warning: Cannot modify header information - headers already sent by (output started at /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php:1) in /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php on line 549

Warning: Cannot modify header information - headers already sent by (output started at /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php:1) in /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php on line 550

Warning: Cannot modify header information - headers already sent by (output started at /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php:1) in /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php on line 551
/*! SerializeJSON jQuery plugin. https://github.com/marioizquierdo/jquery.serializeJSON version 3.2.1 (Feb, 2021) Copyright (c) 2012-2021 Mario Izquierdo Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. */ (function( factory ) { var jQuery; /* global define, require, module */ if ( 'function' === typeof define && define.amd ) { // AMD. Register as an anonymous module. define( ['jquery'], factory ); } else if ( 'object' === typeof exports ) { // Node/CommonJS. jQuery = require( 'jquery' ); module.exports = factory( jQuery ); } else { // Browser globals (zepto supported). factory( window.jQuery || window.Zepto || window.$ ); // Zepto supported on browsers as well. } }( function( $ ) { 'use strict'; var rCRLF = /\r?\n/g; var rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i; var rsubmittable = /^(?:input|select|textarea|keygen)/i; var rcheckableType = /^(?:checkbox|radio)$/i; $.fn.serializeJSON = function( options ) { var f = $.serializeJSON; var _this = this; // NOTE: the set of matched elements is most likely a form, but it could also be a group of inputs. var opts = f.setupOpts( options ); // Validate options and apply defaults. var typeFunctions = $.extend( {}, opts.defaultTypes, opts.customTypes ); // Make a list with {name, value, el} for each input element. var serializedArray = f.serializeArray( _this, opts ); // Convert the serializedArray into a serializedObject with nested keys. var serializedObject = {}; $.each( serializedArray, function( _i, obj ) { var nameSansType = obj.name; var type = $( obj.el ).attr( 'data-value-type' ); var p; var typedValue; var keys; if ( ! type && ! opts.disableColonTypes ) { // Try getting the type from the input name. p = f.splitType( obj.name ); // "foo:string" => ["foo", "string"]. nameSansType = p[0]; type = p[1]; } if ( 'skip' === type ) { return; // Ignore fields with type skip. } if ( ! type ) { type = opts.defaultType; // "string" by default } typedValue = f.applyTypeFunc( obj.name, obj.value, type, obj.el, typeFunctions ); // Parse type as string, number, etc. if ( ! typedValue && f.shouldSkipFalsy( obj.name, nameSansType, type, obj.el, opts ) ) { return; // Ignore falsy inputs if specified in the options. } keys = f.splitInputNameIntoKeysArray( nameSansType ); f.deepSet( serializedObject, keys, typedValue, opts ); } ); return serializedObject; }; // Use $.serializeJSON as namespace for the auxiliary functions // and to define defaults. $.serializeJSON = { defaultOptions: {}, // Reassign to override option defaults for all serializeJSON calls. defaultBaseOptions: { // Do not modify, use defaultOptions instead. checkboxUncheckedValue: undefined, // To include that value for unchecked checkboxes (instead of ignoring them). useIntKeysAsArrayIndex: false, // Tip: name="foo[2]" value="v" => {foo: [null, null, "v"]}, instead of {foo: ["2": "v"]}. skipFalsyValuesForTypes: [], // Skip serialization of falsy values for listed value types. skipFalsyValuesForFields: [], // Skip serialization of falsy values for listed field names. disableColonTypes: false, // Do not interpret ":type" suffix as a type. customTypes: {}, // Extends defaultTypes. defaultTypes: { 'string': function( str ) { return String( str ); }, 'number': function( str ) { return Number( str ); }, 'boolean': function( str ) { var falses = ['false', 'null', 'undefined', '', '0']; return -1 === falses.indexOf( str ); }, 'null': function( str ) { var falses = ['false', 'null', 'undefined', '', '0']; return -1 === falses.indexOf( str ) ? str : null; }, 'array': function( str ) { return JSON.parse( str ); }, 'object': function( str ) { return JSON.parse( str ); }, 'skip': null // Skip is a special type used to ignore fields. }, defaultType: 'string' }, // Validate and set defaults. setupOpts: function( options ) { var f; var validOpts; var opt; if ( null == options ) { options = {}; } f = $.serializeJSON; // Validate. validOpts = [ 'checkboxUncheckedValue', 'useIntKeysAsArrayIndex', 'skipFalsyValuesForTypes', 'skipFalsyValuesForFields', 'disableColonTypes', 'customTypes', 'defaultTypes', 'defaultType' ]; for ( opt in options ) { if ( validOpts.indexOf( opt ) === -1 ) { throw new Error( 'serializeJSON ERROR: invalid option \'' + opt + '\'. Please use one of ' + validOpts.join( ', ' ) ); } } // Helper to get options or defaults. return $.extend( {}, f.defaultBaseOptions, f.defaultOptions, options ); }, // Just like jQuery's serializeArray method, returns an array of objects with name and value. // but also includes the dom element (el) and is handles unchecked checkboxes if the option or data attribute are provided. serializeArray: function( _this, opts ) { var f; var elements; if ( null == opts ) { opts = {}; } f = $.serializeJSON; return _this.map( function() { elements = $.prop( this, 'elements' ); // Handle propHook "elements" to filter or add form elements. return elements ? $.makeArray( elements ) : this; } ).filter( function() { var $el = $( this ); var type = this.type; // Filter with the standard W3C rules for successful controls: http://www.w3.org/TR/html401/interact/forms.html#h-17.13.2. return this.name && // Must contain a name attribute. ! $el.is( ':disabled' ) && // Must not be disable (use .is(":disabled") so that fieldset[disabled] works). rsubmittable.test( this.nodeName ) && ! rsubmitterTypes.test( type ) && // only serialize submittable fields (and not buttons). (this.checked || ! rcheckableType.test( type ) || f.getCheckboxUncheckedValue( $el, opts ) != null); // skip unchecked checkboxes (unless using opts). } ).map( function( _i, el ) { var $el = $( this ); var val = $el.val(); var type = this.type; // "input", "select", "textarea", "checkbox", etc. if ( null == val ) { return null; } if ( rcheckableType.test( type ) && ! this.checked ) { val = f.getCheckboxUncheckedValue( $el, opts ); } if ( isArray( val ) ) { return $.map( val, function( val ) { return {name: el.name, value: val.replace( rCRLF, '\r\n' ), el: el}; } ); } return {name: el.name, value: val.replace( rCRLF, '\r\n' ), el: el}; } ).get(); }, getCheckboxUncheckedValue: function( $el, opts ) { var val = $el.attr( 'data-unchecked-value' ); if ( null == val ) { val = opts.checkboxUncheckedValue; } return val; }, // Parse value with type function. applyTypeFunc: function( name, strVal, type, el, typeFunctions ) { var typeFunc = typeFunctions[type]; if ( ! typeFunc ) { // quick feedback to user if there is a typo or missconfiguration. throw new Error( 'serializeJSON ERROR: Invalid type ' + type + ' found in input name \'' + name + '\', please use one of ' + objectKeys( typeFunctions ) .join( ', ' ) ); } return typeFunc( strVal, el ); }, // Splits a field name into the name and the type. Examples: // "foo" => ["foo", ""]. // "foo:boolean" => ["foo", "boolean"]. // "foo[bar]:null" => ["foo[bar]", "null"]. splitType: function( name ) { var parts = name.split( ':' ); var t; if ( parts.length > 1 ) { t = parts.pop(); return [parts.join( ':' ), t]; } else { return [name, '']; } }, // Check if this input should be skipped when it has a falsy value, // depending on the options to skip values by name or type, and the data-skip-falsy attribute. shouldSkipFalsy: function( name, nameSansType, type, el, opts ) { var skipFromDataAttr = $( el ).attr( 'data-skip-falsy' ); var optForFields; var optForTypes; if ( skipFromDataAttr != null ) { return skipFromDataAttr !== 'false'; // any value is true, except the string "false". } optForFields = opts.skipFalsyValuesForFields; if ( optForFields && (optForFields.indexOf( nameSansType ) !== -1 || optForFields.indexOf( name ) !== -1) ) { return true; } optForTypes = opts.skipFalsyValuesForTypes; return ! ! ( optForTypes && optForTypes.indexOf( type ) !== -1 ); }, // Split the input name in programmatically readable keys. // Examples: // "foo" => ["foo"] // "[foo]" => ["foo"] // "foo[inn][bar]" => ["foo", "inn", "bar"] // "foo[inn[bar]]" => ["foo", "inn", "bar"] // "foo[inn][arr][0]" => ["foo", "inn", "arr", "0"] // "arr[][val]" => ["arr", "", "val"]. splitInputNameIntoKeysArray: function( nameWithNoType ) { var keys = nameWithNoType.split( '[' ); // split string into array. keys = $.map( keys, function( key ) { return key.replace( /\]/g, '' ); } ); // Remove closing brackets. if ( keys[0] === '' ) { keys.shift(); } // Ensure no opening bracket ("[foo][inn]" should be same as "foo[inn]") return keys; }, // Set a value in an object or array, using multiple keys to set in a nested object or array. // This is the main function of the script, that allows serializeJSON to use nested keys. // Examples: // // deepSet(obj, ["foo"], v) // obj["foo"] = v // deepSet(obj, ["foo", "inn"], v) // obj["foo"]["inn"] = v // Create the inner obj["foo"] object, if needed // deepSet(obj, ["foo", "inn", "123"], v) // obj["foo"]["arr"]["123"] = v // // // deepSet(obj, ["0"], v) // obj["0"] = v // deepSet(arr, ["0"], v, {useIntKeysAsArrayIndex: true}) // arr[0] = v // deepSet(arr, [""], v) // arr.push(v) // deepSet(obj, ["arr", ""], v) // obj["arr"].push(v) // // arr = []; // deepSet(arr, ["", v] // arr => [v] // deepSet(arr, ["", "foo"], v) // arr => [v, {foo: v}] // deepSet(arr, ["", "bar"], v) // arr => [v, {foo: v, bar: v}] // deepSet(arr, ["", "bar"], v) // arr => [v, {foo: v, bar: v}, {bar: v}]. deepSet: function( o, keys, value, opts ) { if ( null == opts ) { opts = {}; } var f = $.serializeJSON; if ( isUndefined( o ) ) { throw new Error( 'ArgumentError: param \'o\' expected to be an object or array, found undefined' ); } if ( ! keys || 0 === keys.length ) { throw new Error( 'ArgumentError: param \'keys\' expected to be an array with least one element' ); } var key = keys[0]; // Only one key, then it's not a deepSet, just assign the value in the object or add it to the array. if ( 1 === keys.length ) { if ( key === '' ) { // Push values into an array (o must be an array). o.push( value ); } else { o[key] = value; // Keys can be object keys (strings) or array indexes (numbers). } return; } var nextKey = keys[1]; // Nested key. var tailKeys = keys.slice( 1 ); // List of all other nested keys (nextKey is first). if ( key === '' ) { // Push nested objects into an array (o must be an array). var lastIdx = o.length - 1; var lastVal = o[lastIdx]; // if the last value is an object or array, and the new key is not set yet. if ( isObject( lastVal ) && isUndefined( f.deepGet( lastVal, tailKeys ) ) ) { key = lastIdx; // then set the new value as a new attribute of the same object. } else { key = lastIdx + 1; // otherwise, add a new element in the array. } } if ( nextKey === '' ) { // "" is used to push values into the nested array "array[]". if ( isUndefined( o[key] ) || ! isArray( o[key] ) ) { o[key] = []; // define (or override) as array to push values. } } else { if ( opts.useIntKeysAsArrayIndex && isValidArrayIndex( nextKey ) ) { // if 1, 2, 3 ... then use an array, where nextKey is the index. if ( isUndefined( o[key] ) || ! isArray( o[key] ) ) { o[key] = []; // Define (or override) as array, to insert values using int keys as array indexes. } } else { // nextKey is going to be the nested object's attribute. if ( isUndefined( o[key] ) || ! isObject( o[key] ) ) { o[key] = {}; // Define (or override) as object, to set nested properties. } } } // Recursively set the inner object. f.deepSet( o[key], tailKeys, value, opts ); }, deepGet: function( o, keys ) { var f = $.serializeJSON; var tailKeys; if ( isUndefined( o ) || isUndefined( keys ) || keys.length === 0 || ( ! isObject( o ) && ! isArray( o ) ) ) { return o; } var key = keys[0]; if ( '' === key ) { // "" means next array index (used by deepSet) return undefined; } if ( 1 === keys.length ) { return o[key]; } tailKeys = keys.slice( 1 ); return f.deepGet( o[key], tailKeys ); } }; // Polyfill Object.keys to get option keys in IE<9. var objectKeys = function( obj ) { if ( Object.keys ) { return Object.keys( obj ); } else { var key, keys = []; for ( key in obj ) { keys.push( key ); } return keys; } }; var isObject = function( obj ) { return obj === Object( obj ); }; // true for Objects and Arrays. var isUndefined = function( obj ) { return obj === void 0; }; // safe check for undefined values. var isValidArrayIndex = function( val ) { return /^[0-9]+$/.test( String( val ) ); }; // 1,2,3,4 ... are valid array indexes. var isArray = Array.isArray || function( obj ) { return '[object Array]' === Object.prototype.toString.call( obj ); }; } ) );