-- من [[fr:]]
    local hijricore = require("Module:Hijri/core")
    function errorMessage(text)
        -- Return a html formated version of text stylized as an error.
        local html = mw.html.create('div')
        html:addClass('error')
            :wikitext(text)
            :wikitext('[[تصنيف:صفحات تستدعي قالب مؤلف بطريقة غير صحيحة]]')
        return tostring(html)
    end

    function createLinkRow(link, site)
        -- Return some html stylised formated text of link
        local html = mw.html.create('div')
        html:tag('span')
            :css({['color'] = '#232388', ['font-size'] = '140%', ['line-height'] = '150%'})
            :wikitext('[[ملف:' .. site .. '-logo.svg|12px|link=]]  ')
        html:wikitext(link)
        return html
    end

    function categorization(baseName, parameter)
        -- Return the categorisation wikitext for each element of parameter prefixed with baseName
        if parameter == nil or mw.title.getCurrentTitle().namespace ~= 102 then
            return ''
        end

        local wikitext = ''
        for _,param in pairs(mw.text.split(parameter, '/', true)) do
            wikitext = wikitext .. '[[تصنيف:' .. baseName .. ' ' .. param .. ']]'
        end
        return wikitext
    end

    function computeCenturyFromYear(year)
        -- Return the correpsonding century for the given year
        if year >= 0 then
            return math.ceil(year / 100)
        else
            return -math.ceil(-year / 100)
        end
    end

    function getTextForCentury(century, withHtml, hijri)
        -- Return a roman ordinal of century appended with a trailing text precising
        -- if the date is before of after the calendar reference point.
        local romanNumbers1 = {'', 'الأول', 'الثاني', 'الثالث', 'الرابع', 'الخامس', 'السادس', 'السابع', 'الثامن', 'التاسع', 'العاشر', 'الحادي عشر', 'الثاني عشر', 'الثالث عشر', 'الرابع عشر', 'الخامس عشر', 'السادس عشر', 'السابع عشر', 'الثامن عشر', 'التاسع عشر', 'العشرين', 'الحادي والعشرين'}
        -- local romanNumbers2 = {'', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC'}

        local text = romanNumbers1[math.abs(century) + 1]
        
        if century > 0 then
            return text .. (hijri and ' الهجري'  or ' الميلادي')
        else
            return text .. (hijri and ' قبل الهجرة'  or ' قبل الميلاد')
        end
    end

    function getTextForYear(year, hijri)
        local text = math.abs(year)
        if year < 0 then
            text = text .. (hijri and ' ق هـ' or ' ق م')
        else
            text = text .. (hijri and ' هـ' or ' م')
        end
        return text
    end

    function getDateFromArgs(args, field, fieldUpper, hijri)
        local struct = {
            year = nil,
            century = nil,
            text = nil,
            precision = 0,
        }

        local thijri = hijri and ' الهجرية' or ''
        local thijri2 = hijri and ' الهجري' or ''

        --extract year or century
        local date = args['سنة ' .. fieldUpper .. thijri]
        if date == nil or (not hijri and mw.ustring.match(date, "^(%d+)%s?(ق? ?هـ?)$")) then
            if args[field] then
                if (hijri and mw.ustring.match(args[field], "^(%d+)%s?(ق? ?هـ?)$")) or not hijri then
                    date = args[field]
                end
            end
            if date == nil and hijri then
                date = args[field .. thijri]
            end
        end

        local numdate = tonumber(date)
        if hijri and date and numdate == nil then
            local thy, thyt = mw.ustring.match(date, "^(%d+)%s?(ق? ?هـ?)$")
            if thy then
                numdate = tonumber(thy)
                if thyt.sub(1,2) == 'ق' then
                    numdate = numdate * -1
                end
            end
        end

        if numdate ~= nil then
            struct.year = numdate
            if struct.year == 0 then
                struct.text = errorMessage("التقويم لا يحتوي على سنة 0!")
                return struct
            end
            struct.century = computeCenturyFromYear(struct.year)
            struct.precision = 9
        elseif args['قرن ' .. fieldUpper .. thijri2] ~= nil then
            struct.century = tonumber(args['قرن ' .. fieldUpper .. thijri2])
            struct.precision = 7
        end

        --build text
        if struct.year ~= nil then
            struct.text = getTextForYear(struct.year,hijri)
        elseif struct.century ~= nil then
            struct.text = getTextForCentury(struct.century, true,hijri)
        elseif date ~= nil and (hijri or  not mw.ustring.match(date, "^(%d+)%s?(ق? ?هـ?)$")) then
            struct.text = date
        end
        mw.logObject(struct)
        return struct
    end

    function getDateFromTimeStatements(statements, field)
        if #statements == 0 then
            return { precision = 0 }, {	precision = 0 }
        end

        local time,htime = nil,nil
        for _, statement in pairs(statements) do
            local newTime, hnewTime = getDateFromTimeStatement(statement, field)
            if time == nil then
                time = newTime
            elseif time.year ~= newTime.year then --années contradictoires
                mw.addWarning('عدة سنوات من ' .. field .. ' ممكن على ويكي بيانات. طريقة بسيطة لحل هذه المشكلة هي تعيين التاريخ المراد عرضه في الترتيب "المفضل".')
            end
            if htime == nil then
                htime = hnewTime
            elseif htime.year ~= hnewTime.year then --années contradictoires
                mw.addWarning('عدة سنوات من ' .. field .. ' ممكن على ويكي بيانات. طريقة بسيطة لحل هذه المشكلة هي تعيين التاريخ المراد عرضه في الترتيب "المفضل".')
            end
        end

        if time == nil then
            return { precision = 0 }, {	precision = 0 }
        end

        return time,htime
    end

    function parseWbTime(value, refinedate)
        
        local gyear,gmonth,gday,hy
        for y,m,d in string.gmatch(value.time, '(%-?%d%d%d+)%-(%d+)%-(%d+)T') do
            gyear = tonumber(y)
            gmonth = tonumber(m)
            gday = tonumber(d)
        end
        
        if refinedate then
            for _,ry in pairs(refinedate) do
                if ry.snaktype=="value" then
                    local rylabel = mw.wikibase.getLabelByLang( ry.datavalue.value.id , 'ar')
                    if mw.ustring.match(rylabel, "^(%d+)%s?(ق? ?هـ?)$") then
                        for thy, thyt in mw.ustring.gmatch(rylabel, "^(%d+)%s?(ق? ?هـ?)$") do
                            hy = tonumber(thy)
                            if thyt.sub(1,2) == 'ق' then
                                hy = hy * -1
                            end
                        end
                    end
                end
            end
        end
        if not hy then
            if gmonth == 0 then
                gmonth = 7
                gday=1
            end
            
            local julianday

            if value.calendarmodel == "http://www.wikidata.org/entity/Q1985727" then
                julianday = hijricore.gregorian2jd(gyear, gmonth , gday)
            else
                julianday = hijricore.julian2jd(gyear, gmonth, gday)
            end
            hy,_,_,_ = hijricore.jd2hijri(julianday)
        end

        return {
            year = gyear,
            century = computeCenturyFromYear(gyear),
            text = nil,
            precision = value.precision} , {
            precision = value.precision,
            year = hy,
            century = computeCenturyFromYear(hy),
            text = nil
        }
    end

    function getDateFromTimeStatement(statement, field)
        local struct = {
            year = nil,
            century = nil,
            text = nil,
            precision = 0
        }
        local hstruct = {
            year = nil,
            century = nil,
            text = nil,
            precision = 0
        }
        local snak = statement.mainsnak
        if snak.snaktype == 'novalue' then
            return struct, hstruct
        end
        if snak.snaktype == 'somevalue' then
            struct.text = '??'
            return struct, hstruct
        end
        
        struct,hstruct = parseWbTime(snak.datavalue.value,statement.qualifiers and statement.qualifiers.P4241)
        local prefix = ''
        if struct.precision == 8 then
            prefix = 'تقريبًا '
        end

        --Extract circa
        if statement.qualifiers ~= nil and statement.qualifiers.P1480 ~= nil then
            for _,qualifier in pairs(statement.qualifiers.P1480) do
                if qualifier.datavalue.value.id == 'Q5727902' then
                    prefix = 'تقريبًا '
                    struct.precision = 8 --TODO: hacky
                end
                if qualifier.datavalue.value.id == 'Q79030196' then
                    prefix = 'قبل '
                    struct.precision = 8 --TODO: hacky
                end
            end
        end
        --Use before and after if precision <= century
        if statement.qualifiers ~= nil and struct.precision <= 7 then
            if statement.qualifiers.P1319 ~= nil then
                for _,qualifier in pairs(statement.qualifiers.P1319) do
                    struct = parseWbTime(qualifier.datavalue.value)
                    prefix = 'بعد '
                    struct.precision = 8 --TODO: hacky
                end
            elseif statement.qualifiers.P1326 ~= nil then
                for _,qualifier in pairs(statement.qualifiers.P1326) do
                    struct = parseWbTime(qualifier.datavalue.value)
                    prefix = 'قبل '
                    struct.precision = 8 --TODO: hacky
                end
            elseif statement.qualifiers.P1317 ~= nil then
                for _,qualifier in pairs(statement.qualifiers.P1317) do
                    struct = parseWbTime(qualifier.datavalue.value)
                    prefix = 'عُرف في '
                    struct.precision = 8 --TODO: hacky
                end
            end
        end

        --Create text
        if struct.precision >= 8 then
            struct.text = prefix .. getTextForYear(struct.year)
            hstruct.text = prefix .. getTextForYear(hstruct.year,true)
        elseif struct.precision == 7 then
            struct.text = prefix .. getTextForCentury(struct.century, true)
            hstruct.text = prefix .. getTextForCentury(hstruct.century,true,true)
        else
            struct.text = errorMessage('تاريخ ' .. field .. ' لديه دقة منخفضة جدا على ويكي بيانات')
        end
        
        return struct,hstruct
    end

    function formatDates(birth, death, hbirth, hdeath, class)
        if birth.text == nil and death.text == nil then
            return ''
        end

        local htext = '('
        local text = ''

        if hbirth.text ~= nil then
            htext = htext .. hbirth.text .. ' '
        else
            htext = htext .. "000" .. ' '
        end

        if birth.precision >= 9 then
            local annotation = 'class="bday" itemprop="birthDate"'
            if class ~= "Q5" and class ~= nil then
                annotation = 'itemprop="foundingDate'
            end
            text = text .. '<time datetime="' .. birth.year .. '" ' .. annotation .. '>' .. birth.text .. '</time> '
        elseif birth.text ~= nil then
            text = text .. birth.text .. ' '
        else
            text = text .. "000" .. ' '
        end

        text = text .. '—'
        htext = htext .. '—'
        if hdeath.text ~= nil then
            htext = htext .. hdeath.text .. ' '
        else
            htext = htext .. "000" .. ' '
        end

        if death.precision >= 9 then
            local annotation = 'class="dday" itemprop="deathDate"'
            if class ~= "Q5" and class ~= nil then
                annotation = 'itemprop="dissolutionDate'
            end
            text = text .. ' <time datetime="' .. death.year .. '" ' .. annotation .. '>' .. death.text .. '</time>'
        elseif death.text ~= nil then
            text = text .. ' ' .. death.text
        end

        return htext .. ' = ' .. text .. ')'
    end

    function qidForProperty(item, property)
        local statements = item:getBestStatements(property)
        if statements[1] ~= nil and statements[1].mainsnak.datavalue ~= nil then
            return statements[1].mainsnak.datavalue.value.id
        end
        return nil
    end

    function searchKey(key)
        -- normally the key does not contain any diacritic but it's a common misuse
        -- of the clef = so handle at least the most usual diacritics, note than
        -- prenom can be empty
        local nom, prenom = mw.ustring.match(key, '^([ء-ي]*)[,]?[ ]*(.*)$')
        return prenom .. ' ' .. 'intitle:' .. nom
    end

    function add_category(html, category)
        if mw.title.getCurrentTitle().namespace == 102 then
            html:wikitext('[[تصنيف:' .. category .. ']]')
        end
    end

    function main(frame)
        --create a clean table of parameters with blank parameters removed
        local args = {}
        for k,v in pairs(frame:getParent().args) do
            if v ~= '' then
                args[k] = v
            end
        end

        local birth = getDateFromArgs(args, 'سنة الميلاد', 'الميلاد')
        local hbirth = getDateFromArgs(args, 'سنة الميلاد', 'الميلاد',true)
        local death = getDateFromArgs(args, 'سنة الوفاة', 'الوفاة')
        local hdeath = getDateFromArgs(args, 'سنة الوفاة', 'الوفاة',true)
        local sex = nil
        local class = nil
        local html = mw.html.create()

        html:wikitext('\n__لافهرس__')
            :wikitext('\n');

        if args['الاسم'] == nil and (args['الاسم الأخير'] or args['الاسم الأول']) then
            args['الاسم'] = (args['الاسم الأول'] or '') .. " " .. (args['الاسم الأخير'] or '')
        end
        --Utilise Wikidata si paramètres non renseignés
        local item = mw.wikibase.getEntity()
        if item == nil then
            add_category(html, 'صفحات مؤلفين دون عنصر ويكي بيانات')
        else
            if args['الاسم']  == nil then
                args['الاسم'] = item:getLabel()
            else
                add_category(html, 'صفحات تستخدم قالب مؤلف مع اسم محلي')
            end
            if args['وصف'] ~= nil then
                add_category(html, 'صفحات تستخدم قالب مؤلف مع وصف محلي')
            elseif item.descriptions ~= nil and item.descriptions.ar ~= nil then
                args['وصف'] = mw.text.trim(string.gsub(item.descriptions.ar.value, "%s+%(.*%)%s*", " "))
                if item.descriptions.ar.language ~= 'ar' then
                    args.descriptionLanguageCode = item.descriptions.ar.language
                end
            end
            if args['صورة'] == nil then
                local statements = item:getBestStatements('P154') -- logo
                if next(statements) == nil then
                    statements = item:getBestStatements('P18') --image
                end
                if next(statements) == nil then
                    statements = item:getBestStatements('P6802') -- image en rapport
                end
                if statements[1] ~= nil and statements[1].mainsnak.datavalue ~= nil then
                    args['صورة'] = statements[1].mainsnak.datavalue.value
                end
            else
                add_category(html, 'صفحات تستخدم قالب مؤلف مع وسيط صورة')
            end
            local birthWikidata,hbirthWikidata = getDateFromTimeStatements(item:getBestStatements('P569'), 'birth')
            if birthWikidata.precision == 0 then
                birthWikidata,hbirthWikidata = getDateFromTimeStatements(item:getBestStatements('P571'), 'creation')
            end

            if birth.text == nil then
                birth = birthWikidata
            else
                add_category(html, 'صفحات تستخدم قالب مؤلف بتاريخ محلي')
                if birthWikidata.text == nil then -- on utilise la date de création
                    add_category(html, 'صفحات تستخدم قالب مؤلف مع بيانات للترحيل')
                end
            end

            if hbirth.text == nil then
                hbirth = hbirthWikidata
            else
                add_category(html, 'صفحات تستخدم قالب مؤلف بتاريخ محلي')
                if hbirthWikidata.text == nil then -- on utilise la date de création
                    add_category(html, 'صفحات تستخدم قالب مؤلف مع بيانات للترحيل')
                end
            end

            local deathWikidata,hdeathWikidata = getDateFromTimeStatements(item:getBestStatements('P570'), 'death')
            if deathWikidata.precision == 0 then -- on utilise la date de dissolution
                deathWikidata,hdeathWikidata = getDateFromTimeStatements(item:getBestStatements('P576'), 'dissolution')
            end

            if death.text == nil then
                death = deathWikidata
            else
                add_category(html, 'صفحات تستخدم قالب مؤلف بتاريخ محلي')
                if deathWikidata.text == nil then
                    add_category(html, 'صفحات تستخدم قالب مؤلف مع بيانات للترحيل')
                end
            end

            if hdeath.text == nil then
                hdeath = hdeathWikidata
            else
                add_category(html, 'صفحات تستخدم قالب مؤلف بتاريخ محلي')
                if hdeathWikidata.text == nil then
                    add_category(html, 'صفحات تستخدم قالب مؤلف مع بيانات للترحيل')
                end
            end

            if args.pseudo == nil then
                args.pseudo = item:formatPropertyValues( 'P742' ).value
                if args.pseudo == '' then
                    args.pseudo = nil
                end
            elseif args.pseudo ~= '-' then
                add_category(html, 'Pages utilisant le modèle Auteur avec un pseudo local')
            end
            --sex
            sex = qidForProperty(item, 'P21')
            --class
            class = qidForProperty(item, 'P31')
        end

        if args['الاسم'] == nil then
            args['الاسم'] = mw.title.getCurrentTitle().text
            -- return errorMessage('وسيط "الاسم" إلزامي ويجب أن تحتوي على اسم المؤلف')
        end

        --sort key and initiale
        local firstName = args['الاسم الأول'] or ''
        local familyName = args['الاسم الأخير'] or ''
        if item ~= nil then
            --first name
            local firstNameStatements = item:getBestStatements('P735')
            if firstNameStatements[1] ~= nil then
                if firstNameStatements[1].mainsnak.type == 'value' then
                    local firstNameId = firstNameStatements[1].mainsnak.datavalue.value.id
                    firstName = mw.wikibase.label(firstNameId) or ''
                    --TODO check if the first name is not an initial
                elseif firstNameStatements[1].mainsnak.type == 'somevalue' then
                    add_category(html, 'Auteurs de prénom inconnu')
                end
            end
            --family name
            local familyNameId = qidForProperty(item, 'P734')
            if familyNameId ~= nil then
                familyName = mw.wikibase.label(familyNameId) or ''
            end
        end
        if familyName == '' then
            --We are in a simple case with first name and last name. TODO: bad hack, should be improved
            local nameParts = mw.text.split(args['الاسم'], ' ', true)
            if #nameParts == 1 then
                familyName = nameParts[1]
            elseif #nameParts> 1 then
                firstName = nameParts[1]
                familyName = nameParts[#nameParts]
            end
        end
        
        if args['مفتاح'] == nil then
            if familyName ~= '' then
                local moduleClassement = require 'Module:Classement'
                args['مفتاح'] = moduleClassement.getSortKeyForName({args = {firstName, familyName}})
            else
                return errorMessage('المعلمة "مفتاح" إلزامية ويجب أن تحتوي على مفتاح فرز للمؤلف')
            end
        else
            add_category(html, 'صفحات تستخدم قالب مؤلف مع مفتاح محلي')
        end

        if args['فهرس'] == nil then
            if args['مفتاح'] ~= nil then
                args['فهرس'] = mw.ustring.sub(args['مفتاح'], 1, 1)
            else
                return errorMessage('وسيط "الفهرس" مطلوب ويجب أن يحتوي على الحرف الأول من اسم المؤلف')
            end
        else
            add_category(html, 'صفحات تستخدم قالب مؤلف مع بيانات للترحيل')
        end

        local main = html:tag('div')
            :attr('itemscope', '')
            :css({['background-color'] = '#F1F1DE', ['overflow'] = 'auto', ['border-radius'] = '0.7em', ['box-shadow'] = '0.2em 0.3em 0.2em #B7B7B7'})

        if class == "Q5" or class == nil then
            main = main:attr('itemtype', 'http://schema.org/Person'):addClass('vcard')
        else
            main = main:attr('itemtype', 'http://schema.org/Organization')
        end

        if item ~= nil and item.id ~= nil then
            main:attr('itemid', 'http://www.wikidata.org/entity/' .. item.id)
        end

        --Image
        local image = args['صورة']
        if image ~= nil then
            main:tag('div')
            :css({['float'] = 'left', ['margin'] = '1em'})
            :wikitext('[[ملف:' .. image .. '|140px|alt=' .. args['الاسم'] .. '|class=photo]]')
        end

        --First row
        local firstRow = main:tag('div')

            --Categorie Auteur-X
            firstRow:tag('div')
                :css({['float'] = 'right', ['font-size'] = '115%', ['text-indent'] = '1em'})
                :tag('span')
                    :css('color', '#aaaa66')
                    :wikitext('►')
                    :done()
                :wikitext('&nbsp;[[ويكي مصدر:مؤلفون-' .. args['فهرس'] .. '|مؤلفون&nbsp;' .. args['فهرس'] .. ']]')

            --Title
            firstRow:tag('h1')
                :addClass('fn')
                :attr('itemprop', 'name')
                :css({['text-align'] = 'center', ['font-size'] = '160%', ['font-weight'] = 'bold', ['border-bottom'] = 'none'})
                :wikitext(args['الاسم'])
                :tag('br');
            
        --Second row
        local secondRow = main:tag('div')

            --Interwikis
            local interwikis = secondRow:tag('div')
                :css({['float'] = 'right', ['height'] = '50%', ['font-size'] = '75%', ['text-indent'] = '2em'})
                :node(createLinkRow('<span class="plainlinks">[//ar.wikisource.org/wiki/Special:IndexPages?key=' .. mw.uri.encode(searchKey(args['مفتاح'])) .. ' الفهارس]</span>', 'Wikisource'))
                if item ~= nil and item:getSitelink('arwiki') ~= nil then
                    interwikis:node(createLinkRow('[[w:' .. item:getSitelink('arwiki') .. '|السيرة]]', 'Wikipedia'))
                else
                    interwikis:node(createLinkRow('[[w:' .. args['الاسم'] .. '|<span style="color:#BA0000;">السيرة </span>]]', 'Wikipedia'))
                end
                if item ~= nil and item:getSitelink('arwikiquote') ~= nil then
                    interwikis:node(createLinkRow('[[q:' .. item:getSitelink('arwikiquote') .. '|اقتباسات]]', 'Wikiquote'))
                else
                    interwikis:node(createLinkRow('[[q:' .. args['الاسم'] .. '|<span style="color:#BA0000;">اقتباسات</span>]]', 'Wikiquote'))
                end

                if item ~= nil then
                    local commonsCat = item:formatPropertyValues('P373').value
                    if commonsCat ~= '' then
                        interwikis:node(createLinkRow('[[commons:Category:' .. commonsCat .. '|الوسائط]]', 'Commons'))
                    elseif item:getSitelink('commonswiki') ~= nil then
                        interwikis:node(createLinkRow('[[commons:' .. item:getSitelink('commonswiki') .. '|الوسائط]]', 'Commons'))
                    else
                        interwikis:node(createLinkRow('[[commons:' .. args['الاسم'] .. '|<span style="color:#BA0000;">الوسائط</span>]]', 'Commons'))
                    end
                else
                    interwikis:node(createLinkRow('[[commons:' .. args['الاسم'] .. '|<span style="color:#BA0000;">الوسائط</span>]]', 'Commons'))
                end

                if item ~= nil and item.id ~= nil then
                    interwikis:node(createLinkRow('[[d:' .. item.id .. '|ويكي بيانات]]', 'Wikidata'))
                else
                    interwikis:node(createLinkRow('<span class="plainlinks">[//www.wikidata.org/w/index.php?title=Special:NewItem&site=arwikisource&page=' .. mw.uri.encode(mw.title.getCurrentTitle().fullText) .. '&label=' .. mw.uri.encode(args['الاسم']) .. ' Données&nbsp;structurées</span>]</span>', 'Wikidata'))
                end

                secondRow:tag('div')
                :css({['text-align'] = 'center', ['font-size'] = '95%', ['line-height'] = '95%', ['padding'] = '1em'})
                :wikitext(formatDates(birth, death,hbirth, hdeath, class))
                :newline()

                --Description
            local fullDescription = secondRow:tag('div')
                :css({['text-align'] = 'center', ['font-size'] = '110%', ['line-height'] = '110%', ['padding'] = '1em'})
            local description = fullDescription:tag('span')
                :addClass('label')
                :attr('itemprop', 'description')
                :wikitext(args['وصف'] or '')
            if args.descriptionLanguageCode ~= nil then
                description:attr('lang', item.descriptions.ar.language)
                    :css('font-style', 'italic')
                add_category(html, 'صفحات تستخدم قالب مؤلف بلا وصف عربي')
            elseif args['وصف'] == nil then
                add_category(html, 'صفحات تستخدم قالب مؤلف بلا وصف عربي')
            end
            -- fullDescription
            -- :newline()
                -- :wikitext(formatDates(birth, death,hbirth, hdeath, class))
            if args.pseudo ~= nil and args.pseudo ~= '-' then
                fullDescription:tag('br')
                fullDescription:wikitext('Pseudonyme : ')
                    :tag('span')
                    :attr('itemprop', 'alternateName')
                    :css('font-style', 'italic')
                    :wikitext(args.pseudo)
            end

        --categories
        add_category(html, 'مؤلفون')
        add_category(html, 'مؤلفون-' .. args['فهرس'])
        --genre
        -- if args.genre ~= nil then
        -- 	add_category(html, 'Pages utilisant le modèle Auteur avec un genre local')
        -- 	html:wikitext(categorization('', args.genre))
        -- end
        -- html:wikitext(categorization('', args.genre))
        
        --langue
        if item ~= nil then
            for _, statement in pairs(item:getBestStatements('P6886')) do
                if statement.mainsnak.datavalue ~= nil then
                    local languageLabel = mw.wikibase.label(statement.mainsnak.datavalue.value.id)
                    if languageLabel ~= nil then
                        categoryName = 'تصنيف:مؤلفون يكتبون بـ' .. mw.wikibase.label(statement.mainsnak.datavalue.value.id)
                        html:wikitext('[[' .. categoryName .. ']]')
                        if not mw.title.new( categoryName ).exists then
                            html:wikitext('[[تصنيف:صفحات تستخدم قالب مؤلف مع فئة لغة غير موجودة]]')
                        end
                    end
                end
            end
        end
        if args.langue ~= nil then
            add_category(html, 'صفحات تستخدم قالب مؤلف بوسيط لغة محلي')
        end
        --الجنسيات
        -- local categoryForCountry = mw.loadData('Module:Auteur2/nationalités')
        -- local withNationality = false
        -- if item ~= nil then
        -- 	for _, statement in pairs(item:getBestStatements('P27')) do
        -- 		if statement.mainsnak.datavalue ~= nil then
        -- 			countryId = statement.mainsnak.datavalue.value.id
        -- 			if categoryForCountry[countryId] == nil then
        -- 				add_category(html, 'Pages utilisant le modèle Auteur avec une nationalité sans catégorie')
        -- 				withNationality = true
        -- 			elseif categoryForCountry[countryId] then
        -- 				add_category(html, categoryForCountry[countryId])
        -- 				withNationality = true
        -- 			end
        -- 		end
        -- 	end
        -- end
        -- if args.pays ~= nil then
        -- 	add_category(html, 'Pages utilisant le modèle Auteur avec une nationalité locale')
        -- 	withNationality = true
        -- end
        -- if not withNationality then
        -- 	add_category(html, 'Pages « Auteur » sans nationalité')
        -- end

        --الوظائف
        -- categoryForOccupation = mw.loadData('Module:Auteur2/occupations')
        -- if item ~= nil then
        -- 	for _, statement in pairs(item:getBestStatements('P106')) do
        -- 		if statement.mainsnak.datavalue ~= nil then
        -- 			occupationId = statement.mainsnak.datavalue.value.id
        -- 			if categoryForOccupation[occupationId] == nil then
        -- 				add_category(html, 'Pages utilisant le modèle Auteur avec une occupation sans catégorie')
        -- 			elseif categoryForOccupation[occupationId] then
        -- 				add_category(html, categoryForOccupation[occupationId])
        -- 			end
        -- 		end
        -- 	end
        -- end
        -- if args.metier ~= nil or args["métier"] ~= nil then
        -- 	html:wikitext(categorization('', args.metier or args["métier"]))
        -- 	add_category(html, 'Pages utilisant le modèle Auteur avec une occupation locale')
        -- end
        --prix
        if args['جائزة'] ~= nil then
            html:wikitext(categorization('حائزون على', args['جائزة']))
            add_category(html, 'صفحات تستخدم قالب مؤلف بوسيط جائزة محلي')
        end
        if item ~= nil then
            for _, awardStatement in pairs(item:getBestStatements('P166')) do
                if awardStatement.mainsnak.datavalue ~= nil then
                    distinctionItem = mw.wikibase.getEntity(awardStatement.mainsnak.datavalue.value.id)
                    for _, awardeeCatStatement in pairs(distinctionItem:getBestStatements('P2517')) do
                        if awardeeCatStatement.mainsnak.datavalue ~= nil then
                            wikisourceCategory = mw.wikibase.sitelink(awardeeCatStatement.mainsnak.datavalue.value.id)
                            if wikisourceCategory then
                                html:wikitext('[[' .. wikisourceCategory .. ']]')
                            end
                        end
                    end
                end
            end
        end

        --categorie dates
        if birth.precision >= 9 and birth.year > 1500 then
            add_category(html, 'مواليد ' .. birth.year)
        end
        if death.precision >= 9 and death.year > 1500 then
            add_category(html, 'وفيات ' .. death.year)
        end

        if hbirth.precision >= 9 and hbirth.year > -13 then
            add_category(html, 'مواليد ' .. hbirth.year .. ' هـ')
        end
        if hdeath.precision >= 9 and hdeath.year > -13 then
            add_category(html, 'وفيات ' .. hdeath.year  .. ' هـ')
        end

        local withoutEpoque = true
        if birth.century ~= nil and (birth.precision < 9 or birth.year <= birth.century * 100 - 20) then
            if 15 <= birth.century then
                add_category(html, 'مؤلفو القرن ' .. getTextForCentury(birth.century, false))
            elseif 6 <= birth.century and birth.century <= 14 then
                add_category(html, 'مؤلفو القرون الوسطى الميلادية')
            else
                add_category(html, 'كتاب قدماء')
            end
            withoutEpoque = false
        end

        if death.century ~= nil and (death.precision < 9 or (death.century - 1) * 100 + 5 <= death.year) then
            if 15 <= death.century then
                add_category(html, 'مؤلفو القرن ' .. getTextForCentury(death.century, false))
            elseif 6 <= death.century and death.century <= 14 then
                add_category(html, 'مؤلفو القرون الوسطى الميلادية')
            else
                add_category(html, 'كتاب قدماء')
            end
            withoutEpoque = false
        end

        if hbirth.century ~= nil and (hbirth.precision < 9 or hbirth.year <= hbirth.century * 100 - 20) then
            if 0 <= hbirth.century then
                add_category(html, 'مؤلفو القرن ' .. getTextForCentury(hbirth.century, false,true))
            end
            withoutEpoque = false
        end

        if hdeath.century ~= nil and (hdeath.precision < 9 or (hdeath.century - 1) * 100 + 5 <= hdeath.year) then
            if 0 <= hdeath.century then
                add_category(html, 'مؤلفو القرن ' .. getTextForCentury(hdeath.century, false, true))
            elseif 0 >= hdeath.century then
                add_category(html, 'مؤلفو عصر ما قبل الإسلام')
            end
            withoutEpoque = false
        end

        if withoutEpoque then
            add_category(html, 'عصر مجهول')
        end
        if sex == 'Q6581072' then
            add_category(html, 'مؤلفات')
        end

        --droits
        -- if args.droits == nil then
        -- 	args.droits = '70'
        -- end
        -- droitsNumber = tonumber(args.droits)
        -- if args.droits == 'mpf' then
        -- 	if death.precision >= 9 and tonumber(os.date("%Y")) <= death.year + 95 then --TODO: guess 'mpf' from P166:Q3324507 in Wikidata?
        -- 		html:wikitext(frame:expandTemplate({title = 'Auteur Mort pour la France'}))
        -- 	end
        -- 	add_category(html, 'Auteurs morts pour la France')
        -- elseif args.droits == 'non' then
        -- 	--rien à faire
        -- elseif droitsNumber ~= nil then
        -- 	if death.year ~= nil and tonumber(os.date("%Y")) <= death.year + droitsNumber then --XX ans on vérifie le DP-EU
        -- 		if birth.year == nil or 1923 - birth.year > 20 then
        -- 			html:wikitext(frame:expandTemplate({title = 'DP-EU-Auteur'}))
        -- 		end
        -- 	end
        -- 	if args.droits ~= '70' then
        -- 	add_category(html, 'Droits d’auteur ' .. args.droits .. ' ans')
        -- 	end
        -- else
        -- 	return errorMessage('Le paramètre droit contient une valeur non supportés. Valeurs possibles : 70/60/50 (durée du droit d\'auteur), "mpf" (mort pour la france). Par défaut: 70')
        -- end
        

        --maintenance

        if args['مفتاح'] ~= nil then
            html:wikitext(frame:preprocess('{{DEFAULTSORT:' .. args['مفتاح'] .. '}}'))
        end

        -- contenu
        -- html:wikitext('\n__لافهرس__')
        -- 	:wikitext('\n');
        if args['محتوى'] then
            html:wikitext(args['محتوى'])
            :wikitext('\n')
            :wikitext((require 'Module:ضبط استنادي').authorityControl(frame))
        end
        
        return tostring(html)
    end

    local p = {};

    function p.author( frame )
        return main( frame )
    end

    return p