Editing Module:Lang

Warning: You are not logged in. Once you make an edit, a temporary account will be created for you. Learn more. Log in or create an account to continue receiving notifications after this account expires, and to access other features.
The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.
Latest revision Your text
Line 7: Line 7:
-- the expected key does not have a localization entry
-- the expected key does not have a localization entry
local KEY_OVERRIDES = {
local KEY_OVERRIDES = {
BurnDurationBase_label = 'AfterburnDurationBase_label',
BurnDurationBase_postfix = 'AfterburnDurationBase_postfix',
     MoveSlowPercent_label = 'MovementSlow_label',
     MoveSlowPercent_label = 'MovementSlow_label',
     BonusHealthRegen_label = 'HealthRegen_label',
     BonusHealthRegen_label = 'HealthRegen_label',
Line 19: Line 17:
     EvasionChance_label = 'EvasionChance_Label',
     EvasionChance_label = 'EvasionChance_Label',
     DelayBetweenShots_label = 'DelayBetweenShots_Label',
     DelayBetweenShots_label = 'DelayBetweenShots_Label',
    MoveSlowDuration_postfix = 'EnemyMoveSlowDuration_postfix',
    StaminaRecoveryDisabledDuration_postfix = 'AbilityDuration_postfix',
    PostInvisBuffDuration_label = 'BuffDuration_label',
    PostInvisBuffDuration_postfix = 'BuffDuration_postfix',
    ProjectileFuse_label = 'BellLifetime_label',
    ProjectileFuse_postfix = 'BellLifetime_postfix',
    SelfBuffDuration_label = 'BuffDuration_label',
    SelfBuffDuration_postfix = 'BuffDuration_postfix',
    LifeStealPercentOnHit_label = 'LifestealPercentOnHit_label',
    LifeStealPercentOnHit_postfix = 'LifestealPercentOnHit_postfix',
    AuraFireRateBonus_label = 'FireRateBonus_label',
    AuraFireRateBonus_postfix = 'FireRateBonus_postfix',
    MoveSlowDuration_label = 'SlowDuration_label',
    MoveSlowDuration_postfix = 'SlowDuration_postfix',
DashRange_label = 'TargetDashRadius_label',
DashRange_postfix = 'TargetDashRadius_postfix',
SpeedOnLandDuration_label = 'BuffDuration_label',
SpeedOnLandDuration_postfix = 'BuffDuration_postfix',
SummonCount_label = 'GhoulCount_label',
TetherDuration_label = 'ImmobilizeTrap_CurseDuration_label'
}
}


Line 54: Line 32:
     if not text or type(text) ~= "string" then return text end
     if not text or type(text) ~= "string" then return text end
     -- Replace "n with newline character
     -- Replace "n with newline character
     return text:gsub('"n', '<br/>')
     return text:gsub('"n', '\n')
end
end


Line 61: Line 39:
      
      
     local replacements = {
     local replacements = {
    BonusFireRate = {icon='{{Icon/Brown|[[File:Fire_Rate.png|link=Fire Rate|20px]]}}', label_color='#ffefd7', link='Fire Rate'},
        SpiritIcon = '{{Icon/Purple|[[File:AttributeIconTechShieldHealth.png|link=Spirit Damage|12px]]}}',
    BonusMoveSpeed = {icon='{{Icon/Green|[[File:Move_speed.png|link=Move speed|20px]]}}', label_color='#ffefd7', link='Move speed'},
        SpiritDamage = '{{Icon/Purple|[[File:AttributeIconTechShieldHealth.png|link=Spirit Damage|12px]]}}<span style="color:#bc8ee8;font-weight: bold;">{{#invoke:Lang|get_string|InlineAttribute_SpiritDamage}}</span>',
    BonusSprintSpeed = {icon='{{Icon/Green|[[File:Move_speed.png|link=Sprint speed|20px]]}}', label_color='#ffefd7', link='Sprint speed'},
        SpiritResist = '{{Icon/Purple|[[File:Spirit_Armor.png|link=Damage_Resistance|20px]]}}<span style="color:#bc8ee8;font-weight: bold;">{{#invoke:Lang|get_string|InlineAttribute_SpiritResist}}</span>',
    BonusSpiritDamage = {icon='{{Icon/NoColor|[[File:Spirit damage.png|link=Spirit Damage|20px]]}}', label_color='#bc8ee8', link='Spirit Damage'},
        FireRate = '{{Icon/White|[[File:Fire_Rate.png|link=Fire Rate|20px]]}}<span style="color:#ffefd7;font-weight: bold;">{{#invoke:Lang|get_string|InlineAttribute_FireRate}}</span>',
    BonusWeaponDamage = {icon='{{Icon/NoColor|[[File:Bullet Damage.png|link=Weapon Damage|20px]]}}', label_color='#ec981a', link='Weapon Damage'},
        ReducedFireRate = '{{Icon/White|[[File:Fire_Rate.png|link=Fire Rate|20px]]}}<span style="color:#ffefd7;font-weight: bold;">{{#invoke:Lang|get_string|InlineAttribute_ReducedFireRate}}</span>',
    bullet_armor_up = {icon='{{Icon/White|[[File:Barrier.png|link=Barrier|20px]]}}', label_color='#ffefd7', link='Barrier'},
        MeleeDamage = '{{Icon/Brown|[[File:Melee damage.png|link=Melee Damage|20px]]}}<span style="font-weight: bold;color:#ec981a">{{#invoke:Lang|get_string|InlineAttribute_MeleeDamage}}</span>',
    bullet_damage = {icon='{{Icon/NoColor|[[File:Bullet_damage.png|link=Weapon Damage|20px]]}}', label_color='#ec981a', link='Weapon Damage'},
        WeaponDamage = '{{Icon/Brown|[[File:Damage.png|link=Weapon Damage|20px]]}}<span style="color:#ec981a;font-weight: bold;">{{#invoke:Lang|get_string|InlineAttribute_WeaponDamage}}</span>',
    BulletResist = {icon='{{Icon/Brown|[[File:Bullet_Armor.png|link=Damage_Resistance|20px]]}}', label_color='#ec981a', link='Damage_Resistance'},
        BulletResist = '{{Icon/Brown|[[File:Bullet_Armor.png|link=Damage_Resistance|20px]]}}<span style="color:#ec981a;font-weight: bold;">{{#invoke:Lang|get_string|InlineAttribute_BulletResist}}</span>',
    cast = {icon='{{Icon/White|[[File:Cast.png|link=|20px]]}}', label_color='#ffefd7', link=''},
        BonusWeaponDamage = '{{Icon/Brown|[[File:Damage.png|link=Weapon Damage|20px]]}}<span style="color:#ec981a;font-weight: bold;">{{#invoke:Lang|get_string|InlineAttribute_BonusWeaponDamage}}</span>',
    CombatBarrier = {icon='{{Icon/White|[[File:Bullet Armor (item).png|link=Damage_Resistance|20px]]}}', label_color='#ffefd7', link='Barrier'},
        MoveSpeed = '{{Icon/White|[[File:Move_speed.png|link=Move speed|20px]]}}<span style="color:#ffefd7;font-weight: bold;">{{#invoke:Lang|get_string|InlineAttribute_MoveSpeed}}</span>',
    cooldown = {icon='{{Icon/White|[[File:AttributeIconTechDuration.png|link=Ability Cooldown|20px]]}}', label_color='#ffefd7', link='Ability Cooldown'},
        BonusSpiritDamage = '{{Icon/Purple|[[File:AttributeIconTechShieldHealth.png|link=Spirit Damage|12px]]}}<span style="color:#bc8ee8;font-weight: bold;">{{#invoke:Lang|get_string|InlineAttribute_BonusSpiritDamage}}</span>',
    damage = {icon='{{Icon/NoColor|[[File:Damage heart.png|link=Damage|20px]]}}', label_color='#ec981a', link='Damage'},
        BonusFireRate =     '{{Icon/White|[[File:Fire_Rate.png|link=Fire Rate|20px]]}}<span style="color:#ffefd7;font-weight: bold;">{{#invoke:Lang|get_string|InlineAttribute_BonusFireRate}}</span>',
    DamageAmp = {icon='{{Icon/White|[[File:Damage heart.png|link=Damage Amp|20px]]}}', label_color='#ffefd7', link='Damage Amp'},
        Heal =             '{{Icon/Green|[[File:Health_regen.png|link=Health_Regen|20px]]}}<span style="color:#13f278;font-weight: bold;">{{#invoke:Lang|get_string|InlineAttribute_Heal}}</span>',
    FireRate = {icon='{{Icon/White|[[File:Fire_Rate.png|link=Fire Rate|20px]]}}', label_color='#ffefd7', link='Fire Rate'},
        BonusMoveSpeed =   '{{Icon/White|[[File:Move_speed.png|link=Move speed|20px]]}}<span style="color:#ffefd7;font-weight: bold;">{{#invoke:Lang|get_string|InlineAttribute_BonusMoveSpeed}}</span>',
    fire_rate = {icon='{{Icon/White|[[File:Fire_Rate.png|link=Fire Rate|20px]]}}', label_color='#ffefd7', link='Fire Rate'},
        Spirit =           '{{Icon/NoColor|[[File:Spirit_icon.png|link=Spirit Power|20px]]}}<span style="color:#bc8ee8;font-weight: bold;">{{#invoke:Lang|get_string|InlineAttribute_Spirit}}</span>',
    Heal = {icon='{{Icon/Green|[[File:Healing.png|link=Health_Regen|20px]]}}', label_color='#13f278', link='Health_Regen'},
        Stun =             '{{Icon/White|[[File:Status_Stun.png|link=Stun|20px]]}}<span style="font-weight: bold;">{{#invoke:Lang|get_string|InlineAttribute_Stun}}</span>',
    Healing = {icon='{{Icon/Green|[[File:Healing.png|link=Healing|20px]]}}', label_color='#13f278', link='Healing'},
        SpiritDPS =         '{{Icon/Purple|[[File:AttributeIconTechShieldHealth.png|link=Spirit Damage|12px]]}}<span style="color:#bc8ee8;font-weight: bold;">{{#invoke:Lang|get_string|InlineAttribute_SpiritDPS}}</span>',
    Immobilize = {icon='{{Icon/White|[[File:Immobilize.png|link=Status Effects#Immobilized|20px]]}}', label_color='#ffefd7', link='Status Effects#Immobilized'},
    Healing =           '{{Icon/Green|[[File:Health_regen.png|link=Healing|20px]]}}<span style="color:#13f278;font-weight: bold;">{{#invoke:Lang|get_string|InlineAttribute_Healing}}</span>',
    invisible = {icon='{{Icon/White|[[File:Invisible.png|link=|20px]]}}', label_color='#ffefd7', link=''},
    Regen =             '{{Icon/Green|[[File:Health_regen.png|link=Health_Regen|20px]]}}<span style="color:#13f278;font-weight: bold;">{{#invoke:Lang|get_string|InlineAttribute_Regen}}</span>',
    KnockBack = {icon='{{Icon/NoColor|[[File:Displacement.png|link=|20px]]}}', label_color='#ffefd7', link='Status_Effects'},
    Slow = '{{Icon/White|[[File:MoveSlow.png|link=Movement_Slow|20px]]}}<span style="color:#ffefd7;font-weight: bold;">{{#invoke:Lang|get_string|InlineAttribute_Slow}}</span>',
    KnockUp =  {icon='{{Icon/NoColor|[[File:Displacement.png|link=|20px]]}}', label_color='#ffefd7', link='Status_Effects'},
    SlowResistance = '{{Icon/White|[[File:MoveSlow.png|link=Movement_Slow#Movement_Slow_Resist|20px]]}}<span style="color:#ffefd7;font-weight: bold;">{{#invoke:Lang|get_string|InlineAttribute_SlowResistance}}</span>',
    MaxHealth = {icon='{{Icon/Green|[[File:Healing.png|link=Health|20px]]}}', label_color='#13f278', link='Health'},
    }
    MeleeDamage = {icon='{{Icon/Brown|[[File:Melee damage.png|link=Melee Damage|20px]]}}', label_color='#ec981a', link='Melee Damage'},
   
    MoveSpeed = {icon='{{Icon/Green|[[File:Move_speed.png|link=Move speed|20px]]}}', label_color='#ffefd7', link='Move speed'},
    -- Process citadel_inline_attribute tags
    move_speed = {icon='{{Icon/Green|[[File:Move_speed.png|link=Move speed|20px]]}}', label_color='#ffefd7', link='Move speed'},
    text = text:gsub("{g:citadel_inline_attribute:'(.-)'}", function(key)
    Pull =      {icon='{{Icon/NoColor|[[File:Displacement.png|link=|20px]]}}', label_color='#ffefd7', link='Status_Effects'},
        if replacements[key] then
    Pulling =  {icon='{{Icon/NoColor|[[File:Displacement.png|link=|20px]]}}', label_color='#ffefd7', link='Status_Effects'},
            return replacements[key]
    Pulls =    {icon='{{Icon/NoColor|[[File:Displacement.png|link=|20px]]}}', label_color='#ffefd7', link='Status_Effects'},
        else
    PureDamage = {icon='{{Icon/NoColor|[[File:Damage.png|link=Pure Damage|20px]]}}', label_color='#ffefd7', link='Pure Damage'},
            return '<span style="color:red;font-weight:bold;border-bottom:1px dotted red;" title="Missing attribute definition - Add \''..key..'\' to local replacements in [Module:Lang]">['..key..']</span>'
    ReducedFireRate = {icon='{{Icon/Brown|[[File:Fire_Rate.png|link=Fire Rate|20px]]}}', label_color='#ffefd7', link='Fire Rate'},
        end
    Regen = {icon='{{Icon/Green|[[File:Healing.png|link=Health_Regen|20px]]}}', label_color='#13f278', link='Health_Regen'},
    end)
    revealed = {icon='{{Icon/White|[[File:Revealed.png|link=|20px]]}}', label_color='#ffefd7', link=''},
   
    silence = {icon='{{Icon/White|[[File:Silence.png|link=|20px]]}}', label_color='#ffefd7', link=''},
    Silence = {icon='{{Icon/Purple|[[File:Silence.png|link=Silence|20px]]}}', label_color='#bc8ee8', link='Silence'},
    Slow = {icon='{{Icon/White|[[File:MoveSlow.png|link=Movement_Slow|20px]]}}', label_color='#ffefd7', link='Movement_Slow'},
    slow = {icon='{{Icon/White|[[File:MoveSlow.png|link=Movement_Slow|20px]]}}', label_color='#ffefd7', link='Movement_Slow'},
    SlowResistance = {icon='{{Icon/White|[[File:MoveSlow.png|link=Movement_Slow#Movement_Slow_Resist|20px]]}}', label_color='#ffefd7', link='Movement_Slow#Movement_Slow_Resist'},
    Spirit = {icon='{{Icon/NoColor|[[File:Spirit_icon.png|link=Spirit Power|20px]]}}', label_color='#bc8ee8', link='Spirit Power'},
    SpiritDamage = {icon='{{Icon/NoColor|[[File:Spirit damage.png|link=Spirit Damage|20px]]}}', label_color='#bc8ee8', link='Spirit Damage'},
    SpiritDPS = {icon='{{Icon/NoColor|[[File:Spirit damage.png|link=Spirit Damage|20px]]}}', label_color='#bc8ee8', link='Spirit Damage'},
    SpiritIcon = {icon='{{Icon/NoColor|[[File:Spirit damage.png|link=Spirit Damage|20px]]}}', link='Spirit Damage'},
    SpiritResist = {icon='{{Icon/Purple|[[File:Spirit_Armor.png|link=Damage_Resistance|20px]]}}', label_color='#bc8ee8', link='Damage_Resistance'},
    StatDesc_TechPower = {icon='{{Icon/NoColor|[[File:Spirit damage.png|link=Spirit Damage|20px]]}}', label_color='#bc8ee8', link='Spirit Damage'},
    Stun = {icon='{{Icon/White|[[File:Status_Stun.png|link=Stun|20px]]}}', link='Stun'},
    stun = {icon='{{Icon/White|[[File:Stun.png|link=|20px]]}}', label_color='#ffefd7', link=''},
    tech_armor_up = {icon='{{Icon/White|[[File:Barrier.png|link=Barrier|20px]]}}', label_color='#ffefd7', link='Barrier'},
    tech_damage = {icon='{{Icon/NoColor|[[File:Spirit damage.png|link=Spirit Damage|20px]]}}', link='Spirit Damage'},
    WeaponDamage = {icon='{{Icon/NoColor|[[File:Bullet Damage.png|link=Weapon Damage|20px]]}}', label_color='#ec981a', link='Weapon Damage'},
    Heal = {icon='{{Icon/Green|[[File:Healing.png|link=Healing|20px]]}}', label_color='#13f278', link='Healing'},
    Heals = {icon='{{Icon/Green|[[File:Healing.png|link=Healing|20px]]}}', label_color='#13f278', link='Healing'},
}
 
     -- Process HTML spans
     -- Process HTML spans
     text = text:gsub('<span class="highlight">(.-)</span>', "<span style= font-weight:bold>%1</span>")
     text = text:gsub('<span class="highlight">(.-)</span>', "<span style= font-weight:bold>%1</span>")
    text = text:gsub('<span class="highlight_spirit">(.-)</span>', '<span style="font-weight:bold; color:#bc8ee8">%1</span>')
    text = text:gsub('<span class="highlight_courage">(.-)</span>', '<span style="font-weight:bold; color:#ec981a">%1</span>')
     text = text:gsub('<span class="diminish">(.-)</span>', '<span style="font-style: italic;color:#C0C0C0">%1</span>')
     text = text:gsub('<span class="diminish">(.-)</span>', '<span style="font-style: italic;color:#C0C0C0">%1</span>')
     text = text:gsub('<span class=".-">(.-)</span>', '%1')
     text = text:gsub('<span class=".-">(.-)</span>', '%1')
    text = text:gsub('<Panel class=\"AbilityPropertyIcon StatDesc_TechPower\">', '{{Icon/Purple|[[File:Spirit damage.png|link=Spirit Damage|20px]]}}')
    text = text:gsub('</Panel>', '')
   
    -- Process panel tags
text = text:gsub('<Panel class=\"AbilityPropertyIcon prop_(.-)\">', function(key)
    local replacement = replacements[key]
    if replacement then
        local label_color = replacement.label_color or 'inherit'
        local icon = replacement.icon or ''
        local link = replacement.link or ''
        -- pre-process string, then check to omit link if the string is empty
        local translated = frame:preprocess('{{#invoke:Lang|get_string|InlineAttribute_' .. key .. '}}')
       
        if translated == '' then
            return string.format('<span class="no-blue-link" style="text-wrap:nowrap; font-weight:bold; color:%s;">%s</span>', label_color, icon)
        else
            return string.format('<span class="no-blue-link" style="text-wrap:nowrap; font-weight:bold; color:%s;">%s [[%s|%s]]</span>',
                label_color,
                icon,
                link,
                translated)
        end
    else
        return '<span style="color:red;font-weight:bold;border-bottom:1px dotted red;" title="Missing attribute definition - Add \''..key..'\' to local replacements in [Module:Lang]">['..key..']</span>'
    end
end)
   
    -- Process citadel_inline_attribute tags
text = text:gsub("{g:citadel_inline_attribute:'(.-)'}", function(key)
    local replacement = replacements[key]
    if replacement then
        local label_color = replacement.label_color or 'inherit'
        local icon = replacement.icon or ''
        local link = replacement.link or ''
        -- pre-process string, then check to omit link if the string is empty
        local translated = frame:preprocess('{{#invoke:Lang|get_string|InlineAttribute_' .. key .. '}}')
       
        if translated == '' then
            return string.format('<span class="no-blue-link" style="text-wrap:nowrap; font-weight:bold; color:%s;">%s</span>', label_color, icon)
        else
            return string.format('<span class="no-blue-link" style="text-wrap:nowrap; font-weight:bold; color:%s;">%s [[%s|%s]]</span>',
                label_color,
                icon,
                link,
                translated)
        end
    else
        return '<span style="color:red;font-weight:bold;border-bottom:1px dotted red;" title="Missing attribute definition - Add \''..key..'\' to local replacements in [Module:Lang]">['..key..']</span>'
    end
end)
   
    -- List for keybinds with mismatched names. Replace with the correct name under "citadel_keybind_[key]" in Data:Lang
    keybinds = {
        MoveForward = "forward",
        AltCast = "alt_cast",
        }
   
    -- Process citadel_binding/citadel_keybind tags to replace with keybind strings/templates
text = text:gsub("{g:citadel_binding:'(.-)'}", function(key)
  -- convert key to lowercase
        local lower_key = key:lower()
        -- look up key with Module:Lang. check if it has a replacement key first
        local replacement = keybinds[key] or lower_key
        local translated = frame:preprocess('{{#invoke:Lang|get_string|citadel_keybind_'.. replacement ..'}}')
  if translated ~= nil and translated ~= '' then
        return "'''" .. translated .. "'''"
        else
            return '<span style="color:red;font-weight:bold;border-bottom:1px dotted red;" title="Missing keybind - Add \''..key..'\' to local replacements in [Module:Lang]">['..key..']</span>'
        end
end)
    -- Force spaces around keybinds where the source data omits them
    text = text:gsub("'''([a-zA-Z])", "''' %1")


     -- Clean up extra spaces between a keybind and following punctuation
     return frame:preprocess(text)
    text = text:gsub("'''%s+:", "''':")
 
return frame:preprocess(text)
end
end




function p.get_string(key, lang_code_override, fallback_str, remove_var_index, item_name)
function p.get_string(key, lang_code_override, fallback_str, remove_var_index)
     -- Get frame object (either passed directly or via first argument)
     -- Get frame object (either passed directly or via first argument)
     local frame
     local frame
     if type(key) == "table" and key.args then
     if type(key) == "table" and key.args then
         frame = type(key.preprocess) == "function" and key or mw.getCurrentFrame()
         frame = key
          
         key = frame.args[1]
        local args = key.args
         lang_code_override = frame.args["lang_code_override"]
        key = args[1]
         fallback_str = frame.args["fallback_str"]
         lang_code_override = args["lang_code_override"]
         remove_var_index = frame.args["remove_var_index"]
         fallback_str = args["fallback_str"]
         remove_var_index = args["remove_var_index"]
        item_name = args["item_name"]
     else
     else
         frame = mw.getCurrentFrame()
         frame = mw.getCurrentFrame()
Line 230: Line 107:
     -- Localize
     -- Localize
     local label = data[KEY_OVERRIDES[key] or key]
     local label = data[KEY_OVERRIDES[key] or key]
-- Some labels use key with "_postvalue_label" instead, so check this if previous search failed
if label == nil and key ~= nil and key:sub(-6) == '_label' then
    local postvalue_key = key:sub(1, -7) .. '_postvalue_label'
    label = data[postvalue_key]
end
     if (label == nil) then
     if (label == nil) then
         -- Apply fallback (without HTML processing for fallback)
         -- Apply fallback (without HTML processing for fallback)
Line 242: Line 112:
         local fallback
         local fallback
         if (fallback_str == 'en') then
         if (fallback_str == 'en') then
             fallback = p.get_string(key, 'en', key .. fallback_tooltip, remove_var_index, item_name)
             fallback = p.get_string(key, 'en', key .. fallback_tooltip, remove_var_index)
         elseif fallback_str == 'dictionary' then
         elseif fallback_str == 'dictionary' then
             return dictionary_module.translate(key, lang_code_override)
             return dictionary_module.translate(key, lang_code_override)
Line 253: Line 123:
     end
     end
      
      
    -- Always retrieve the last parameter if string contains "|"
    if type(label) == "string" and label:find("|") then
        local parts = mw.text.split(label, "|")
        label = parts[#parts]
    end
   
  -- Remove hashtags
  if type(label) == "string" and label:find("#") then
        local parts = mw.text.split(label, "#")
        label = parts[#parts]
    end
     -- Apply remove_var
     -- Apply remove_var
     if (remove_var_index ~= nil) then  
     if (remove_var_index ~= nil) then  
         label = util_module.remove_var(label, remove_var_index)
         label = util_module.remove_var(label, remove_var_index)
    end
   
    -- Process variables if item_name is provided
    if item_name and item_name ~= '' then
        local item_data_module = require('Module:ItemData')
        label = label:gsub("{s:([^}]+)}", function(variable_name)
            -- Get the value from ItemData
            local value = item_data_module.get_prop({args = {item_name, variable_name}})
           
            -- If value exists, remove non-number symbols (but keep + and -)
            if value then
                value = value:gsub("[^0-9+-.]", "")
                -- Return empty string if nothing left, otherwise return the filtered value
                return value ~= "" and value or variable_name
            else
                return variable_name -- Fallback to variable name if value not found
            end
        end)
     end
     end
      
      
Please note that all contributions to The Deadlock Wiki are considered to be released under the Creative Commons Attribution-NonCommercial-ShareAlike (see Deadlock:Copyrights for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource. Do not submit copyrighted work without permission!
Cancel Editing help (opens in new window)
Preview page with this template