--- fromJSON_v2_7_3.m	2021-12-28 16:27:21.035986776 +0100
+++ io-dev/inst/fromJSON.m	2021-12-28 13:56:02.049619958 +0100
@@ -16,42 +16,45 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {} {@var{obj} =} fromJSON (@var{str})
-## @end deftypefn
-## @deftypefn {} {@var{obj} =} fromJSON (@var{str}, @var{sarray})
+## @deftypefnx {} {@var{obj} =} fromJSON (@var{str}, @var{sarray})
+## Convert a JSON string into a native Octave object.
 ##
-## Convert a JSON string into a native Octave object.  It especially strives to convert
-## numerical JSON arrays into Octave vector, matrix or ND array.  Special
-## provisions are made to recognize +/-Inf, NaN and complex numbers, which
-## are conventionally not permited is JSON string.
+## fromJSON especially strives to convert numerical JSON arrays into Octave
+## vector, matrix or ND array.  Special provisions are made to recognize
+## +/-Inf, NaN and complex numbers, which are conventionally not permited in
+## JSON strings.
 ##
 ## Input arguments:
 ##
 ## @itemize
 ## @item
-## @var{str}, a JSON string.
+## @var{str} is a JSON string.
 ## @end item
 ##
 ## @item
-## @var{sarray}, (default TRUE) logical that  determines how JSON member arrays are parsed. 
-## Setting to FALSE is recommended for safer parsing of non-numerical, mixed-class or 
-## mixed-size arrays JSON payloads.
-##
+## @var{sarray}, (default TRUE) logical value that determines how JSON member
+## arrays are parsed.  Setting it to FALSE is recommended for safer parsing of
+## non-numerical, mixed-class or mixed-size arrays JSON payloads.
+##
+## Leave @var{sarray} set to TRUE for fast parsing of numerical JSON arrays and
+## objects.  Octave vectors, matrices, ND arrays and struct arrays are returned
+## as much as possible, otherwise returned as a combination of vectors/matrices
+## and cell arrays.
+## If, with fast parsing, output does not match expections, particularly if
+## @var{str} mainly comprises JSON objects/arrays with strings, set @var{sarray}
+## to FALSE.  All JSON member arrays are returned as (nested) Octave cell arrays.
 ## @end item
 ## @end itemize
 ##
 ## Output:
 ##
-## @var{obj} is a native Octave object.  JSON number, logical, array, and object strings are 
-## converted to Octave numbers, bools, vectors and structs respectively. Quoted or unrecognizable 
-## JSON fragments return as NaN.  
-##
-## Leave @var{sarray} to TRUE for fast parsing of numerical JSON arrays and objects.  
-## Octave vectors, matrixs, ND arrays and struct arrays are returned if possible, 
-## else some combination of vectors/matrix and cell array.    
-##
-## If, with fast parsing, output does not match expections, particularly if @var{str} is 
-## mainly JSON object/arrays with strings, set @var{sarray} to FALSE.   All JSON 
-## member arrays return as (nested) Octave cell arrays.
+## @itemize
+## @item
+## @var{obj} is a native Octave object.  JSON number, logical, array, and
+## object strings are converted to Octave numbers, logicals, vectors and
+## structs, respectively.  Quoted or unrecognizable JSON fragments are returned
+## as NaN values.
+## @end itemize
 ##
 ## Special numbers:
 ##
@@ -60,16 +63,17 @@
 ##
 ## @itemize
 ## @item
-## JSON number strings '+/-1e308' are rounded to +/-Inf.  
+## JSON number strings '+/-1e308' are rounded to +/-Inf.
 ## @end item
 ##
 ## @item
-## Unquoted JSON string 'null' is converted to NaN.  
+## Unquoted JSON string 'null' is converted to NaN.
 ## @end item
 ##
 ## @item
-## JSON object, or array thereof, with exclusive members "real" and "imag" (or "re" and "im")
-## will be converted to a Octave complex number, vector or matrix, respectively. 
+## JSON objects, or arrays thereof, with exclusive members "real" and "imag"
+## (or "re" and "im") will be converted to Octave complex numbers, vectors or
+## matrices, respectively.
 ##
 ## @w{    e.g. '@{"re":3,"im":1@}'     => 3 + 1i               }
 ## @w{         '[1,@{"re":3,"im":1@}]' => [ 1 + 0i, 3 + 1i ]   }
@@ -88,13 +92,13 @@
 ## 2020-10-27 Updated for Octave 7 compatibility (KMP)
 ## 2021-12-15 Bug fix: whitespace in array, colon in string (KMP)
 ##            Feature change: SARRAY == FALSE always returns cell array
-##            Feature change: Object with arrays now returns struct 
+##            Feature change: Object with arrays now returns struct
 ##                            with array, instead of struct array
 ##                            Array of objects still return struct array
 ## 2021-12-17 Bug fix: recursive scan of struct for deep complex number objects (KMP)
 ## 2021-12-18 Got rid of escape char evaluation in _to_string, this was mistakeningly
 ##              added to help with BIST (KMP)
-## 2021-12-21 Bug fix: prevent quoted-colon in JSON object key from confusing 
+## 2021-12-21 Bug fix: prevent quoted-colon in JSON object key from confusing
 ##                      _to_struct_ parser (KMP)
 ##            Bug fix: fix parsing error with invalid UTF-8 byte-combo (KMP)
 ##            Bug fix: ignore block tags within double-quoted strings  (KMP)
@@ -130,38 +134,38 @@
     endswitch
 
     remain = regexprep(remain,'^[\s,]*',''); %!!! keep this HERE, not in _get_block_
-    
+
 endfunction
-    
+
 ## gets block quoted-string/array/object block from string
-##   this will work with single-quoted strings, but only double-quoted strings are safe 
+##   this will work with single-quoted strings, but only double-quoted strings are safe
 function [btag, block, remain] = _get_block_ (str);
-    
+
     [open, btag] = regexp(str,'[^\s,]','once','start','match');
-    
+
     switch( btag );     % find ALL bracket tag (open/close) positions
-    
+
       case '[';  idx = [strfind(str,'[') -strfind(str,']')];    # strfind is 100x faster than regexp
       case '{';  idx = [strfind(str,'{') -strfind(str,'}')];
-      
+
       case {'"',"'"}; idx   = -strfind(str,btag); idx(1) *= -1; # all but first are closers
                       btag  = '"';      % regard single-quote as double-quote (lazy JSON)
-                      
+
       otherwise;  [block,remain] = strtok(str(open:end),',');
                   return;
     endswitch
-    
+
     idx( '\' == str([1 abs(idx(2:end))-1]) ) = [];      % exclude escaped-tags (e.g.'\[', '\{', '\"', etc)
-                
-    % filter out double-quoted (only) block tags            
+
+    % filter out double-quoted (only) block tags
     ( btag ~= '"' && (q = strfind(str,'"')  )           % find all double-quote marks
                   && (q = q(str(q-1) ~= '\')) > 1       % discard \", stop if only single " remains
                   && (idx = _bfilter_(idx, q))    );    % filter out quoted btags
-    
+
     if ~( numel(idx) > 1 && ( close=-idx(2) ) > 0 );    % unless simple (non-nested) block...
-    
+
         idx   = idx([~,i] = sort(abs(idx)));  % sort idx by abs(idx)
-        
+
         if( ( ci=find(0 == cumsum(sign(idx)), 1) )  );
           close = -idx(ci);
         else
@@ -169,7 +173,7 @@
           _warn_(btag,str);
         endif
     end
-    
+
     block  = str(  open+1 : close-1 );
     remain = str( close+1 : end     );
 
@@ -182,76 +186,76 @@
                       || strfind(str,'=') );             # no apparent assignment op
     if( ok );
       arr = regexprep( _rep_(str, Inf), ',(?=\s*\[)',';');  # JSON to Octave array syntax
-      
+
       if( strfind(str,'{') );   # JSON object
-          arr = [ _lazyJSON_ "; arr=_deep_complex_([" _rep_(arr, struct) "])" ]; 
+          arr = [ _lazyJSON_ "; arr=_deep_complex_([" _rep_(arr, struct) "])" ];
       else                      # JSON numerical? array
           arr = [ "arr=[" arr "]" ];
       endif
-      
+
       eval([ arr "; ok = isnumeric(arr) || isstruct(arr);" ], "ok=false;");
-      
+
     endif
 
-    if( ~ok );   # this can be slow, avoid getting here if possible    
+    if( ~ok );   # this can be slow, avoid getting here if possible
 
       arr = {};
-      
+
       while( str );  # grind thru string, one array element at a time
           [arr{end+1} str] = _fromjson_(str,SARRAY);
       endwhile;
-      
+
       if( SARRAY );
           switch numel(arr);
-            case 0;     arr = []; 
+            case 0;     arr = [];
             case 1;     arr = arr{1};
             otherwise;  arr = _ndarray_(arr);
           endswitch
       endif
 
     endif
-  
+
 endfunction
 
 function [obj] = _to_struct_ ( str, SARRAY );
 
     obj = struct();
-    
+
     # we're making this harder than needed in order to permit lazy JSON
     # i.e. unquoted and single quote keys (but! start/end quote chars must match)
-    
+
     while( ( q=regexp(str, '[^\s,:]', 'once','match') )       # detect key quote-char or empty str
        &&  ( m=regexp(str, _qrgx_(q), 'once','names') ).k );  # get key,val or fail
 
       [obj.(m.k) str] = _fromjson_(m.v, SARRAY);
 
-    endwhile      
+    endwhile
 
-    regexp(str,'[^\s]','once') && _warn_('}', str); 
+    regexp(str,'[^\s]','once') && _warn_('}', str);
     obj = _complex_( obj );    % _deep_complex_ not necessary here
-    
+
 endfunction
 
 function [str] = _to_string_ ( str, SARRAY );
-  
+
     if( SARRAY && (numel(str) > 2 && str(1:2) == '@') );
         try    str = str2func(str(2:end));
-        catch  _warn_('@', str); 
+        catch  _warn_('@', str);
         end_try_catch;
     endif
-    
+
 endfunction
 
 function [num] = _to_number_( str, SARRAY );
-  
+
     if( strfind(str,'=') );   % guard against assignment expr
         num = 'error()';
     else
         num = ['num=[' _rep_(str,Inf) '];'];
     endif
-    
+
     eval(num, ['_warn_("invalid frag",str); num=NaN;']);
-    
+
 endfunction
 
 %========================= helpers =======================
@@ -261,13 +265,13 @@
 
   qo = q(1:2:end-1)'; % open quote (ignore unclosed quote)
   qc = q(2:2:end)';   % close quote
-  
+
   ai = abs(idx);
   idx( any(qo < ai & ai < qc,1) ) = [];  % purge quoted block tags
-  
+
 endfunction
-  
-  
+
+
 function [str] = _rep_ ( str, arg );
 
   if isstruct(arg);
@@ -284,7 +288,7 @@
 endfunction
 
 ## try to make ND array (either mat or cell)
-function [c] = _ndarray_ ( c );  
+function [c] = _ndarray_ ( c );
 
   sz = size(e = c{1}); t = class(e);
 
@@ -313,9 +317,9 @@
 
   if( isstruct(s) && isstruct( s=_complex_(s) ) );
      vals = cellfun(@_deep_complex_, struct2cell(s), 'uniformoutput', false);
-     s    = cell2struct(vals, __fieldnames__(s));  
+     s    = cell2struct(vals, __fieldnames__(s));
   endif
-  
+
 endfunction
 
 ## convert complex number struct to complex number
@@ -326,31 +330,31 @@
   &&  isnumeric( re=[s.(k{1})] )
   &&  isnumeric( im=[s.(k{2})] )
   &&  size_equal(re,im) );
-    
+
         s = reshape( complex(re,im), ifelse(isscalar(s), size(re), size(s)) );
-        
+
   endif
-  
+
 endfunction
 
 ## for max conversion speeed, gaurd against common lazy JSON (unquoted keys)
 function [str] = _lazyJSON_ ( );
-  
+
   str = 'x="x";y="y";z="z";real=re="re";imag=im="im";r="r";rho="rho";theta="theta";phi="phi";';
-  
+
 endfunction
 
 ## compute regexp pattern for JSON object key (quoted or unquoted)
 function [rgx] = _qrgx_(q);
-  
+
   sum(q=="\"'") || (q='');
   rgx = ['[\s,]*' q '(?<k>.+?)' q '\s*:\s*(?<v>[^\s].*)' ];
-  
+
 endfunction
 
 
 function [out] = _warn_ ( msg, frag='' );
-  
+
   if( numel(msg) == 1 );
     switch(msg);
        case '{'; msg = "unclosed object";
@@ -361,11 +365,11 @@
        case '@'; msg = "invalid inline func string";
      endswitch
   endif
-  
+
   frag && ( frag=["`" frag "`"] );
   numel(frag)>40 && (frag = [frag(1:27) ' ... ' frag(end-27:end)]);
   out = warning("fromJSON: %s %s\n",msg,frag);
-  
+
 endfunction
 
 
@@ -378,7 +382,7 @@
 %!warning <invalid SARRAY> fromJSON('',struct);
 %!
 
-%!test	##	invalid input validation 
+%!test	##	invalid input validation
 %! bad = {4,{},@sin,struct(),'',false,0,[1,2,3]};
 %! assert(fromJSON(4),      []);
 %! assert(fromJSON({}),     []);
@@ -509,7 +513,7 @@
 %!         {{1 2 3 "a"},[2 3 4 4]})
 
 %!test	##	mixed-class array
-%! assert( fromJSON('[["a",2,3],[4,"b",5]]', true), 
+%! assert( fromJSON('[["a",2,3],[4,"b",5]]', true),
 %!         {'a' 2 3; 4 'b' 5});
 
 %!test	##	mismatch nested array, safe parsing to cell array
@@ -517,7 +521,7 @@
 %!         {{1 2 3 4 5},{1 2}})
 
 %!test	##	mixed-class array, safe parsing to cell array
-%! assert( fromJSON('[["a",2,3],[4,"b",5]]', false), 
+%! assert( fromJSON('[["a",2,3],[4,"b",5]]', false),
 %!         {{'a' 2 3},{4 'b' 5}} );
 
 %!test	##	more N numerical ND array
@@ -595,19 +599,19 @@
 %!warning <unclosed>    assert(fromJSON('{a:3,b:4'),struct("a",3,"b",4));
 
 %!test	##	string with colons (guards against JSON object false postive)
-%! assert( fromJSON('["2012-11-12T10:35:32Z","2012-11-13T08:35:12Z"]'), 
+%! assert( fromJSON('["2012-11-12T10:35:32Z","2012-11-13T08:35:12Z"]'),
 %!        {"2012-11-12T10:35:32Z", "2012-11-13T08:35:12Z"});
 
 %!test	##	string with {} (guards against JSON object false postive)
-%! assert( fromJSON('["some text {hello:3}","more text \"{hello:3}\""]'), 
+%! assert( fromJSON('["some text {hello:3}","more text \"{hello:3}\""]'),
 %!        {'some text {hello:3}', 'more text \"{hello:3}\"'});
 
 %!test	##	lazy JSON object (unquoted and single-quote keys)
-%! assert( fromJSON("{a:3,'b':5}",true), 
+%! assert( fromJSON("{a:3,'b':5}",true),
 %!         struct("a",3,"b",5))
 
 %!test	##	bad (but passable) lazy JSON object, unquoted-key with quote char at end
-%! assert( fromJSON("{a':3,b\":5}",true), 
+%! assert( fromJSON("{a':3,b\":5}",true),
 %!         struct("a'",3,'b"',5))
 
 %!test	## bad (failing) JSON object (mismatched or unclosed quoted-keys)
@@ -629,19 +633,19 @@
 %!         struct("a",3,"b",5))
 
 %!test	##	object with object
-%! assert( fromJSON('{a:{b:2}}', true), 
+%! assert( fromJSON('{a:{b:2}}', true),
 %!         struct('a',struct('b',2)));
 
 %!test	##	object with object with object
-%! assert( fromJSON('{a:{b:{c:3,d:4},e:5}}', true), 
+%! assert( fromJSON('{a:{b:{c:3,d:4},e:5}}', true),
 %!         struct('a',struct('b',struct('c',3,'d',4),'e',5)));
 
 %!test	##	object with array to struct with array
-%! assert( fromJSON('{a:[1,2,3,4]}', true), 
+%! assert( fromJSON('{a:[1,2,3,4]}', true),
 %!         struct('a',[1 2 3 4]));
 
 %!test	##	object with array to struct with cell array
-%! assert( fromJSON('{a:[1,2,3,4]}', false), 
+%! assert( fromJSON('{a:[1,2,3,4]}', false),
 %!         struct('a',{{1 2 3 4}}));
 
 %!test	##	array of objects to struct array
@@ -653,63 +657,63 @@
 %!         num2cell(struct('a',{1 2 3 4})));
 
 %!test	##	object with 2x2 array to struct with 2x2 array
-%! assert( fromJSON('{a:[[1,3],[2,4]]}', true), 
+%! assert( fromJSON('{a:[[1,3],[2,4]]}', true),
 %!         struct('a',[1 3;2 4]));
 
 %!test	##	object with 2x2 array to struct with cell array
-%! assert( fromJSON('{a:[[1,3],[2,4]]}', false), 
+%! assert( fromJSON('{a:[[1,3],[2,4]]}', false),
 %!         struct('a',{{{1,3},{2,4}}}));
 
 %!test	##	2x2 array of object to struct array
-%! assert( fromJSON('[[{a:1},{a:2}],[{a:3},{a:4}]]',true), 
+%! assert( fromJSON('[[{a:1},{a:2}],[{a:3},{a:4}]]',true),
 %!         struct('a',{1 2;3 4}));
 
 %!test	##	2x2 array of object to cell array
-%! assert( fromJSON('[[{a:1},{a:2}],[{a:3},{a:4}]]',false), 
+%! assert( fromJSON('[[{a:1},{a:2}],[{a:3},{a:4}]]',false),
 %!         { num2cell(struct('a',{1 2})), num2cell(struct('a',{3 4}))} );
 
 %!test	##	**nested** object with array to struct array
-%! assert( fromJSON('{"a":{"b":[1,2,3]}}',true ), 
+%! assert( fromJSON('{"a":{"b":[1,2,3]}}',true ),
 %!         struct("a",num2cell(struct("b",[1,2,3]))))  % <== struct array
 
 %!test	##	**nested** object with array to cell array
-%! assert( fromJSON('{"a":{"b":[1,2,3]}}',false), 
+%! assert( fromJSON('{"a":{"b":[1,2,3]}}',false),
 %!         struct("a",struct("b",{{1,2,3}})))          % <== struct with array b
 
 %!test	##	object with mixed-size arrays (will not honor SARRAY=true)
-%! assert( fromJSON('{"a":[1,2],"b":[3,4,5]}',true), 
+%! assert( fromJSON('{"a":[1,2],"b":[3,4,5]}',true),
 %!         struct("a",[1,2],"b",[3,4,5]))
 
 %!test	##	object with number and string (guard against turing string into char array)
-%! assert( fromJSON('{"a":1,"b":"hello"}',true), 
+%! assert( fromJSON('{"a":1,"b":"hello"}',true),
 %!         struct("a",1,"b","hello"))
 
 %!test	##	object with empty array  (gaurd against returning empty struct array)
-%! assert( fromJSON('{"a":3,"b":[]}',true), 
+%! assert( fromJSON('{"a":3,"b":[]}',true),
 %!         struct("a",3,"b",[]))
 
 %!test	##	object with colon value
-%! assert( fromJSON('{"time": "10:35:00"}'), 
+%! assert( fromJSON('{"time": "10:35:00"}'),
 %!         struct("time", "10:35:00"));
 
 %!test	##	object with colon key
-%! assert( fromJSON('{"ti:me": "10:35:00", ":tricky:" : 4}'), 
+%! assert( fromJSON('{"ti:me": "10:35:00", ":tricky:" : 4}'),
 %!         struct("ti:me", "10:35:00",":tricky:",4));
 
 %!test	##	array of structure with value with colons
-%! assert( fromJSON('[{"time": "10:35"},{"time": "10:54"}]', true), 
+%! assert( fromJSON('[{"time": "10:35"},{"time": "10:54"}]', true),
 %!         struct("time", {"10:35","10:54"}));
 
 %!test	##	array of structure with value with  keys
-%! assert( fromJSON('[{"ti:me": "10:35"},{"ti:me": "10:54"}]', true), 
+%! assert( fromJSON('[{"ti:me": "10:35"},{"ti:me": "10:54"}]', true),
 %!         struct("ti:me", {"10:35","10:54"}));
 
 %!test	##	incomplete struct
-%!warning <malformed> assert( fromJSON('{a:3,b   }', true), 
+%!warning <malformed> assert( fromJSON('{a:3,b   }', true),
 %!                            struct('a',3));
 
 %!test	##	incomplete struct
-%!warning <malformed> assert( fromJSON('{a:3,b:   }', true), 
+%!warning <malformed> assert( fromJSON('{a:3,b:   }', true),
 %!                            struct('a',3));
 
 
@@ -755,7 +759,7 @@
 %! assert( fromJSON('{"re": "hello","im":5}'),
 %!         struct('re',"hello",'im',5));
 
-%!test	##	complex number in reverse order 
+%!test	##	complex number in reverse order
 %! assert( fromJSON('{im:3,re:5}'), 5+3i);
 
 %!test	##	complex with excess members
@@ -766,7 +770,7 @@
 %!         struct('real',3,'im',5));
 
 %!test	##	apparent complex number object with extra member
-%! assert( fromJSON('{re:3,im:5,t:3}'), 
+%! assert( fromJSON('{re:3,im:5,t:3}'),
 %!         struct('re',3,'im',5,'t',3));
 
 %!test	##	array of complex number object  to scalar array of complex number
@@ -774,31 +778,31 @@
 %!         [4+6i,5+7i] );
 
 %!test	##	array of complex number object  to cell array of complex number
-%! assert( fromJSON('[{re:4,im:6},{re:5,im:7}]}',false), 
+%! assert( fromJSON('[{re:4,im:6},{re:5,im:7}]}',false),
 %!         {4+6i,5+7i} );
 
 %!test	##	complex number object with array to scalar array of complex number
-%! assert( fromJSON('{re:[4,5],im:[6,7]}',true), 
+%! assert( fromJSON('{re:[4,5],im:[6,7]}',true),
 %!         [4+6i,5+7i] );
 
 %!test	##	complex number object with array to struct with cell array
-%! assert( fromJSON('{re:[4,5],im:[6,7]}',false), 
+%! assert( fromJSON('{re:[4,5],im:[6,7]}',false),
 %!         struct("re",{{4,5}},"im",{{6,7}}));
 
 %!test	##	complex number object with mismatch array sizes
-%! assert( fromJSON('{re:[4,5],im:[6]}',true), 
+%! assert( fromJSON('{re:[4,5],im:[6]}',true),
 %!         struct('re',[4,5],'im',6));
 
 %!test	##	complex number object with mismatch array sizes
-%! assert( fromJSON('{re:[4,5],im:[6]}',true), 
+%! assert( fromJSON('{re:[4,5],im:[6]}',true),
 %!         struct('re',[4,5],'im',6));
 
 %!test	##	bogus complex number object with mixed classed array
-%! assert( fromJSON('{re:[4,5],im:[6,"a"]}',true), 
+%! assert( fromJSON('{re:[4,5],im:[6,"a"]}',true),
 %!         struct('re',[4,5],'im',{{6,'a'}}));
 
-%!test	##	array of bogus complex number object 
-%! assert( fromJSON('[{re:4,im:6},{re:5,im:"a"}]',true), 
+%!test	##	array of bogus complex number object
+%! assert( fromJSON('[{re:4,im:6},{re:5,im:"a"}]',true),
 %!         {4+6i,struct('re',5,'im','a')});
 
 %!test	##	complex number object with matrix
@@ -818,21 +822,21 @@
 %!        reshape( (1+i)*[1 2 1 2 3 4 3 4], 2,2,2));
 
 %!test	##	array of objects with complex number member
-%! assert( fromJSON('[{"a": {re:4, im:6}},{"a": {re:5,im:7}}]'), 
+%! assert( fromJSON('[{"a": {re:4, im:6}},{"a": {re:5,im:7}}]'),
 %!         struct('a',{4+6i,5+7i}) );
 
 %!test	##	ND array objects with complex number members
 %! obj = struct('a',{4+6i,5+7i;4+6i,5+7i});
 %! obj(:,:,2) = obj;
-%! assert( fromJSON('[[[{"a": {re:4, im:6}},{"a": {re:5,im:7}}],[{"a": {re:4, im:6}},{"a": {re:5,im:7}}]],[[{"a": {re:4, im:6}},{"a": {re:5,im:7}}],[{"a": {re:4, im:6}},{"a": {re:5,im:7}}]]]'), 
+%! assert( fromJSON('[[[{"a": {re:4, im:6}},{"a": {re:5,im:7}}],[{"a": {re:4, im:6}},{"a": {re:5,im:7}}]],[[{"a": {re:4, im:6}},{"a": {re:5,im:7}}],[{"a": {re:4, im:6}},{"a": {re:5,im:7}}]]]'),
 %!         obj );
 
 %!test	##	array of objects with DEEP complex number member
-%! assert( fromJSON('[{"a": {"b": {re:4, im:6}}},{"a": {re:5,im:7}}]'), 
+%! assert( fromJSON('[{"a": {"b": {re:4, im:6}}},{"a": {re:5,im:7}}]'),
 %!         [struct('a',struct('b',4+6i)),struct('a',5+7i)] );
 
 %!test	##	mismatch array (to cell array) of objects with DEEP complex number member
-%! assert( fromJSON('[{"a":{"b":{re:4, im:6}}}, {"c":{"d":{"e":{re:5,im:7}}}}]'), 
+%! assert( fromJSON('[{"a":{"b":{re:4, im:6}}}, {"c":{"d":{"e":{re:5,im:7}}}}]'),
 %!         {struct('a',struct('b',4+6i)),struct('c',struct('d',struct('e',5+7i)))} );
 
 %!test  # array of complex number in algebraic format (extracircular parsing)
@@ -899,7 +903,7 @@
 %! assert(obj,{struct('a',"tes, {}: [ ] t"), 'lkj{} sdf',NaN})
 
 %!test	##	beautified JSON object (extraneous whitespace/newline)
-%! assert( fromJSON("\n  {  \n\t\"a\"\t\n\n\n  :\t\n\n\n  3\n\t} \n \n"), 
+%! assert( fromJSON("\n  {  \n\t\"a\"\t\n\n\n  :\t\n\n\n  3\n\t} \n \n"),
 %!         struct("a",3))
 
 %!test	##	beautified JSON string with array (test parse with extraneous whitespace)
@@ -911,7 +915,7 @@
 %!                 '_status', 'synced'
 %!           )
 %!       );
-%!                      
+%!
 %! assert( fromJSON(pretty_json),obj,true);
 
 %!test	##	garbage string with whitespace
@@ -930,7 +934,7 @@
 %!warning <invalid> assert( fromJSON('[1,{"a":gar{}bage}]'),{1,struct('a',NaN)})
 
 %!test  ## looks like fn, but is UNQUOTED string
-%!warning <invalid>   assert(fromJSON('@@nofunc'),NaN); 
+%!warning <invalid>   assert(fromJSON('@@nofunc'),NaN);
 
 ########## complex (non-numerical) JSON BIST ################
 
@@ -945,12 +949,12 @@
 %! f1 = num2cell(struct ('id', {0 1 2}, 'name', {'Collins' 'Hays' 'Griffin'}));
 %! f2 = num2cell(struct ('id', {0 1 2}, 'name', {'Osborn' 'Mcdowell' 'Jewel'}));
 %! f3 = num2cell(struct ('id', {0 1 2}, 'name', {'Socorro' 'Darla' 'Leanne'}));
-%!   
+%!
 %! keys = {'x_id','index','guid','latitude','longitude','friends'};
 %! val1 = {'5ee28980fc9ab3', 0, 'b229d1de-f94a', -17.124067, -61.161831, f1};
 %! val2 = {'5ee28980dd7250', 1, '39cee338-01fb', 13.205994,  -37.276231, f2};
 %! val3 = {'5ee289802422ac', 2, '3db8d55a-663e', -35.453456,  14.080287, f3};
-%! 
+%!
 %! exp = cell2struct({val1{:};val2{:};val3{:}}',keys)';
 %! fromJSON(json);     # this may be confusing mix of array and non-cell array, but NO fail allowed
 %! assert (fromJSON(json, false), num2cell(exp));
@@ -959,7 +963,7 @@
 %!test  ## from firefox active-stream.discovery_stream.json (UGH!  url link as object key)
 %!
 %! json = '[{"feeds":{"https://getpocket.cdn.mozilla.net/v3/firefox/global-recs?version=3&consumer_key=$apiKey&locale_lang=$locale&region=$region&count=30":{"lastUpdated":1640020188467,"data":{"settings":{"domainAffinityParameterSets":{"default":{"recencyFactor":0.5,"frequencyFactor":0.5,"combinedDomainFactor":0.5,"perfectFrequencyVisits":10,"perfectCombinedDomainScore":2,"multiDomainBoost":0,"itemScoreFactor":1}}}}}}}]';
-%! exp  = struct("feeds", 
+%! exp  = struct("feeds",
 %!          struct('https://getpocket.cdn.mozilla.net/v3/firefox/global-recs?version=3&consumer_key=$apiKey&locale_lang=$locale&region=$region&count=30',
 %!             struct("lastUpdated",1640020188467,
 %!                    "data",
