User:PerfektesChaos/js/WikiSyntaxTextMod/dX.js

/// PerfektesChaos/js/WikiSyntaxTextMod/dX.js /// 2024-05-11 PerfektesChaos@de.wikipedia /// Fingerprint: #0#0# /// @license: CC-by-sa/4.0 GPLv3 /// // WikiSyntaxTextMod: Wiki syntax specific code: tags ... /* 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.64,       sign     =  "WikiSyntaxTextMod",       sub      =  "X",       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.w  !==  "object" ) {      WSTM.w  =  { tags: { }  };   }   if ( typeof WSTM.w.tags  !==  "object" ) {      WSTM.w.tags  =  { };   }   WSTM.w.tags.vsn   =  version;   WSTM.w.tags.self  =  self;   if ( typeof WSTM.bb  !==  "object" ) {      WSTM.bb  =  { };   }   if ( typeof WSTM.debugging  !==  "object" ) {      WSTM.debugging  =  { };   } } ( mw ) );

/* Requires: JavaScript 1.3 (String.charCodeAt String.fromCharCode String.replace) JavaScript 1.5 RegExp non-capturing parenthese */

//---

mw.libs.WikiSyntaxTextMod.bb.bbX =  function ( WSTM ) { // Building block and run environment support // 2012-05-18 PerfektesChaos@de.wikipedia "use strict"; if ( typeof WSTM.util !==  "object" ) { WSTM.util =  { }; }

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 } );

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

//---

mw.libs.WikiSyntaxTextMod.bb.tags =  function ( WSTM ) { // Analyzing and formatting of tags ... // Uses: //   .util.fiatObjects // 2024-05-11 PerfektesChaos@de.wikipedia "use strict"; WSTM.util.fiatObjects( WSTM, "w",                          { tags:  { }  }                        ); if ( typeof WSTM.w.reWhitespaceMult !==  "object" ) { WSTM.w.reWhitespaceMult =  new RegExp( "\\s+", "g" ); }

WSTM.w.tags.elt =  { banned:     "a|applet|area|audio" + "|base|body|button" + "|command|embed" + "|form|frame|frameset" + "|head|html" + "|iframe|img|input|isindex" + "|layer|link|map|meta" + "|object|option" + "|script|select|style" + "|textarea|title" + "|xml", binary:    "blockquote|center|chem|code|dfn" + "|gallery|graph" + "|h1|h2|h3|h4|h5|h6" + "|hiddentext|hiero" + "|imagemap|includeonly|inputbox" + "|kbd|li|mapframe|math|noinclude" + "|ol|onlyinclude|p|poem|pre" + "|ruby|rb|rbc|rp|rt|rtc" + "|s|samp|score|strike" + "|templatedata|ul", blockEnd:  "gallery|graph|imagemap|inputbox" + "|mapframe|ol|pre" + "|references|templatedata|ul", codeBlock: "pre", codeData:  "chem|graph|hiero|imagemap|inputbox" + "|mapframe|maplink|math|poem" + "|score" + "|templatedata" + "|timeline", codedFix:  "syntaxhighlight|source", codedOpt:  "mapframe", codeInline: "code|dfn|kbd|maplink|poem|samp", comment:   "hiddentext", direct:    "bdi|br|ref|hiddentext" + "|ruby|rb|rbc|rp|rt|rtc", enclose:   "b|big|center|dfn|em|i" + "|s|samp|span|strike|strong" + "|u|var", marker:    "gallery" + "|imagemap" + "|includeonly|onlyinclude" + "|ref|references", obsolet:   + "b|big|blockquote|center|dfn|em" + "|font|hiddentext|i|samp|strike" + "|strong|var", parNone:   "graph|hiddentext" + "|imagemap|includeonly|inputbox" + "|noinclude|nowiki|onlyinclude" + "|rb|rbc|rp|rt|rtc" + "|timeline", parWith:   "bdi|br|code|dfn|div|gallery|hiero" + "|kbd|mapframe|math|p|poem|pre" + "|ref|references|ruby" + "|samp|section|small|source" + "|span|strike|sub|sup" + "|syntaxhighlight|tt", unary:     "br|hr|templatestyles|wbr" };  // 2024-05-11   WSTM.w.tags.pars  =  { gallery:         "caption=|class=|heights=" + "|id=|mode=|perrow=" + "|showfilename|style=" + "|widths=", math:           "display=|chem", ref:            "!|name=|group=", references:     "group=" + "|responsive=|responsive", syntaxhighlight: "class=|enclose=|highlight=" + "|inline|id=" + "|lang=|line=|line" + "|pre|start=|style=|title=" };  // 2023-12-05

WSTM.w.tags.fade =  function ( about, assign ) { // Update HTML attribute as CSS style // Precondition: //   about   -- string with HTML attribute name //   assign  -- string with old value, trimmed // Postcondition: //   Returns string with CSS code // Uses: //   this //   >< .html2css //   >< .reHashStart //   >< .reHex //   >< .reDigits // 2019-09-07 PerfektesChaos@de.wikipedia var r =  assign; if ( typeof this.html2css !==  "object" ) { this.html2css =  { align:   "text-align", bgcolor: "background", color:  "color", valign: "vertical-align", width:  "width" }; }     switch ( about ) { case "bgcolor": if ( typeof WSTM.w.encountered.sortable ===  "boolean" ) { this.html2css.bgcolor =  "background-color"; }  // fall through case "color": if ( typeof this.reHashStart !==  "object" ) { this.reHashStart =  new RegExp( "^#" ); this.reHex       =  new RegExp( "^[0-9A-Fa-f]+$" ); }           if ( ! this.reHashStart.test(r)                 &&   ( r.length === 3  ||  r.length === 6 )                 &&   this.reHex.test( r ) ) { r =  "#" + r.toUpperCase; }           break; case "width": if ( typeof this.reDigits !==  "object" ) { this.reDigits =  new RegExp( "^[0-9]+$" ); }           if ( this.reDigits.test(r) ) { r =  r + "px"; }           break; default: r =  r.toLowerCase; }  // switch about r =  this.html2css[ about ]  +  ":"  +  r;      return  r;   };   // .w.tags.fade

WSTM.w.tags.fair =  function (adjust, around) { // Analyze and polish class="" declaration // 2015-10-15 PerfektesChaos@de.wikipedia // Precondition: //   adjust  -- class list content, normalized by space separation //   around  -- true:  false: table // Postcondition: //   Returns modified string, even empty // Uses: //   this //   >  .w.tags.reClassComma //   >< .w.tags.reClassDiscard //   >< .w.reWhitespaceMult //    < .mod.lazy //   .hooks.fire //   .str.trim //   .errors.found // 2019-09-07 PerfektesChaos@de.wikipedia var r =  adjust, discard, s;     if ( r ) { if ( r.indexOf( "," ) >=  0 ) { r             =  r.replace( this.reClassComma,  " " ); WSTM.mod.lazy =  false; }        discard  =  WSTM.hooks.fire( "class_discard" ); if ( discard ) { if ( typeof this.reClassDiscard !==  "object" ) { this.reClassDiscard =  new RegExp( " (" + discard + ") ",                                                   "g" ); }           r  =  " " + r + " "; s =  r.replace( this.reClassDiscard, " " ); if ( s !== r ) { r =  s.replace( this.reClassDiscard, " " ); }        }         r  =  WSTM.str.trim( r.replace( WSTM.w.reWhitespaceMult, " " ) );     } else { WSTM.errors.found( ( around ? "tag" : "table" )                           + "AttrValueEmpty",                            false,                            "class=\"\"" ); }     return  r;   };   // .w.tags.fair

WSTM.w.tags.feature =  function (arglist,access,adjust,assign,alone){ // Retrieve particular tag parameter value, and/or set value // Precondition: //   arglist  -- tag object //               >< .props //   access   -- attribute name //   adjust   -- true: downcase value //   assign   -- true: remove attribute,  string: set value //   alone    -- true: set unary // Postcondition: //   Returns attribute value (string or true for unary), //   or false if not available yet // 2015-12-20 PerfektesChaos@de.wikipedia var r =  false, e =  arglist.props, i =  0, n =  0, p;     if ( e ) { n =  e.length; for ( i = 0; i < n;  i++ ) { p =  e[ i ]; if ( p[ 1 ] === access ) { r =  p[ 3 ]; if ( ! r ) { r =  p[ 2 ]; if ( adjust && r ) { r =  r.toLowerCase; }              }               if ( assign  ||  assign === "" ) { if ( typeof assign ===  "string" ) { p[2] =  assign; } else if ( n === 1 &&  ! i ) { arglist.props =  false; } else { arglist.props.splice( i, 1 ); }              }               i  =  -1; break;  // for i            } }  // for i      } if ( typeof assign === "string"   &&   i === n ) { p =  [ " ",  access,  assign,  ( alone ? true : false ) ]; if ( n ) { arglist.props.push(p); } else { arglist.props =  [ p ]; }     }      return  r;   };   // .w.tags.feature

WSTM.w.tags.features =  function ( assign, about ) { // Parse tag parameters // Precondition: //   assign  -- non-empty string with attr=val assignments //   about   -- tag name // Postcondition: //   Returns false, if not a valid tag, or Array //      Every element is an Array(3) //         [0] leading whitespace (standardized) //         [1] keyword //         [2] value (string content),  or false (sole) //         [3] true: unary //         or false // Uses: //   >  .w.tags.reTagAttrL //   >  .w.tags.reTagAttrQ //   >  .w.tags.reTagAttrX //   >  .w.tags.reTagAttrS //   >  .w.tags.reTagAttrE //   >  .w.tags.attrUnary //   >  .w.tags.reTagAttrT //   >  .w.tags.reTagAttrU //   >  .w.tags.reTagAttr1 //    < .mod.lazy //   .str.isLetter //   .errors.found //   .str.trim //   .str.trimR //   .w.tags.fade //   .str.substrEnd //   .w.tags.fair //   .w.css.fashion // 2020-05-15 PerfektesChaos@de.wikipedia var got      =  true, letter   =  WSTM.str.isLetter( about ), r        =  false, stitch   =  "|class|style|", stoneage =  "|bgcolor|color|valign|", sub      =  " " + assign, vals     =  { }, i, leap, lone, p, seek, set, show, sign, spc; while ( got ) { sign =  false; got  =  this.reTagAttrL.exec( "\f" + sub + "\f" ); if ( got ) { set      =  false; got[ 0 ] =  got[ 1 ] + got[ 2 ]; } else { got  =  this.reTagAttrQ.exec( sub ); if ( got ) { if ( got[ 3 ] ) { set =  got[ 3 ]; } else { set =  got[ 4 ]; }              if ( typeof set  === "string" ) { set =  WSTM.str.trim( set, true ); } else { set =  ""; }              if (! set.length) { WSTM.errors.found( ( letter ? "tag" : "table" )                                    + "AttrValueEmpty",                                     false,                                     ( letter ? "<" : "" )                                    + about + " " + got[2] + "=\"\""                                     + ( letter ? ">" : "" ) );                 set  =  "???????"; }           } else { got =  this.reTagAttrX.exec( sub ); if ( got ) { if ( got[ 3 ] ) { set =  got[ 3 ]; } else if (got[ 4 ]) { set =  got[ 4 ]; } else { set =  got[ 5 ]; }                 WSTM.mod.lazy  =  false; if ( got[ 6 ] ) { got[ 0 ] =  WSTM.str.trimR( got[ 0 ], true ); }              } else { set =  false; got =  this.reTagAttrS.exec( sub + "/" ); if ( got ) { sign =  sub; got  =  this.reTagAttrE.exec( sub ); if ( got ) { sign =  got[ 1 ]; if ( sign === "responsive"  &&                             about === "references" ) { got =  false; sub =  sign; }                    }                     if ( got ) { WSTM.errors.found( ( letter ? "tag" : "table" )                                          + "AttrValueEmpty",                                           false,                                           ( letter ? "<" : "" )                                          + about + " " + sign + "="                                           + ( letter ? ">" : "" ) );                       got  =  false; } else { if ( typeof this.attrUnary[ about ]                                                       ===  "string" ) { set =  this.attrUnary[ about ]; got =  this.reTagAttrT.exec( sub + " " ); if ( got ) { sign =  got[ 1 ].toLowerCase; if ( set.indexOf("|" + sign + "|" )                                                               >=  0 ) { got = [ " ", sign, "", true ]; set =  ""; sub =  ""; } else { got =  false; }                          }                        }                        if ( ! got ) { WSTM.errors.found( ( letter ? "tag" : "table" )                                             + "AttrInvalid",                                              false,                                              ( letter ? "<" : "" )                                             + about + " " + assign ); }                    }                     if ( ! got ) { spc =  " "; set =  "???"; sub =  " "; }                 } else { got =  this.reTagAttrU.exec( sub + "/" ); if ( got ) { WSTM.errors.found( ( letter ? "tag" : "table" )                                          + "AttrInvalid",                                           false,                                           ( letter ? "<" : "" )                                          + about + " " + assign ); set =  sub; } else { spc  =  " "; sign =  sub; if ( ! this.reTagAttr1.test( sign ) ) { WSTM.errors.found( ( letter ? "tag" : "table" )                                             + "AttrInvalid",                                              false,                                              ( letter ? "<" : "" )                                             + about + " " + sign ); got =  false; }                    }                  }               }            }         }         if ( got ) { spc =  got[ 1 ]; p   =  spc.indexOf( "\n" ); if ( p < 0 ) { spc =  " "; } else { spc =  spc.substr( p ); }           if ( got[ 2 ] ) { sign =  got[ 2 ].toLowerCase; sign =  WSTM.str.trim( sign, true ); }           if ( set ) { set =  WSTM.str.trim( set, true ); }           lone  =  got[ 3 ]; seek =  "|" + sign + "|"; if ( stoneage.indexOf( seek ) >=  0 ) { set  =  this.fade( sign, set ); sign =  "style"; }           seek  =  "|" + sign + "|"; sub  =  sub.substr( got[ 0 ].length ); if ( typeof vals[ sign ] !==  "string" ) { vals[ sign ] =  set; } else if ( vals[ sign ] === set ) { sign =  ""; } else { show =  ( letter ? "tag" : "table" )  +  "AttrRepeated"; leap =  false; got  =  ( letter ? "<" : "" )  +  about  +  " " + assign.substr( 0,                                          assign.length - sub.length ); if ( stitch.indexOf( seek ) >=  0 ) { for ( i = 0; i < r.length;  i++ ) { p =  r[ i ]; if ( p[ 1 ] ===  sign ) { WSTM.mod.lazy =  false; if ( sign === "style"  &&                            WSTM.str.substrEnd( p[ 2 ], 1 )  !==  ";" ) { p[ 2 ] =  p[ 2 ] + ";"; }                       set     =  p[ 2 ] + " " + set; r[ i ] =  [ spc, sign, set ]; leap   =  true; break; }                 }   // for i               } sign =  ""; if ( ! leap ) { WSTM.errors.found( show, false, got ); }           }         }         if ( sign.length ) { p =  [ spc, sign, set, lone ]; if ( r ) { r.push( p ); } else { r =  [ p ]; }        }      }   // while got sub =  WSTM.str.trim( sub, true ); if ( sub.length ) { WSTM.errors.found( ( letter ? "tag" : "table" )                           + "AttrInvalid",                            false,                            ( letter ? "<" : "" )                           +  about + " " + assign ); }     if ( r ) { for ( i = r.length - 1; i >= 0;  i-- ) { p =  r[ i ]; switch ( p[ 1 ] ) { case "class": if ( p[ 2 ] ) { p[ 2 ] =  this.fair( p[ 2 ],  letter ); if ( ! p[ 2 ] ) { r.splice( i, 1 ); }                 } else { WSTM.errors.found( ( letter ? "tag" : "table" )                                       + "AttrInvalid",                                        false,                                        p[ 1 ] + "=??? in: " + assign ); }                 break; case "style": if ( p[ 2 ] ) { set =  WSTM.w.css.fashion( p[ 2 ], about ); if ( set ) { p[ 2 ]          =  set; WSTM.mod.lazy =  false; }                 } else { WSTM.errors.found( ( letter ? "tag" : "table" )                                       + "AttrInvalid",                                        false,                                        p[ 1 ] + "=??? in: " + assign ); }                 break; }  // switch p[1] }  // for i-- }     return  r;   };   // .w.tags.features

WSTM.w.tags.fence =  function ( all, arglist ) { // Isolate fixed tag range // Precondition: //   all      -- WikiTom to be analyzed and subdivided (root) //   arglist  -- tag information provided by .tags.fetch //               >  .scope //               >  .node //               >  .limited //               >< .join //               >< .move //                < .lookup //                < .lone // Postcondition: //   Returns true, if found,  or false // Uses: //   >  .w.chr.whitespace //   >< .w.tags.reEndTags //   .o.WikiTom.find //   .o.WikiTom.fetch //   .o.WikiTom.flip //   .errors.found // 2012-08-02 PerfektesChaos@de.wikipedia var lag =  false, lbb =  false, lbe =  false, leb =  false, lee =  false, re  =  this.reEndTags[ arglist.scope ], i,         j,          k,          m,          n,          r,          s;      if ( ! re ) { re =  "[" + WSTM.w.chr.whitespace + "]*"; re =  "(<" + re + "[/\\\\]" + re + arglist.scope + re + ">)" + "(\n|<!--)?"; re =  new RegExp(re, "i"); this.reEndTags[ arglist.scope ] =  re; }     r  =  all.find( [ re, 1 ],                      arglist.join + arglist.move,                      arglist.node,                      true,                      false ); if ( r ) { j =  arglist.join; m =  0; i =  r.i;         n  =  r.r[ 1 ].length; k =  i - j - arglist.move - 1; s =  ""; if ( arglist.limited ) { j =  ( j  ?  j - 1  :  0 ); m =  j - arglist.join + arglist.move + 3; s =  all.fetch(arglist.node, j, false); k =  i - j;            s  =  s.substr(0, k); if ( arglist.scope === "source" ) { lag =  ( s.toLowerCase.indexOf( "syntaxhighlight" )                                                                   <  0); if ( lag ) { arglist.scope =  "syntaxhighlight"; }           }            if ( arglist.join ) { lbb =  ( s.charCodeAt( 0 ) !== 10 ); lbe =  ( s.charCodeAt( m + 1 )  !==  10 ); }           leb  =  ( s.charCodeAt( s.length - 1 )  !==  10 ); lee =  ( typeof r.r[2]  !==  "string" ); if ( lbb || lbe ) { n +=  k;               i   =  j;               if ( lbe ) { s  =  s.substr( 0,  m + 1 )   +  "\n" +  s.substr( m + 1 ); k++; }              if ( lbb ) { s =  s.substr( 0, 1 )  +  "\n"  +  s.substr( 1 ); arglist.join++; }           } else { s =  ""; }           if ( leb ) { s =  s + "\n"; k++; }        }         if ( k === 1 ) { arglist.lone =  true; i--; n++; s =  " />"; } else { s             =  s + ""; arglist.move +=  arglist.scope.length + 1; }        arglist.move  +=  k - m + 3; if ( lee ) { s =  s + "\n"; }        arglist.lookup   =  false; if ( s !==  r.r[ 1 ] ) { all.flip( arglist.node, i, n, s ); }        if ( lag ) { all.flip( arglist.node,                     arglist.join + 1,                      6,                      arglist.scope ); }        r  =  true; } else { s =  all.fetch( arglist.node, arglist.join, false ); WSTM.errors.found( "tagEndMissing",                           false,                            s.substr( 0, 50 ) ); }     return  r;   };   // .w.tags.fence

WSTM.w.tags.fetch =  function (arglist) { // Detect and format tag // Precondition: //   arglist  -- tag object //               >< .leader  heading slash present //                            <  may be removed //               >< .move    number of characters processed //                            <  progress //               >< .scope   lowercase tag name //               >< .source  found text after '<' //                            <  limited to '>' //               >< .scan    search key (|scope|) //                < .lone    unary //                < .n       length of found tag, with '<' and '>' //                           0  if failed; then no more info //                < .props   Array with attributes, or false //                < .shift   re-formatted tag after <, if changed; //                           or false //                  .leave   neutral (span div) //                  .limited single line // Postcondition: //   Returns false, if seriously failed, or updated arglist // Uses: //   >  .w.chr.detected.tab //   >  .w.tags.reTagEnd //   >  .w.tags.single //   >  .w.tags.sole //   >  .w.tags.pars //   >  .w.tags.suckNowiki //   .errors.found //   .w.chr.fixTab //   .str.trim //   .w.tags.features //   .w.tags.focus //   .w.tags.format // 2013-04-30 PerfektesChaos@de.wikipedia var lucky =  false, got, i,         m,          n,          sub; arglist.n =  arglist.source.indexOf( ">", arglist.move )  +  1; if ( arglist.n ) { lucky          =  true; arglist.props  =  false; m              =  arglist.n - 1; arglist.source =  arglist.source.substr( 0, m ); i              =  arglist.source.indexOf( "<", arglist.move ); n              =  arglist.source.indexOf( "\n\n",                                                    arglist.move ); if ( n > arglist.move ) { n =  ( n > 100  ?  100  :  n ); WSTM.errors.found("tagFormBroken",                             false,                              "<"  +  arglist.source.substr(0, n)); arglist.move =  ( i > arglist.move  ?  i - 1  :  m ); lucky        =  false; } else if ( i > arglist.move ) { arglist.move =  i - 1; i            =  ( i > 100  ?  100  :  i ); WSTM.errors.found( "tagFormReOpen",                              false,                               "<"  +  arglist.source.substr( 0, i ) ); lucky =  false; } else { sub          =  arglist.source.substr( arglist.move ); arglist.move =  m;         } if ( lucky ) { got =  this.reTagEnd.exec( sub ); n   =  sub.length; if ( got ) { arglist.lone  =  true; n            -=  got[1].length; sub           =  sub.substr(0, n); } else { arglist.lone  =  false; }           if ( this.sole.indexOf( arglist.scan )  >=  0 ) { arglist.leader =  false; arglist.lone   =  true; }           if ( n ) { if ( WSTM.w.chr.detected.tab ) { got =  WSTM.w.chr.fixTab( sub ); if (got) { sub =  got; }              }               got  =  WSTM.str.trim( sub, true, true ); n   =  got.length; }           if (n) { got =  this.features( sub, arglist.scope ); if (got) { if (this.single.indexOf(arglist.scan) >= 0) { WSTM.errors.found( "tagAttrUnexpected",                                       false,                                        "<"  +                                        arglist.source.substr( 0, 200 ) );                    arglist.n  =  0; }                 if (arglist.leader) { arglist.source =  arglist.source.substr(0, 200); WSTM.errors.found( "tagEndAttr",                                       false,                                        "<" + arglist.source + ">" ); arglist.n =  0; }                 if ( arglist.n ) { this.focus( got, arglist ); }              }            }         }         if ( lucky && arglist.n ) { if ( arglist.leader && arglist.lone ) { WSTM.errors.found( "tooManySlashes",                                 false,                                  "<"                                    +  arglist.source.substr( 0, 100 ) ); arglist.n =  0; }           if ( arglist.n ) { if ( arglist.lone &&  ! arglist.props ) { got =  this.pars[ arglist.scope ]; if (got) { got =  "|" + got; if ( got.indexOf( "|!|" ) >=  0 ) { WSTM.errors.found( "tagUnaryNoAttr",                                          false,                                           "<" + arglist.scope + " />" ); }                 }                  if ( this.suckNowiki.indexOf( arglist.scan )  >=  0 ) { arglist.scope =  "nowiki"; arglist.scan  =  "|nowiki|"; arglist.move  =  arglist.source.length; }              }               if ( arglist.scope === "strike" ) { arglist.scope =  "s"; }              sub            =  this.format( arglist ); arglist.shift =  (sub === arglist.source  ?  false                                                          :  sub); }        }      } else { WSTM.errors.found("tagFormNoEnd",                          false,                           "<"  +  arglist.source.substr(0, 100)); }     return  (arglist.n > 0  ?  arglist  :  false); };  // .w.tags.fetch

WSTM.w.tags.fire =  function ( all ) { // Start tag soup stirring: subdivision of tags and tagged elements // Precondition: //   all  -- WikiTom to be analyzed and subdivided (root) //            < .children //            < .shift // Postcondition: //   all  has been subdivided, if necessary // Uses: //   >  .w.chr.whitespace //   >  .w.tags.elt //   >  .w.tags.elt.banned //   >  .w.tags.elt.blockEnd //   >  .w.tags.elt.codeBlock //   >  .w.tags.elt.codeData //   >  .w.tags.elt.codedFix //   >  .w.tags.elt.codeInline //   >  .w.tags.elt.codedOpt //   >  .w.tags.elt.comment //   >  .w.tags.elt.direct //   >  .w.tags.elt.marker //   >  .w.tags.elt.parNone //   >  .w.tags.elt.unary //   >  .w.tags.elt.enclose //   >  .warn.attribute //   >  .warn.property //   >  .warn.tag //   >  .w.chr.detected.tab //    < .w.tags.attrUnary //    < .w.tags.blocks //    < .w.tags.pending //    < .w.tags.reClassComma //    < .w.tags.reCommentBeg //    < .w.tags.reEndTags //    < .w.tags.reTagAttr1 //    < .w.tags.reTagAttrE //    < .w.tags.reTagAttrQ //    < .w.tags.reTagAttrS //    < .w.tags.reTagAttrT //    < .w.tags.reTagAttrU //    < .w.tags.reTagAttrX //    < .w.tags.reTagBeg //    < .w.tags.reTagEnd //    < .w.tags.sealed //    < .w.tags.setter //    < .w.tags.single //    < .w.tags.slice //    < .w.tags.sole //    < .w.tags.sources //    < .w.tags.stack //    < .w.tags.stop //    < .w.tags.storing //    < .w.tags.suckNowiki //    < .w.tags.suitable //    < .w.tags.supply //    < .w.tags.setting //    < .w.tags.say //   .o.WikiTom.find //   .str.uniques //   .util.regexp.fiat //   .errors.found //   .o.WikiTom.fetch //   .o.WikiTom.flip //   .o.WikiTom.fresh //   .o.WikiTom.frame //   .w.tags.fold //   .w.tags.frame //   .o.WikiTom.fixTab // Requires: JavaScript 1.3  fromCharCode // 2024-05-11 PerfektesChaos@de.wikipedia var got  =  all.find("<", 0, 0, true, false), open =  [ ], s    =  "([" + WSTM.w.chr.whitespace + "]+)?", sat  =  "([-a-z_A-Z:0-9]+)", sqd  =  String.fromCharCode(34,8220,8221,8222), sqs  =  String.fromCharCode(39,8216,8217,8218), j, k, tag; this.attrUnary    =  { gallery:         "|showfilename|", math:           "|chem|", references:     "|responsive|", source:         "|inline|line|pre|", syntaxhighlight: "|inline|line|pre|" }; this.blocks       =  false; this.pending      =  { }; this.reClassComma =  new RegExp("[, ]+", "g"); this.reCommentBeg =  new RegExp("^" + s + "!--"); this.reEndTags    =  { }; this.reTagAttr1   =  new RegExp("^[a-z_A-Z:0-9 \n]*$"); this.reTagAttrE   =  new RegExp("\\b([^ =\n]+)[ \n]*=[ \n]*$"); this.reTagAttrL   =  new RegExp("\f( *\n *| +)"                                         + sat                                         + "(?:" //?: + "(?: +| *\n *)" //?: + "[^= \n]" + "(?:.|\n)*" //?: + ")\f"); this.reTagAttrQ   =  new RegExp("^" + "( *\n *| +)"                                           + sat                                           + " *\n? *= *\n? *"                                           + "(?:'([^'\n]*)'" + "|\"([^\"\n]*)\""                                          + ")");      this.reTagAttrS    =  new RegExp("^" + "( *\n *| +)"                                           + sat                                           + "(?: *\n? *"                                             + "([^= ]"                                                 + "(?:.|\n)*))$");      this.reTagAttrT    =  new RegExp("^ *([a-zA-Z]+) ");      this.reTagAttrU    =  new RegExp("^" + "( *\n *| +)"                                           + "([a-z_A-Z:0-9]+)"                                           + "(?: *\n? *= *)"                                             + "((.|\n)*)$");      this.reTagAttrX    =  new RegExp("^" + "( *\n *| +)"                                           + sat                                           + " *\n? *= *\n? *"                                           + "(?:[" + sqs + "]" +                                             "([^" + sqs + "]*)" +                                             "[" + sqs + "]"                                           + "|[" + sqd + "]" +                                             "([^" + sqd + "]*)" +                                             "[" + sqd + "]"                                           + "|([^ \n]+)"                                            + "( +|$)"                                           + ")");      this.reTagBeg      =  new RegExp("^" + "("                                              + s                                              + "([/\\\\]?)" + s                                             + "([a-zA-Z]+[1-6]?))"                                              + "["                                                  + WSTM.w.chr.whitespace                                                  + "/\\.>\n<]"); this.reTagEnd     =  new RegExp("(" + s + "[/\\\\]" + s + ")$"); this.scream       =  "|" + this.elt.banned + "|"; this.sealed       =  "|" + this.elt.codeBlock + "|" + this.elt.codeData + "|" + this.elt.codedFix + "|" + this.elt.codeInline + "|" + this.elt.comment + "|"; this.setter       =  "|div|span|"; this.shallow      =  "|" + this.elt.codedOpt + "|"; this.single       =  "|" + this.elt.parNone + "|"; this.slice        =  "|" + this.elt.marker + "|"; this.sole         =  "|" + this.elt.unary + "|"; this.sources      =  "|" + this.elt.codedFix + "|"; this.spacing      =  "|" + this.elt.direct + "|"; this.stack        =  "|" + this.elt.blockEnd + "|" + this.elt.codeInline + "|ref|"; this.stop         =  "|" + this.elt.blockEnd + "|" + this.elt.codeBlock + "|"; this.storing      =  "|" + this.elt.binary + "|"; this.suckNowiki   =  "|" + this.elt.enclose + "|"; if (! this.suitable) { this.suitable =  ""; for (s in this.elt) { this.suitable =  this.suitable + "|" + this.elt[s]; }  // for s in elt this.suitable =  "|" + WSTM.str.uniques(this.suitable, "|") + "|";      }      if ( WSTM.warn ) { if ( WSTM.warn.attribute ) { k =  WSTM.warn.attribute.length; if ( k ) { this.supply =  "|"; for ( j = 0; j < k;  j++ ) { tag =  WSTM.warn.attribute[ j ]; if ( tag                      &&   typeof tag  ===  "object"                       &&   tag.length === 2                       &&   typeof tag[ 0 ]  ===  "string" ) { if ( typeof tag[ 1 ] ===  "string" ) { tag[ 0 ]    =  tag[ 0 ].toLowerCase; this.supply =  this.supply + tag[ 0 ] + "|"; tag[ 1 ]    =  WSTM.util.regexp.fiat( tag[ 1 ],                                                 false,                                                 ".config.warn.attribute"                                                 + "[" + j + "][1]" ); }                 } else { WSTM.errors.found( "Invalid",                                       false,                                        ".config.warn.attribute"                                        + "[" + j + "]" ); }              }   // for j            } }        if ( WSTM.warn.property ) { k = WSTM.warn.property.length; if ( k ) { this.setting =  "|"; for ( j = 0; j < k;  j++ ) { this.setting =  this.setting + WSTM.warn.property[ j ] + "|"; }  // for j               this.setting  =  this.setting.toLowerCase; }        }         if (WSTM.warn.tag) { k = WSTM.warn.tag.length; if (k) { this.say =  "|"; for (j = 0; j < k;  j++) { this.say =  this.say + WSTM.warn.tag[j] + "|"; }  // for j               this.say  =  this.say.toLowerCase; }        }      }      while (got) { j =  got.i + 1; k =  got.k;         s  =  all.fetch(k, j, false); if (s) { tag =  this.fold(s); if (tag) { if (tag.shift) { all.flip(k, j, tag.move, tag.shift); tag.move  =  tag.shift.length; tag.shift =  false; all.fresh(false); } else if (! tag.move ||  isNaN(tag.move)) { tag.move =  0; }              tag.join  =  got.i;               tag.node  =  k;               if (tag.scope) { this.frame(all, tag, open); } else if (! tag.move) { tag.move =  1; }              j  =  tag.join + tag.move; k =  tag.node; }        }         got  =  all.find("<", j, k, true, false); }  // while got if (open.length) { WSTM.errors.found("tagEndMissingFinal",                          false,                           ""); } else if (WSTM.w.chr.detected.tab) { if (all.children) { for (j = 0; j < all.children.length;  j++) { all.children[j].fixTab(all.children[j]); }  // for j         } else { all.fixTab(all); }     }   };   // .w.tags.fire

WSTM.w.tags.fix =  function ( arglist ) { // Improve tag, e.g. BR clear or DIV // Precondition: //   arglist  -- tag object //               >  .scan //               >  .scope //               >  .lone //               >  .props //               >  .source //                < .limited //                < .shift // Postcondition: //   Returns true, if to be folded as limited, or false // Uses: //   >  .w.tags.setter //   .w.tags.feature //   .w.css.fashion //   .w.tags.format //   >< .w.tags.reClear // 2020-05-15 PerfektesChaos@de.wikipedia var r     =  false, lone, s,         style; if ( arglist.props  &&           ( arglist.scope === "br"  || arglist.scope === "div" ) ) { s =  this.feature( arglist, "clear", true ); if ( s ) { lone =  true; this.feature( arglist, "clear", true, true ); style =  this.feature( arglist, "style", true ); if ( style ) { if ( typeof this.reClear !==  "object" ) { this.reClear =  new RegExp( "; *clear *: *[a-z]+ *;",                                               "i" ); }              if ( this.reClear.test( ";" + style + ";" ) ) { style =  "clear:" + s + ";" + style; }           } else { style =  "clear:" + s;            } style =  WSTM.w.css.fashion( style, arglist.scope ) || style; this.feature( arglist, "style", false, style ); r =  true; } else if ( this.feature( arglist, "style", true ) ) { lone =  true; }        if ( lone  &&  arglist.scope === "br" ) { arglist.scope   =  "div"; arglist.limited =  true; arglist.lone    =  true; arglist.scan    =  "|div|"; r               =  true; }     }      if ( this.setter.indexOf( arglist.scan )  >=  0           &&   arglist.lone           &&   arglist.props ) { s =  this.format( arglist ); if ( s  &&              arglist.source.substr( 0, 1 )  !==  "/" ) { s =  s.substr( 0,  s.length - 2 ) +  ">  .node //               >  .scope //               >  .move //               >< .mode //               >< .join // Postcondition: //   tag object and WikiTom updated // Uses: //   >  .w.tags.pending.references //   >  .o.WikiTom.TagBegin //   >  .o.WikiTom.TagEnd //   .o.WikiTom.focus //   .str.isBlank //   .w.tags.flip //   .w.tags.free // 2015-01-01 PerfektesChaos@de.wikipedia var later   =  false, liaison =  true, lonely  =  false, c,         i,          j,          s;      if ( arglist.lone ) { later =  ( arglist.scope === "br" ); } else { later =  ( arglist.mode === WSTM.o.WikiTom.TagEnd ); if (arglist.scope === "ref") { liaison =  ( ! this.pending.references ); lonely  =  ( ! liaison ); }     }      if ( liaison ) { if ( arglist.mode === WSTM.o.WikiTom.TagBegin ) { i =  arglist.join + arglist.move; s =  all.fetch( arglist.node, i, false ); for ( j = 0; j < s.length;  j++ ) { c =  s.charCodeAt(j); if ( ! WSTM.str.isWhiteBlank( c, false, false ) ) { break;  // for j               } }  //   for j            if ( j ) { all.flip( arglist.node, i, j, "" ); }        } else if ( later && arglist.join ) { i =  arglist.join - 1; j =  i;            do { c =  all.fetch( arglist.node, i, true ); if ( WSTM.str.isWhiteBlank( c, false, false ) ) { i--; } else { break;  // while }           } while ( i >= 0 );   // do            if ( i < j ) { all.flip( arglist.node, i + 1,  j - i,  "" ); arglist.join -=  j - i;            } }     }      if ( lonely ) { this.free( all, arglist ); }  };   // .w.tags.flow

WSTM.w.tags.flush =  function (attributes, arglist) { // Format attributes // Precondition: //   attributes  -- Array with attributes //   arglist     -- tag description, or false //                      < .n      // Postcondition: //   Returns formatted attribute list // Uses: //   >  .w.tags.setting //   >  .w.tags.supply //   >  .warn.attribute //   .errors.found //   .warn.found // 2015-10-16 PerfektesChaos@de.wikipedia var r =  "", e, i, j, p, v, w;     for (i = 0;  i < attributes.length;  i++) { p =  attributes[i]; r =  r + p[0] + p[1]; if (p[2]) { p =  p[2]; if (p.indexOf("\"") < 0) {              r  =  r + "=\"" + p + "\"";            } else if (p.indexOf("'") < 0) {               r  =  r + "='" + p + "'";            } else {               WSTM.errors.found("tagAttrQuote", false, r);               if (arglist) {                  arglist.n  =  0;               }            }         }      }   // for i      if (this.setting || this.supply) {         for (i = 0;  i < attributes.length;  i++) {            p  =  attributes[i];            e  =  p[1];            if (this.setting) {               if (this.setting.indexOf("|" + e + "|")  >  0) {                  WSTM.warn.found("property",  e + "=");               }            }            if (this.supply) {               v  =  p[2];               if (v  &&  this.supply.indexOf(e) > 0) {                  for (j = 0;  j < WSTM.warn.attribute.length;  j++) {                     w  =  WSTM.warn.attribute[j]; if (e === w[0]) { if (w[1].test(v)) { WSTM.warn.found("attribute", e + "=" + v); }                    }                  }   // for j               } }        }   // for i      } return r;   };   // .w.tags.flush

WSTM.w.tags.focus =  function (apply, arglist) { // Analyse tag parameters; submit error message if unknown // Precondition: //   apply    -- Array with attributes //               Every element is an Array(3) //                  [0] leading whitespace (standardized) //                  [1] keyword //                  [2] value (string content) //                  or false //   arglist  -- tag object //               >  .scope //                < .props // Postcondition: //   Array .props has been assigned // Uses: //   .errors.found //   >  .w.tags.pars //   .str.trim // 2015-11-09 PerfektesChaos@de.wikipedia var support =  this.pars[ arglist.scope ], i, lone, p, s;     if (support) { support =  "|" + support + "|"; for (i = 0; i < apply.length;  i++) { p =  apply[i]; p[1] =  WSTM.str.trim(p[1]); if (p[1]) { lone =  (! p[2]  ||  p[2] === "???"); s    =  "|"  +  p[1]  +  (lone ? "|" : "=|"); if (support.indexOf(s) < 0) { WSTM.errors.found("tagAttrUnknown",                                   false,                                    "<" + arglist.scope + " " + p[1]                                    + (p[2] ? "=...>" : ">"));              } else if (lone) { apply[i][2] =  false; }           } else { if (! p[2]  &&   i  ===  apply.length - 1) { apply.pop; } else { WSTM.errors.found("tagAttrUnknown",                                   false,                                    "<" + arglist.scope + " "                                    + (p[2] ? "=...>" : "=>"));              }            }         }   // for i      } arglist.props =  apply; };  // .w.tags.focus

WSTM.w.tags.fold =  function (adjust) { // Detect and format tag // Precondition: //   adjust  -- string beginning after '<' // Postcondition: //   Returns false, if not a valid tag, or object //      .join    0, or -1 to jump before '<' //      .leader  end tag //      .lone    unary tag //      .mode    type of tag (comment) //      .move    number of characters to move forward in source //               if tag: length of got tag including '<' until '>' //      .props   Array with attributes, or false //      .shift   re-formatted tag after '<', if changed;  or false //      .scope   standardized keyword // Uses: //   >  .w.tags.reCommentBeg //   >  .o.WikiTom.Comment //   >  .warn.comment //   >  .w.tags.replComment //   >  .o.WikiTom.TextOnly //   >  .w.tags.reTagBeg //   >  .w.tags.suitable //   >  .o.WikiTom.Tag //   >< .w.tags.reCommentVsn //   .errors.found //   .hooks.fire //   .warn.found //   .str.substrEnd //   .w.tags.fetch // 2015-11-13 PerfektesChaos@de.wikipedia var got   =  this.reCommentBeg.exec( adjust ), r     =  false, j,         n,          s,          seek, swift; if ( got ) { if ( got[ 1 ] ) { j =  got[ 1 ].length; n =  adjust.indexOf( "-->",  j + 3 ); if ( n < 0 ) { r =  { join: 0, mode: WSTM.o.WikiTom.Comment, move: n + 4, shift: adjust.substr( j, n + 4 - j ) }; WSTM.errors.found( "tagCommentBegin",                                 true,                                  "<"  +  r.shift.substr( 0, 50 ) ); }        } else { r =  { join:  0, mode: WSTM.o.WikiTom.Comment, scan: "-- --", scope: "-- --" }; n =  adjust.indexOf("-->", 3); if ( n > 0 ) { s      =  adjust.substr( 3,  n - 3 ); r.move =  n + 4; swift  =  WSTM.hooks.fire( "comment", s ); if ( swift ) { if ( typeof swift ===  "string" ) { r.shift =  "!--" + swift + "-->"; n       =  swift.length + 3; } else { r.shift =  ""; r.join  =  -1; r.mode  =  0; n       =  0; }                 r.move--; }              if ( n ) { if ( WSTM.warn.comment ) { for ( j = 0; j < WSTM.warn.comment.length;  j++ ) { if ( s.indexOf( WSTM.warn.comment[ j ] )                                                               >=  0 ) { WSTM.warn.found( "comment",                                           "&lt;!--" + s + "--&gt;" ); break;  // for j                        } }  // for j                  } if ( this.replComment ) { swift =  ""; for ( j = 0; j < this.replComment.length;  j++ ) { swift =  swift.replace( this.replComment[j][0],                                                 this.replComment[j][1]                                               ); }  // for j                     if ( swift  !==  "" ) { r.mode =  WSTM.o.WikiTom.TextOnly; if ( swift.substr(0, 4) ===  "" ) { //                     if (swift.slice(-3) === "-->") { r.mode  =  WSTM.o.WikiTom.Comment; r.shift =  swift.substr( 1 ); r.move--; }                       }                        if ( r.mode === WSTM.o.WikiTom.TextOnly ) { // discard comment r.join  =  -1; r.shift =  swift; }                    }                  }               }            } else { r.move =  adjust.length + 1; WSTM.errors.found( "tagCommentNoEnd",                                 false,                                  "<"  +  adjust.substr( 0, 50 ) ); }        }      } else { got =  this.reTagBeg.exec( adjust ); if ( got ) { s    =  got[ 5 ].toLowerCase; seek =  "|" + s + "|"; if ( this.suitable.indexOf( seek ) >=  0 ) { r =  { leader:  false, move:   got[ 1 ].length, scan:   seek, scope:  s,                       source:  adjust }; if ( typeof got[ 3 ] ===  "string" ) { if ( got[ 3 ].length ) {  // IE save r.leader =  true; }              }               r  =  this.fetch( r ); if ( ! r ) { r =  { move: got.move }; }           }         }      }      return  r;   };   // .w.tags.fold

WSTM.w.tags.format =  function (arglist) { // Format tag // Precondition: //   arglist  -- tag object //               >  .leader  heading slash present //               >  .scope   lowercase tag name //               >  .props   Array with attributes, or false //               >  .lone    unary tag //                < .n       0 if failed // Postcondition: //   Returns formatted tag content with exception of '<' and '>' // Uses: //   .str.trim //   .w.tags.flush // 2012-08-02 PerfektesChaos@de.wikipedia var r =  (arglist.leader ? "/" : "")  +  arglist.scope; if (arglist.scope !== WSTM.str.trim(arglist.scope, true)) { mw.log(WSTM.debugging,               ".w.tags.format    <" + arglist.scope + ">",                1); }     if (arglist.props) { r =  r + WSTM.w.tags.flush(arglist.props, arglist); }     if (arglist.lone) { r =  r + " /"; // 2012-08-14    .move }     return  r;   };   // .w.tags.format

WSTM.w.tags.frame =  function ( all, arglist, ago ) { // Isolate tag range and handle specific content formatting // Precondition: //   all      -- WikiTom to be analyzed and subdivided (root) //                < .mode //   arglist  -- tag information provided by .tags.fetch //               >  .scan //               >  .scope //               >  .stop //               >  .props //               >  .leader //               >  .source //               >< .mode //               >< .join //               >< .lone //               >< .node //               >< .move //                < .limited //                < .lookup //                < .leave //   ago      -- Array with pending opening tags //               >< may pop or push // Postcondition: //   all  has been subdivided or merged, if necessary // Uses: //   >  .w.tags.say //   >  .w.tags.stop //   >  .o.WikiTom.Comment //   >  .o.WikiTom.TextOnly //   >  .o.WikiTom.Nowiki //   >  .o.WikiTom.CodedBlock //   >  .o.WikiTom.Code //   >  .o.WikiTom.CodedInline //   >  .o.WikiTom.TagEnd //   >  .o.WikiTom.TagBegin //   >  .o.WikiTom.TagBinary //   >  .w.tags.sealed //   >  .w.tags.shallow //   >  .w.tags.sources //   >  .w.tags.stack //   >  .w.tags.shift //   >  .w.tags.spacing //   >  .w.tags.slice //   >  .w.tags.setter //   >< .w.tags.pending.* //    < .w.encountered.include //   .warn.found //   .w.tags.future //   .w.tags.friend //   .w.tags.fence //   .errors.found //   .o.WikiTom.flip //   .w.tags.free //   .w.tags.furnished //   .w.tags.fix //   .w.elem.refgroups //   .o.WikiTom.fetch //   .str.trim //   .o.WikiTom.flow //   .o.WikiTom.folder //   .o.WikiTom.fork // 2024-05-11 PerfektesChaos@de.wikipedia var l      =  false, lapsus =  false, link   =  false, m      =  0, p      =  false; if ( this.say &&           this.say.indexOf(arglist.scan) >= 0  &&           ! arglist.leader ) { WSTM.warn.found( "tag", "&lt;" + arglist.scope + ">" ); }     arglist.lookup   =  true; arglist.limited =  ( this.stop.indexOf( arglist.scan )  >=  0 ); if ( arglist.mode === WSTM.o.WikiTom.Comment ) { arglist.lookup =  false; arglist.lone   =  true; l =  true; } else if ( arglist.mode === WSTM.o.WikiTom.TextOnly ) { void( 0 ); } else if ( arglist.scope === "nowiki" ) { l =  arglist.lone; if ( l ) { arglist.mode   =  WSTM.o.WikiTom.Nowiki; arglist.move   =  10; arglist.lookup =  false; } else { l =  this.fence(all, arglist); if ( l ) { arglist.mode =  WSTM.o.WikiTom.Nowiki; if ( arglist.props ) { WSTM.errors.found( "tagAttrUnexpected",                                    false,                                     "<" + arglist.tags.format + ">" ); }           }         }      } else if ( this.sealed.indexOf( arglist.scan )  >=  0 ) { if ( arglist.lone ) { m =  0; if ( this.shallow.indexOf( arglist.scan ) <  0 ) { WSTM.errors.found( "tagUnaryIllegal",                                 false,                                  "<" + arglist.scope + " />" ); }        } else { if ( this.sources.indexOf( arglist.scan ) >=  0 ) { m =  WSTM.o.WikiTom.CodedBlock; } else { m =  WSTM.o.WikiTom.Code; }        }         if ( m  &&  arglist.leader ) { p =  all.fetch( arglist.node,                             arglist.join + arglist.move + 2,                             false ); p =  WSTM.str.trim( p, true, true ); if ( ! p.length ) { p =  ( arglist.join > 50  ?  arglist.join - 50                                          :  0 ); p =  all.fetch( arglist.node, p, false ); p =  "... " + WSTM.str.trim( p ); }           p  =  p.substr(0, 50); WSTM.errors.found( "tagEndHeading",                              false,                               " " + p ); lapsus =  true; } else if ( m ) { if ( m === WSTM.o.WikiTom.CodedBlock ) { if ( arglist.props ) { if ( this.feature( arglist, "lang", false, false ) ) { l =  false; p =  this.feature( arglist,                                         "enclose",                                         true,                                         false ); if ( p === "none" ) { m =  WSTM.o.WikiTom.CodedInline; l =  true; this.feature( arglist,                                     "enclose",                                      false,                                      true ); this.feature( arglist,                                     "inline",                                      false,                                      "",                                      true ); } else { if ( p ) { this.feature( arglist,                                        "enclose",                                         false,                                         true ); l =  true; }                       p  =  this.feature( arglist, "inline" ); if (p) { m =  WSTM.o.WikiTom.CodedInline; } else { arglist.limited =  true; }                       p  =  true; }                    if ( l ) { arglist.shift =  arglist.scope + this.flush( arglist.props,                                                       arglist ); all.flip( arglist.node, arglist.join + 1,                                  arglist.move,  arglist.shift ); arglist.move =  arglist.shift.length; }                 }               }               if ( ! p ) { WSTM.errors.found("tagAttrMissing",                                   false,                                    "<" + arglist.scope + " lang=????>"); }           }            l  =  this.fence( all, arglist ); if ( l ) { arglist.mode =  m;            } }     } else if ( this.scream.indexOf( arglist.scan )  >=  0 ) { WSTM.errors.found( "tagForbidden",                           true,                            "<" + arglist.scope + ">" ); if ( arglist.join ) { all.flip( arglist.node, arglist.join, 1, "&lt;" ); }     } else if ( ! arglist.lone ) { if ( this.slice.indexOf( arglist.scan ) >=  0 ) { if ( arglist.leader ) { this.pending[ arglist.scope ] =  false; } else if ( this.pending[ arglist.scope ] ) { WSTM.errors.found( "tagNestingSelf",                                 false,                                  "<" + arglist.scope + ">" ); } else { this.pending[ arglist.scope ] =  true; }        }         if ( arglist.leader ) { p =  ago.length; if ( p ) { p =  ago[ p - 1 ]; if ( p.scope === arglist.scope ) { if ( this.friend( all, p, arglist ) ) { if ( this.pending[ arglist.scope ] ) { this.pending[ arglist.scope ] =  false; }                 } else if ( p.leave ) { if ( arglist.node >= p.node ) { all.flip( arglist.node,                                 arglist.join,                                  arglist.scope.length + 3,                                  "" ); }                    all.flip( p.node,                               p.join,                               arglist.scope.length + 2,                               "" ); arglist.move -=  2 * arglist.scope.length + 5; arglist.scope =  false; }                 m  =  p.node; ago.pop; /*              } else if (this.setter.indexOf(arglist.scan) >= 0) { // TODO: remove pair with insides, if p.leave // Not in cx translation tool. } else if ( p.scope ) { WSTM.errors.found( "tagNesting",                                    false,                                     "<" + p.scope + ">..." +                                     "" ); lapsus =  true; }           } else { p =  all.fetch( arglist.node,                                arglist.join + arglist.move + 2,                                false ); p =  WSTM.str.trim( p, true, true ); if ( ! p.length ) { p =  (arglist.join > 50  ?  arglist.join - 50  :  0); p =  all.fetch(arglist.node, p, false); p =  "... " + WSTM.str.trim( p ); }              p  =  p.substr( 0, 50 ); WSTM.errors.found( "tagEndHeading",                                 false,                                  " " + p ); lapsus =  true; }        } else { arglist.leave = ( this.setter.indexOf( arglist.scan )  >=  0                               &&  ! arglist.props ); ago.push( arglist ); if ( this.stack.indexOf( arglist.scan ) >=  0 ) { this.future( arglist.scope, true ); }        }      }      if ( arglist.lone  ||  ! arglist.leader ) { if ( ( arglist.scope === "br" &&  arglist.props )   ||              arglist.scope === "div"   ||              arglist.scope === "span" ) { if ( this.fix( arglist ) ) { if ( arglist.shift ) { all.flip( arglist.node, arglist.join + 1,                            arglist.move,  arglist.shift ); arglist.move =  arglist.shift.length; }              l  =  arglist.limited; }        }         if ( arglist.lone ) { if ( this.pending[ arglist.scope ] ) { WSTM.errors.found( "tagNestingSelf",                                 false,                                  "<" + arglist.scope + ">" ); }        }      }      if ( ! l ) { arglist.move +=  2; }     if ( arglist.limited ) { this.free( all, arglist ); if ( arglist.scope === "references" ) { if ( ! ( arglist.lone || arglist.leader ) ) { WSTM.w.elem.refgroups( arglist ); link =  ( ! lapsus ); }        }      }      if ( ! arglist.lone ) { if ( this.slice.indexOf( arglist.scan ) >=  0 ) { if ( ! lapsus ) { arglist.mode =  ( arglist.leader                                             ? WSTM.o.WikiTom.TagEnd                                             : WSTM.o.WikiTom.TagBegin ); l            =  ( arglist.scope !== "ref" ); }        }      }      if ( this.spacing.indexOf( arglist.scan )  >=  0 ) { this.flow( all, arglist ); }     if ( l ) { p =  all.folder( arglist.join,                           arglist.node,                           arglist.join + arglist.move,                           arglist.node ); if ( p ) { p.mode    =  arglist.mode; p.limited =  arglist.limited; p.lookup  =  arglist.lookup; if ( arglist.join ) { arglist.node++; arglist.join =  0; m++; }           if ( link ) { p =  { }; for ( link in arglist ) { p[ link ] =  arglist[ link ]; }  // for link in arglist ago[ ago.length - 1 ] =  p;            } if ( arglist.mode === WSTM.o.WikiTom.TagEnd ) { m =  ( m ? --m : 0 ); l =  ( arglist.scope === "includeonly"  ||                       arglist.scope === "onlyinclude" ); if ( l ) { WSTM.w.encountered.include =  true; }              all.fork( m,                         arglist.node,                         arglist.scope,                         WSTM.o.WikiTom.TagBinary,                         l ); arglist.node =  m;            } arglist.node++; arglist.move =  0; }     }   };   // .w.tags.frame

WSTM.w.tags.free =  function (all, arglist) { // Place tag on a single line // Precondition: //   all      -- WikiTom to be analyzed and isolated (root) //   arglist  -- tag information provided by .tags.fetch //               >  .node //               >< .move //               >< .join // Uses: //   .o.WikiTom.fetch //   .str.isBlank //   .o.WikiTom.flip // 2012-05-10 Perfekteschaos@de.wikipedia var late =  false, lead =  false, j    =  (arglist.join > 0  ?  arglist.join - 1  :  0), s    =  all.fetch(arglist.node, j, false), k,         m,          n;      if (j) { lead =  (s.charCodeAt(0) !== 10); }     m  =  s.indexOf(">"); if (m > 0) { s =  s.substr(0,  m + 5); n =  s.length; if (n > m) { m++; if (m > n) { k =  s.charCodeAt(m); if (k === 60) {  // '<' late =  (s.substr(m, 3)  !==  "!--"); } else if (k !== 10) { late =  true; }           }         }      }      if (lead || late) { if (late) { s            =  s.substr(0, m)  +  "\n"; arglist.move =  m + 1; }        if (lead) { s =  s.substr(0, 1)  +  "\n"  +  s.substr(1, arglist.move); arglist.join++; if (WSTM.str.isBlank(s.charCodeAt(0), false)) { s =  s.substr(1); arglist.join--; n =  j;               while (n) { k =  all.fetch(arglist.node,  n - 1,  true); if (WSTM.str.isBlank(k, false)) { arglist.join--; n--; } else { break;  // while }              }   // while }        }         all.flip(arglist.node,  j,  arglist.move + 1,  s); }  };   // .w.tags.free

WSTM.w.tags.friend =  function ( all, ancestor, arglist ) { // Merge possible pair of tags into one unary tag  // Precondition: //   all       -- root WikiTom to be manipulated //   ancestor  -- begin tag object; merged with arglist if unary //                >  .join //                >  .node //                 < .leader //                 < .lone //                 < .move //   arglist   -- tag object of end //                >< .join //                >< .move //                >< .scan //                >< .scope // Postcondition: //   Returns true, if strings have been merged, or false // Uses: //   >  .w.tags.storing //   >  .w.tags.setter //   >  .w.tags.scan //   >  .w.tags.props //   .o.WikiTom.fetch //   .str.trim //   .errors.found //   .w.tags.format // 2020-10-11 PerfektesChaos@de.wikipedia var r =  false, j =  arglist.join, m =  -1, k,         s;      if ( ancestor.node === arglist.node ) { j -=  ancestor.join; s  =  all.fetch( ancestor.node, ancestor.join, false ); m  =  j - ancestor.move; if ( m > 0 ) { if ( s.charCodeAt( 0 ) === 60 ) {  // '<' k =  s.indexOf( ">" ); } else { k =  0; }           s  =  s.substr( k + 1,  m ); }     } else if ( arglist.node  ===  ancestor.node + 1 ) { m =  arglist.join; s =  all.fetch( arglist.node, m, false ); }     if ( m > 0 ) { s =  WSTM.str.trim( s, true, true, true ); m =  s.length; }     if ( ! m ) { s =  this.storing + this.setter; if ( s.indexOf( arglist.scan ) <  0   &&              ancestor.source ) { s =  all.fetch( ancestor.node, ancestor.join, false ); m =  s.indexOf( ">" ); s =  all.fetch( arglist.node, arglist.join, false ); k =  s.indexOf( ">" ); r =  ( m > 0  &&  k > 0 ); if ( r ) { ancestor.lone   =  true; ancestor.leader =  false; ancestor.source =  this.format( ancestor ); ancestor.n      =  ancestor.source.length; ancestor.mode   =  WSTM.o.WikiTom.TagUnary; ancestor.move   =  0; if ( arglist.node > ancestor.node ) { all.flip( arglist.node, 0,  k,  "" ); } else { m +=  k;               } all.flip( ancestor.node,                        ancestor.join + 1,                         m,                         ancestor.source ); arglist.lone    =  null; arglist.leader  =  null; arglist.mode    =  0; arglist.move   +=  j - m - k + ancestor.n;               arglist.join     =  ancestor.join; arglist.scope   =  false; arglist.source  =  ""; arglist.scan    =  false; arglist.n       =  0; }        } else if ( this.setter.indexOf( arglist.scan )  <  0 ) { WSTM.errors.found( "tagEmptyUndesired",                              false,                               "<" + arglist.scope + "> " ); }     }      return  r;   };   // .w.tags.friend

WSTM.w.tags.frozen =  function  { // Prepare comment modification, if any // Uses: //   >  .mod.comment //          -- user defined comment modification object, or false //          .raw  array with link replacements //                Each element is an array with 2 or 3 elements //                [0] regexp string //                    starting with "" //                [1] replacement string //                [2] true: case insensitive //                    omitted or false: case sensitive //          .name  name of user defined request variable //    < .w.tags.replComment //   .util.isArray //   .errors.found //   .str.substrEnd // 2012-05-10 PerfektesChaos@de.wikipedia var p =  WSTM.mod.comment, a,         d,          f,          i,          l,          m,          n,          r,          s,          t,          x;      if ( p ) { s =  p.name; d =  p.raw; m =  d.length; x =  [ ]; for ( i = 0; i < m;  i++ ) { a =  d[i]; if ( WSTM.util.isArray( a ) ) { n =  a.length; if ( n >= 2 ) { f =  a[ 0 ]; t =  a[ 1 ]; l =  ( n > 2  ?  a[ 2 ]  :  false ); if ( typeof f !==  "string" ) { WSTM.errors.found( "modStringRequired",                                       false,                                        s + "[" + i + "][0]=" + f ); a =  false; }                 if ( typeof t  !==  "string" ) { WSTM.errors.found( "modStringRequired",                                       false,                                        s + "[" + i + "][1]=" + t ); a =  false; }                 if ( a ) { if ( f.substr( 0, 4 ) ===  "" ) { //                     f.slice(-3) === "-->") {                        try {                           r  =  new RegExp( f,  ( l ? "i" : "" ) );                           x.push( [ r, t] );                        } catch ( e ) {                           WSTM.errors.found( "BadRegExp", false, e + " * " + s + "[" + i + "][0]=" + f );                       }                     } else {                        WSTM.errors.found( "modCommentRequired", false, s + "[" + i + "][0]=" + f );                    }   // valid                  }   // typeof               }   // a.length            } else {               WSTM.errors.found( "modArrayRequired", false, s + "[" + i + "]" );           }   // isArray         }   // for i         if ( x.length ) {            this.replComment  =  x;         }   // anything useful      }   };   // .w.tags.frozen

WSTM.w.tags.furnished =  function (attributes, access) { // Retrieve attribute value // Precondition: //   attributes  -- Array with properties   .props of this.feature //   access      -- attribute name to be accessed // Postcondition: //   Returns value of access, or false // 2012-05-05 PerfektesChaos@de.wikipedia var r =  false, e,         i,          n;      if (attributes) { n =  attributes.length; for (i = 0; i < n;  i++) { e =  attributes[i]; if (e[1] === access) { r =  e[2]; break;  // for i            } }  // for i      } return r;   };   // .w.tags.furnished

WSTM.w.tags.future =  function (assigned, append) { // Update list of blocks to be processed later // Precondition: //   assigned  -- tag name //   append    -- true: add item   false: query for assigned // Postcondition: //   Extends block collection, if tag not yet known //   Returns true, if already stored // Uses: //   .util.isElement //   >< .w.tags.blocks // 2012-09-28 PerfektesChaos@de.wikipedia var r =  false; if (this.blocks) { r =  WSTM.util.isElement(this.blocks, assigned); if (append &&  ! r) { this.blocks.push(assigned); }     } else if (append) { this.blocks =  [ assigned ]; }     return  r;   };   // .w.tags.future

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

mw.libs.WikiSyntaxTextMod.bb.css =  function ( WSTM ) { // Analyzing and formatting of tags ... // Uses: //   .util.fiatObjects // 2022-02-02 PerfektesChaos@de.wikipedia "use strict"; WSTM.util.fiatObjects( WSTM, "w",                          { css:  { }  }                        ); WSTM.w.css.html   =  { align:   "text-align", bgcolor: "background", valign: "vertical-align" }; WSTM.w.css.values =  { "text-align":     "|left|center|right|", "vertical-align": "|top|middle|bottom|" + "baseline|sub|super|" + "text-bottom|" + "text-top|" };

WSTM.w.css.fashion =  function ( adjust, about ) { // Analyze and polish CSS declaration // Precondition: //   adjust  -- string with CSS code //   about   -- tag name or table code // Postcondition: //   Returns modified string, or false if unchanged // Uses: //   this //   >  .w.reWhitespaceMult //   >  .w.css.reAlpha //   >  .w.css.reURL //   >  .w.css.reQuote //   >  .w.css.reBadchar //   >  .w.encountered.sortable //   >  .w.css.html //   >  .w.css.values //   .str.trim //   .errors.found //   .w.css.first //   .w.css.favourite //   .w.css.four //   .w.css.field // 2022-09-12 PerfektesChaos@de.wikipedia var i, k, lean, light, n, r, rules, sign, set, style, vals; style =  adjust.replace( WSTM.w.reWhitespaceMult, " " ); lean  =  ( style.indexOf( "; " )  <  0 ); rules =  style.split( ";" ); n     =  rules.length; light =  ( lean   ||   style.indexOf( ": " )  <  0 ); for ( i = 0; i < n;  i++ ) { set =  rules[ i ]; k   =  set.indexOf( ":" ); if ( k >= 0 ) { sign =  WSTM.str.trim( set.substr( 0, k ) ); set  =  WSTM.str.trim( set.substr( k + 1 ) ); if ( sign === "" ) { if ( set === "" ) { k =  -2; } else { k =  0; }           }            if ( k > 0 ) { this.first( "Alpha" ); if ( this.reAlpha.test( sign ) ) { if ( set === "" ) { WSTM.errors.found( "cssValueMissing",                                       false,                                        sign ); set =  "??????"; } else { this.first( "URL" ); sign =  sign.toLowerCase; if ( this.reURL.test( set ) ) { WSTM.errors.found( "cssValueURL",                                          false,                                           sign + ": " + set ); } else if ( ! this.reQuote.test( set )                                &&  sign !== "font-family"                                 &&  this.reBadchar.test( set ) ) { WSTM.errors.found( "cssValueInvalid",                                          false,                                           sign + ": " + set ); } else { vals =  vals || { }; switch ( sign ) { case "background-color": if ( about !== "!"  ||                                   typeof WSTM.w.encountered.sortable                                                       !==  "boolean" ) { sign =  "background"; }  // fall through case "border-bottom-color": case "border-left-color": case "border-right-color": case "border-top-color": case "color": set =  this.favourite( set, sign ); break; case "border-color": set =  this.four( set, "color", sign ); break; case "border-bottom-width": case "border-left-width": case "border-right-width": case "border-top-width": case "height": case "line-height": case "min-height": case "min-width": case "margin-bottom": case "margin-left": case "margin-right": case "margin-top": case "max-height": case "max-width": case "padding-bottom": case "padding-left": case "padding-right": case "padding-top": case "width": set =  this.field( set, sign ); break; case "border-width": case "margin": case "padding": set =  this.four( set, "length", sign ); break; case "background": case "border": case "border-bottom": case "border-left": case "border-right": case "border-top": set =  this.features( set, sign ); break; case "position": switch ( set ) { case "absolute": case "fixed": case "relative": case "static": case "sticky": break; default: WSTM.errors.found( "cssValueInvalid",                                                      false,                                                       "position:" + set                                                                + ";" ); }  // switch set break; case "display": case "font-family": break; case "clear": switch ( set ) { case "all": set =  "both"; break; case "both": case "left": case "right": case "none": break; default: WSTM.errors.found( "cssValueInvalid",                                                      false,                                                       "clear:" + set                                                                + ";" ); }  // switch set break; case "-moz-column-count": case "-webkit-column-count": case "column-count": if ( typeof vals[ "column-count" ]                                                       ===  "string" ) { sign =  false; } else { sign =  "column-count"; }                             break; case "-moz-column-width": case "-webkit-column-width": case "column-width": if ( typeof vals[ "column-width" ]                                                       ===  "string" ) { sign =  false; } else { sign =  "column-width"; }                             break; default: set =  set.toLowerCase; if ( typeof this.html[ sign ]                                                       ===  "string" ) { WSTM.errors.found("cssHTMLsymbol",                                                  false,                                                   "style=\"" + sign                                                   + ":...\" -> "                                                   + this.html[sign]); } else if ( typeof this.values[ sign ]                                                           ===  "string"                                         &&  this.values[ sign ]                                                .indexOf("|" + set + "|")                                             <  0) { WSTM.errors.found("cssValueInvalid",                                                  false,                                                   sign + ": " + set                                                   + " -> " +                                                   this.values[ sign ] ); }                       }   // switch sign }                    if ( sign && set ) { vals =  vals || { }; if ( typeof vals[ sign ] ===  "string" ) { if ( vals[ sign ] ===  set ) { sign =  false; set  =  false; } else { WSTM.errors.found( "cssPropertyRepeated",                                                false,                                                 sign + ": " + set ); }                       } else { vals[ sign ] =  set; }                    }                  }               } else { WSTM.errors.found( "cssIDinvalid", false, sign ); }           }         } else if ( WSTM.str.trim( set )  !==  "" ) { k =  0; }        if ( ! k ) { WSTM.errors.found( "cssIDmissing", false, set ); sign =  "???"; }        if ( k >= 0  &&  sign  &&  set ) { set =  WSTM.str.trim( set ); if ( r ) { r =  r  +  ( lean ? ";" : "; " ); } else { r =  ""; }           r  =  r  +  sign  +  ( light ? ":" : ": " )  +  set; }     }   // for i      if ( r   &&   style.indexOf( ";" )  >  0 ) { r =  r + ";"; }     if ( r === adjust ) { r =  false; } else if ( ! r ) { r =  ""; }     return  r;   };   // .w.css.fashion

WSTM.w.css.favourite =  function ( assign, about ) { // Standardize colour code // Precondition: //   assign   -- string, trimmed value; #hex or rgb or name //   about    -- string, CSS attribute name // Postcondition: //   Returns attribute value, may be refined // Uses: //   >  .w.css.reHEX //   >  .w.css.reRGB //   >  .w.css.reName //   .w.css.first //   .errors.found // 2020-05-28 PerfektesChaos@de.wikipedia var s =  assign, got, i, k, limit, max, r;     if ( s.charCodeAt( 0 )  ===  35 ) {   // # s =  s.substr( 1 ).toUpperCase; this.first( "HEX" ); if ( this.reHEX.test( s ) ) { switch ( s.length ) { case 1: s =  s + s + s;   // fall through case 3: s =    s.substr( 0, 1 )  +  s.substr( 0, 1 ) + s.substr( 1, 1 ) +  s.substr( 1, 1 ) + s.substr( 2, 1 ) +  s.substr( 2, 1 ); break; case 6: break; default: s =  false; }  // switch s.length } else { s =  false; }        if ( s ) { r =  "#" + s;         } } else { s =  s.toLowerCase; if ( s.substr( 0, 4 ) ===  "rgb(" ) {            this.first( "RGB" );            got  =  this.reRGB.exec( s );            if ( got ) {               r  =  "#";               for ( i = 1;  i <= 3;  i++ ) {                  s  =  got[ i ];                  k  =  s.length - 1;                  limit  =  ( s.substr( k, 1 )  ===  "%" );                  if ( limit ) {                     s    =  s.substr( 0, k );                     max  =  100;                  } else {                     max  =  255;                  }                  if ( s  ===  max + "" ) {                     r  =  r + "FF";                  } else {                     k  =  parseInt( s, 10 );                     if ( k > max ) {                        r  =  false;                        break;   // for i                     } else {                        if ( limit ) {                           k  =  Math.floor( ( k * 256 ) / 256 ); }                    }                     if ( k < 16 ) { r =  r + "0"; }                    r  =  r + k.toString( 16 ).toUpperCase; }              }   // for i            } } else { this.first( "Name" ); if ( this.reName.test( s ) ) { r =  s;            } }     }      if ( ! r ) { WSTM.errors.found( "cssValueInvalid",                           false,                            about + ": " + assign ); r =  assign; }     return  r;   };   // .w.css.favourite

WSTM.w.css.features =  function ( assign, about ) { // Correct combined specification // Postcondition: //   Returns attribute value, may be refined // Uses: //   .w.css.flat //   .w.css.first //   .w.css.favourite //   .w.css.field //   .errors.found // 2020-07-03 PerfektesChaos@de.wikipedia var kColor = 2, kStyle = 1, kWidth = 0, s      =  this.flat( assign ), got    =  [ false, false, false ], r      =  "", tokens =  s.split( " " ), n      =  tokens.length, i, k;     this.first( "Numeric" ); for ( i = 0; i < n;  i++ ) { s =  tokens[ i ]; if ( s.charCodeAt( 0 ) ===  35 ) {   // # s =  this.favourite( s, about ); k =  kColor; } else if ( this.reNumeric.test( s ) ) { s =  this.field( s, about ); k =  kWidth; } else { s =  s.toLowerCase; switch ( s ) { case "thin": case "medium": case "thick": k =  kWidth; break; case "none": case "hidden": case "dotted": case "dashed": case "solid": case "double": case "groove": case "ridge": case "inset": case "outset": case "inherit": k =  kStyle; break; case "cyan": s =  "aqua"; k =  kColor; break; case "magenta": s =  "fuchsia"; k =  kColor; break; case "aqua": case "black": case "blue": case "fuchsia": case "gray": case "green": case "lime": case "maroon": case "navy": case "olive": case "orange": case "purple": case "red": case "silver": case "teal": case "white": case "yellow": case "transparent": k =  kColor; break; default: if ( s.substr( 0, 4 ) === "rgb(" ) {                     s  =  this.favourite( s, about );                  }                  k  =  kColor;                  break;            }   // switch s         }         if ( k < 2  &&  got[ k ] ) {            WSTM.errors.found( "cssValueInvalid", false, about + ": " + got[ k ] + " " + s );        }         if ( got[ k ] ) {            got[ k ]  =  got[ k ] + " " + s;         } else {            got[ k ]  =  s;         }      }   // for i      for ( i = 0;  i < 3;  i++ ) {         s  =  got[ i ];         if ( s ) {            if ( r ) {               r  =  r + " " + s;            } else {               r  =  s;            }         }      }   // for i      if ( n > 1 ) { //       r  =  " " + r;      }      return  r;   };   // .w.css.features

WSTM.w.css.field =  function ( assign, about ) { // Correct single length measure // Precondition: //   assign   -- string, value //   about    -- string, CSS attribute name // Postcondition: //   Returns attribute value, may be refined // Uses: //   >< .w.css.reDigits //   >< .w.css.reLengthListCorr //   >< .w.css.reLengthZero //   .errors.found // 2020-10-16 PerfektesChaos@de.wikipedia var r =  assign.toLowerCase, s, scan, suffix; if ( r !== "auto"  &&  r !== "inherit" ) { if ( typeof this.reLengthListCorr !==  "object"   ||              typeof this.reDigits  !==  "object" ) { s      =  "[0-9]+|[0-9]*\\.[0-9]+"; suffix =  "(%|em|ex|px|rem)"; scan   =  "-?(" + s + ")\\s+" + suffix; }        if ( typeof this.reDigits  !==  "object" ) { this.reDigits         =  new RegExp( "^-?[0-9]+$" ); this.reLengthSole     =  new RegExp( "^(?:-?" + s                                                 +      ")[%a-z]+$" ); this.reLengthSoleCorr =  new RegExp( "^" + scan + "$" ); }        if ( this.reDigits.test( r ) ) { r =  r + "px"; } else { r =  r.replace( this.reLengthSoleCorr, "$1$2" ); }        if ( ! this.reLengthSole.test( r ) ) { WSTM.errors.found( "cssValueInvalid",                              false,                               about + ": " + r ); }        if ( typeof this.reLengthZero  !==  "object" ) { s                     =  "-?0*\\.?0+[%a-z]*"; this.reLengthZero     =  new RegExp( "^" + s + "$" ); }        if ( this.reLengthZero.test( r ) ) { r =  "0"; }     }      return  r;   };   // .w.css.field

WSTM.w.css.first =  function ( at ) { // Initialize CSS analysis // Precondition: //   at   -- RegExp name // Postcondition: //   Ensures RegExp // Uses: //   this //    < .w.css.reAlpha //    < .w.css.reBadchar //    < .w.css.reHEX //    < .w.css.reName //    < .w.css.reQuote //    < .w.css.reRGBstd //    < .w.css.reRGB //    < .w.css.reURL // 2020-05-15 PerfektesChaos@de.wikipedia var s;     if ( typeof this[ "re" + at ]  !==  "object" ) { switch ( at ) { case "Alpha": this.reAlpha =  new RegExp( "^[-a-zA-Z]+$" ); break; case "HEX": this.reHEX =  new RegExp( "^[0-9A-F]+$" ); break; case "Name": this.reName =  new RegExp( "^[a-z]+$" ); break; case "Numeric": this.reNumeric =  new RegExp( "^-?(?:[0-9]+|" + "[0-9]*\\.[0-9]+)" );              break; case "RGB": s =  " *([0-9]+%?) *"; s =  "rgb\\(" + s + ","                              + s + ","                              + s + "\\)"; this.reRGB    =  new RegExp( "^" + s + "$" ); this.reRGBstd =  new RegExp( s, "gi" ); break; case "URL": this.reBadchar =  new RegExp( "[^-a-z_A-Z.0-9% #]" ); this.reQuote   =  new RegExp( "['\"]");               this.reURL      =  new RegExp( "\\burl\\s*\\(", "i" );               break;         }   // switch at      }   };   // .w.css.first

WSTM.w.css.flat =  function ( assign ) { // Normalize rgb colour assignment // Precondition: //   assign   -- string, rgb or not // Postcondition: //   Returns attribute value, may be refined // Uses: //   >  .w.css.reRGBstd //   .w.css.first // 2020-05-15 PerfektesChaos@de.wikipedia var r;     if ( assign.indexOf( "(" )  >  0 ) {         this.first( "RGB" );         r  =  assign.replace( this.reRGBstd, "rgb($1,$2,$3)");      }      return  r  ||  assign;   };   // .w.css.flat

WSTM.w.css.four =  function ( assign, ask, about ) { // Standardize list of up to 4 items // Precondition: //   assign   -- string, multiple items permitted //   ask      -- string, "color" or "length" //   about    -- string, CSS attribute name // Postcondition: //   Returns attribute value, may be refined // Uses: //   .w.css.flat //   .errors.found //   .w.css.favourite //   .w.css.field // 2020-05-15 PerfektesChaos@de.wikipedia var i, n, r, s, tokens; if ( ask === "color" ) { s =  this.flat( assign ); } else { s =  assign; }     tokens  =  s.split( " " ); n      =  tokens.length; if ( n > 4 ) { WSTM.errors.found( "cssValueInvalid",                           false,                            about + ": " + assign ); } else { for ( i = 0; i < n;  i++ ) { s =  tokens[ i ]; switch ( ask ) { case "color": s =  this.favourite( s, about ); break; case "length": s =  this.field( s, about ); break; }  // switch s.length if ( r ) { r =  r + " " + s;            } else { r =  s;            } }  // for i         if ( n > 1 ) { r =  " " + r;         } }     return  r  ||  assign; };  // .w.css.four

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

//---

( function ( WSTM ) {  "use strict";   var sub      =  "X",       self     =  WSTM.w.tags.self,       version  =  WSTM.w.tags.vsn,       rls;   if ( typeof WSTM.main  ===  "object" &&    WSTM.main   && typeof WSTM.main.wait ===  "function" ) {      // Start on import: callback to waiting ...      WSTM.main.wait( sub, version );   } else 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/dX.js