{"version":3,"file":"autolinker.js","sourceRoot":"","sources":["../../src/autolinker.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAGxD,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAkB,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAkB,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyGG;AACH;IA2WI;;;;OAIG;IACH,oBAAY,GAA0B;QAA1B,oBAAA,EAAA,QAA0B;QAlStC;;;;;;WAMG;QACM,YAAO,GAAG,UAAU,CAAC,OAAO,CAAC;QAEtC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAmCG;QACc,SAAI,GAAkB,EAAE,CAAC,CAAC,gGAAgG;QAE3I;;;;;WAKG;QACc,UAAK,GAAY,IAAI,CAAC,CAAC,gGAAgG;QAExI;;;;;WAKG;QACc,UAAK,GAAY,IAAI,CAAC,CAAC,gGAAgG;QAExI;;;;;;;;;;;;;WAaG;QACc,YAAO,GAAkB,KAAK,CAAC,CAAC,gGAAgG;QAEjJ;;;;;;;;;;;;;WAaG;QACc,YAAO,GAAkB,KAAK,CAAC,CAAC,gGAAgG;QAEjJ;;;;WAIG;QACc,cAAS,GAAY,IAAI,CAAC,CAAC,gGAAgG;QAE5I;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAgCG;QACc,gBAAW,GAAmC;YAC3D,MAAM,EAAE,IAAI;YACZ,GAAG,EAAE,IAAI;SACZ,CAAC,CAAC,gGAAgG;QAEnG;;;;;;;;WAQG;QACc,uBAAkB,GAAY,IAAI,CAAC,CAAC,gGAAgG;QAErJ;;;;;;;;WAQG;QACc,0BAAqB,GAAY,IAAI,CAAC,CAAC,gGAAgG;QAExJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WA8CG;QACc,aAAQ,GAAgC;YACrD,MAAM,EAAE,CAAC;YACT,QAAQ,EAAE,KAAK;SAClB,CAAC,CAAC,gGAAgG;QAEnG;;;;;;;;;;;;;;;WAeG;QACc,cAAS,GAAW,EAAE,CAAC,CAAC,gGAAgG;QAEzI;;;;;;;;;;;;;;;;WAgBG;QACc,cAAS,GAAqB,IAAI,CAAC,CAAC,gGAAgG;QAErJ;;;;;;WAMG;QACc,YAAO,GAAuB,SAAS,CAAC,CAAC,gGAAgG;QAE1J;;;;;;;;;;;;;WAaG;QACc,iBAAY,GAAY,KAAK,CAAC,CAAC,gGAAgG;QAEhJ;;;;;;WAMG;QACK,eAAU,GAA4B,IAAI,CAAC;QAQ/C,uEAAuE;QACvE,kEAAkE;QAClE,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;QAC3D,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;QAC3D,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC;QAC3C,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC;QAC3C,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC;QAC3E,IAAI,CAAC,WAAW,GAAG,uBAAuB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAC5D,IAAI,CAAC,kBAAkB,GAAG,SAAS,CAAC,GAAG,CAAC,kBAAkB,CAAC;YACvD,CAAC,CAAC,GAAG,CAAC,kBAAkB;YACxB,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC;QAC9B,IAAI,CAAC,qBAAqB,GAAG,SAAS,CAAC,GAAG,CAAC,qBAAqB,CAAC;YAC7D,CAAC,CAAC,GAAG,CAAC,qBAAqB;YAC3B,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC;QACjC,IAAI,CAAC,YAAY,GAAG,GAAG,CAAC,YAAY,IAAI,KAAK,CAAC;QAE9C,0CAA0C;QAC1C,IAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAC7B,IAAI,OAAO,KAAK,KAAK,IAAI,eAAe,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YAC/D,MAAM,IAAI,KAAK,CAAC,iCAA4B,OAAO,iBAAc,CAAC,CAAC;QACvE,CAAC;QAED,0CAA0C;QAC1C,IAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAC7B,IAAI,OAAO,KAAK,KAAK,IAAI,eAAe,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YAC/D,MAAM,IAAI,KAAK,CAAC,iCAA4B,OAAO,iBAAc,CAAC,CAAC;QACvE,CAAC;QAED,IAAI,CAAC,QAAQ,GAAG,oBAAoB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACnD,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC;QACjD,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC;QACjD,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC;IACvC,CAAC;IArYD;;;;;;;;;;;;;;;;;;;;;OAqBG;IACI,eAAI,GAAX,UAAY,UAAkB,EAAE,OAA0B;QACtD,IAAM,UAAU,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC;QAC3C,OAAO,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACvC,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCG;IACI,gBAAK,GAAZ,UAAa,UAAkB,EAAE,OAA0B;QACvD,IAAM,UAAU,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC;QAC3C,OAAO,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACxC,CAAC;IAwUD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;IACH,0BAAK,GAAL,UAAM,UAAkB;QAAxB,iBA6DC;QA5DG,IAAM,YAAY,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC9C,IAAI,kBAAkB,GAAG,CAAC,CAAC,CAAC,gKAAgK;QAE5L,IAAI,OAAO,GAAY,EAAE,CAAC;QAE1B,qEAAqE;QACrE,wDAAwD;QACxD,SAAS,CAAC,UAAU,EAAE;YAClB,SAAS,EAAE,UAAC,OAAe;gBACvB,IAAI,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;oBACrC,kBAAkB,EAAE,CAAC;gBACzB,CAAC;YACL,CAAC;YACD,MAAM,EAAE,UAAC,IAAY,EAAE,MAAc;gBACjC,8EAA8E;gBAC9E,IAAI,kBAAkB,KAAK,CAAC,EAAE,CAAC;oBAC3B,gEAAgE;oBAChE,qDAAqD;oBACrD,qDAAqD;oBACrD,2DAA2D;oBAC3D,sDAAsD;oBACtD,IAAM,0BAA0B,GAC5B,4DAA4D,CAAC,CAAC,kGAAkG;oBACpK,IAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;oBAEzD,IAAI,eAAa,GAAG,MAAM,CAAC;oBAC3B,SAAS,CAAC,OAAO,CAAC,UAAC,SAAS,EAAE,CAAC;wBAC3B,8DAA8D;wBAC9D,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;4BACd,IAAM,eAAe,GAAG,KAAI,CAAC,SAAS,CAAC,SAAS,EAAE,eAAa,CAAC,CAAC;4BACjE,OAAO,CAAC,IAAI,OAAZ,OAAO,2BAAS,eAAe,WAAE;wBACrC,CAAC;wBACD,eAAa,IAAI,SAAS,CAAC,MAAM,CAAC;oBACtC,CAAC,CAAC,CAAC;gBACP,CAAC;YACL,CAAC;YACD,UAAU,EAAE,UAAC,OAAe;gBACxB,IAAI,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;oBACrC,kBAAkB,GAAG,IAAI,CAAC,GAAG,CAAC,kBAAkB,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,2FAA2F;gBACzJ,CAAC;YACL,CAAC;YACD,SAAS,EAAE,WAAC,mBAAmB,IAAM,CAAC,EAAE,mCAAmC;YAC3E,SAAS,EAAE,WAAC,mBAAmB,IAAM,CAAC,EAAE,mCAAmC;SAC9E,CAAC,CAAC;QAEH,kEAAkE;QAClE,sEAAsE;QACtE,sEAAsE;QACtE,oEAAoE;QACpE,mEAAmE;QACnE,QAAQ;QACR,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAEvC,oEAAoE;QACpE,qEAAqE;QACrE,sEAAsE;QACtE,yDAAyD;QACzD,OAAO,GAAG,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC;QAE9C,OAAO,OAAO,CAAC;IACnB,CAAC;IAED;;;;;;;;;;OAUG;IACK,mCAAc,GAAtB,UAAuB,OAAgB;QACnC,uEAAuE;QACvE,SAAS;QACT,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAE5B,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,IAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YACzB,IAAM,MAAM,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;YACjC,IAAM,iBAAiB,GAAG,KAAK,CAAC,cAAc,EAAE,CAAC,MAAM,CAAC;YAExD,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;gBACzB,iEAAiE;gBACjE,8DAA8D;gBAC9D,2DAA2D;gBAC3D,iDAAiD;gBACjD,IAAI,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,KAAK,MAAM,EAAE,CAAC;oBACxC,2BAA2B;oBAC3B,IAAM,SAAS,GACX,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC,MAAM,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;oBAC3E,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;oBAC7B,SAAS;gBACb,CAAC;gBAED,gEAAgE;gBAChE,EAAE;gBACF,+DAA+D;gBAC/D,gEAAgE;gBAChE,4DAA4D;gBAC5D,8DAA8D;gBAC9D,mDAAmD;gBACnD,EAAE;gBACF,+DAA+D;gBAC/D,+DAA+D;gBAC/D,6DAA6D;gBAC7D,+DAA+D;gBAC/D,6DAA6D;gBAC7D,4DAA4D;gBAC5D,6CAA6C;gBAC7C,6CAA6C;gBAC7C,gCAAgC;gBAChC,gBAAgB;gBAChB,IAAI;YACR,CAAC;YACD,CAAC,EAAE,CAAC;QACR,CAAC;QAED,OAAO,OAAO,CAAC;IACnB,CAAC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACK,0CAAqB,GAA7B,UAA8B,OAAgB;QAC1C,IAAI,CAAC,IAAI,CAAC,OAAO;YACb,mBAAmB,CAAC,OAAO,EAAE,UAAC,KAAY;gBACtC,OAAO,KAAK,CAAC,OAAO,EAAE,KAAK,SAAS,CAAC;YACzC,CAAC,CAAC,CAAC;QACP,IAAI,CAAC,IAAI,CAAC,KAAK;YACX,mBAAmB,CAAC,OAAO,EAAE,UAAC,KAAY;gBACtC,OAAO,KAAK,CAAC,OAAO,EAAE,KAAK,OAAO,CAAC;YACvC,CAAC,CAAC,CAAC;QACP,IAAI,CAAC,IAAI,CAAC,KAAK;YACX,mBAAmB,CAAC,OAAO,EAAE,UAAC,KAAY;gBACtC,OAAO,KAAK,CAAC,OAAO,EAAE,KAAK,OAAO,CAAC;YACvC,CAAC,CAAC,CAAC;QACP,IAAI,CAAC,IAAI,CAAC,OAAO;YACb,mBAAmB,CAAC,OAAO,EAAE,UAAC,KAAY;gBACtC,OAAO,KAAK,CAAC,OAAO,EAAE,KAAK,SAAS,CAAC;YACzC,CAAC,CAAC,CAAC;QACP,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YAC3B,mBAAmB,CACf,OAAO,EACP,UAAC,CAAQ;gBACL,OAAA,CAAC,CAAC,OAAO,EAAE,KAAK,KAAK,IAAK,CAAc,CAAC,eAAe,EAAE,KAAK,QAAQ;YAAvE,CAAuE,CAC9E,CAAC;QACN,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACxB,mBAAmB,CACf,OAAO,EACP,UAAC,CAAQ,IAAK,OAAA,CAAC,CAAC,OAAO,EAAE,KAAK,KAAK,IAAK,CAAc,CAAC,eAAe,EAAE,KAAK,KAAK,EAApE,CAAoE,CACrF,CAAC;QACN,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACzB,mBAAmB,CACf,OAAO,EACP,UAAC,CAAQ,IAAK,OAAA,CAAC,CAAC,OAAO,EAAE,KAAK,KAAK,IAAK,CAAc,CAAC,eAAe,EAAE,KAAK,MAAM,EAArE,CAAqE,CACtF,CAAC;QACN,CAAC;QAED,OAAO,OAAO,CAAC;IACnB,CAAC;IAED;;;;;;;;;;;;;;;;;;;;OAoBG;IACK,8BAAS,GAAjB,UAAkB,IAAY,EAAE,MAAc;QAC1C,MAAM,GAAG,MAAM,IAAI,CAAC,CAAC;QACrB,IAAM,OAAO,GAAY,YAAY,CAAC,IAAI,EAAE;YACxC,UAAU,EAAE,IAAI,CAAC,aAAa,EAAE;YAChC,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;YAC3C,qBAAqB,EAAE,IAAI,CAAC,qBAAqB;YACjD,kBAAkB,EAAE,IAAI,CAAC,OAAyB;YAClD,kBAAkB,EAAG,IAAI,CAAC,OAA0B,IAAI,SAAS;SACpE,CAAC,CAAC;QAEH,iEAAiE;QACjE,gEAAgE;QAChE,iEAAiE;QACjE,4CAA4C;QAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,GAAG,cAAc,EAAE,CAAC,EAAE,EAAE,CAAC;YACvE,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;QAC1D,CAAC;QAED,OAAO,OAAO,CAAC;IACnB,CAAC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,yBAAI,GAAJ,UAAK,UAAkB;QACnB,IAAI,CAAC,UAAU,EAAE,CAAC;YACd,OAAO,EAAE,CAAC;QACd,CAAC,CAAC,sIAAsI;QAExI;;;WAGG;QACH,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,UAAU,GAAG,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACxE,CAAC;QAED,IAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACvC,IAAM,OAAO,GAAG,IAAI,KAAK,CAAS,OAAO,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QAC1D,IAAI,SAAS,GAAG,CAAC,CAAC;QAElB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;YACjD,IAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YAEzB,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;YACjE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC;YAE/C,SAAS,GAAG,KAAK,CAAC,SAAS,EAAE,GAAG,KAAK,CAAC,cAAc,EAAE,CAAC,MAAM,CAAC;QAClE,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,uCAAuC;QAEtF,OAAO,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5B,CAAC;IAED;;;;;;;;;;;OAWG;IACK,yCAAoB,GAA5B,UAA6B,KAAY;QACrC,6CAA6C;QAC7C,IAAI,eAAgC,CAAC;QACrC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,qCAAqC;QACrG,CAAC;QAED,IAAI,OAAO,eAAe,KAAK,QAAQ,EAAE,CAAC;YACtC,OAAO,eAAe,CAAC,CAAC,0CAA0C;QACtE,CAAC;aAAM,IAAI,eAAe,KAAK,KAAK,EAAE,CAAC;YACnC,OAAO,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC,+BAA+B;QAClE,CAAC;aAAM,IAAI,eAAe,YAAY,OAAO,EAAE,CAAC;YAC5C,OAAO,eAAe,CAAC,cAAc,EAAE,CAAC;QAC5C,CAAC;aAAM,CAAC;YACJ,qEAAqE;YACrE,qDAAqD;YACrD,IAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,yCAAyC;YAE7E,OAAO,SAAS,CAAC,cAAc,EAAE,CAAC;QACtC,CAAC;IACL,CAAC;IAED;;;;;;OAMG;IACK,kCAAa,GAArB;QACI,IAAI,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QAEjC,IAAI,CAAC,UAAU,EAAE,CAAC;YACd,UAAU,GAAG,IAAI,CAAC,UAAU,GAAG,IAAI,gBAAgB,CAAC;gBAChD,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,SAAS,EAAE,IAAI,CAAC,SAAS;aAC5B,CAAC,CAAC;QACP,CAAC;QAED,OAAO,UAAU,CAAC;IACtB,CAAC;IAxvBD,qDAAqD;IAErD;;;;;;;OAOG;IACa,kBAAO,GAAG,OAAO,AAAV,CAAW;IA+uBtC,iBAAC;CAAA,AA1vBD,IA0vBC;eA1vBoB,UAAU;AA4vB/B;;;;;;;;;GASG;AACH,SAAS,gBAAgB,CAAC,IAA4B;IAClD,IAAI,IAAI,IAAI,IAAI;QAAE,IAAI,GAAG,IAAI,CAAC,CAAC,oBAAoB;IAEnD,IAAI,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;QAClB,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IACxE,CAAC;SAAM,CAAC;QACJ,cAAc;QACd,OAAO;YACH,aAAa,EAAE,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI;YACxE,UAAU,EAAE,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI;YAC/D,WAAW,EAAE,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI;SACrE,CAAC;IACN,CAAC;AACL,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,uBAAuB,CAC5B,WAA0C;IAE1C,IAAI,WAAW,IAAI,IAAI;QAAE,WAAW,GAAG,IAAI,CAAC,CAAC,oBAAoB;IAEjE,IAAI,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC;QACzB,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC;IACrD,CAAC;SAAM,CAAC;QACJ,cAAc;QACd,OAAO;YACH,MAAM,EAAE,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI;YACjE,GAAG,EAAE,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI;SAC3D,CAAC;IACN,CAAC;AACL,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,oBAAoB,CAAC,QAAoC;IAC9D,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IACjD,CAAC;SAAM,CAAC;QACJ,4BAA4B;QAC5B,kBACI,MAAM,EAAE,MAAM,CAAC,iBAAiB,EAChC,QAAQ,EAAE,KAAK,IACZ,QAAQ,EACb;IACN,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,SAAS,aAAa,CAAC,CAAQ,EAAE,CAAQ;IACrC,OAAO,CAAC,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,SAAS,EAAE,CAAC;AACzC,CAAC","sourcesContent":["import { version } from './version';\nimport { isBoolean, removeWithPredicate } from './utils';\nimport { AnchorTagBuilder } from './anchor-tag-builder';\nimport { Match } from './match/match';\nimport { UrlMatch } from './match/url-match';\nimport { HtmlTag } from './html-tag';\nimport { parseMatches } from './parser/parse-matches';\nimport { parseHtml } from './htmlParser/parse-html';\nimport { MentionService, mentionServices } from './parser/mention-utils';\nimport { HashtagService, hashtagServices } from './parser/hashtag-utils';\n\n/**\n * @class Autolinker\n * @extends Object\n *\n * Utility class used to process a given string of text, and wrap the matches in\n * the appropriate anchor (&lt;a&gt;) tags to turn them into links.\n *\n * Any of the configuration options may be provided in an Object provided\n * to the Autolinker constructor, which will configure how the {@link #link link()}\n * method will process the links.\n *\n * For example:\n *\n *     var autolinker = new Autolinker( {\n *         newWindow : false,\n *         truncate  : 30\n *     } );\n *\n *     var html = autolinker.link( \"Joe went to www.yahoo.com\" );\n *     // produces: 'Joe went to <a href=\"http://www.yahoo.com\">yahoo.com</a>'\n *\n *\n * The {@link #static-link static link()} method may also be used to inline\n * options into a single call, which may be more convenient for one-off uses.\n * For example:\n *\n *     var html = Autolinker.link( \"Joe went to www.yahoo.com\", {\n *         newWindow : false,\n *         truncate  : 30\n *     } );\n *     // produces: 'Joe went to <a href=\"http://www.yahoo.com\">yahoo.com</a>'\n *\n *\n * ## Custom Replacements of Links\n *\n * If the configuration options do not provide enough flexibility, a {@link #replaceFn}\n * may be provided to fully customize the output of Autolinker. This function is\n * called once for each URL/Email/Phone#/Hashtag/Mention (Twitter, Instagram, Soundcloud)\n * match that is encountered.\n *\n * For example:\n *\n *     var input = \"...\";  // string with URLs, Email Addresses, Phone #s, Hashtags, and Mentions (Twitter, Instagram, Soundcloud)\n *\n *     var linkedText = Autolinker.link( input, {\n *         replaceFn : function( match ) {\n *             console.log( \"href = \", match.getAnchorHref() );\n *             console.log( \"text = \", match.getAnchorText() );\n *\n *             switch( match.getType() ) {\n *                 case 'url' :\n *                     console.log( \"url: \", match.getUrl() );\n *\n *                     if( match.getUrl().indexOf( 'mysite.com' ) === -1 ) {\n *                         var tag = match.buildTag();  // returns an `Autolinker.HtmlTag` instance, which provides mutator methods for easy changes\n *                         tag.setAttr( 'rel', 'nofollow' );\n *                         tag.addClass( 'external-link' );\n *\n *                         return tag;\n *\n *                     } else {\n *                         return true;  // let Autolinker perform its normal anchor tag replacement\n *                     }\n *\n *                 case 'email' :\n *                     var email = match.getEmail();\n *                     console.log( \"email: \", email );\n *\n *                     if( email === \"my@own.address\" ) {\n *                         return false;  // don't auto-link this particular email address; leave as-is\n *                     } else {\n *                         return;  // no return value will have Autolinker perform its normal anchor tag replacement (same as returning `true`)\n *                     }\n *\n *                 case 'phone' :\n *                     var phoneNumber = match.getPhoneNumber();\n *                     console.log( phoneNumber );\n *\n *                     return '<a href=\"http://newplace.to.link.phone.numbers.to/\">' + phoneNumber + '</a>';\n *\n *                 case 'hashtag' :\n *                     var hashtag = match.getHashtag();\n *                     console.log( hashtag );\n *\n *                     return '<a href=\"http://newplace.to.link.hashtag.handles.to/\">' + hashtag + '</a>';\n *\n *                 case 'mention' :\n *                     var mention = match.getMention();\n *                     console.log( mention );\n *\n *                     return '<a href=\"http://newplace.to.link.mention.to/\">' + mention + '</a>';\n *             }\n *         }\n *     } );\n *\n *\n * The function may return the following values:\n *\n * - `true` (Boolean): Allow Autolinker to replace the match as it normally\n *   would.\n * - `false` (Boolean): Do not replace the current match at all - leave as-is.\n * - Any String: If a string is returned from the function, the string will be\n *   used directly as the replacement HTML for the match.\n * - An {@link Autolinker.HtmlTag} instance, which can be used to build/modify\n *   an HTML tag before writing out its HTML text.\n */\nexport default class Autolinker {\n    // NOTE: must be 'export default' here for UMD module\n\n    /**\n     * @static\n     * @property {String} version\n     *\n     * The Autolinker version number in the form major.minor.patch\n     *\n     * Ex: 3.15.0\n     */\n    static readonly version = version;\n\n    /**\n     * Automatically links URLs, Email addresses, Phone Numbers, Twitter handles,\n     * Hashtags, and Mentions found in the given chunk of HTML. Does not link URLs\n     * found within HTML tags.\n     *\n     * For instance, if given the text: `You should go to http://www.yahoo.com`,\n     * then the result will be `You should go to &lt;a href=\"http://www.yahoo.com\"&gt;http://www.yahoo.com&lt;/a&gt;`\n     *\n     * Example:\n     *\n     *     var linkedText = Autolinker.link( \"Go to google.com\", { newWindow: false } );\n     *     // Produces: \"Go to <a href=\"http://google.com\">google.com</a>\"\n     *\n     * @static\n     * @param {String} textOrHtml The HTML or text to find matches within (depending\n     *   on if the {@link #urls}, {@link #email}, {@link #phone}, {@link #mention},\n     *   {@link #hashtag}, and {@link #mention} options are enabled).\n     * @param {Object} [options] Any of the configuration options for the Autolinker\n     *   class, specified in an Object (map). See the class description for an\n     *   example call.\n     * @return {String} The HTML text, with matches automatically linked.\n     */\n    static link(textOrHtml: string, options?: AutolinkerConfig) {\n        const autolinker = new Autolinker(options);\n        return autolinker.link(textOrHtml);\n    }\n\n    /**\n     * Parses the input `textOrHtml` looking for URLs, email addresses, phone\n     * numbers, username handles, and hashtags (depending on the configuration\n     * of the Autolinker instance), and returns an array of {@link Autolinker.match.Match}\n     * objects describing those matches (without making any replacements).\n     *\n     * Note that if parsing multiple pieces of text, it is slightly more efficient\n     * to create an Autolinker instance, and use the instance-level {@link #parse}\n     * method.\n     *\n     * Example:\n     *\n     *     var matches = Autolinker.parse(\"Hello google.com, I am asdf@asdf.com\", {\n     *         urls: true,\n     *         email: true\n     *     });\n     *\n     *     console.log(matches.length);         // 2\n     *     console.log(matches[0].getType());   // 'url'\n     *     console.log(matches[0].getUrl());    // 'google.com'\n     *     console.log(matches[1].getType());   // 'email'\n     *     console.log(matches[1].getEmail());  // 'asdf@asdf.com'\n     *\n     * @static\n     * @param {String} textOrHtml The HTML or text to find matches within\n     *   (depending on if the {@link #urls}, {@link #email}, {@link #phone},\n     *   {@link #hashtag}, and {@link #mention} options are enabled).\n     * @param {Object} [options] Any of the configuration options for the Autolinker\n     *   class, specified in an Object (map). See the class description for an\n     *   example call.\n     * @return {Autolinker.match.Match[]} The array of Matches found in the\n     *   given input `textOrHtml`.\n     */\n    static parse(textOrHtml: string, options?: AutolinkerConfig) {\n        const autolinker = new Autolinker(options);\n        return autolinker.parse(textOrHtml);\n    }\n\n    /**\n     * The Autolinker version number exposed on the instance itself.\n     *\n     * Ex: 0.25.1\n     *\n     * @property {String} version\n     */\n    readonly version = Autolinker.version;\n\n    /**\n     * @cfg {Boolean/Object} [urls]\n     *\n     * `true` if URLs should be automatically linked, `false` if they should not\n     * be. Defaults to `true`.\n     *\n     * Examples:\n     *\n     *     urls: true\n     *\n     *     // or\n     *\n     *     urls: {\n     *         schemeMatches : true,\n     *         tldMatches    : true,\n     *         ipV4Matches   : true\n     *     }\n     *\n     * As shown above, this option also accepts an Object form with 3 properties\n     * to allow for more customization of what exactly gets linked. All default\n     * to `true`:\n     *\n     * @cfg {Boolean} [urls.schemeMatches] `true` to match URLs found prefixed\n     *   with a scheme, i.e. `http://google.com`, or `other+scheme://google.com`,\n     *   `false` to prevent these types of matches.\n     * @cfg {Boolean} [urls.tldMatches] `true` to match URLs with known top\n     *   level domains (.com, .net, etc.) that are not prefixed with a scheme\n     *   (such as 'http://'). This option attempts to match anything that looks\n     *   like a URL in the given text. Ex: `google.com`, `asdf.org/?page=1`, etc.\n     *   `false` to prevent these types of matches.\n     * @cfg {Boolean} [urls.ipV4Matches] `true` to match IPv4 addresses in text\n     *   that are not prefixed with a scheme (such as 'http://'). This option\n     *   attempts to match anything that looks like an IPv4 address in text. Ex:\n     *   `192.168.0.1`, `10.0.0.1/?page=1`, etc. `false` to prevent these types\n     *   of matches.\n     */\n    private readonly urls: UrlsConfigObj = {}; // default value just to get the above doc comment in the ES5 output and documentation generator\n\n    /**\n     * @cfg {Boolean} [email=true]\n     *\n     * `true` if email addresses should be automatically linked, `false` if they\n     * should not be.\n     */\n    private readonly email: boolean = true; // default value just to get the above doc comment in the ES5 output and documentation generator\n\n    /**\n     * @cfg {Boolean} [phone=true]\n     *\n     * `true` if Phone numbers (\"(555)555-5555\") should be automatically linked,\n     * `false` if they should not be.\n     */\n    private readonly phone: boolean = true; // default value just to get the above doc comment in the ES5 output and documentation generator\n\n    /**\n     * @cfg {Boolean/String} [hashtag=false]\n     *\n     * A string for the service name to have hashtags (ex: \"#myHashtag\")\n     * auto-linked to. The currently-supported values are:\n     *\n     * - 'twitter'\n     * - 'facebook'\n     * - 'instagram'\n     * - 'tiktok'\n     * - 'youtube'\n     *\n     * Pass `false` to skip auto-linking of hashtags.\n     */\n    private readonly hashtag: HashtagConfig = false; // default value just to get the above doc comment in the ES5 output and documentation generator\n\n    /**\n     * @cfg {String/Boolean} [mention=false]\n     *\n     * A string for the service name to have mentions (ex: \"@myuser\")\n     * auto-linked to. The currently supported values are:\n     *\n     * - 'twitter'\n     * - 'instagram'\n     * - 'soundcloud'\n     * - 'tiktok'\n     * - 'youtube'\n     *\n     * Defaults to `false` to skip auto-linking of mentions.\n     */\n    private readonly mention: MentionConfig = false; // default value just to get the above doc comment in the ES5 output and documentation generator\n\n    /**\n     * @cfg {Boolean} [newWindow=true]\n     *\n     * `true` if the links should open in a new window, `false` otherwise.\n     */\n    private readonly newWindow: boolean = true; // default value just to get the above doc comment in the ES5 output and documentation generator\n\n    /**\n     * @cfg {Boolean/Object} [stripPrefix=true]\n     *\n     * `true` if 'http://' (or 'https://') and/or the 'www.' should be stripped\n     * from the beginning of URL links' text, `false` otherwise. Defaults to\n     * `true`.\n     *\n     * Examples:\n     *\n     *     stripPrefix: true\n     *\n     *     // or\n     *\n     *     stripPrefix: {\n     *         scheme : true,\n     *         www    : true\n     *     }\n     *\n     * As shown above, this option also accepts an Object form with 2 properties\n     * to allow for more customization of what exactly is prevented from being\n     * displayed. Both default to `true`:\n     *\n     * @cfg {Boolean} [stripPrefix.scheme] `true` to prevent the scheme part of\n     *   a URL match from being displayed to the user. Example:\n     *   `'http://google.com'` will be displayed as `'google.com'`. `false` to\n     *   not strip the scheme. NOTE: Only an `'http://'` or `'https://'` scheme\n     *   will be removed, so as not to remove a potentially dangerous scheme\n     *   (such as `'file://'` or `'javascript:'`)\n     * @cfg {Boolean} [stripPrefix.www] www (Boolean): `true` to prevent the\n     *   `'www.'` part of a URL match from being displayed to the user. Ex:\n     *   `'www.google.com'` will be displayed as `'google.com'`. `false` to not\n     *   strip the `'www'`.\n     */\n    private readonly stripPrefix: Required<StripPrefixConfigObj> = {\n        scheme: true,\n        www: true,\n    }; // default value just to get the above doc comment in the ES5 output and documentation generator\n\n    /**\n     * @cfg {Boolean} [stripTrailingSlash=true]\n     *\n     * `true` to remove the trailing slash from URL matches, `false` to keep\n     *  the trailing slash.\n     *\n     *  Example when `true`: `http://google.com/` will be displayed as\n     *  `http://google.com`.\n     */\n    private readonly stripTrailingSlash: boolean = true; // default value just to get the above doc comment in the ES5 output and documentation generator\n\n    /**\n     * @cfg {Boolean} [decodePercentEncoding=true]\n     *\n     * `true` to decode percent-encoded characters in URL matches, `false` to keep\n     *  the percent-encoded characters.\n     *\n     *  Example when `true`: `https://en.wikipedia.org/wiki/San_Jos%C3%A9` will\n     *  be displayed as `https://en.wikipedia.org/wiki/San_José`.\n     */\n    private readonly decodePercentEncoding: boolean = true; // default value just to get the above doc comment in the ES5 output and documentation generator\n\n    /**\n     * @cfg {Number/Object} [truncate=0]\n     *\n     * ## Number Form\n     *\n     * A number for how many characters matched text should be truncated to\n     * inside the text of a link. If the matched text is over this number of\n     * characters, it will be truncated to this length by adding a two period\n     * ellipsis ('..') to the end of the string.\n     *\n     * For example: A url like 'http://www.yahoo.com/some/long/path/to/a/file'\n     * truncated to 25 characters might look something like this:\n     * 'yahoo.com/some/long/pat..'\n     *\n     * Example Usage:\n     *\n     *     truncate: 25\n     *\n     *\n     *  Defaults to `0` for \"no truncation.\"\n     *\n     *\n     * ## Object Form\n     *\n     * An Object may also be provided with two properties: `length` (Number) and\n     * `location` (String). `location` may be one of the following: 'end'\n     * (default), 'middle', or 'smart'.\n     *\n     * Example Usage:\n     *\n     *     truncate: { length: 25, location: 'middle' }\n     *\n     * @cfg {Number} [truncate.length=0] How many characters to allow before\n     *   truncation will occur. Defaults to `0` for \"no truncation.\"\n     * @cfg {\"end\"/\"middle\"/\"smart\"} [truncate.location=\"end\"]\n     *\n     * - 'end' (default): will truncate up to the number of characters, and then\n     *   add an ellipsis at the end. Ex: 'yahoo.com/some/long/pat..'\n     * - 'middle': will truncate and add the ellipsis in the middle. Ex:\n     *   'yahoo.com/s..th/to/a/file'\n     * - 'smart': for URLs where the algorithm attempts to strip out unnecessary\n     *   parts first (such as the 'www.', then URL scheme, hash, etc.),\n     *   attempting to make the URL human-readable before looking for a good\n     *   point to insert the ellipsis if it is still too long. Ex:\n     *   'yahoo.com/some..to/a/file'. For more details, see\n     *   {@link Autolinker.truncate.TruncateSmart}.\n     */\n    private readonly truncate: Required<TruncateConfigObj> = {\n        length: 0,\n        location: 'end',\n    }; // default value just to get the above doc comment in the ES5 output and documentation generator\n\n    /**\n     * @cfg {String} className\n     *\n     * A CSS class name to add to the generated links. This class will be added\n     * to all links, as well as this class plus match suffixes for styling\n     * url/email/phone/hashtag/mention links differently.\n     *\n     * For example, if this config is provided as \"myLink\", then:\n     *\n     * - URL links will have the CSS classes: \"myLink myLink-url\"\n     * - Email links will have the CSS classes: \"myLink myLink-email\", and\n     * - Phone links will have the CSS classes: \"myLink myLink-phone\"\n     * - Hashtag links will have the CSS classes: \"myLink myLink-hashtag\"\n     * - Mention links will have the CSS classes: \"myLink myLink-mention myLink-[type]\"\n     *   where [type] is either \"instagram\", \"twitter\" or \"soundcloud\"\n     */\n    private readonly className: string = ''; // default value just to get the above doc comment in the ES5 output and documentation generator\n\n    /**\n     * @cfg {Function} replaceFn\n     *\n     * A function to individually process each match found in the input string.\n     *\n     * See the class's description for usage.\n     *\n     * The `replaceFn` can be called with a different context object (`this`\n     * reference) using the {@link #context} cfg.\n     *\n     * This function is called with the following parameter:\n     *\n     * @cfg {Autolinker.match.Match} replaceFn.match The Match instance which\n     *   can be used to retrieve information about the match that the `replaceFn`\n     *   is currently processing. See {@link Autolinker.match.Match} subclasses\n     *   for details.\n     */\n    private readonly replaceFn: ReplaceFn | null = null; // default value just to get the above doc comment in the ES5 output and documentation generator\n\n    /**\n     * @cfg {Object} context\n     *\n     * The context object (`this` reference) to call the `replaceFn` with.\n     *\n     * Defaults to this Autolinker instance.\n     */\n    private readonly context: object | undefined = undefined; // default value just to get the above doc comment in the ES5 output and documentation generator\n\n    /**\n     * @cfg {Boolean} [sanitizeHtml=false]\n     *\n     * `true` to HTML-encode the start and end brackets of existing HTML tags found\n     * in the input string. This will escape `<` and `>` characters to `&lt;` and\n     * `&gt;`, respectively.\n     *\n     * Setting this to `true` will prevent XSS (Cross-site Scripting) attacks,\n     * but will remove the significance of existing HTML tags in the input string. If\n     * you would like to maintain the significance of existing HTML tags while also\n     * making the output HTML string safe, leave this option as `false` and use a\n     * tool like https://github.com/cure53/DOMPurify (or others) on the input string\n     * before running Autolinker.\n     */\n    private readonly sanitizeHtml: boolean = false; // default value just to get the above doc comment in the ES5 output and documentation generator\n\n    /**\n     * @private\n     * @property {Autolinker.AnchorTagBuilder} tagBuilder\n     *\n     * The AnchorTagBuilder instance used to build match replacement anchor tags.\n     * Note: this is lazily instantiated in the {@link #getTagBuilder} method.\n     */\n    private tagBuilder: AnchorTagBuilder | null = null;\n\n    /**\n     * @method constructor\n     * @param {Object} [cfg] The configuration options for the Autolinker instance,\n     *   specified in an Object (map).\n     */\n    constructor(cfg: AutolinkerConfig = {}) {\n        // Note: when `this.something` is used in the rhs of these assignments,\n        //       it refers to the default values set above the constructor\n        this.urls = normalizeUrlsCfg(cfg.urls);\n        this.email = isBoolean(cfg.email) ? cfg.email : this.email;\n        this.phone = isBoolean(cfg.phone) ? cfg.phone : this.phone;\n        this.hashtag = cfg.hashtag || this.hashtag;\n        this.mention = cfg.mention || this.mention;\n        this.newWindow = isBoolean(cfg.newWindow) ? cfg.newWindow : this.newWindow;\n        this.stripPrefix = normalizeStripPrefixCfg(cfg.stripPrefix);\n        this.stripTrailingSlash = isBoolean(cfg.stripTrailingSlash)\n            ? cfg.stripTrailingSlash\n            : this.stripTrailingSlash;\n        this.decodePercentEncoding = isBoolean(cfg.decodePercentEncoding)\n            ? cfg.decodePercentEncoding\n            : this.decodePercentEncoding;\n        this.sanitizeHtml = cfg.sanitizeHtml || false;\n\n        // Validate the value of the `mention` cfg\n        const mention = this.mention;\n        if (mention !== false && mentionServices.indexOf(mention) === -1) {\n            throw new Error(`invalid \\`mention\\` cfg '${mention}' - see docs`);\n        }\n\n        // Validate the value of the `hashtag` cfg\n        const hashtag = this.hashtag;\n        if (hashtag !== false && hashtagServices.indexOf(hashtag) === -1) {\n            throw new Error(`invalid \\`hashtag\\` cfg '${hashtag}' - see docs`);\n        }\n\n        this.truncate = normalizeTruncateCfg(cfg.truncate);\n        this.className = cfg.className || this.className;\n        this.replaceFn = cfg.replaceFn || this.replaceFn;\n        this.context = cfg.context || this;\n    }\n\n    /**\n     * Parses the input `textOrHtml` looking for URLs, email addresses, phone\n     * numbers, username handles, and hashtags (depending on the configuration\n     * of the Autolinker instance), and returns an array of {@link Autolinker.match.Match}\n     * objects describing those matches (without making any replacements).\n     *\n     * This method is used by the {@link #link} method, but can also be used to\n     * simply do parsing of the input in order to discover what kinds of links\n     * there are and how many.\n     *\n     * Example usage:\n     *\n     *     var autolinker = new Autolinker( {\n     *         urls: true,\n     *         email: true\n     *     } );\n     *\n     *     var matches = autolinker.parse( \"Hello google.com, I am asdf@asdf.com\" );\n     *\n     *     console.log( matches.length );           // 2\n     *     console.log( matches[ 0 ].getType() );   // 'url'\n     *     console.log( matches[ 0 ].getUrl() );    // 'google.com'\n     *     console.log( matches[ 1 ].getType() );   // 'email'\n     *     console.log( matches[ 1 ].getEmail() );  // 'asdf@asdf.com'\n     *\n     * @param {String} textOrHtml The HTML or text to find matches within\n     *   (depending on if the {@link #urls}, {@link #email}, {@link #phone},\n     *   {@link #hashtag}, and {@link #mention} options are enabled).\n     * @return {Autolinker.match.Match[]} The array of Matches found in the\n     *   given input `textOrHtml`.\n     */\n    parse(textOrHtml: string) {\n        const skipTagNames = ['a', 'style', 'script'];\n        let skipTagsStackCount = 0; // used to only Autolink text outside of anchor/script/style tags. We don't want to autolink something that is already linked inside of an <a> tag, for instance\n\n        let matches: Match[] = [];\n\n        // Find all matches within the `textOrHtml` (but not matches that are\n        // already nested within <a>, <style> and <script> tags)\n        parseHtml(textOrHtml, {\n            onOpenTag: (tagName: string) => {\n                if (skipTagNames.indexOf(tagName) >= 0) {\n                    skipTagsStackCount++;\n                }\n            },\n            onText: (text: string, offset: number) => {\n                // Only process text nodes that are not within an <a>, <style> or <script> tag\n                if (skipTagsStackCount === 0) {\n                    // \"Walk around\" common HTML entities. An '&nbsp;' (for example)\n                    // could be at the end of a URL, but we don't want to\n                    // include the trailing '&' in the URL. See issue #76\n                    // TODO: Handle HTML entities separately in parseHtml() and\n                    // don't emit them as \"text\" except for &amp; entities\n                    const htmlCharacterEntitiesRegex =\n                        /(&nbsp;|&#160;|&lt;|&#60;|&gt;|&#62;|&quot;|&#34;|&#39;)/gi; // NOTE: capturing group is significant to include the split characters in the .split() call below\n                    const textSplit = text.split(htmlCharacterEntitiesRegex);\n\n                    let currentOffset = offset;\n                    textSplit.forEach((splitText, i) => {\n                        // even number matches are text, odd numbers are html entities\n                        if (i % 2 === 0) {\n                            const textNodeMatches = this.parseText(splitText, currentOffset);\n                            matches.push(...textNodeMatches);\n                        }\n                        currentOffset += splitText.length;\n                    });\n                }\n            },\n            onCloseTag: (tagName: string) => {\n                if (skipTagNames.indexOf(tagName) >= 0) {\n                    skipTagsStackCount = Math.max(skipTagsStackCount - 1, 0); // attempt to handle extraneous </a> tags by making sure the stack count never goes below 0\n                }\n            },\n            onComment: (/*_offset: number*/) => {}, // no need to process comment nodes\n            onDoctype: (/*_offset: number*/) => {}, // no need to process doctype nodes\n        });\n\n        // After we have found all matches, remove subsequent matches that\n        // overlap with a previous match. This can happen for instance with an\n        // email address where the local-part of the email is also a top-level\n        // domain, such as in \"google.com@aaa.com\". In this case, the entire\n        // email address should be linked rather than just the 'google.com'\n        // part.\n        matches = this.compactMatches(matches);\n\n        // And finally, remove matches for match types that have been turned\n        // off. We needed to have all match types turned on initially so that\n        // things like hashtags could be filtered out if they were really just\n        // part of a URL match (for instance, as a named anchor).\n        matches = this.removeUnwantedMatches(matches);\n\n        return matches;\n    }\n\n    /**\n     * After we have found all matches, we need to remove matches that overlap\n     * with a previous match. This can happen for instance with an\n     * email address where the local-part of the email is also a top-level\n     * domain, such as in \"google.com@aaa.com\". In this case, the entire email\n     * address should be linked rather than just the 'google.com' part.\n     *\n     * @private\n     * @param {Autolinker.match.Match[]} matches\n     * @return {Autolinker.match.Match[]}\n     */\n    private compactMatches(matches: Match[]) {\n        // First, the matches need to be sorted in order of offset in the input\n        // string\n        matches.sort(byMatchOffset);\n\n        let i = 0;\n        while (i < matches.length - 1) {\n            const match = matches[i];\n            const offset = match.getOffset();\n            const matchedTextLength = match.getMatchedText().length;\n\n            if (i + 1 < matches.length) {\n                // Remove subsequent matches that equal offset with current match\n                // This can happen when matching the text \"google.com@aaa.com\"\n                // where we have both a URL ('google.com') and an email. We\n                // should only keep the email match in this case.\n                if (matches[i + 1].getOffset() === offset) {\n                    // Remove the shorter match\n                    const removeIdx =\n                        matches[i + 1].getMatchedText().length > matchedTextLength ? i : i + 1;\n                    matches.splice(removeIdx, 1);\n                    continue;\n                }\n\n                // Remove subsequent matches that overlap with the current match\n                //\n                // NOTE: This was a fundamental snippet of the Autolinker.js v3\n                // algorithm where we had multiple regular expressions searching\n                // the input string for matches. The regexes would sometimes\n                // overlap such as in the case of \"google.com/#link\", where we\n                // would have both a URL match and a hashtag match.\n                //\n                // However, the Autolinker.js v4 algorithm uses a state machine\n                // parser and knows that the '#link' part of 'google.com/#link'\n                // is part of the URL that precedes it, so we don't need this\n                // piece of code any more. Keeping it here commented for now in\n                // case we need to put it back at some point, but none of the\n                // test cases are currently able to trigger the need for it.\n                // const endIdx = offset + matchedTextLength;\n                // if (matches[i + 1].getOffset() < endIdx) {\n                //     matches.splice(i + 1, 1);\n                //     continue;\n                // }\n            }\n            i++;\n        }\n\n        return matches;\n    }\n\n    /**\n     * Removes matches for matchers that were turned off in the options. For\n     * example, if {@link #hashtag hashtags} were not to be matched, we'll\n     * remove them from the `matches` array here.\n     *\n     * Note: we *must* use all Matchers on the input string, and then filter\n     * them out later. For example, if the options were `{ url: false, hashtag: true }`,\n     * we wouldn't want to match the text '#link' as a HashTag inside of the text\n     * 'google.com/#link'. The way the algorithm works is that we match the full\n     * URL first (which prevents the accidental HashTag match), and then we'll\n     * simply throw away the URL match.\n     *\n     * @private\n     * @param {Autolinker.match.Match[]} matches The array of matches to remove\n     *   the unwanted matches from. Note: this array is mutated for the\n     *   removals.\n     * @return {Autolinker.match.Match[]} The mutated input `matches` array.\n     */\n    private removeUnwantedMatches(matches: Match[]) {\n        if (!this.hashtag)\n            removeWithPredicate(matches, (match: Match) => {\n                return match.getType() === 'hashtag';\n            });\n        if (!this.email)\n            removeWithPredicate(matches, (match: Match) => {\n                return match.getType() === 'email';\n            });\n        if (!this.phone)\n            removeWithPredicate(matches, (match: Match) => {\n                return match.getType() === 'phone';\n            });\n        if (!this.mention)\n            removeWithPredicate(matches, (match: Match) => {\n                return match.getType() === 'mention';\n            });\n        if (!this.urls.schemeMatches) {\n            removeWithPredicate(\n                matches,\n                (m: Match) =>\n                    m.getType() === 'url' && (m as UrlMatch).getUrlMatchType() === 'scheme'\n            );\n        }\n        if (!this.urls.tldMatches) {\n            removeWithPredicate(\n                matches,\n                (m: Match) => m.getType() === 'url' && (m as UrlMatch).getUrlMatchType() === 'tld'\n            );\n        }\n        if (!this.urls.ipV4Matches) {\n            removeWithPredicate(\n                matches,\n                (m: Match) => m.getType() === 'url' && (m as UrlMatch).getUrlMatchType() === 'ipV4'\n            );\n        }\n\n        return matches;\n    }\n\n    /**\n     * Parses the input `text` looking for URLs, email addresses, phone\n     * numbers, username handles, and hashtags (depending on the configuration\n     * of the Autolinker instance), and returns an array of {@link Autolinker.match.Match}\n     * objects describing those matches.\n     *\n     * This method processes a **non-HTML string**, and is used to parse and\n     * match within the text nodes of an HTML string. This method is used\n     * internally by {@link #parse}.\n     *\n     * @private\n     * @param {String} text The text to find matches within (depending on if the\n     *   {@link #urls}, {@link #email}, {@link #phone},\n     *   {@link #hashtag}, and {@link #mention} options are enabled). This must be a non-HTML string.\n     * @param {Number} [offset=0] The offset of the text node within the\n     *   original string. This is used when parsing with the {@link #parse}\n     *   method to generate correct offsets within the {@link Autolinker.match.Match}\n     *   instances, but may be omitted if calling this method publicly.\n     * @return {Autolinker.match.Match[]} The array of Matches found in the\n     *   given input `text`.\n     */\n    private parseText(text: string, offset: number) {\n        offset = offset || 0;\n        const matches: Match[] = parseMatches(text, {\n            tagBuilder: this.getTagBuilder(),\n            stripPrefix: this.stripPrefix,\n            stripTrailingSlash: this.stripTrailingSlash,\n            decodePercentEncoding: this.decodePercentEncoding,\n            hashtagServiceName: this.hashtag as HashtagService,\n            mentionServiceName: (this.mention as MentionService) || 'twitter',\n        });\n\n        // Correct the offset of each of the matches. They are originally\n        // the offset of the match within the provided text node, but we\n        // need to correct them to be relative to the original HTML input\n        // string (i.e. the one provided to #parse).\n        for (let i = 0, numTextMatches = matches.length; i < numTextMatches; i++) {\n            matches[i].setOffset(offset + matches[i].getOffset());\n        }\n\n        return matches;\n    }\n\n    /**\n     * Automatically links URLs, Email addresses, Phone numbers, Hashtags,\n     * and Mentions (Twitter, Instagram, Soundcloud) found in the given chunk of HTML. Does not link\n     * URLs found within HTML tags.\n     *\n     * For instance, if given the text: `You should go to http://www.yahoo.com`,\n     * then the result will be `You should go to\n     * &lt;a href=\"http://www.yahoo.com\"&gt;http://www.yahoo.com&lt;/a&gt;`\n     *\n     * This method finds the text around any HTML elements in the input\n     * `textOrHtml`, which will be the text that is processed. Any original HTML\n     * elements will be left as-is, as well as the text that is already wrapped\n     * in anchor (&lt;a&gt;) tags.\n     *\n     * @param {String} textOrHtml The HTML or text to autolink matches within\n     *   (depending on if the {@link #urls}, {@link #email}, {@link #phone}, {@link #hashtag}, and {@link #mention} options are enabled).\n     * @return {String} The HTML, with matches automatically linked.\n     */\n    link(textOrHtml: string) {\n        if (!textOrHtml) {\n            return '';\n        } // handle `null` and `undefined` (for JavaScript users that don't have TypeScript support), and nothing to do with an empty string too\n\n        /* We would want to sanitize the start and end characters of a tag\n         * before processing the string in order to avoid an XSS scenario.\n         * This behaviour can be changed by toggling the sanitizeHtml option.\n         */\n        if (this.sanitizeHtml) {\n            textOrHtml = textOrHtml.replace(/</g, '&lt;').replace(/>/g, '&gt;');\n        }\n\n        const matches = this.parse(textOrHtml);\n        const newHtml = new Array<string>(matches.length * 2 + 1);\n        let lastIndex = 0;\n\n        for (let i = 0, len = matches.length; i < len; i++) {\n            const match = matches[i];\n\n            newHtml.push(textOrHtml.substring(lastIndex, match.getOffset()));\n            newHtml.push(this.createMatchReturnVal(match));\n\n            lastIndex = match.getOffset() + match.getMatchedText().length;\n        }\n        newHtml.push(textOrHtml.substring(lastIndex)); // handle the text after the last match\n\n        return newHtml.join('');\n    }\n\n    /**\n     * Creates the return string value for a given match in the input string.\n     *\n     * This method handles the {@link #replaceFn}, if one was provided.\n     *\n     * @private\n     * @param {Autolinker.match.Match} match The Match object that represents\n     *   the match.\n     * @return {String} The string that the `match` should be replaced with.\n     *   This is usually the anchor tag string, but may be the `matchStr` itself\n     *   if the match is not to be replaced.\n     */\n    private createMatchReturnVal(match: Match): string {\n        // Handle a custom `replaceFn` being provided\n        let replaceFnResult: ReplaceFnReturn;\n        if (this.replaceFn) {\n            replaceFnResult = this.replaceFn.call(this.context, match); // Autolinker instance is the context\n        }\n\n        if (typeof replaceFnResult === 'string') {\n            return replaceFnResult; // `replaceFn` returned a string, use that\n        } else if (replaceFnResult === false) {\n            return match.getMatchedText(); // no replacement for the match\n        } else if (replaceFnResult instanceof HtmlTag) {\n            return replaceFnResult.toAnchorString();\n        } else {\n            // replaceFnResult === true, or no/unknown return value from function\n            // Perform Autolinker's default anchor tag generation\n            const anchorTag = match.buildTag(); // returns an Autolinker.HtmlTag instance\n\n            return anchorTag.toAnchorString();\n        }\n    }\n\n    /**\n     * Returns the {@link #tagBuilder} instance for this Autolinker instance,\n     * lazily instantiating it if it does not yet exist.\n     *\n     * @private\n     * @return {Autolinker.AnchorTagBuilder}\n     */\n    private getTagBuilder() {\n        let tagBuilder = this.tagBuilder;\n\n        if (!tagBuilder) {\n            tagBuilder = this.tagBuilder = new AnchorTagBuilder({\n                newWindow: this.newWindow,\n                truncate: this.truncate,\n                className: this.className,\n            });\n        }\n\n        return tagBuilder;\n    }\n}\n\n/**\n * Normalizes the {@link #urls} config into an Object with its 2 properties:\n * `schemeMatches` and `tldMatches`, both booleans.\n *\n * See {@link #urls} config for details.\n *\n * @private\n * @param {Boolean/Object} urls\n * @return {Object}\n */\nfunction normalizeUrlsCfg(urls: UrlsConfig | undefined): Required<UrlsConfigObj> {\n    if (urls == null) urls = true; // default to `true`\n\n    if (isBoolean(urls)) {\n        return { schemeMatches: urls, tldMatches: urls, ipV4Matches: urls };\n    } else {\n        // object form\n        return {\n            schemeMatches: isBoolean(urls.schemeMatches) ? urls.schemeMatches : true,\n            tldMatches: isBoolean(urls.tldMatches) ? urls.tldMatches : true,\n            ipV4Matches: isBoolean(urls.ipV4Matches) ? urls.ipV4Matches : true,\n        };\n    }\n}\n\n/**\n * Normalizes the {@link #stripPrefix} config into an Object with 2\n * properties: `scheme`, and `www` - both Booleans.\n *\n * See {@link #stripPrefix} config for details.\n *\n * @private\n * @param {Boolean/Object} stripPrefix\n * @return {Object}\n */\nfunction normalizeStripPrefixCfg(\n    stripPrefix: StripPrefixConfig | undefined\n): Required<StripPrefixConfigObj> {\n    if (stripPrefix == null) stripPrefix = true; // default to `true`\n\n    if (isBoolean(stripPrefix)) {\n        return { scheme: stripPrefix, www: stripPrefix };\n    } else {\n        // object form\n        return {\n            scheme: isBoolean(stripPrefix.scheme) ? stripPrefix.scheme : true,\n            www: isBoolean(stripPrefix.www) ? stripPrefix.www : true,\n        };\n    }\n}\n\n/**\n * Normalizes the {@link #truncate} config into an Object with 2 properties:\n * `length` (Number), and `location` (String).\n *\n * See {@link #truncate} config for details.\n *\n * @private\n * @param {Number/Object} truncate\n * @return {Object}\n */\nfunction normalizeTruncateCfg(truncate: TruncateConfig | undefined): Required<TruncateConfigObj> {\n    if (typeof truncate === 'number') {\n        return { length: truncate, location: 'end' };\n    } else {\n        // object, or undefined/null\n        return {\n            length: Number.POSITIVE_INFINITY,\n            location: 'end',\n            ...truncate,\n        };\n    }\n}\n\n/**\n * Helper function for Array.prototype.sort() to sort the Matches by\n * their offset in the input string.\n */\nfunction byMatchOffset(a: Match, b: Match) {\n    return a.getOffset() - b.getOffset();\n}\n\nexport interface AutolinkerConfig {\n    urls?: UrlsConfig;\n    email?: boolean;\n    phone?: boolean;\n    hashtag?: HashtagConfig;\n    mention?: MentionConfig;\n    newWindow?: boolean;\n    stripPrefix?: StripPrefixConfig;\n    stripTrailingSlash?: boolean;\n    truncate?: TruncateConfig;\n    className?: string;\n    replaceFn?: ReplaceFn | null;\n    context?: object;\n    sanitizeHtml?: boolean;\n    decodePercentEncoding?: boolean;\n}\n\nexport type UrlsConfig = boolean | UrlsConfigObj;\nexport interface UrlsConfigObj {\n    schemeMatches?: boolean;\n    tldMatches?: boolean;\n    ipV4Matches?: boolean;\n}\n\nexport type StripPrefixConfig = boolean | StripPrefixConfigObj;\nexport interface StripPrefixConfigObj {\n    scheme?: boolean;\n    www?: boolean;\n}\n\nexport type TruncateConfig = number | TruncateConfigObj;\nexport interface TruncateConfigObj {\n    length?: number;\n    location?: 'end' | 'middle' | 'smart';\n}\n\nexport type HashtagConfig = false | HashtagService;\nexport type MentionConfig = false | MentionService;\n\nexport type ReplaceFn = (match: Match) => ReplaceFnReturn;\nexport type ReplaceFnReturn = boolean | string | HtmlTag | null | undefined | void;\n"]}