function Encode(R)if not inited then Init()end local x=Copy(dictionary)local K,I,t="",{},#x local U,d,A=1,{},0 local function h(R)local K=ToBase93(x[R])if#K>U then U,A,d[U]=#K,0,A end I[#I+1]=(" "):rep(U-#K)..K A=A+1 end R=Escape(R)for I=1,#R,1 do local U=R:sub(I,I)local d=K..U if x[d]then K=d else h(K)K,t=U,t+1 x[d],x[t]=t,d end end h(K)d[U]=A return table.concat(d,"\044")..("\124"..table.concat(I))end function Decode(R)if not inited then Init()end local x=Copy(dictionary)local K,I,t={},R:match("\040\046-\041\124\040\046\042\041")local U,d={},1 for R in I:gmatch("\037\100\043")do local x=#U+1 U[x]=t:sub(d,(d+R*x)-1)d=d+R*x end local A for R=1,#U,1 do for R in U[R]:gmatch(("\046"):rep(R))do local I=x[ToBase10(R)]if A then if I then K[#K+1]=I x[#x+1]=A..I:sub(1,1)else I=A..A:sub(1,1)K[#K+1]=I x[#x+1]=I end else K[1]=I end A=I end end return Unescape(table.concat(K))end function Escape(R)return R:gsub("\091\037\099\"\092\093",function(R)return"\127"..escapemap[R]end)end function Unescape(R)return R:gsub("\127\040\046\041",function(R)return escapemap[R]end)end function Copy(R)local x={}for R,K in pairs(R)do x[R]=K end return x end function ToBase93(R)local x=""repeat local K=R%93 x=dictionary[K]..x R=(R-K)/93 until R==0 return x end function ToBase10(R)local x=0 for K=1,#R,1 do x=x+93^(K-1)*dictionary[R:sub(-K,-K)]end return x end function Init()for R=32,127,1 do if R~=34 and R~=92 then local x=string.char(R)dictionary[x],dictionary[length]=length,x length=length+1 end end for R=1,34,1 do R=({34;92,127})[R-31]or R local x,K=string.char(R),string.char(R+31)escapemap[x],escapemap[K]=K,x end inited=true end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

function Encode(text)
	--- Init (if haven't already)
	if not inited then
		Init()
	end

	--- Main
	local dictionary = Copy(dictionary)
	local key, sequence, size = "", {}, #dictionary
	local width, spans, span = 1, {}, 0
	local function listkey(key)
		local value = ToBase93(dictionary[key])
		if #value > width then
			width, span, spans[width] = #value, 0, span
		end
		sequence[#sequence + 1] = (" "):rep(width - #value) .. value
		span = span + 1
	end
	text = Escape(text)

	for i = 1, #text do
		local c = text:sub(i, i)
		local new = key .. c
		if dictionary[new] then
			key = new
		else
			listkey(key)
			key, size = c, size + 1
			dictionary[new], dictionary[size] = size, new
		end
	end
	listkey(key)
	spans[width] = span

	--
	return table.concat(spans, ",") .. "|" .. table.concat(sequence)
end

function Decode(text)
	--- Init (if haven't already)
	if not inited then
		Init()
	end

	--- Main
	local dictionary = Copy(dictionary)
	local sequence, spans, content = {}, text:match("(.-)|(.*)")
	local groups, start = {}, 1
	for span in spans:gmatch("%d+") do
		local width = #groups + 1
		groups[width] = content:sub(start, start + span * width - 1)
		start = start + span * width
	end

	local previous
	for width = 1, #groups do
		for value in groups[width]:gmatch(("."):rep(width)) do
			local entry = dictionary[ToBase10(value)]
			if previous then
				if entry then
					sequence[#sequence + 1] = entry
					dictionary[#dictionary + 1] = previous .. entry:sub(1, 1)
				else
					entry = previous .. previous:sub(1, 1)
					sequence[#sequence + 1] = entry
					dictionary[#dictionary + 1] = entry
				end
			else
				sequence[1] = entry
			end
			previous = entry
		end
	end

	--
	return Unescape(table.concat(sequence))
end

function Escape(s)
	return (s:gsub('[%c"\\]', function(c)
		return "\127" .. escapemap[c]
	end))
end

function Unescape(s)
	return (s:gsub("\127(.)", function(c)
		return escapemap[c]
	end))
end

function Copy(t)
	local new = {}
	for k, v in pairs(t) do
		new[k] = v
	end
	return new
end

function ToBase93(n)
	local value = ""
	repeat
		local remainder = n % 93
		value = dictionary[remainder] .. value
		n = (n - remainder) / 93
	until n == 0
	return value
end

function ToBase10(value)
	local n = 0
	for i = 1, #value do
		n = n + 93 ^ (i - 1) * dictionary[value:sub(-i, -i)]
	end
	return n
end

function Init()
	for i = 32, 127 do
		if i ~= 34 and i ~= 92 then
			local c = string.char(i)
			dictionary[c], dictionary[length] = length, c
			length = length + 1
		end
	end

	for i = 1, 34 do
		i = ({ 34, 92, 127 })[i - 31] or i
		local c, e = string.char(i), string.char(i + 31)
		escapemap[c], escapemap[e] = e, c
	end

	--
	inited = true
end
