spamscanner 7.0.10 → 7.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/arf.cjs.map +1 -1
- package/dist/cjs/index.cjs +1326 -177
- package/dist/cjs/index.cjs.map +4 -4
- package/dist/esm/arf.js.map +1 -1
- package/dist/esm/cli.js +1255 -122
- package/dist/esm/cli.js.map +4 -4
- package/dist/esm/index.js +1295 -162
- package/dist/esm/index.js.map +4 -4
- package/dist/types/attachments.d.ts +1 -0
- package/dist/types/entities.d.ts +2 -0
- package/dist/types/html.d.ts +2 -2
- package/dist/types/index.d.ts +26 -6
- package/dist/types/links.d.ts +24 -0
- package/dist/types/parse.d.ts +1 -1
- package/package.json +1 -1
package/dist/cjs/index.cjs
CHANGED
|
@@ -1624,6 +1624,286 @@ var init_homograph = __esm({
|
|
|
1624
1624
|
}
|
|
1625
1625
|
});
|
|
1626
1626
|
|
|
1627
|
+
// src/entities.js
|
|
1628
|
+
var NAMED, NAMED_REFERENCES;
|
|
1629
|
+
var init_entities = __esm({
|
|
1630
|
+
"src/entities.js"() {
|
|
1631
|
+
NAMED = [
|
|
1632
|
+
"AElig=c6,AMP=26,Aacute=c1,Abreve=102,Acirc=c2,Acy=410,Afr=1d504,Agrave=c0,Alpha=391,Amacr=100,And=2a",
|
|
1633
|
+
"53,Aogon=104,Aopf=1d538,ApplyFunction=2061,Aring=c5,Ascr=1d49c,Assign=2254,Atilde=c3,Auml=c4,Backsla",
|
|
1634
|
+
"sh=2216,Barv=2ae7,Barwed=2306,Bcy=411,Because=2235,Bernoullis=212c,Beta=392,Bfr=1d505,Bopf=1d539,Bre",
|
|
1635
|
+
"ve=2d8,Bscr=212c,Bumpeq=224e,CHcy=427,COPY=a9,Cacute=106,Cap=22d2,CapitalDifferentialD=2145,Cayleys=",
|
|
1636
|
+
"212d,Ccaron=10c,Ccedil=c7,Ccirc=108,Cconint=2230,Cdot=10a,Cedilla=b8,CenterDot=b7,Cfr=212d,Chi=3a7,C",
|
|
1637
|
+
"ircleDot=2299,CircleMinus=2296,CirclePlus=2295,CircleTimes=2297,ClockwiseContourIntegral=2232,CloseC",
|
|
1638
|
+
"urlyDoubleQuote=201d,CloseCurlyQuote=2019,Colon=2237,Colone=2a74,Congruent=2261,Conint=222f,ContourI",
|
|
1639
|
+
"ntegral=222e,Copf=2102,Coproduct=2210,CounterClockwiseContourIntegral=2233,Cross=2a2f,Cscr=1d49e,Cup",
|
|
1640
|
+
"=22d3,CupCap=224d,DD=2145,DDotrahd=2911,DJcy=402,DScy=405,DZcy=40f,Dagger=2021,Darr=21a1,Dashv=2ae4,",
|
|
1641
|
+
"Dcaron=10e,Dcy=414,Del=2207,Delta=394,Dfr=1d507,DiacriticalAcute=b4,DiacriticalDot=2d9,DiacriticalDo",
|
|
1642
|
+
"ubleAcute=2dd,DiacriticalGrave=60,DiacriticalTilde=2dc,Diamond=22c4,DifferentialD=2146,Dopf=1d53b,Do",
|
|
1643
|
+
"t=a8,DotDot=20dc,DotEqual=2250,DoubleContourIntegral=222f,DoubleDot=a8,DoubleDownArrow=21d3,DoubleLe",
|
|
1644
|
+
"ftArrow=21d0,DoubleLeftRightArrow=21d4,DoubleLeftTee=2ae4,DoubleLongLeftArrow=27f8,DoubleLongLeftRig",
|
|
1645
|
+
"htArrow=27fa,DoubleLongRightArrow=27f9,DoubleRightArrow=21d2,DoubleRightTee=22a8,DoubleUpArrow=21d1,",
|
|
1646
|
+
"DoubleUpDownArrow=21d5,DoubleVerticalBar=2225,DownArrow=2193,DownArrowBar=2913,DownArrowUpArrow=21f5",
|
|
1647
|
+
",DownBreve=311,DownLeftRightVector=2950,DownLeftTeeVector=295e,DownLeftVector=21bd,DownLeftVectorBar",
|
|
1648
|
+
"=2956,DownRightTeeVector=295f,DownRightVector=21c1,DownRightVectorBar=2957,DownTee=22a4,DownTeeArrow",
|
|
1649
|
+
"=21a7,Downarrow=21d3,Dscr=1d49f,Dstrok=110,ENG=14a,ETH=d0,Eacute=c9,Ecaron=11a,Ecirc=ca,Ecy=42d,Edot",
|
|
1650
|
+
"=116,Efr=1d508,Egrave=c8,Element=2208,Emacr=112,EmptySmallSquare=25fb,EmptyVerySmallSquare=25ab,Eogo",
|
|
1651
|
+
"n=118,Eopf=1d53c,Epsilon=395,Equal=2a75,EqualTilde=2242,Equilibrium=21cc,Escr=2130,Esim=2a73,Eta=397",
|
|
1652
|
+
",Euml=cb,Exists=2203,ExponentialE=2147,Fcy=424,Ffr=1d509,FilledSmallSquare=25fc,FilledVerySmallSquar",
|
|
1653
|
+
"e=25aa,Fopf=1d53d,ForAll=2200,Fouriertrf=2131,Fscr=2131,GJcy=403,GT=3e,Gamma=393,Gammad=3dc,Gbreve=1",
|
|
1654
|
+
"1e,Gcedil=122,Gcirc=11c,Gcy=413,Gdot=120,Gfr=1d50a,Gg=22d9,Gopf=1d53e,GreaterEqual=2265,GreaterEqual",
|
|
1655
|
+
"Less=22db,GreaterFullEqual=2267,GreaterGreater=2aa2,GreaterLess=2277,GreaterSlantEqual=2a7e,GreaterT",
|
|
1656
|
+
"ilde=2273,Gscr=1d4a2,Gt=226b,HARDcy=42a,Hacek=2c7,Hat=5e,Hcirc=124,Hfr=210c,HilbertSpace=210b,Hopf=2",
|
|
1657
|
+
"10d,HorizontalLine=2500,Hscr=210b,Hstrok=126,HumpDownHump=224e,HumpEqual=224f,IEcy=415,IJlig=132,IOc",
|
|
1658
|
+
"y=401,Iacute=cd,Icirc=ce,Icy=418,Idot=130,Ifr=2111,Igrave=cc,Im=2111,Imacr=12a,ImaginaryI=2148,Impli",
|
|
1659
|
+
"es=21d2,Int=222c,Integral=222b,Intersection=22c2,InvisibleComma=2063,InvisibleTimes=2062,Iogon=12e,I",
|
|
1660
|
+
"opf=1d540,Iota=399,Iscr=2110,Itilde=128,Iukcy=406,Iuml=cf,Jcirc=134,Jcy=419,Jfr=1d50d,Jopf=1d541,Jsc",
|
|
1661
|
+
"r=1d4a5,Jsercy=408,Jukcy=404,KHcy=425,KJcy=40c,Kappa=39a,Kcedil=136,Kcy=41a,Kfr=1d50e,Kopf=1d542,Ksc",
|
|
1662
|
+
"r=1d4a6,LJcy=409,LT=3c,Lacute=139,Lambda=39b,Lang=27ea,Laplacetrf=2112,Larr=219e,Lcaron=13d,Lcedil=1",
|
|
1663
|
+
"3b,Lcy=41b,LeftAngleBracket=27e8,LeftArrow=2190,LeftArrowBar=21e4,LeftArrowRightArrow=21c6,LeftCeili",
|
|
1664
|
+
"ng=2308,LeftDoubleBracket=27e6,LeftDownTeeVector=2961,LeftDownVector=21c3,LeftDownVectorBar=2959,Lef",
|
|
1665
|
+
"tFloor=230a,LeftRightArrow=2194,LeftRightVector=294e,LeftTee=22a3,LeftTeeArrow=21a4,LeftTeeVector=29",
|
|
1666
|
+
"5a,LeftTriangle=22b2,LeftTriangleBar=29cf,LeftTriangleEqual=22b4,LeftUpDownVector=2951,LeftUpTeeVect",
|
|
1667
|
+
"or=2960,LeftUpVector=21bf,LeftUpVectorBar=2958,LeftVector=21bc,LeftVectorBar=2952,Leftarrow=21d0,Lef",
|
|
1668
|
+
"trightarrow=21d4,LessEqualGreater=22da,LessFullEqual=2266,LessGreater=2276,LessLess=2aa1,LessSlantEq",
|
|
1669
|
+
"ual=2a7d,LessTilde=2272,Lfr=1d50f,Ll=22d8,Lleftarrow=21da,Lmidot=13f,LongLeftArrow=27f5,LongLeftRigh",
|
|
1670
|
+
"tArrow=27f7,LongRightArrow=27f6,Longleftarrow=27f8,Longleftrightarrow=27fa,Longrightarrow=27f9,Lopf=",
|
|
1671
|
+
"1d543,LowerLeftArrow=2199,LowerRightArrow=2198,Lscr=2112,Lsh=21b0,Lstrok=141,Lt=226a,Map=2905,Mcy=41",
|
|
1672
|
+
"c,MediumSpace=205f,Mellintrf=2133,Mfr=1d510,MinusPlus=2213,Mopf=1d544,Mscr=2133,Mu=39c,NJcy=40a,Nacu",
|
|
1673
|
+
"te=143,Ncaron=147,Ncedil=145,Ncy=41d,NegativeMediumSpace=200b,NegativeThickSpace=200b,NegativeThinSp",
|
|
1674
|
+
"ace=200b,NegativeVeryThinSpace=200b,NestedGreaterGreater=226b,NestedLessLess=226a,NewLine=a,Nfr=1d51",
|
|
1675
|
+
"1,NoBreak=2060,NonBreakingSpace=a0,Nopf=2115,Not=2aec,NotCongruent=2262,NotCupCap=226d,NotDoubleVert",
|
|
1676
|
+
"icalBar=2226,NotElement=2209,NotEqual=2260,NotEqualTilde=2242.338,NotExists=2204,NotGreater=226f,Not",
|
|
1677
|
+
"GreaterEqual=2271,NotGreaterFullEqual=2267.338,NotGreaterGreater=226b.338,NotGreaterLess=2279,NotGre",
|
|
1678
|
+
"aterSlantEqual=2a7e.338,NotGreaterTilde=2275,NotHumpDownHump=224e.338,NotHumpEqual=224f.338,NotLeftT",
|
|
1679
|
+
"riangle=22ea,NotLeftTriangleBar=29cf.338,NotLeftTriangleEqual=22ec,NotLess=226e,NotLessEqual=2270,No",
|
|
1680
|
+
"tLessGreater=2278,NotLessLess=226a.338,NotLessSlantEqual=2a7d.338,NotLessTilde=2274,NotNestedGreater",
|
|
1681
|
+
"Greater=2aa2.338,NotNestedLessLess=2aa1.338,NotPrecedes=2280,NotPrecedesEqual=2aaf.338,NotPrecedesSl",
|
|
1682
|
+
"antEqual=22e0,NotReverseElement=220c,NotRightTriangle=22eb,NotRightTriangleBar=29d0.338,NotRightTria",
|
|
1683
|
+
"ngleEqual=22ed,NotSquareSubset=228f.338,NotSquareSubsetEqual=22e2,NotSquareSuperset=2290.338,NotSqua",
|
|
1684
|
+
"reSupersetEqual=22e3,NotSubset=2282.20d2,NotSubsetEqual=2288,NotSucceeds=2281,NotSucceedsEqual=2ab0.",
|
|
1685
|
+
"338,NotSucceedsSlantEqual=22e1,NotSucceedsTilde=227f.338,NotSuperset=2283.20d2,NotSupersetEqual=2289",
|
|
1686
|
+
",NotTilde=2241,NotTildeEqual=2244,NotTildeFullEqual=2247,NotTildeTilde=2249,NotVerticalBar=2224,Nscr",
|
|
1687
|
+
"=1d4a9,Ntilde=d1,Nu=39d,OElig=152,Oacute=d3,Ocirc=d4,Ocy=41e,Odblac=150,Ofr=1d512,Ograve=d2,Omacr=14",
|
|
1688
|
+
"c,Omega=3a9,Omicron=39f,Oopf=1d546,OpenCurlyDoubleQuote=201c,OpenCurlyQuote=2018,Or=2a54,Oscr=1d4aa,",
|
|
1689
|
+
"Oslash=d8,Otilde=d5,Otimes=2a37,Ouml=d6,OverBar=203e,OverBrace=23de,OverBracket=23b4,OverParenthesis",
|
|
1690
|
+
"=23dc,PartialD=2202,Pcy=41f,Pfr=1d513,Phi=3a6,Pi=3a0,PlusMinus=b1,Poincareplane=210c,Popf=2119,Pr=2a",
|
|
1691
|
+
"bb,Precedes=227a,PrecedesEqual=2aaf,PrecedesSlantEqual=227c,PrecedesTilde=227e,Prime=2033,Product=22",
|
|
1692
|
+
"0f,Proportion=2237,Proportional=221d,Pscr=1d4ab,Psi=3a8,QUOT=22,Qfr=1d514,Qopf=211a,Qscr=1d4ac,RBarr",
|
|
1693
|
+
"=2910,REG=ae,Racute=154,Rang=27eb,Rarr=21a0,Rarrtl=2916,Rcaron=158,Rcedil=156,Rcy=420,Re=211c,Revers",
|
|
1694
|
+
"eElement=220b,ReverseEquilibrium=21cb,ReverseUpEquilibrium=296f,Rfr=211c,Rho=3a1,RightAngleBracket=2",
|
|
1695
|
+
"7e9,RightArrow=2192,RightArrowBar=21e5,RightArrowLeftArrow=21c4,RightCeiling=2309,RightDoubleBracket",
|
|
1696
|
+
"=27e7,RightDownTeeVector=295d,RightDownVector=21c2,RightDownVectorBar=2955,RightFloor=230b,RightTee=",
|
|
1697
|
+
"22a2,RightTeeArrow=21a6,RightTeeVector=295b,RightTriangle=22b3,RightTriangleBar=29d0,RightTriangleEq",
|
|
1698
|
+
"ual=22b5,RightUpDownVector=294f,RightUpTeeVector=295c,RightUpVector=21be,RightUpVectorBar=2954,Right",
|
|
1699
|
+
"Vector=21c0,RightVectorBar=2953,Rightarrow=21d2,Ropf=211d,RoundImplies=2970,Rrightarrow=21db,Rscr=21",
|
|
1700
|
+
"1b,Rsh=21b1,RuleDelayed=29f4,SHCHcy=429,SHcy=428,SOFTcy=42c,Sacute=15a,Sc=2abc,Scaron=160,Scedil=15e",
|
|
1701
|
+
",Scirc=15c,Scy=421,Sfr=1d516,ShortDownArrow=2193,ShortLeftArrow=2190,ShortRightArrow=2192,ShortUpArr",
|
|
1702
|
+
"ow=2191,Sigma=3a3,SmallCircle=2218,Sopf=1d54a,Sqrt=221a,Square=25a1,SquareIntersection=2293,SquareSu",
|
|
1703
|
+
"bset=228f,SquareSubsetEqual=2291,SquareSuperset=2290,SquareSupersetEqual=2292,SquareUnion=2294,Sscr=",
|
|
1704
|
+
"1d4ae,Star=22c6,Sub=22d0,Subset=22d0,SubsetEqual=2286,Succeeds=227b,SucceedsEqual=2ab0,SucceedsSlant",
|
|
1705
|
+
"Equal=227d,SucceedsTilde=227f,SuchThat=220b,Sum=2211,Sup=22d1,Superset=2283,SupersetEqual=2287,Supse",
|
|
1706
|
+
"t=22d1,THORN=de,TRADE=2122,TSHcy=40b,TScy=426,Tab=9,Tau=3a4,Tcaron=164,Tcedil=162,Tcy=422,Tfr=1d517,",
|
|
1707
|
+
"Therefore=2234,Theta=398,ThickSpace=205f.200a,ThinSpace=2009,Tilde=223c,TildeEqual=2243,TildeFullEqu",
|
|
1708
|
+
"al=2245,TildeTilde=2248,Topf=1d54b,TripleDot=20db,Tscr=1d4af,Tstrok=166,Uacute=da,Uarr=219f,Uarrocir",
|
|
1709
|
+
"=2949,Ubrcy=40e,Ubreve=16c,Ucirc=db,Ucy=423,Udblac=170,Ufr=1d518,Ugrave=d9,Umacr=16a,UnderBar=5f,Und",
|
|
1710
|
+
"erBrace=23df,UnderBracket=23b5,UnderParenthesis=23dd,Union=22c3,UnionPlus=228e,Uogon=172,Uopf=1d54c,",
|
|
1711
|
+
"UpArrow=2191,UpArrowBar=2912,UpArrowDownArrow=21c5,UpDownArrow=2195,UpEquilibrium=296e,UpTee=22a5,Up",
|
|
1712
|
+
"TeeArrow=21a5,Uparrow=21d1,Updownarrow=21d5,UpperLeftArrow=2196,UpperRightArrow=2197,Upsi=3d2,Upsilo",
|
|
1713
|
+
"n=3a5,Uring=16e,Uscr=1d4b0,Utilde=168,Uuml=dc,VDash=22ab,Vbar=2aeb,Vcy=412,Vdash=22a9,Vdashl=2ae6,Ve",
|
|
1714
|
+
"e=22c1,Verbar=2016,Vert=2016,VerticalBar=2223,VerticalLine=7c,VerticalSeparator=2758,VerticalTilde=2",
|
|
1715
|
+
"240,VeryThinSpace=200a,Vfr=1d519,Vopf=1d54d,Vscr=1d4b1,Vvdash=22aa,Wcirc=174,Wedge=22c0,Wfr=1d51a,Wo",
|
|
1716
|
+
"pf=1d54e,Wscr=1d4b2,Xfr=1d51b,Xi=39e,Xopf=1d54f,Xscr=1d4b3,YAcy=42f,YIcy=407,YUcy=42e,Yacute=dd,Ycir",
|
|
1717
|
+
"c=176,Ycy=42b,Yfr=1d51c,Yopf=1d550,Yscr=1d4b4,Yuml=178,ZHcy=416,Zacute=179,Zcaron=17d,Zcy=417,Zdot=1",
|
|
1718
|
+
"7b,ZeroWidthSpace=200b,Zeta=396,Zfr=2128,Zopf=2124,Zscr=1d4b5,aacute=e1,abreve=103,ac=223e,acE=223e.",
|
|
1719
|
+
"333,acd=223f,acirc=e2,acute=b4,acy=430,aelig=e6,af=2061,afr=1d51e,agrave=e0,alefsym=2135,aleph=2135,",
|
|
1720
|
+
"alpha=3b1,amacr=101,amalg=2a3f,amp=26,and=2227,andand=2a55,andd=2a5c,andslope=2a58,andv=2a5a,ang=222",
|
|
1721
|
+
"0,ange=29a4,angle=2220,angmsd=2221,angmsdaa=29a8,angmsdab=29a9,angmsdac=29aa,angmsdad=29ab,angmsdae=",
|
|
1722
|
+
"29ac,angmsdaf=29ad,angmsdag=29ae,angmsdah=29af,angrt=221f,angrtvb=22be,angrtvbd=299d,angsph=2222,ang",
|
|
1723
|
+
"st=c5,angzarr=237c,aogon=105,aopf=1d552,ap=2248,apE=2a70,apacir=2a6f,ape=224a,apid=224b,apos=27,appr",
|
|
1724
|
+
"ox=2248,approxeq=224a,aring=e5,ascr=1d4b6,ast=2a,asymp=2248,asympeq=224d,atilde=e3,auml=e4,awconint=",
|
|
1725
|
+
"2233,awint=2a11,bNot=2aed,backcong=224c,backepsilon=3f6,backprime=2035,backsim=223d,backsimeq=22cd,b",
|
|
1726
|
+
"arvee=22bd,barwed=2305,barwedge=2305,bbrk=23b5,bbrktbrk=23b6,bcong=224c,bcy=431,bdquo=201e,becaus=22",
|
|
1727
|
+
"35,because=2235,bemptyv=29b0,bepsi=3f6,bernou=212c,beta=3b2,beth=2136,between=226c,bfr=1d51f,bigcap=",
|
|
1728
|
+
"22c2,bigcirc=25ef,bigcup=22c3,bigodot=2a00,bigoplus=2a01,bigotimes=2a02,bigsqcup=2a06,bigstar=2605,b",
|
|
1729
|
+
"igtriangledown=25bd,bigtriangleup=25b3,biguplus=2a04,bigvee=22c1,bigwedge=22c0,bkarow=290d,blackloze",
|
|
1730
|
+
"nge=29eb,blacksquare=25aa,blacktriangle=25b4,blacktriangledown=25be,blacktriangleleft=25c2,blacktria",
|
|
1731
|
+
"ngleright=25b8,blank=2423,blk12=2592,blk14=2591,blk34=2593,block=2588,bne=3d.20e5,bnequiv=2261.20e5,",
|
|
1732
|
+
"bnot=2310,bopf=1d553,bot=22a5,bottom=22a5,bowtie=22c8,boxDL=2557,boxDR=2554,boxDl=2556,boxDr=2553,bo",
|
|
1733
|
+
"xH=2550,boxHD=2566,boxHU=2569,boxHd=2564,boxHu=2567,boxUL=255d,boxUR=255a,boxUl=255c,boxUr=2559,boxV",
|
|
1734
|
+
"=2551,boxVH=256c,boxVL=2563,boxVR=2560,boxVh=256b,boxVl=2562,boxVr=255f,boxbox=29c9,boxdL=2555,boxdR",
|
|
1735
|
+
"=2552,boxdl=2510,boxdr=250c,boxh=2500,boxhD=2565,boxhU=2568,boxhd=252c,boxhu=2534,boxminus=229f,boxp",
|
|
1736
|
+
"lus=229e,boxtimes=22a0,boxuL=255b,boxuR=2558,boxul=2518,boxur=2514,boxv=2502,boxvH=256a,boxvL=2561,b",
|
|
1737
|
+
"oxvR=255e,boxvh=253c,boxvl=2524,boxvr=251c,bprime=2035,breve=2d8,brvbar=a6,bscr=1d4b7,bsemi=204f,bsi",
|
|
1738
|
+
"m=223d,bsime=22cd,bsol=5c,bsolb=29c5,bsolhsub=27c8,bull=2022,bullet=2022,bump=224e,bumpE=2aae,bumpe=",
|
|
1739
|
+
"224f,bumpeq=224f,cacute=107,cap=2229,capand=2a44,capbrcup=2a49,capcap=2a4b,capcup=2a47,capdot=2a40,c",
|
|
1740
|
+
"aps=2229.fe00,caret=2041,caron=2c7,ccaps=2a4d,ccaron=10d,ccedil=e7,ccirc=109,ccups=2a4c,ccupssm=2a50",
|
|
1741
|
+
",cdot=10b,cedil=b8,cemptyv=29b2,cent=a2,centerdot=b7,cfr=1d520,chcy=447,check=2713,checkmark=2713,ch",
|
|
1742
|
+
"i=3c7,cir=25cb,cirE=29c3,circ=2c6,circeq=2257,circlearrowleft=21ba,circlearrowright=21bb,circledR=ae",
|
|
1743
|
+
",circledS=24c8,circledast=229b,circledcirc=229a,circleddash=229d,cire=2257,cirfnint=2a10,cirmid=2aef",
|
|
1744
|
+
",cirscir=29c2,clubs=2663,clubsuit=2663,colon=3a,colone=2254,coloneq=2254,comma=2c,commat=40,comp=220",
|
|
1745
|
+
"1,compfn=2218,complement=2201,complexes=2102,cong=2245,congdot=2a6d,conint=222e,copf=1d554,coprod=22",
|
|
1746
|
+
"10,copy=a9,copysr=2117,crarr=21b5,cross=2717,cscr=1d4b8,csub=2acf,csube=2ad1,csup=2ad0,csupe=2ad2,ct",
|
|
1747
|
+
"dot=22ef,cudarrl=2938,cudarrr=2935,cuepr=22de,cuesc=22df,cularr=21b6,cularrp=293d,cup=222a,cupbrcap=",
|
|
1748
|
+
"2a48,cupcap=2a46,cupcup=2a4a,cupdot=228d,cupor=2a45,cups=222a.fe00,curarr=21b7,curarrm=293c,curlyeqp",
|
|
1749
|
+
"rec=22de,curlyeqsucc=22df,curlyvee=22ce,curlywedge=22cf,curren=a4,curvearrowleft=21b6,curvearrowrigh",
|
|
1750
|
+
"t=21b7,cuvee=22ce,cuwed=22cf,cwconint=2232,cwint=2231,cylcty=232d,dArr=21d3,dHar=2965,dagger=2020,da",
|
|
1751
|
+
"leth=2138,darr=2193,dash=2010,dashv=22a3,dbkarow=290f,dblac=2dd,dcaron=10f,dcy=434,dd=2146,ddagger=2",
|
|
1752
|
+
"021,ddarr=21ca,ddotseq=2a77,deg=b0,delta=3b4,demptyv=29b1,dfisht=297f,dfr=1d521,dharl=21c3,dharr=21c",
|
|
1753
|
+
"2,diam=22c4,diamond=22c4,diamondsuit=2666,diams=2666,die=a8,digamma=3dd,disin=22f2,div=f7,divide=f7,",
|
|
1754
|
+
"divideontimes=22c7,divonx=22c7,djcy=452,dlcorn=231e,dlcrop=230d,dollar=24,dopf=1d555,dot=2d9,doteq=2",
|
|
1755
|
+
"250,doteqdot=2251,dotminus=2238,dotplus=2214,dotsquare=22a1,doublebarwedge=2306,downarrow=2193,downd",
|
|
1756
|
+
"ownarrows=21ca,downharpoonleft=21c3,downharpoonright=21c2,drbkarow=2910,drcorn=231f,drcrop=230c,dscr",
|
|
1757
|
+
"=1d4b9,dscy=455,dsol=29f6,dstrok=111,dtdot=22f1,dtri=25bf,dtrif=25be,duarr=21f5,duhar=296f,dwangle=2",
|
|
1758
|
+
"9a6,dzcy=45f,dzigrarr=27ff,eDDot=2a77,eDot=2251,eacute=e9,easter=2a6e,ecaron=11b,ecir=2256,ecirc=ea,",
|
|
1759
|
+
"ecolon=2255,ecy=44d,edot=117,ee=2147,efDot=2252,efr=1d522,eg=2a9a,egrave=e8,egs=2a96,egsdot=2a98,el=",
|
|
1760
|
+
"2a99,elinters=23e7,ell=2113,els=2a95,elsdot=2a97,emacr=113,empty=2205,emptyset=2205,emptyv=2205,emsp",
|
|
1761
|
+
"=2003,emsp13=2004,emsp14=2005,eng=14b,ensp=2002,eogon=119,eopf=1d556,epar=22d5,eparsl=29e3,eplus=2a7",
|
|
1762
|
+
"1,epsi=3b5,epsilon=3b5,epsiv=3f5,eqcirc=2256,eqcolon=2255,eqsim=2242,eqslantgtr=2a96,eqslantless=2a9",
|
|
1763
|
+
"5,equals=3d,equest=225f,equiv=2261,equivDD=2a78,eqvparsl=29e5,erDot=2253,erarr=2971,escr=212f,esdot=",
|
|
1764
|
+
"2250,esim=2242,eta=3b7,eth=f0,euml=eb,euro=20ac,excl=21,exist=2203,expectation=2130,exponentiale=214",
|
|
1765
|
+
"7,fallingdotseq=2252,fcy=444,female=2640,ffilig=fb03,fflig=fb00,ffllig=fb04,ffr=1d523,filig=fb01,fjl",
|
|
1766
|
+
"ig=66.6a,flat=266d,fllig=fb02,fltns=25b1,fnof=192,fopf=1d557,forall=2200,fork=22d4,forkv=2ad9,fparti",
|
|
1767
|
+
"nt=2a0d,frac12=bd,frac13=2153,frac14=bc,frac15=2155,frac16=2159,frac18=215b,frac23=2154,frac25=2156,",
|
|
1768
|
+
"frac34=be,frac35=2157,frac38=215c,frac45=2158,frac56=215a,frac58=215d,frac78=215e,frasl=2044,frown=2",
|
|
1769
|
+
"322,fscr=1d4bb,gE=2267,gEl=2a8c,gacute=1f5,gamma=3b3,gammad=3dd,gap=2a86,gbreve=11f,gcirc=11d,gcy=43",
|
|
1770
|
+
"3,gdot=121,ge=2265,gel=22db,geq=2265,geqq=2267,geqslant=2a7e,ges=2a7e,gescc=2aa9,gesdot=2a80,gesdoto",
|
|
1771
|
+
"=2a82,gesdotol=2a84,gesl=22db.fe00,gesles=2a94,gfr=1d524,gg=226b,ggg=22d9,gimel=2137,gjcy=453,gl=227",
|
|
1772
|
+
"7,glE=2a92,gla=2aa5,glj=2aa4,gnE=2269,gnap=2a8a,gnapprox=2a8a,gne=2a88,gneq=2a88,gneqq=2269,gnsim=22",
|
|
1773
|
+
"e7,gopf=1d558,grave=60,gscr=210a,gsim=2273,gsime=2a8e,gsiml=2a90,gt=3e,gtcc=2aa7,gtcir=2a7a,gtdot=22",
|
|
1774
|
+
"d7,gtlPar=2995,gtquest=2a7c,gtrapprox=2a86,gtrarr=2978,gtrdot=22d7,gtreqless=22db,gtreqqless=2a8c,gt",
|
|
1775
|
+
"rless=2277,gtrsim=2273,gvertneqq=2269.fe00,gvnE=2269.fe00,hArr=21d4,hairsp=200a,half=bd,hamilt=210b,",
|
|
1776
|
+
"hardcy=44a,harr=2194,harrcir=2948,harrw=21ad,hbar=210f,hcirc=125,hearts=2665,heartsuit=2665,hellip=2",
|
|
1777
|
+
"026,hercon=22b9,hfr=1d525,hksearow=2925,hkswarow=2926,hoarr=21ff,homtht=223b,hookleftarrow=21a9,hook",
|
|
1778
|
+
"rightarrow=21aa,hopf=1d559,horbar=2015,hscr=1d4bd,hslash=210f,hstrok=127,hybull=2043,hyphen=2010,iac",
|
|
1779
|
+
"ute=ed,ic=2063,icirc=ee,icy=438,iecy=435,iexcl=a1,iff=21d4,ifr=1d526,igrave=ec,ii=2148,iiiint=2a0c,i",
|
|
1780
|
+
"iint=222d,iinfin=29dc,iiota=2129,ijlig=133,imacr=12b,image=2111,imagline=2110,imagpart=2111,imath=13",
|
|
1781
|
+
"1,imof=22b7,imped=1b5,in=2208,incare=2105,infin=221e,infintie=29dd,inodot=131,int=222b,intcal=22ba,i",
|
|
1782
|
+
"ntegers=2124,intercal=22ba,intlarhk=2a17,intprod=2a3c,iocy=451,iogon=12f,iopf=1d55a,iota=3b9,iprod=2",
|
|
1783
|
+
"a3c,iquest=bf,iscr=1d4be,isin=2208,isinE=22f9,isindot=22f5,isins=22f4,isinsv=22f3,isinv=2208,it=2062",
|
|
1784
|
+
",itilde=129,iukcy=456,iuml=ef,jcirc=135,jcy=439,jfr=1d527,jmath=237,jopf=1d55b,jscr=1d4bf,jsercy=458",
|
|
1785
|
+
",jukcy=454,kappa=3ba,kappav=3f0,kcedil=137,kcy=43a,kfr=1d528,kgreen=138,khcy=445,kjcy=45c,kopf=1d55c",
|
|
1786
|
+
",kscr=1d4c0,lAarr=21da,lArr=21d0,lAtail=291b,lBarr=290e,lE=2266,lEg=2a8b,lHar=2962,lacute=13a,laempt",
|
|
1787
|
+
"yv=29b4,lagran=2112,lambda=3bb,lang=2329,langd=2991,langle=27e8,lap=2a85,laquo=ab,larr=2190,larrb=21",
|
|
1788
|
+
"e4,larrbfs=291f,larrfs=291d,larrhk=21a9,larrlp=21ab,larrpl=2939,larrsim=2973,larrtl=21a2,lat=2aab,la",
|
|
1789
|
+
"tail=2919,late=2aad,lates=2aad.fe00,lbarr=290c,lbbrk=2772,lbrace=7b,lbrack=5b,lbrke=298b,lbrksld=298",
|
|
1790
|
+
"f,lbrkslu=298d,lcaron=13e,lcedil=13c,lceil=2308,lcub=7b,lcy=43b,ldca=2936,ldquo=201c,ldquor=201e,ldr",
|
|
1791
|
+
"dhar=2967,ldrushar=294b,ldsh=21b2,le=2264,leftarrow=2190,leftarrowtail=21a2,leftharpoondown=21bd,lef",
|
|
1792
|
+
"tharpoonup=21bc,leftleftarrows=21c7,leftrightarrow=2194,leftrightarrows=21c6,leftrightharpoons=21cb,",
|
|
1793
|
+
"leftrightsquigarrow=21ad,leftthreetimes=22cb,leg=22da,leq=2264,leqq=2266,leqslant=2a7d,les=2a7d,lesc",
|
|
1794
|
+
"c=2aa8,lesdot=2a7f,lesdoto=2a81,lesdotor=2a83,lesg=22da.fe00,lesges=2a93,lessapprox=2a85,lessdot=22d",
|
|
1795
|
+
"6,lesseqgtr=22da,lesseqqgtr=2a8b,lessgtr=2276,lesssim=2272,lfisht=297c,lfloor=230a,lfr=1d529,lg=2276",
|
|
1796
|
+
",lgE=2a91,lhard=21bd,lharu=21bc,lharul=296a,lhblk=2584,ljcy=459,ll=226a,llarr=21c7,llcorner=231e,llh",
|
|
1797
|
+
"ard=296b,lltri=25fa,lmidot=140,lmoust=23b0,lmoustache=23b0,lnE=2268,lnap=2a89,lnapprox=2a89,lne=2a87",
|
|
1798
|
+
",lneq=2a87,lneqq=2268,lnsim=22e6,loang=27ec,loarr=21fd,lobrk=27e6,longleftarrow=27f5,longleftrightar",
|
|
1799
|
+
"row=27f7,longmapsto=27fc,longrightarrow=27f6,looparrowleft=21ab,looparrowright=21ac,lopar=2985,lopf=",
|
|
1800
|
+
"1d55d,loplus=2a2d,lotimes=2a34,lowast=2217,lowbar=5f,loz=25ca,lozenge=25ca,lozf=29eb,lpar=28,lparlt=",
|
|
1801
|
+
"2993,lrarr=21c6,lrcorner=231f,lrhar=21cb,lrhard=296d,lrm=200e,lrtri=22bf,lsaquo=2039,lscr=1d4c1,lsh=",
|
|
1802
|
+
"21b0,lsim=2272,lsime=2a8d,lsimg=2a8f,lsqb=5b,lsquo=2018,lsquor=201a,lstrok=142,lt=3c,ltcc=2aa6,ltcir",
|
|
1803
|
+
"=2a79,ltdot=22d6,lthree=22cb,ltimes=22c9,ltlarr=2976,ltquest=2a7b,ltrPar=2996,ltri=25c3,ltrie=22b4,l",
|
|
1804
|
+
"trif=25c2,lurdshar=294a,luruhar=2966,lvertneqq=2268.fe00,lvnE=2268.fe00,mDDot=223a,macr=af,male=2642",
|
|
1805
|
+
",malt=2720,maltese=2720,map=21a6,mapsto=21a6,mapstodown=21a7,mapstoleft=21a4,mapstoup=21a5,marker=25",
|
|
1806
|
+
"ae,mcomma=2a29,mcy=43c,mdash=2014,measuredangle=2221,mfr=1d52a,mho=2127,micro=b5,mid=2223,midast=2a,",
|
|
1807
|
+
"midcir=2af0,middot=b7,minus=2212,minusb=229f,minusd=2238,minusdu=2a2a,mlcp=2adb,mldr=2026,mnplus=221",
|
|
1808
|
+
"3,models=22a7,mopf=1d55e,mp=2213,mscr=1d4c2,mstpos=223e,mu=3bc,multimap=22b8,mumap=22b8,nGg=22d9.338",
|
|
1809
|
+
",nGt=226b.20d2,nGtv=226b.338,nLeftarrow=21cd,nLeftrightarrow=21ce,nLl=22d8.338,nLt=226a.20d2,nLtv=22",
|
|
1810
|
+
"6a.338,nRightarrow=21cf,nVDash=22af,nVdash=22ae,nabla=2207,nacute=144,nang=2220.20d2,nap=2249,napE=2",
|
|
1811
|
+
"a70.338,napid=224b.338,napos=149,napprox=2249,natur=266e,natural=266e,naturals=2115,nbsp=a0,nbump=22",
|
|
1812
|
+
"4e.338,nbumpe=224f.338,ncap=2a43,ncaron=148,ncedil=146,ncong=2247,ncongdot=2a6d.338,ncup=2a42,ncy=43",
|
|
1813
|
+
"d,ndash=2013,ne=2260,neArr=21d7,nearhk=2924,nearr=2197,nearrow=2197,nedot=2250.338,nequiv=2262,nesea",
|
|
1814
|
+
"r=2928,nesim=2242.338,nexist=2204,nexists=2204,nfr=1d52b,ngE=2267.338,nge=2271,ngeq=2271,ngeqq=2267.",
|
|
1815
|
+
"338,ngeqslant=2a7e.338,nges=2a7e.338,ngsim=2275,ngt=226f,ngtr=226f,nhArr=21ce,nharr=21ae,nhpar=2af2,",
|
|
1816
|
+
"ni=220b,nis=22fc,nisd=22fa,niv=220b,njcy=45a,nlArr=21cd,nlE=2266.338,nlarr=219a,nldr=2025,nle=2270,n",
|
|
1817
|
+
"leftarrow=219a,nleftrightarrow=21ae,nleq=2270,nleqq=2266.338,nleqslant=2a7d.338,nles=2a7d.338,nless=",
|
|
1818
|
+
"226e,nlsim=2274,nlt=226e,nltri=22ea,nltrie=22ec,nmid=2224,nopf=1d55f,not=ac,notin=2209,notinE=22f9.3",
|
|
1819
|
+
"38,notindot=22f5.338,notinva=2209,notinvb=22f7,notinvc=22f6,notni=220c,notniva=220c,notnivb=22fe,not",
|
|
1820
|
+
"nivc=22fd,npar=2226,nparallel=2226,nparsl=2afd.20e5,npart=2202.338,npolint=2a14,npr=2280,nprcue=22e0",
|
|
1821
|
+
",npre=2aaf.338,nprec=2280,npreceq=2aaf.338,nrArr=21cf,nrarr=219b,nrarrc=2933.338,nrarrw=219d.338,nri",
|
|
1822
|
+
"ghtarrow=219b,nrtri=22eb,nrtrie=22ed,nsc=2281,nsccue=22e1,nsce=2ab0.338,nscr=1d4c3,nshortmid=2224,ns",
|
|
1823
|
+
"hortparallel=2226,nsim=2241,nsime=2244,nsimeq=2244,nsmid=2224,nspar=2226,nsqsube=22e2,nsqsupe=22e3,n",
|
|
1824
|
+
"sub=2284,nsubE=2ac5.338,nsube=2288,nsubset=2282.20d2,nsubseteq=2288,nsubseteqq=2ac5.338,nsucc=2281,n",
|
|
1825
|
+
"succeq=2ab0.338,nsup=2285,nsupE=2ac6.338,nsupe=2289,nsupset=2283.20d2,nsupseteq=2289,nsupseteqq=2ac6",
|
|
1826
|
+
".338,ntgl=2279,ntilde=f1,ntlg=2278,ntriangleleft=22ea,ntrianglelefteq=22ec,ntriangleright=22eb,ntria",
|
|
1827
|
+
"nglerighteq=22ed,nu=3bd,num=23,numero=2116,numsp=2007,nvDash=22ad,nvHarr=2904,nvap=224d.20d2,nvdash=",
|
|
1828
|
+
"22ac,nvge=2265.20d2,nvgt=3e.20d2,nvinfin=29de,nvlArr=2902,nvle=2264.20d2,nvlt=3c.20d2,nvltrie=22b4.2",
|
|
1829
|
+
"0d2,nvrArr=2903,nvrtrie=22b5.20d2,nvsim=223c.20d2,nwArr=21d6,nwarhk=2923,nwarr=2196,nwarrow=2196,nwn",
|
|
1830
|
+
"ear=2927,oS=24c8,oacute=f3,oast=229b,ocir=229a,ocirc=f4,ocy=43e,odash=229d,odblac=151,odiv=2a38,odot",
|
|
1831
|
+
"=2299,odsold=29bc,oelig=153,ofcir=29bf,ofr=1d52c,ogon=2db,ograve=f2,ogt=29c1,ohbar=29b5,ohm=3a9,oint",
|
|
1832
|
+
"=222e,olarr=21ba,olcir=29be,olcross=29bb,oline=203e,olt=29c0,omacr=14d,omega=3c9,omicron=3bf,omid=29",
|
|
1833
|
+
"b6,ominus=2296,oopf=1d560,opar=29b7,operp=29b9,oplus=2295,or=2228,orarr=21bb,ord=2a5d,order=2134,ord",
|
|
1834
|
+
"erof=2134,ordf=aa,ordm=ba,origof=22b6,oror=2a56,orslope=2a57,orv=2a5b,oscr=2134,oslash=f8,osol=2298,",
|
|
1835
|
+
"otilde=f5,otimes=2297,otimesas=2a36,ouml=f6,ovbar=233d,par=2225,para=b6,parallel=2225,parsim=2af3,pa",
|
|
1836
|
+
"rsl=2afd,part=2202,pcy=43f,percnt=25,period=2e,permil=2030,perp=22a5,pertenk=2031,pfr=1d52d,phi=3c6,",
|
|
1837
|
+
"phiv=3d5,phmmat=2133,phone=260e,pi=3c0,pitchfork=22d4,piv=3d6,planck=210f,planckh=210e,plankv=210f,p",
|
|
1838
|
+
"lus=2b,plusacir=2a23,plusb=229e,pluscir=2a22,plusdo=2214,plusdu=2a25,pluse=2a72,plusmn=b1,plussim=2a",
|
|
1839
|
+
"26,plustwo=2a27,pm=b1,pointint=2a15,popf=1d561,pound=a3,pr=227a,prE=2ab3,prap=2ab7,prcue=227c,pre=2a",
|
|
1840
|
+
"af,prec=227a,precapprox=2ab7,preccurlyeq=227c,preceq=2aaf,precnapprox=2ab9,precneqq=2ab5,precnsim=22",
|
|
1841
|
+
"e8,precsim=227e,prime=2032,primes=2119,prnE=2ab5,prnap=2ab9,prnsim=22e8,prod=220f,profalar=232e,prof",
|
|
1842
|
+
"line=2312,profsurf=2313,prop=221d,propto=221d,prsim=227e,prurel=22b0,pscr=1d4c5,psi=3c8,puncsp=2008,",
|
|
1843
|
+
"qfr=1d52e,qint=2a0c,qopf=1d562,qprime=2057,qscr=1d4c6,quaternions=210d,quatint=2a16,quest=3f,questeq",
|
|
1844
|
+
"=225f,quot=22,rAarr=21db,rArr=21d2,rAtail=291c,rBarr=290f,rHar=2964,race=223d.331,racute=155,radic=2",
|
|
1845
|
+
"21a,raemptyv=29b3,rang=232a,rangd=2992,range=29a5,rangle=27e9,raquo=bb,rarr=2192,rarrap=2975,rarrb=2",
|
|
1846
|
+
"1e5,rarrbfs=2920,rarrc=2933,rarrfs=291e,rarrhk=21aa,rarrlp=21ac,rarrpl=2945,rarrsim=2974,rarrtl=21a3",
|
|
1847
|
+
",rarrw=219d,ratail=291a,ratio=2236,rationals=211a,rbarr=290d,rbbrk=2773,rbrace=7d,rbrack=5d,rbrke=29",
|
|
1848
|
+
"8c,rbrksld=298e,rbrkslu=2990,rcaron=159,rcedil=157,rceil=2309,rcub=7d,rcy=440,rdca=2937,rdldhar=2969",
|
|
1849
|
+
",rdquo=201d,rdquor=201d,rdsh=21b3,real=211c,realine=211b,realpart=211c,reals=211d,rect=25ad,reg=ae,r",
|
|
1850
|
+
"fisht=297d,rfloor=230b,rfr=1d52f,rhard=21c1,rharu=21c0,rharul=296c,rho=3c1,rhov=3f1,rightarrow=2192,",
|
|
1851
|
+
"rightarrowtail=21a3,rightharpoondown=21c1,rightharpoonup=21c0,rightleftarrows=21c4,rightleftharpoons",
|
|
1852
|
+
"=21cc,rightrightarrows=21c9,rightsquigarrow=219d,rightthreetimes=22cc,ring=2da,risingdotseq=2253,rla",
|
|
1853
|
+
"rr=21c4,rlhar=21cc,rlm=200f,rmoust=23b1,rmoustache=23b1,rnmid=2aee,roang=27ed,roarr=21fe,robrk=27e7,",
|
|
1854
|
+
"ropar=2986,ropf=1d563,roplus=2a2e,rotimes=2a35,rpar=29,rpargt=2994,rppolint=2a12,rrarr=21c9,rsaquo=2",
|
|
1855
|
+
"03a,rscr=1d4c7,rsh=21b1,rsqb=5d,rsquo=2019,rsquor=2019,rthree=22cc,rtimes=22ca,rtri=25b9,rtrie=22b5,",
|
|
1856
|
+
"rtrif=25b8,rtriltri=29ce,ruluhar=2968,rx=211e,sacute=15b,sbquo=201a,sc=227b,scE=2ab4,scap=2ab8,scaro",
|
|
1857
|
+
"n=161,sccue=227d,sce=2ab0,scedil=15f,scirc=15d,scnE=2ab6,scnap=2aba,scnsim=22e9,scpolint=2a13,scsim=",
|
|
1858
|
+
"227f,scy=441,sdot=22c5,sdotb=22a1,sdote=2a66,seArr=21d8,searhk=2925,searr=2198,searrow=2198,sect=a7,",
|
|
1859
|
+
"semi=3b,seswar=2929,setminus=2216,setmn=2216,sext=2736,sfr=1d530,sfrown=2322,sharp=266f,shchcy=449,s",
|
|
1860
|
+
"hcy=448,shortmid=2223,shortparallel=2225,shy=ad,sigma=3c3,sigmaf=3c2,sigmav=3c2,sim=223c,simdot=2a6a",
|
|
1861
|
+
",sime=2243,simeq=2243,simg=2a9e,simgE=2aa0,siml=2a9d,simlE=2a9f,simne=2246,simplus=2a24,simrarr=2972",
|
|
1862
|
+
",slarr=2190,smallsetminus=2216,smashp=2a33,smeparsl=29e4,smid=2223,smile=2323,smt=2aaa,smte=2aac,smt",
|
|
1863
|
+
"es=2aac.fe00,softcy=44c,sol=2f,solb=29c4,solbar=233f,sopf=1d564,spades=2660,spadesuit=2660,spar=2225",
|
|
1864
|
+
",sqcap=2293,sqcaps=2293.fe00,sqcup=2294,sqcups=2294.fe00,sqsub=228f,sqsube=2291,sqsubset=228f,sqsubs",
|
|
1865
|
+
"eteq=2291,sqsup=2290,sqsupe=2292,sqsupset=2290,sqsupseteq=2292,squ=25a1,square=25a1,squarf=25aa,squf",
|
|
1866
|
+
"=25aa,srarr=2192,sscr=1d4c8,ssetmn=2216,ssmile=2323,sstarf=22c6,star=2606,starf=2605,straightepsilon",
|
|
1867
|
+
"=3f5,straightphi=3d5,strns=af,sub=2282,subE=2ac5,subdot=2abd,sube=2286,subedot=2ac3,submult=2ac1,sub",
|
|
1868
|
+
"nE=2acb,subne=228a,subplus=2abf,subrarr=2979,subset=2282,subseteq=2286,subseteqq=2ac5,subsetneq=228a",
|
|
1869
|
+
",subsetneqq=2acb,subsim=2ac7,subsub=2ad5,subsup=2ad3,succ=227b,succapprox=2ab8,succcurlyeq=227d,succ",
|
|
1870
|
+
"eq=2ab0,succnapprox=2aba,succneqq=2ab6,succnsim=22e9,succsim=227f,sum=2211,sung=266a,sup=2283,sup1=b",
|
|
1871
|
+
"9,sup2=b2,sup3=b3,supE=2ac6,supdot=2abe,supdsub=2ad8,supe=2287,supedot=2ac4,suphsol=27c9,suphsub=2ad",
|
|
1872
|
+
"7,suplarr=297b,supmult=2ac2,supnE=2acc,supne=228b,supplus=2ac0,supset=2283,supseteq=2287,supseteqq=2",
|
|
1873
|
+
"ac6,supsetneq=228b,supsetneqq=2acc,supsim=2ac8,supsub=2ad4,supsup=2ad6,swArr=21d9,swarhk=2926,swarr=",
|
|
1874
|
+
"2199,swarrow=2199,swnwar=292a,szlig=df,target=2316,tau=3c4,tbrk=23b4,tcaron=165,tcedil=163,tcy=442,t",
|
|
1875
|
+
"dot=20db,telrec=2315,tfr=1d531,there4=2234,therefore=2234,theta=3b8,thetasym=3d1,thetav=3d1,thickapp",
|
|
1876
|
+
"rox=2248,thicksim=223c,thinsp=2009,thkap=2248,thksim=223c,thorn=fe,tilde=2dc,times=d7,timesb=22a0,ti",
|
|
1877
|
+
"mesbar=2a31,timesd=2a30,tint=222d,toea=2928,top=22a4,topbot=2336,topcir=2af1,topf=1d565,topfork=2ada",
|
|
1878
|
+
",tosa=2929,tprime=2034,trade=2122,triangle=25b5,triangledown=25bf,triangleleft=25c3,trianglelefteq=2",
|
|
1879
|
+
"2b4,triangleq=225c,triangleright=25b9,trianglerighteq=22b5,tridot=25ec,trie=225c,triminus=2a3a,tripl",
|
|
1880
|
+
"us=2a39,trisb=29cd,tritime=2a3b,trpezium=23e2,tscr=1d4c9,tscy=446,tshcy=45b,tstrok=167,twixt=226c,tw",
|
|
1881
|
+
"oheadleftarrow=219e,twoheadrightarrow=21a0,uArr=21d1,uHar=2963,uacute=fa,uarr=2191,ubrcy=45e,ubreve=",
|
|
1882
|
+
"16d,ucirc=fb,ucy=443,udarr=21c5,udblac=171,udhar=296e,ufisht=297e,ufr=1d532,ugrave=f9,uharl=21bf,uha",
|
|
1883
|
+
"rr=21be,uhblk=2580,ulcorn=231c,ulcorner=231c,ulcrop=230f,ultri=25f8,umacr=16b,uml=a8,uogon=173,uopf=",
|
|
1884
|
+
"1d566,uparrow=2191,updownarrow=2195,upharpoonleft=21bf,upharpoonright=21be,uplus=228e,upsi=3c5,upsih",
|
|
1885
|
+
"=3d2,upsilon=3c5,upuparrows=21c8,urcorn=231d,urcorner=231d,urcrop=230e,uring=16f,urtri=25f9,uscr=1d4",
|
|
1886
|
+
"ca,utdot=22f0,utilde=169,utri=25b5,utrif=25b4,uuarr=21c8,uuml=fc,uwangle=29a7,vArr=21d5,vBar=2ae8,vB",
|
|
1887
|
+
"arv=2ae9,vDash=22a8,vangrt=299c,varepsilon=3f5,varkappa=3f0,varnothing=2205,varphi=3d5,varpi=3d6,var",
|
|
1888
|
+
"propto=221d,varr=2195,varrho=3f1,varsigma=3c2,varsubsetneq=228a.fe00,varsubsetneqq=2acb.fe00,varsups",
|
|
1889
|
+
"etneq=228b.fe00,varsupsetneqq=2acc.fe00,vartheta=3d1,vartriangleleft=22b2,vartriangleright=22b3,vcy=",
|
|
1890
|
+
"432,vdash=22a2,vee=2228,veebar=22bb,veeeq=225a,vellip=22ee,verbar=7c,vert=7c,vfr=1d533,vltri=22b2,vn",
|
|
1891
|
+
"sub=2282.20d2,vnsup=2283.20d2,vopf=1d567,vprop=221d,vrtri=22b3,vscr=1d4cb,vsubnE=2acb.fe00,vsubne=22",
|
|
1892
|
+
"8a.fe00,vsupnE=2acc.fe00,vsupne=228b.fe00,vzigzag=299a,wcirc=175,wedbar=2a5f,wedge=2227,wedgeq=2259,",
|
|
1893
|
+
"weierp=2118,wfr=1d534,wopf=1d568,wp=2118,wr=2240,wreath=2240,wscr=1d4cc,xcap=22c2,xcirc=25ef,xcup=22",
|
|
1894
|
+
"c3,xdtri=25bd,xfr=1d535,xhArr=27fa,xharr=27f7,xi=3be,xlArr=27f8,xlarr=27f5,xmap=27fc,xnis=22fb,xodot",
|
|
1895
|
+
"=2a00,xopf=1d569,xoplus=2a01,xotime=2a02,xrArr=27f9,xrarr=27f6,xscr=1d4cd,xsqcup=2a06,xuplus=2a04,xu",
|
|
1896
|
+
"tri=25b3,xvee=22c1,xwedge=22c0,yacute=fd,yacy=44f,ycirc=177,ycy=44b,yen=a5,yfr=1d536,yicy=457,yopf=1",
|
|
1897
|
+
"d56a,yscr=1d4ce,yucy=44e,yuml=ff,zacute=17a,zcaron=17e,zcy=437,zdot=17c,zeetrf=2128,zeta=3b6,zfr=1d5",
|
|
1898
|
+
"37,zhcy=436,zigrarr=21dd,zopf=1d56b,zscr=1d4cf,zwj=200d,zwnj=200c"
|
|
1899
|
+
].join("");
|
|
1900
|
+
NAMED_REFERENCES = new Map(NAMED.split(",").map((entry) => {
|
|
1901
|
+
const [name, codes] = entry.split("=");
|
|
1902
|
+
return [name, String.fromCodePoint(...codes.split(".").map((code) => Number.parseInt(code, 16)))];
|
|
1903
|
+
}));
|
|
1904
|
+
}
|
|
1905
|
+
});
|
|
1906
|
+
|
|
1627
1907
|
// src/html.js
|
|
1628
1908
|
function fromCode(code) {
|
|
1629
1909
|
if (code === 0 || code > 1114111 || code >= 55296 && code <= 57343) {
|
|
@@ -1640,8 +1920,8 @@ function decodeEntities(value, { attribute = false } = {}) {
|
|
|
1640
1920
|
if (hex !== void 0 || decimal !== void 0) {
|
|
1641
1921
|
return fromCode(hex === void 0 ? Number.parseInt(decimal, 10) : Number.parseInt(hex, 16));
|
|
1642
1922
|
}
|
|
1643
|
-
if (semicolon &&
|
|
1644
|
-
return
|
|
1923
|
+
if (semicolon && NAMED_REFERENCES.has(name)) {
|
|
1924
|
+
return NAMED_REFERENCES.get(name);
|
|
1645
1925
|
}
|
|
1646
1926
|
let legacy;
|
|
1647
1927
|
for (let length = Math.min(name.length, LEGACY_LONGEST); length >= 2 && legacy === void 0; length--) {
|
|
@@ -1655,7 +1935,7 @@ function decodeEntities(value, { attribute = false } = {}) {
|
|
|
1655
1935
|
if (attribute && /[\da-zA-Z=]/.test(next)) {
|
|
1656
1936
|
return match;
|
|
1657
1937
|
}
|
|
1658
|
-
return
|
|
1938
|
+
return NAMED_REFERENCES.get(legacy) + rest;
|
|
1659
1939
|
});
|
|
1660
1940
|
}
|
|
1661
1941
|
function readTag(html2, start) {
|
|
@@ -2296,106 +2576,14 @@ function visibleText(html2) {
|
|
|
2296
2576
|
}
|
|
2297
2577
|
return { text: parts.join(""), hidden };
|
|
2298
2578
|
}
|
|
2299
|
-
var LATIN1,
|
|
2579
|
+
var LATIN1, LEGACY, LEGACY_LONGEST, WINDOWS_1252, REFERENCE, UNSHOWN, RAW_SHOWN, RAW_END, BREAKS, SPECIAL, SCOPE, FORMATTING, LINE, OWN_PLACE, VOID, CLOSES_PARAGRAPH, PARAGRAPH, IMPLIED, TABLE_PARTS, TABLE_BOXES, HEADINGS, IMPLIED_END, PARTS_OF_TABLE, TABLE_STRUCTURE, IN_TABLE, MAX_FORMATTING, MARKERS, FOSTERED_MARKERS, NOT_REOPENING, LEAVES_FOREIGN, HOLDS_HTML, SVG_UNSHOWN, MAX_OPEN, MAX_ATTRIBUTES, MAX_STYLE, COMMENT_END, WHITESPACE2, NO_WORD_ATTRIBUTES, FIELDS, FIELD_HELP, HINTS, MAX_HELP, LABEL_END, isHelp, MAX_VALUE, LENGTH, UNITS, SIZE_KEYWORDS, ZERO_NUMBER, DISPLAY_INLINE, DISPLAY_BLOCK, isZero, declarationCache, ROOT, DOCTYPE, QUIRKS_PUBLIC, QUIRKS_IF_NO_SYSTEM;
|
|
2300
2580
|
var init_html = __esm({
|
|
2301
2581
|
"src/html.js"() {
|
|
2582
|
+
init_entities();
|
|
2302
2583
|
init_linear();
|
|
2303
2584
|
LATIN1 = "nbsp iexcl cent pound curren yen brvbar sect uml copy ordf laquo not shy reg macr deg plusmn sup2 sup3 acute micro para middot cedil sup1 ordm raquo frac14 frac12 frac34 iquest Agrave Aacute Acirc Atilde Auml Aring AElig Ccedil Egrave Eacute Ecirc Euml Igrave Iacute Icirc Iuml ETH Ntilde Ograve Oacute Ocirc Otilde Ouml times Oslash Ugrave Uacute Ucirc Uuml Yacute THORN szlig agrave aacute acirc atilde auml aring aelig ccedil egrave eacute ecirc euml igrave iacute icirc iuml eth ntilde ograve oacute ocirc otilde ouml divide oslash ugrave uacute ucirc uuml yacute thorn yuml".split(" ");
|
|
2304
|
-
ENTITIES = new Map([
|
|
2305
|
-
...LATIN1.map((name, index) => [name, String.fromCodePoint(160 + index)]),
|
|
2306
|
-
["amp", "&"],
|
|
2307
|
-
["lt", "<"],
|
|
2308
|
-
["gt", ">"],
|
|
2309
|
-
["quot", '"'],
|
|
2310
|
-
["apos", "'"],
|
|
2311
|
-
["AMP", "&"],
|
|
2312
|
-
["LT", "<"],
|
|
2313
|
-
["GT", ">"],
|
|
2314
|
-
["QUOT", '"'],
|
|
2315
|
-
["COPY", "\xA9"],
|
|
2316
|
-
["REG", "\xAE"],
|
|
2317
|
-
["OElig", "\u0152"],
|
|
2318
|
-
["oelig", "\u0153"],
|
|
2319
|
-
["Scaron", "\u0160"],
|
|
2320
|
-
["scaron", "\u0161"],
|
|
2321
|
-
["Yuml", "\u0178"],
|
|
2322
|
-
["fnof", "\u0192"],
|
|
2323
|
-
["circ", "\u02C6"],
|
|
2324
|
-
["tilde", "\u02DC"],
|
|
2325
|
-
["ensp", "\u2002"],
|
|
2326
|
-
["emsp", "\u2003"],
|
|
2327
|
-
["thinsp", "\u2009"],
|
|
2328
|
-
["zwnj", "\u200C"],
|
|
2329
|
-
["zwj", "\u200D"],
|
|
2330
|
-
["lrm", "\u200E"],
|
|
2331
|
-
["rlm", "\u200F"],
|
|
2332
|
-
["ndash", "\u2013"],
|
|
2333
|
-
["mdash", "\u2014"],
|
|
2334
|
-
["lsquo", "\u2018"],
|
|
2335
|
-
["rsquo", "\u2019"],
|
|
2336
|
-
["sbquo", "\u201A"],
|
|
2337
|
-
["ldquo", "\u201C"],
|
|
2338
|
-
["rdquo", "\u201D"],
|
|
2339
|
-
["bdquo", "\u201E"],
|
|
2340
|
-
["dagger", "\u2020"],
|
|
2341
|
-
["Dagger", "\u2021"],
|
|
2342
|
-
["bull", "\u2022"],
|
|
2343
|
-
["hellip", "\u2026"],
|
|
2344
|
-
["permil", "\u2030"],
|
|
2345
|
-
["prime", "\u2032"],
|
|
2346
|
-
["Prime", "\u2033"],
|
|
2347
|
-
["lsaquo", "\u2039"],
|
|
2348
|
-
["rsaquo", "\u203A"],
|
|
2349
|
-
["euro", "\u20AC"],
|
|
2350
|
-
["trade", "\u2122"],
|
|
2351
|
-
["larr", "\u2190"],
|
|
2352
|
-
["uarr", "\u2191"],
|
|
2353
|
-
["rarr", "\u2192"],
|
|
2354
|
-
["darr", "\u2193"],
|
|
2355
|
-
["hearts", "\u2665"],
|
|
2356
|
-
["check", "\u2713"],
|
|
2357
|
-
// The punctuation of a web address, as browsers read these names
|
|
2358
|
-
// ("https://bank.example@evil.example/" goes to evil.example)
|
|
2359
|
-
["Tab", " "],
|
|
2360
|
-
["NewLine", "\n"],
|
|
2361
|
-
["excl", "!"],
|
|
2362
|
-
["num", "#"],
|
|
2363
|
-
["dollar", "$"],
|
|
2364
|
-
["percnt", "%"],
|
|
2365
|
-
["lpar", "("],
|
|
2366
|
-
["rpar", ")"],
|
|
2367
|
-
["ast", "*"],
|
|
2368
|
-
["midast", "*"],
|
|
2369
|
-
["plus", "+"],
|
|
2370
|
-
["comma", ","],
|
|
2371
|
-
["period", "."],
|
|
2372
|
-
["sol", "/"],
|
|
2373
|
-
["colon", ":"],
|
|
2374
|
-
["semi", ";"],
|
|
2375
|
-
["equals", "="],
|
|
2376
|
-
["quest", "?"],
|
|
2377
|
-
["commat", "@"],
|
|
2378
|
-
["lsqb", "["],
|
|
2379
|
-
["lbrack", "["],
|
|
2380
|
-
["bsol", "\\"],
|
|
2381
|
-
["rsqb", "]"],
|
|
2382
|
-
["rbrack", "]"],
|
|
2383
|
-
["Hat", "^"],
|
|
2384
|
-
["lowbar", "_"],
|
|
2385
|
-
["UnderBar", "_"],
|
|
2386
|
-
["grave", "`"],
|
|
2387
|
-
["DiacriticalGrave", "`"],
|
|
2388
|
-
["lcub", "{"],
|
|
2389
|
-
["lbrace", "{"],
|
|
2390
|
-
["verbar", "|"],
|
|
2391
|
-
["vert", "|"],
|
|
2392
|
-
["VerticalLine", "|"],
|
|
2393
|
-
["rcub", "}"],
|
|
2394
|
-
["rbrace", "}"]
|
|
2395
|
-
]);
|
|
2396
2585
|
LEGACY = /* @__PURE__ */ new Set([...LATIN1, "amp", "lt", "gt", "quot", "AMP", "LT", "GT", "QUOT", "COPY", "REG"]);
|
|
2397
2586
|
LEGACY_LONGEST = Math.max(...[...LEGACY].map((name) => name.length));
|
|
2398
|
-
LONGER_NAMES = new Set("centerdot copysr divideontimes gtcc gtcir gtdot gtlPar gtquest gtrapprox gtrarr gtrdot gtreqless gtreqqless gtrless gtrsim ltcc ltcir ltdot lthree ltimes ltlarr ltquest ltrPar ltri ltrie ltrif notin notinE notindot notinva notinvb notinvc notni notniva notnivb notnivc parallel timesb timesbar timesd".split(" "));
|
|
2399
2587
|
WINDOWS_1252 = [8364, 129, 8218, 402, 8222, 8230, 8224, 8225, 710, 8240, 352, 8249, 338, 141, 381, 143, 144, 8216, 8217, 8220, 8221, 8226, 8211, 8212, 732, 8482, 353, 8250, 339, 157, 382, 376];
|
|
2400
2588
|
REFERENCE = /&(?:#([xX])([\da-fA-F]+)|#(\d+)|([a-zA-Z][a-zA-Z\d]{0,31}))(;?)/g;
|
|
2401
2589
|
UNSHOWN = /* @__PURE__ */ new Set(["script", "style", "title", "noembed", "noframes", "iframe"]);
|
|
@@ -2790,7 +2978,7 @@ function endsInsideTag(html2, end, link) {
|
|
|
2790
2978
|
const joined = trimEndOf(link.replace(/^https?:\/\//i, "") + after, ".-");
|
|
2791
2979
|
return joined !== host && (!isHost(host) || isHost(joined) && registrableDomain(joined) !== registrableDomain(host));
|
|
2792
2980
|
}
|
|
2793
|
-
function extractLinks(text, html2, { maxLength = 5e5, bareHosts = false } = {}) {
|
|
2981
|
+
function extractLinks(text, html2, { maxLength = 5e5, bareHosts: bareHosts2 = false } = {}) {
|
|
2794
2982
|
text = typeof text === "string" ? foldToAscii(text) : text;
|
|
2795
2983
|
html2 = typeof html2 === "string" ? foldToAscii(html2) : html2;
|
|
2796
2984
|
const links = [];
|
|
@@ -2857,7 +3045,7 @@ ${shown || ""}`;
|
|
|
2857
3045
|
}
|
|
2858
3046
|
add(link);
|
|
2859
3047
|
}
|
|
2860
|
-
if (
|
|
3048
|
+
if (bareHosts2 && index < 2) {
|
|
2861
3049
|
bareLinkHosts(read, (host) => {
|
|
2862
3050
|
bareFound.push(host);
|
|
2863
3051
|
});
|
|
@@ -4423,7 +4611,8 @@ async function parseWithin(raw, parse = parseMessage, deadline = Date.now() + PA
|
|
|
4423
4611
|
}
|
|
4424
4612
|
}
|
|
4425
4613
|
}
|
|
4426
|
-
async function expandAttachments(attachments = [], errors = [], parse = parseMessage,
|
|
4614
|
+
async function expandAttachments(attachments = [], errors = [], parse = parseMessage, gets = {}) {
|
|
4615
|
+
const { unopened = [], mails = [] } = Array.isArray(gets) ? { unopened: gets } : gets;
|
|
4427
4616
|
const all = [];
|
|
4428
4617
|
const deadline = Date.now() + PARSE_TIMEOUT;
|
|
4429
4618
|
let budget = MAX_NESTED_BYTES;
|
|
@@ -4472,6 +4661,7 @@ async function expandAttachments(attachments = [], errors = [], parse = parseMes
|
|
|
4472
4661
|
if (inner.error) {
|
|
4473
4662
|
errors.push(inner.error);
|
|
4474
4663
|
}
|
|
4664
|
+
mails.push(inner.mail);
|
|
4475
4665
|
await visit(inner.mail.attachments, prefix ? `${prefix}/${name}` : name || "attached message", depth + 1);
|
|
4476
4666
|
}
|
|
4477
4667
|
}
|
|
@@ -6015,6 +6205,924 @@ var init_classifier = __esm({
|
|
|
6015
6205
|
}
|
|
6016
6206
|
});
|
|
6017
6207
|
|
|
6208
|
+
// src/links.js
|
|
6209
|
+
function isHostCode2(code) {
|
|
6210
|
+
return code >= 97 && code <= 122 || code >= 65 && code <= 90 || code >= 48 && code <= 57 || code === 45 || code === 46;
|
|
6211
|
+
}
|
|
6212
|
+
function isSpace(code) {
|
|
6213
|
+
return code === 32 || code >= 9 && code <= 13;
|
|
6214
|
+
}
|
|
6215
|
+
function urlOf(value) {
|
|
6216
|
+
let href = value.replaceAll(/[\t\n\r]/g, "");
|
|
6217
|
+
let start = 0;
|
|
6218
|
+
let end = href.length;
|
|
6219
|
+
while (start < end && href.codePointAt(start) <= 32) {
|
|
6220
|
+
start++;
|
|
6221
|
+
}
|
|
6222
|
+
while (end > start && href.codePointAt(end - 1) <= 32) {
|
|
6223
|
+
end--;
|
|
6224
|
+
}
|
|
6225
|
+
while (end > start && TRAILING.has(href[end - 1])) {
|
|
6226
|
+
end--;
|
|
6227
|
+
}
|
|
6228
|
+
href = href.slice(start, end);
|
|
6229
|
+
if (/^[\\/]{2}/.test(href)) {
|
|
6230
|
+
href = `https://${href.slice(2)}`;
|
|
6231
|
+
} else if (/^www\./i.test(href)) {
|
|
6232
|
+
href = `http://${href}`;
|
|
6233
|
+
} else if (!/^https?:/i.test(href)) {
|
|
6234
|
+
return null;
|
|
6235
|
+
}
|
|
6236
|
+
try {
|
|
6237
|
+
return new URL(href);
|
|
6238
|
+
} catch {
|
|
6239
|
+
return null;
|
|
6240
|
+
}
|
|
6241
|
+
}
|
|
6242
|
+
function hostOfUrl(url) {
|
|
6243
|
+
let host = url.hostname.toLowerCase();
|
|
6244
|
+
let dots = host.length;
|
|
6245
|
+
while (dots > 0 && host[dots - 1] === ".") {
|
|
6246
|
+
dots--;
|
|
6247
|
+
}
|
|
6248
|
+
host = host.slice(0, dots);
|
|
6249
|
+
if (host.startsWith("[") && host.endsWith("]")) {
|
|
6250
|
+
host = host.slice(1, -1);
|
|
6251
|
+
}
|
|
6252
|
+
if (!host || NAMESPACES.has(host)) {
|
|
6253
|
+
return null;
|
|
6254
|
+
}
|
|
6255
|
+
return (0, import_node_net4.isIP)(host) ? host : lookupName(host);
|
|
6256
|
+
}
|
|
6257
|
+
function hostsOf(value) {
|
|
6258
|
+
const url = urlOf(value);
|
|
6259
|
+
if (!url) {
|
|
6260
|
+
return [];
|
|
6261
|
+
}
|
|
6262
|
+
const host = hostOfUrl(url);
|
|
6263
|
+
const hosts = host ? [host] : [];
|
|
6264
|
+
const target = unwrapLink(url.href);
|
|
6265
|
+
if (target && target.href !== url.href) {
|
|
6266
|
+
const targetHost = hostOfUrl(target);
|
|
6267
|
+
if (targetHost && targetHost !== host) {
|
|
6268
|
+
hosts.push(targetHost);
|
|
6269
|
+
}
|
|
6270
|
+
const further = unwrapLink(target.href);
|
|
6271
|
+
if (further && further.href !== target.href) {
|
|
6272
|
+
hosts.unresolved = true;
|
|
6273
|
+
}
|
|
6274
|
+
}
|
|
6275
|
+
return hosts;
|
|
6276
|
+
}
|
|
6277
|
+
function* attributesOf(html2) {
|
|
6278
|
+
TAG_START.lastIndex = 0;
|
|
6279
|
+
let match;
|
|
6280
|
+
while ((match = TAG_START.exec(html2)) !== null) {
|
|
6281
|
+
let i = match.index + match[0].length;
|
|
6282
|
+
while (i < html2.length && html2[i] !== ">") {
|
|
6283
|
+
if (isSpace(html2.codePointAt(i)) || html2[i] === "/") {
|
|
6284
|
+
i++;
|
|
6285
|
+
continue;
|
|
6286
|
+
}
|
|
6287
|
+
let j = i;
|
|
6288
|
+
while (j < html2.length && html2[j] !== "=" && html2[j] !== ">" && html2[j] !== "/" && !isSpace(html2.codePointAt(j))) {
|
|
6289
|
+
j++;
|
|
6290
|
+
}
|
|
6291
|
+
const name = html2.slice(i, j).toLowerCase();
|
|
6292
|
+
if (j === i) {
|
|
6293
|
+
j++;
|
|
6294
|
+
}
|
|
6295
|
+
while (j < html2.length && isSpace(html2.codePointAt(j))) {
|
|
6296
|
+
j++;
|
|
6297
|
+
}
|
|
6298
|
+
if (html2[j] !== "=") {
|
|
6299
|
+
i = j;
|
|
6300
|
+
continue;
|
|
6301
|
+
}
|
|
6302
|
+
j++;
|
|
6303
|
+
while (j < html2.length && isSpace(html2.codePointAt(j))) {
|
|
6304
|
+
j++;
|
|
6305
|
+
}
|
|
6306
|
+
let value;
|
|
6307
|
+
if (html2[j] === '"' || html2[j] === "'") {
|
|
6308
|
+
const close = html2.indexOf(html2[j], j + 1);
|
|
6309
|
+
const stop = close === -1 ? html2.length : close;
|
|
6310
|
+
value = html2.slice(j + 1, stop);
|
|
6311
|
+
j = stop + 1;
|
|
6312
|
+
} else {
|
|
6313
|
+
const start = j;
|
|
6314
|
+
while (j < html2.length && html2[j] !== ">" && !isSpace(html2.codePointAt(j))) {
|
|
6315
|
+
j++;
|
|
6316
|
+
}
|
|
6317
|
+
value = html2.slice(start, j);
|
|
6318
|
+
}
|
|
6319
|
+
if (name) {
|
|
6320
|
+
yield [name, value];
|
|
6321
|
+
}
|
|
6322
|
+
i = j;
|
|
6323
|
+
}
|
|
6324
|
+
TAG_START.lastIndex = Math.max(i, match.index + 1);
|
|
6325
|
+
}
|
|
6326
|
+
}
|
|
6327
|
+
function linksOf(name, value, add, embed) {
|
|
6328
|
+
const decoded = decodeEntities(value, { attribute: true });
|
|
6329
|
+
switch (name) {
|
|
6330
|
+
case "srcdoc": {
|
|
6331
|
+
embed(decoded);
|
|
6332
|
+
break;
|
|
6333
|
+
}
|
|
6334
|
+
case "style": {
|
|
6335
|
+
for (const [, link] of decoded.matchAll(CSS_URL)) {
|
|
6336
|
+
add(link);
|
|
6337
|
+
}
|
|
6338
|
+
break;
|
|
6339
|
+
}
|
|
6340
|
+
case "srcset": {
|
|
6341
|
+
for (const candidate of decoded.split(",")) {
|
|
6342
|
+
add(candidate.trim().split(/\s/, 1)[0]);
|
|
6343
|
+
}
|
|
6344
|
+
break;
|
|
6345
|
+
}
|
|
6346
|
+
// (several, separated by spaces)
|
|
6347
|
+
case "ping": {
|
|
6348
|
+
for (const link of decoded.split(/\s+/)) {
|
|
6349
|
+
add(link);
|
|
6350
|
+
}
|
|
6351
|
+
break;
|
|
6352
|
+
}
|
|
6353
|
+
// (only the address of a refresh)
|
|
6354
|
+
case "content": {
|
|
6355
|
+
const match = /(?:^|[\s;,])url\s*=\s*["']?([^\s"';]+)/i.exec(decoded.slice(0, 4096));
|
|
6356
|
+
if (match) {
|
|
6357
|
+
add(match[1]);
|
|
6358
|
+
}
|
|
6359
|
+
break;
|
|
6360
|
+
}
|
|
6361
|
+
default: {
|
|
6362
|
+
add(decoded);
|
|
6363
|
+
}
|
|
6364
|
+
}
|
|
6365
|
+
}
|
|
6366
|
+
function lenientLinks(html2, add, done, embed) {
|
|
6367
|
+
LENIENT.lastIndex = 0;
|
|
6368
|
+
let match;
|
|
6369
|
+
while (!done() && (match = LENIENT.exec(html2)) !== null) {
|
|
6370
|
+
const name = match[1].toLowerCase();
|
|
6371
|
+
let i = LENIENT.lastIndex;
|
|
6372
|
+
let end = i;
|
|
6373
|
+
if (html2[i] === '"' || html2[i] === "'") {
|
|
6374
|
+
const quote = html2[i];
|
|
6375
|
+
i++;
|
|
6376
|
+
end = i;
|
|
6377
|
+
while (end < html2.length && html2[end] !== quote && html2[end] !== "<" && html2[end] !== ">") {
|
|
6378
|
+
end++;
|
|
6379
|
+
}
|
|
6380
|
+
if (end < html2.length && html2[end] !== quote) {
|
|
6381
|
+
const close = html2.indexOf(quote, end);
|
|
6382
|
+
if (close !== -1 && close - i <= MAX_LENIENT_VALUE) {
|
|
6383
|
+
linksOf(name, html2.slice(i, close), add, embed);
|
|
6384
|
+
}
|
|
6385
|
+
}
|
|
6386
|
+
} else {
|
|
6387
|
+
while (end < html2.length && !isSpace(html2.codePointAt(end)) && !UNQUOTED_END.has(html2[end])) {
|
|
6388
|
+
end++;
|
|
6389
|
+
}
|
|
6390
|
+
}
|
|
6391
|
+
linksOf(name, html2.slice(i, end), add, embed);
|
|
6392
|
+
}
|
|
6393
|
+
}
|
|
6394
|
+
function endsLink2(text, i) {
|
|
6395
|
+
const code = text.codePointAt(i);
|
|
6396
|
+
if (code < 128) {
|
|
6397
|
+
return isSpace(code) || code === 34 || code === 39 || code === 60 || code === 62 || code === 96;
|
|
6398
|
+
}
|
|
6399
|
+
return /\s/u.test(text[i]);
|
|
6400
|
+
}
|
|
6401
|
+
function linkReader(text) {
|
|
6402
|
+
let read = 0;
|
|
6403
|
+
let space = -1;
|
|
6404
|
+
let scheme = -1;
|
|
6405
|
+
return (start) => {
|
|
6406
|
+
for (; read < start; read++) {
|
|
6407
|
+
if (endsLink2(text, read)) {
|
|
6408
|
+
space = read;
|
|
6409
|
+
} else if (text[read] === "/" && text[read - 1] === "/" && text[read - 2] === ":") {
|
|
6410
|
+
scheme = read;
|
|
6411
|
+
}
|
|
6412
|
+
}
|
|
6413
|
+
return scheme > space;
|
|
6414
|
+
};
|
|
6415
|
+
}
|
|
6416
|
+
function isSchemeless(text, start) {
|
|
6417
|
+
if (start < 2 || text[start - 2] !== "/") {
|
|
6418
|
+
return false;
|
|
6419
|
+
}
|
|
6420
|
+
if (start === 2) {
|
|
6421
|
+
return true;
|
|
6422
|
+
}
|
|
6423
|
+
const before = text[start - 3];
|
|
6424
|
+
return !(before === ":" || before === "/" || isHostCode2(text.codePointAt(start - 3)));
|
|
6425
|
+
}
|
|
6426
|
+
function bareName(name) {
|
|
6427
|
+
const labels = name.split(".");
|
|
6428
|
+
const tld = labels.pop();
|
|
6429
|
+
if (!/^(?:[a-z]{2,24}|xn--[a-z\d-]{1,59})$/i.test(tld)) {
|
|
6430
|
+
return null;
|
|
6431
|
+
}
|
|
6432
|
+
const names = [];
|
|
6433
|
+
while (labels.length > 0 && names.length < 11) {
|
|
6434
|
+
const label = labels.pop();
|
|
6435
|
+
if (!/^[a-z\d-]{1,63}$/i.test(label)) {
|
|
6436
|
+
break;
|
|
6437
|
+
}
|
|
6438
|
+
names.unshift(label);
|
|
6439
|
+
}
|
|
6440
|
+
if (names.length === 0) {
|
|
6441
|
+
return null;
|
|
6442
|
+
}
|
|
6443
|
+
names[0] = names[0].replace(/^-+/, "");
|
|
6444
|
+
if (!names[0]) {
|
|
6445
|
+
return null;
|
|
6446
|
+
}
|
|
6447
|
+
return `${names.join(".")}.${tld}`.toLowerCase();
|
|
6448
|
+
}
|
|
6449
|
+
function isRealName(host) {
|
|
6450
|
+
const parsed = (0, import_tldts4.parse)(host);
|
|
6451
|
+
return Boolean(parsed.isIcann && parsed.domain);
|
|
6452
|
+
}
|
|
6453
|
+
function bareHosts(text, add, { done, seen, from = 0, cutEnd = false }) {
|
|
6454
|
+
let previous = -1;
|
|
6455
|
+
const inLink = linkReader(text);
|
|
6456
|
+
for (let slash = text.indexOf("/"); slash !== -1; slash = text.indexOf("/", slash + 1)) {
|
|
6457
|
+
if (done()) {
|
|
6458
|
+
return;
|
|
6459
|
+
}
|
|
6460
|
+
const floor = Math.max(previous + 1, slash - MAX_HOST);
|
|
6461
|
+
previous = slash;
|
|
6462
|
+
let end = slash;
|
|
6463
|
+
while (end > floor && text.codePointAt(end - 1) >= 48 && text.codePointAt(end - 1) <= 57) {
|
|
6464
|
+
end--;
|
|
6465
|
+
}
|
|
6466
|
+
end = end > floor && text[end - 1] === ":" ? end - 1 : slash;
|
|
6467
|
+
let start = end;
|
|
6468
|
+
while (start > floor && isHostCode2(text.codePointAt(start - 1))) {
|
|
6469
|
+
start--;
|
|
6470
|
+
}
|
|
6471
|
+
if (start === end || start < from || cutEnd && slash === text.length - 1) {
|
|
6472
|
+
continue;
|
|
6473
|
+
}
|
|
6474
|
+
if (start > 0 && (IN_WORD2.test(text[start - 1]) || text[start - 1] === "/" && !isSchemeless(text, start)) || inLink(start)) {
|
|
6475
|
+
continue;
|
|
6476
|
+
}
|
|
6477
|
+
while (end > start && text[end - 1] === ".") {
|
|
6478
|
+
end--;
|
|
6479
|
+
}
|
|
6480
|
+
const host = bareName(text.slice(start, end));
|
|
6481
|
+
if (!host || seen.has(host)) {
|
|
6482
|
+
continue;
|
|
6483
|
+
}
|
|
6484
|
+
if (seen.size < MAX_SEEN) {
|
|
6485
|
+
seen.add(host);
|
|
6486
|
+
}
|
|
6487
|
+
if (isRealName(host)) {
|
|
6488
|
+
add(`http://${host}/`);
|
|
6489
|
+
}
|
|
6490
|
+
}
|
|
6491
|
+
}
|
|
6492
|
+
function looseHosts(text, add, { from = 0, cutEnd = false, seen, done }) {
|
|
6493
|
+
const inLink = linkReader(text);
|
|
6494
|
+
const { length } = text;
|
|
6495
|
+
let i = 0;
|
|
6496
|
+
while (i < length) {
|
|
6497
|
+
if (!isHostCode2(text.codePointAt(i))) {
|
|
6498
|
+
i++;
|
|
6499
|
+
continue;
|
|
6500
|
+
}
|
|
6501
|
+
const start = i;
|
|
6502
|
+
while (i < length && isHostCode2(text.codePointAt(i))) {
|
|
6503
|
+
i++;
|
|
6504
|
+
}
|
|
6505
|
+
let end = i;
|
|
6506
|
+
if (end - start > MAX_HOST || start < from || cutEnd && end === length) {
|
|
6507
|
+
continue;
|
|
6508
|
+
}
|
|
6509
|
+
while (end > start && text[end - 1] === ".") {
|
|
6510
|
+
end--;
|
|
6511
|
+
}
|
|
6512
|
+
const before = start > 0 ? text[start - 1] : "";
|
|
6513
|
+
const after = end < length ? text[end] : "";
|
|
6514
|
+
if (after === "/" || after === "@" || before === "@") {
|
|
6515
|
+
continue;
|
|
6516
|
+
}
|
|
6517
|
+
if (before && (IN_WORD2.test(before) || before === "/" || before === "\\" || before === "&" || before === "#")) {
|
|
6518
|
+
continue;
|
|
6519
|
+
}
|
|
6520
|
+
if (after && after !== "." && IN_WORD2.test(after)) {
|
|
6521
|
+
continue;
|
|
6522
|
+
}
|
|
6523
|
+
const name = text.slice(start, end);
|
|
6524
|
+
if (!name.includes(".") || inLink(start)) {
|
|
6525
|
+
continue;
|
|
6526
|
+
}
|
|
6527
|
+
const lower = name.toLowerCase();
|
|
6528
|
+
if (seen.has(lower)) {
|
|
6529
|
+
continue;
|
|
6530
|
+
}
|
|
6531
|
+
if (seen.size < MAX_SEEN) {
|
|
6532
|
+
seen.add(lower);
|
|
6533
|
+
}
|
|
6534
|
+
if (done()) {
|
|
6535
|
+
return;
|
|
6536
|
+
}
|
|
6537
|
+
const host = bareName(name);
|
|
6538
|
+
if (host && isRealName(host)) {
|
|
6539
|
+
add(host);
|
|
6540
|
+
}
|
|
6541
|
+
}
|
|
6542
|
+
}
|
|
6543
|
+
function* chunksOf(html2) {
|
|
6544
|
+
let start = 0;
|
|
6545
|
+
let cutStart = false;
|
|
6546
|
+
while (start < html2.length) {
|
|
6547
|
+
const end = Math.min(html2.length, start + DECODE_CHUNK);
|
|
6548
|
+
if (end < html2.length) {
|
|
6549
|
+
let cut = end;
|
|
6550
|
+
while (cut > end - 65536 && cut > start) {
|
|
6551
|
+
if (html2[cut] === "<" || isSpace(html2.codePointAt(cut))) {
|
|
6552
|
+
break;
|
|
6553
|
+
}
|
|
6554
|
+
cut--;
|
|
6555
|
+
}
|
|
6556
|
+
if (cut > start && cut > end - 65536) {
|
|
6557
|
+
yield { text: html2.slice(start, cut), cutStart, cutEnd: false };
|
|
6558
|
+
start = cut;
|
|
6559
|
+
cutStart = false;
|
|
6560
|
+
continue;
|
|
6561
|
+
}
|
|
6562
|
+
yield { text: html2.slice(start, end), cutStart, cutEnd: true };
|
|
6563
|
+
start = end - CHUNK_OVERLAP;
|
|
6564
|
+
cutStart = true;
|
|
6565
|
+
continue;
|
|
6566
|
+
}
|
|
6567
|
+
yield { text: html2.slice(start, end), cutStart, cutEnd: false };
|
|
6568
|
+
start = end;
|
|
6569
|
+
}
|
|
6570
|
+
}
|
|
6571
|
+
function withoutNul(text) {
|
|
6572
|
+
return text.includes("\0") ? `${text}
|
|
6573
|
+
${text.replaceAll("\0", "")}` : text;
|
|
6574
|
+
}
|
|
6575
|
+
function hexValue(code) {
|
|
6576
|
+
if (code >= 48 && code <= 57) {
|
|
6577
|
+
return code - 48;
|
|
6578
|
+
}
|
|
6579
|
+
if (code >= 65 && code <= 70) {
|
|
6580
|
+
return code - 55;
|
|
6581
|
+
}
|
|
6582
|
+
if (code >= 97 && code <= 102) {
|
|
6583
|
+
return code - 87;
|
|
6584
|
+
}
|
|
6585
|
+
return -1;
|
|
6586
|
+
}
|
|
6587
|
+
function percentDecoded(text) {
|
|
6588
|
+
const input = import_node_buffer7.Buffer.from(text);
|
|
6589
|
+
const output = import_node_buffer7.Buffer.allocUnsafe(input.length);
|
|
6590
|
+
let length = 0;
|
|
6591
|
+
for (let i = 0; i < input.length; i++) {
|
|
6592
|
+
const high = input[i] === 37 ? hexValue(input[i + 1]) : -1;
|
|
6593
|
+
const low = high === -1 ? -1 : hexValue(input[i + 2]);
|
|
6594
|
+
if (low === -1) {
|
|
6595
|
+
output[length++] = input[i];
|
|
6596
|
+
continue;
|
|
6597
|
+
}
|
|
6598
|
+
output[length++] = high * 16 + low;
|
|
6599
|
+
i += 2;
|
|
6600
|
+
}
|
|
6601
|
+
return output.subarray(0, length);
|
|
6602
|
+
}
|
|
6603
|
+
function swapped(bytes) {
|
|
6604
|
+
return import_node_buffer7.Buffer.from(bytes.subarray(0, bytes.length - bytes.length % 2)).swap16().toString("utf16le");
|
|
6605
|
+
}
|
|
6606
|
+
function decodeText(content, charset = "") {
|
|
6607
|
+
if (content[0] === 255 && content[1] === 254) {
|
|
6608
|
+
return content.subarray(2).toString("utf16le");
|
|
6609
|
+
}
|
|
6610
|
+
if (content[0] === 254 && content[1] === 255) {
|
|
6611
|
+
return swapped(content.subarray(2));
|
|
6612
|
+
}
|
|
6613
|
+
if (UTF16LE.has(charset)) {
|
|
6614
|
+
return content.toString("utf16le");
|
|
6615
|
+
}
|
|
6616
|
+
return UTF16BE.has(charset) ? swapped(content) : content.toString("utf8");
|
|
6617
|
+
}
|
|
6618
|
+
function dataDocument(value) {
|
|
6619
|
+
const match = DATA_DOCUMENT.exec(value.slice(0, 1024));
|
|
6620
|
+
if (!match) {
|
|
6621
|
+
return null;
|
|
6622
|
+
}
|
|
6623
|
+
const bytes = percentDecoded(value.slice(match[0].length));
|
|
6624
|
+
const content = /;\s*base64\s*$/i.test(match[1]) ? import_node_buffer7.Buffer.from(bytes.toString("latin1"), "base64") : bytes;
|
|
6625
|
+
const charset = /;\s*charset\s*=\s*"?([^;"\s]+)/i.exec(match[1]);
|
|
6626
|
+
return decodeText(content, charset ? charset[1].toLowerCase() : "");
|
|
6627
|
+
}
|
|
6628
|
+
function readEscapes(text, lenient = false) {
|
|
6629
|
+
let index = text.indexOf("\\");
|
|
6630
|
+
if (index === -1) {
|
|
6631
|
+
return text;
|
|
6632
|
+
}
|
|
6633
|
+
let out = "";
|
|
6634
|
+
let parts = [];
|
|
6635
|
+
let start = 0;
|
|
6636
|
+
while (index !== -1 && index + 1 < text.length) {
|
|
6637
|
+
const next = text[index + 1];
|
|
6638
|
+
if (lenient || "nN,;\\".includes(next)) {
|
|
6639
|
+
parts.push(text.slice(start, index), next === "n" || next === "N" ? "\n" : next);
|
|
6640
|
+
start = index + 2;
|
|
6641
|
+
index = text.indexOf("\\", start);
|
|
6642
|
+
if (parts.length >= 65536) {
|
|
6643
|
+
out += parts.join("");
|
|
6644
|
+
parts = [];
|
|
6645
|
+
}
|
|
6646
|
+
} else {
|
|
6647
|
+
index = text.indexOf("\\", index + 1);
|
|
6648
|
+
}
|
|
6649
|
+
}
|
|
6650
|
+
parts.push(text.slice(start));
|
|
6651
|
+
return out + parts.join("");
|
|
6652
|
+
}
|
|
6653
|
+
function valueColon(line) {
|
|
6654
|
+
let colon = line.indexOf(":");
|
|
6655
|
+
let from = 0;
|
|
6656
|
+
for (; ; ) {
|
|
6657
|
+
const quote = line.indexOf('"', from);
|
|
6658
|
+
if (quote === -1 || colon === -1 || colon < quote) {
|
|
6659
|
+
return colon;
|
|
6660
|
+
}
|
|
6661
|
+
const end = line.indexOf('"', quote + 1);
|
|
6662
|
+
if (end === -1) {
|
|
6663
|
+
return -1;
|
|
6664
|
+
}
|
|
6665
|
+
from = end + 1;
|
|
6666
|
+
if (colon < from) {
|
|
6667
|
+
colon = line.indexOf(":", from);
|
|
6668
|
+
}
|
|
6669
|
+
}
|
|
6670
|
+
}
|
|
6671
|
+
function trimSpaceEnd(text) {
|
|
6672
|
+
let end = text.length;
|
|
6673
|
+
while (end > 0 && (text[end - 1] === " " || text[end - 1] === " ")) {
|
|
6674
|
+
end--;
|
|
6675
|
+
}
|
|
6676
|
+
return end === text.length ? text : text.slice(0, end);
|
|
6677
|
+
}
|
|
6678
|
+
function decodeQuotedPrintable(value, charset) {
|
|
6679
|
+
let decoder;
|
|
6680
|
+
try {
|
|
6681
|
+
decoder = new TextDecoder(charset || "utf8");
|
|
6682
|
+
} catch {
|
|
6683
|
+
decoder = new TextDecoder("utf8");
|
|
6684
|
+
}
|
|
6685
|
+
if (!/[\u0080-\u{10FFFF}]/u.test(value)) {
|
|
6686
|
+
const bytes = import_node_buffer7.Buffer.from(value, "latin1");
|
|
6687
|
+
let length = 0;
|
|
6688
|
+
for (let index = 0; index < bytes.length; index++) {
|
|
6689
|
+
const hex = bytes[index] === 61 ? value.slice(index + 1, index + 3) : "";
|
|
6690
|
+
if (/^[\da-f]{2}$/i.test(hex)) {
|
|
6691
|
+
bytes[length++] = Number.parseInt(hex, 16);
|
|
6692
|
+
index += 2;
|
|
6693
|
+
} else {
|
|
6694
|
+
bytes[length++] = bytes[index];
|
|
6695
|
+
}
|
|
6696
|
+
}
|
|
6697
|
+
return decoder.decode(bytes.subarray(0, length));
|
|
6698
|
+
}
|
|
6699
|
+
return value.replaceAll(/(?:=[\da-f]{2})+/gi, (run) => decoder.decode(import_node_buffer7.Buffer.from(run.replaceAll("=", ""), "hex")));
|
|
6700
|
+
}
|
|
6701
|
+
function quotedPrintableValues(text) {
|
|
6702
|
+
if (!/quoted-printable/i.test(text)) {
|
|
6703
|
+
return text;
|
|
6704
|
+
}
|
|
6705
|
+
const lines2 = text.split(LINE_BREAK);
|
|
6706
|
+
const out = [];
|
|
6707
|
+
for (let i = 0; i < lines2.length; i++) {
|
|
6708
|
+
const line = lines2[i];
|
|
6709
|
+
const colon = valueColon(line);
|
|
6710
|
+
const parameters = colon === -1 ? "" : line.slice(0, colon);
|
|
6711
|
+
if (colon === -1 || !QUOTED_PRINTABLE.test(parameters)) {
|
|
6712
|
+
out.push(line);
|
|
6713
|
+
continue;
|
|
6714
|
+
}
|
|
6715
|
+
const charset = /;\s*charset\s*=\s*"?([\w.:-]+)/i.exec(parameters)?.[1];
|
|
6716
|
+
const parts = [trimSpaceEnd(line.slice(colon + 1))];
|
|
6717
|
+
while (parts.at(-1).endsWith("=") && i + 1 < lines2.length) {
|
|
6718
|
+
parts[parts.length - 1] = parts.at(-1).slice(0, -1);
|
|
6719
|
+
parts.push(trimSpaceEnd(lines2[++i]));
|
|
6720
|
+
}
|
|
6721
|
+
out.push(line.slice(0, colon + 1) + decodeQuotedPrintable(parts.join(""), charset));
|
|
6722
|
+
}
|
|
6723
|
+
return out.join("\n");
|
|
6724
|
+
}
|
|
6725
|
+
function hasQuotedPrintable(text) {
|
|
6726
|
+
const unfolded = text.replaceAll(FOLD, "");
|
|
6727
|
+
if (!/quoted-printable/i.test(unfolded)) {
|
|
6728
|
+
return false;
|
|
6729
|
+
}
|
|
6730
|
+
return unfolded.split(LINE_BREAK).some((line) => {
|
|
6731
|
+
const colon = valueColon(line);
|
|
6732
|
+
return colon !== -1 && QUOTED_PRINTABLE.test(line.slice(0, colon));
|
|
6733
|
+
});
|
|
6734
|
+
}
|
|
6735
|
+
function shownText(text, full = true) {
|
|
6736
|
+
const unfolded = text.replaceAll(FOLD, "");
|
|
6737
|
+
const shown = /* @__PURE__ */ new Set([text, readEscapes(unfolded)]);
|
|
6738
|
+
let decoded = unfolded;
|
|
6739
|
+
if (full) {
|
|
6740
|
+
decoded = quotedPrintableValues(unfolded);
|
|
6741
|
+
if (decoded !== unfolded) {
|
|
6742
|
+
shown.add(readEscapes(decoded));
|
|
6743
|
+
if (unfolded !== text) {
|
|
6744
|
+
shown.add(quotedPrintableValues(text));
|
|
6745
|
+
}
|
|
6746
|
+
}
|
|
6747
|
+
}
|
|
6748
|
+
if (/\\[^nN,;\\]/.test(decoded)) {
|
|
6749
|
+
shown.add(readEscapes(decoded, true));
|
|
6750
|
+
}
|
|
6751
|
+
return [...shown].reverse().join("\n");
|
|
6752
|
+
}
|
|
6753
|
+
function htmlDescriptions(text) {
|
|
6754
|
+
if (!/[<&]|altrep/i.test(text)) {
|
|
6755
|
+
return "";
|
|
6756
|
+
}
|
|
6757
|
+
const html2 = [];
|
|
6758
|
+
for (const line of text.replaceAll(FOLD, "").split(LINE_BREAK)) {
|
|
6759
|
+
const colon = valueColon(line);
|
|
6760
|
+
if (colon === -1) {
|
|
6761
|
+
continue;
|
|
6762
|
+
}
|
|
6763
|
+
const altrep = /;\s*altrep\s*=\s*"([^"]*)"/i.exec(line.slice(0, colon))?.[1];
|
|
6764
|
+
if (altrep) {
|
|
6765
|
+
html2.push(`<iframe src="${altrep.replaceAll("&", "&").replaceAll('"', """).replaceAll("<", "<")}"></iframe>`);
|
|
6766
|
+
}
|
|
6767
|
+
if (!HTML_PROPERTIES.test(line)) {
|
|
6768
|
+
continue;
|
|
6769
|
+
}
|
|
6770
|
+
const value = readEscapes(line.slice(colon + 1));
|
|
6771
|
+
if (/[<&]/.test(value)) {
|
|
6772
|
+
html2.push(value);
|
|
6773
|
+
}
|
|
6774
|
+
}
|
|
6775
|
+
return html2.join("\n");
|
|
6776
|
+
}
|
|
6777
|
+
function withoutBinaryValues(text) {
|
|
6778
|
+
if (!/base64|binary|encoding\s*=\s*"?b|;\s*b\s*[;:]/i.test(text)) {
|
|
6779
|
+
return text;
|
|
6780
|
+
}
|
|
6781
|
+
const lines2 = text.split(LINE_BREAK);
|
|
6782
|
+
const out = [];
|
|
6783
|
+
for (let i = 0; i < lines2.length; i++) {
|
|
6784
|
+
const line = lines2[i];
|
|
6785
|
+
const colon = valueColon(line);
|
|
6786
|
+
if (colon === -1 || !BINARY.test(line.slice(0, colon))) {
|
|
6787
|
+
out.push(line);
|
|
6788
|
+
continue;
|
|
6789
|
+
}
|
|
6790
|
+
const value = [line.slice(colon + 1)];
|
|
6791
|
+
let next = i + 1;
|
|
6792
|
+
while (next < lines2.length && (lines2[next].startsWith(" ") || lines2[next].startsWith(" "))) {
|
|
6793
|
+
value.push(lines2[next++]);
|
|
6794
|
+
}
|
|
6795
|
+
if (!value.every((part) => /^[\w+/=\s]*$/.test(part))) {
|
|
6796
|
+
for (let index = i; index < next; index++) {
|
|
6797
|
+
out.push(lines2[index]);
|
|
6798
|
+
}
|
|
6799
|
+
i = next - 1;
|
|
6800
|
+
continue;
|
|
6801
|
+
}
|
|
6802
|
+
while (next < lines2.length && lines2[next] !== "" && /^[\w+/=]+$/.test(lines2[next])) {
|
|
6803
|
+
value.push(lines2[next++]);
|
|
6804
|
+
}
|
|
6805
|
+
if (next < lines2.length && lines2[next] === "") {
|
|
6806
|
+
next++;
|
|
6807
|
+
}
|
|
6808
|
+
i = next - 1;
|
|
6809
|
+
const name = line.slice(0, colon).split(";")[0].split(".").pop().trim().toLowerCase();
|
|
6810
|
+
out.push(MEDIA_PROPERTIES.has(name) ? line.slice(0, colon + 1) : line.slice(0, colon + 1) + import_node_buffer7.Buffer.from(value.join("").replaceAll(/\s/g, ""), "base64").toString("utf8"));
|
|
6811
|
+
}
|
|
6812
|
+
return out.join("\n");
|
|
6813
|
+
}
|
|
6814
|
+
function extensionOf2(filename) {
|
|
6815
|
+
let end = filename.length;
|
|
6816
|
+
while (end > 0 && (filename[end - 1] === "." || filename[end - 1] === " ")) {
|
|
6817
|
+
end--;
|
|
6818
|
+
}
|
|
6819
|
+
const name = filename.slice(0, end).trim().toLowerCase();
|
|
6820
|
+
const index = name.lastIndexOf(".");
|
|
6821
|
+
return index !== -1 && index < name.length - 1 ? name.slice(index + 1) : null;
|
|
6822
|
+
}
|
|
6823
|
+
function extensionsOf(attachment) {
|
|
6824
|
+
const names = [];
|
|
6825
|
+
if (typeof attachment.filename === "string") {
|
|
6826
|
+
names.push(attachment.filename);
|
|
6827
|
+
}
|
|
6828
|
+
const { headers } = attachment;
|
|
6829
|
+
if (headers && typeof headers.get === "function") {
|
|
6830
|
+
for (const [field, parameter] of [["content-type", "name"], ["content-disposition", "filename"]]) {
|
|
6831
|
+
const value = headers.get(field)?.params?.[parameter];
|
|
6832
|
+
if (typeof value === "string" && value !== "") {
|
|
6833
|
+
names.push(value);
|
|
6834
|
+
}
|
|
6835
|
+
}
|
|
6836
|
+
}
|
|
6837
|
+
return new Set(names.flatMap((name) => [extensionOf2(name), extensionOf(name)]).filter(Boolean));
|
|
6838
|
+
}
|
|
6839
|
+
function charsetOf(attachment) {
|
|
6840
|
+
const { headers } = attachment;
|
|
6841
|
+
const charset = headers && typeof headers.get === "function" ? headers.get("content-type")?.params?.charset : null;
|
|
6842
|
+
return typeof charset === "string" ? charset.toLowerCase() : "";
|
|
6843
|
+
}
|
|
6844
|
+
function documentsOf(attachments, until) {
|
|
6845
|
+
const documents = [];
|
|
6846
|
+
let bytes = 0;
|
|
6847
|
+
let opened = 0;
|
|
6848
|
+
for (const attachment of attachments) {
|
|
6849
|
+
const { content } = attachment ?? {};
|
|
6850
|
+
if (!import_node_buffer7.Buffer.isBuffer(content) || content.length === 0) {
|
|
6851
|
+
continue;
|
|
6852
|
+
}
|
|
6853
|
+
const type = typeof attachment.contentType === "string" ? attachment.contentType.toLowerCase() : "";
|
|
6854
|
+
const extensions = extensionsOf(attachment);
|
|
6855
|
+
const has = (set) => [...extensions].some((name) => set.has(name));
|
|
6856
|
+
if (MESSAGE_TYPES.has(type) || extensions.has("eml") || extensions.has("u8msg")) {
|
|
6857
|
+
continue;
|
|
6858
|
+
}
|
|
6859
|
+
const isHtml = HTML_TYPES.has(type) || has(HTML_EXTENSIONS);
|
|
6860
|
+
const isCard = !isHtml && (CARD_TYPES.has(type) || has(CARD_EXTENSIONS));
|
|
6861
|
+
const isText = isCard || !isHtml && type === "text/plain";
|
|
6862
|
+
if (!isHtml && !isText) {
|
|
6863
|
+
continue;
|
|
6864
|
+
}
|
|
6865
|
+
if (!isText && ++opened > MAX_ATTACHED || bytes + content.length > MAX_ATTACHED_BYTES) {
|
|
6866
|
+
documents.tooComplex = true;
|
|
6867
|
+
return documents;
|
|
6868
|
+
}
|
|
6869
|
+
if (Date.now() > until) {
|
|
6870
|
+
documents.incomplete = true;
|
|
6871
|
+
return documents;
|
|
6872
|
+
}
|
|
6873
|
+
bytes += content.length;
|
|
6874
|
+
const text = decodeText(content, charsetOf(attachment));
|
|
6875
|
+
if (isHtml) {
|
|
6876
|
+
documents.push({ html: text });
|
|
6877
|
+
continue;
|
|
6878
|
+
}
|
|
6879
|
+
if (!isCard) {
|
|
6880
|
+
documents.push({ text });
|
|
6881
|
+
continue;
|
|
6882
|
+
}
|
|
6883
|
+
const readable = withoutBinaryValues(text);
|
|
6884
|
+
const full = readable.length <= MAX_SHOWN_BYTES;
|
|
6885
|
+
if (!full && hasQuotedPrintable(readable)) {
|
|
6886
|
+
documents.tooComplex = true;
|
|
6887
|
+
continue;
|
|
6888
|
+
}
|
|
6889
|
+
documents.push({ text: shownText(readable, full) });
|
|
6890
|
+
const html2 = htmlDescriptions(readable);
|
|
6891
|
+
if (html2 !== "") {
|
|
6892
|
+
documents.push({ html: html2 });
|
|
6893
|
+
}
|
|
6894
|
+
}
|
|
6895
|
+
return documents;
|
|
6896
|
+
}
|
|
6897
|
+
function carriedLinkHosts(mail, {
|
|
6898
|
+
mails = [],
|
|
6899
|
+
attachments = [],
|
|
6900
|
+
maxHosts = 250,
|
|
6901
|
+
hostsInText = false
|
|
6902
|
+
} = {}) {
|
|
6903
|
+
const hosts = /* @__PURE__ */ new Set();
|
|
6904
|
+
const loose = /* @__PURE__ */ new Set();
|
|
6905
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6906
|
+
const seenBare = /* @__PURE__ */ new Set();
|
|
6907
|
+
const seenLoose = /* @__PURE__ */ new Set();
|
|
6908
|
+
let more = false;
|
|
6909
|
+
let tooComplex = false;
|
|
6910
|
+
const done = () => more;
|
|
6911
|
+
const looseDone = () => more || loose.size > maxHosts;
|
|
6912
|
+
const addLoose = (host) => {
|
|
6913
|
+
if (!looseDone()) {
|
|
6914
|
+
loose.add(host);
|
|
6915
|
+
}
|
|
6916
|
+
};
|
|
6917
|
+
const until = Date.now() + MAX_READ_TIME;
|
|
6918
|
+
let incomplete = false;
|
|
6919
|
+
const late = () => {
|
|
6920
|
+
if (!incomplete && Date.now() > until) {
|
|
6921
|
+
incomplete = true;
|
|
6922
|
+
}
|
|
6923
|
+
return incomplete;
|
|
6924
|
+
};
|
|
6925
|
+
const carried = documentsOf(attachments, until);
|
|
6926
|
+
tooComplex = Boolean(carried.tooComplex);
|
|
6927
|
+
incomplete = Boolean(carried.incomplete);
|
|
6928
|
+
const queue = [mail, ...mails, ...carried].map((document) => ({ document, depth: 0 }));
|
|
6929
|
+
let depth = 0;
|
|
6930
|
+
let embedded = 0;
|
|
6931
|
+
let embeddedLength = 0;
|
|
6932
|
+
const embed = (html2) => {
|
|
6933
|
+
if (depth >= MAX_EMBED_DEPTH || embedded >= MAX_EMBEDDED || embeddedLength + html2.length > MAX_EMBEDDED_LENGTH) {
|
|
6934
|
+
tooComplex = true;
|
|
6935
|
+
return;
|
|
6936
|
+
}
|
|
6937
|
+
embedded++;
|
|
6938
|
+
embeddedLength += html2.length;
|
|
6939
|
+
queue.push({ document: { html: html2 }, depth: depth + 1 });
|
|
6940
|
+
};
|
|
6941
|
+
const add = (value) => {
|
|
6942
|
+
if (more || typeof value !== "string" || value === "" || seen.has(value)) {
|
|
6943
|
+
return;
|
|
6944
|
+
}
|
|
6945
|
+
if (seen.size < MAX_SEEN) {
|
|
6946
|
+
seen.add(value);
|
|
6947
|
+
}
|
|
6948
|
+
if (/^\s*data:/i.test(value)) {
|
|
6949
|
+
const html2 = dataDocument(value);
|
|
6950
|
+
if (html2 !== null) {
|
|
6951
|
+
embed(html2);
|
|
6952
|
+
}
|
|
6953
|
+
return;
|
|
6954
|
+
}
|
|
6955
|
+
const found = hostsOf(value);
|
|
6956
|
+
if (found.unresolved) {
|
|
6957
|
+
tooComplex = true;
|
|
6958
|
+
}
|
|
6959
|
+
for (const host of found) {
|
|
6960
|
+
if (hosts.has(host)) {
|
|
6961
|
+
continue;
|
|
6962
|
+
}
|
|
6963
|
+
if (hosts.size >= maxHosts) {
|
|
6964
|
+
more = true;
|
|
6965
|
+
return;
|
|
6966
|
+
}
|
|
6967
|
+
hosts.add(host);
|
|
6968
|
+
}
|
|
6969
|
+
};
|
|
6970
|
+
const readText = (source, { cutStart = false, cutEnd = false } = {}) => {
|
|
6971
|
+
for (const match of source.matchAll(URL_START)) {
|
|
6972
|
+
if (more) {
|
|
6973
|
+
break;
|
|
6974
|
+
}
|
|
6975
|
+
if (cutStart && match.index === 0) {
|
|
6976
|
+
continue;
|
|
6977
|
+
}
|
|
6978
|
+
if (cutEnd && match.index + match[0].length === source.length) {
|
|
6979
|
+
const value = match[0];
|
|
6980
|
+
const at = /^www\./i.test(value) ? 0 : value.indexOf("//") + 2;
|
|
6981
|
+
if (/[/?#\\]/.test(value.slice(at))) {
|
|
6982
|
+
add(value);
|
|
6983
|
+
} else if (source.length - match.index > CHUNK_OVERLAP) {
|
|
6984
|
+
tooComplex = true;
|
|
6985
|
+
}
|
|
6986
|
+
continue;
|
|
6987
|
+
}
|
|
6988
|
+
add(match[0]);
|
|
6989
|
+
}
|
|
6990
|
+
const from = cutStart ? 1 : 0;
|
|
6991
|
+
bareHosts(source, add, {
|
|
6992
|
+
done,
|
|
6993
|
+
seen: seenBare,
|
|
6994
|
+
from,
|
|
6995
|
+
cutEnd
|
|
6996
|
+
});
|
|
6997
|
+
if (hostsInText && !looseDone()) {
|
|
6998
|
+
looseHosts(source, addLoose, {
|
|
6999
|
+
from,
|
|
7000
|
+
cutEnd,
|
|
7001
|
+
seen: seenLoose,
|
|
7002
|
+
done: looseDone
|
|
7003
|
+
});
|
|
7004
|
+
}
|
|
7005
|
+
};
|
|
7006
|
+
for (const element of queue) {
|
|
7007
|
+
if (more || late()) {
|
|
7008
|
+
break;
|
|
7009
|
+
}
|
|
7010
|
+
({ depth } = element);
|
|
7011
|
+
const { document } = element;
|
|
7012
|
+
const html2 = withoutNul(typeof document?.html === "string" ? document.html : "");
|
|
7013
|
+
const text = withoutNul(typeof document?.text === "string" ? document.text : "");
|
|
7014
|
+
for (const [name, value] of attributesOf(html2)) {
|
|
7015
|
+
if (more) {
|
|
7016
|
+
break;
|
|
7017
|
+
}
|
|
7018
|
+
if (LINK_ATTRIBUTES.has(name)) {
|
|
7019
|
+
linksOf(name, value, add, embed);
|
|
7020
|
+
}
|
|
7021
|
+
}
|
|
7022
|
+
lenientLinks(html2, add, done, embed);
|
|
7023
|
+
for (const pattern of [CSS_URL, CSS_IMPORT]) {
|
|
7024
|
+
for (const [, link] of html2.matchAll(pattern)) {
|
|
7025
|
+
if (more) {
|
|
7026
|
+
break;
|
|
7027
|
+
}
|
|
7028
|
+
add(decodeEntities(link, { attribute: true }));
|
|
7029
|
+
}
|
|
7030
|
+
}
|
|
7031
|
+
if (!more) {
|
|
7032
|
+
readText(text);
|
|
7033
|
+
}
|
|
7034
|
+
for (const chunk2 of chunksOf(html2)) {
|
|
7035
|
+
if (more || late()) {
|
|
7036
|
+
break;
|
|
7037
|
+
}
|
|
7038
|
+
readText(decodeEntities(chunk2.text), chunk2);
|
|
7039
|
+
}
|
|
7040
|
+
}
|
|
7041
|
+
if (!more && !incomplete) {
|
|
7042
|
+
for (const name of loose) {
|
|
7043
|
+
if (hosts.size >= maxHosts) {
|
|
7044
|
+
break;
|
|
7045
|
+
}
|
|
7046
|
+
const [host] = hostsOf(`http://${name}/`);
|
|
7047
|
+
if (host) {
|
|
7048
|
+
hosts.add(host);
|
|
7049
|
+
}
|
|
7050
|
+
}
|
|
7051
|
+
}
|
|
7052
|
+
return {
|
|
7053
|
+
hosts: [...hosts],
|
|
7054
|
+
more,
|
|
7055
|
+
tooComplex,
|
|
7056
|
+
incomplete
|
|
7057
|
+
};
|
|
7058
|
+
}
|
|
7059
|
+
var import_node_buffer7, import_node_net4, import_tldts4, LINK_ATTRIBUTES, TAG_START, URL_START, CSS_URL, CSS_IMPORT, LENIENT, IN_WORD2, NAMESPACES, MAX_HOST, MAX_SEEN, TRAILING, DECODE_CHUNK, CHUNK_OVERLAP, MAX_EMBED_DEPTH, MAX_EMBEDDED, MAX_EMBEDDED_LENGTH, MAX_ATTACHED, MAX_ATTACHED_BYTES, MAX_READ_TIME, MAX_SHOWN_BYTES, MAX_LENIENT_VALUE, UNQUOTED_END, UTF16LE, UTF16BE, DATA_DOCUMENT, LINE_BREAK, FOLD, QUOTED_PRINTABLE, MEDIA_PROPERTIES, HTML_PROPERTIES, BINARY, HTML_TYPES, HTML_EXTENSIONS, CARD_TYPES, CARD_EXTENSIONS, MESSAGE_TYPES;
|
|
7060
|
+
var init_links = __esm({
|
|
7061
|
+
"src/links.js"() {
|
|
7062
|
+
import_node_buffer7 = require("node:buffer");
|
|
7063
|
+
import_node_net4 = require("node:net");
|
|
7064
|
+
import_tldts4 = require("tldts");
|
|
7065
|
+
init_attachments();
|
|
7066
|
+
init_dnsbl();
|
|
7067
|
+
init_html();
|
|
7068
|
+
init_tokenizer();
|
|
7069
|
+
LINK_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
7070
|
+
"href",
|
|
7071
|
+
"src",
|
|
7072
|
+
"srcset",
|
|
7073
|
+
"background",
|
|
7074
|
+
"action",
|
|
7075
|
+
"formaction",
|
|
7076
|
+
"poster",
|
|
7077
|
+
"cite",
|
|
7078
|
+
"longdesc",
|
|
7079
|
+
"xlink:href",
|
|
7080
|
+
"style",
|
|
7081
|
+
"data",
|
|
7082
|
+
"ping",
|
|
7083
|
+
// (of a <meta> refresh: "0;url=https://example.com/")
|
|
7084
|
+
"content",
|
|
7085
|
+
// (a document of its own, see linksOf)
|
|
7086
|
+
"srcdoc"
|
|
7087
|
+
]);
|
|
7088
|
+
TAG_START = /<[a-z][^\s/>]*/gi;
|
|
7089
|
+
URL_START = /\b(?:https?:\/\/|www\.)[^\s<>"'`]+/gi;
|
|
7090
|
+
CSS_URL = /url\(\s*["']?([^()"']*)/gi;
|
|
7091
|
+
CSS_IMPORT = /@import\s+["']([^"'<>]*)/gi;
|
|
7092
|
+
LENIENT = /[\s"'/<](href|src|srcset|background|action|formaction|poster|cite|longdesc|xlink:href|style|data|ping|content|srcdoc)\s*=\s*/gi;
|
|
7093
|
+
IN_WORD2 = /[\p{L}\p{N}\p{M}_%]/u;
|
|
7094
|
+
NAMESPACES = /* @__PURE__ */ new Set(["www.w3.org", "w3.org"]);
|
|
7095
|
+
MAX_HOST = 760;
|
|
7096
|
+
MAX_SEEN = 1e5;
|
|
7097
|
+
TRAILING = /* @__PURE__ */ new Set([")", ".", ",", ";", ":", "!", "?", "'", '"', "]"]);
|
|
7098
|
+
DECODE_CHUNK = 1024 * 1024;
|
|
7099
|
+
CHUNK_OVERLAP = 4096;
|
|
7100
|
+
MAX_EMBED_DEPTH = 3;
|
|
7101
|
+
MAX_EMBEDDED = 1e3;
|
|
7102
|
+
MAX_EMBEDDED_LENGTH = 10 * 1024 * 1024;
|
|
7103
|
+
MAX_ATTACHED = 100;
|
|
7104
|
+
MAX_ATTACHED_BYTES = 50 * 1024 * 1024;
|
|
7105
|
+
MAX_READ_TIME = 5e3;
|
|
7106
|
+
MAX_SHOWN_BYTES = 4 * 1024 * 1024;
|
|
7107
|
+
MAX_LENIENT_VALUE = 4096;
|
|
7108
|
+
UNQUOTED_END = /* @__PURE__ */ new Set(["<", ">", '"', "'", "`", "="]);
|
|
7109
|
+
UTF16LE = /* @__PURE__ */ new Set(["csunicode", "iso-10646-ucs-2", "ucs-2", "unicode", "unicodefeff", "utf-16", "utf-16le"]);
|
|
7110
|
+
UTF16BE = /* @__PURE__ */ new Set(["unicodefffe", "utf-16be"]);
|
|
7111
|
+
DATA_DOCUMENT = /^\s*data:\s*(?:text\/html|application\/xhtml\+xml|image\/svg\+xml|text\/xml|application\/xml)\b([^,]*),/i;
|
|
7112
|
+
LINE_BREAK = /\r\n?|\n/;
|
|
7113
|
+
FOLD = /(?:\r\n?|\n)[ \t]/g;
|
|
7114
|
+
QUOTED_PRINTABLE = /;\s*(?:encoding\s*=\s*)?"?quoted-printable"?\s*(?:;|$)/i;
|
|
7115
|
+
MEDIA_PROPERTIES = /* @__PURE__ */ new Set(["photo", "logo", "sound", "key", "attach"]);
|
|
7116
|
+
HTML_PROPERTIES = /^(?:x-alt-desc|styled-description|description|comment)[;:]/i;
|
|
7117
|
+
BINARY = /;\s*(?:(?:encoding\s*=\s*)?"?(?:b|base64)"?|value\s*=\s*"?binary"?)\s*(?:;|$)/i;
|
|
7118
|
+
HTML_TYPES = /* @__PURE__ */ new Set(["text/html", "application/xhtml+xml", "image/svg+xml", "text/xml", "application/xml"]);
|
|
7119
|
+
HTML_EXTENSIONS = /* @__PURE__ */ new Set(["html", "htm", "shtml", "xhtml", "xht", "svg", "xml"]);
|
|
7120
|
+
CARD_TYPES = /* @__PURE__ */ new Set(["text/calendar", "text/x-vcalendar", "application/ics", "text/vcard", "text/x-vcard", "text/directory"]);
|
|
7121
|
+
CARD_EXTENSIONS = /* @__PURE__ */ new Set(["ics", "ical", "ifb", "vcs", "vcf", "vcard"]);
|
|
7122
|
+
MESSAGE_TYPES = /* @__PURE__ */ new Set(["message/rfc822", "message/global"]);
|
|
7123
|
+
}
|
|
7124
|
+
});
|
|
7125
|
+
|
|
6018
7126
|
// src/is-arbitrary.js
|
|
6019
7127
|
function unquoted(text) {
|
|
6020
7128
|
let start = 0;
|
|
@@ -6079,13 +7187,13 @@ function joinsDisplay(brand, display, name) {
|
|
|
6079
7187
|
return false;
|
|
6080
7188
|
}
|
|
6081
7189
|
function isOfficial({ brand, official }, domain, display, shared = true) {
|
|
6082
|
-
const parsed = (0,
|
|
7190
|
+
const parsed = (0, import_tldts5.parse)(domain);
|
|
6083
7191
|
const name = parsed.domainWithoutSuffix ?? "";
|
|
6084
7192
|
const compact = brand.replaceAll(" ", "");
|
|
6085
7193
|
if (parsed.publicSuffix === compact || compact.length >= 5 && joinsDisplay(brand, display, name) && !JOINED_WORDS.some((word) => name.slice(compact.length).includes(word))) {
|
|
6086
7194
|
return true;
|
|
6087
7195
|
}
|
|
6088
|
-
return official.some((entry) => entry instanceof RegExp ? entry.test(registrableDomain(domain)) : entry.includes(".") ? (shared || (0,
|
|
7196
|
+
return official.some((entry) => entry instanceof RegExp ? entry.test(registrableDomain(domain)) : entry.includes(".") ? (shared || (0, import_tldts5.parse)(entry).domain !== null) && (domain === entry || domain.endsWith(`.${entry}`)) : name === entry);
|
|
6089
7197
|
}
|
|
6090
7198
|
function headerString(mail, name) {
|
|
6091
7199
|
const value = mail.headers?.get?.(name);
|
|
@@ -6187,7 +7295,7 @@ ${withoutHelp(markup)}`) || isInjection(readable) || attributeText(markup).some(
|
|
|
6187
7295
|
}
|
|
6188
7296
|
} else if (claimed && isWholeName(name, claimed)) {
|
|
6189
7297
|
const domain = claimed[1];
|
|
6190
|
-
const brand = MAILBOXES.has((0,
|
|
7298
|
+
const brand = MAILBOXES.has((0, import_tldts5.parse)(domain).domainWithoutSuffix) ? null : DISPLAY_BRANDS.find((entry) => isOfficial(entry, domain, "", false) && !isOfficial(entry, session.originalFromAddressDomain, ""));
|
|
6191
7299
|
if (brand) {
|
|
6192
7300
|
hit("FROM_NAME_BRAND", 2, `Display name is an address of "${brand.brand}" but the message is from ${fromRoot}`, "PHISHING");
|
|
6193
7301
|
}
|
|
@@ -6220,10 +7328,10 @@ ${withoutHelp(markup)}`) || isInjection(readable) || attributeText(markup).some(
|
|
|
6220
7328
|
category
|
|
6221
7329
|
};
|
|
6222
7330
|
}
|
|
6223
|
-
var
|
|
7331
|
+
var import_tldts5, GTUBE, BLOCKED_SUBJECT, HACKED_SUBJECT, COIN, CODE, CURRENCY, MONEY, CRYPTOCURRENCY, AMOUNT_DEMAND, AMOUNT_GIVEN, HARM_VERB, HARMED, RECORDING, THREAT, HOURS, COUNT, DEADLINE, isPaymentDemand, BITCOIN_ADDRESS, IGNORE_INSTRUCTIONS, AI_ACTION, AI_OBJECT, AI_ACTION_OBJECT, AI_NEAR, VERDICT, VERDICT_WORD, VERDICT_ORDER, VERDICT_CLAIM, CLASSIFY, SYSTEM_PROMPT, YOU_ARE, QUOTE, CONDITION, DISCUSSED, DISCUSSED_SHOWN, DISCUSSED_NEAR, isDiscussed, isInjection, QUOTE_OR_SPACE, SHOWN_NEAR, isOrder, PAYPAL_DOMAIN, PAYPAL_SPAM_TYPE_IDS, PAYPAL_OWN_REQUEST, PAYPAL_INVOICE_SUBJECT, MS_SPAM_VERDICT, MS_SPAM_CATEGORY, APPLE_NEXT, APPLE_FILLER, APPLE_STRONG, APPLE_BUSINESS, APPLE_ALONE, APPLE_BESIDE, APPLE_PART, NEXT_WORD, MAX_AFTER, APPLE, DISPLAY_BRANDS, ADDRESSES, LIST_HOSTS, VIA_LIST, MAILBOXES, BEFORE_ADDRESS, AFTER_ADDRESS, isWholeName, JOINED_WORDS, MAX_DISPLAY;
|
|
6224
7332
|
var init_is_arbitrary = __esm({
|
|
6225
7333
|
"src/is-arbitrary.js"() {
|
|
6226
|
-
|
|
7334
|
+
import_tldts5 = require("tldts");
|
|
6227
7335
|
init_homograph();
|
|
6228
7336
|
init_html();
|
|
6229
7337
|
init_linear();
|
|
@@ -6474,7 +7582,7 @@ function authHeaders(config) {
|
|
|
6474
7582
|
case "basic": {
|
|
6475
7583
|
const user = config.username ?? "";
|
|
6476
7584
|
const pass = config.password ?? config.apiKey ?? "";
|
|
6477
|
-
headers.authorization = `Basic ${
|
|
7585
|
+
headers.authorization = `Basic ${import_node_buffer8.Buffer.from(`${user}:${pass}`).toString("base64")}`;
|
|
6478
7586
|
break;
|
|
6479
7587
|
}
|
|
6480
7588
|
case "x-api-key": {
|
|
@@ -6921,10 +8029,10 @@ function replyText(api, reply2) {
|
|
|
6921
8029
|
}
|
|
6922
8030
|
return reply2?.choices?.[0]?.message?.content || null;
|
|
6923
8031
|
}
|
|
6924
|
-
var
|
|
8032
|
+
var import_node_buffer8, import_node_crypto2, import_node_os, import_node_process, PROVIDERS, DECISION_APIS, TOP_LOGPROBS, VERDICTS, VERDICT_CRITERIA, SIGNS, GUIDE, DEFAULT_SYSTEM_PROMPT, DECISION_SYSTEM_PROMPT, DECISION_INSTRUCTIONS, LOCALHOST, PRIVATE_HOST, REDACTIONS, THINK_OPEN, THINK_CLOSE, ANSWER_FIRST, LOCAL_CHARACTER, BREAKS2, VERDICT_WORD2, NOT, DENIED, JOINED, SPAM_LABEL, HAM_WORDS, HAM_LABEL, NOT_HAM_LABEL, UNWANTED, MIN_VERDICT_MASS, percent, MODES, LLMClassifier;
|
|
6925
8033
|
var init_llm = __esm({
|
|
6926
8034
|
"src/llm.js"() {
|
|
6927
|
-
|
|
8035
|
+
import_node_buffer8 = require("node:buffer");
|
|
6928
8036
|
import_node_crypto2 = require("node:crypto");
|
|
6929
8037
|
import_node_os = __toESM(require("node:os"), 1);
|
|
6930
8038
|
import_node_process = __toESM(require("node:process"), 1);
|
|
@@ -7676,7 +8784,7 @@ var init_package = __esm({
|
|
|
7676
8784
|
package_default = {
|
|
7677
8785
|
name: "spamscanner",
|
|
7678
8786
|
description: "Spam, phishing and malware filter for email in any language: a trainable classifier, link and attachment checks, SPF/DKIM/DMARC, and an optional AI second opinion from any LLM, including local Ollama models. Works as a library, CLI, Postfix milter or HTTP API.",
|
|
7679
|
-
version: "7.0.
|
|
8787
|
+
version: "7.0.11",
|
|
7680
8788
|
author: "Forward Email (https://forwardemail.net)",
|
|
7681
8789
|
bin: {
|
|
7682
8790
|
spamscanner: "./dist/esm/cli.js"
|
|
@@ -7865,10 +8973,10 @@ function splitMessage(raw) {
|
|
|
7865
8973
|
const match = /^\r?\n|\r?\n\r?\n/.exec(text);
|
|
7866
8974
|
if (!match) {
|
|
7867
8975
|
const newline2 = text.includes("\n") && !text.includes("\r\n") ? "\n" : "\r\n";
|
|
7868
|
-
return { header: text.replace(/\r?\n$/, ""), body:
|
|
8976
|
+
return { header: text.replace(/\r?\n$/, ""), body: import_node_buffer9.Buffer.alloc(0), newline: newline2 };
|
|
7869
8977
|
}
|
|
7870
8978
|
const newline = match[0].startsWith("\r") ? "\r\n" : "\n";
|
|
7871
|
-
return { header: text.slice(0, match.index), body: raw.subarray(
|
|
8979
|
+
return { header: text.slice(0, match.index), body: raw.subarray(import_node_buffer9.Buffer.byteLength(text.slice(0, match.index + match[0].length), "latin1")), newline };
|
|
7872
8980
|
}
|
|
7873
8981
|
function subjectTagText(tag, spaceAfter = false) {
|
|
7874
8982
|
const line = String(tag).replaceAll(new RegExp("\\p{Cc}+", "gu"), " ").trim();
|
|
@@ -7878,14 +8986,14 @@ function subjectTagText(tag, spaceAfter = false) {
|
|
|
7878
8986
|
const words2 = [];
|
|
7879
8987
|
let chunk2 = "";
|
|
7880
8988
|
for (const character of spaceAfter ? `${line} ` : line) {
|
|
7881
|
-
if (
|
|
8989
|
+
if (import_node_buffer9.Buffer.byteLength(chunk2 + character, "utf8") > ENCODED_BYTES) {
|
|
7882
8990
|
words2.push(chunk2);
|
|
7883
8991
|
chunk2 = "";
|
|
7884
8992
|
}
|
|
7885
8993
|
chunk2 += character;
|
|
7886
8994
|
}
|
|
7887
8995
|
words2.push(chunk2);
|
|
7888
|
-
return words2.map((word) => `=?UTF-8?B?${
|
|
8996
|
+
return words2.map((word) => `=?UTF-8?B?${import_node_buffer9.Buffer.from(word, "utf8").toString("base64")}?=`).join(" ");
|
|
7889
8997
|
}
|
|
7890
8998
|
function taggedSubject(tag, current, newline = "\r\n") {
|
|
7891
8999
|
const unfolded = current.replaceAll(/\r?\n/g, "");
|
|
@@ -7916,7 +9024,7 @@ function taggedSubject(tag, current, newline = "\r\n") {
|
|
|
7916
9024
|
return lines2.join(newline).slice("Subject: ".length);
|
|
7917
9025
|
}
|
|
7918
9026
|
function rewriteMessage(source, headers = [], options = {}) {
|
|
7919
|
-
const raw =
|
|
9027
|
+
const raw = import_node_buffer9.Buffer.isBuffer(source) ? source : import_node_buffer9.Buffer.from(String(source), "utf8");
|
|
7920
9028
|
const { header, body, newline } = splitMessage(raw);
|
|
7921
9029
|
const remove = options.remove ?? /^x-spam-/i;
|
|
7922
9030
|
const lines2 = header === "" ? [] : header.split(/\r?\n/);
|
|
@@ -7941,15 +9049,15 @@ function rewriteMessage(source, headers = [], options = {}) {
|
|
|
7941
9049
|
}
|
|
7942
9050
|
}
|
|
7943
9051
|
}
|
|
7944
|
-
const added = headers.map(([name, value]) => foldHeader(name,
|
|
9052
|
+
const added = headers.map(([name, value]) => foldHeader(name, import_node_buffer9.Buffer.from(String(value), "utf8").toString("latin1"), newline));
|
|
7945
9053
|
const mbox = kept.length > 0 && kept[0][0].startsWith("From ") ? kept.shift() : [];
|
|
7946
9054
|
const head = [...mbox, ...added, ...kept.map((field) => field.join(newline))].join(newline);
|
|
7947
|
-
return
|
|
9055
|
+
return import_node_buffer9.Buffer.concat([import_node_buffer9.Buffer.from(head === "" && header === "" ? newline : `${head}${newline}${newline}`, "latin1"), body]);
|
|
7948
9056
|
}
|
|
7949
|
-
var
|
|
9057
|
+
var import_node_buffer9, ENCODED_BYTES, PLAIN_WORD, ENCODED_LINE, MAX_LINE2, ENCODED_WORD, ENCODED_START;
|
|
7950
9058
|
var init_headers = __esm({
|
|
7951
9059
|
"src/headers.js"() {
|
|
7952
|
-
|
|
9060
|
+
import_node_buffer9 = require("node:buffer");
|
|
7953
9061
|
ENCODED_BYTES = 39;
|
|
7954
9062
|
PLAIN_WORD = 64;
|
|
7955
9063
|
ENCODED_LINE = 76;
|
|
@@ -8125,7 +9233,7 @@ async function* readJsonl(file, options = {}) {
|
|
|
8125
9233
|
}
|
|
8126
9234
|
async function* walk(directory) {
|
|
8127
9235
|
const entries = await import_promises.default.readdir(directory, { withFileTypes: true });
|
|
8128
|
-
entries.sort((a, b) =>
|
|
9236
|
+
entries.sort((a, b) => import_node_buffer10.Buffer.compare(import_node_buffer10.Buffer.from(a.name), import_node_buffer10.Buffer.from(b.name)));
|
|
8129
9237
|
for (const entry of entries) {
|
|
8130
9238
|
if (SKIP.has(entry.name) || entry.name.startsWith(".")) {
|
|
8131
9239
|
continue;
|
|
@@ -8150,7 +9258,7 @@ async function* readMessages(source) {
|
|
|
8150
9258
|
const handle = await import_promises.default.open(file);
|
|
8151
9259
|
let head;
|
|
8152
9260
|
try {
|
|
8153
|
-
const { buffer, bytesRead } = await handle.read(
|
|
9261
|
+
const { buffer, bytesRead } = await handle.read(import_node_buffer10.Buffer.alloc(64), 0, 64, 0);
|
|
8154
9262
|
head = buffer.subarray(0, bytesRead).toString("latin1");
|
|
8155
9263
|
} finally {
|
|
8156
9264
|
await handle.close();
|
|
@@ -8162,10 +9270,10 @@ async function* readMessages(source) {
|
|
|
8162
9270
|
}
|
|
8163
9271
|
}
|
|
8164
9272
|
}
|
|
8165
|
-
var
|
|
9273
|
+
var import_node_buffer10, import_node_fs3, import_promises, import_node_path2, import_node_readline, import_node_zlib, SKIP, SPAM_LABELS, HAM_LABELS, MAX_RECORD_LINES, MAX_RECORD_LENGTH, TEXT_NAMES, LABEL_NAMES, JSONL_LABEL_NAMES, JSONL_TEXT_NAMES;
|
|
8166
9274
|
var init_sources = __esm({
|
|
8167
9275
|
"src/sources.js"() {
|
|
8168
|
-
|
|
9276
|
+
import_node_buffer10 = require("node:buffer");
|
|
8169
9277
|
import_node_fs3 = require("node:fs");
|
|
8170
9278
|
import_promises = __toESM(require("node:fs/promises"), 1);
|
|
8171
9279
|
import_node_path2 = __toESM(require("node:path"), 1);
|
|
@@ -8339,8 +9447,8 @@ function sessionFromQuery(query) {
|
|
|
8339
9447
|
return session;
|
|
8340
9448
|
}
|
|
8341
9449
|
function sameToken(given, expected) {
|
|
8342
|
-
const a =
|
|
8343
|
-
const b =
|
|
9450
|
+
const a = import_node_buffer11.Buffer.from(String(given));
|
|
9451
|
+
const b = import_node_buffer11.Buffer.from(String(expected));
|
|
8344
9452
|
return a.length === b.length && (0, import_node_crypto5.timingSafeEqual)(a, b);
|
|
8345
9453
|
}
|
|
8346
9454
|
function readBody(request, limit) {
|
|
@@ -8360,7 +9468,7 @@ function readBody(request, limit) {
|
|
|
8360
9468
|
reject(error);
|
|
8361
9469
|
return;
|
|
8362
9470
|
}
|
|
8363
|
-
resolve(
|
|
9471
|
+
resolve(import_node_buffer11.Buffer.concat(chunks));
|
|
8364
9472
|
});
|
|
8365
9473
|
request.on("error", reject);
|
|
8366
9474
|
});
|
|
@@ -8375,7 +9483,7 @@ function createHttpServer(scanner, options = {}) {
|
|
|
8375
9483
|
let active = 0;
|
|
8376
9484
|
const server = import_node_http2.default.createServer(async (request, response) => {
|
|
8377
9485
|
const send = (status, body, headers = {}) => {
|
|
8378
|
-
const isBuffer =
|
|
9486
|
+
const isBuffer = import_node_buffer11.Buffer.isBuffer(body);
|
|
8379
9487
|
response.writeHead(status, { "content-type": isBuffer ? "message/rfc822" : "application/json; charset=utf-8", "cache-control": "no-store", ...headers });
|
|
8380
9488
|
response.end(isBuffer ? body : `${JSON.stringify(body)}
|
|
8381
9489
|
`);
|
|
@@ -8448,14 +9556,14 @@ function createTcpServer(scanner, options = {}) {
|
|
|
8448
9556
|
timeout = 6e4,
|
|
8449
9557
|
maxConnections = MAX_CONNECTIONS
|
|
8450
9558
|
} = options;
|
|
8451
|
-
const server =
|
|
9559
|
+
const server = import_node_net5.default.createServer({ allowHalfOpen: true }, (socket) => {
|
|
8452
9560
|
const chunks = [];
|
|
8453
9561
|
let size = 0;
|
|
8454
9562
|
socket.setTimeout(timeout, () => socket.destroy());
|
|
8455
9563
|
const onEnd = async () => {
|
|
8456
9564
|
socket.setTimeout(0);
|
|
8457
9565
|
try {
|
|
8458
|
-
const result = await scanner.scan(
|
|
9566
|
+
const result = await scanner.scan(import_node_buffer11.Buffer.concat(chunks));
|
|
8459
9567
|
socket.end(json ? `${JSON.stringify(serializeResult(result))}
|
|
8460
9568
|
` : `${result.isSpam ? "SPAM" : "HAM"} ${result.score.toFixed(1)}/${result.threshold.toFixed(1)} ${result.tests.map((test) => test.name).join(",")}
|
|
8461
9569
|
`);
|
|
@@ -8484,13 +9592,13 @@ function createTcpServer(scanner, options = {}) {
|
|
|
8484
9592
|
server.maxConnections = maxConnections;
|
|
8485
9593
|
return server;
|
|
8486
9594
|
}
|
|
8487
|
-
var
|
|
9595
|
+
var import_node_buffer11, import_node_crypto5, import_node_http2, import_node_net5, MAX_MESSAGE_SIZE, MAX_CONNECTIONS;
|
|
8488
9596
|
var init_server = __esm({
|
|
8489
9597
|
"src/server.js"() {
|
|
8490
|
-
|
|
9598
|
+
import_node_buffer11 = require("node:buffer");
|
|
8491
9599
|
import_node_crypto5 = require("node:crypto");
|
|
8492
9600
|
import_node_http2 = __toESM(require("node:http"), 1);
|
|
8493
|
-
|
|
9601
|
+
import_node_net5 = __toESM(require("node:net"), 1);
|
|
8494
9602
|
init_headers();
|
|
8495
9603
|
init_version();
|
|
8496
9604
|
MAX_MESSAGE_SIZE = 25 * 1024 * 1024;
|
|
@@ -8499,12 +9607,12 @@ var init_server = __esm({
|
|
|
8499
9607
|
});
|
|
8500
9608
|
|
|
8501
9609
|
// src/milter.js
|
|
8502
|
-
function packet(command, data2 =
|
|
8503
|
-
const payload =
|
|
8504
|
-
const header =
|
|
9610
|
+
function packet(command, data2 = import_node_buffer12.Buffer.alloc(0)) {
|
|
9611
|
+
const payload = import_node_buffer12.Buffer.isBuffer(data2) ? data2 : import_node_buffer12.Buffer.from(data2, "latin1");
|
|
9612
|
+
const header = import_node_buffer12.Buffer.alloc(5);
|
|
8505
9613
|
header.writeUInt32BE(payload.length + 1);
|
|
8506
9614
|
header.write(command, 4, "latin1");
|
|
8507
|
-
return
|
|
9615
|
+
return import_node_buffer12.Buffer.concat([header, payload]);
|
|
8508
9616
|
}
|
|
8509
9617
|
function cstrings(data2) {
|
|
8510
9618
|
const parts = data2.toString("latin1").split("\0");
|
|
@@ -8514,19 +9622,19 @@ function cstrings(data2) {
|
|
|
8514
9622
|
return parts;
|
|
8515
9623
|
}
|
|
8516
9624
|
function cstring(value) {
|
|
8517
|
-
return
|
|
9625
|
+
return import_node_buffer12.Buffer.from(`${value}\0`, "latin1");
|
|
8518
9626
|
}
|
|
8519
9627
|
function address(value) {
|
|
8520
9628
|
const text = String(value ?? "").trim();
|
|
8521
9629
|
const match = /^<?([^<>]*)>?$/.exec(text);
|
|
8522
9630
|
return match ? match[1] : text;
|
|
8523
9631
|
}
|
|
8524
|
-
var
|
|
9632
|
+
var import_node_buffer12, import_node_events, import_node_net6, COMMANDS, RESPONSES, ACTIONS, PROTOCOL, MAX_PACKET, MilterSession, MilterServer;
|
|
8525
9633
|
var init_milter = __esm({
|
|
8526
9634
|
"src/milter.js"() {
|
|
8527
|
-
|
|
9635
|
+
import_node_buffer12 = require("node:buffer");
|
|
8528
9636
|
import_node_events = require("node:events");
|
|
8529
|
-
|
|
9637
|
+
import_node_net6 = __toESM(require("node:net"), 1);
|
|
8530
9638
|
init_headers();
|
|
8531
9639
|
init_auth();
|
|
8532
9640
|
init_server();
|
|
@@ -8644,7 +9752,7 @@ var init_milter = __esm({
|
|
|
8644
9752
|
if (this.buffered < this.needed) {
|
|
8645
9753
|
return;
|
|
8646
9754
|
}
|
|
8647
|
-
let buffer = this.chunks.length === 1 ? this.chunks[0] :
|
|
9755
|
+
let buffer = this.chunks.length === 1 ? this.chunks[0] : import_node_buffer12.Buffer.concat(this.chunks);
|
|
8648
9756
|
this.needed = 4;
|
|
8649
9757
|
while (buffer.length >= 4) {
|
|
8650
9758
|
const length = buffer.readUInt32BE(0);
|
|
@@ -8689,7 +9797,7 @@ var init_milter = __esm({
|
|
|
8689
9797
|
const protocol = data2.readUInt32BE(8);
|
|
8690
9798
|
const wanted = ACTIONS.ADDHDRS | ACTIONS.CHGHDRS | ACTIONS.QUARANTINE;
|
|
8691
9799
|
this.leadingSpace = Boolean(protocol & PROTOCOL.HDR_LEADSPC);
|
|
8692
|
-
const reply2 =
|
|
9800
|
+
const reply2 = import_node_buffer12.Buffer.alloc(12);
|
|
8693
9801
|
reply2.writeUInt32BE(Math.min(version, 6), 0);
|
|
8694
9802
|
reply2.writeUInt32BE(actions & wanted, 4);
|
|
8695
9803
|
reply2.writeUInt32BE(protocol & (PROTOCOL.HDR_LEADSPC | PROTOCOL.NOUNKNOWN), 8);
|
|
@@ -8754,7 +9862,7 @@ var init_milter = __esm({
|
|
|
8754
9862
|
if (this.truncated || this.size + data2.length > options.maxSize) {
|
|
8755
9863
|
this.truncated = true;
|
|
8756
9864
|
} else {
|
|
8757
|
-
this.body.push(
|
|
9865
|
+
this.body.push(import_node_buffer12.Buffer.from(data2));
|
|
8758
9866
|
this.size += data2.length;
|
|
8759
9867
|
}
|
|
8760
9868
|
this.send(RESPONSES.CONTINUE);
|
|
@@ -8789,7 +9897,7 @@ var init_milter = __esm({
|
|
|
8789
9897
|
/** @returns {Buffer} */
|
|
8790
9898
|
rawMessage() {
|
|
8791
9899
|
const head = this.headers.map(([name, value]) => `${name}:${this.leadingSpace || value.startsWith(" ") || value.startsWith(" ") ? "" : " "}${value}`).join("\r\n");
|
|
8792
|
-
return
|
|
9900
|
+
return import_node_buffer12.Buffer.concat([import_node_buffer12.Buffer.from(this.headers.length > 0 ? `${head}\r
|
|
8793
9901
|
\r
|
|
8794
9902
|
` : "\r\n", "latin1"), ...this.body]);
|
|
8795
9903
|
}
|
|
@@ -8800,9 +9908,9 @@ var init_milter = __esm({
|
|
|
8800
9908
|
const key = name.toLowerCase();
|
|
8801
9909
|
counts.set(key, (counts.get(key) || 0) + 1);
|
|
8802
9910
|
if (key.startsWith("x-spam-")) {
|
|
8803
|
-
const index =
|
|
9911
|
+
const index = import_node_buffer12.Buffer.alloc(4);
|
|
8804
9912
|
index.writeUInt32BE(counts.get(key));
|
|
8805
|
-
this.send(RESPONSES.CHGHEADER,
|
|
9913
|
+
this.send(RESPONSES.CHGHEADER, import_node_buffer12.Buffer.concat([index, cstring(name), cstring("")]));
|
|
8806
9914
|
}
|
|
8807
9915
|
}
|
|
8808
9916
|
}
|
|
@@ -8825,7 +9933,7 @@ var init_milter = __esm({
|
|
|
8825
9933
|
}
|
|
8826
9934
|
this.server.report(error);
|
|
8827
9935
|
this.removeForgedHeaders();
|
|
8828
|
-
this.send(RESPONSES.ADDHEADER,
|
|
9936
|
+
this.send(RESPONSES.ADDHEADER, import_node_buffer12.Buffer.concat([cstring("X-Spam-Virus-Scan"), cstring(`${this.leadingSpace ? " " : ""}failed`)]));
|
|
8829
9937
|
this.send(RESPONSES.CONTINUE);
|
|
8830
9938
|
this.resetMessage();
|
|
8831
9939
|
return;
|
|
@@ -8846,15 +9954,15 @@ var init_milter = __esm({
|
|
|
8846
9954
|
headers.unshift(["Authentication-Results", formatAuthResultsHeader(result.results.authentication, options.hostname)]);
|
|
8847
9955
|
}
|
|
8848
9956
|
for (const [name, value] of headers) {
|
|
8849
|
-
this.send(RESPONSES.ADDHEADER,
|
|
9957
|
+
this.send(RESPONSES.ADDHEADER, import_node_buffer12.Buffer.concat([cstring(name), cstring(`${this.leadingSpace ? " " : ""}${value}`.replaceAll("\r\n", "\n"))]));
|
|
8850
9958
|
}
|
|
8851
9959
|
if (result.isSpam && options.subjectTag) {
|
|
8852
9960
|
const subject = this.headers.find(([name]) => name.toLowerCase() === "subject");
|
|
8853
9961
|
const value = taggedSubject(options.subjectTag, subject ? subject[1].trim() : "", "\n");
|
|
8854
9962
|
if (value !== null) {
|
|
8855
|
-
const index =
|
|
9963
|
+
const index = import_node_buffer12.Buffer.alloc(4);
|
|
8856
9964
|
index.writeUInt32BE(1);
|
|
8857
|
-
this.send(RESPONSES.CHGHEADER,
|
|
9965
|
+
this.send(RESPONSES.CHGHEADER, import_node_buffer12.Buffer.concat([index, cstring("Subject"), cstring(`${this.leadingSpace ? " " : ""}${value}`.replaceAll("\r\n", "\n"))]));
|
|
8858
9966
|
}
|
|
8859
9967
|
}
|
|
8860
9968
|
if (result.action === "reject" && options.reject) {
|
|
@@ -8905,7 +10013,7 @@ var init_milter = __esm({
|
|
|
8905
10013
|
throw new RangeError(`rejectCode must be a 4xx or 5xx SMTP code, not ${this.options.rejectCode}`);
|
|
8906
10014
|
}
|
|
8907
10015
|
this.sockets = /* @__PURE__ */ new Set();
|
|
8908
|
-
this.server =
|
|
10016
|
+
this.server = import_node_net6.default.createServer((socket) => {
|
|
8909
10017
|
this.sockets.add(socket);
|
|
8910
10018
|
socket.on("close", () => this.sockets.delete(socket));
|
|
8911
10019
|
return new MilterSession(socket, this);
|
|
@@ -8981,7 +10089,7 @@ function reply(code, text, headers = [], body = null) {
|
|
|
8981
10089
|
lines2.push(`Content-length: ${body.length}`);
|
|
8982
10090
|
}
|
|
8983
10091
|
lines2.push(...headers.map(([name, value]) => `${name}: ${value}`), "", "");
|
|
8984
|
-
return body === null ?
|
|
10092
|
+
return body === null ? import_node_buffer13.Buffer.from(lines2.join("\r\n")) : import_node_buffer13.Buffer.concat([import_node_buffer13.Buffer.from(lines2.join("\r\n")), body]);
|
|
8985
10093
|
}
|
|
8986
10094
|
function report(result) {
|
|
8987
10095
|
const lines2 = [
|
|
@@ -9026,11 +10134,11 @@ async function answer(scanner, request, message, options) {
|
|
|
9026
10134
|
return reply(EX_OK, "EX_OK", [verdict]);
|
|
9027
10135
|
}
|
|
9028
10136
|
case "SYMBOLS": {
|
|
9029
|
-
return reply(EX_OK, "EX_OK", [verdict],
|
|
10137
|
+
return reply(EX_OK, "EX_OK", [verdict], import_node_buffer13.Buffer.from(result.tests.map((test) => test.name).join(",")));
|
|
9030
10138
|
}
|
|
9031
10139
|
case "REPORT":
|
|
9032
10140
|
case "REPORT_IFSPAM": {
|
|
9033
|
-
return reply(EX_OK, "EX_OK", [verdict], command === "REPORT" || result.isSpam ?
|
|
10141
|
+
return reply(EX_OK, "EX_OK", [verdict], command === "REPORT" || result.isSpam ? import_node_buffer13.Buffer.from(report(result)) : import_node_buffer13.Buffer.alloc(0));
|
|
9034
10142
|
}
|
|
9035
10143
|
default: {
|
|
9036
10144
|
const rewritten = rewriteMessage(message, spamHeaders(result, { version: VERSION }), { subjectTag: result.isSpam ? options.subjectTag : null });
|
|
@@ -9038,7 +10146,7 @@ async function answer(scanner, request, message, options) {
|
|
|
9038
10146
|
return reply(EX_OK, "EX_OK", [verdict], rewritten);
|
|
9039
10147
|
}
|
|
9040
10148
|
const { header, newline } = splitMessage(rewritten);
|
|
9041
|
-
return reply(EX_OK, "EX_OK", [verdict],
|
|
10149
|
+
return reply(EX_OK, "EX_OK", [verdict], import_node_buffer13.Buffer.from(`${header}${newline}${newline}`, "latin1"));
|
|
9042
10150
|
}
|
|
9043
10151
|
}
|
|
9044
10152
|
}
|
|
@@ -9052,8 +10160,8 @@ function createSpamdServer(scanner, options = {}) {
|
|
|
9052
10160
|
maxConnections: MAX_CONNECTIONS,
|
|
9053
10161
|
...options
|
|
9054
10162
|
};
|
|
9055
|
-
const server =
|
|
9056
|
-
let head =
|
|
10163
|
+
const server = import_node_net7.default.createServer({ allowHalfOpen: true }, (socket) => {
|
|
10164
|
+
let head = import_node_buffer13.Buffer.alloc(0);
|
|
9057
10165
|
const chunks = [];
|
|
9058
10166
|
let size = 0;
|
|
9059
10167
|
let request = null;
|
|
@@ -9079,7 +10187,7 @@ function createSpamdServer(scanner, options = {}) {
|
|
|
9079
10187
|
return;
|
|
9080
10188
|
}
|
|
9081
10189
|
if (!request) {
|
|
9082
|
-
head =
|
|
10190
|
+
head = import_node_buffer13.Buffer.concat([head, chunk2]);
|
|
9083
10191
|
const end = head.indexOf("\r\n\r\n");
|
|
9084
10192
|
if (end === -1) {
|
|
9085
10193
|
if (head.length > 64 * 1024) {
|
|
@@ -9114,7 +10222,7 @@ function createSpamdServer(scanner, options = {}) {
|
|
|
9114
10222
|
chunks.push(chunk2);
|
|
9115
10223
|
size += chunk2.length;
|
|
9116
10224
|
if (request.length === null ? ["PING", "SKIP"].includes(request.command) : size >= request.length) {
|
|
9117
|
-
finish(
|
|
10225
|
+
finish(import_node_buffer13.Buffer.concat(chunks).subarray(0, request.length ?? 0));
|
|
9118
10226
|
} else if (size > settings.maxSize) {
|
|
9119
10227
|
fail(EX_DATAERR, `Message larger than ${settings.maxSize} bytes`);
|
|
9120
10228
|
}
|
|
@@ -9126,7 +10234,7 @@ function createSpamdServer(scanner, options = {}) {
|
|
|
9126
10234
|
if (!request) {
|
|
9127
10235
|
fail(EX_PROTOCOL, "Incomplete request");
|
|
9128
10236
|
} else if (request.length === null) {
|
|
9129
|
-
finish(
|
|
10237
|
+
finish(import_node_buffer13.Buffer.concat(chunks));
|
|
9130
10238
|
} else {
|
|
9131
10239
|
fail(EX_PROTOCOL, `Message shorter than its Content-length of ${request.length} bytes`);
|
|
9132
10240
|
}
|
|
@@ -9137,11 +10245,11 @@ function createSpamdServer(scanner, options = {}) {
|
|
|
9137
10245
|
server.maxConnections = settings.maxConnections;
|
|
9138
10246
|
return server;
|
|
9139
10247
|
}
|
|
9140
|
-
var
|
|
10248
|
+
var import_node_buffer13, import_node_net7, EX_OK, EX_USAGE, EX_DATAERR, EX_SOFTWARE, EX_PROTOCOL, EX_NOPERM, COMMANDS2;
|
|
9141
10249
|
var init_spamd = __esm({
|
|
9142
10250
|
"src/spamd.js"() {
|
|
9143
|
-
|
|
9144
|
-
|
|
10251
|
+
import_node_buffer13 = require("node:buffer");
|
|
10252
|
+
import_node_net7 = __toESM(require("node:net"), 1);
|
|
9145
10253
|
init_headers();
|
|
9146
10254
|
init_server();
|
|
9147
10255
|
init_version();
|
|
@@ -9353,21 +10461,21 @@ async function withTimeout(promise, ms, fallback) {
|
|
|
9353
10461
|
}
|
|
9354
10462
|
}
|
|
9355
10463
|
async function toBuffer(source) {
|
|
9356
|
-
if (
|
|
10464
|
+
if (import_node_buffer14.Buffer.isBuffer(source)) {
|
|
9357
10465
|
return source;
|
|
9358
10466
|
}
|
|
9359
10467
|
if (typeof source === "string") {
|
|
9360
|
-
return
|
|
10468
|
+
return import_node_buffer14.Buffer.from(source, "utf8");
|
|
9361
10469
|
}
|
|
9362
10470
|
if (source instanceof Uint8Array) {
|
|
9363
|
-
return
|
|
10471
|
+
return import_node_buffer14.Buffer.from(source);
|
|
9364
10472
|
}
|
|
9365
10473
|
if (source && typeof source[Symbol.asyncIterator] === "function") {
|
|
9366
10474
|
const chunks = [];
|
|
9367
10475
|
for await (const chunk2 of source) {
|
|
9368
|
-
chunks.push(
|
|
10476
|
+
chunks.push(import_node_buffer14.Buffer.isBuffer(chunk2) ? chunk2 : import_node_buffer14.Buffer.from(chunk2));
|
|
9369
10477
|
}
|
|
9370
|
-
return
|
|
10478
|
+
return import_node_buffer14.Buffer.concat(chunks);
|
|
9371
10479
|
}
|
|
9372
10480
|
throw new TypeError("A message must be a Buffer, a string, a Uint8Array or a readable stream");
|
|
9373
10481
|
}
|
|
@@ -9442,12 +10550,12 @@ function fromDomain(mail) {
|
|
|
9442
10550
|
function withHeader(raw) {
|
|
9443
10551
|
const first = raw.subarray(0, 1e3).toString("latin1");
|
|
9444
10552
|
const headerless = raw.length > 0 && !/^(?:[!-9;-~]+[ \t]*:|From |[\r\n])/.test(first);
|
|
9445
|
-
return headerless ?
|
|
10553
|
+
return headerless ? import_node_buffer14.Buffer.concat([import_node_buffer14.Buffer.from("\r\n"), raw]) : raw;
|
|
9446
10554
|
}
|
|
9447
|
-
var
|
|
10555
|
+
var import_node_buffer14, import_promises2, import_node_util2, debug2, DEFAULTS2, NESTED, MAX_LOOKALIKE_HOSTS, MAX_DECEPTIVE_LINKS, CLAMAV_CONCURRENCY, CLAMAV_TIMEOUT, CLAMAV_LIMITS, MAX_NSFW_IMAGES, MAX_REPUTATION_CACHES, SpamScanner, src_default;
|
|
9448
10556
|
var init_src = __esm({
|
|
9449
10557
|
"src/index.js"() {
|
|
9450
|
-
|
|
10558
|
+
import_node_buffer14 = require("node:buffer");
|
|
9451
10559
|
import_promises2 = require("node:fs/promises");
|
|
9452
10560
|
import_node_util2 = require("node:util");
|
|
9453
10561
|
init_attachments();
|
|
@@ -9456,6 +10564,7 @@ var init_src = __esm({
|
|
|
9456
10564
|
init_classifier();
|
|
9457
10565
|
init_dnsbl();
|
|
9458
10566
|
init_html();
|
|
10567
|
+
init_links();
|
|
9459
10568
|
init_homograph();
|
|
9460
10569
|
init_is_arbitrary();
|
|
9461
10570
|
init_language();
|
|
@@ -9498,6 +10607,19 @@ var init_src = __esm({
|
|
|
9498
10607
|
cloudflare: true,
|
|
9499
10608
|
adult: true,
|
|
9500
10609
|
maxHosts: 25,
|
|
10610
|
+
// Also read the links of the whole message and of what it carries
|
|
10611
|
+
// (attached messages, HTML, SVG and XML files, text files, invitations
|
|
10612
|
+
// and contact cards, documents in iframes and data: URLs) when link
|
|
10613
|
+
// hosts are looked up, for at most five seconds: off by default, as it
|
|
10614
|
+
// reads all of it, up to 50 MB of attachments.
|
|
10615
|
+
attachments: false,
|
|
10616
|
+
// Milliseconds the link lookups may take in all (default: timeout).
|
|
10617
|
+
timeout: void 0,
|
|
10618
|
+
// Also look up host names written in the text without a link or a path
|
|
10619
|
+
// ("evil.example"), which mail clients make links of, as far as there is
|
|
10620
|
+
// room: off by default, as a quoted reply or a signature may name any
|
|
10621
|
+
// site (they are checked for lookalikes either way).
|
|
10622
|
+
hostsInText: false,
|
|
9501
10623
|
// Characters of text read for links (twice as many of HTML): more than
|
|
9502
10624
|
// for the classifier (maxLength), as a link anywhere in a message may be
|
|
9503
10625
|
// followed; a longer message sets results.linksTruncated.
|
|
@@ -9699,7 +10821,10 @@ var init_src = __esm({
|
|
|
9699
10821
|
async scanFile(file, options) {
|
|
9700
10822
|
return this.scan(await (0, import_promises2.readFile)(file), options);
|
|
9701
10823
|
}
|
|
9702
|
-
|
|
10824
|
+
// (`from`: the sender's domain; `carried`: the link hosts of the whole
|
|
10825
|
+
// message and of what it carries, see carriedLinkHosts)
|
|
10826
|
+
async checkLinks(links, config, hosts = [], options = {}) {
|
|
10827
|
+
const { from = "", carried = null } = typeof options === "string" ? { from: options } : options;
|
|
9703
10828
|
const phishing = [];
|
|
9704
10829
|
const homographs = [];
|
|
9705
10830
|
const seenHosts = /* @__PURE__ */ new Set();
|
|
@@ -9755,7 +10880,11 @@ var init_src = __esm({
|
|
|
9755
10880
|
for (const host of hosts) {
|
|
9756
10881
|
lookalike(host, { source: "text" });
|
|
9757
10882
|
}
|
|
9758
|
-
const
|
|
10883
|
+
const carriedHosts = (carried?.hosts ?? []).map((host) => lookupName(host)).filter(Boolean);
|
|
10884
|
+
for (const host of carriedHosts) {
|
|
10885
|
+
seenHosts.add(host);
|
|
10886
|
+
}
|
|
10887
|
+
const ordered = [.../* @__PURE__ */ new Set([...[...found.filter((link) => link.text), ...found.filter((link) => !link.text), ...bare].map((link) => lookupName(destination(link))).filter(Boolean), ...carriedHosts])];
|
|
9759
10888
|
const firsts = /* @__PURE__ */ new Map();
|
|
9760
10889
|
for (const host of ordered) {
|
|
9761
10890
|
const domain = registrableDomain(host);
|
|
@@ -9767,6 +10896,7 @@ var init_src = __esm({
|
|
|
9767
10896
|
const domains = [...new Set(checked.map((host) => registrableDomain(host)))];
|
|
9768
10897
|
const blocked = [];
|
|
9769
10898
|
let answered = 0;
|
|
10899
|
+
const linkTimeout = Number(config.phishing.timeout) > 0 ? Number(config.phishing.timeout) : config.timeout;
|
|
9770
10900
|
const cloudflare = async () => {
|
|
9771
10901
|
await withTimeout(Promise.all(checked.map(async (host) => {
|
|
9772
10902
|
const found2 = await this.dns.checkCloudflare([host], { adult: config.phishing.adult });
|
|
@@ -9774,12 +10904,12 @@ var init_src = __esm({
|
|
|
9774
10904
|
if (!found2.unanswered?.length) {
|
|
9775
10905
|
answered++;
|
|
9776
10906
|
}
|
|
9777
|
-
})),
|
|
10907
|
+
})), linkTimeout, null);
|
|
9778
10908
|
return { found: [...blocked], unanswered: checked.length - answered };
|
|
9779
10909
|
};
|
|
9780
10910
|
const [cloudflareResult, listed] = await Promise.all([
|
|
9781
10911
|
config.phishing.cloudflare && checked.length > 0 ? cloudflare() : { found: [], unanswered: 0 },
|
|
9782
|
-
config.dnsbl.domain?.length > 0 && domains.length > 0 ? withTimeout(this.dns.checkDomains(domains, config.dnsbl.domain),
|
|
10912
|
+
config.dnsbl.domain?.length > 0 && domains.length > 0 ? withTimeout(this.dns.checkDomains(domains, config.dnsbl.domain), linkTimeout, []) : []
|
|
9783
10913
|
]);
|
|
9784
10914
|
for (const { host, category } of cloudflareResult.found) {
|
|
9785
10915
|
phishing.push(finding(category === "malware" ? { type: "malicious_domain", domain: host, message: `Link hostname ${host} is blocked by Cloudflare's malware filtering as phishing or malware` } : { type: "adult_domain", domain: host, message: `Link hostname ${host} was detected by Cloudflare's family filtering to contain adult-related content` }));
|
|
@@ -9795,7 +10925,8 @@ var init_src = __esm({
|
|
|
9795
10925
|
return {
|
|
9796
10926
|
phishing,
|
|
9797
10927
|
homographs,
|
|
9798
|
-
|
|
10928
|
+
// (at least one when the message has more hosts than were read)
|
|
10929
|
+
uncheckedHosts: Math.max(seenHosts.size - checked.length, carried?.more ? 1 : 0),
|
|
9799
10930
|
timedOutHosts: cloudflareResult.unanswered
|
|
9800
10931
|
};
|
|
9801
10932
|
}
|
|
@@ -9967,10 +11098,17 @@ ${visibleText(html2.slice(0, config.maxLength * 2)).text}`, { maxLength: config.
|
|
|
9967
11098
|
styled: plainObfuscation.styled || shownObfuscation.styled
|
|
9968
11099
|
};
|
|
9969
11100
|
const unopened = [];
|
|
9970
|
-
const
|
|
11101
|
+
const opened = [];
|
|
11102
|
+
const attached = await expandAttachments(mail.attachments, parseErrors, void 0, { unopened, mails: opened });
|
|
11103
|
+
const carried = config.phishing.attachments === true && (config.phishing.cloudflare || config.dnsbl.domain?.length > 0) ? carriedLinkHosts(mail, {
|
|
11104
|
+
mails: opened,
|
|
11105
|
+
attachments: attached,
|
|
11106
|
+
maxHosts: config.phishing.maxHosts,
|
|
11107
|
+
hostsInText: config.phishing.hostsInText === true
|
|
11108
|
+
}) : null;
|
|
9971
11109
|
const attachments = config.attachments === false ? [] : inspectAttachments(attached).filter((item) => config.macros !== false || !["macro", "pdf_active", "rtf_object"].includes(item.type)).map((item) => finding(item));
|
|
9972
11110
|
const [links, authentication, checkedReputation, dnsbl, virusScan, toxicity, nsfw] = await Promise.all([
|
|
9973
|
-
this.checkLinks(checkedLinks, config, extracted.hosts, fromDomain(mail)),
|
|
11111
|
+
this.checkLinks(checkedLinks, config, extracted.hosts, { from: fromDomain(mail), carried }),
|
|
9974
11112
|
config.authenticationResults && typeof config.authenticationResults === "object" ? normalizeAuthOutput(config.authenticationResults) : config.authentication && session.remoteAddress ? withTimeout(authenticate(raw, {
|
|
9975
11113
|
timeout: config.timeout,
|
|
9976
11114
|
...typeof config.authentication === "object" ? config.authentication : {},
|
|
@@ -10098,6 +11236,14 @@ ${visibleText(html2.slice(0, config.maxLength * 2)).text}`, { maxLength: config.
|
|
|
10098
11236
|
// Whether the message has more text than phishing.maxLength, whose
|
|
10099
11237
|
// links were not read.
|
|
10100
11238
|
linksTruncated,
|
|
11239
|
+
// Whether a link host of the message or of what it carries was
|
|
11240
|
+
// never read whole (it runs past where long text is cut to be
|
|
11241
|
+
// read, it goes through more security gateways than are
|
|
11242
|
+
// unwrapped, or it is in more documents than are read), and whether
|
|
11243
|
+
// an attachment was left unread for time: in either case not every
|
|
11244
|
+
// link was checked (see phishing.attachments).
|
|
11245
|
+
linksTooComplex: Boolean(carried?.tooComplex),
|
|
11246
|
+
linksIncomplete: Boolean(carried?.incomplete),
|
|
10101
11247
|
idnHomographAttack: {
|
|
10102
11248
|
detected: links.homographs.length > 0,
|
|
10103
11249
|
domains: links.homographs,
|
|
@@ -10109,6 +11255,9 @@ ${visibleText(html2.slice(0, config.maxLength * 2)).text}`, { maxLength: config.
|
|
|
10109
11255
|
language: extracted.language,
|
|
10110
11256
|
tokens: extracted.words,
|
|
10111
11257
|
mail,
|
|
11258
|
+
// (the attachments of the message and of its attached messages, as
|
|
11259
|
+
// read, an attached message's named after it)
|
|
11260
|
+
attached,
|
|
10112
11261
|
version: VERSION,
|
|
10113
11262
|
metrics: { totalTime: time }
|
|
10114
11263
|
};
|