--[[ 	القرآن 	Quran 	 	created and maintained in Arabic Wikipedia  ]] local cfg = mw.loadData('Module:Quran/Configuration') local quran_text_data local quran_data  local quran_norm local aya_symbol_template = cfg.default.aya_symbol_template local sour local quran_shape = cfg.default.shape local string=mw.ustring local text=mw.text local strspace = "[ " .. string.char(160) .. "]"  local function eastern_numbers(thenumber) 	local str_number = tostring(thenumber) 	local ret_str = 	 	for i=1,#str_number do 		ret_str = ret_str .. string.char(0x0660 + tonumber(string.sub(str_number,i,i))) 	end 	return ret_str end  local function shape_numbers(thenumber) 	local str_number = tostring(thenumber) 	local numbers_shape = cfg.presentation.numbers_shape 	if numbers_shape == "" then 		return str_number 	end 	local ret_str =  	local c_n 	for i=1,#str_number do 		c_n = tonumber(string.sub(str_number,i,i))+1 		ret_str = ret_str .. string.sub(numbers_shape, c_n,c_n) 	end 	return ret_str end  local gtonumber = tonumber  local function tonumber(str)     if not str then         return nil     end     local thenumber = gtonumber(str) or mw.language.getContentLanguage():parseFormattedNumber(str)     if not thenumber then         return nil     end     return math.floor(thenumber) end  local function set_quran_shape(in_shape) 	if in_shape then 		for k, shapelist in pairs(cfg.shape_aliases) do 			for _, shapevalue in ipairs(shapelist) do 				if in_shape == shapevalue then 					quran_shape = k 					return 				end 			end 		end	 	end end  local function substitute( msg, args ) 	return args and mw.message.newRawMessage( msg, args ):plain() or msg; end  local function error_comment(msg, args ) 	return substitute( cfg.presentation.error, {mw.getCurrentFrame():getParent():getTitle() , substitute( msg, args )} ); end  local function some_aya(souranum,ayanum,start_word,end_word) 	if not start_word and not end_word then 		return quran_data[souranum][ayanum],true 	end 	local fullaya = true 	local ayaText = ' ' .. quran_data[souranum][ayanum] .. ' ' 	local f,l,wb 	local fnorm=1 	local norm_ayaText 	if start_word then 		f=string.find(ayaText,' ' .. start_word .. ' ',1,true) 		if not f then 			if not quran_norm then 				quran_norm = mw.loadData('Module:Quran/data norm') 			end 			norm_ayaText=' ' .. quran_norm[souranum][ayanum] .. ' ' 			f=string.find(string.gsub(norm_ayaText, string.char(160),' '), ' ' .. start_word .. ' ',1,true) 			fnorm=f 			if not f then 				return error_comment(cfg.msgs.from_word_err) 			end 			if quran_shape ~= 'text' and string.sub(norm_ayaText,f,f)==string.char(160) then 				ff=1 				tmp=1 				while tmp do 					tmp = string.find(string.sub(norm_ayaText,1,f),' ',ff+1,true) 					if tmp then 						ff=tmp 					end 				end 				f=ff 			end 			_, wb = string.gsub(string.sub(norm_ayaText,1,f-1),strspace," ") 			f=1 			for i=1,wb do 				f=string.find(ayaText," ",f+1) 			end 		end 	end 	f=f or 1 	if end_word then 		 		l=string.find(ayaText,' ' .. end_word .. ' ',f,true) 		if l then 			l=l + end_word:len() 		else 			if not quran_norm then 				quran_norm = mw.loadData('Module:Quran/data norm') 			end 			norm_ayaText=' ' .. quran_norm[souranum][ayanum] .. ' ' 			l = string.find(string.gsub(norm_ayaText,string.char(160),' '),' ' .. end_word .. ' ',fnorm,true) 			if not l then 				return error_comment(cfg.msgs.to_word_err) 			end 			l=l + string.len(end_word) 			_, wb =string.gsub(string.sub(norm_ayaText,1,l-1),strspace," ") 			l=1 			for i=1,wb do 				l=string.find(ayaText, " ",l+1) 			end 		end 		if l<#ayaText then 			fullaya=false 		end 	end 	return text.trim(string.sub(ayaText,f,l)),fullaya end  local function argument_wrapper(arg) 	local nilargs = {} 	return setmetatable({}, 	{ 		__index = function ( tbl, k ) 			local v = rawget(tbl,k) 			if v then 				return v 			elseif nilargs[k] then 				return nil 			end 			local list = cfg.aliases[k]; 			for _,arglist in ipairs(arg) do 				if type( list ) == 'table' then 					for _, alias_key in ipairs( list ) do 						if arglist[alias_key] then 							v = arglist[alias_key] 							break; 						end 					end 				elseif list ~= nil then 					v = arglist[list] 				end  				if v then 					break; 				end 			end 			if v == nil then 				nilargs[k] = true 			elseif string.len(v) == 0 then 				nilargs[k] = true 				v = nil 			else 				rawset( tbl, k, v ) 			end 			return v 		end, 	}); end  local function soura_number( str_soura ) 	for i=1,114 do 		if sour[i].name == str_soura then 			return i 		end 	end  	for i=1,114 do 		for _, v in ipairs(sour[i].search) do 			if v == str_soura then 				return i 			end 		end 	end  	return nil end  local function arg2soura_num(arg_soura)     local soura_num = tonumber(arg_soura)          if soura_num and (soura_num < 1 or soura_num > 114) then         return  0, error_comment(cfg.msgs.soura_num_err)     end          if not soura_num then         soura_num = soura_number(arg_soura)         if not soura_num then             return 0, error_comment(cfg.msgs.soura_name_err)         end     end     return soura_num, "" end  local function load_data() 	quran_data =  mw.loadData('Module:Quran/data ' .. quran_shape)  end  local function aya_number(aya_num, frame)     if aya_symbol_template then         if cfg.presentation[aya_symbol_template] then         	return substitute(cfg.presentation[aya_symbol_template], shape_numbers(aya_num))     	else         	return frame:expandTemplate{ title = aya_symbol_template, args = { aya_num } }     	end     else         return '۝' .. eastern_numbers(aya_num)     end end  local function get_ayat(soura, start_aya, end_aya) 	local ret_text	= 	for aya_num = start_aya, end_aya do 		ret_text = ret_text .. quran_data[soura][aya_num] .. aya_number(aya_num) 	end 	return string.sub(ret_text,1,#ret_text -1)	 end  local function aya(frame) 	local A = argument_wrapper({frame.args, frame:getParent().args,mw.loadData("Module:Art pref/data")["قرآن"] or {}}) 	local soura =  tonumber(A[1] or A.soura or A.s) 	local aya =  tonumber(A.from_aya or A.a)     local ret =      if soura> 114 or soura<1 then     	return error_comment(cfg.msgs.soura_num_err)     end 	     if A.shape then 		set_quran_shape(A.shape)     end     local soura_data = mw.loadData('Module:Quran/data general').sour[soura]     if aya <1 or aya > soura_data.ayacount then         return error_comment(cfg.msgs.from_aya_err,{soura_data.name,soura_data.ayacount})      end 	load_data() 	local ret = quran_data[soura][aya] 	if quran_shape == "KFGQPC" then 		ret= string.gsub(ret,'آ', 'آ') 	end 	return ret end  local function search(A, frame) 	local soura= A[1] or A.soura 	local start_soura 	local ret = 	sour = mw.loadData('Module:Quran/data general').sour 	if soura then 		start_soura, errmsg = arg2soura_num(soura)         if start_soura == 0 then             return errmsg         end 	end 	quran_norm = mw.loadData('Module:Quran/data norm') 	start_soura = start_soura or 1 	for soura_num=start_soura,114 do 		for aya_num=1,sour[soura_num].ayacount do 			if quran_norm[soura_num][aya_num]:gsub("\160"," "):find(A.search) then 				if not quran_data then load_data() end 				ret = ret .. "*" .. substitute(cfg.presentation.quran, { quran_shape, quran_data[soura_num][aya_num] .. ' ' .. aya_number(aya_num,frame)}) .. substitute(cfg.presentation.cite_quran, { sour[soura_num].name, ':' .. aya_num}) .. "\n" 				if A.viewtemplate and A.viewtemplate=="1" or A.viewtemplate=="نعم" then 					ret = ret .. substitute("{{قرآن|$1|$2}}",{soura_num,aya_num}) .. "\n" 				end 			end 		end 	end 	if #ret==0 then 		return error_comment("لا نتائج") 	else 		return ret 	end end  local function ayat(frame) 	local A = argument_wrapper({frame:getParent().args, frame.args,mw.loadData("Module:Art pref/data")["قرآن"] or {}}) 	local nocite = A["no-cite"] and A["no-cite"] ~= '0' and A["no-cite"] ~= 'لا'     if A.shape and string.len(A.shape)>0 then 		set_quran_shape(A.shape) 		if quran_shape=='Text' then 			strspace = "[ " .. string.char(160) .. "]" 		else 			strspace = " " 		end 	end      if A.aya_template and (cfg.presentation[A.aya_template] or mw.title.new("template:" .. A.aya_template).exists) then         aya_symbol_template = A.aya_template     end          if A.search and string.len(A.search)>0 then         return search(A,frame)         end      sour = mw.loadData('Module:Quran/data general').sour     local ret_text = ""      if A.from_aya and string.len(A.from_aya)> 0 then         local soura_num, soura, from_aya, to_aya, errmsg         soura_num, errmsg = arg2soura_num(A[1] or A.soura)         if soura_num == 0 then             return errmsg         end          soura = sour[soura_num]         if string.find(A.from_aya,'-',1,true) then 			local from_aya_splits = mw.text.split(A.from_aya, '-', true ) 			from_aya = tonumber(from_aya_splits[1]) 			to_aya = tonumber(from_aya_splits[2]) 		else 			from_aya =  tonumber(A.from_aya) 		end          		if not from_aya or from_aya>soura.ayacount or from_aya<1 then             return error_comment(cfg.msgs.from_aya_err,{soura.name,soura.ayacount})         end  		if not to_aya or to_aya>soura.ayacount then 			local arg_aya_add = A.addition_ayat 			if arg_aya_add then 				to_aya = from_aya + (tonumber(arg_aya_add) or 0) 			elseif A.to_aya then 				to_aya = tonumber(A.to_aya) 			else 				to_aya = from_aya 			end 		end          		if to_aya>soura.ayacount or to_aya<1 then             return error_comment(cfg.msgs.to_aya_err,{soura.name,soura.ayacount})         end 		 		load_data()         for aya_num = from_aya, to_aya do             local fullaya=true             if (aya_num==from_aya or aya_num == to_aya) and (A.from_word or A.to_word) then             	local temp_text             	temp_text, fullaya = some_aya(soura_num,aya_num,              		(aya_num==from_aya and A.from_word or nil),              		(aya_num == to_aya and A.to_word or nil))             	if temp_text:find("error") then             		return temp_text         		end             	ret_text = ret_text .. temp_text         	else             	ret_text = ret_text .. quran_data[soura_num][aya_num]         	end         	         	if fullaya then                 ret_text = ret_text .. ' ' .. aya_number(aya_num, frame) .. ' ' 			end         end                  if quran_shape == "KFGQPC" then 			ret_text = string.gsub(ret_text,'آ', 'آ') 		end                  return substitute(cfg.presentation.quran, { quran_shape, text.trim(ret_text) }) .. ((not nocite) and (substitute(cfg.presentation.cite_quran, { soura.name, ':' .. from_aya .. ((to_aya>from_aya) and ("–" .. to_aya) or )})) or "")     else         ret_text = substitute(cfg.presentation.quran, { quran_shape, A[1] or A.user_text })         if A.s and string.len(A.s)>0 then             local soura_num, errmsg = arg2soura_num(A.s)             if soura_num == 0 then                 return errmsg             end             local soura=sour[soura_num]             ret_text = ret_text .. substitute(cfg.presentation.cite_quran, { soura.name, (A.a and (":" .. A.a) or "")})         end         return ret_text     end end  local function number_of_soura( frame )	 	local idx = tonumber(frame.args[1]) 	if idx and idx>=1 and idx <=114 then 		return idx 	end 	sour = mw.loadData('Module:Quran/data general').sour 	return soura_number(frame.args[1]) end  local function soura_name( frame )	 	local idx = tonumber(frame.args[1]) 	if not idx or idx<1 or idx > 114 then 		return nil 	end 	sour = mw.loadData('Module:Quran/data general').sour 	return sour[idx].name end  local function aya_count( frame )	 	local idx = tonumber(frame.args[1]) 	if not idx or idx<1 or idx > 114 then 		return nil 	end 	sour = mw.loadData('Module:Quran/data general').sour 	return sour[idx].ayacount end  return {  		aya = aya, 		ayat=ayat, 		number_of_soura = number_of_soura, 		soura_name = soura_name, 		aya_count = aya_count }