local a=require'pl.utils'local string=string;local b=string.find;local type,setmetatable,ipairs=type,setmetatable,ipairs;local error=error;local c=string.gsub;local d=string.rep;local e=string.sub;local f=string.reverse;local g=table.concat;local h=table.insert;local i=a.escape;local j,k=math.ceil,math.max;local l,m=a.assert_arg,a.split;local n;local function o(p,q)l(p,q,'string')end;local function r(q)return#q>0 end;local function s(p,q)l(p,q,'string',r,'must be a non-empty string')end;local function t(u)return setmetatable(u,require('pl.List'))end;local v={}function v.isalpha(q)o(1,q)return b(q,'^%a+$')==1 end;function v.isdigit(q)o(1,q)return b(q,'^%d+$')==1 end;function v.isalnum(q)o(1,q)return b(q,'^%w+$')==1 end;function v.isspace(q)o(1,q)return b(q,'^%s+$')==1 end;function v.islower(q)o(1,q)return b(q,'^[%l%s]+$')==1 end;function v.isupper(q)o(1,q)return b(q,'^[%u%s]+$')==1 end;local function w(q,x)return b(q,x,1,true)==1 end;local function y(q,z)return#q>=#z and b(q,z,#q-#z+1,true)and true or false end;local function A(q,B,C)if type(B)=='string'then return C(q,B)elseif type(B)=='table'then for D,E in ipairs(B)do if C(q,E)then return true end end;return false else error(("argument #2 expected a 'string' or a 'table', got a '%s'"):format(type(B)))end end;function v.startswith(q,x)o(1,q)return A(q,x,w)end;function v.endswith(q,z)o(1,q)return A(q,z,y)end;function v.join(q,F)o(1,q)return g(F,q)end;function v.splitlines(q,G)o(1,q)local H={}local I=1;while true do local J=b(q,'[\r\n]',I)if not J then break end;local K=e(q,J,J)if K=='\r'and e(q,J+1,J+1)=='\n'then K='\r\n'end;local L=e(q,I,J-1)if G then L=L..K end;h(H,L)I=J+#K end;if I<=#q then h(H,e(q,I))end;return t(H)end;function v.split(q,M,p)o(1,q)local N=true;if not M then q=n(q)N=false end;local H=m(q,M,N,p)if M and M~=''and b(q,M,-#M,true)and(p or math.huge)>#H then H[#H+1]=""end;return t(H)end;function v.expandtabs(q,O)o(1,q)O=O or 8;return q:gsub("([^\t\r\n]*)\t",function(P)return P..(" "):rep(O-#P%O)end)end;local function Q(q,e,R,S,T)R=R or 1;S=S or#q;if e==''then return S+1,S-R+1 end;local U,V=b(q,e,R,true)local H;local W=0;while U do if S and V>S then break end;H=U;W=W+1;if T then U,V=b(q,e,U+1,true)else U,V=b(q,e,V+1,true)end end;return H,W end;function v.lfind(q,e,R,S)o(1,q)o(2,e)local U,V=b(q,e,R,true)if U and(not S or V<=S)then return U else return nil end end;function v.rfind(q,e,R,S)o(1,q)o(2,e)return Q(q,e,R,S,true)end;function v.replace(q,X,Y,p)o(1,q)o(2,X)o(3,Y)return c(q,i(X),Y:gsub('%%','%%%%'),p)end;function v.count(q,e,T)o(1,q)local D,W=Q(q,e,1,false,T)return W end;local function Z(q,_,a0,a1,a2)local p=#q;if _>p then if not a0 then a0=' 'end;local a3,a4;if a1 and a2 then local a5=j((_-p)/2)local a6=_-p-a5;a3=d(a0,a6)a4=d(a0,a5)elseif a2 then a3=d(a0,_-p)a4=''else a4=d(a0,_-p)a3=''end;return a3 ..q..a4 else return q end end;function v.ljust(q,_,a0)o(1,q)l(2,_,'number')return Z(q,_,a0,true,false)end;function v.rjust(q,_,a0)o(1,q)l(2,_,'number')return Z(q,_,a0,false,true)end;function v.center(q,_,a0)o(1,q)l(2,_,'number')return Z(q,_,a0,true,true)end;local function a7(q,a1,a2,a8)if not a8 then a8='%s'else a8='['..i(a8)..']'end;local a9=1;local aa;if a1 then local U,V=b(q,'^'..a8 ..'*')if V>=U then a9=V+1 end end;if a2 then if#q<200 then local U,V=b(q,a8 ..'*$',a9)if V>=U then aa=U-1 end else local ab=f(q)local U,V=b(ab,'^'..a8 ..'*')if V>=U then aa=-V-1 end end end;return e(q,a9,aa)end;function v.lstrip(q,a8)o(1,q)return a7(q,true,false,a8)end;n=v.lstrip;function v.rstrip(q,a8)o(1,q)return a7(q,false,true,a8)end;function v.strip(q,a8)o(1,q)return a7(q,true,true,a8)end;function v.splitv(q,M)o(1,q)return a.splitv(q,M)end;local function ac(ad,ae,C)local U,V=C(ad,ae)if not U or U==-1 then return ad,'',''else if not V then V=U end;return e(ad,1,U-1),e(ad,U,V),e(ad,V+1)end end;function v.partition(q,a0)o(1,q)s(2,a0)return ac(q,a0,v.lfind)end;function v.rpartition(q,a0)o(1,q)s(2,a0)local af,ag,ah=ac(q,a0,v.rfind)if af==q then return ah,ag,af end;return af,ag,ah end;function v.at(q,ai)o(1,q)l(2,ai,'number')return e(q,ai,ai)end;function v.lines(q)o(1,q)if not q:find'\n$'then q=q..'\n'end;return q:gmatch('([^\n]*)\n')end;function v.title(q)o(1,q)return q:gsub('(%S)(%S*)',function(a9,aj)return a9:upper()..aj:lower()end)end;v.capitalize=v.title;local ak='...'local al=#ak;function v.shorten(q,_,am)o(1,q)if#q>_ then if _<al then return ak:sub(1,_)end;if am then local an=#q-_+1+al;return ak..q:sub(an)else return q:sub(1,_-al)..ak end end;return q end;local function ao(q)local ap='([%[%]])(=*)%1'local aq,ar,D;local as=1;repeat D,as,D,ar=q:find(ap,as)if ar then aq=k(aq or 0,#ar)end until not ar;return aq end;function v.quote_string(q)o(1,q)local at=ao(q.."]")if(q:find("\n")or at)and not q:find("\r")then at=("="):rep((at or-1)+1)if q:find("^\n")then q="\n"..q end;local au,av="["..at.."[","]"..at.."]"q=au..q..av else q=("%q"):format(q):gsub("\r","\\r")end;return q end;function v.import()a.import(v,string)end;return v