User:PerfektesChaos/js/WikiSyntaxTextMod/dU.js

/// PerfektesChaos/js/WikiSyntaxTextMod/dU.js /// 2022-01-30 PerfektesChaos@de.wikipedia /// Fingerprint: #0#0# /// @license: CC-by-sa/4.0 GPLv3 /// // Utilities (non-Wiki) for WikiSyntaxTextMod /* global mw:true, mediaWiki:false                                    */ /* jshint forin:false, bitwise:true, curly:true, eqeqeq:true, latedef:true, laxbreak:true, nocomma:true, strict:true, undef:true, unused:true          */

if ( typeof mediaWiki !==  "object" ) {   // disconnected mw =  { libs:   { WikiSyntaxTextMod:  { } },           log:    function  {"use strict";} }; } ( function ( mw ) {  "use strict";   var version  =  -7.59,       sign     =  "WikiSyntaxTextMod",       sub      =  "U",       rls, self, WSTM;   if ( typeof mw.loader  ===  "object" ) {      rls   =  { };      self  =  "user:PerfektesChaos/" + sign + "/" + sub;      rls[ self ] = "loading";      mw.loader.state( rls );   }   if ( typeof mw.libs[ sign ]  !==  "object" ) {   // isolated      mw.libs[ sign ]  =  { };   }   WSTM  =  mw.libs[ sign ];   if ( typeof WSTM.util  !==  "object" ) {      WSTM.util  =  { };   }   WSTM.util.vsn   =  version;   WSTM.util.self  =  self;   if ( typeof WSTM.bb  !==  "object" ) {      WSTM.bb  =  { };   }   if ( typeof WSTM.debugging  !==  "object" ) {      WSTM.debugging  =  { };   } } ( mw ) );

/* Requires: JavaScript 1.3 (Object.toSource          String.charCodeAt String.fromCharCode String.replace) */

//---

mw.libs.WikiSyntaxTextMod.bb.utilU =  function ( WSTM ) { // General Utilities // 2021-10-26 PerfektesChaos@de.wikipedia "use strict";

if ( typeof WSTM.util.fiatObjects !==  "function" ) { WSTM.util.fiatObjects =  function ( adult, activate, assign ) { // Ensure existence of at least empty object // Precondition: //   adult     -- parent object //   activate  -- String with name of child object //   assign    -- optional object with initial definition //                if containing object components, //                they will be asserted as well // Postcondition: //   adult has been extended // Uses: //   .util.fiatObjects  -- recursive // 2012-05-18 PerfektesChaos@de.wikipedia var elt, obj, s;        if ( typeof adult[ activate ]  !==  "object" ) { adult[ activate ] =  ( assign  ?  assign  :  { } ); }        if ( assign ) { obj =  adult[ activate ]; for ( s in assign ) { elt =  assign[ s ]; if ( typeof elt ===  "object" ) { WSTM.util.fiatObjects( obj, s, elt ); }           }  //  for s in assign }     };   // .util.fiatObjects }

WSTM.util.fiatObjects( WSTM, "debugging",  { loud: false } ); WSTM.util.fiatObjects( WSTM, "util",                          { code:      { },                            date:      { },                            dnb:       { },                            gtin:      { },                            isbn:      { },                            issn:      { },                            re:        { },                            regexp:    { },                            translate: { }                          } );

WSTM.util.isArray =  function ( anything ) { // Is anything an array? // Precondition: //   anything  -- thing to be tested // Postcondition: //   Returns true, if Array // 2012-02-01 PerfektesChaos@de.wikipedia var r =  ( anything !== null ); if ( r ) { r =  ( typeof anything  === "object" ); if ( r ) { r =  ( anything.constructor.toString.substr( 0, 17 )                                 .indexOf( "function Array" )  >=  0 ); }     }   // non-null return r;   };   // .util.isArray

WSTM.util.isElement =  function ( array, access ) { // Is anything element of an array? // Precondition: //   array   -- Array to be searched; may be empty or false //   access  -- thing to be found // Postcondition: //   Returns true, if access is element of array // 2016-01-21 PerfektesChaos@de.wikipedia var r =  false, i;     if ( typeof array  ===  "object"          &&  array          &&  typeof array.length === "number" ) { for ( i = 0; i < array.length;  i++ ) { if ( array[ i ] === access ) { r =  true; break;  // for i            } }  // for i      } return r;   };   // .util.isElement

WSTM.util.isEscValid =  function (attempt) { // Are bad percent escapings in attempt? // Precondition: //   attempt  -- string with possible percent escapings // Postcondition: //   Returns  string with violating sequence //            false if correct // Uses: //   >< .util.re.hex2 // 2021-10-26 PerfektesChaos@de.wikipedia var i =  0, r =  false, s;     do {   // while i >= 0 i = attempt.indexOf( "%", i ); if ( i >= 0 ) { s = attempt.substr( i + 1, 2 ); if ( s.length === 2 ) { if ( s === "00" ) { r =  "%00"; break;  // while i >= 0 }              if ( typeof WSTM.util.re.hex2  !==  "object" ) { WSTM.util.re.hex2 = new RegExp( "[0-9A-Fa-f][0-9A-Fa-f]" ); }              if ( WSTM.util.re.hex2.test( s ) ) { i = i + 2; } else { r =  "%" + s;                  break;   // while i >= 0 }           } else { r =  "%" + s;               break;   // while i >= 0 }        }      } while ( i >= 0 ); return r;   };   // .util.isEscValid

WSTM.util.isO_639_1 =  function ( ask ) { // Is string a valid ISO 639-1 language code? // Precondition: //   ask  -- lowercase 2 letter query string // Postcondition: //   Returns  true  iff  ask is a valid ISO 639-1 language code // 2016-09-14 PerfektesChaos@de.wikipedia var s =   "|aa|ab|ae|af|ak|am|an|ar|as|av|ay|az" + "|ba|be|bg|bh|bi|bm|bn|bo|br|bs" + "|ca|ce|ch|co|cr|cs|cu|cv|cy" + "|da|de|dv|dz" + "|ee|el|en|eo|es|et|eu" + "|fa|ff|fi|fj|fo|fr|fy" + "|ga|gd|gl|gn|gu|gv" + "|ha|he|hi|ho|hr|ht|hu|hy|hz" + "|ia|id|ie|ig|ii|ik|io|is|it|iu" + "|ja|jv" + "|ka|kg|kj|kk|kl|km|kn|ko|kr|ks|ku|kv|kw|ky" + "|la|lb|lg|li|ln|lo|lt|lv" + "|mg|mh|mi|mk|ml|mn|mr|ms|mt|my" + "|na|nb|nd|ne|ng|nl|nn|no|nr|nv" + "|oc|oj|om|or|os" + "|pa|pi|pl|ps|pt" + "|qu" + "|rm|rn|ro|ru|rw" + "|sa|sc|sd|se|sg|sh|si|sk|sl|sm|sn" + "|so|sq|sr|ss|st|su|sv|sw" + "|ta|te|tg|th|ti|tk|tl|tn|to|tr|ts|tt|tw|ty" + "|ug|uk|ur|uz" + "|ve|vi|vo" + "|wa|wo" + "|xh" + "|yi|yo" + "|za|zh|zu|"; return ( s.indexOf( ask ) > 0 ); };  // .util.isO_639_1

WSTM.util.isURL =  function ( attempt, allow, any ) { // Is attempt a valid URL? // Precondition: //   attempt  -- string with trimmed URL //   allow    -- permit other schemes than http https ftp //   any      -- permit invalid www domains // Postcondition: //   Returns  string with error hint //            false if correct // Uses: //   >< .util.re.whitespace //    < .util.re.nonAlNum2 //    < .util.re.all0alpha //    < .util.re.alphaNum //    < .util.re.nonAlNumBeg //    < .util.re.nonAlNumEnd //    < .util.re.urlPort //    < .util.re.urlProtocol //    < .util.re.urlPunycode //   .str.isASCII //   .lang.fetch // 2021-10-26 PerfektesChaos@de.wikipedia var r =  false, got, i, n, parts, s, scheme; if ( typeof this.re.whitespace !==  "object" ) { this.re.nonAlNum2   =  new RegExp( "[^a-z0-9][^a-z0-9]" ); this.re.all0alpha   =  new RegExp( "^[^a-z]+$" ); this.re.alphaNum    =  new RegExp( "[a-z0-9]+" ); this.re.nonAlNumBeg =  new RegExp( "^[^a-z0-9]" ); this.re.nonAlNumEnd =  new RegExp( "[^a-z0-9]$" ); this.re.whitespace  =  new RegExp( "\\S\\s+\\S" ); this.re.urlPort     =  new RegExp( "^(.+):[0-9]+$" ); this.re.urlProtocol =  new RegExp( "^(?:(https?|s?ftp):)?" +                                             "//.",                                             "i" ); this.re.urlPunycode =  new RegExp( "^xn--[a-z0-9]+" +                                             "(-[a-z0-9]+)?$",                                             "i" ); }     if ( this.re.whitespace.test( attempt ) ) { r =  "whitespace"; } else if ( allow ) { // TODO  mailto: } else { got =  this.re.urlProtocol.exec( attempt ); if (got) { scheme =  got[ 1 ]; if (scheme) { scheme =  scheme.toLowerCase; } else { scheme =  "http"; }           s  =  attempt.substr( got[ 0 ].length - 1 ); i =  s.indexOf( "/" ); if (i > 0) { s =  s.substr( 0, i ); }        } else { r =  "scheme:resource"; }     }      if ( s   &&   s.indexOf( ":" )  >  0           &&   "http https ftp".indexOf( scheme ) >= 0 ) { got =  this.re.urlPort.exec( s ); if (got) { s =  got[ 1 ]; } else { r =  "port"; s =  false; }     }      if ( s  &&  ! any ) { s     =  s.toLowerCase; parts =  s.split( "." ); n     =  parts.length; if ( n > 1 ) { for ( i = 0; i < n;  i++ ) { s =  parts[ i ]; if ( ! this.re.alphaNum.test( s ) ) { if ( WSTM.str.isASCII( s ) ) { if ( s.substr( 0, 4 ) ===  "xn--" ) { if ( ! this.re.urlPunycode.test( s ) ) { r =  "Punycode: " + s;                        } } else if ( i ===  n - 1                                 &&  this.re.all0alpha.test( s ) ) { r =  "TLD: ." + s;                    } else if ( this.re.nonAlNumBeg.test( s )   ||                                 this.re.nonAlNumEnd.test( s ) ) { r =  "." + s + "."; break;  // for i                     } else if (  this.re.nonAlNum2.test( s ) ) { r =  "." + s + "."; break;  // for i                     } } else if (i ===  n - 1) { if ( ! WSTM.lang.fetch( "TLD.IDN" ).test( s ) ) { r =  "TLD (IDN): ." + s;                    } }              }            }   // for i         } else { r =  "TLD-"; }     }      return  r;   };   // .util.isURL

WSTM.util.roman2int =  function ( attempt ) { // What does this roman number mean? // Precondition: //   attempt  -- string with trimmed roman number // Postcondition: //   Returns  string with original code or digits // Uses: //   >< .util.romanDigits // 2019-08-20 PerfektesChaos@de.wikipedia var s =  attempt.toUpperCase, d, i, j, k, l, r;     if ( typeof this.romanDigits  !==  "object" ) { this.romanDigits =  { "I": 1, "V": 5, "X": 10, "L": 50, "C": 100, "D": 500, "M": 1000 }; }     for ( i = 0;  i < s.length;  i++ ) { k =  this.romanDigits[ s.charAt( i ) ]; if ( k ) { d =  d  ||  [ ]; d.push( k ); } else { d =  false; break;  // for i         } }  // for i      if ( d ) { r =  0; j =  0; l =  true; for ( i = d.length - 1; i >= 0;  i-- ) { k =  d[ i ]; if ( k > j ) { r =  r + k;               l  =  true; } else if ( k < j ) { r =  r - k;               l  =  false; } else if ( l ) { r =  r + k;            } else { r =  r - k;            } j =  k;         }   // for i-- r =  r + ""; }     return  r  ||  attempt; };  // .util.roman2int

};  // .bb.utilU mw.libs.WikiSyntaxTextMod.bb.utilU( mw.libs.WikiSyntaxTextMod ); delete mw.libs.WikiSyntaxTextMod.bb.utilU;

//---

mw.libs.WikiSyntaxTextMod.bb.dating =  function ( WSTM ) { // Date and time analysis, error message // Public: //   .util.date.fetch //   .util.date.format // 2019-11-29 PerfektesChaos@de.wikipedia "use strict";

WSTM.util.fiatObjects( WSTM.util, "date",                          { domax: [ false, 31, 29, 31, 30, 31, 30,                                            31, 31, 30, 31, 30, 31 ],                            units: [ "era",                                     "year",                                     "month",                                     "dom",                                     "hour",                                     "minute",                                     "second",                                     "msec",                                     "mysec" ],                            words: { doweek: [ "Sunday",                                               "Monday",                                               "Tuesday",                                               "Wednesday",                                               "Thursday",                                               "Friday", "Saturday" ], dow:  { n: 3 }, month: [ false, "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ], mon:  { n: 3 } }, re:   { } } );

WSTM.util.date.fetch =  function ( attempt, ahead, alien ) { // Retrieve date // Precondition: //   attempt  -- string with presumable date and time //   ahead    -- true: future moment permitted //   alien    -- string with other language code than en, or false // Postcondition: //   Returns object of components, or false if not ISO or future // Uses: //   >< .util.date.re.* //   .lang.l      //    .str.trim //   .util.date.formal // 2019-11-29 PerfektesChaos@de.wikipedia var s =  WSTM.str.trim(attempt), got, o, r;     if ( typeof this.re.yyyy  !==  "object" ) { this.re.dd   =  new RegExp( "^-([0-3]?[0-9])([T ].*)?$" ); this.re.hh   =  new RegExp( "^([0-2][0-9])(:.*)?$" ); this.re.min  =  new RegExp( "^:([0-5][0-9])(:.*)?$" ); this.re.mon  =  new RegExp( "^-([01]?[0-9])(-.+)?$" ); this.re.ss   =  new RegExp( "^:([0-6][0-9])([. ].*)?$" ); this.re.yyyy =  new RegExp( "^([1-9][0-9]*)(-.+)?$" ); }     got  =  this.re.yyyy.exec( s ); if (got) { r =  { year:   parseInt(got[1], 10) }; s =  got[2]; if (s) { got =  this.re.mon.exec(s); if (got) { r.month =  parseInt(got[1], 10); s       =  got[2]; if (s) { got =  this.re.dd.exec(s); if (got) { r.dom =  parseInt(got[1], 10); s     =  got[2]; if (s) { s =  s.substr(1); }                 } else { r =  false; s =  false; }              } else { r =  false; s =  false; }           } else { r =  false; }        }      }      if (s) { got =  this.re.hh.exec(s); if (got) { if ( ! r) { r =  { }; }           r.hour  =  parseInt(got[1], 10); s      =  got[2]; if (s) { got =  this.re.min.exec(s); if (got) { r.minute =  parseInt(got[1], 10); s        =  got[2]; if (s) { got =  this.re.ss.exec(s); if (got) { r.second =  parseInt(got[1], 10); s        =  got[2]; } else { r =  false; }                 } else { r =  false; }              } else { r =  false; }           }         }      }      if ( ! r ) { o =  WSTM.lang.l;         if ( typeof o.en  ===  "object"   &&              typeof o.en.date  ===  "object"   &&              typeof o.en.date.fetch  ===  "function") { r =  o.en.date.fetch( attempt ); }        if ( ! r  &&              typeof o[ alien ]  ===  "object"   &&              typeof o[ alien ].date  ===  "object"   &&              typeof o[ alien ].date.fetch  ===  "function") { r =  o[ alien ].date.fetch( attempt ); }     }      if ( r ) { r =  this.formal( r, ahead ); }     return  ( r || false ); };  // .util.date.fetch

WSTM.util.date.fiat =  function ( attempt ) { // Equip object of components with JS object // Precondition: //   attempt  -- object of components //               >< .date // 2015-12-23 PerfektesChaos@de.wikipedia var ih  =  0, im  =  0, ims =  0, is  =  0; switch ( typeof attempt.date ) { case "boolean": case "object": break; default: if ( typeof attempt.year ===  "number"   &&                 typeof attempt.month  ===  "number"   &&                 typeof attempt.dom  ===  "number" ) { if ( typeof attempt.hour ===  "number" ) { ih =  attempt.hour; if ( typeof attempt.minute ===  "number" ) { im =  attempt.minute; if ( typeof attempt.second ===  "number" ) { is =  attempt.second; if ( typeof attempt.msec ===  "number" ) { ims =  attempt.msec; if ( typeof attempt.mysec ===  "number" ) { ims =  ims  +  0.001 * attempt.mysec; }                       }                     }                  }               }               attempt.date  =  new Date( attempt.year,                                          attempt.month - 1,                                          attempt.dom - 1,                                          ih, im, is, ims ); } else { attempt.date =  false; }     }   // switch typeof attempt.date return attempt.date; };  // .util.date.fiat

WSTM.util.date.fill =  function ( at, assembly ) { // Create month name translation map for lang // Precondition: //   at        -- .lang.l.*.date object //   assembly  -- object to collect // Postcondition: //   assembly has been equipped by lang // Uses: //   >< .util.date.re      //    >< .util.date.re.digits //    < .lang.l.*.date.greg12 // 2019-11-29 PerfektesChaos@de.wikipedia var m, min, r, s;     if ( typeof at.monAbbr  ===  "object" ) { if ( typeof at.monAbbr.n ===  "number" ) { min =  at.monAbbr.n;         } for ( m in at.monAbbr ) { if ( typeof this.re !==  "object" ) { this.re =  { }; }           if ( typeof this.re.digits  !==  "object" ) { this.re.digits =  new RegExp( "^\\d+$" ); }           if ( typeof m  ===  "number"   ||                 this.re.digits.test( m ) ) { s             =  at.monAbbr[ m ].toLowerCase; assembly[ s ] =  m;               r              =  true; }        }   // for m in at.monAbbr }     if ( typeof at.monFull  ===  "object" ) { for ( m in at.monFull ) { s             =  at.monFull[ m ].toLowerCase; assembly[ s ] =  m;            r              =  true; if ( min &&  s.length > min ) { s             =  s.substr( 0, min); assembly[ s ] =  m;            } }  // for m in at.monFull }     return  r;   };   // .util.date.fill

WSTM.util.date.filler =  function ( at ) { // Create month name translation map // Precondition: //   at       -- .lang.l.*.date object // Postcondition: //   .lang.l.*.date object equipped by component // Uses: //   this //   >  .lang.l.*.date.consider //    < .lang.l.*.date.greg12 //   .util.date.fill // 2015-11-26 PerfektesChaos@de.wikipedia var o    =  { }, live =  this.fill( at, o ), i, l, x;     if ( typeof at.consider  ===  "object" ) { for ( i = 0; i < at.consider.length;  i++ ) { x =  WSTM.lang.l[ at.consider[i] ]; if ( typeof x ===  "object"   &&                 typeof x.date  ===  "object" ) { l    =  this.fill( x.date, o ); live =  ( live || l ); }        }   // for i      } if ( live ) { at.greg12 =  { }; for ( x in o ) { i =  o[ x ]; switch ( typeof i ) { case "number": at.greg12[ x ] =  i;                  break; case "string": at.greg12[ x ] =  parseInt( i, 10 ); break; }  // switch typeof i         }   // for x in o      } else { at.greg12 =  null; }  };   // .util.date.filler

WSTM.util.date.find =  function ( attempt, at ) { // Translate month name into month number // Precondition: //   attempt  -- string with presumable month name //   at       -- .lang.l.*.date object // Postcondition: //   Returns month number 1...12, or false // Uses: //   this //   >< .lang.l.*.date.greg12 //   .util.date.filler // 2015-11-26 PerfektesChaos@de.wikipedia var r, s;     if ( typeof at.greg12  !==  "object" ) { this.filler( at ); }     if ( at.greg12 ) { s =  attempt.toLowerCase; if ( typeof at.greg12[ s ] ===  "number" ) { r =  at.greg12[ s ]; }     }      return  ( r || false ); };  // .util.date.find

WSTM.util.date.formal =  function ( attempt, ahead ) { // Check validity of datetime components // Precondition: //   attempt  -- object of components, or false //   ahead    -- true: future moment permitted // Postcondition: //   Returns attempt, or false if invalid or unpermitted future // Uses: //   this //   >< .util.date.current //   .util.date.further //   .util.date.full // 2016-01-04 PerfektesChaos@de.wikipedia var r =  attempt, j, m, n;     if ( r ) { if ( typeof r.year ===  "number" ) { j =  r.year; this.further( r ); } else { r.year =  false; }     }      if ( r ) { if ( typeof r.month ===  "number" ) { m =  r.month; if ( m < 1 ||  m > 12 ) { r =  false; }        } else { r.month =  false; }     }      if ( r ) { if ( typeof r.dom ===  "number" ) { n =  r.dom; if ( n > 0 &&  n <= 31 ) { if (m) { if (n > this.full(r)) { r =  false; }              } else if ( j ) { r =  false; }           } else { r =  false; }        } else { r.dom =  false; }     }      if ( r ) { if ( typeof r.hour ===  "number" ) { if (r.hour < 0 ||  r.hour > 23) { r =  false; }        } else { r.hour =  false; }     }      if ( r ) { if ( typeof r.minute ===  "number" ) { if ( r.minute < 0 ||  r.minute > 59 ) { r =  false; }        } else { r.minute =  false; }     }      if ( r ) { if ( typeof r.second ===  "number" ) { if (r.second < 0 ||  r.second > 60) { r =  false; } else { if ( typeof r.minute ===  "number" ) { if (r.second === 60 &&  r.minute !== 59) { r =  false; }              } else if ( typeof r.hour  ===  "number" ) { r =  false; }           }         } else { r.second =  false; }     }      if ( r && ahead && j && m && n ) { if ( typeof this.current !==  "object" ) { this.current =  new Date; }        if ( j > this.current.getUTCFullYear ) { r =  false; } else if (j === this.current.getUTCFullYear &&                    m  >  this.current.getUTCMonth) { if ( m >  this.current.getUTCMonth + 1   ||                 n  >  this.current.getUTCDate ) { r =  false; }        }      }      return  ( r || false ); };  // .util.date.formal

WSTM.util.date.format =  function ( attempt, apply ) { // Format date // Precondition: //   attempt  -- object of components //   apply    -- Array with layout description //               number: ISO, maximum permitted components //               string: PHP //               Array: [0] country code //                      [1] country subtype (lowercase) //                      [2] mode //                      [3] number of maximum permitted components // Postcondition: //   Returns string // Uses: //   this //   .util.date.formatISO //   .util.date.formatPHP // 2015-12-23 PerfektesChaos@de.wikipedia var r =  "", f, n, o;     switch ( typeof apply ) { case "number": r =  this.formatISO( attempt, apply ); break; case "object": if ( apply ) { o =  WSTM.lang.l;               if ( typeof o[ apply[ 0 ] ]  ===  "object" ) { o =  o[ apply[ 0 ] ]; if ( apply[ 1 ]  &&                       typeof o[ apply[ 1 ] ]  ===  "object"   &&                       typeof o[ apply[ 1 ] ].date  ===  "object"   &&                       typeof o[ apply[ 1 ] ].date.format                                                      ===  "function" ) { f =  o[ apply[ 1 ] ].date.format; } else if ( typeof o.date ===  "object"   &&                              typeof o.date.format  ===  "function" ) { f =  o.date.format; }              }               if ( typeof apply[ 3 ]  ===  "number" ) { n =  apply[ 3 ]; }           }            break; case "string": r =  this.formatPHP( attempt, apply ); break; }  // switch typeof apply if ( f ) { r =  f( attempt, apply [2 ], n ); } else if ( ! r) { r =  this.formatISO( attempt, n ); }     return  r;   };   // .util.date.format

WSTM.util.date.formatISO =  function ( attempt, amount ) { // Format date in ISO (human: space between date and time) // Precondition: //   attempt  -- object of components //   amount   -- number of maximum permitted components, else max // Postcondition: //   Returns string // Uses: //   this //   >  .util.date.units //   >< .util.date.isoFormat //   .str.makeString // 2015-12-23 PerfektesChaos@de.wikipedia var r =  "", i, k, n, o;     if ( attempt.year ) { r =  "" + attempt.year; n =  4 - r.length; if ( n ) { r =  WSTM.str.makeString( 48, n )  +  r;         } if ( typeof this.isoFormat !==  "object" ) { this.isoFormat =  { month:  { n:  10,  sep: "-" }, dom:   { n:  10,  sep: "-" }, hour:  { n:  10,  sep: " " }, minute: { n: 10,  sep: ":" }, second: { n: 10,  sep: ":" }, msec:  { n: 100,  sep: "." },                                mysec:  { n: 100,  sep: "" } };        }         k  =  ( typeof amount  ===  "number"  ?  amount                                               :  this.units.length ); for ( i = 2; i <= k;  i++ ) { o =  this.units[ i ]; n =  attempt[ o ]; if ( typeof n ===  "number" ) { o =  this.isoFormat[ o ]; r =  r + o.sep; if ( n < o.n ) { r =  r + "0"; if ( o.n === 100 &&  n < 10 ) { r =  r + "0"; }              }               r  =  r + n;            } else { break;  // for i            } }  // for i      } return r;   };   // .util.date.formatISO

WSTM.util.date.formatPHP =  function (attempt, apply, assign) { // Format date by PHP specifiers // Precondition: //   attempt  -- object of components //   apply    -- string: PHP code like #time: //   assign   -- object with localised names //               "month":  Array of month names; //                         counting from 1 (1=January) //               "mon":    Array of abbreviated month names; //                         counting from 1 (1=Jan) //                         number: length of abbreviation //               "doweek": Array of day of week names; //                         counting from 0 (0=Sunday) //               "dow":    Array of abbreviated day of week names; //                         counting from 0 (0=Sun) //                         number: length of abbreviation // Uses: //   this //   >  .util.date.domax //   .str.substrEnd //   .util.date.furnish //   .util.date.formatISO //   .util.date.fiat //   .util.date.further //   .util.date.formatPHP   -- self-recursive //   .util.date.full // 2017-01-01 PerfektesChaos@de.wikipedia var r =  "", i, n, o, s, v;     if ( typeof this.phpCodes  !==  "object" ) { this.phpCodes =  { Y:   { s: "year",  n: 4 }, y:  { s: "year",  n: 2,  m: 2 }, L:  true, M:  { s: "month",  o: "mon" }, F:  { s: "month",  o: "month" }, m:  { s: "month",  n: 1 }, n:  { s: "month",  n: 2 }, t:  true, W:  true, z:  true, j:  { s: "dom",  n: 1 }, d:  { s: "dom",  n: 2 }, D:  true, l:  true, w:  true, N:  true, G:  { s: "hour",  n: 1 }, H:  { s: "hour",  n: 2 }, g:  true, h:  true, a:  true, A:  true, i:  { s: "minute",  n: 2 }, s:  { s: "second",  n: 2 }, c:  true, r:  true, U:  true, e:  true, I:  true, O:  true, P:  true, T:  true, Z:  true, '"': true };     }      for ( i = 0;  i <= apply.length;  i++ ) {         s  =  apply.substr( i, 1 );         switch ( typeof this.phpCodes[ s ] ) {            case "object":               o  =  this.phpCodes[ s ];               if ( typeof o.s  ===  "string" ) {                  if ( typeof attempt[ o.s ]  ===  "number") {                     v  =  attempt[ o.s ];                     if ( typeof o.n  ===  "number" ) {                        switch (o.n) {                           case 2:                              if ( typeof o.m  ===  "number" ) {                                 if ( v < 100 ) {                                    if ( v < 10 ) {                                       v  =  "0" + v;                                    }                                 } else {                                    v  =  WSTM.str.substrEnd( "" + v,                                                              2 ); }                             } else { if ( v < 10 ) { v =  "0" + v;                                 } }                             break; case 4: if ( v < 1000 ) { v =  WSTM.str.substrEnd( "000" + v,                                                           4 ); }                             break; }  // switch o.n                     } else if ( typeof o.o  ===  "string" ) { v =  this.furnish(v, o.o, assign); }                    r  =  r + v;                  } }              break; case "boolean": switch ( s ) { case '"':                    i++;                     n  =  apply.indexOf( '"', i ); if ( n < 0 ) { r =  r + apply.substr( i ); i =  apply.length; } else { r =  r  +  apply.substring( i, n ); i =  n;                     } break; case "A": case "a": if ( typeof attempt.hour ===  "number" ) { if ( attempt.hour > 12 ) { v =  "PM"; } else { v =  "AM"; }                       if (s === "a") { v =  v.toLowerCase; }                       r  =  r + v;                     } break; case "c":  // ISO r =  r + this.formatISO( attempt ); break; case "D": case "l": case "N": case "w": if ( this.fiat( attempt ) ) { v =  attempt.date.getDay; switch ( s ) { case "D": v =  this.furnish( v, "dow", assign ); break; case "l": v =  this.furnish( v, "doweek", assign ); break; case "N":  // Sunday = 7 if ( ! v ) { v =  7; }                             break; case "w":  // Sunday = 0 break; }  // switch s                        r  =  r + v;                     } break; case "e": case "I": case "O": case "P": case "T": case "Z": if ( this.fiat( attempt ) ) { v =  attempt.date.getTimezoneOffset; switch ( s ) { case "e": case "T": if ( ! v) { v =  "UTC"; break; }  // fall through case "O": case "P": o =  (v < 0); if ( o ) { v =  v * -1; }                             n  =  v % 60; v =  v  -  n * 60; if ( n < 10 ) { n =  "0" + n;                              } if ( v < 10 ) { v =  "0" + v;                              } if ( s === "P" ) { v =  ":" + v;                              } v =  n + v;                              if ( o ) { v =  "-" + v;                              } else { v =  "+" + v;                              } break; case "I": v =  "0"; break; case "Z": v =  v * 60; break; }  // switch s                        r  =  r + v;                     } break; case "g": case "h": if ( typeof attempt.hour ===  "number" ) { v =  ( attempt.hour > 12  ?  attempt.hour - 12                                                   :  attempt.hour ); if ( s === "h" &&  v < 10 ) { v =  "0" + v;                        } r =  r + v;                     } break; case "L":  // leap year r =  r  +  (this.further(attempt) ? "1" : "0" ); break; case "r":  // RFC 2822 r =  r + this.formatPHP(attempt,                                              "D, j M Y H:i:s O"); break; case "t": r =  r + this.full(attempt); break; case "U":  // 1970-01-01 if ( this.fiat( attempt ) ) { r =  r + attempt.date.getTime * 1000; }                    break; case "W": case "z": if ( typeof attempt.month ===  "number"  &&                          typeof attempt.dom  ===  "number" ) { v =  attempt.dom - 1; if ( attempt.month === 2 ) { v +=  31; }                       if ( typeof attempt.year  ===  "number" ) { if ( attempt.month > 2 ) { for ( n = attempt.month - 1;                                   n === 2;                                    n-- ) { v +=  this.domax[ n ]; }  // for n-- this.fiat( attempt ); if ( ! attempt.leap) { v--; }                          }                           if ( s === "W" ) {   // woy  ISO 8601 if ( typeof attempt.jan1 !==  "number" ) { o =  new Date( attempt.year, 0, 0 ); attempt.jan1 =  o.getDay; }                             if ( attempt.jan1 < 4 ) { v -=  attempt.jan1; }                             v  =  Math.ceil( ++v / 7 ); // erste Kalenderwoche im Jahr // Woche mit dem ersten Januar-Donnerstag definiert. }                          r  =  r + v;                        } else if ( s === "z"  &&  attempt.month <= 2 ) { r =  r + v;                        } }                    break; }  // switch s               break; default: r =  r + s;         }   // switch typeof phpCodes[ s ] }  // for i      return  r;   };   // .util.date.formatPHP

WSTM.util.date.full =  function ( attempt ) { // Number of days in month // Precondition: //   attempt  -- object of components //               >  .month //               >  .leap // Postcondition: //   Returns number, may be zero if no month provided // Uses: //   this //   >  .util.date.domax //   .util.date.further // 2016-05-14 PerfektesChaos@de.wikipedia var r = 0, m;     if ( typeof attempt.month  ===  "number" ) { m =  attempt.month; if ( m >= 1 &&  m <= 12 ) { r =  this.domax[ m ]; if ( m === 2 ) { this.further( attempt ); if ( ! attempt.leap ) { r =  28; }           }         }      }      return  r;   };   // .util.date.full

WSTM.util.date.furnish =  function (at, as, assign, again) { // Retrieve textual representation of date component // Precondition: //   at       -- number //   as       -- string with keyword (month, mon, doweek, dow) //   assign   -- object with localised names, or not //               "month":  Array of month names; //                         counting from 1 (1=January) //               "mon":    Array of abbreviated month names; //                               counting from 1 (1=Jan) //                         object else: //                                n: length of abbreviation //                                suffix: if desired //               "doweek": Array of day of week names; //                         counting from 0 (0=Sunday) //               "dow":    Array of abbreviated day of week names; //                               counting from 0 (0=Sun) //                         object else: //                                n: length of abbreviation //                                suffix: if desired //   again    -- true: fallback mode, not again // Postcondition: //   Returns string // Uses: //   this //   >  .util.date.words //   .util.date.furnish   -- self-recursive // 2016-03-22 PerfektesChaos@de.wikipedia var o, r, s;     if ( typeof assign  ===  "object"  &&           typeof assign[ as ]  ===  "object" ) { o =  assign[ as ]; if ( typeof o.length ===  "number" ) { r =  o[ at ]; } else if (as.length === 3 &&                     typeof o.n  ===  "number" ) { s =  (as === "mon"  ?  "month"  :  "doweek" ); if ( typeof assign[ s ] ===  "object"  &&                 typeof assign[ s ][ at ]  ===  "string" ) { r =  assign[ s ][ at ].substr( 0, o.n ); if ( typeof o.suffix ===  "string" ) { r =  r + o.suffix; }           }         }      }      if ( ! r ) { if ( again ) { r =  "<" + at + ">"; } else { r =  this.furnish( at, as, this.words, true ); }     }      return  r;   };   // .util.date.furnish

WSTM.util.date.further =  function ( attempt ) { // Is this a leap year? // Precondition: //   attempt  -- object of components //               >  .bc      //                >  .year //               >< .leap // Postcondition: //   Returns boolean // 2018-01-28 PerfektesChaos@de.wikipedia var r, j;     if ( typeof attempt.leap  ===  "boolean" ) { r =  attempt.leap; } else { r =  false; if ( typeof attempt.year ===  "number"   &&              ( typeof attempt.bc  ===  "undefined"  || ! attempt.bc ) ) { j =  attempt.year; if ( j > 0 &&  j <= 2100 ) { if ( ! j % 4    &&                    ( j % 100   ||   ! j % 400 ) ) { r =  true; }           }         }         attempt.leap  =  r;      } return r;   };   // .util.date.further

//--- };  // .bb.dating mw.libs.WikiSyntaxTextMod.bb.dating( mw.libs.WikiSyntaxTextMod ); delete mw.libs.WikiSyntaxTextMod.bb.dating;

//---

mw.libs.WikiSyntaxTextMod.bb.idcodes =  function ( WSTM ) { // ID code syntax analysis, error message // Public: //   .util.code.dnb //   .util.code.doi //   .util.code.isbn //   .util.code.issn //   .util.code.lccn //   .util.code.pmc //   .util.code.pmid //   .util.code.urn //   .util.code.viaf //   .util.code.zdb // Uses: //   .util.fiatObjects // 2020-02-07 PerfektesChaos@de.wikipedia "use strict";

WSTM.util.fiatObjects( WSTM.util, "code",                         { re: { } } );

WSTM.util.code.fetch =  function ( attempt, amount, allowX, about ) { // Retrieve Array with digits // Precondition: //   attempt  -- string with presumable code; digits space hyphens //   amount   -- number of maximum permitted digits //   allowX   -- number; of (last) position for permitted xX      //                boolean; xX at last position permitted //   about    -- string with thematic context // Postcondition: //   Returns Array of digits including 10, or false if invalid // Uses: //   >  .str.sticks //   >  .str.spaces //   .errors.found // Requires: JavaScript 1.3  charCodeAt   fromCharCode // 2016-06-10 PerfektesChaos@de.wikipedia var k =  0, n =  attempt.length, r =  new Array( amount ), c,         i;      for ( i = 0;  i < n;  i++ ) { c =  attempt.charCodeAt( i ); if ( c >= 48 &&  c <= 57 ) {   // 0...9 c -=  48; if ( k < amount ) { r[ k ] =  c;            } else { r =  false; WSTM.errors.found( "badCodeDigitcount",                                 false,                                  about + ": " + attempt ); break;  // for i            } k++; } else if ( c === 88 ||  c === 120 ) {   // X x            if ( allowX   &&   i  ===  n - 1 ) { if ( allowX === true  ||   allowX  ===  k + 1 ) { r[ k ] =  10; k++; } else { r =  false; }           } else { r =  false; }           if ( ! r ) { WSTM.errors.found( "badCodeX",                                 false,                                  about + ": " + attempt); }           break;   // for i         } else if ( c !== 32  &&  c !== 45 ) {   // space hyphen c =  String.fromCharCode(c); if ( WSTM.str.sticks.indexOf( c ) < 0 &&                 WSTM.str.spaces.indexOf( c ) < 0 ) { r =  false; WSTM.errors.found( "badCodeChar",                                 false,                                  about + ": " + attempt ); break;  // for i            } }     }   // for i      if ( r ) { if ( k < amount ) { r.splice( k, amount - k ); }     }      return  r;   };   // .util.code.fetch

WSTM.util.code.dnb =  function ( adjust ) { // Check DNB code // Precondition: //   adjust  -- DNB code (no leading keyword) // Postcondition: //   Returns false if valid, or true if invalid // Uses: //   .util.dnb.failure // 2013-06-23 PerfektesChaos@de.wikipedia return WSTM.util.dnb.failure( adjust, "DNB" ); };  // .util.code.dnb

WSTM.util.code.doi =  function ( adjust, allow ) { // DOI syntax analysis, error message // Precondition: //   adjust  -- identifier (trimmed) //   allow   -- permit Wikisyntax characters;  else interwiki link // Postcondition: //   Returns false if valid, or Array with error info [1] // Uses: //   .util.doi.format // 2013-06-27 PerfektesChaos@de.wikipedia return WSTM.util.doi.format( adjust, allow ); };  // .util.code.doi

WSTM.util.code.ean =  function ( adjust ) { // Check EAN code // Precondition: //   adjust  -- EAN code (no leading keyword) // Postcondition: //   Returns false if to be kept, or string if to be corrected // Uses: //   .util.gtin.format // 2013-06-21 PerfektesChaos@de.wikipedia return WSTM.util.gtin.format( adjust, "EAN" ); };  // .util.code.ean

WSTM.util.code.gnd =  function ( adjust ) { // Check GND code // Precondition: //   adjust  -- GND code (no leading keyword) // Postcondition: //   Returns false if valid, or true if invalid // Uses: //   .util.dnb.failure // 2016-06-19 PerfektesChaos@de.wikipedia return WSTM.util.dnb.failure( adjust, "GND", 8, false ); };  // .util.code.gnd

WSTM.util.code.gtin =  function ( adjust ) { // Check GTIN code // Precondition: //   adjust  -- GTIN code (no leading keyword) // Postcondition: //   Returns false if to be kept, or string if to be corrected // Uses: //   .util.gtin.format // 2013-06-21 PerfektesChaos@de.wikipedia return WSTM.util.gtin.format( adjust, "GTIN" ); };  // .util.code.gtin

WSTM.util.code.isbn =  function ( adjust, accept ) { // Format ISBN code // Precondition: //   adjust  -- ISBN code (no leading keyword) //   accept  -- 10, 13, false or omitted // Uses: //   .util.isbn.format // Postcondition: //   Returns  array[2] //            [0] number  of characters successfully consumed //                        at least 10, some more for hyphens etc.      //                         [1] string  reformatted ISBN: //                                    insert hyphens etc.      //                                     spaces replaced by hyphens //                                    x->X //                                    hyphens inserted //                                            before checknumber //                                            at ISBN-13 //                            false   no formatting necessary //                false   adjust is invalid sequence //                        [1] error code -1,1...12 // 2012-12-22 PerfektesChaos@de.wikipedia return WSTM.util.isbn.format( adjust,                                     (accept ? accept : false) ); };  // .util.code.isbn

WSTM.util.code.issn =  function ( adjust ) { // Format ISSN code // Precondition: //   adjust  -- ISSN code (no leading keyword) // Postcondition: //   Returns false if to be kept, or string if to be corrected // Uses: //   .util.issn.format // 2013-06-02 PerfektesChaos@de.wikipedia return WSTM.util.issn.format( adjust ); };  // .util.code.issn

WSTM.util.code.lang =  function ( adjust ) { // Check ISO 639 code // Precondition: //   adjust  -- lang code // Postcondition: //   Returns false if valid, //           string if to be adjusted, //           or Array with error info [1] // Uses: //   >< .util.code.re.baselang //   .str.trim //   .util.isO_639_1 //   .str.capitalize // 2021-10-26 PerfektesChaos@de.wikipedia var r     =  WSTM.str.trim( adjust ), parts =  r.split( "-" ), s;     r  =  parts[ 0 ].toLowerCase; switch ( r.length ) { case 2 : if ( ! WSTM.util.isO_639_1( r ) ) { r =  false; }            break; case 3 : if ( typeof WSTM.util.code.re.baselang !==  "object" ) { WSTM.util.code.re.baselang =  new RegExp( "^[a-z]+$" ); }            if ( ! WSTM.util.code.re.baselang.test( r ) ) { r =  false; }            break; default : r =  false; }  // switch r.length if ( r ) { if ( parts.length > 1 ) { if ( parts.length === 2 ) { s =  parts[ 1 ]; if ( typeof WSTM.util.code.re.baselang !==  "object" ) { WSTM.util.code.re.baselang = new RegExp( "^[a-z]+$" ); }              if ( WSTM.util.code.re.baselang.test( r ) ) { switch ( s.length ) { case 2 : s =  s.toUpperCase; break; case 4 : s =  WSTM.str.capitalize( s ); break; default : s =  false; }  // switch s.length } else { s =  false; }              if ( s ) { r =  r + "-" + s;               } else { r =  [ adjust, "Invalid; bad subset ID" ]; }           } else { r =  [ adjust, "Invalid; too many hyphens" ]; }        }         if ( r === adjust ) { r =  false; }     } else { r =  [ adjust, "Invalid; bad ID" ]; }     return  r;   };   // .util.code.lang

WSTM.util.code.lccn =  function ( adjust, apply ) { // Check LCCN code // Precondition: //   adjust  -- LCCN code (no leading keyword) //   apply   -- '/' or '-' or false // Postcondition: //   Returns false if valid, //           string if to be adjusted, //           or Array with error info [1] // Uses: //   .util.lccn.format // 2013-06-27 PerfektesChaos@de.wikipedia return WSTM.util.lccn.format( adjust, apply ); };  // .util.code.lccn

WSTM.util.code.pmc =  function ( adjust ) { // Check PMC code // Precondition: //   adjust  -- PMC code (trimmed, no leading keyword) // Postcondition: //   Returns false if valid, or true if invalid // Uses: //   >< .util.code.re.pmc // 2021-10-26 PerfektesChaos@de.wikipedia if ( typeof WSTM.util.code.re.pmc !==  "object" ) { WSTM.util.code.re.pmc =  new RegExp( "^[1-9][0-9]{4,9}$" ); }     return  ( ! WSTM.util.code.re.pmc.test( adjust ) ); };  // .util.code.pmc

WSTM.util.code.pmid =  function ( adjust ) { // Check PMID code // Precondition: //   adjust  -- PMID code (trimmed, no leading keyword) // Postcondition: //   Returns false if valid, or true if invalid // Uses: //   >< .util.code.re.pmid // 2021-10-26 PerfektesChaos@de.wikipedia if ( typeof WSTM.util.code.re.pmid !==  "object" ) { WSTM.util.code.re.pmid =  new RegExp( "^[1-9]([0-9]{1,9})?$" ); }     return  ( ! WSTM.util.code.re.pmid.test( adjust ) ); };  // .util.code.pmid

WSTM.util.code.urn =  function ( adjust ) { // Check URN code // Precondition: //   adjust  -- URN code (URI) // Postcondition: //   Returns false if valid, or true if invalid // Uses: //   .util.urn.failure // 2013-06-21 PerfektesChaos@de.wikipedia return WSTM.util.urn.failure( adjust ); };  // .util.code.urn

WSTM.util.code.viaf =  function ( adjust ) { // Check VIAF code // Precondition: //   adjust  -- VIAF code (trimmed, no leading keyword) // Postcondition: //   Returns false if valid, or true if invalid // Uses: //   >< .util.code.re.viaf // 2021-10-26 PerfektesChaos@de.wikipedia if ( typeof WSTM.util.code.re.viaf !==  "object" ) { WSTM.util.code.re.viaf =  new RegExp( "^[1-9][0-9]{3,13}$" ); }     return  ( ! WSTM.util.code.re.viaf.test( adjust ) ); };  // .util.code.viaf

WSTM.util.code.zdb =  function ( adjust ) { // Check ZDB code // Precondition: //   adjust  -- ZDB code (no leading keyword) // Postcondition: //   Returns false if valid, or true if invalid // Uses: //   .util.dnb.failure // 2016-06-19 PerfektesChaos@de.wikipedia return WSTM.util.dnb.failure( adjust, "ZDB", 4, true ); //               };   // .util.code.zdb

};  // .bb.idcodes mw.libs.WikiSyntaxTextMod.bb.idcodes( mw.libs.WikiSyntaxTextMod ); delete mw.libs.WikiSyntaxTextMod.bb.idcodes;

//---

mw.libs.WikiSyntaxTextMod.bb.dnb =  function (WSTM) { // DNB family (DNB, GND, ZDB) code syntax analysis // Public: //   .util.dnb.failure // Uses: //   .util.code.fetch //   .errors.found // 2013-06-23 PerfektesChaos@de.wikipedia "use strict"; WSTM.util.fiatObjects( WSTM.util, "dnb" );

WSTM.util.dnb.failure =  function ( attempt, about, amount, alt ) { // Is DNB code invalid? // Precondition: //   attempt  -- DNB code (no leading keyword) //   about    -- keyword //   amount   -- minimum length of core //   alt      -- hyphen required // Postcondition: //   Returns false if valid, or true/string/number if invalid // Uses: //   >< .util.re.dnbX //   .util.code.fetch //   .util.dnb.faith // 2021-10-26 PerfektesChaos@de.wikipedia var j   =  attempt.indexOf( "/" ), dnb, s,         r;      if ( j > 0 ) { s =  attempt.substr( 0, j ); } else { s =  attempt; }     dnb  =  WSTM.util.code.fetch( s, 11, true, about ); if ( dnb ) { j = dnb.length; if ( amount &&  j <= amount ) { r =  amount; }        if ( ! r   &&   typeof alt  ===  "boolean" ) { if ( attempt.indexOf( "-" ) < 0 ) { r =  alt; } else { r =  ( ! alt ); }        }         if ( ! r  &&  j <= 8 ) { if ( typeof WSTM.util.re.dnbX !==  "object" ) { WSTM.util.re.dnbX = new RegExp( "^[1-9][0-9]{3,6}-[0-9xX]$" ); }           if ( WSTM.util.re.dnbX.test( s ) ) { r = ( ( 11 - this.faith( dnb ) ) %  11                                                     !==  dnb[ j - 1 ] ); j = false; } else { r = true; }        }         if ( ! r  &&  j  &&  ! alt ) { r = ( this.faith( dnb ) !==  dnb[ j - 1 ] ); }     } else { r = true; }     return  r;   };   // .util.dnb.failure

WSTM.util.dnb.faith =  function ( assert ) { // Compute DNB family (DNB, GND, ZDB) check digit // Precondition: //   assert  -- Array with digits // Postcondition: //   Returns   0...9 // 2013-06-23 PerfektesChaos@de.wikipedia var n =  assert.length, k =  n,          r  =  0, i;     n--; for ( i = 0; i < n;  i++ ) { r =  r  +  k * assert[ i ]; k =  k - 1; }  // for i      r  =  ( 11  -  r % 11 )   %   11; return r;   };   // .util.dnb.faith

};  // .bb.dnb mw.libs.WikiSyntaxTextMod.bb.dnb(mw.libs.WikiSyntaxTextMod); delete mw.libs.WikiSyntaxTextMod.bb.dnb;

//---

mw.libs.WikiSyntaxTextMod.bb.doi =  function (WSTM) { // DOI syntax analysis, code correction and formatting // Public: //   .util.doi.format // Uses: //   .util.code.fetch //   .errors.found // 2013-06-27 PerfektesChaos@de.wikipedia "use strict"; WSTM.util.fiatObjects( WSTM.util, "doi" );

WSTM.util.doi.failure =  function ( attempt ) { // Is DOI invalid? // Precondition: //   attempt  -- identifier (trimmed) // Postcondition: //   Returns false if valid, //           string if to be adjusted, //           or Array with error info [1] // Uses: //   .util.doi.format //   .str.decodeXML // 2013-06-27 PerfektesChaos@de.wikipedia var r =  this.format(attempt, false), s;     if ( r ) { s =  attempt.replace( /&(#x200[9A-F]|lrm|rlm|zwn?j);/, "" ); if ( s !== attempt ) { r =  s;         } }     return  r;   };   //    .util.doi.failure

WSTM.util.doi.format =  function (adjust, allow) { // DOI syntax analysis, error message // Precondition: //   adjust  -- identifier (trimmed) //   allow   -- permit Wikisyntax characters;  else interwiki link // Postcondition: //   Returns false if valid, or Array with error info [1] // Uses: //   >< .util.doi.re.* //   .str.decodeXML // 2017-07-18 PerfektesChaos@de.wikipedia var r =  false, i, s;     if ( adjust.substr( 0, 3 ) === "10." ) { s =  adjust.substr( 3 ); i =  s.indexOf( "/" ); if ( i > 3 ) { if ( typeof this.re !==  "object" ) { this.re =  { }; this.re.org =  new RegExp( "^[1-9][0-9]{3,7}$", "" ); this.re.doi =  "-0-9/A-Z.a-z_;,:"; this.re.iw  =  new RegExp( "^["                                              + this.re.doi + "&#]{3,}$",                                           "" ); this.re.doi =  new RegExp( "^" + "[/0-9.A-Za-z(<]" + "(?:[" + this.re.doi                                                      + "<>]+|\\[|\\])+" + "[0-9A-Za-z#+)]$",                                          "" ); }           if ( this.re.org.test( s.substr( 0, i ) ) ) { s =  s.substr( i + 1 ); if ( ! allow ) { if ( ! this.re.iw.test( s ) ) { r =  "invalid character in ID: " + adjust; }              }               if ( ! r ) { s =  WSTM.str.decodeXML( s ); if ( ! this.re.doi.test( s ) ) { r =  "bad selector '" + s + "'"; }              }            } else { r =  "bad number '"  +  s.substr( 0, i )  +  "'"; }        } else { r =  "missing '/'"; }     } else { r =  "leading '10.' missing"; }     return  ( r  ?  [ false, r ]  :  false ); };  // .util.doi.format

};  // .bb.doi mw.libs.WikiSyntaxTextMod.bb.doi(mw.libs.WikiSyntaxTextMod); delete mw.libs.WikiSyntaxTextMod.bb.doi;

//---

mw.libs.WikiSyntaxTextMod.bb.gtin =  function (WSTM) { // GTIN (EAN) syntax analysis, code correction and formatting // Public: //   .util.gtin.format // Uses: //   .util.fiatObjects //   .util.code.fetch //   .errors.found // 2013-06-23 PerfektesChaos@de.wikipedia "use strict"; WSTM.util.fiatObjects( WSTM.util, "gtin" );

WSTM.util.gtin.faith =  function ( assert ) { // Compute GTIN check digit // Precondition: //   assert  -- Array with digits // Postcondition: //   Returns   0...9 // 2013-06-23 PerfektesChaos@de.wikipedia var lead =  true, r    =  0, i,         k;      for ( i = 0;  i < 12;  i++ ) { k  =  assert[i]; r +=  k;         if ( lead ) {   // odd lead =  false; } else {  // even r    +=  k + k;            lead   =  true; }     }   // for i      r  =  ( 10  -  r % 10 )   %   10; return r;   };   // .util.gtin.faith

WSTM.util.gtin.fashion =  function (acquired) { // Format GTIN code // Precondition: //   acquired  -- Array with digits // 2013-06-23 PerfektesChaos@de.wikipedia var r =  "", i;     for (i = 0;  i < 4;  i++) { r =  r + String.fromCharCode(acquired[i]+48); }  // for i      r  =  r + "-"; for (i = 4; i < 12;  i++) { r =  r + String.fromCharCode(acquired[i]+48); }  // for i      r  =  r + "-" + String.fromCharCode(acquired[12]+48); return r;   };   // .util.gtin.faith

WSTM.util.gtin.format =  function (attempt, about) { // Format GTIN code // Precondition: //   attempt  -- GTIN code (no leading keyword) //   about    -- keyword // Postcondition: //   Returns false if valid, or string if to be corrected // Uses: //   .util.code.fetch //   .util.gtin.faith //   .str.trim //   .util.gtin.fashion //   .errors.found // 2013-06-23 PerfektesChaos@de.wikipedia var r =  WSTM.util.code.fetch( attempt, 13, false, "GTIN" ); if ( r ) { if ( r.length === 13 ) { if ( this.faith( r ) === r[ 12 ] ) { if ( attempt.indexOf("-") > 0 ) { r =  WSTM.str.trim( attempt ); if ( r === attempt ) { r =  false; }              } else { r =  this.fashion(r); }           } else { r =  false; WSTM.errors.found( "badCodeCheckdig",                                 false,                                  about + ": " + attempt ); }        } else { r =  false; WSTM.errors.found( "badCodeDigitcount",                              false,                               about + ": " + attempt ); }     }      return  r;   };   // .util.gtin.format

};  // .bb.gtin mw.libs.WikiSyntaxTextMod.bb.gtin(mw.libs.WikiSyntaxTextMod); delete mw.libs.WikiSyntaxTextMod.bb.gtin;

//---

mw.libs.WikiSyntaxTextMod.bb.isbn =  function (WSTM) { // ISBN syntax analysis, code correction and formatting // Public: //   .util.isbn.factory //   .util.isbn.format // Uses: //   >  .str.sticks //    < .util.isbn.grouping //   .util.fiatObjects //   .util.gtin.faith //   .errors.found //   .str.substrEnd // 2016-03-20 PerfektesChaos@de.wikipedia "use strict"; WSTM.util.fiatObjects(WSTM.util, "isbn"); WSTM.util.isbn.grouping  =  false;   // segmentation data

WSTM.util.isbn.factory =  function (attribute) { // Make regexp string for ISBN detection // Precondition: //   attribute  -- URLs are excluded from detection // Postcondition: //   Returns string for RegExp //               [1]  prolog //                    preceding non-whitespace //               [2]  "ISBN" //       6 10 14 [3]  10 | 13      //              4 [4]  '=' assignment, if any //            15 [5]  I-S-B-N //            17 [6]  epilog // Uses: //   >  .str.sticks // Requires: JavaScript 1.5  RegExp non-capturing parenthese // 2013-09-26 PerfektesChaos@de.wikipedia return "(^|"  +  (attribute ? "\\W" : "[ \n]") +  ")"  +             // 1 "(ISBN)" +                                            // 2 "(?:" +                "(?:[" + WSTM.str.sticks + " ]?" +                   "(10|13):?" +                                    // 3                 ")?)" +              " *" +              "(?::? *| |&#160;|" +                 "(=)" +                                             // 4                 ")?" +              " *[" + WSTM.str.sticks + "]?" +             "([0-9]" +                  "(?:[" + WSTM.str.sticks + " .0-9]| |&#160;)+" +                     "[0-9X])" +                                     // 5 "([ -.]*[^" + WSTM.str.sticks + ". 0-9X]|\\.? *$)";   // 6 };  // .util.isbn.factory

WSTM.util.isbn.faith =  function ( attempt, amount ) { // Compute ISBN check digit // Precondition: //   attempt -- string with digits and hyphens without last digit //   amount  -- 10 or 13 // Postcondition: //   Returns   0...9, 40 for X, if attempt is valid;  else < 0 //             -1  attempt is empty //             -2  illegal char //             -3  invalid length // Uses: //   .util.gtin.faith // 2013-06-23 PerfektesChaos@de.wikipedia var d =  new Array( amount ), k =  0, n =  attempt.length, r =  -1, c,         i;      for ( i = 0;  i < n;  i++ ) { c =  attempt.charCodeAt( i ); if ( c >= 48 &&  c <= 57 ) { d[ k ] =  c - 48; k++; } else if ( c !== 32 &&  c !== 45 ) {   // space hyphen r =  -2; i =  n + 1; }     }   // for i      if ( i === n ) { if ( amount === 13 ) {  // 13 if ( k === 12 ) { r =  WSTM.util.gtin.faith( d ); } else { r =  -3; }        } else {   // 10 if ( k === 9 ) { k =  0; for ( i = 0; i < 9;  i++ ) { k +=  ( i + 1 )  *  d[ i ]; }  // for i               r  =  k % 11; if ( r === 10 ) { r =  40;   // X(88d) - 48 }           } else { r =  -3; }        }      }   // regular return r;   };   // .util.isbn.faith

WSTM.util.isbn.fault =  function ( alert, about, another ) { // Manage detected error // Precondition: //   alert    -- identifier of error message //   about    -- additional information as found, or false //               plain wikitext; will be HTML-escaped later //   another  -- error function other than WSTM built-in //               called with: another(alert, about) // Postcondition: //   Environment application package has been notified // Uses: //   .errors.found // 2012-10-02 PerfektesChaos@de.wikipedia if ( typeof another ===  "function" ) { another.call( null, alert, about ); } else { WSTM.errors.found( alert, false, about ); }  };   // .util.isbn.fault

WSTM.util.isbn.flip =  function ( adjust, another ) { // Find ISBN counterpart: ISBN-10 for ISBN-13, ISBN-13 for ISBN-10 // Precondition: //   adjust  -- string, should contain ISBN, may be formatted //   another  -- error function other than WSTM built-in // Postcondition: //   Returns formatted counterpart of adjust, or false // Uses: //   .util.isbn.format //   .util.isbn.faith // 2013-11-06 PerfektesChaos@de.wikipedia var g =  this.format( adjust, false, another ), r =  false, n, s;     if ( typeof g[ 0 ]  ===  "number" ) { s =  ( g[ 1 ] ? g[ 1 ] : adjust ).replace( /-/g, "" ); n =  s.length; s =  s.substr( 0,  n - 1 ); if ( n === 10 ) { n =  13; s =  "978" + s;         } else { n =  10; s =  s.substr( 3 ); }        n  =  this.faith( s, n ); if ( n >= 0 ) { s =  s   +   ( n === 40  ?  "X"  :  n ); g =  this.format( s, false, false ); r =  g[ 1 ]; }     }      return  r;   };   // .util.isbn.flip

WSTM.util.isbn.fold =  function ( ahead, area, adjust ) { // Divide ISBN substring, separate publisher and title numbers // Precondition: //   ahead   -- true: bookland 979;  false: 978 or none //   area    -- numeric group (0, 3, 99999 etc.) //   adjust  -- string with publisher and title numbers //              digits and hyphens only // Postcondition: //   Returns modified area+adjust, or false // Uses: //   >  .util.isbn.grouping // 2022-01-30 PerfektesChaos@de.wikipedia var f  =  this.grouping[ ( ahead ? 1 : 0 ) ], id =  area, j  =  adjust.indexOf( "-" ), r  =  false, s  =  adjust, d,         g,          i,          n,          k,          m;      if ( j < 0 ) { j =  false; } else { if ( ! j ) { s =  adjust.substr( 1 ); j =  false; } else { s =  s.substr( 0, j )  +  s.substr( j + 1 ); }  // leading hyphen k =  s.indexOf( "-" ); while ( k >= 0 ) { s =  s.substr( 0, k )  +  s.substr( k + 1 ); k =  s.indexOf( "-" ); j =  false; }  // while k      }   // one hyphen if ( f ) { n =  f.length; for ( i = 0; i < n;  i++ ) { g =  f[ i ]; m =  g[ 0 ]; if ( m === area ) { f =  false; break;  // for i            } }  // for i         if ( f ) { s =  area + s;            for ( i = 0;  i < n;  i++ ) { g =  f[ i ]; m =  g[ 0 ]; if ( m < 10 ) { k =  1; } else if ( m < 100 ) { k =  2; } else if ( m < 1000 ) { k =  3; } else if ( m < 10000 ) { k =  4; } else { k =  5; }              if ( m  ===  parseInt( s.substr( 0, k ),  10 ) ) { id =  m;                  s   =  s.substr( k ); f  =  false; break;  // for i               } }  // for i         } if ( ! f ) { n =  g.length; for ( i = 1; i < n;  i++ ) { f =  g[ i ];   // certain length k =  parseInt( s.substr( 0, f[ 0 ] ),  10 ); for ( m = 1; m < f.length;  m++ ) { d =  f[ m ]; if ( k >= d[ 0 ] &&  k <= d[ 1 ] ) { r =  d[ 2 ]; n =  -1; break;  // for m                  }   // match }  // for m            }   // for i         }   // group match }  // bookland if ( r ) { if ( j ) { if ( j === r &&  id === area ) { r =  false; }  // unchanged }  // one hyphen found if ( r ) { g =  s.substr( r ); r =  id  +  "-"  +  s.substr( 0, r ); if ( g ) { r =  r + "-" + g;            } }  // hyphen modified }  // publisher identified return r;   };   // .util.isbn.fold

WSTM.util.isbn.format =  function (adjust, ask, another) { // Parse ISBN string, reformat / standardize if necessary // Precondition: //   adjust   -- string, containing possible ISBN //   ask      -- 10:    require ISBN-10 //               13:    require ISBN-13 //               false: no type required //   another  -- error function other than WSTM built-in // Postcondition: //   Returns  array[2] //            [0] number  of characters successfully consumed //                        at least 10, some more for hyphens etc.      //                         [1] string  reformatted ISBN: //                                    insert hyphens etc.      //                                     spaces replaced by hyphens //                                    x->X //                                    hyphens inserted //                                            before checknumber //                                            at ISBN-13 //                            false   no formatting necessary //                false   adjust is invalid sequence //                        [1] error code -1,1...12 // Uses: //   >  .util.isbn.grouping //   .util.isbn.fault //   .util.isbn.faith //   .str.substrEnd //   .util.isbn.furnish //   .util.isbn.fold // Requires: JavaScript 1.3  charCodeAt   fromCharCode // 2022-01-30 PerfektesChaos@de.wikipedia var chain  =  false, i      =  0, impact =  0, last   =  false, lazy   =  false, loop   =  true, max    =  ( ask ? ask : 13 ), n      =  adjust.length, naked  =  0, r      =  [ false, false ], shift  =  "", scope  =  "", c,         j,          lead, lean, slang, swap; // Universelle Error-Funktion    impact-Nr.->msgName + s      while ( loop ) { c    =  adjust.charCodeAt(i); lead =  ( c >= 48  &&  c <= 57 ); if ( lead ) { if ( last ) { impact =  1;   // digit after 'X'               this.fault( "badISBNdigitAfterX",                           adjust.substr(0,  i + 1),                           another ); }        } else { switch ( c ) { case  32 :   // space case  46 :   // dot case 173 :   // shy case 8208 :  // hyphen case 8209 :  // nb-hyphen case 8210 :  // figure dash case 8211 :  // ndash case 8212 :  // mdash case 8213 :  // horizontal bar case 8259 :  // hyphen bullet case 8722 :  // minus case 9472 :  // box drawings light horizontal case  38 :   // '&' lazy =  true;   // fall-through case  45 :   // hyphen if ( c === 38 ) { swap =  adjust.substr( i, 6 ); if ( swap === " " ||                          swap === "&#160;"  ||                          swap === "&#xA0;"  ||                          swap === "&#xa0;" ) { i +=  5; } else { loop =  false; }                 }                  if ( chain ) { if ( naked < max ) { shift =  shift + "-"; }                    chain  =  false; } else if ( naked === max ) { if ( c === 45 ) { impact =  2;   // hyphen after last digit this.fault( "badISBNhyphenAfterEnd",                                   adjust.substr( 0,  i + 1 ),                                    another ); } else if ( ! lazy ) { loop =  false; }                 }                  break; case  88 :   // X               case  120 :   // x                  if ( last ) { impact =  3;   // multiple 'X'                     this.fault("badISBNmultipleX",                                adjust.substr(0,  i + 1),                                another); } else { last =  true; if (ask) { lead =  (naked  ===  ask - 1); } else { lead =  (naked === 9); }                    if (lead) { c =  88; } else { impact =  4;   // 'X' at bad position this.fault("badISBNXbadPosition",                                  adjust.substr(0,  i + 1),                                   another); }                 }                  break; default : loop =  false; break; }  // switch c         }   // no digit if ( lead ) { if ( ! impact ) { if ( naked === max ) { impact =  5;   // too many digits this.fault( "badISBNtooManyDigits1",                             adjust.substr( 0,  i + 1 ),                              another ); } else { c =  String.fromCharCode( c ); naked++; shift =  shift + c;                  scope  =  scope + c;                  chain  =  true; }  // loop }  // valid }  // lead if ( impact > 0 ) { loop =  false; }  // invalid if ( loop ) { i++; loop =  ( i < n ); }  // loop }  // while loop if ( ! impact ) { if ( ask ) { if ( naked !== ask ) { impact =  6;   // too many digits this.fault( "badISBNtooManyDigits2",                          adjust.substr( 0,  i + 1 ),                           another ); }        } else if ( naked !== 10  &&  naked !== 13 ) { impact =  7;   // bad number of digits this.fault("badISBNcountingDigits",                      "[" + naked + "] "                       +   adjust.substr( 0,  i + 1 ),                       another); }  // check length if ( ! impact ) { if ( naked === 13 ) { j =  shift.indexOf( "-" ); while ( j > 0 &&  j < 3 ) { shift =  shift.substr( 0, j ) + shift.substr( j + 1 ); j     =  shift.indexOf( "-" ); }  // while "-" c =  shift.substr( 0, 3 ); if ( c !== "978" &&  c !== "979" ) { impact =  8;   // bad bookland (EAN) in ISBN-13 this.fault( "badISBN13bookland",                             adjust.substr( 0,  i + 1 ),                              another ); } else if ( shift.substr( 3, 1 ) !==  "-" ) { shift =  shift.substr( 0, 3 ) + "-"  +  shift.substr( 3 ); }           }         } else if (naked < 5) {   // too short impact =  -1; }     }   // basically valid if ( ! impact ) { lean =  ( naked === 13 ); if ( lean ) { lead =  ( shift.charCodeAt( 2 )  ===  57 );   // 97*9* } else { lead =  false; }        j  =  shift.length; n =  j;         j--; if ( shift.charCodeAt( j ) === 45 ) {  // '-' n--; j--; shift =  shift.substr( 0, n ); }        c  =  this.faith( shift.substr( 0, j ),  naked ); if ( c < 0 ) { impact =  8 - c;   // invalid checkdigit switch ( c ) { case -1 : shift =  "badISBNcheckdigEmpty"; break; case -2 : shift =  "badISBNcheckdigChar"; break; case -3 : shift =  "badISBNcheckdigLength"; break; }  // switch faith this.fault( shift,  adjust.substr( 0,  i + 1 ),   another ); } else if ( c  !==   shift.charCodeAt( j )  -  48 ) { impact =  12;   // wrong checkdigit this.fault( "badISBNcheckdigWrong",                       adjust.substr(0,  i + 1),                        another ); }     }      if ( ! impact ) { c =  WSTM.str.substrEnd( shift, 1 ); if ( lean ) { if ( shift.substr( 3, 1 ) !==  "-" ) { shift =  shift.substr( 0, 3 ) + "-"  +  shift.substr( 3 ); n++; }        }         if ( shift.substr( n - 2,  1 )   !==   "-" ) { shift =  shift.substr( 0,  n - 1 )   +   "-"   +   c;         } slang =  shift.substr( ( lean ? 4 : 0 ) );        slang  =  slang.substr( 0,  slang.length - 2 ); j     =  slang.indexOf( "-" ); while (j > 0) { slang =  slang.substr(0, j)  +  slang.substr(j + 1); j     =  slang.indexOf("-"); }  // while "-" n =  1; c =  Number( slang.substr( 0, 1 ) ); if ( c === 1 ) { if ( lead  &&                 slang.substr( 1, 1 )  ===  "0" ) {   // 979-10 fr               n  =  2; c =  10; //           }         } else if ( c === 6 ) { n =  -1; c =  false; } else if ( c >= 8 ) { n =  2; c =  Number( slang.substr( 0, n ) ); if ( c > 94 ) { n =  3; c =  Number( slang.substr( 0, n ) ); if ( c > 989 ) { n =  4; c =  Number( slang.substr( 0, n ) ); if ( c > 9989 ) { n =  5;  // ERROR c =  Number( slang.substr( 0, n ) ); }              }            }         }         if ( n > 0 ) { swap =  slang.substr( n ); if ( lean ) {  // bookland scope  =  shift.substr( 0, 3 )  +  "-"; n     +=  4; } else { scope =  ""; }           if ( ! this.grouping ) { this.furnish; }           swap  =  this.fold( lead, c, swap ); if ( swap ) { shift =  scope  +  swap  +  WSTM.str.substrEnd(shift, 2); } else {  // not separated if ( scope + c + "-" !==  shift.substr( 0, n ) ) { if ( shift.charCodeAt( n ) === 45 ) {  // '-' n++; }  // already present shift =  scope  +  c  +  "-"  +  shift.substr( n ); }           }         }         r[ 0 ]  =  i;         if ( shift  !==  adjust.substr( 0, i ) ) { r[ 1 ] =  shift; }     } else { r[ 1 ] =  impact; }  // result return r;   };   // .util.isbn.format

WSTM.util.isbn.furnish =  function  { // Define ISBN separation between publisher and title numbers // Postcondition: //   Global variable was set // Uses: //    < .util.isbn.grouping // 2022-01-30 PerfektesChaos@de.wikipedia this.grouping =  [   // Commemorate LISP [  // 978 or none [ 0,   // en              [2, [ 0, 19, 2], [20, 69, 3],                 [70, 84, 4],                  [85, 89, 5],                  [90, 94, 6],                  [95, 99, 7]   ]              ],            [  1,   // en              [2, [ 0,  9, 2], [10, 39, 3],                 [40, 54, 4],                  [55, 85, 5]   ],              [4, [8600, 8697, 5],                  [8698, 9989, 6],                  [9990, 9999, 7]   ]              ],            [  2,   // fr              [2, [ 0, 19, 2], [20, 34, 3],                 [35, 39, 5],                  [40, 69, 3],                  [70, 83, 4],                  [84, 89, 5],                  [90, 94, 6],                  [95, 99, 7]   ]              ],            [  3,   // de              [2, [ 0,  0, 2], [ 5, 19, 2],                 [20, 69, 3],                  [70, 84, 4],                  [85, 89, 5],                  [90, 94, 6],                  [96, 96, 5],                  [97, 98, 7],                  [99, 99, 5]   ],              [3, [ 34,  36, 4],                  [ 37,  39, 5],                  [950, 953, 7],                  [954, 969, 5]   ]              ],            [  4,   // ja              [2, [ 0, 19, 2], [20, 69, 3],                 [70, 84, 4],                  [85, 89, 5],                  [90, 94, 6],                  [95, 99, 7]   ]              ],            [  5,   // ru/SU [2, [ 0, 19, 2],                 [20, 41, 3],                  [45, 69, 3],                  [70, 84, 4],                  [85, 89, 5],                  [90, 90, 6],                  [91, 91, 5],                  [92, 92, 4],                  [93, 94, 5],                  [96, 97, 7],                  [98, 98, 5]   ],              [3, [420, 420, 3],                  [421, 429, 4],                  [430, 430, 3],                  [431, 439, 4],                  [440, 440, 3],                  [441, 449, 4],                  [990, 990, 7],                  [991, 999, 4]   ],              [4, [9500, 9500, 7],                  [9501, 9599, 4]   ]              ],            [  7,   // cn              [2, [ 0,  9, 2], [10, 49, 3],                 [50, 79, 4],                  [80, 89, 5],                  [90, 99, 6]   ]              ],            [ 80,   // cz sk              [2, [ 0, 19, 2], [20, 69, 3],                 [70, 84, 4],                  [85, 89, 5],                  [90, 99, 6]   ]              ],            [ 81,   // in              [2, [ 0, 19, 2], [20, 69, 3],                 [70, 84, 4],                  [85, 89, 5],                  [90, 99, 6]   ]              ],            [ 82,   // no              [2, [ 0, 19, 2], [20, 69, 3],                 [70, 89, 4],                  [90, 98, 5],                  [99, 99, 6]   ]              ],            [ 83,   // pl              [2, [ 0, 19, 2], [20, 59, 3],                 [60, 69, 5],                  [70, 84, 4],                  [90, 99, 6]   ]              ],            [ 84,   // es              [2, [ 0, 14, 2], [15, 19, 5],                 [20, 69, 3],                  [70, 84, 4],                  [85, 89, 5],                  [90, 91, 4],                  [93, 94, 6],                  [95, 96, 5],                  [97, 99, 4]   ],              [3, [920, 923, 6],                  [924, 929, 5]   ]              ],            [ 85,   // br              [2, [ 0, 19, 2], [20, 59, 3],                 [60, 69, 5],                  [70, 84, 4],                  [85, 89, 5],                  [90, 98, 6],                  [98, 99, 5]   ]              ],            [ 86,   // rs me              [2, [ 0, 29, 2], [30, 59, 3],                 [60, 79, 4],                  [80, 89, 5],                  [90, 99, 6]   ]              ],            [ 87,   // dk              [2, [ 0, 29, 2], [40, 64, 3],                 [70, 79, 4],                  [85, 94, 5],                  [97, 99, 6]   ]              ],            [ 88,   // it              [2, [ 0, 19, 2], [20, 59, 3],                 [60, 84, 4],                  [85, 89, 5],                  [90, 94, 6],                  [95, 99, 5]   ]              ],            [ 89,   // kr              [2, [ 0, 24, 2], [25, 54, 3],                 [55, 84, 4],                  [85, 94, 5],                  [95, 99, 6]   ]              ],            [ 90,   // nl              [2, [ 0, 19, 2], [20, 49, 3],                 [50, 69, 4],                  [70, 79, 5],                  [80, 84, 6],                  [85, 89, 4],                  [90, 90, 2],                  [91, 93, 6],                  [94, 94, 2],                  [95, 99, 6]   ]              ],            [ 91,   // se              [2, [ 0,  1, 1], [20, 49, 2],                 [50, 64, 3],                  [70, 79, 4],                  [85, 94, 5],                  [97, 99, 6]   ]              ],            [ 92,   // int [2, [ 0, 5, 1],                  [60, 79, 2],                  [80, 89, 3],                  [90, 94, 4],                  [95, 98, 5],                  [99, 99, 6]   ]              ],           // 93       in            [ 94,   // nl              [1, [0, 5, 3], [6, 8, 4],                 [9, 9, 5]   ]              ],            [600,   // ir              [2, [ 0,  9, 2], [10, 49, 3],                 [50, 89, 4],                  [90, 99, 5]   ]             ],            [601,   // kz              [2, [ 0, 19, 2], [20, 69, 3],                 [70, 79, 4],                  [80, 84, 5],                  [85, 99, 2]   ]              ],            [602,   // id              [2, [ 0, 19, 2], [20, 79, 3],                 [80, 94, 4],                  [95, 99, 5]   ]              ],            [603,   // sa              [2, [ 0,  4, 2], [50, 79, 3],                 [80, 89, 4],                  [90, 99, 5]   ]              ],            [604,   // vn              [2, [ 0,  4, 1], [50, 89, 2],                 [90, 97, 3],                  [98, 99, 4]   ]              ],            [605,   // tr              [2, [ 0,  9, 2], [10, 39, 3],                 [40, 59, 4],                  [60, 89, 5]   ]              ],            [950,   // ar              [2, [ 0, 49, 2], [50, 89, 3],                 [90, 98, 4],                  [99, 99, 5]   ]              ],            [951,   // fi              [2, [ 0,  1, 1], [20, 54, 2],                 [55, 88, 3],                  [89, 94, 4],                  [95, 99, 5]   ]              ],            [952,   // fi              [2, [ 0, 19, 2], [20, 49, 3],                 [50, 59, 4],                  [60, 65, 2],                  [66, 66, 4],                  [67, 69, 5],                  [70, 79, 4],                  [80, 94, 2],                  [95, 98, 4],                  [99, 99, 5]   ]              ],            [953,   // hr              [2, [ 0,  0, 1], [10, 14, 2],                 [15, 54, 3],                  [55, 59, 5],                  [60, 94, 4],                  [95, 99, 5]   ]              ],            [954,   // bg              [2, [ 0, 20, 2], [30, 79, 3],                 [80, 89, 4],                  [90, 92, 5],                  [93, 99, 4]   ]              ],            [955,   // lk              [2, [ 0,  0, 1], [10, 19, 4],                 [20, 54, 2],                  [55, 79, 3],                  [80, 94, 4],                  [95, 99, 5]   ]              ],            [956,   // cl              [2, [ 0, 19, 2], [20, 69, 3],                 [70, 99, 4]   ]              ],            [957,   // tw              [2, [ 0,  2, 2], [ 3, 4, 4],                  [ 5, 19, 2],                  [20, 20, 4],                  [21, 27, 2],                  [28, 30, 5],                  [31, 43, 2],                  [44, 81, 3],                  [82, 96, 4],                  [97, 99, 5]   ]              ],            [958,   // co              [2, [ 0, 59, 2], [60, 79, 3],                 [80, 94, 4],                  [95, 99, 5]   ]              ],            [959,   // cu              [2, [ 0, 19, 2], [20, 69, 3],                 [70, 84, 4]   ]              ],            [960,   // gr              [2, [ 0, 19, 2], [20, 65, 3],                 [66, 68, 4],                  [69, 69, 3],                  [70, 84, 4],                  [85, 92, 5],                  [93, 93, 2],                  [94, 97, 4],                  [98, 99, 5]   ]              ],            [961,   // si              [2, [ 0, 19, 2], [20, 59, 3],                 [60, 89, 4],                  [90, 99, 5]   ]              ],            [962,   // hk              [2, [ 0, 19, 2], [20, 69, 3],                 [70, 84, 4],                  [85, 86, 5],                  [87, 89, 4],                  [90, 99, 3]   ]              ],            [963,   // hu              [2, [ 0, 19, 2], [20, 69, 3],                 [70, 84, 4],                  [85, 89, 5],                  [90, 99, 4]   ]              ],            [964,   // ir              [2, [ 0, 14, 2], [15, 24, 3],                 [25, 29, 4],                  [30, 54, 3],                  [55, 89, 4],                  [90, 96, 5],                  [97, 98, 3],                  [99, 99, 4]   ]              ],            [965,   // il              [2, [ 0, 19, 2], [20, 59, 3],                 [70, 79, 4],                  [90, 99, 5]   ]              ],            [966,   // ua              [2, [ 0, 19, 2], [20, 29, 4],                 [30, 69, 3],                  [70, 89, 4],                  [90, 99, 5]   ]              ],            [967,   // my              [2, [ 0, 29, 2], [30, 49, 3],                 [50, 59, 4],                  [60, 89, 2],                  [90, 98, 4]   ],              [3, [990, 989, 4],                  [999, 999, 5]   ]              ],            [968,   // mx              [2, [ 0, 39, 2], [40, 49, 3],                 [50, 79, 4],                  [80, 89, 5],                  [90, 99, 4]   ]              ],            [969,   // pk              [2, [ 0,  1, 1], [20, 39, 2],                 [40, 79, 3],                  [80, 99, 4]   ]              ],            [970,   // mx              [2, [ 0, 59, 2], [60, 89, 3],                 [90, 90, 4],                  [91, 96, 5],                  [97, 99, 4]   ]              ],            [971,   // ph              [2, [ 0,  1, 3], [ 2, 2, 2],                  [ 3,  5, 4],                  [ 6, 49, 2],                  [50, 84, 3],                  [85, 90, 4],                  [91, 99, 5]   ]              ],            [972,   // pt              [2, [ 0,  1, 1], [20, 54, 2],                 [55, 79, 3],                  [80, 94, 4],                  [95, 99, 5]   ]              ],            [973,   // ro              [2, [ 0,  0, 1], [10, 16, 3],                 [17, 19, 4],                  [20, 54, 2],                  [55, 75, 3],                  [76, 84, 4],                  [85, 88, 5],                  [89, 94, 4],                  [95, 99, 5]   ]              ],            [974,   // th              [2, [ 0, 19, 2], [20, 69, 3],                 [70, 84, 4],                  [85, 94, 5],                  [95, 99, 4]   ]              ],            [975,   // tr              [2, [ 0,  0, 5], [ 1, 24, 2],                 [25, 59, 3],                  [60, 91, 4],                  [92, 98, 5],                  [99, 99, 3]   ]              ],            [976,   // Caribbean Community [2, [ 0, 30, 1],                 [40, 59, 2],                  [60, 79, 3],                  [80, 94, 4],                  [95, 99, 5]   ]              ],            [977,   // eg              [2, [ 0, 19, 2], [20, 49, 3],                 [50, 69, 4],                  [70, 99, 3]   ]              ],            [978,   // ng              [2, [ 0, 19, 3], [20, 29, 4],                 [30, 79, 5],                  [80, 89, 4],                  [90, 99, 3]   ]              ],            [979,   // id              [2, [ 0,  9, 3], [10, 14, 4],                 [15, 19, 5],                  [20, 29, 2],                  [30, 39, 4],                  [40, 79, 4],                  [95, 99, 5]   ]              ],            [980,   // ve              [2, [ 0, 19, 2], [20, 59, 3],                 [60, 99, 4]   ]              ],            [981,   // sg              [2, [ 0, 19, 2], [20, 29, 3],                 [30, 99, 4]   ]              ],            [982,   // South Pacific [2, [ 0, 9, 2],                  [10, 69, 3],                  [70, 89, 2],                  [90, 99, 4]   ]              ],            [983,   // my              [2, [ 0,  1, 2], [ 2, 19, 3],                 [20, 39, 4],                  [40, 44, 5],                  [45, 79, 2],                  [80, 89, 3],                  [90, 98, 4],                  [99, 99, 5]   ]              ],            [984,   // bd              [2, [ 0, 39, 2], [40, 79, 3],                 [80, 89, 4],                  [90, 99, 5]   ]              ],            [985,   // by              [2, [ 0, 39, 2], [40, 59, 3],                 [60, 89, 4],                  [90, 99, 5]   ]              ],            [986,   // tw              [2, [ 0, 11, 2], [12, 55, 3],                 [56, 79, 4],                  [80, 99, 5]   ]              ],            [987,   // ar              [2, [ 0,  9, 2], [10, 19, 4],                 [20, 29, 5],                  [30, 49, 2],                  [50, 89, 3],                  [90, 94, 4],                  [95, 99, 5]   ]              ],            [988,   // hk              [2, [ 0, 16, 2], [17, 19, 5],                 [20, 79, 3],                  [80, 96, 4],                  [97, 99, 5]   ]              ],            [989,   // pt              [2, [ 0, 19, 1], [20, 54, 2],                 [55, 79, 3],                  [80, 94, 4],                  [95, 99, 5]   ]              ],            [9937,   // np              [2, [ 0, 29, 1], [30, 49, 2],                 [50, 79, 3],                  [80, 99, 4]   ]              ],            [9938,   // tn              [2, [ 0, 79, 2], [80, 94, 3],                 [95, 99, 4]   ]              ],            [9939,   // am              [2, [ 0, 49, 1], [50, 79, 2],                 [80, 89, 3],                  [90, 99, 4]   ]              ],            [9940,   // me              [2, [ 0, 19, 1], [20, 49, 2],                 [50, 89, 3],                  [90, 99, 4]   ]              ],            [9941,   // ge              [2, [ 0,  9, 1], [10, 39, 2],                 [40, 89, 3],                  [90, 99, 4]   ]              ],            [9942,   // ec              [3, [  0, 899, 2], [900, 994, 3],                 [995, 999, 4]   ]              ],            [9943,   // uz              [2, [ 0, 29, 2], [30, 39, 3],                 [40, 99, 4]   ]              ],            [9944,   // tr              [2, [ 0, 29, 2], [30, 49, 3],                 [50, 59, 4],                  [60, 89, 2],                  [90, 99, 3]   ]              ],            [9945,   // do              [2, [ 0,  0, 2], [ 1, 7, 3],                  [ 8, 39, 2],                  [40, 56, 3],                  [57, 57, 2],                  [58, 84, 3],                  [85, 99, 4]   ]              ],            [9946,   // kp              [2, [ 0, 19, 1], [20, 39, 2],                 [40, 89, 3],                  [90, 99, 4]   ]              ],            [9947,   // dz              [2, [ 0, 19, 1], [20, 79, 2],                 [80, 99, 3]   ]              ],            [9948,   // ae              [2, [ 0, 39, 2], [40, 84, 3],                 [85, 99, 4]   ]              ],            [9949,   // ee              [2, [ 0,  9, 1], [10, 39, 2],                 [40, 89, 3],                  [90, 99, 4]   ]              ],            [9950,   // ps              [2, [ 0, 29, 2], [30, 84, 3],                 [85, 99, 4]   ]              ],            [9951,   // Kosova [2, [ 0, 29, 2],                 [30, 84, 3],                  [85, 99, 4]   ]              ],            [9952,   // az              [2, [ 0, 19, 1], [20, 39, 2],                 [40, 79, 3],                  [80, 99, 4]   ]              ],            [9953,   // lb              [2, [ 0,  9, 1], [10, 39, 2],                 [40, 59, 3],                  [60, 89, 2],                  [90, 99, 4]   ]              ],            [9954,   // ma              [2, [ 0, 19, 1], [20, 39, 2],                 [40, 79, 3],                  [80, 99, 4]   ]              ],            [9955,   // lt              [2, [ 0, 39, 2], [40, 92, 3],                 [93, 99, 4]   ]              ],            [9956,   // cm              [2, [ 0,  9, 1], [10, 39, 2],                 [40, 89, 3],                  [90, 99, 4]   ]              ],            [9957,   // jo              [2, [ 0, 39, 2], [40, 69, 3],                 [70, 84, 2],                  [85, 99, 4]   ]              ],            [9958,   // ba              [2, [ 0,  9, 1], [10, 49, 2],                 [50, 89, 3],                  [90, 99, 4]   ]              ],            [9959,   // ly              [2, [ 0, 19, 1], [20, 79, 2],                 [80, 94, 3],                  [95, 99, 4]   ]              ],            [9960,   // sa              [2, [ 0, 59, 2], [60, 89, 3],                 [90, 99, 4]   ]              ],            [9961,   // dz              [2, [ 0, 29, 1], [30, 69, 2],                 [70, 94, 3],                  [95, 99, 4]   ]              ],            [9962,   // pa              [2, [ 0, 54, 2], [55, 55, 4],                 [56, 59, 2],                  [60, 84, 3],                  [85, 99, 4]   ]              ],            [9963,   // cy              [2, [ 0, 29, 1], [30, 54, 2],                 [55, 74, 3],                  [75, 99, 4]   ]              ],            [9964,   // gh              [2, [ 0, 69, 2], [70, 94, 3],                 [95, 99, 4]   ]              ],            [9965,   // kz              [2, [ 0, 39, 2], [40, 89, 3],                 [90, 99, 4]   ]              ],            [9966,   // ke              [2, [ 0, 69, 2], [70, 74, 4],                 [75, 95, 3],                  [96, 99, 4]   ]              ],            [9967,   // kg              [2, [ 0, 39, 2], [40, 89, 3],                 [90, 99, 4]   ]              ],            [9968,   // cr              [2, [ 0, 49, 2], [50, 93, 3],                 [94, 99, 4]   ]              ],            [9970,   // ug              [2, [ 0, 39, 2], [40, 89, 3],                 [90, 99, 4]   ]              ],            [9971,   // sg              [2, [ 0, 59, 1], [60, 89, 2],                 [90, 98, 3],                  [99, 99, 4]   ]              ],            [9972,   // pe              [2, [ 0,  9, 2], [10, 19, 1],                 [20, 24, 3],                  [25, 29, 4],                  [30, 59, 2],                  [60, 89, 3],                  [90, 99, 4]   ]              ],            [9973,   // tn              [2, [ 0,  5, 2], [ 6, 8, 3],                  [ 9,  9, 4],                  [10, 69, 2],                  [70, 96, 3],                  [97, 99, 4]   ]              ],            [9974,   // ug              [2, [ 0, 29, 1], [30, 54, 2],                 [55, 74, 3],                  [75, 94, 4],                  [95, 99, 2]   ]              ],            [9975,   // md              [2, [ 0,  0, 1], [10, 39, 3],                 [40, 44, 4],                  [45, 89, 2],                  [90, 94, 3],                  [95, 99, 4]   ]              ],            [9976,   // tz              [2, [ 0, 50, 1], [60, 89, 2],                 [90, 98, 3],                  [99, 99, 4]   ]              ],            [9977,   // cr              [2, [ 0, 89, 2], [90, 98, 3],                 [99, 99, 4]   ]              ],            [9978,   // ec              [2, [ 0, 29, 2], [30, 39, 3],                 [40, 94, 2],                  [95, 98, 3],                  [99, 99, 4]   ]              ],            [9979,   // is              [2, [ 0, 49, 1], [50, 64, 2],                 [65, 65, 3],                  [66, 75, 2],                  [76, 89, 3],                  [90, 99, 4]   ]              ],            [9980,   // pg              [2, [ 0, 30, 1], [40, 89, 2],                 [90, 98, 3],                  [90, 99, 4]   ]              ],            [9981,   // ma              [2, [ 0,  9, 2], [10, 15, 3],                 [16, 19, 2],                  [20, 79, 2],                  [80, 94, 3],                  [95, 99, 4]   ]              ],            [9982,   // zm              [2, [ 0, 79, 2], [80, 98, 3],                 [99, 99, 4]   ]              ],            [9983,   // gm              [2, [80, 94, 2], [95, 98, 3],                 [99, 99, 4]   ]              ],            [9984,   // lv              [2, [ 0, 49, 2], [50, 79, 3],                 [90, 99, 4]   ]              ],            [9985,   // ee              [2, [ 0, 49, 1], [50, 79, 2],                 [80, 89, 3],                  [90, 99, 4]   ]              ],            [9986,   // lt              [2, [ 0, 39, 2], [40, 89, 3],                 [90, 93, 4],                  [94, 96, 3],                  [97, 99, 2]   ]              ],            [9987,   // tz              [2, [ 0, 39, 2], [40, 87, 3],                 [88, 99, 4]   ]              ],            [9988,   // gh              [2, [ 0, 29, 1], [30, 54, 2],                 [55, 74, 3],                  [75, 99, 4]   ]              ],            [9989,   // mk              [2, [ 0,  0, 1], [10, 19, 3],                 [20, 29, 4],                  [60, 94, 3],                  [95, 99, 4]   ]              ],            [99901,   // bh              [2, [ 0, 49, 2], [50, 79, 3],                 [80, 99, 2]   ]              ],          // 99902,   // ga   no ranges fixed yet [99903,  // mu              [2, [ 0, 19, 1], [20, 89, 2],                 [90, 99, 3]   ]              ],            [99904,   // an              [2, [ 0, 59, 1], [60, 89, 2],                 [90, 99, 3]   ]              ],            [99905,   // bo              [2, [ 0, 39, 1], [40, 79, 2],                 [80, 99, 3]   ]              ],            [99906,   // kw              [2, [ 0, 29, 1], [30, 59, 2],                 [60, 69, 2],                  [70, 89, 2],                  [90, 99, 1]   ]              ],            [99908,   // mw              [2, [ 0,  0, 1], [10, 89, 2],                 [90, 99, 3]   ]              ],            [99909,   // mt              [2, [ 0, 39, 1], [40, 94, 2],                 [95, 99, 3]   ]              ],            [99910,   // sl              [2, [ 0, 29, 1], [30, 89, 2],                 [90, 99, 3]   ]              ],            [99911,   // ls              [2, [ 0, 59, 2], [60, 99, 3]  ]              ],            [99912,   // bw              [2, [ 0, 39, 1], [40, 59, 3],                 [60, 89, 2],                  [90, 99, 3]   ]              ],            [99913,   // ad              [3, [  0, 299, 1], [439, 350, 2],                 [600, 604, 3]   ]              ],            [99914,   // sr              [2, [ 0, 49, 1], [50, 89, 2],                 [90, 94, 3]   ]              ],            [99915,   // mv              [2, [ 0, 49, 1], [50, 79, 2],                 [80, 99, 3]   ]              ],            [99916,   // na              [2, [ 0, 29, 1], [30, 69, 2],                 [70, 99, 3]   ]              ],            [99917,   // bn              [2, [ 0, 29, 1], [30, 89, 2],                 [90, 99, 3]   ]              ],            [99918,   // fo              [2, [ 0, 39, 1], [40, 79, 2],                 [80, 99, 3]   ]              ],            [99919,   // bj              [2, [ 0, 29, 1], [40, 69, 2],                 [90, 99, 3]   ]              ],            [99920,   // ad              [2, [ 0, 49, 1], [50, 89, 2],                 [90, 99, 3]   ]              ],            [99921,   // qa              [2, [ 0,  9, 1], [20, 69, 2],                 [70, 79, 3],                  [80, 89, 1],                  [90, 99, 2]   ]              ],            [99922,   // gt              [2, [ 0, 39, 1], [40, 69, 2],                 [70, 99, 3]   ]              ],            [99923,   // sv              [2, [ 0, 19, 1], [20, 79, 2],                 [80, 99, 3]   ]              ],            [99924,   // ni              [2, [ 0, 29, 1], [30, 79, 2],                 [80, 99, 3]   ]              ],            [99925,   // py              [2, [ 0, 39, 1], [40, 79, 2],                 [80, 99, 3]   ]              ],            [99926,   // hn              [2, [ 0,  9, 1], [10, 59, 2],                 [60, 99, 3]   ]              ],            [99927,   // al              [2, [ 0, 29, 1], [30, 59, 2],                 [60, 99, 3]   ]              ],            [99928,   // ge              [2, [ 0,  9, 1], [10, 79, 2],                 [80, 99, 3]   ]              ],            [99929,   // mn              [2, [ 0, 49, 1], [50, 79, 2],                 [80, 99, 3]   ]              ],            [99930,   // am              [2, [ 0, 49, 1], [50, 79, 2],                 [80, 99, 3]   ]              ],            [99931,   // sc              [2, [ 0, 49, 1], [50, 79, 2],                 [80, 99, 3]   ]              ],            [99932,   // mt              [2, [ 0,  9, 1], [10, 59, 2],                 [60, 69, 3],                  [70, 79, 1],                  [80, 99, 2]   ]              ],            [99933,   // np              [2, [ 0, 29, 1], [30, 59, 2],                 [60, 99, 3]   ]              ],            [99934,   // do              [2, [ 0, 19, 1], [20, 79, 2],                 [80, 99, 3]   ]              ],            [99935,   // ht              [2, [ 0, 29, 1], [30, 59, 2],                 [60, 69, 3],                  [70, 89, 1],                  [90, 99, 2]   ]              ],            [99936,   // bt              [2, [ 0,  9, 1], [10, 59, 2],                 [60, 99, 3]   ]              ],            [99937,   // mo              [2, [ 0, 19, 1], [20, 59, 2],                 [60, 99, 3]   ]              ],            [99938,   // Srpska [2, [ 0, 19, 1],                 [20, 59, 2],                  [60, 69, 3],                  [90, 99, 2]   ]              ],            [99939,   // gt              [2, [ 0, 59, 1], [60, 89, 2],                 [90, 99, 3]   ]              ],            [99940,   // ge              [2, [ 0,  9, 1], [10, 69, 2],                 [70, 99, 3]   ]              ],            [99941,   // am              [2, [ 0, 29, 1], [30, 79, 2],                 [80, 99, 3]   ]              ],            [99942,   // sd              [2, [ 0, 49, 1], [50, 79, 2],                 [80, 99, 3]   ]              ],            [99943,   // al              [2, [ 0, 29, 1], [30, 59, 2],                 [60, 99, 3]   ]              ],            [99944,   // et              [2, [ 0, 49, 1], [50, 79, 2],                 [80, 99, 3]   ]              ],            [99945,   // na              [2, [ 0, 59, 1], [60, 89, 2],                 [90, 99, 3]   ]              ],            [99946,   // np              [2, [ 0, 29, 1], [30, 59, 2],                 [60, 99, 3]   ]              ],            [99947,   // tj              [2, [ 0, 29, 1], [30, 69, 2],                 [70, 99, 3]   ]              ],            [99948,   // er              [2, [ 0, 49, 1], [50, 79, 2],                 [80, 99, 3]   ]              ],            [99949,   // mu              [2, [ 0, 19, 1], [20, 89, 2],                 [90, 99, 3]   ]              ],            [99950,   // kh              [2, [ 0, 49, 1], [50, 79, 2],                 [80, 99, 3]   ]              ],          // 99951,   // cg   no ranges fixed yet [99952,  // ml              [2, [ 0, 49, 1], [50, 79, 2],                 [80, 99, 3]   ]              ],            [99953,   // py              [2, [ 0, 29, 1], [30, 79, 2],                 [80, 99, 3]   ]              ],            [99954,   // bo              [2, [ 0, 29, 1], [30, 69, 2],                 [70, 99, 3]   ]              ],            [99955,   // Srpska [2, [ 0, 19, 1],                 [20, 59, 2],                  [60, 89, 3],                  [90, 99, 2]   ]              ],            [99956,   // al              [2, [ 0, 59, 2], [60, 99, 3]  ]              ]                  ],         [   // 979            [ 0,              [1, [0, 9, 8]   ]              ],            [ 2,              [1, [0, 9, 8]   ]              ],            [ 3,              [1, [0, 9, 8]   ]              ],            [ 4,              [1, [0, 9, 8]   ]              ],            [ 5,              [1, [0, 9, 8]   ]              ],            [ 6,              [1, [0, 9, 8]   ]              ],            [ 7,              [1, [0, 9, 8]   ]              ],            [ 8,   // USA [2, [ 0, 19, 8],                 [20, 21, 3],                  [22, 39, 8],                  [40, 79, 4]   ],              [3, [800, 884, 8],                  [885, 899, 5],                  [900, 984, 8],                  [985, 986, 7],                  [987, 999, 8]   ]              ],            [ 9,              [1, [ 0, 9, 8]   ]              ],            [ 10,   // fr              [2, [ 0, 19, 2], [20, 69, 3],                 [70, 89, 4]   ],              [3, [900, 975, 5],                  [976, 999, 6]   ]              ],            [ 11,   // ROK [2, [ 0, 24, 2],                 [25, 54, 3],                  [55, 84, 4],                  [85, 94, 5],                  [95, 99, 6]   ]              ],            [ 12,   // ITA [2, [ 0, 19, 7],                 [20, 29, 3]   ],              [3, [300, 544, 7],                  [545, 599, 4],                  [600, 799, 7],                  [800, 849, 5],                  [850, 999, 7]   ]              ],            [ 13,              [1, [0, 9, 7]   ]              ],            [ 14,              [1, [0, 9, 7]   ]              ],            [ 15,              [1, [0, 9, 7]   ]              ],            [ 16,              [1, [0, 9, 7]   ]              ],            [ 17,              [1, [0, 9, 7]   ]              ],            [ 18,              [1, [0, 9, 7]   ]              ],            [ 19,              [1, [0, 9, 7]   ]              ]                  ]                ];   // .util.isbn.grouping };  // .util.isbn.furnish

};  // .bb.isbn mw.libs.WikiSyntaxTextMod.bb.isbn(mw.libs.WikiSyntaxTextMod); delete mw.libs.WikiSyntaxTextMod.bb.isbn;

//---

mw.libs.WikiSyntaxTextMod.bb.issn =  function (WSTM) { // ISSN syntax analysis, code correction and formatting // Public: //   .util.issn.format // Uses: //   .util.fiatObjects //   .errors.found // 2013-06-27 PerfektesChaos@de.wikipedia "use strict"; WSTM.util.fiatObjects(WSTM.util, "issn");

WSTM.util.issn.faith =  function (acquired) { // Compute and compare ISSN check digit (4-4) // Precondition: //   acquired  -- Array(8) with digits 0...9, or 10 at [7] // Postcondition: //   Returns  true if valid // 2013-08-03 PerfektesChaos@de.wikipedia var k =  0, i;     for (i = 0;  i < 7;  i++) { k +=  acquired[i]  *  (8 - i); }  // for i      k  =  (11  -  k % 11)   %   11; return (k === acquired[7]); };  // .util.issn.faith

WSTM.util.issn.fashion =  function (acquired) { // Format ISSN digits for 8 or 13 // Precondition: //   acquired  -- Array(8) with digits 0...9, or 10 at [7] // Postcondition: //   Returns  true if valid // Requires: JavaScript 1.3  fromCharCode // 2013-06-20 PerfektesChaos@de.wikipedia var i,         n  =  acquired.length, r;     if ( n === 8 ) { r =  ""; for ( i = 0; i < 4;  i++ ) { r =  r + String.fromCharCode( acquired[i] + 48 ); }  // for i         r  =  r + "-"; for ( i = 4; i < 7;  i++ ) { r =  r + String.fromCharCode( acquired[i] + 48 ); }  // for i         if ( acquired[7] === 10 ) { r =  r + "X"; } else { r =  r + String.fromCharCode( acquired[7] + 48 ); }     } else if ( n === 13 ) { r =  "977-"; for ( i = 3; i < 10;  i++ ) { r =  r + String.fromCharCode( acquired[i] + 48 ); }  // for i         r  =  r + "-"; for ( i = 10; i < 12;  i++ ) { r =  r + String.fromCharCode( acquired[i] + 48 ); }  // for i         r  =  r + "-" + String.fromCharCode( acquired[12] + 48 ); }     return  r;   };   // .util.issn.fashion

WSTM.util.issn.fetch =  function ( attempt ) { // Convert presumable ISSN code into Array // Precondition: //   attempt  -- ISSN code (no leading keyword) // Postcondition: //   Returns Array with digits 0...9, or 10 at last position // Uses: //   .util.code.fetch // Requires: JavaScript 1.3  charCodeAt   fromCharCode // 2013-06-23 PerfektesChaos@de.wikipedia var n =  attempt.length, m,         r;      if ( n >= 13   &&   attempt.substr( 0, 3 ) ===  "977" ) {   // EAN m =  13; } else { m =  8; }     r  =  WSTM.util.code.fetch( attempt, m, 8, "ISSN" ); return r;   };   // .util.issn.fetch

WSTM.util.issn.format =  function (adjust) { // Format ISSN code // Precondition: //   adjust  -- ISSN code (no leading keyword) // Postcondition: //   Returns false if valid, or string if to be corrected // Uses: //   .util.issn.fetch //   .util.issn.faith //   .util.gtin.faith // 2013-06-23 PerfektesChaos@de.wikipedia var issn =  this.fetch( adjust ), r    =  false, n;     if ( issn ) { n =  issn.length; if ( n === 8 ||  n === 13 ) { if ( n === 8 ) { if ( ! this.faith( issn ) ) { WSTM.errors.found( "badISSNcheckdig", false, adjust ); issn =  false; }           } else if ( WSTM.util.gtin.faith( issn ) !== issn[ 12 ] ) { issn =  false; WSTM.errors.found( "badISSNcheckdig", false, adjust ); }           if (issn) { r =  this.fashion(issn); if (r === adjust) { r =  false; }           }         } else { WSTM.errors.found("badISSNstrange", false, adjust); }     }      return  r;   };   // .util.issn.format

};  // .bb.issn mw.libs.WikiSyntaxTextMod.bb.issn(mw.libs.WikiSyntaxTextMod); delete mw.libs.WikiSyntaxTextMod.bb.issn;

//---

mw.libs.WikiSyntaxTextMod.bb.lccn =  function (WSTM) { // LCCN syntax analysis, code correction and formatting // Public: //   .util.lccn.format // Uses: //   .util.fiatObjects // 2013-06-27 PerfektesChaos@de.wikipedia "use strict"; WSTM.util.fiatObjects( WSTM.util, "lccn" );

WSTM.util.lccn.format =  function (attempt, apply) { // Check LCCN code // Precondition: //   attempt  -- LCCN code (no leading keyword) //   apply   -- '/' or '-' (true='-') or false // Postcondition: //   Returns false if valid, //           Array with //                 [0] string if to be adjusted, or false //                 [1] error info (could be false) // Uses: //   >< .util.urn.re.* // 2015-03-25 PerfektesChaos@de.wikipedia // a{1,2}9{2|4}9{1,6} // n79022889 -> n/79/22889 -> n79-22889 // nr00001027 -> nr/00/1027 // xx2001000555 -> xx/2001/555 // yyyy>2000 var r =  false, d, got, j, s, small; if ( typeof this.re !==  "object" ) { this.re         =  { }; this.re.pre     =  new RegExp( "^ *([A-Za-z]{1,3})?"                                         + "([/0-9])"                                         + "(.+[^ \n])[ \n]*$",                                         "" ); this.re.year    =  new RegExp( "^([0-9][0-9])"                                         + "([0-9][0-9])"                                         + "([0-9]*)$",                                         "" ); this.re.yearser =  new RegExp( "^(([0-9][0-9])|(20[0-9][0-9]))"                                         + "([/-])"                                         + "(.+)",                                         "" ); }     if ( attempt ) { got = this.re.pre.exec( attempt ); if ( got ) { s =  got[ 1 ]; if (s) { small =  s.toLowerCase; if (s !== small) { r =  small + got[ 2 ] + got[ 3 ]; }           } else { small =  false; }           if ( got[2] === "/" ) { got =  this.re.yearser.exec( got[ 3 ] ); if ( got ) { if (got[ 4 ] !== "/") { got =  false; }              }               if ( got ) { j =  got[ 3 ]; } else { r =  [ r, "invalid slash segmentation" ]; }           } else { s   =  got[ 2 ] + got[ 3 ]; got =  this.re.yearser.exec(s); if ( got ) { j =  ( got[4] === "-"  ?  got[3]  :  false ); } else { got = this.re.year.exec(s); if (got) { if (got[1] === "20") { j      =  got[1] + got[2]; got[5] =  got[3]; } else { j      =  got[1]; got[5] =  got[2] + got[3]; }                 }               }            }         } else { r =  [ false, "invalid prefix" ]; }        if ( j   &&   typeof r  !==  "object" ) { d =  j.length; if ( d !== 2 &&  d !== 4 ) { r =  false; } else if ( apply === "/" ) { r =  ( small  ?  small + "/"  :  "" ) + j + "/" + got[ 5 ]; } else if ( apply === "-" ||  apply === true ) { r =  ( small ? small : "" )  +  j  +  "-"  +  got[ 5 ]; } else { r =  ( small ? small : "" )  +  j  +  got[ 5 ]; }           if ( r ) { j =  parseInt( j, 10 ); if ( j > 2000 ) { d =  new Date; if ( j > d.getFullYear ) { r =  false; }              } else if ( j > 100 ) { r =  false; }           }            if ( ! r ) { r =  [ r,  "invalid year: " + j ]; }        }         if ( typeof r  ===  "string" ) { r =  [ r, false ]; }     }      return  r;   };   // .util.lccn.format

};  // .bb.lccn mw.libs.WikiSyntaxTextMod.bb.lccn(mw.libs.WikiSyntaxTextMod); delete mw.libs.WikiSyntaxTextMod.bb.lccn;

//---

mw.libs.WikiSyntaxTextMod.bb.urn =  function (WSTM) { // URN syntax analysis, code correction and formatting // Public: //   .util.urn.failure // Uses: //   .util.fiatObjects // 2013-06-27 PerfektesChaos@de.wikipedia "use strict"; WSTM.util.fiatObjects( WSTM.util, "urn" );

WSTM.util.urn.sns =    ":3gpp:cablelabs:cgi:clei:dgiwg:dvb:ebu:epc" + ":epcglobal:example:fdc:fipa:geant:ietf:iptc" + ":isan:isbn:iso:issn:ivis:lex:liberty:mace" + ":mpeg:nbn:nena:newsml:nfc:nzl:oasis:ogc:ogf" + ":oid:oipf:oma:pin:publicid:s1000d:schac" + ":service:smpte:swift:tva:uci:ucode:uuid" + ":web3d:xmlorg:xmpp:";

WSTM.util.urn.failure =  function (attempt) { // Is URN URI invalid? // Precondition: //   attempt  -- URN // Postcondition: //   Returns false if valid, //           string if to be adjusted, //           or Array with error info [1] // Uses: //   >  .util.urn.sns //   >< .util.urn.re.* //   .util.isEscValid // 2013-06-27 PerfektesChaos@de.wikipedia var r =  false, crash, got, small, space, subject, swap; if ( typeof this.re !==  "object" ) { this.re         =  { }; this.re.chr =  new RegExp( "([^-A-Za-z0-9+,.:=@;$_!*'%].*)$",                                     "" ); this.re.org =  new RegExp( "^ *"                                     + "(urn:)"                                     + "([A-Za-z0-9]+:)?"                                     + "(.*[^ \n])"                                     + "[ \n]*",                                     "i" ); }     if ( attempt ) { got =  this.re.org.exec( attempt ); if ( got ) { space =  got[2]; if ( space ) { space =  space.toLowerCase; if (this.sns.indexOf(":" + space) >=  0) { small   =  "urn:" + space; subject =  got[3]; swap    =  WSTM.util.isEscValid(subject); crash   =  this.re.chr.exec(subject); if (crash) { r =  [ false,  "bad character: " + crash[1]]; } else if (swap) { r =  [ false,  "bad escaping: " + swap]; } else if (got[1] + got[2] !==  small) { r =  small + subject; }              } else { r =  [ false, "unknown namespace" ]; }           } else { r =  [ false, "missing namespace" ]; }        } else { r =  [ false, "invalid scheme (urn:)" ]; }     }      return  r;   };   // .util.urn.failure

};  // .bb.urn mw.libs.WikiSyntaxTextMod.bb.urn(mw.libs.WikiSyntaxTextMod); delete mw.libs.WikiSyntaxTextMod.bb.urn;

//---

mw.libs.WikiSyntaxTextMod.bb.regexp =  function ( WSTM ) { // Support for user defined regexp // Public: //   .util.regexp.fiat //   .util.regexp.flag // Uses: //   .util.fiatObjects // 2012-05-26 PerfektesChaos@de.wikipedia "use strict"; WSTM.util.fiatObjects( WSTM.util, "regexp" );

WSTM.util.regexp.fault =  function ( attempt ) { // Guess whether attempt is a RegExp object // Precondition: //   attempt  -- thing to be tested // Postcondition: //   Return  string with error info, or false if appears to be RE      // 2012-11-15 PerfektesChaos@de.wikipedia var r =  false; if ( attempt ) { if ( typeof attempt ===  "object" ) { if ( typeof attempt.ignoreCase !==  "boolean" ) { r =  "Object not RegExp"; }        } else { r =  "RegExp definition not object"; }     } else { r =  "Empty RegExp definition (" + attempt + ")"; }     return  r;   };   // .util.regexp.fault

WSTM.util.regexp.fiat =  function ( attempt, adjust, alert ) { // Safe creation of RegExp from regexp string // Precondition: //   attempt  -- pattern string to be tested //   adjust   -- optional string: flags //   alert    -- optional location for immediate error message // Postcondition: //   Returns RegExp object if no error detected,  or      //            in case of error //           string with error message and data, if not alert,  or      //            false if message displayed // Uses: //   .util.regexp.fault //   .lang.text.fetch //   .main.fault // 2013-05-28 PerfektesChaos@de.wikipedia var r  =  false, s  =  false, lt, sf; switch ( typeof attempt ) { case "string": if ( attempt ) { lt =  ( typeof adjust  ===  "string" ); sf =  ( lt ? adjust : "" ); try { r =  new RegExp( attempt, sf ); } catch ( err ) { s =  err + "\n" + attempt; if ( adjust ) { s =  s + "\nflags: " + adjust; }              }   // try-catch } else { s =  "Empty string"; }           break; case "object": s =  this.fault( attempt ); if ( ! s ) { r =  attempt; }           break; default: s =  "Invalid type"; }  // switch typeof attempt if ( s ) { if ( alert ) { WSTM.main.fault( WSTM.lang.text.fetch( "BadRegExp" ) + s,                            alert ); r =  false; } else { r =  s;         } }     return  r;   };   // .util.regexp.fiat

WSTM.util.regexp.flag =  function (attempt, apply, about) { // Is attempt a well-formed regexp string? // Precondition: //   attempt  -- flag string to be tested, or false //   apply    -- default flags //   about    -- user info // Postcondition: //   Return value  --  flag string // Versioning: //   'm' flag applied //       available for JavaScript = 1.5+ //       required by:  IE 8   for  "^...$" line matches //   'y' proprietary flag applied // Uses: //   .lang.text.fetch //   .main.fault // 2012-05-26 PerfektesChaos@de.wikipedia var r =  apply, l,         s;      if ( attempt ) { l =  ( typeof attempt  ===  "string"); if ( l ) { l =  (attempt.search(/[^gGiImMyY]/) < 0); if ( l ) { s =  attempt.toLowerCase; if ( s.indexOf( "g" ) < 0 ) { if ( r.indexOf( "g" ) >= 0 ) { r =  r.replace( /g/, "" ); }              }   // not global if ( s.indexOf( "i" ) >= 0 ) { r =  r + "i"; }  // ignoreCase if ( s.indexOf( "y" ) >= 0 ) { r =  r + "y"; }           }         }         if ( ! l ) { WSTM.main.fault( WSTM.lang.text.fetch( "BadRegExpFlag" )                            + " " + attempt,                             about ); }     }      return  r;   };   // .util.regexp.flag

};  // .bb.regexp mw.libs.WikiSyntaxTextMod.bb.regexp(mw.libs.WikiSyntaxTextMod); delete mw.libs.WikiSyntaxTextMod.bb.regexp;

//---

mw.libs.WikiSyntaxTextMod.bb.translate =  function (WSTM) { // String translation map // Public: //   .util.translate.factory //   .util.translate. //   .util.translate.flip //   .util.translate.further // Uses: //   .util.fiatObjects // 2012-05-27 PerfektesChaos@de.wikipedia "use strict"; WSTM.util.fiatObjects( WSTM.util, "translate" );

WSTM.util.translate.factory =  function ( adjust, about ) { // Fast definition of replacements (internal) // Precondition: //   adjust  -- array of mappings //              Each mapping is an array of strings. //              It is either  [re, rp]  or  [re, rp, flag]. //              re   -- regular expression string //              rp   -- replacement string or function //              flag -- RegExp-Flag; Standard is "g" //                      alternatively: "gi", "i", "" //                      (g for global, i for ignoreCase) //   about   -- context (variable name) // Postcondition: //   Returns array of mappings. //   Each mapping is an array [RE, rp]. //                            RE -- RegExp object //                            rp -- replacement string (unchanged) // Uses: //   .main.fault // Requires: JavaScript 1.2 // 2012-05-27 PerfektesChaos@de.wikipedia var n =  adjust.length, r =  new Array(n), e, f, i, m, s;     for ( i = 0;  i < n;  i++ ) { m =  adjust[i]; f =  ( m.length < 3  ?  "g"                               :  m[ 2 ] ); s =  m[ 0 ]; try { e =  new RegExp( s, f ); } catch ( err ) { WSTM.main.fault( "RegExp error:\n"                            + err + "\n"                             + s + "\nin " + about + "[" + i + "]",                             false ); r.splice( i, 1 ); i--; break; }  // try-catch r[ i ] =  [ e,  m[ 1 ] ]; }  // for i      return  r;   };   // .util.translate.factory

WSTM.util.translate.fiat =  function ( assign, apply, about ) { // Transfer user defined pair of regexp string and replacement // Precondition: //   assign  -- array of strings  [re, rp, flags]  to be evaluated //                                re  -- may be string or RegExp //                                       if string than flags //   apply   -- default flags //   about   -- user info // Postcondition: //   Return value  --  false if not applicable //                     array[2] with RegExp and replacement // Uses: //   .util.isArray //   .util.regexp.flag //   .util.regexp.fault //   .main.fault // 2012-11-15 PerfektesChaos@de.wikipedia var r   =  false, bug, s,         sf, sh, sr; if ( WSTM.util.isArray( assign ) ) { if ( assign.length > 1 ) { bug =  false; sh  =  assign[ 1 ]; s   =  typeof sh; if ( s === "string" ||  s === "function" ) { sr =  assign[ 0 ]; if ( sr === false ||  sr === true  ||  sr === "" ) { sr =  "^.*$"; }              switch ( typeof sr ) { case "string": if ( assign.length < 3 ) { sf =  apply; } else { sf =  WSTM.util.regexp.flag( assign[ 2 ],                                                      apply,                                                      about ); }                    try { r =  [ new RegExp( sr, sf ),  sh ]; } catch (err) { bug = err + "\n" + sr; if ( typeof sf ===  "string") { bug =  bug + "\nflags:  " + sf; }  // adjust provided bug =  [ "BadRegExp", bug ]; }  // try-catch break; case "object": bug =  WSTM.util.regexp.fault(sr); if ( bug ) { bug =  [ bug, false ]; } else { r =  [ sr, sh ]; }                    break; }  // switch typeof assign[0] } else { bug =  [ "IsNotStringOrFunction", sh ]; }           if ( bug ) { WSTM.main.fault( WSTM.lang.text.fetch( bug[ 0 ] ),                               bug[ 1 ] ); }        }      }      return  r;   };   // .util.translate.fiat

WSTM.util.translate.flip =  function ( adjust, apply ) { // Modify string by multiple replacement // Precondition: //   adjust  -- string to be modified //   apply   -- array of mappings //              Each mapping is an array  [RE, rp]. //              RE  -- RegExp object //              rp  -- replacement string // Postcondition: //   Returns modified string, even unchanged. // Requires: JavaScript 1.2  replace // 2012-05-27 PerfektesChaos@de.wikipedia var n =  apply.length, r =  adjust, i,         s,          t,          x;      for ( i = 0;  i < n;  i++ ) { t =  apply[i]; x =  t[1]; s =  typeof x;         if ( s === "string" ) { r =  r.replace(t[0], x); } else if ( s === "function" ) { r =  r.replace( t[ 0 ],  x( 1, i, 0, r ) ); }     }   // for i      return  r;   };   // .util.translate.flip

WSTM.util.translate.further =  function (add, all, adhere, already) { // Definition of additional replacements by user // Precondition: //   add      -- array of mappings to be added //               Each mapping is an array of strings. //               For details see  this.factory //   all      -- accumulated array of mappings //               false if empty (internally created) //               extended if not empty and valid array of mappings //   adhere   -- User visible name of add (optional string) //   already  -- optional //               User is an expert now, mapping already checked // Postcondition: //   Return value  -- all has been extended //                    (created RE objects instead if re strings) //                    if successful and input data valid, //                    false if error detected // Remark: //   Function can be called several times; //   mappings will cumulate in order of applying. // Versioning: //   'm' flag applied //       available for JavaScript = 1.5+ //       required by:  IE 8   for  "^...$" line matches //   'y' proprietary flag applied // Uses: //   .util.isArray //   .lang.text.fetch //   .util.regexp.flag //   .util.regexp.fiat //   .main.fault // Requires: JavaScript 1.3  charCodeAt // 2012-07-15 PerfektesChaos@de.wikipedia var s       =  false, story   =  ( typeof adhere  ===  "string"                                                    ?  adhere                                                    :  "'add.further'" ), wstmTXT =  WSTM.lang.text.fetch, c, e, f, i, j, k, learnt, n, source, x;     if ( WSTM.util.isArray( add ) ) { learnt =  ( already ? true : false ); n      =  add.length; if ( ! all ) {  // new k   =  0; all =  new Array(n); } else {  // expand k   =  all.length; all =  all.concat( new Array( n ) ); }  // all for ( i = 0; i < n;  i++ ) { e =  add[i]; if ( WSTM.util.isArray( e ) ) { c =  e.length; if ( learnt ) {  // no debug if ( c > 2 ) { x =  e[ 2 ]; } else { c =  2; }              } else { source =  story + " #" + ( i+1 ) + " "; if ( c < 2 ) { s =  source + wstmTXT( "Not" ) + " min. Array(2)"; break; } else if ( typeof e[0] !==  "string" ) { s =  "regexp in " + source + wstmTXT( "IsNotAString" ); break; } else if ( typeof e[1] !==  "string"  &&                              typeof e[1]  !==  "function" ) { s =  wstmTXT( "ReplacementIn" ) + " " + source + wstmTXT( "IsNotStringOrFunction" ); break; } else if ( c > 4 ) { s =  source + wstmTXT( "HasMoreThan4Elements" ); break; } else if ( c > 2 ) { x =  e[ 2 ]; if ( typeof x ===  "string") { x =  x.toLowerCase; for ( j = x.length - 1; j >= 0;  j-- ) { switch (x.charCodeAt(j)) { case 103 :  // g                           case 105 :   // i                           case 109 :   // m                           case 121 :   // y                              break; default : s =  "flag '" + x[j] + "' in " + source + wstmTXT("Invalid") + ": '" + e[2] + "'"; break; }  // switch charCodeAt }  // for j-- } else { if ( c > 3 ) { if ( x &&                                x !== null  &&                                x !== undefined ) { s =  "flag in " + source + wstmTXT( "IsNotAString" ); break; }  // skip empty element, leave flag default }  // may be ', ,' c =  2; }   // e[2] flag }              }   // debug array if ( ! s ) { f =  ( c > 2  ?  x  :  "gm" );   // JS=1.5+  *  IE8 if ( learnt ) {  // no debug x =  new RegExp( e[ 0 ], f ); } else { x =  WSTM.util.regexp.fiat( e[ 0 ], f, false ); if ( typeof x ===  "string") { s =  "RegExp error:\n" + x + "\nin " + story + " #" + (i+1); all.splice( k, 1 ); break;  // for i                     }   // error detected }  // debug regexp all[k] =  [ x, e[ 1 ] ]; k++; }           } else { s =  source + wstmTXT( "IsNotAnArray" ); break; }  // m         }   // for i      } else { s =  story + wstmTXT( "IsNotAnArray" ); }  // add if ( s ) { WSTM.main.fault( s, false ); }  // s      return  ( s ? false : all ); };  // .util.translate.further

};  // .bb.translate mw.libs.WikiSyntaxTextMod.bb.translate(mw.libs.WikiSyntaxTextMod); delete mw.libs.WikiSyntaxTextMod.bb.translate;

//---

( function ( WSTM ) {  "use strict";   var sub      =  "U",       self     =  WSTM.util.self,       version  =  WSTM.util.vsn,       rls;   if ( typeof WSTM.main  !==  "object" ) {      WSTM.main  =  { };   }   if ( ! WSTM.main.bb ) {     WSTM.main.bb  =  { };   }   WSTM.main.bb[ sub ]  =  { load: true,                             vsn:  version };   if ( typeof WSTM.main.wait  ===  "function" ) {      // Start on import: callback to waiting ...      WSTM.main.wait( sub, version );   }   if ( typeof mw.loader  ===  "object"   && typeof mw.hook !==  "undefined" ) {      rls = { };      rls[ self ] = "ready";      mw.loader.state( rls );      mw.hook( "WikiSyntaxTextMod/" + sub + ".ready" )        .fire( [ sub, version ] );   } } ( mw.libs.WikiSyntaxTextMod ) );

// Emacs // Local Variables: // coding: iso-8859-1-dos // fill-column: 80 // End:

/// EOF  WikiSyntaxTextMod/dU.js