Разговор о Медијавикију:FileUploadWizard.js/Архива 1

Архива 1 Архива 2

Поправке

Требало би исправити сљедеће:

  • примакнуту црту заменити са одмакнутом јер се не повезује нпр. „Ауторство—Дијелити” (ово двоје нема никакве међусобне везе) него се раздваја „Кријејтив комонс Ауторство” и остатак с десне стране
  • „Ауторство” би требало да буде малим почетним словом, не знам који је разлог за велико јер „Attribution” не означава никакву властиту именицу него је оно енгл. истицање свих ријечи великим почетним словом осим везника и др., мада може се посматрати и као издвојени дио али ја не знам да ли то или ово прво (ако је устаљено досад било писање великим словом, па чак и писање с примакнутом цртом, онда се не исплати мијењати на хиљаду мјеста [доле удну стоји „Текст је доступан под лиценцом Кријејтив комонс Ауторство—Делити под истим условима”] — разлог више за екавицу а мање за исправљање црте и размишљање о овом великом слову)
  • „посвјећивање” је сигурно „посвећивање” и на ијекавици и на екавици (а требаће ја мислим све пребацити на екавицу, и онај образац и ово, јер софтвер је цијели колико знам на екавици па не би требало правити изузетак са овим обрасцем)
  • „Кријејтив комонс-нула” замијенити са „КК-нула”; у ствари тај ред бих ја ставио да буде „Предавање у универзално јавно власништво (cc-0)” јер је тако досљедно
  • „доле” је „доље” на ијекавици; боље је замијенити ово са „испод”
  • „Јавном власништво” треба да буде или „Јавном власништву” или „Јавно власништво”
  • „Ставка” и „предмет” промијенити у „Дјело”

Овдје ћу додати још ствари за исправити како будем прегледао онај образац и овај Медијавики...  Обсусер 13:07, 27. октобар 2016. (CEST)Одговори

Преводи

<b>No</b>, I want to upload this file here on this wiki only.<br/>" + 
          "<small>This way it can be used only on the English Wikipedia. However, somebody " +
          "else might still decide to copy it to Commons or use it elsewhere later. If you " +
          "do not want your file to be copied to Commons and deleted locally, consider adding " +
          "{{tl|Keep local}}.</small>") :
         "Upload this file.";
   fuwGet('SubmitButton').value = validForCommons ? "Upload locally" : "Upload";
<b>Не</b>, желим да ову датотеку отпремим овдје, само на ову Википедију.<br/>" + 
          "<small>Овако ће се датотека моћи користити само на Википедији на српском језику. Међутим, неко " +
          "други би могао да је копира на Оставу и потом је користи негдје друго. Ако Ви " +
          "не желите да се ова датотека копира на Оставу а потом обрише овдје, додајте " +
          "{{tl|keep local}}.</small>") :
         "Отпреми ову датотеку.";
   fuwGet('SubmitButton').value = validForCommons ? "Отпреми локално" : "Отпреми";

 Обсусер 13:26, 27. октобар 2016. (CEST)Одговори

@Obsuser: Ако имаш времена да преведеш, замолио бих те да то урадиш у неком свом именском простору, а ја ћу то онда прењети овдје. —Ранко Николић (разговор) 13:40, 27. октобар 2016. (CEST)Одговори
Покушаћу.  Обсусер 14:42, 27. октобар 2016. (CEST)Одговори
/*
* ===============================================================
*                    FileUploadWizard.js
* Script for uploading files through a dynamic questionnaire.
* This is the code to accompany [[Wikipedia:File Upload Wizard]].
* ===============================================================
*/

var fuwTesting = false;
var fuwDefaultTextboxLength = 60;
var fuwDefaultTextareaWidth = '90%';
var fuwDefaultTextareaLines = 3;

// ================================================================
// Constructor function of global fuw (= File Upload Wizard) object
// ================================================================
function fuwGlobal() {

   // Loading the accompanying .css
   mw.loader.load( mw.config.get('wgServer') + mw.config.get('wgScriptPath') +
      '/index.php?title=MediaWiki:FileUploadWizard.css&action=raw&ctype=text/css', 
      'text/css'  );

   // see if user is logged in, autoconfirmed, experienced etc.
   this.getUserStatus();

   fuwSetVisible('warningLoggedOut', (this.userStatus == 'anon'));
   fuwSetVisible('warningNotConfirmed', (this.userStatus == 'notAutoconfirmed'));
   if ((this.userStatus == 'anon') || (this.userStatus == 'notAutoconfirmed')) {
      return;
   }
   fuwSetVisible('fuwStartScriptLink', false);

   // create the form element to wrap the main ScriptForm area
   // containing input elements of Step2 and Step3
   var frm = fuwGet('fuwScriptForm');
   if (! frm) {
      frm = document.createElement('form');
      frm.id = "fuwScriptForm";
      var area = fuwGet('placeholderScriptForm');
      var parent = area.parentNode;
      parent.insertBefore(frm, area);
      parent.removeChild(area);
      frm.appendChild(area);
   }
   this.ScriptForm = frm;

   // create the TargetForm element that contains the filename
   // input box, together with hidden input controls.
   // This is the form that is actually submitted to the api.php.
   frm = fuwGet('TargetForm');
   if (! frm) {
      frm = document.createElement('form');
      frm.id = "TargetForm";
      frm.method = "post";
      frm.enctype = "multipart/form-data";
      // "enctype" doesn't work properly on IE; need "encoding" instead:
      frm.encoding = "multipart/form-data"; 
      // we'll submit via api.php, not index.php, mainly because that
      // allows us to use a proper edit summary different from the page content
      frm.action = mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/api.php';

      // However, since api.php sends back a response page that humans won't want to read,
      // we'll have to channel that response away and discard it. We'll use a hidden iframe
      // for that purpose.
      // Unfortunately, it doesn't seem possible to submit file upload content through an 
      // Xmlhtml object via Ajax.
 
      frm.target = "TargetIFrame";
      //testing:
      //frm.target = "_blank";
      var area = fuwGet('placeholderTargetForm');
      var parent = area.parentNode;
      parent.insertBefore(frm, area);
      parent.removeChild(area);
      frm.appendChild(area);
   }
   this.TargetForm = frm;

   // For the testing version, create a third form that will display
   // the contents to be submitted, at the bottom of the page
   if (fuwTesting) {
      frm = fuwGet('fuwTestForm');
      if (! frm) {
         frm = document.createElement('form');
         frm.id = "fuwTestForm";
         var area = fuwGet('placeholderTestForm');
         var parent = area.parentNode;
         parent.insertBefore(frm, area);
         parent.removeChild(area);
         frm.appendChild(area);
      }
      this.TestForm = frm;
   }

   // objects to hold cached results during validation and processing
   this.opts = { };
   this.warn = { };

   // create the input filename box
   var filebox  = document.createElement('input');
   filebox.id   = 'file';
   filebox.name = 'file';
   filebox.type = 'file';
   filebox.size = fuwDefaultTextboxLength;
   filebox.onchange = fuwValidateFile;
   filebox.accept = 'image/png,image/jpeg,image/gif,image/svg+xml,image/tiff,image/x-xcf,application/pdf,image/vnd.djvu,audio/ogg,video/ogg,audio/rtp-midi';
   fuwAppendInput('file', filebox);

   // create hidden controls for sending the remaining API parameters:
   fuwMakeHiddenfield('action', 'upload', 'apiAction');
   fuwMakeHiddenfield('format', 'xml', 'apiFormat');
   fuwMakeHiddenfield('filename', '', 'apiFilename');
   fuwMakeHiddenfield('text', '', 'apiText');
   fuwMakeHiddenfield('comment', '', 'apiComment');
   fuwMakeHiddenfield('token', mw.user.tokens.get('editToken'), 'apiToken');
   fuwMakeHiddenfield('ignorewarnings', 1, 'apiIgnorewarnings');
   fuwMakeHiddenfield('watch', 1, 'apiWatch');

   if (fuwTesting) {
      fuwMakeHiddenfield('title', mw.config.get('wgPageName') + "/sandbox", 'SandboxTitle');
      fuwMakeHiddenfield('token', mw.user.tokens.get('editToken'), 'SandboxToken');
      fuwMakeHiddenfield('recreate', 1, 'SandboxRecreate');
   }

   // create a hidden IFrame to send the api.php response to
   var ifr = document.createElement('iframe');
   ifr.id   = "TargetIFrame";
   ifr.name = "TargetIFrame";
   //ifr.setAttribute('style', 'float:right;width:150px;height:150px;');
   ifr.style.display = "празно";
   ifr.src = "";

   fuwAppendInput('TargetIFrame', ifr);

   if (fuwTesting) {

      // create the sandbox submit button
      btn = document.createElement('input');
      btn.id = 'SandboxButton';
      btn.value = 'Пијесак';
      btn.name  = 'Sandbox';
      btn.disabled = true;
      btn.type = 'button';
      btn.style.width = '12em';
      btn.onclick = fuwSubmitSandbox;
      fuwAppendInput('SandboxButton', btn);

   }

   // create the real submit button
   btn = document.createElement('input');
   btn.id = "SubmitButton";
   btn.value = "Отпреми";
   btn.name = "Upload";
   btn.disabled = true;
   btn.type = "button";
   btn.onclick = fuwSubmitUpload;
   btn.style.width = '12em';
   fuwAppendInput('SubmitButton', btn);

   // create the Commons submit button
   btn = document.createElement('input');
   btn.id = "CommonsButton";
   btn.value = "Отпреми на Оставу";
   btn.name  = "Upload_on_Commons";
   btn.disabled = true;
   btn.type = "button";
   btn.onclick = fuwSubmitCommons;
   btn.style.width = '12em';
   fuwAppendInput('CommonsButton', btn);

   // create reset buttons
   for (i = 1; i<=2; i++) {
      btn = document.createElement('input');
      btn.id = 'ResetButton' + i;
      btn.value = "Ресетуј образац";
      btn.name  = "Reset form";
      btn.type  = "button";
      btn.onclick = fuwReset;
      btn.style.width = '12em';
      fuwAppendInput('ResetButton' + i, btn);
   }

   // names of radio button fields
   var optionRadioButtons = {
      // top-level copyright status choice
      'FreeOrNonFree' : ['OptionFree','OptionNonFree','OptionNoGood'],
      // main subsections under OptionFree
      'FreeOptions'   : ['OptionOwnWork', 'OptionThirdParty', 'OptionFreeWebsite',
                         'OptionPDOld', 'OptionPDOther'],
      // main subsections under OptionNonFree
      'NonFreeOptions': ['OptionNFSubject','OptionNF3D','OptionNFExcerpt',
                         'OptionNFCover','OptionNFLogo','OptionNFPortrait',
                         'OptionNFMisc'],
      // response options inside warningFileExists
      'FileExistsOptions': 
                        ['NoOverwrite','OverwriteSame','OverwriteDifferent'],
      // choice of evidence in OptionThirdParty subsection
      'ThirdPartyEvidenceOptions' : 
                        ['ThirdPartyEvidenceOptionLink',
                         'ThirdPartyEvidenceOptionOTRS',
                         'ThirdPartyEvidenceOptionOTRSForthcoming',
                         'ThirdPartyEvidenceOptionNone'],
      // choice of PD status in OptionPDOld subsection
      'PDOldOptions'  : ['PDUS1923','PDURAA','PDFormality','PDOldOther'],
      // choice of PD status in OptionPDOther subsection
      'PDOtherOptions': ['PDOtherUSGov','PDOtherOfficial','PDOtherSimple',
                         'PDOtherOther'],
      // whether target article is wholly or only partly dedicated to discussing non-free work:
      'NFSubjectCheck': ['NFSubjectCheckDedicated','NFSubjectCheckDiscussed'],
      'NF3DCheck'     : ['NF3DCheckDedicated','NF3DCheckDiscussed'],
      // choice about copyright status of photograph in OptionNF3D
      'NF3DOptions'   : ['NF3DOptionFree','NF3DOptionSame']
   };
   for (var group in optionRadioButtons) {
      var op = optionRadioButtons[group];
      for (i=0; i<op.length; i++) {
         fuwMakeRadiobutton(group, op[i]);
      }
   }
   this.ScriptForm.NoOverwrite.checked = true;
   
   // input fields that trigger special
   // onchange() event handlers for validation:
   fuwMakeTextfield('InputName', fuwValidateFilename);
   fuwMakeTextfield('NFArticle', fuwValidateNFArticle);

   // names of input fields that trigger normal
   // validation event handler
   var activeTextfields = [
      'Artist3D','Country3D',
      'Date','OwnWorkCreation','OwnWorkPublication',
      'Author','Source',
      'Permission','ThirdPartyOtherLicense',
      'ThirdPartyEvidenceLink','ThirdPartyOTRSTicket',
      'FreeWebsiteOtherLicense',
      'PDOldAuthorLifetime','Publication',
      'PDOldCountry','PDOldPermission',
      'PDOfficialPermission','PDOtherPermission',
      'NFSubjectPurpose', 'NF3DOrigDate', 'NF3DPurpose',
      'NF3DCreator',
      'NFPortraitDeceased',
      'EditSummary'
   ];
   for (i=0; i<activeTextfields.length; i++) {
      fuwMakeTextfield(activeTextfields[i]);
   }

   // names of multiline textareas
   var activeTextareas = [
      'InputDesc','NF3DPermission',
      'NFCommercial','NFPurpose','NFReplaceableText',
      'NFReplaceable','NFCommercial','NFMinimality','AnyOther'
   ];
   for (i=0; i<activeTextareas.length; i++) {
      fuwMakeTextarea(activeTextareas[i]);
   };

   var checkboxes = [
      'NFCoverCheckDedicated','NFLogoCheckDedicated','NFPortraitCheckDedicated'
   ];
   for (i=0; i<checkboxes.length; i++) {
      fuwMakeCheckbox(checkboxes[i]);
   };

   var licenseLists = {
      'OwnWorkLicense' : 
        // array structure as expected for input to fuwMakeSelection() function.
        // any entry that is a two-element array will be turned into an option
        // (first element is the value, second element is the display string).
        // Entries that are one-element arrays will be the label of an option group.
        // Zero-element arrays mark the end of an option group.
        [
        ['Допуштате свима употребу док Вас наводе као аутора и дијеле под сличним условима'],
        ['self|GFDL|cc-by-sa-4.0|migration=redundant', 
         'Кријејтив комонс Ауторство—Дијелити под истим условима 4.0 + ГНУ-ова лиценца за слободну документацију (препоручено)',
         true],
        ['self|cc-by-sa-4.0',
         'Кријејтив комонс Ауторство—Дијелити под истим условима 4.0'],
        [],
        ['Допуштате свима употребу док Вас наводе као аутора'],
        ['self|cc-by-4.0',
         'Кријејтив комонс Ауторство 4.0'],
        [],
        ['Без задржавања права'],
        ['cc-zero',
         'Предавање у универзално јавно власништво (cc-0)'],
        []
        ],   
      'ThirdPartyLicense' :
        [
        ['', 'изаберите једну од опција...'],
        ['Слободне лиценце:'],
        ['cc-by-sa-4.0', 'Кријејтив комонс Ауторство—Дијелити под истим условима (cc-by-sa-4.0)'],
        ['cc-by-4.0', 'Кријејтив комонс Ауторство (cc-by-4.0)'],
        ['GFDL', 'ГНУ-ова лиценца за слободну документацију (GFDL)'],
        [],
        ['Без задржавања права:'],
        ['PD-author', 'Јавно власништво'],
        [],
        ['Остало (погледајте испод)'],
        []
        ],   
      'FreeWebsiteLicense' :
        [
        ['', 'изаберите једну од опција...'],
        ['Слободне лиценце:'],
        ['cc-by-sa-4.0', 'Кријејтив комонс Ауторство—Дијелити под истим условима (cc-by-sa-4.0)'],
        ['cc-by-4.0', 'Кријејтив комонс Ауторство (cc-by-4.0)'],
        ['GFDL', 'ГНУ-ова лиценца за слободну документацију (GFDL)'],
        [],
        ['Без задржавања права:'],
        ['PD-author', 'Јавно власништво'],
        [],
        ['Остало (погледајте испод)'],
        []
        ],   
      'USGovLicense' :
       [
       ['PD-USGov', 'Федерална влада САД'],
       ['PD-USGov-NASA','НАСА'],
       ['PD-USGov-Military-Navy','Ратна морнарица САД'],
       ['PD-USGov-NOAA','Национална океанска и атмосферска администрација'],
       ['PD-USGov-Military-Air_Force','Ратно ваздухопловство САД'],
       ['PD-USGov-Military-Army','Армија САД'],
       ['PD-USGov-CIA-WF','CIA World Factbook'],
       ['PD-USGov-USGS','Геолошки топографски институт САД']
       ],
      'IneligibleLicense' :
       [
       ['', 'изаберите једну од опција...'],
       ['PD-shape','Дјело се састоји искључиво од једноставних геометријских облика'],
       ['PD-text','Дјело се састоји само од неколико појединачних ријечи или слова'],
       ['PD-textlogo','Лого или слично дјело које се састоји искључиво од слова и једноставних геометријских облика'],
       ['PD-chem','Хемијска структурална формула'],
       ['PD-ineligible','Друга врста дјела које не садржи оригинално ауторство']
       ],
      'NFSubjectLicense' :
       [
       ['', 'изаберите једну од опција...'],
       ['Non-free 2D art', '2-димензионално умјетничко дјело (слика, цртеж итд.)'], 
       ['Non-free historic image', 'Јединствена историјска фотографија'], 
       ['Non-free fair use in', 'нешто друго (опишите у пољу за кратак опис 2. корака изнад)']
       ],
      'NF3DLicense' :
       [
       ['', 'изаберите једну од опција...'],
       ['Non-free architectural work', 'Архитектонско дјело'], 
       ['Non-free 3D art', 'Друго 3-димензионално креативно дјело (скулптура итд.)']
       ],
      'NFCoverLicense' :
         [
         ['', 'изаберите једну од опција...'],
         ['Non-free book cover', 'Корица књиге'], 
         ['Non-free album cover', 'Омот звучног записа (албум, сингл, пјесма, ЦД)'], 
         ['Non-free game cover', 'Омот видео/рачунарске игре'], 
         ['Non-free magazine cover', 'Насловна страна часописа'], 
         ['Non-free video cover', 'Омот видео-траке'], 
         ['Non-free software cover', 'Омот софтверског производа'], 
         ['Non-free product cover', 'Омот неког комерцијалног производа'], 
         ['Non-free title-card', 'Уводна шпица ТВ програма'], 
         ['Non-free movie poster', 'Филмски постер'], 
         ['Non-free poster', 'Званични постер догађаја'], 
         ['Non-free fair use in', 'нешто друго (опишите у пољу за кратак опис 2. корака изнад)']
         ],
      'NFExcerptLicense' :
         [
         ['', 'изаберите једну од опција...'],
         ['Non-free television screenshot', 'Снимак екрана ТВ програма'], 
         ['Non-free film screenshot', 'Снимак екрана филма'], 
         ['Non-free game screenshot', 'Снимак екрана игре'], 
         ['Non-free video screenshot', 'Снимак екрана видеа'], 
         ['Non-free music video screenshot', 'Снимак екрана музичког видеа'], 
         ['Non-free software screenshot', 'Снимак екрана софтвера'], 
         ['Non-free web screenshot', 'Снимак екрана веб-сајта'], 
         ['Non-free speech', 'Аудио-исјечак говора'], 
         ['Non-free audio sample', 'Звучни одломак аудио-снимка'], 
         ['Non-free video sample', 'Исјечак видеа'], 
         ['Non-free sheet music', 'Ноте које представљају музичко дјело'], 
         ['Non-free comic', 'Дио стрипа, графички роман, манга итд.'], 
         ['Non-free computer icon', 'Рачунарска икона'], 
         ['Non-free newspaper image', 'Страница новина'], 
         ['Non-free fair use in', 'нешто друго (опишите у пољу за кратак опис 2. корака изнад)']
         ],      
      'NFLogoLicense' :
         [
         ['Non-free logo', 'Лого компаније, организације итд.'], 
         ['Non-free seal', 'Званични печат, грб итд.'], 
         ['Non-free symbol', 'Други званични симбол']
         ],
      'NFMiscLicense' :
         [
         ['Non-free fair use in', 'нешто друго (опишите у пољу за кратак опис 2. корака изнад)'], 
         ['Non-free historic image', 'Историјска фотографија'], 
         ['Non-free 2D art', '2-димензионално умјетничко дјело (слика, цртеж итд.)'], 
         ['Non-free currency', 'Депикција валуте (новчанице, кованице итд.)'], 
         ['Non-free architectural work', 'Архитектонско дјело'], 
         ['Non-free 3D art', 'Друго 3-димензионално креативно дјело (скулптура итд.)'], 
         ['Non-free book cover', 'Корица књиге'], 
         ['Non-free album cover', 'Омот звучног записа (албум, сингл, пјесма, ЦД)'], 
         ['Non-free game cover', 'Омот видео/рачунарске игре'], 
         ['Non-free magazine cover', 'Насловна страна часописа'], 
         ['Non-free video cover', 'Омот видео-траке'], 
         ['Non-free software cover', 'Омот софтверског производа'], 
         ['Non-free product cover', 'Омот неког комерцијалног производа'], 
         ['Non-free title-card', 'Уводна шпица ТВ програма'], 
         ['Non-free movie poster', 'Филмски постер'], 
         ['Non-free poster', 'Званични постер догађаја'], 
         ['Non-free television screenshot', 'Снимак екрана ТВ програма'], 
         ['Non-free film screenshot', 'Снимак екрана филма'], 
         ['Non-free game screenshot', 'Снимак екрана игре'], 
         ['Non-free video screenshot', 'Снимак екрана видеа'], 
         ['Non-free music video screenshot', 'Снимак екрана музичког видеа'], 
         ['Non-free software screenshot', 'Снимак екрана софтвера'], 
         ['Non-free web screenshot', 'Снимак екрана веб-сајта'], 
         ['Non-free speech', 'Аудио-исјечак говора'], 
         ['Non-free audio sample', 'Звучни одломак аудио-снимка'], 
         ['Non-free video sample', 'Исјечак видеа'], 
         ['Non-free sheet music', 'Ноте које представљају музичко дјело'], 
         ['Non-free comic', 'Дио стрипа, графички роман, манга итд.'], 
         ['Non-free computer icon', 'Рачунарска икона'], 
         ['Non-free newspaper image', 'Страница новина'], 
         ['Non-free logo', 'Лого компаније, организације итд.'], 
         ['Non-free seal', 'Званични печат, грб итд.'], 
         ['Non-free symbol', 'Други званични симбол'], 
         ['Non-free sports uniform', 'Спортска униформа'], 
         ['Non-free stamp', 'Поштанска марка'] 
         ],
      'NFExtraLicense' :
         [
         ['', 'none'],
         ['Ауторска права Круне и други владини извори'],
         ['Non-free Crown copyright', 'Ауторско право Круне УК'],
         ['Non-free New Zealand Crown Copyright', 'Ауторско право Круне НЗ'],
         ['Non-free Canadian Crown Copyright', 'Ауторско право Круне Канаде'],
         ['Non-free AUSPIC', 'AUSPIC (Сликовна база података Аустралијског парламента)'],
         ['Non-free Philippines government', 'Филипинска влада'],
         ['Non-free Finnish Defence Forces', 'Финске одбрамбене снаге'],
         [],
         ['Остали појединачни извори'],
         ['Non-free Denver Public Library', 'Денверска јавна библиотека'],
         ['Non-free ESA media', 'ЕСА (Европска свемирска агенција)'],
         [],
         ['Могуће јавно власништво у другим земљама'],
         ['Non-free Old-50', 'Аутор умро прије више од 50 година'],
         ['Non-free Old-70', 'Аутор умро прије више од 70 година'],
         [],
         ['Неке дозволе дате, али није потпуно слободно'],
         ['Non-free promotional', 'Из промотивног прес-кита'],
         ['Non-free with NC', 'Дозвола дата, али само за образовне и/или некомерцијалне сврхе'],
         ['Non-free with ND', 'Дозвола дата, али прерађивање дјела није дозвољено'],
         ['Non-free with permission', 'Дозвола дата, али само за Википедију'],
         []
         ]
   };
   for (var group in licenseLists) {
      fuwMakeSelection(group, licenseLists[group]);
   }


   this.knownCommonsLicenses = {
      'self|GFDL|cc-by-sa-all|migration=redundant' : 1,
      'self|Cc-zero' : 1,
      'PD-self' : 1,
      'self|GFDL|cc-by-sa-4.0|migration=redundant' : 1,
      'self|GFDL|cc-by-4.0|migration=redundant' : 1,
      'self|GFDL|cc-by-sa-3.0|migration=redundant' : 1,
      'self|GFDL|cc-by-3.0|migration=redundant' : 1,
      'self|cc-by-sa-4.0' : 1,
      'self|cc-by-sa-3.0' : 1,
      'cc-by-sa-4.0' : 1,
      'cc-by-sa-3.0' : 1,
      'cc-by-sa-2.5' : 1,
      'cc-by-4.0' : 1,
      'cc-by-3.0' : 1,
      'cc-by-2.5' : 1,
      'FAL' : 1,
      'PD-old-100' : 1,
      'PD-old' : 1,
      'PD-Art' : 1,
      'PD-US' : 1,
      'PD-USGov' : 1,
      'PD-USGov-NASA' : 1,
      'PD-USGov-Military-Navy' : 1,
      'PD-ineligible' : 1,
      'attribution' : 1,
      'copyrighted free use' : 1
   };


   // textfields that don't react directly
   // to user input and are used only for assembling stuff:
   if (fuwTesting) {
      fuwMakeTextfield('SandboxSummary', function(){void(0);});
      fuwMakeTextarea('SandboxText', function(){void(0);});
      fuwGet('SandboxSummary').disabled="онемогућено";
      fuwGet('SandboxText').disabled="онемогућено";
      fuwGet('SandboxText').rows = 12;
   }

   // set links to "_blank" target, so we don't accidentally leave the page,
   // because on some browsers that would destroy all the input the user has already entered
   $('.fuwOutLink a').each(function() {
      this.target = '_blank';
   });

   // make main area visible
   fuwSetVisible('UploadScriptArea', true);

}
// ====================================== 
// end of fuwGlobal constructor function
// ======================================



function fuwRadioClick(e) {
   var ev = e || event;
   var src = ev.target || ev.srcElement;
   //alert('onclick event from ' + src + ' (' + src.value + ')');
   fuwUpdateOptions();
   return true;
}

/* 
* =============================================================
* function fuwUpdateOptions
* =============================================================
* This is the onchange event handler for most of the input
* elements in the main form. It changes visibility and disabled
* status for the various sections of the input form in response
* to which options are chosen.
*/
function fuwUpdateOptions() {

   var fuw = window.fuw;
   var warn = fuw.warn;
   var opts = fuw.opts = { };
   opts.InputFilename = $('#TargetForm input#file').val();

   var widgets = fuw.ScriptForm.elements;
   for (i = 0; i < widgets.length; i++) {
      var w = widgets[i];
      if (w.type == "radio") {
         var nm = w.name;
         var id = w.id;
         var vl = w.checked && !w.disabled && fuwIsVisible(w);
         opts[id] = vl;
         if (vl) opts[nm] = id;
      }
      else {
         var id = w.id;
         var active = !w.disabled && fuwIsVisible(w);
         if (active) {
            var value = ((type == 'checkbox') ? w.checked : w.value);
            opts[id] = value;         
         }
      }
   };
   opts.MainOption = opts.FreeOptions || opts.NonFreeOptions;
   
   // some parts of the input form are re-used across sections
   // and must be moved into the currently active input section:

   // minimality section is shared between all NF sections
   fuwMove('NFMinimalitySection', 'detailsNFSubject', (opts.OptionNFSubject)) ||
   fuwMove('NFMinimalitySection', 'detailsNF3D', (opts.OptionNF3D)) ||
   fuwMove('NFMinimalitySection', 'detailsNFExcerpt', (opts.OptionNFExcerpt)) ||
   fuwMove('NFMinimalitySection', 'detailsNFCover', (opts.OptionNFCover)) ||
   fuwMove('NFMinimalitySection', 'detailsNFLogo', (opts.OptionNFLogo)) ||
   fuwMove('NFMinimalitySection', 'detailsNFPortrait', (opts.OptionNFPortrait)) ||
   fuwMove('NFMinimalitySection', 'detailsNFMisc', true);

   // AnyOtherInfo section is shared between all
   fuwMove('AnyOtherInfo', 'detailsOwnWork', opts.OptionOwnWork) ||
   fuwMove('AnyOtherInfo', 'detailsThirdParty', opts.OptionThirdParty) ||
   fuwMove('AnyOtherInfo', 'detailsFreeWebsite', opts.OptionFreeWebsite) ||
   fuwMove('AnyOtherInfo', 'detailsPDOld', opts.OptionPDOld) ||
   fuwMove('AnyOtherInfo', 'detailsPDOther', opts.OptionPDOther) ||
   fuwMove('AnyOtherInfo', 'detailsNFSubject', opts.OptionNFSubject) ||
   fuwMove('AnyOtherInfo', 'detailsNF3D', opts.OptionNF3D) ||
   fuwMove('AnyOtherInfo', 'detailsNFExcerpt', opts.OptionNFExcerpt) ||
   fuwMove('AnyOtherInfo', 'detailsNFCover', opts.OptionNFCover) ||
   fuwMove('AnyOtherInfo', 'detailsNFLogo', opts.OptionNFLogo) ||
   fuwMove('AnyOtherInfo', 'detailsNFPortrait', opts.OptionNFPortrait) ||
   fuwMove('AnyOtherInfo', 'detailsNFMisc', opts.OptionNFMisc);

   // author input field is shared between all sections except "Own Work".
   // (will serve for the immediate/photographic author, in those cases where there
   // are two author fields)
   fuwMove('Author', 'placeholderFreeWebsiteAuthor', (opts.OptionFreeWebsite)) ||
   fuwMove('Author', 'placeholderPDOldAuthor', (opts.OptionPDOld)) ||
   fuwMove('Author', 'placeholderPDOtherAuthor', (opts.OptionPDOther)) ||
   fuwMove('Author', 'placeholderNFSubjectAuthor', (opts.OptionNFSubject)) ||
   fuwMove('Author', 'placeholderNF3DAuthor', (opts.OptionNF3D)) ||
   fuwMove('Author', 'placeholderNFExcerptAuthor', (opts.OptionNFExcerpt)) ||
   fuwMove('Author', 'placeholderNFCoverAuthor', (opts.OptionNFCover)) ||
   fuwMove('Author', 'placeholderNFPortraitAuthor', (opts.OptionNFPortrait)) ||
   fuwMove('Author', 'placeholderNFMiscAuthor', (opts.OptionNFMisc)) ||
   fuwMove('Author', 'placeholderAuthor', true);

   // source input field is shared between all sections except "Own Work".
   // (will serve for immediate/web source, in those cases where there are two
   // source fields involved)
   fuwMove('Source', 'placeholderFreeWebsiteSource', (opts.OptionFreeWebsite)) ||
   fuwMove('Source', 'placeholderPDOldSource', (opts.OptionPDOld)) ||
   fuwMove('Source', 'placeholderPDOtherSource', (opts.OptionPDOther)) ||
   fuwMove('Source', 'placeholderNFSubjectSource', (opts.OptionNFSubject)) ||
   fuwMove('Source', 'placeholderNF3DSource', (opts.OptionNF3D)) ||
   fuwMove('Source', 'placeholderNFExcerptSource', (opts.OptionNFExcerpt)) ||
   fuwMove('Source', 'placeholderNFCoverSource', (opts.OptionNFCover)) ||
   fuwMove('Source', 'placeholderNFLogoSource', (opts.OptionNFLogo)) ||
   fuwMove('Source', 'placeholderNFPortraitSource', (opts.OptionNFPortrait)) ||
   fuwMove('Source', 'placeholderNFMiscSource', (opts.OptionNFMisc)) ||
   fuwMove('Source', 'placeholderSource', true);

   // date input field is shared between all sections except "Logo", which doesn't need it.
   // will serve for derived/photographic date in the case of 3D items
   fuwMove('Date', 'placeholderFreeWebsiteDate', (opts.OptionFreeWebsite)) ||
   fuwMove('Date', 'placeholderThirdPartyDate', (opts.OptionThirdParty)) ||
   fuwMove('Date', 'placeholderPDOldDate', (opts.OptionPDOld)) ||
   fuwMove('Date', 'placeholderPDOtherDate', (opts.OptionPDOther)) ||
   fuwMove('Date', 'placeholderNFSubjectDate', (opts.OptionNFSubject)) ||
   fuwMove('Date', 'placeholderNF3DDate', (opts.OptionNF3D)) ||
   fuwMove('Date', 'placeholderNFExcerptDate', (opts.OptionNFExcerpt)) ||
   fuwMove('Date', 'placeholderNFCoverDate', (opts.OptionNFCover)) ||
   fuwMove('Date', 'placeholderNFPortraitDate', (opts.OptionNFPortrait)) ||
   fuwMove('Date', 'placeholderNFMiscDate', (opts.OptionNFMisc)) ||
   fuwMove('Date', 'placeholderDate', true);
   
   // permission field is shared between ThirdParty and FreeWebsite sections
   fuwMove('Permission', 'placeholderFreeWebsitePermission', (opts.OptionFreeWebsite)) ||
   fuwMove('Permission', 'placeholderPermission', true);

   // publication field is shared between PDOld, NFPortrait and NFMisc
   fuwMove('Publication', 'placeholderNFPortraitPublication', (opts.OptionNFPortrait)) ||
   fuwMove('Publication', 'placeholderNFMiscPublication', (opts.OptionNFMisc)) ||
   fuwMove('Publication', 'placeholderPublication', true);

   // Purpose, Commercial, Replaceable and ReplaceableText FUR fields are shared
   // between some but not all of the non-free sections
   fuwMove('NFPurpose', 'placeholderNFExcerptPurpose', (opts.OptionNFExcerpt)) ||
   fuwMove('NFPurpose', 'placeholderNFPurpose');
   fuwMove('NFCommercial', 'placeholderNFPortraitCommercial', (opts.OptionNFPortrait)) ||
   fuwMove('NFCommercial', 'placeholderNFCommercial');
   fuwMove('NFReplaceable', 'placeholderNFPortraitReplaceable', (opts.OptionNFPortrait)) ||
   fuwMove('NFReplaceable', 'placeholderNFReplaceable');
   fuwMove('NFReplaceableText', 'placeholderNFExcerptReplaceable', (opts.OptionNFExcerpt)) ||
   fuwMove('NFReplaceableText', 'placeholderNFReplaceableText', true);

   // submit button goes to Step1 if user has chosen a plain overwrite of an existing file,
   // and to the active section of Step3 if otherwise
   fuwMove('fuwSubmit', 'UploadScriptStep1', (warn.ImageExists && opts.OverwriteSame)) ||
   fuwMove('fuwSubmit', 'detailsOwnWork', opts.OptionOwnWork) ||
   fuwMove('fuwSubmit', 'detailsThirdParty', opts.OptionThirdParty) ||
   fuwMove('fuwSubmit', 'detailsFreeWebsite', opts.OptionFreeWebsite) ||
   fuwMove('fuwSubmit', 'detailsPDOld', opts.OptionPDOld) ||
   fuwMove('fuwSubmit', 'detailsPDOther', opts.OptionPDOther) ||
   fuwMove('fuwSubmit', 'detailsNFSubject', opts.OptionNFSubject) ||
   fuwMove('fuwSubmit', 'detailsNF3D', opts.OptionNF3D) ||
   fuwMove('fuwSubmit', 'detailsNFExcerpt', opts.OptionNFExcerpt) ||
   fuwMove('fuwSubmit', 'detailsNFCover', opts.OptionNFCover) ||
   fuwMove('fuwSubmit', 'detailsNFLogo', opts.OptionNFLogo) ||
   fuwMove('fuwSubmit', 'detailsNFPortrait', opts.OptionNFPortrait) ||
   fuwMove('fuwSubmit', 'fuwSubmitHost', true);


   // Show and hide warnings:

   // filename-related warnings:
   fuwSetVisible('warningIllegalChars', warn.IllegalChars);
   fuwSetVisible('warningBadFilename',  warn.BadFilename);
   fuwSetVisible('warningImageOnCommons', warn.ImageOnCommons);
   fuwSetVisible('warningImageExists', warn.ImageExists);
   fuwMove('warningImageThumb', 'warningImageOnCommons', warn.ImageOnCommons, true) ||
   fuwMove('warningImageThumb', 'warningImageExists', true, true);


   // notices related to the top-level options:
   fuwSetVisible('warningWhyNotCommons', opts.OptionFree);
   fuwSetVisible('warningNF', opts.OptionNonFree);
   fuwSetVisible('warningNoGood', opts.OptionNoGood);

   // warnings related to non-free "used in" article
   fuwSetVisible('warningNFArticleNotFound', warn.NFArticleNotFound);
   fuwSetVisible('warningNFArticleNotMainspace', warn.NFArticleNotMainspace);
   fuwSetVisible('warningUserspaceDraft', warn.UserspaceDraft);
   fuwSetVisible('warningNFArticleDab', warn.NFArticleDab);
   fuwSetVisible('NFArticleOK', warn.NFArticleOK);

   // warnings depending on user status:
   if (fuw.userStatus.match(/problem|newbie|notAutoconfirmed/)) {
      fuwSetVisible('warningFreeWebsite', opts.OptionFreeWebsite);
      fuwSetVisible('warningOwnWork', opts.OptionOwnWork);
      fuwSetVisible('warningPDOther', opts.OptionPDOther);
      fuwSetVisible('warningNFSubject', opts.OptionNFSubject);
   }

   // hide main sections in case of intended plain overwrite:   
   fuwSetVisible('UploadScriptStep2', !(warn.ImageExists && opts.OverwriteSame));
   fuwSetVisible('UploadScriptStep3', !(warn.ImageExists && opts.OverwriteSame));

   // show/hide top-level options
   fuwSetVisible('detailsFreeStatus', opts.OptionFree);
   fuwSetVisible('sendToCommons', opts.OptionFree);

   // show/hide details sections
   fuwSetVisible('detailsNFArticle', opts.OptionNonFree);
   fuwSetVisible('detailsNFWorkType', opts.OptionNonFree);
   fuwSetVisible('detailsOwnWork', opts.OptionOwnWork);
   fuwSetVisible('detailsThirdParty', opts.OptionThirdParty);
   fuwSetVisible('detailsFreeWebsite', opts.OptionFreeWebsite);
   fuwSetVisible('detailsPDOld', opts.OptionPDOld);
   fuwSetVisible('detailsPDOther', opts.OptionPDOther);
   fuwSetVisible('detailsNFSubject', opts.OptionNFSubject);
   fuwSetVisible('detailsNF3D', opts.OptionNF3D);
   fuwSetVisible('detailsNFExcerpt', opts.OptionNFExcerpt);
   fuwSetVisible('detailsNFCover', opts.OptionNFCover);
   fuwSetVisible('detailsNFLogo', opts.OptionNFLogo);
   fuwSetVisible('detailsNFPortrait', opts.OptionNFPortrait);
   fuwSetVisible('detailsNFMisc', opts.OptionNFMisc);

   fuwSetVisible('EditSummaryDiv', opts.OverwriteSame || opts.OverwriteDifferent);

   // set enabled/disabled
   // It might be useful to adapt this to be more liberal about
   // the order of input, at least for experienced users.

   //fuwSetEnabled('Artist3D', opts.PD3D);
   //fuwSetEnabled('Country3D', opts.FOP3D);
   fuwSetEnabled('ThirdPartyEvidenceLink', opts.ThirdPartyEvidenceOptionLink);
   fuwSetEnabled('ThirdPartyOTRSTicket', opts.ThirdPartyEvidenceOptionOTRS);
   fuwSetEnabled('NFSubjectPurpose', opts.NFSubjectCheckDiscussed);
   fuwSetEnabled('NF3DPurpose', opts.NF3DCheckDiscussed);
   fuwSetEnabled('NF3DPermission', opts.NF3DOptionFree);
   fuwSetEnabled('USGovLicense', opts.PDOtherUSGov);
   fuwSetEnabled('PDOfficialPermission', opts.PDOtherOfficial);
   fuwSetEnabled('IneligibleLicense', opts.PDOtherSimple);
   fuwSetEnabled('PDOtherPermission', opts.PDOtherOther);
   fuwSetEnabled('AnyOther', true);

   // need to re-collect the remaining (non-radiobutton) input into the opts object again,
   // preparing for validation:
   for (i = 0; i < widgets.length; i++) {
      var w = widgets[i];
      var type = w.type;

      if (type != "radio") {
         var id = w.id;
         var active = !w.disabled && fuwIsVisible(w);
         if (active) {
            var value = ((type == 'checkbox') ? w.checked : w.value);
            opts[id] = value;         
         }
      }
   };

   // final step of validation: check if input is sufficient for
   // setting the submit buttons active
   var valid = fuw.validateInput();
   var validForCommons = valid && opts.OptionFree && !(opts.OverwriteSame || opts.OverwriteDifferent)
         && !opts.ThirdPartyEvidenceOptionNone;
   fuwSetVisible('sendToCommons', opts.OptionFree);
   fuwSetEnabled('CommonsButton', validForCommons);
   fuwGet('fuwSubmitText').innerHTML = opts.OptionFree ? 
         ("<b>Не</b>, желим да ову датотеку отпремим овдје, само на ову Википедију.<br/>" + 
          "<small>Овако ће се датотека моћи користити само на Википедији на српском језику. Међутим, неко " +
          "други би могао да је копира на Оставу и потом је користи негдје друго. Ако Ви " +
          "не желите да се ова датотека копира на Оставу а потом обрише овдје, додајте " +
          "{{tl|keep local}}.</small>") :
         "Отпреми ову датотеку.";
   fuwGet('SubmitButton').value = validForCommons ? "Отпреми локално" : "Отпреми";   
   fuwSetEnabled('EditSummary', true);
   fuwSetEnabled('SubmitButton', valid && (fuw.userStatus != 'notAutoconfirmed'));
   if (fuwTesting) {
      fuwSetEnabled('SandboxButton', valid);
   }

   // if we're in testing mode, update the Sandbox display fields
   // after each input change. In normal mode, collectInput() will
   // only be needed on submit.
   if (fuwTesting) {
      fuw.collectInput();
      fuw.formatOutput(false);
      fuwSetVisible('placeholderTestForm', true);
   }  
}

// ============================================================
// methods of the global fuw object
// ============================================================

// ============================================================
// report validation status of filename information
// ============================================================
// This is called from within fuw.validateInput(), i.e. every
// time anything in the whole form is changed. It only reports
// results that have previously been cached in the opts and warn
// objects. The actual checking is done in the event handler
// of the file input boxes.
fuwGlobal.prototype.hasValidFilename = function() {
   var opts = this.opts;
   var warn = this.warn;
   var valid =   
      opts.InputName &&
      opts.InputFilename &&
      !warn.BadFilename &&
      !warn.ImageOnCommons &&
      // if image exists on enwiki, accept only if user has confirmed overwrite:
      !(warn.ImageExists && !(opts.OverwriteSame || opts.OverwriteDifferent));
   //alert("HasValidFilename: " + valid);
   return valid;
};

// ============================================================
// validation status for common input elements for all free
// options
// ============================================================
fuwGlobal.prototype.hasValidCommonFreeInput = function() {
   var opts = this.opts;
   var warn = this.warn;
   var valid = opts.InputDesc;
   //alert("HasValidCommonFreeInput: " + valid);
   return valid;
};
// ============================================================
// validation status for common input elements for all non-free
// options
// ============================================================
fuwGlobal.prototype.hasValidCommonNFInput = function() {
   var opts = this.opts;
   var warn = this.warn;
   var valid =
      opts.OptionNonFree &&
      opts.InputDesc && 
      opts.NFArticle &&
      opts.Source &&
      opts.NFMinimality &&
      !warn.NFArticleNotFound &&
      !warn.NFArticleNotMainspace &&
      !warn.NFArticleDab;
   //alert("hasValidCommonNFInput: " + valid);
   return valid;
};
// ============================================================
// Main validation routine. Modify this to tweak which fields
// are to be considered obligatory for each case group
// ============================================================
fuwGlobal.prototype.validateInput = function() {
   var opts = this.opts;
   var warn = this.warn;
   var valid = (
      this.hasValidFilename()
      &&
      (! (opts.OverwriteDifferent && ! opts.EditSummary))
      &&
      (
       ( // overwriting is okay if there is an edit summary
        opts.OverwriteSame && opts.EditSummary
       )
       ||
       ( // free options
         this.hasValidCommonFreeInput() &&
         (
          (opts.OptionOwnWork &&
           opts.Date &&
           opts.OwnWorkLicense)
          ||
          (opts.OptionThirdParty &&
           opts.Author &&
           opts.Source &&
           opts.Permission &&
           (opts.ThirdPartyOtherLicense || opts.ThirdPartyLicense) &&
           ((opts.ThirdPartyEvidenceOptionLink && opts.ThirdPartyEvidenceLink) ||
            opts.ThirdPartyEvidenceOptionOTRS ||
            opts.ThirdPartyEvidenceOptionOTRSForthcoming ||
            opts.ThirdPartyEvidenceOptionNone))
          ||
          (opts.OptionFreeWebsite &&
           opts.Author &&
           opts.Source &&
           (opts.FreeWebsiteOtherLicense || opts.FreeWebsiteLicense) &&
           opts.Permission)
          ||
          (opts.OptionPDOld &&
           opts.Author &&
           opts.PDOldAuthorLifetime &&
           opts.Publication &&
           opts.Date &&
           opts.Source &&
           opts.PDOldOptions && 
           (! (opts.PDOldOther && ! opts.PDOldPermission)))
          ||
          (opts.OptionPDOther &&
           opts.Author &&
           opts.Source &&
           ((opts.PDOtherUSGov && opts.USGovLicense) ||
            (opts.PDOtherOfficial && opts.PDOfficialPermission) ||
            (opts.PDOtherSimple && opts.IneligibleLicense) ||
            (opts.PDOtherOther && opts.PDOtherPermission)))
        )
       ) // end of free options
       ||
       ( // non-free options
         this.hasValidCommonNFInput() &&
         (
          (opts.OptionNFSubject &&
           opts.NFSubjectLicense &&
           opts.Author &&
           (opts.NFSubjectCheckDedicated ||
           (opts.NFSubjectCheckDiscussed && opts.NFSubjectPurpose)))
          ||
          (opts.OptionNF3D &&
           opts.NF3DLicense &&
           opts.NF3DCreator &&
           opts.Author &&
           (opts.NF3DOptionSame ||
           (opts.NF3DOptionFree || opts.NF3DPermission)) && 
           (opts.NF3DCheckDedicated ||
            (opts.NF3DCheckDiscussed && opts.NF3DPurpose)))
          ||
          (opts.OptionNFExcerpt &&
           opts.NFExcerptLicense &&
           opts.Author &&
           opts.NFPurpose)
          ||
          (opts.OptionNFCover &&
           opts.NFCoverLicense &&
           opts.Author &&
           opts.NFCoverCheckDedicated 
          )
          ||
          (opts.OptionNFLogo &&
           opts.NFLogoLicense &&
           opts.NFLogoCheckDedicated
          )
          ||
          (opts.OptionNFPortrait &&
           opts.Publication &&
           opts.NFPortraitDeceased &&
           opts.Author &&
           opts.NFPortraitCheckDedicated &&
           opts.NFReplaceable &&
           opts.NFCommercial)
          ||
          (opts.OptionNFMisc &&
           opts.NFMiscLicense &&
           opts.Author &&
           opts.Publication &&
           opts.NFPurpose &&
           opts.NFReplaceableText &&
           opts.NFReplaceable &&
           opts.NFCommercial)
         )
       ) // end of non-free options
      )
   );
   return valid;
};

// =============================================================
// return which template name will be used as the main
// description template
// =============================================================
fuwGlobal.prototype.getDescriptionTemplateName = function() {
   // standard "Information" template for free files:
   if (this.opts.OptionFree) return "Information";
   // experimental new version of fair-use rationale template,
   // designed to fit the fields used in the wizard
   else if (this.opts.OptionNonFree) return "Non-free use rationale 2";
   return undefined;
};

// =============================================================
// get the license tag code from the appropriate input element
// =============================================================

fuwGlobal.prototype.getStandardLicense = function() {
   var opts = this.opts;
   
}

fuwGlobal.prototype.getLicense = function() {
   var opts = this.opts;
      // ThirdParty and FreeWebsite have alternative input fields
      // for manual entry of other licenses:
   var license = {};
   if (opts.PDOtherOther || opts.PDOldOther) {
      license.special = opts.PDOtherOther ? opts.PDOtherPermission : opts.PDOldPermission;
      if (! (license.special.match(/^\s*\{\{.+\}\}\s*$/))) {
         license.special = '{{PD-because|' + license.special + '}}';
      }
   }
   else {
      license.special = 
         opts.ThirdPartyOtherLicense || 
         opts.FreeWebsiteOtherLicense ||
         (opts.PDOtherOfficial ? ('{{PD-because|званично дјело правно изузето од ауторских права у земљи свог поријекла}}') : null) ||
         (opts.OptionNFPortrait ? ('{{non-free biog-pic|' + opts.NFArticle + '}}') : null);
   }   
   if (! license.special) {
      // standard, non-parametrized tag licenses from dropdownbox.
      var simpleLicense = (opts.OptionOwnWork ? opts.OwnWorkLicense : null) ||
          (opts.OptionThirdParty ? opts.ThirdPartyLicense : null) ||
          (opts.OptionFreeWebsite ? opts.FreeWebsiteLicense : null) ||
          (opts.OptionNFSubject ? opts.NFSubjectLicense : null) ||
          (opts.OptionNF3D ? opts.NF3DLicense : null) ||
          (opts.OptionNFExcerpt ? opts.NFExcerptLicense : null) ||
          (opts.OptionNFCover ? opts.NFCoverLicense : null) ||
          (opts.OptionNFLogo ? opts.NFLogoLicense : null) ||
          (opts.OptionNFMisc ? opts.NFMiscLicense : null) ||
          (opts.PDOtherUSGov ? opts.USGovLicense : null) ||
          (opts.PDOtherSimple ? opts.IneligibleLicense : null) ||
          (opts.PDUS1923 ? 'PD-US-1923' : null) ||
          (opts.PDURAA   ? 'PD-URAA' : null) ||
          (opts.PDFormality ? 'PD-US' : null);

       // "PD-author" needs parameter, at least on Commons
       if (simpleLicense == 'PD-author') {
          license.special = '{{PD-author|' + opts.Author + '}}';
       }
       else if (this.knownCommonsLicenses[simpleLicense]) {
       // make sure we send only those licenses as "standard" licenses
       // that exist in the Commons license dropdown box
          license.standard = simpleLicense;
       }
       else {
          license.special = '\{\{' + simpleLicense + '\}\}';
       }
   }
   return license;
};

function fuwSubst(template) {
   return '{{subst:' + template + '}}';
}

// ===================================================================
// Produce code for local tracking categories
// ===================================================================
fuwGlobal.prototype.getTrackingCategory = function() {
   var opts = this.opts;
   var cat = "";
   if (opts.OptionFreeWebsite) { cat = "Датотеке из слободно лиценцираних спољашњих извора"; }
   else if (opts.OptionThirdParty) { cat = "Датотеке лиценциране од стране трећих лица"; }
   else if (opts.PDOtherOther || opts.PDOldOther) { cat = "Датотеке са нестандардним изјавама јавног власништва"; }
   else if (opts.OptionNFSubject || opts.OptionNF3D) { cat = "Неслободне датотеке отпремљене за сврху коментара"; }
   if (cat) {
      cat = "\n\{\{category ordered by date|" + cat + "|" + 
      fuwSubst("CURRENTYEAR") + "|" + fuwSubst("CURRENTMONTH") + "|" + fuwSubst("CURRENTDAY2") + "\}\}";
   }
   return cat;
};

// ===================================================================
// Get or create an edit summary for the upload
// ===================================================================
// Note: if we work with the api.php interface, we can have separate
// data for the edit summary and the description page, which is far
// better than the way the index.php interface does it.
// TO DO: need to actually define an input element for a manually
// entered edit summary. Must be obligatory when overwriting files.
// In other cases we'll use an automatic edit summary.
// ===================================================================
fuwGlobal.prototype.getEditSummary = function() {
   var opts = this.opts;
   return (
      (opts.EditSummary ? (opts.EditSummary + ' ([[' + mw.config.get('wgPageName') + '|Чаробњак за отпремање]])') : null)||
      ("отпремање " +
       (
        (opts.OptionOwnWork ? 'личне датотеке ' : false) ||
        (opts.OptionThirdParty ? 'слободне датотеке некога другог ' : false) ||
        (opts.OptionFreeWebsite ? 'датотеке из слободно објављеног извора ' : false) ||
        (opts.OptionPDOld       ? 'старог дјела у јавном власништву ' : false) ||
        (opts.OptionPDOther     ? 'дјела у јавном власништву ' : false) ||
        (opts.OptionNFSubject   ? 'неслободног дјела као предмета расправе ' : false) ||
        (opts.OptionNF3D        ? 'депикције неслободног 3Д дјела ' : false) ||
        (opts.OptionNFExcerpt   ? 'исјечка неслободног дјела ' : false) ||
        (opts.OptionNFCover     ? 'неслободног омота ' : false) ||
        (opts.OptionNFLogo      ? 'неслободног логоа ' : false) ||
        (opts.OptionNFPortrait    ? 'неслободног историјског портрета ' : false) ||
        (opts.OptionNFMisc      ? 'неслободне датотеке ' : "")
       )
       + 
       ("путем [[" + mw.config.get('wgPageName') + "|Чаробњака за отпремање]]")
      ));
};


function fuwPackInfo(text, forCommons) {
   if (forCommons) {
      // reformat wikilinks embedded in description fields to adapt them for Commons
      text = text.replace(/\[\[([^\]]+)\]\]/g, 
         function(str, p1, offset, s) {

            // mark File links as local
            if (p1.match(/^:(File|Image|Датотека|Слика|Datoteka|Slika):/)) {
               return "[[:sr" + p1 + "]]";
            }      
            // leave prefixed links unchanged:
            else if (p1.match(/^:[\w\-]+:/)) {
               return str;
            }
            // if the link is piped, add a prefix only
            else if (p1.match(/.+\|/)) {
               return "[[:sr:" + p1 + "]]";
            }
            // introduce a pipe
            else {
               return "[[:sr:" + p1 + "|" + p1 + "]]";
            }
         }
      );
      return "{{sr|" + text + "}}";
   } else return text;
}

// ================================================================
// This is the main method called by the event handler for the 
// (experimental) submit button. Its main task is to collect the 
// input into a single string of wikitext for the description page.
// ================================================================
fuwGlobal.prototype.collectInput = function() {
   var opts = this.opts;

   // object representing template fields for filling in
   // the description template. Pre-loaded with some
   // standard settings:
   var descFields = this.descFields = { 
      'Description' : opts.InputDesc,
      'Author'      : opts.Author,
      'Date'        : opts.Date,
      'Source'      : opts.Source
   };
   // "other information" (outside the template)
   this.otherInfo = null;
   
   if (opts.OptionNonFree) {
      descFields.Article = opts.NFArticle;
   }
   
   // add/modify option-specific fields:
   switch (opts.MainOption) {
      case 'OptionOwnWork':
      
         // use standard "source" field for optional "how created?" and 
         // "previously published" input fields.
         descFields.Source = fuwAppendLines([
            (opts.OwnWorkCreation || "{{own}}"), 
            "<br/>\n", 
            fuwSurroundString("'''Претходно објављено:''' ", opts.OwnWorkPublication)]);
         var username = mw.user.getName();
         descFields.Author = '[[User:' + username + '|' + username + ']]';
         break;

      case 'OptionThirdParty':
      
         // use standard "permission" field for a compilation of the
         // "permission" input field and the various "evidence" options
         var evidence = (
            opts.ThirdPartyEvidenceOptionLink ? 
               ("Изјава о лиценци може се пронаћи онлајн на: " + opts.ThirdPartyEvidenceLink) :
               (opts.ThirdPartyEvidenceOptionOTRS ? 
               ("Споразум о лиценци прослијеђен је на [[Википедија:OTRS|OTRS]]." + 
                  fuwSurroundString(" Тикет: ", opts.ThirdPartyOTRSTicket) + "\{\{OTRS pending|year=" + fuwSubst("CURRENTYEAR") + 
                                                                              "|month=" + fuwSubst("CURRENTMONTH") + 
                                                                              "|day=" + fuwSubst("CURRENTDAY2") + "\}\}") :
               (opts.ThirdPartyEvidenceOptionOTRSForthcoming ? 
               "Споразум о лиценци биће ускоро прослијеђен на [[Википедија:OTRS|OTRS]]. \{\{OTRS pending|year=" + fuwSubst("CURRENTYEAR") + 
                                                                              "|month=" + fuwSubst("CURRENTMONTH") + 
                                                                              "|day=" + fuwSubst("CURRENTDAY2") + "\}\}" :
               (opts.ThirdPartyEvidenceOptionNone ?
               "Биће обезбијеђено на захтјев." : null))));
         descFields.Permission = fuwAppendLines([
            opts.ThirdPartyPermission,
            "<br/>\n",
            fuwSurroundString("'''Доказ:''' ", evidence)]);
         break;
         
      case 'OptionFreeWebsite':
         descFields.Permission = opts.Permission;
         break;
         
      case 'OptionPDOld':
         // add "lifetime" input to "author" field
         descFields.Author = fuwAppendLines([
            opts.Author,
            "<br/>\n",
            fuwSurroundString("(Животни вијек: ", opts.PDOldAuthorLifetime, ")")
         ]);
         
         // combine original and direct source into standard "source" field: 
         descFields.Source = fuwAppendLines([
            fuwSurroundString("'''Оригинално објављивање''': ", opts.Publication),
            "<br/>\n",
            fuwSurroundString("'''Непосредни извор''': ", opts.Source)
         ]);
         
         // no standard tag available for "lack-of-registration" PD-US. Need
         // to put this into the "permission" field
         if (opts.PDFormality) 
            descFields.Permission = 
               "Ауторска права су истекла јер је дјело објављено без напомене " +
               "о истима и/или без неопходне регистрације истих.";
      
         // add optional "explanation" input to "permission" field
         if (opts.PDOldPermission) {
            descFields.Permission = fuwAppendLines([
               descFields.Permission,
               "\n\n",
               opts.PDOldPermission
            ]);
         }
         break;
         
      case 'OptionPDOther':
         // Need "permission" field in case of "official item" option
         if (opts.PDOtherOfficial) 
            descFields.Permission = opts.PDOfficialPermission;
         break; 

      case 'OptionNFSubject':
         // most FUR elements can be automatically provided:
         descFields.Purpose = (
            opts.NFSubjectCheckDedicated ? 
             ("За визуелну идентификацију објекта чланка. " +
              "Чланак у цјелини посвећен је баш расправи о овом дјелу.") :
            (opts.NFSubjectCheckDiscussed ?
             ("Да се подржи енциклопедијска расправа о овом дјелу у чланку у питању. " +
              "Илустрација је неопходна да подржи сљедећи специфични навод: " +
              "<br/>\n" + opts.NFSubjectPurpose) : null)
         );
         // I hate FURs filled with trivial/predictable/redundant verbiage,
         // so we'll just cut it short. And don't anybody dare complain that
         // that's not a valid FUR.
         descFields.Replaceability = "Н/Д";
         descFields.Commercial     = "Н/Д";
         break;

      case 'OptionNF3D':
         // complex case: we need to assemble attribution and FUR both for the 
         // original 3D work and for the photographic depiction. Both might be 
         // non-free.
         descFields.Author = fuwAppendLines([
            fuwSurroundString("'''Оригинално дјело:''' ", opts.NF3DCreator),
            "<br/>\n",
            fuwSurroundString("'''Депикција:''' ", opts.Author)
         ]);
         descFields.Date = fuwAppendLines([
            fuwSurroundString("'''Оригинално дјело:''' ", opts.NF3DOrigDate),
            "<br/>\n",
            fuwSurroundString("'''Депикција:''' ", opts.Date)
         ]);
         descFields.Purpose = (
            opts.NF3DCheckDedicated ? 
             ("За визуелну идентификацију објекта чланка. " +
              "Чланак у цјелини посвећен је баш расправи о овом дјелу.") :
            (opts.NF3DCheckDiscussed ? 
             ("Да се подржи енциклопедијска расправа о овом дјелу у чланку у питању. " +
              "Илустрација је неопходна да подржи сљедећи специфични навод: " +
              "<br/>\n" + opts.NF3DPurpose) : null)
         );
         descFields.Replaceability = "Н/Д";
         descFields.Commercial    = "Н/Д";
         descFields["Other information"] = (
            opts.NF3DOptionSame ?
            ("Слику је направио и објавио исти аутор који посједује " +
             "ауторска права за оригинално дјело (објекат) и није " +
             "могуће сврсисходно створити алтернативни приказ.") :
            ("Аутор слике објавио је фотографско дјело под " +
             "слободном лиценцом, или је иста у јавном власништву: " + opts.NF3DPermission)
         );
         break; 
         
      case 'OptionNFExcerpt':
         // FURs for screenshots etc. don't normally need to bother
         // about replaceability (with free images) and with commercial role,
         // but do need to bother about purpose and about replaceability with text.
         descFields.Purpose        = opts.NFPurpose;
         descFields.Replaceability_text = opts.NFReplaceableText;
         descFields.Replaceability = "Н/Д";
         descFields.Commercial     = "Н/Д";
         break;
         
      case 'OptionNFCover':
         // cover art gets standard rationales.
         descFields.Purpose = 
            "да служи као примарно средство визуелне идентификације " +
            "при врху чланка посвећеног дјелу у питању.";
         descFields.Replaceability = "Н/Д";
         descFields.Commercial     = "Н/Д";
         break;
 
      case 'OptionNFLogo':
         // logos get standard rationales.
         descFields.Purpose = 
            "да служи као примарно средство визуелне идентификације " +
            "при врху чланка посвећеног ентитету у питању.";
         descFields.Replaceability = "Н/Д";
         descFields.Commercial     = "Н/Д";
         break;

      case 'OptionNFPortrait':
         // as with other historic photographs, it is useful to have both
         // original publication and direct source
         descFields.Source = fuwAppendLines([
            fuwSurroundString("'''Оригинално објављивање''': ", opts.Publication),
            "<br/>\n",
            fuwSurroundString("'''Непосредни извор''': ", opts.Source)
         ]);   
         descFields.Purpose = 
            "за визуелну идентификацију особе у питању, " +
            "при врху његовог/њеног биографског чланка";
         descFields.Replaceability = opts.NFReplaceable;
         descFields.Commercial = opts.NFCommercial;
         descFields['Other information'] = 
            "Субјекат на фотографији је покојник/ца од: " + opts.NFPortraitDeceased;
         break;
         
      case 'OptionNFMisc':
         descFields.Source = fuwAppendLines([
            fuwSurroundString(
               "'''Оригинално објављивање''': ", 
               opts.Publication,
               "<br/>\n'''Непосредни извор:''' "),
            "",
            opts.Source
         ]);   
         descFields.Purpose = opts.NFPurpose;
         descFields.Replaceability = opts.NFReplaceable;
         descFields.Replaceability_text = opts.NFReplaceable_text;
         descFields.Commercial = opts.NFCommercial; 
         break;     
   };

   if (opts.OptionNonFree) {
      // common stuff for all non-free files:
      
      // Minimality field (same for all NF options):
      descFields.Minimality = opts.NFMinimality;
      
      // append optional "extra license" selector and "AnyOther" fields
      // to "Other information" field:
      descFields['Other information'] = fuwAppendLines([
         descFields['Other information'],
         "<br/>\n",
         fuwSurroundString('\{\{', opts.NFExtraLicense, '\}\}'),
         "<br/>\n",
         opts.AnyOther
      ]);
   }
   else {
      // common stuff for all free files:
      descFields.Other_versions = ''
      this.otherInfo = fuwAppendLines([this.otherInfo, "\n\n", opts.AnyOther]);
   
   }

};

fuwGlobal.prototype.formatOutput = function(forCommons) {
   var baseForm = this.ScriptForm;
   var targetForm = this.TargetForm;
   if (fuwTesting) {
      var testForm   = this.TestForm;
   }
   var opts = this.opts;
   var otherInfo = this.otherInfo;
   var descFields = this.descFields;

   var summary = "{{" + this.getDescriptionTemplateName();

   // assemble all fields into the wikitext of the description page:
   var fieldOrder = [
      'Source', 'Date', 'Author', 'Permission', 'Other_versions',
      'Article', 'Purpose', 'Replaceability', 'Replaceability_text', 
      'Minimality', 'Commercial', 'Other information'
   ];
   summary += "\n|Description = " + fuwPackInfo(descFields['Description'], forCommons);
   for (var i = 0; i < fieldOrder.length; i++) {
      if (descFields[fieldOrder[i]]) {
         summary += "\n|" + fieldOrder[i] + " = " + descFields[fieldOrder[i]];
      }
   }
   summary += "\n}}\n";
   if (otherInfo) {
      summary += "\n;Other information:\n" + fuwPackInfo(otherInfo, forCommons) + "\n";
   }

   var editSummary = this.getEditSummary();
   
   var license = this.getLicense();
   
   if (forCommons) {
      // pack our description info into an url pointing to the 
      // standard Commons Special:Upload
      // with pre-loaded description fields

      summary = fuwSubst("Ознаку отпремања је додао ЧО sr.wp") + "\n" + summary;
      summary = summary.replace(/\{\{OTRS pending\}\}/g, fuwSubst("OP"));

      if (license.special) {
         // manually format the whole description page including the license tag, if it
         // isn't one of the bare standard licenses in the dropdown box. Otherwise,
         // submit description summary and license as two separate url parameters.
         summary = summary + "\n\n" + license.special;
      }
      return (fuwGetCommonsURL() +
         "?title=Special:Upload" +
         "&wpUploadDescription=" +
         encodeURIComponent(summary) +
         (license.standard ? 
          ("&wpLicense=" + encodeURIComponent(license.standard)) : '') +
         "&wpDestFile=" + 
         encodeURIComponent(opts.InputName));
   }
   else {
      // pack all description into a single "text" parameter to be submitted
      // to the local api.php upload.
      summary = "==Опис==\n" + 
         summary + 
         "\n==Лиценцирање==\n" + 
         (license.standard ? ("\{\{" + license.standard + "\}\}") : license.special) +
         this.getTrackingCategory();
         
      if (fuwTesting) {
         // Testing mode: show our data in the dummy form
         // at the bottom of the page.
         fuwGet('placeholderSandboxFilename').innerHTML = opts.InputName;
         this.TestForm.SandboxSummary.value = editSummary;
         this.TestForm.SandboxText.value = summary;
         fuwSetVisible('placeholderTestForm', true);
      }
      // write output parameters into target form
      // I can't believe IE7 is too stupid to simply understand "this.TargetForm.filename.value".
      ($('#TargetForm [name="filename"]')[0]).value = opts.InputName;
      ($('#TargetForm [name="text"]'    )[0]).value = summary;
      ($('#TargetForm [name="comment"]' )[0]).value = editSummary;
      ($('#TargetForm [name="token"]'   )[0]).value = mw.user.tokens.get('editToken');

   }
   
};

function fuwHasUserGroup(group) {
   // workaround because old IE versions don't have array.indexOf :-(
   for (i = 0; i < mw.config.get('wgUserGroups').length; i++) {
      if (mw.config.get('wgUserGroups')[i] == group) {
         return true;
      }
   }
   return false
}

fuwGlobal.prototype.getUserStatus = function() {
   // function to determine the experience status and userrights of the current user:
   // 'anon': not logged in; can't use script.
   // 'notAutoconfirmed': can't use local upload, but may use script to prepare upload for Commons
   // 'newbie': autoconfirmed but editcount < 100 
   //    (may be used in future to adapt instructions more to newbie needs)
   // 'problem': autoconfirmed but has 3 or more image-related warnings or deletion notifications among recent user talk entries
   //    (may be used in future to produce more strongly worded instructions)
   // 'autoconfirmed': regular user
   // 'sysop'

   if (mw.config.get('wgUserName')) {
      if (fuwHasUserGroup('sysop')) {
         this.userStatus = 'sysop';
      }
      else if (fuwHasUserGroup('autoconfirmed') || fuwHasUserGroup('confirmed')) {
         this.userStatus = 'autoconfirmed';
         $.ajax({
            url     : mw.util.wikiScript( 'api' ),
            type    : 'GET',
            dataType: 'xml',
            traditional : true,
            data:   {
                     format: 'xml',
                     action: 'query',
                     meta  : 'userinfo',
                     uiprop: 'editcount',
                     prop  : 'revisions',
                     titles: 'User talk' + mw.config.get('wgUserName'),
                     rvprop: 'comment|user',
                     rvlimit: 30
                    },      
            success: function(data) {
            // callback func     
               var fuw = window.fuw;
               if (data) {
                  var ui = data.getElementsByTagName('userinfo');
                  if (ui) {
                     var editcount = ui[0].getAttribute('editcount');
                     if (editcount < 100) {
                        fuw.userStatus = 'newbie';
                     }
                  }
                  var revs = data.getElementsByTagName('rev');
                  var countWarn = 0;
                  for (i = 0; i < revs.length; i++) {
                     var rev = revs[i];
                     var usr = rev.getAttribute('user');
                     var cmt = rev.getAttribute('comment');
                     if ((usr == 'ImageTaggingBot') ||
                         (cmt.search(/(означавање за брисање \[\[Датотека)|(недостају датотеке за отпремање)|(Датотека (извор и )?проблем са лиценцирањем ауторских права)|(Номиновање за брзо брисање \[\[Датотека)|(Обавјештење: стављање на списак \[\[могуће неслободне датотеке)/) >= 0)) {
                        countWarn += 1;   
                     }
                  }
                  if (countWarn >= 3) {
                     fuw.userStatus = 'problem';
                  }
               }
            }
         });
      }
      else {
         this.userStatus = 'notAutoconfirmed';
      }
   }
   else {
      this.userStatus = 'anon';
   }
};

// =================================================================
// Convenience function for getting the regular index.php
// interface of Commons. Not very elegant.
// =================================================================
function fuwGetCommonsURL() {
   if (document.URL.match(/^https:/)) 
      return "https://commons.wikimedia.org/w/index.php";
   else
      return "http://commons.wikimedia.org/w/index.php";
}  

// ==================================================================
// functions for building form elements
// ==================================================================
fuwMakeRadiobutton = function(group, option, checked, event) {
   // Stupid IE7 doesn't get "value" attribute unless it's created in this convoluted way.
   // Annoying.   
   var node = $('<input type="radio" id="' + option + '" name="' + group + '" value="' + option + '"></input>')[0];
   if (checked) node.checked = true;
   node.onclick = event || fuwRadioClick;
   node.onclick = event || fuwRadioClick;
   fuwAppendInput(option, node);
};
fuwMakeTextfield = function(label, event) {
   var node  = document.createElement('input');
   node.type = 'text';
   node.name = label;
   node.size = fuwDefaultTextboxLength;
   node.onchange = event || fuwUpdateOptions;
   // only for testing:
   //node.value = label;
   fuwAppendInput(label, node);
};
fuwMakeTextarea = function(label, event) {
   var node  = document.createElement('textarea');
   node.name = label;
   node.rows = fuwDefaultTextareaLines;
   node.style.width = fuwDefaultTextareaWidth;
   node.onchange = event || fuwUpdateOptions;
   //only for testing:
   //node.innerHTML = label;
   fuwAppendInput(label, node);
};
fuwMakeCheckbox = function(label, checked, event) {
   var node  = document.createElement('input');
   node.name = label;
   node.type = 'checkbox';
   //only for testing:
   //node.title= label;
   node.checked = checked;
   node.onchange = event || fuwUpdateOptions;
   fuwAppendInput(label, node);
}
fuwMakeHiddenfield = function(name, value, id) {
   var node   = document.createElement('input');
   node.name  = name;
   node.type  = 'hidden';
   node.value = value;
   fuwAppendInput((id || name), node);
};
fuwMakeAnchor = function(label, href, content) {
   var node   = document.createElement('a');
   node.name  = label;
   node.target= "_blank";
   node.href  = href;
   node.innerHTML = content;
   fuwAppendInput(label, node);
};
fuwMakeSelection = function(name, values) {
   var root = document.createElement('select');
   var current = root;
   try {
      for (i=0; i<values.length; i++) {
         var line = values[i];
         var entry;
         if (line.length == 0) {
            current = root;
         }
         else if (line.length == 1) {
            entry = document.createElement('optgroup');
            entry.setAttribute('label', line[0]);
            root.appendChild(entry);
            current = entry;
         }
         else {
            entry = document.createElement('option');
            entry.setAttribute('value', line[0]);
            entry.setAttribute('title', '{{' + line[0] + '}}');
            entry.innerHTML = line[1];
            if (line.length > 2) {
               entry.setAttribute('selected', 'selected');
            } 
            current.appendChild(entry);
         }
      }
   } catch (e) { alert("Назив: " + name + ", i=" + i); }
   root.name = name;
   root.onchange = fuwUpdateOptions;
   fuwAppendInput(name, root);
};
function fuwMakeWikilink(place, target, redlink, display) {
   
   place = fuwGet(place);
   var id = place.id;
   var anchor;
   if (place.tagName == 'A') {
      anchor = place;
   }
   else {
      anchor = document.createElement('a');
      place.appendChild(anchor);
   }
   anchor.href = mw.util.getUrl(target);
   anchor.title = target;
   anchor.innerHTML = target;
   anchor.className = (redlink ? 'new' : null);
}

function fuwAppendInput(label, content) {
   // append a newly created input element to an existing
   // span element marked as id="placeholderXYZ"
   var node = fuwGet('placeholder' + label);
   var old  = fuwGet(label);
   if (old) {
      old.parentNode.removeChild(old);
   }
   content.id = content.id || label;
   if (node) {
      while (node.hasChildNodes()) {
         node.removeChild(node.firstChild);
      }
      node.appendChild(content);
   }
}

// ======================================================
// move an element away from its current position
// and append it to a target element if condition is true
// ======================================================
function fuwMove(mv, tg, condition, toStart) {
   if (condition) {
      move   = fuwGet(mv);
      target = fuwGet(tg);
      if (move && target) {
         var parent = move.parentNode;
         if (! (target===parent)) {
            parent.removeChild(move);
            if (toStart) {
               target.insertBefore(move, target.firstChild);
            }
            else {
               target.appendChild(move);
            }
         }
      }
      else {
         alert("Непронађени елементи: move=" + mv + "(" + move + "), target=" + tg + "(" + target + ")");
      } 
   }
   return condition;
}

// ===================================================
// make an element visible/invisible
// ===================================================
function fuwSetVisible(tg, condition) {
   target = fuwGet(tg);
   if (target) {
      if (condition) {
         $(target).show();
      }
      else {
         $(target).hide();
      }
   }
   else {
      alert("Непронађени елемент: " +  (tg.nodeType ? tg.id : tg));
   }
}

// ===================================================
// set enabled/disabled status for an element and/or
// all input controls contained in it.
// ===================================================
function fuwSetEnabled(tg, condition) {
   target = fuwGet(tg);
   try {
      var elements = (target.tagName.match(/^(input|textarea|select|button|a)$/i) ? 
         [target] :
         $('#' + target.id + ' *'));
      for (i = 0; i<elements.length; i++) {
         if (elements[i].tagName.match(/^(input|textarea|select|button|a)$/i)) {
            elements[i].disabled = (condition ? null : "онемогућено");
         }
      }
   } catch (e) { alert("Непронађени елемент: " +  (tg.nodeType ? tg.id : tg)); }
}

// ===================================================
// convenience function to check whether a given
// element is currenly visible. Needs to check display
// property of the element and its ancestors
// ===================================================
function fuwIsVisible(el) {
   element = fuwGet(el);
   if (!element) return false;
   el = element.id;
   
   var visible = true;
   while (! (element === document.body)) {
      if (element.style.display == "празно") {
         visible = false;
         break;
      }
      element = element.parentNode;
   }
   return visible;
}

// ===================================================
// cleanup filename
// ===================================================
function fuwCleanFilename() {
   var nameBox = window.fuw.ScriptForm.InputName;
   var oldname = name = $.trim(nameBox.value);

   if (name) {
      // strip accidentally added [[   ]] or [[:  ]] brackets
      name = name.replace(/(^\[\[:?)|(\]\]$)/g, "");
      // strip accidentally added "File:" prefix
      name = name.replace(/^(File|Image|Датотека|Слика|Datoteka|Slika):/, "");
      // replace underscores with spaces
      name = name.replace(/_/g, " ");
      // uppercase first letter
      name = name.charAt( 0 ).toUpperCase() + name.slice(1);
   }
   if (oldname != name) {
      nameBox.value = name;
   }
   // always return true so the next validation step will proceed:
   return true;
}


// ==================================================
// check filename for technically illegal 
// characters, trying to fix them automatically
// ==================================================
function fuwCheckLegalFilename() {
   var nameBox = window.fuw.ScriptForm.InputName;
   var oldname = name = $.trim(nameBox.value);

   if (name) {
      // resolve accidentally entered html entities and URI-encoded %XX character codes
      name = name.replace(/\&[a-z]+;/g, fuwHtmlEntityDecode);
      name = name.replace(/(\%[A-F0-9]{2,2})/g, decodeURI);
      // remove illegal characters # < > [ ] | { } /:
      // using a best guess for an acceptable replacement
      name = name.replace(/[<\[\{]/g, "(");
      name = name.replace(/[>\]\}]/g, ")");
      name = name.replace(/[#:\|]/g,  ",");
      name = name.replace(/\//g, "-");
      // remove sequences of tildes
      name = name.replace(/\~{3,}/g, "---");
      // remove initial slash
      name = name.replace(/^\//, "");
   }
   
   if (oldname != name) {
      window.fuw.warn.IllegalChars = true;
      nameBox.value = name;
      return false;
   }
   else {
      window.fuw.warn.IllegalChars = false;
      return true;
   }
}
function fuwHtmlEntityDecode(str) {
   // hack to translate accidentally entered html entity code
   // into actual characters
   var ta=document.createElement('textarea');
   ta.innerHTML=str.replace(/</g,'<').replace(/>/g,'>');
   return ta.value;
}

// =======================================================
// Check against various common patterns of poorly chosen
// filenames (too short / too generic)
// =======================================================
function fuwCheckPoorFilename() {
   var nameBox = window.fuw.ScriptForm.InputName;
   var name = $.trim(nameBox.value);
	name = name.replace(/\.(png|gif|jpg|jpeg|xcf|pdf|mid|ogg|ogv|svg|djvu|tiff|tif|oga)$/i, "");

   // name should be at least 10 characters long, excluding file type extension
   var tooShort = (name.length < 10);
   
   // common generic filename patterns: 
   // IMG......jpg
   // Image....jpg
   // DSC......jpg
   // Picture......jpg
   // Pic..........jpg
   // anything that has fewer than 3 alphabetic letters and then just numbers
   var pattern = /^(img|image|dsc|picture|pic)?(\\s*|\\_*|[a-z]{,3})?\\d+$/i;
   var auto = name.match(pattern);

   window.fuw.warn.BadFilename = (tooShort || auto);
   return !tooShort && !auto;
}

// =======================================================
// check if file extensions match between local filename
// and target filename input box. Automatically append 
// appropriate extension to target filename if they don't.
// =======================================================
function fuwCheckFileExtension() {
   var nameBox = window.fuw.ScriptForm.InputName;
   var name = $.trim(nameBox.value);
   var fileBox = window.fuw.TargetForm.file;
   var file = fileBox.value;
   
   // cancel check if no filename has been provided yet
   if (!file || !name) return true;
   
   var extensions = /.+\.(png|gif|jpg|jpeg|xcf|pdf|mid|ogg|ogv|svg|djvu|tiff|tif|oga)$/i;
   var mimetypes = {
      "png"  : "image/png",
      "gif"  : "image/gif",
      "jpg"  : "image/jpeg",
      "jpeg" : "image/jpeg",
      "xcf"  : "image/x-xcf",
      "pdf"  : "application/pdf",
      "mid"  : "audio/rtp-midi",
      "ogg"  : "audio/ogg",
      "ogv"  : "video/ogg",
      "svg"  : "image/svg+xml",
      "djvu" : "image/vnd.djvu",
      "tiff" : "image/tiff",
      "tif"  : "image/tiff",
      "oga"  : "video/ogg"
   };   

   var found = extensions.exec(file);
   var fileExt = found ? found[1].toLowerCase() : "";
   found = extensions.exec(name);
   var nameExt = found ? found[1].toLowerCase() : "";
   var mime = mimetypes[fileExt]; 
   
   if (fileExt && mime && (mimetypes[nameExt] != mime)) {
      nameBox.value = name.replace(/\.?$/, ('.' + fileExt));
   }
   return true;
}

// ============================================================
// Check if a file under the chosen name already exists,
// either locally or on Commons.
// Store results in the fuw.warn object, so warnings will
// be displayed on the next fuwUpdateOptions() call
// ============================================================
function fuwCheckFileExists() {
   // this is an asynchronous AJAX function.
   // results won't yet be present when this function returns.

   var nameBox = window.fuw.ScriptForm.InputName;
   var name = $.trim(nameBox.value);

   // using the jQuery wrapper for the Ajax functionality:
   $.ajax({
      url     : mw.util.wikiScript( 'api' ),
      type    : 'GET',
      dataType: 'xml',
      traditional : true,
      data:   {
               format: 'xml',
               action: 'query',
               titles: 'File:' + name,
               prop  : 'imageinfo',
               iiprop: 'url|user',
               iiurlwidth: 120
              },      
      success: function(resp) {
      // callback function, called when API query has succeeded:
         // see if the request has returned info from an existing image:
         var foundlist = resp.getElementsByTagName('ii');
         var exists = (foundlist.length >= 1);
         var isCommons = false;
         if (exists) {

            // extract description data from http response.
            // see https://www.mediawiki.org/wiki/API:Properties#imageinfo_.2F_ii 
            // for structure of API response
            var foundImg = foundlist[0];
            isCommons = (foundImg.parentNode.parentNode.getAttribute('imagerepository')=='shared');

            // need this data for creating our own image thumb link
            var width = foundImg.getAttribute('thumbwidth');
            var height = foundImg.getAttribute('thumbheight');
            var thumbURL = foundImg.getAttribute('thumburl');
            var lastUser = foundImg.getAttribute('user');
            var descURL = foundImg.getAttribute('descriptionurl');

            // API returns link to local description page even for Commons images.
            // However, we want a direct link to Commons.
            if (isCommons) {
               descURL = descURL.replace(/sr\.wikipedia\.org/, "commons.wikimedia.org");
               descURL = descURL.replace(/\/\/secure\.wikimedia\.org\/wikipedia\/sr/, "commons.wikimedia.org");
            }

            // build the image info into the warning section of our page:
            thumbDiv = fuwGet('warningImageThumb');
            if (thumbDiv) {
            
               // make all links point to description page:
               var thumbA = thumbDiv.getElementsByTagName('a');
               for (i = 0; i<thumbA.length; i++) {
                  thumbA[i].setAttribute('href', descURL);
               }
               // insert the image itself:
               var thumbImg = thumbDiv.getElementsByTagName('img');
               if (thumbImg.length > 0) {
                  thumbImg = thumbImg[0];
                  thumbImg.setAttribute('src', thumbURL);
                  thumbImg.setAttribute('width', width);
                  thumbImg.setAttribute('height', height);
               }
               // insert the name of the last uploader:
               var thumbSpan = fuwGet('existingImageUploader');
               // TO DO: turn this into a proper link
               if (thumbSpan) thumbSpan.innerHTML = lastUser;
            }

            
         }
         warn = window.fuw.warn;
         warn.ImageOnCommons = exists && isCommons;
         warn.ImageExists    = exists && !isCommons;

         fuwUpdateOptions();
      }
   });
}

// ===========================================================
// onchange event handler for the local filename box
// ===========================================================
fuwValidateFile = function() {
   fuwCheckFileExtension();
   fuwUpdateOptions();
}

// ===========================================================
// onchange event handler for the name input box
// ===========================================================
fuwValidateFilename = function() {
   fuwCleanFilename();
   if (
      fuwCheckLegalFilename() &&
      fuwCheckPoorFilename() &&
      fuwCheckFileExtension()) {
      // after fuwCheckFileExists(),
      // fuwUpdateOptions will be triggered
      // by the callback function after Ajax completion
      fuwCheckFileExists();
   }
   else {
      // if there's been no Ajax call.
      fuwUpdateOptions();
   }
};

// ==========================================================
// function fuwValidateNFArticle()
// ==========================================================
// This is the validation routine for the obligatory
// article-to-be-used-in field for non-free files. It queries
// api.php about the target article through an Ajax call.
// It will store error info in the fuw.warn object,
// triggering the following error on the next updateOptions():
// * warningNFArticleNotFound : target page doesn't exist.
// * warningNFArticleNotMainspace : target is not an article. 
// * warningNFArticleDab : target is a disambiguation page.
// Redirects will automatically be substituted.
// ==========================================================
fuwValidateNFArticle = function() {
   
   var nameBox = window.fuw.ScriptForm.NFArticle;
   oldname = name = nameBox.value;
   
   // cleanup article name:
   // automatically fix accidentally added [[ ... ]] and
   // regularize underscores
   name = $.trim(name);
   name = name.replace(/(^\[\[)|(\]\]$)/g, "");
   // automatically fix article names entered as full urls:
   name = name.replace(/^https?:\/\/sr\.wikipedia\.org\/wiki\//, "");
   name = name.replace(/^https?:\/\/sr\.wikipedia\.org\/w\/index\.php\?title=/, "");
   name = name.replace(/_/g, " ");
   if (name != oldname) nameBox.value = name;
   
   // do nothing more if field was blank
   if (!name) return;

   // using the jQuery wrapper for the Ajax functionality:
   $.ajax({
      url     : mw.util.wikiScript( 'api' ),
      type    : 'GET',
      dataType: 'xml',
      traditional : true,
      data:   {
               format: 'xml',
               action: 'query',
               titles: name,
               prop  : 'info|categories|links'
              },      
      success: function(resp) {
      // callback function, called when API query has succeeded:
         var errorType = 0;
         var pg = resp.getElementsByTagName('page')[0];
         var title = pg.getAttribute('title');
         var target = title;
         if (pg.getAttribute('missing') != null) {
            // no page found under this title.
            errorType = 1;
         }           
         else {
            var userspace = false;
            var ns = pg.getAttribute('ns');
            var rd = pg.getAttribute('redirect');
            if (ns != 0) {
               // not a mainspace page!
               errorType = 2;

               // try to detect if the target might be a user space draft:               
               if (title.match(new RegExp("User( talk)?:" + mw.config.get('wgUserName')))) {
                  userspace = true;
               }
            }
            else if (rd != null) {
               // redirect page
               // API returns an empty redirect="" attribute if
               // the page is a redirect
               var targets = pg.getElementsByTagName('pl');
               for (i=0; i<targets.length; i++) {
                  var link = targets[i];
                  if (link.getAttribute('ns')==0) {
                     target = link.getAttribute('title');
                     errorType = 3;
                     break;
                  }
               }
            }
            else {
               // check for disambiguation categories
               var cats = pg.getElementsByTagName('cl');
               for (i=0; i<cats.length; i++) {
                  var cat = cats[i];
                  if (cat.getAttribute('title') == "Категорија:Вишезначна одредница") {
                     errorType = 4;
                     break;
                  }
               }  
            }
         }
         warn = window.fuw.warn;
         warn.NFArticleNotFound = (errorType==1);
         warn.NFArticleNotMainspace = (errorType==2);
         warn.UserspaceDraft = ((errorType==2) && userspace);
         warn.NFArticleDab = (errorType==4);
         warn.NFArticleOK  = (errorType==0);

         // fix links in error messages:
         if (warn.NFArticleNotFound) {
            fuwMakeWikilink(fuwGet('warningNFArticleNotFound').getElementsByTagName('A')[0], target, true);
         }
         else if (warn.NFArticleNotMainspace) {
            fuwMakeWikilink(fuwGet('warningNFArticleNotMainspace').getElementsByTagName('A')[0], target);
         }
         else if (warn.NFArticleDab) {
            fuwMakeWikilink(fuwGet('warningNFArticleDab').getElementsByTagName('A')[0], target);
         }
         else if (warn.NFArticleOK) {
            fuwMakeWikilink(fuwGet('NFArticleOK').getElementsByTagName('A')[0], target);
         }
                       
         if (errorType==3) {
            // automatically replace title with redirect target
            window.fuw.ScriptForm.NFArticle.value = target;
            // need to recursively call validation again now
            //if (confirm(name + " је преусмјерење. Пратите га до " + target + "?")) {
               fuwValidateNFArticle();
            //}
         }
         else {
            fuwUpdateOptions();
         }          
      }
   });
};

// ================================================
// manually reload script (just for testing)
// ================================================
function fuwReload() {
   mw.loader.load( 'http://localhost/script/uploadscript.js' );
   fuwReset();
}

// ================================================
// reset forms
// TO DO: add a button that actually triggers this.
// ================================================
function fuwReset() {
   var forms = mw.util.$content[0].getElementsByTagName('form');
   for (i = 0; i < forms.length; i++) {
      forms[i].reset();
      window.fuw.warn = { };
      window.fuw.opts = { };
   }
   fuwSetVisible('UploadScriptArea', true);
   fuwSetVisible('fuwSuccess', false);
   fuwSetVisible('fuwWaiting', false);
   fuwUpdateOptions();
}

// ===============================================
// convenience functions for string handling
// ===============================================
function fuwAppendLines(parts) {
   // assemble a string from an array of strings.
   // treat every second element as a conditional
   // separator that will be included only if 
   // surrounding elements are non-empty.
   var build = "";
   for (var i = 0; i < parts.length; i += 2) {
      if (parts[i]) {
         if (build) build += parts[i - 1];
         build += parts[i];
      }
   }
   return build;
}
function fuwSurroundString(prefix, content, suffix) {
   // put a prefix and a suffix on a string, 
   // if the input string is non-empty.
   if (content) 
      return (prefix ? prefix : "") + content + (suffix ? suffix : ""); 
   else return "";
}

// ========================================================
// convenience function for accessing the contents of the
// dummy TargetIFrame
// ========================================================
function fuwGetDocumentFromIFrame(iframe) {
   var doc = (iframe.contentDocument ? iframe.contentDocument : iframe.contentWindow.document);
   if (doc.XMLDocument) {
      doc = doc.XMLDocument;
   }
   return doc;
}
// ========================================================
// event handler for the dummy TargetIFrame's onload event.
// TO DO: expand stub to add real notification of success,
// link to new file page, instructions about how to include
// file in articles, etc.
// ========================================================
function fuwUploadCompleted() {
   var doc = fuwGetDocumentFromIFrame(fuwGet('TargetIFrame'));
   if (doc) {
      //alert(doc);
      fuwSetVisible('successThumb', false);

      var fuw = window.fuw;
      var name = fuw.opts.InputName;

      var uploads = doc.getElementsByTagName('upload');
      var success = false;
      for (i = uploads.length-1; i>=0; i--) {
         if (uploads[i].getAttribute('result') == 'Success') {
            success = true;
            // need to get the real resulting filename here; might be different from the requested one in some cases.
            name = uploads[i].getAttribute('filename');
            break;
         }
      }
      if (success) {

         // need another ajax call to check the file is actually there,
         // and to retrieve its direct thumb img url:
         $.ajax({
            url     : mw.util.wikiScript( 'api' ),
            type    : 'GET',
            dataType: 'xml',
            traditional : true,
            data:   {
                     format: 'xml',
                     action: 'query',
                     titles: 'File:' + name,
                     prop  : 'imageinfo',
                     iiprop: 'url',
                     iiurlwidth: 120
                    },      
            success: function(resp) {
               // callback function, called when API query has succeeded:
               // see if the request has returned info from an existing image:

               var foundImg = resp.getElementsByTagName('ii')[0];
               if (foundImg) {

                  // need this data for creating our own image thumb link
                  var width = foundImg.getAttribute('thumbwidth');
                  var height = foundImg.getAttribute('thumbheight');
                  var thumbURL = foundImg.getAttribute('thumburl');
                  var lastUser = foundImg.getAttribute('user');
                  var descURL = foundImg.getAttribute('descriptionurl');

                  // build the thumbnail in the success message:
                  thumbDiv = fuwGet('successThumb');
                  
                  // make link point to description page:
                  var thumbA = thumbDiv.getElementsByTagName('a')[0];
                  thumbA.href = descURL;

                  // insert the image itself:
                  var thumbImg = thumbDiv.getElementsByTagName('img')[0];
                  thumbImg.setAttribute('src', thumbURL);
                  thumbImg.setAttribute('width', width);
                  thumbImg.setAttribute('height', height);
                  
                  fuwSetVisible(thumbDiv, true);
               }
            }
         });
         fuwMakeWikilink(
            fuwGet('fuwSuccessLink2').getElementsByTagName('a')[0],
            'File:' + name);
         fuwGet('placeholderExFilename1').innerHTML = name;
         fuwGet('placeholderExFilename2').innerHTML = name;
         fuwSetVisible('fuwSuccess', true);
         fuwSetVisible('fuwWaiting', false);
      }
      else {
         var err = doc.getElementsByTagName('error');
         if (err) {
            var info = err[0].getAttribute('info');
            var details = err[0].getElementsByTagName('detail');
            var add = "";
            for (i = 0; i < details.length; i++) {
               if (add.length > 0) add += ", ";
               add += details[i].textContent;
            }
            if (add) {
               info = info + " (" + add + ")";
            }
            alert("Отпремање није успјело: " + info);
         }
         else {
            alert("Непозната грешка: Отпремање можда није успјело.");
         }
      }
   }
}

// ========================================================
// clean out dummy IFrame before submitting a request
// ========================================================
function fuwResetTargetIFrame() {
   var doc = fuwGetDocumentFromIFrame(fuwGet('TargetIFrame'));
   if (doc) {
      while (doc.hasChildNodes()) {
         doc.removeChild(doc.firstChild);
      }
   }
}

// ========================================================
// Event handler for the real submit button
// ========================================================
function fuwSubmitUpload() {
   
   var fuw = window.fuw;
   var frm = fuw.TargetForm;

   fuw.collectInput();
   fuw.formatOutput(false);

   // we will use the iframe's onload event to trigger a function that
   // adds success notification etc.
   fuwResetTargetIFrame();
   var ifr = fuwGet('TargetIFrame');
   if (ifr.attachEvent) {
      // workaround for IE, according to 
      // http://www.nczonline.net/blog/2009/09/15/iframes-onload-and-documentdomain/
      ifr.attachEvent("onload", fuwUploadCompleted);
   }
   else {
      // all other browsers
      ifr.onload = fuwUploadCompleted;
   }

   if (fuwTesting) {
      fuwSetVisible('placeholderTestForm', false);
   }
   fuwSetVisible('UploadScriptArea', false);

   fuwMakeWikilink(
     fuwGet('fuwSuccessLink').getElementsByTagName('a')[0], 'File:' + fuw.opts.InputName);
   fuwSetVisible('fuwWaiting', true);

   frm.submit();
   var opts = window.fuw.opts;
   // the API won't overwrite the description page text while overwriting
   // a file, which is really, really, really annoying and stupid.
   // So in the opts.OverwriteDifferent scenario, we need to edit
   // the description page through a separate ajax call. Dang.
   if (opts.OverwriteDifferent) {
      $.ajax({
         url   : mw.util.wikiScript('api'),
         type  : 'POST',
         dataType : 'xml',
         data  : {
                  format : 'xml',
                  action : 'edit',
                  title  : 'File:' + opts.InputName,
                  token  : mw.user.tokens.get('editToken'),
                  summary : opts.EditSummary,
                  text   : ($('#TargetForm .[name="text"]')[0]).value

                 }
      });
   }
}

// =======================================================
// Event handler for the Commons submit button
// =======================================================
function fuwSubmitCommons() {
   var fuw = window.fuw;
   fuw.collectInput();
   var url = fuw.formatOutput(true);
   alert("Сада ћете бити преусмјерени на Оставу. \nКористите образац за отпремање на Остави да бисте додали категорије у опис датотеке коју отпремате, а потом завршите отпремање.");
   window.location = url;
}

// =======================================================
// Event handler for the test submit button
// (write description string to sandbox only)
// =======================================================
function fuwSubmitSandbox() {
   var frm = window.fuw.TestForm;
   $.ajax({
      url     : mw.util.wikiScript( 'api' ),
      type    : 'POST',
      dataType: 'xml',
      data:   {
               format: 'xml',
               action: 'edit',
               title : mw.config.get('wgPageName') + "/sandbox",
               token : mw.user.tokens.get('editToken'),
               recreate : 1,
               summary  : frm.SandboxSummary.value,
               text     : frm.SandboxText.value
              },      
      success: function(resp) {
         alert("Уређена страница пијеска!");
      }
   });
}



// ========================================================
// convenience wrapper function to replace calls to
// document.getElementById() 
// to avoid browser incompatibility
// ========================================================
function fuwGet(target) {
   if (target && target.nodeType) return target;
   else {
      var found = $('#' + target);
      if (found) return found[0];
   }
   return undefined;
}

// ========================================================
// onload hook function, loading this script
// ========================================================
$(function() { 
   if (fuwGet('UploadScriptArea')) {
      window.fuw = new fuwGlobal();
      fuwUpdateOptions();
   }
});

Ево превео сам овде шта је требало а и шта можда није (не знам да ли описи као што је fuwSurroundString("'''Непосредни извор''': " служе за имена која ће се генерисати овде или за Оставу, али лако је тај дио прекопирати какав је био непреведен па упоредити измјене и евентуално поново превести на српски у том враћеном оригиналном дијелу на енглеском језику оно што треба стварно да буде на српском.

Треба још неколико пута прочитати и ускладити са шаблоном за образац који је тренутно у пијеску и ревидиран први пут.  Обсусер 18:39, 27. октобар 2016. (CEST)Одговори

Потребно исправити: опремања → отпремања, Обајвештење → Обавјештење, < → &lt; и > → &gt; те          (видјети за ово посљедње/размаке у коду на овој СЗР шта је између тагова за код и новики тагова пошто се није приказало).  Обсусер 19:09, 27. октобар 2016. (CEST)Одговори
Гдје извршити ове посљедње три промјене примјене? —Ранко Николић (разговор) 19:14, 27. октобар 2016. (CEST)Одговори
У овом Медијавијију; ова посљедња је мање битна а &lt; и &gt; су се вјероватно претворили у < и > редом у коду (који си директно копирао са ове странице Разговора о Медијавикију а не из самог њеног кода).
Ово се види да се промијенило при успоредби измјена: овдје (подебљане ознаке Ред 1.806 и Ред 1.817).  Обсусер 20:25, 27. октобар 2016. (CEST)Одговори

Наставак

@Ранко Николић и Srdjan m: Шта мислите о ијекавици? Ја сам да се све пребаци у екавицу јер је софтвер иначе на екавици; евентуално, ако је изводљиво, да се дода у подешавањима опција у којој ће се изабрати изговор и зависно од тога да се користи екавски Медијавики и онај образац и ијекавски Медијавики и онај образац (али није на мени да одлучујем о овоме, а и компликовано је и помињао сам ово још једном — и за ћирилицу/латиницу такође такође, да буду четири верзије у зависности од одабира писма и изговора — па није било ништа).

Још боље рјешење је питати на Тргу у вези са ијекавицом у обрасцу за отпремање и да се више корисника изјасни (осим ако нешто мени промиче па треба заиста на ијекавици).

Пошто су ијекавица и екавица потпуно равноправе у српском језику нема потребе за било каквим пребацивањем. —Ранко Николић (разговор) 20:17, 27. октобар 2016. (CEST)Одговори
Јесу потпуно равноправни изговори али иде се превише на штету досљедности. Да ли има иједан други дио интерфејса да је на ијекавици?
Ако нема, мислим да је боље питати на Тргу. Сугерисао сам још сад и нећу више јер није од кључног значаја...
Такође, не знам гдје треба превести фамозно дугме „Choose File” и текст „No file chosen” (и можда има још повезаног текста) — јер ово се све до данас задржало непреведено у тренутном (старом) обрасцу (десно од „Назив изворне датотеке”).  Обсусер 20:25, 27. октобар 2016. (CEST)Одговори
Па ако се будемо увијек ослањали на досљедност никада неће ни бити дијела интерфејса на ијекавици. Можда ти је најбоље да енглезе питаш у чему је проблем. —Ранко Николић (разговор) 20:50, 27. октобар 2016. (CEST)Одговори
Ако можеш копирај само код из овог одјељка Преводи (директно из одјељка након клика на Уреди), сада сам поправио ситнице, и толико од мене сад-засад (ви ревидирајте поново, а ако могу још негдје помоћи кажите).
Могуће је да сам нешто превео што није требало, али цијели нови систем треба добро истестирати и видјети гдје се шта генерише па дорадити (обратити пажњу нпр. на File|Image|Датотека итд., онда спајање реченица, категорије, испис порука о грешкама, описе измјена, шаблоне за лиценце — а такође и слање на Оставу одавде које би могло да буде проблематично).
Такође ово „Животни вијек” ми је чудно [неповезано] ако ту иде датум смрти (или не иде увијек? уноси се 100 [животни вијек] или 1916 [година смрти]?), те помињање неке „расправе” у чланку а мисли се на садржај/дио/дијелове чланка гдје се нешто говори о датотеци (како сам ја схватио).
Ја сам предложио четири верзије: sr-ec-ek, sr-ec-ijek, sr-el-ek, sr-el-ijek и назвао их сновима; ако се икад остваре (а није немогуће), тада ће се цијели интерфејс који је сада на екавици морати превести на ијекавицу и додати у подешавања (и падајући мени гдје су сад само за писма) и опције за изговор. То је само теорија, можда је и неизводљива, али нема везе, нека остане забиљежена као теорија...
„Choose File” и др. видим сада да није изгледа преведено ни на једној Вики, али сада нема везе (може их се наравно и питати, Енглезе, ако ће остати у старом обрасцу а некоме сметати непреведено)... Обсусер 01:01, 28. октобар 2016. (CEST)Одговори
Требаће поправити ово са none/празно и можда онемогућено односно направити да се приказује текст „празно” умјесто „none” а уклонити кутију која се сада приказује у 1. кораку ('none' је можда требало превести)...  Обсусер 01:49, 28. октобар 2016. (CEST)Одговори
Овај посљедњи none што си превео је прави, а један или оба моја празно ваљда утичу на приказ оне кутије у првом кораку које иначе нема па треба тај један или оба вратити у none.  Обсусер 02:26, 31. октобар 2016. (CET)Одговори
Ако се можда користи у овом Медијавикију и исписује негдје (не знам напамет гдје би то могло бити по самом коду Медијавикија) „File:” и сл., замијенити то са „Датотека:” и сл. да се исписује преведен облик.  Обсусер 11:59, 31. октобар 2016. (CET)Одговори
Можда тако нешто има овдје. —Ранко Николић (разговор) 12:59, 31. октобар 2016. (CET)Одговори
@Obsuser: Колико ја знам, то дугме/текст у потпуности зависи од прегледника (можда и од система). На примјер, на Firefox-у ми уопште не пише „Choose File”, већ „Browse...” а поред „No file selected” јер су ми прегледник и систем на енглеском. Ако имаш инсталиран Chrome, можеш лако пребацити језик и провјерити /под „Change the language of your Chrome browser (Windows & Chromebook only)” (ја не могу, јер не ради на macOS-у)/. Ако се не промијени, онда зависи од језика система. – Srdjan m (разговор) 19:12, 31. октобар 2016. (CET)Одговори
@Srdjan m: У праву си, пробао сам прије неколико сати и било је преведено када сам у Chrome-у промијенио језик у српски.
Али који је смисао тога? Зар није сваки веб-сајт „за себе” односно сам текст који исписује не би требало да уопште зависи од претраживача него од самог сајта (једино да претраживач утиче на нека форматирања односно CSS и сл.). Мислим веома је чудно, али можда су морали тако јер се приступа рачунару да се узме слика па је сигурније кроз претраживач и то...
Него ако можеш, ти погледај недостаје ли шта и преведи на Транслејт викију шта је повезано за онај Чаробњак, а успут молим те погледај и оно што сам ја преводио овде и у пијеску (могуће је да има у овом Медијавикију неко „File:” које треба замијенити са „Датотека:” да се исписује преведено и сл.; обратити пажњу и на File|Image|Датотека итд., онда спајање реченица, категорије, испис порука о грешкама, описе измјена, шаблоне за лиценце — а такође и слање на Оставу; понављам: такође ово „Животни вијек” ми је чудно [неповезано] ако ту иде датум смрти (или не иде увијек? уноси се 100 [животни вијек] или 1916 [година смрти]?), те помињање неке „расправе” у чланку а мисли се на садржај/дио/дијелове чланка гдје се нешто говори о теми тог чланка а повезано с датотеком која је за то неопходна).  Обсусер 05:17, 1. новембар 2016. (CET)Одговори
На сајту Translatewiki све је у реду, а видјећу остатак у пијеску. Чаробњак би ваљало/требало темељно тестирати, само што не знам како то извести без да се потпуно спамују скорашње измјене... – Srdjan m (разговор) 07:58, 1. новембар 2016. (CET)Одговори

Дорада

@Ранко Николић: Ситница, треба замијенити "|Водич за отпремање]]") са "|Водича за отпремање]]").  Обсусер 17:50, 29. април 2017. (CEST)Одговори

   Урађено . — Ранко   Нико лић   18:54, 29. април 2017. (CEST)Одговори

Исправити и „Non-free Denver Public Library” у „Non-free Denver Public Library image”.  Обсусер 20:14, 18. мај 2017. (CEST)Одговори

   Урађено . — Ранко   Нико лић   21:01, 18. мај 2017. (CEST)Одговори

@Ранко Николић: Треба замијенити додајте  са у поље за другу лиценцу додајте  и {{tl|keep local}} са „&#123;&#123;keep local&#125;&#125;”.  Обсусер 22:26, 24. мај 2017. (CEST)Одговори

Замијенио и додао нове лиценце. — Ранко   Нико лић   22:34, 24. мај 2017. (CEST)Одговори
Стави и наводнике, а ово се тренутно налази у „Ово је неслободно дјело заштићено ауторским правима, али вјерујем да спада под поштену употребу.” > „нека друга врста неслободног дјела” > „Посебан извор и услови лиценцирања (необавезно)”.
Да би оне за државне акте биле међу слободнима, покушај копирати овдје све што је везано за „USGovLicense” односно на ВП:Водич за отпремање што је везано за „Дјело створила агенција Федералне владе САД.” (за ово може да пише „Дјело створила агенција владе, влада или неки државни орган друге земље.”). Ција и Државни акти САД не треба (већ има додато), само оне за државне акте Србије и Црне Горе. Ако не буде радило (требало би да дода једну опцију), онда вратити и смислити нешто друго.  Обсусер 22:51, 24. мај 2017. (CEST)Одговори
@Ранко Николић: Такође треба превести \n;Other information у \n;Остале информације и замијенити:
  • 'File:' + name са 'Датотека:' + name (више појављивања)
  • 'File:' + fuw.opts.InputName са 'Датотека:' + fuw.opts.InputName
  • 'File:' + opts.InputName са 'Датотека:' + opts.InputName
(Мислим да се због овог првог није исписивала порука о успешном отпремању.)  Обсусер 13:37, 27. мај 2017. (CEST)Одговори

@Ранко Николић: Ево, покушај:

/*
* ===============================================================
*                    FileUploadWizard.js
* Script for uploading files through a dynamic questionnaire.
* This is the code to accompany [[Wikipedia:File Upload Wizard]].
* ===============================================================
*/

var fuwTesting = false;
var fuwDefaultTextboxLength = 60;
var fuwDefaultTextareaWidth = '90%';
var fuwDefaultTextareaLines = 3;

// ================================================================
// Constructor function of global fuw (= File Upload Wizard) object
// ================================================================
function fuwGlobal() {

   // Loading the accompanying .css
   mw.loader.load( mw.config.get('wgServer') + mw.config.get('wgScriptPath') +
      '/index.php?title=MediaWiki:FileUploadWizard.css&action=raw&ctype=text/css', 
      'text/css'  );

   // see if user is logged in, autoconfirmed, experienced etc.
   this.getUserStatus();

   fuwSetVisible('warningLoggedOut', (this.userStatus == 'anon'));
   fuwSetVisible('warningNotConfirmed', (this.userStatus == 'notAutoconfirmed'));
   if ((this.userStatus == 'anon') || (this.userStatus == 'notAutoconfirmed')) {
      return;
   }
   fuwSetVisible('fuwStartScriptLink', false);

   // create the form element to wrap the main ScriptForm area
   // containing input elements of Step2 and Step3
   var frm = fuwGet('fuwScriptForm');
   if (! frm) {
      frm = document.createElement('form');
      frm.id = "fuwScriptForm";
      var area = fuwGet('placeholderScriptForm');
      var parent = area.parentNode;
      parent.insertBefore(frm, area);
      parent.removeChild(area);
      frm.appendChild(area);
   }
   this.ScriptForm = frm;

   // create the TargetForm element that contains the filename
   // input box, together with hidden input controls.
   // This is the form that is actually submitted to the api.php.
   frm = fuwGet('TargetForm');
   if (! frm) {
      frm = document.createElement('form');
      frm.id = "TargetForm";
      frm.method = "post";
      frm.enctype = "multipart/form-data";
      // "enctype" doesn't work properly on IE; need "encoding" instead:
      frm.encoding = "multipart/form-data"; 
      // we'll submit via api.php, not index.php, mainly because that
      // allows us to use a proper edit summary different from the page content
      frm.action = mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/api.php';

      // However, since api.php sends back a response page that humans won't want to read,
      // we'll have to channel that response away and discard it. We'll use a hidden iframe
      // for that purpose.
      // Unfortunately, it doesn't seem possible to submit file upload content through an 
      // Xmlhtml object via Ajax.
 
      frm.target = "TargetIFrame";
      //testing:
      //frm.target = "_blank";
      var area = fuwGet('placeholderTargetForm');
      var parent = area.parentNode;
      parent.insertBefore(frm, area);
      parent.removeChild(area);
      frm.appendChild(area);
   }
   this.TargetForm = frm;

   // For the testing version, create a third form that will display
   // the contents to be submitted, at the bottom of the page
   if (fuwTesting) {
      frm = fuwGet('fuwTestForm');
      if (! frm) {
         frm = document.createElement('form');
         frm.id = "fuwTestForm";
         var area = fuwGet('placeholderTestForm');
         var parent = area.parentNode;
         parent.insertBefore(frm, area);
         parent.removeChild(area);
         frm.appendChild(area);
      }
      this.TestForm = frm;
   }

   // objects to hold cached results during validation and processing
   this.opts = { };
   this.warn = { };

   // create the input filename box
   var filebox  = document.createElement('input');
   filebox.id   = 'file';
   filebox.name = 'file';
   filebox.type = 'file';
   filebox.size = fuwDefaultTextboxLength;
   filebox.onchange = fuwValidateFile;
   filebox.accept = 'image/png,image/jpeg,image/gif,image/svg+xml,image/tiff,image/x-xcf,application/pdf,image/vnd.djvu,audio/ogg,video/ogg,audio/rtp-midi';
   fuwAppendInput('file', filebox);

   // create hidden controls for sending the remaining API parameters:
   fuwMakeHiddenfield('action', 'upload', 'apiAction');
   fuwMakeHiddenfield('format', 'xml', 'apiFormat');
   fuwMakeHiddenfield('filename', '', 'apiFilename');
   fuwMakeHiddenfield('text', '', 'apiText');
   fuwMakeHiddenfield('comment', '', 'apiComment');
   fuwMakeHiddenfield('token', mw.user.tokens.get('editToken'), 'apiToken');
   fuwMakeHiddenfield('ignorewarnings', 1, 'apiIgnorewarnings');
   fuwMakeHiddenfield('watch', 1, 'apiWatch');

   if (fuwTesting) {
      fuwMakeHiddenfield('title', mw.config.get('wgPageName') + "/sandbox", 'SandboxTitle');
      fuwMakeHiddenfield('token', mw.user.tokens.get('editToken'), 'SandboxToken');
      fuwMakeHiddenfield('recreate', 1, 'SandboxRecreate');
   }

   // create a hidden IFrame to send the api.php response to
   var ifr = document.createElement('iframe');
   ifr.id   = "TargetIFrame";
   ifr.name = "TargetIFrame";
   //ifr.setAttribute('style', 'float:right;width:150px;height:150px;');
   ifr.style.display = "none";
   ifr.src = "";

   fuwAppendInput('TargetIFrame', ifr);

   if (fuwTesting) {

      // create the sandbox submit button
      btn = document.createElement('input');
      btn.id = 'SandboxButton';
      btn.value = 'Пијесак';
      btn.name  = 'Sandbox';
      btn.disabled = true;
      btn.type = 'button';
      btn.style.width = '12em';
      btn.onclick = fuwSubmitSandbox;
      fuwAppendInput('SandboxButton', btn);

   }

   // create the real submit button
   btn = document.createElement('input');
   btn.id = "SubmitButton";
   btn.value = "Отпреми";
   btn.name = "Upload";
   btn.disabled = true;
   btn.type = "button";
   btn.onclick = fuwSubmitUpload;
   btn.style.width = '12em';
   fuwAppendInput('SubmitButton', btn);

   // create the Commons submit button
   btn = document.createElement('input');
   btn.id = "CommonsButton";
   btn.value = "Отпреми на Оставу";
   btn.name  = "Upload_on_Commons";
   btn.disabled = true;
   btn.type = "button";
   btn.onclick = fuwSubmitCommons;
   btn.style.width = '12em';
   fuwAppendInput('CommonsButton', btn);

   // create reset buttons
   for (i = 1; i<=2; i++) {
      btn = document.createElement('input');
      btn.id = 'ResetButton' + i;
      btn.value = "Ресетуј образац";
      btn.name  = "Reset form";
      btn.type  = "button";
      btn.onclick = fuwReset;
      btn.style.width = '12em';
      fuwAppendInput('ResetButton' + i, btn);
   }

   // names of radio button fields
   var optionRadioButtons = {
      // top-level copyright status choice
      'FreeOrNonFree' : ['OptionFree','OptionNonFree','OptionNoGood'],
      // main subsections under OptionFree
      'FreeOptions'   : ['OptionOwnWork', 'OptionThirdParty', 'OptionFreeWebsite',
                         'OptionPDOld', 'OptionPDOther'],
      // main subsections under OptionNonFree
      'NonFreeOptions': ['OptionNFSubject','OptionNF3D','OptionNFExcerpt',
                         'OptionNFCover','OptionNFLogo','OptionNFPortrait',
                         'OptionNFMisc'],
      // response options inside warningFileExists
      'FileExistsOptions': 
                        ['NoOverwrite','OverwriteSame','OverwriteDifferent'],
      // choice of evidence in OptionThirdParty subsection
      'ThirdPartyEvidenceOptions' : 
                        ['ThirdPartyEvidenceOptionLink',
                         'ThirdPartyEvidenceOptionOTRS',
                         'ThirdPartyEvidenceOptionOTRSForthcoming',
                         'ThirdPartyEvidenceOptionNone'],
      // choice of PD status in OptionPDOld subsection
      'PDOldOptions'  : ['PDUS1923','PDURAA','PDFormality','PDOldOther'],
      // choice of PD status in OptionPDOther subsection
      'PDOtherOptions': ['PDOtherUSGov','PDOtherGov','PDOtherOfficial','PDOtherSimple',
                         'PDOtherOther'],
      // whether target article is wholly or only partly dedicated to discussing non-free work:
      'NFSubjectCheck': ['NFSubjectCheckDedicated','NFSubjectCheckDiscussed'],
      'NF3DCheck'     : ['NF3DCheckDedicated','NF3DCheckDiscussed'],
      // choice about copyright status of photograph in OptionNF3D
      'NF3DOptions'   : ['NF3DOptionFree','NF3DOptionSame']
   };
   for (var group in optionRadioButtons) {
      var op = optionRadioButtons[group];
      for (i=0; i<op.length; i++) {
         fuwMakeRadiobutton(group, op[i]);
      }
   }
   this.ScriptForm.NoOverwrite.checked = true;
   
   // input fields that trigger special
   // onchange() event handlers for validation:
   fuwMakeTextfield('InputName', fuwValidateFilename);
   fuwMakeTextfield('NFArticle', fuwValidateNFArticle);

   // names of input fields that trigger normal
   // validation event handler
   var activeTextfields = [
      'Artist3D','Country3D',
      'Date','OwnWorkCreation','OwnWorkPublication',
      'Author','Source',
      'Permission','ThirdPartyOtherLicense',
      'ThirdPartyEvidenceLink','ThirdPartyOTRSTicket',
      'FreeWebsiteOtherLicense',
      'PDOldAuthorLifetime','Publication',
      'PDOldCountry','PDOldPermission',
      'PDOfficialPermission','PDOtherPermission',
      'NFSubjectPurpose', 'NF3DOrigDate', 'NF3DPurpose',
      'NF3DCreator',
      'NFPortraitDeceased',
      'EditSummary'
   ];
   for (i=0; i<activeTextfields.length; i++) {
      fuwMakeTextfield(activeTextfields[i]);
   }

   // names of multiline textareas
   var activeTextareas = [
      'InputDesc','NF3DPermission',
      'NFCommercial','NFPurpose','NFReplaceableText',
      'NFReplaceable','NFCommercial','NFMinimality','AnyOther'
   ];
   for (i=0; i<activeTextareas.length; i++) {
      fuwMakeTextarea(activeTextareas[i]);
   };

   var checkboxes = [
      'NFCoverCheckDedicated','NFLogoCheckDedicated','NFPortraitCheckDedicated'
   ];
   for (i=0; i<checkboxes.length; i++) {
      fuwMakeCheckbox(checkboxes[i]);
   };

   var licenseLists = {
      'OwnWorkLicense' : 
        // array structure as expected for input to fuwMakeSelection() function.
        // any entry that is a two-element array will be turned into an option
        // (first element is the value, second element is the display string).
        // Entries that are one-element arrays will be the label of an option group.
        // Zero-element arrays mark the end of an option group.
        [
        ['Допуштате свима употребу док Вас наводе као аутора и дијеле под сличним условима'],
        ['self|GFDL|cc-by-sa-4.0|migration=redundant', 
         'Кријејтив комонс Ауторство—Дијелити под истим условима 4.0 и ГНУ-ова лиценца за слободну документацију (препоручено)',
         true],
        ['self|cc-by-sa-4.0',
         'Кријејтив комонс Ауторство—Дијелити под истим условима 4.0'],
        [],
        ['Допуштате свима употребу док Вас наводе као аутора'],
        ['self|cc-by-4.0',
         'Кријејтив комонс Ауторство 4.0'],
        [],
        ['Без задржавања права'],
        ['cc-zero',
         'Предавање у универзално јавно власништво (cc-0)'],
        []
        ],   
      'ThirdPartyLicense' :
        [
        ['', 'изаберите једну од опција...'],
        ['Слободне лиценце:'],
        ['cc-by-sa-4.0', 'Кријејтив комонс Ауторство—Дијелити под истим условима (cc-by-sa-4.0)'],
        ['cc-by-4.0', 'Кријејтив комонс Ауторство (cc-by-4.0)'],
        ['GFDL', 'ГНУ-ова лиценца за слободну документацију (GFDL)'],
        [],
        ['Без задржавања права:'],
        ['PD-author', 'Јавно власништво'],
        [],
        ['Остало (погледајте испод)'],
        []
        ],   
      'FreeWebsiteLicense' :
        [
        ['', 'изаберите једну од опција...'],
        ['Слободне лиценце:'],
        ['cc-by-sa-4.0', 'Кријејтив комонс Ауторство—Дијелити под истим условима (cc-by-sa-4.0)'],
        ['cc-by-4.0', 'Кријејтив комонс Ауторство (cc-by-4.0)'],
        ['GFDL', 'ГНУ-ова лиценца за слободну документацију (GFDL)'],
        [],
        ['Без задржавања права:'],
        ['PD-author', 'Јавно власништво'],
        [],
        ['Остало (погледајте испод)'],
        []
        ],   
      'USGovLicense' :
       [
       ['PD-USGov', 'Федерална влада САД'],
       ['PD-USGov-NASA','НАСА'],
       ['PD-USGov-Military-Navy','Ратна морнарица САД'],
       ['PD-USGov-NOAA','Национална океанска и атмосферска администрација'],
       ['PD-USGov-Military-Air_Force','Ратно ваздухопловство САД'],
       ['PD-USGov-Military-Army','Армија САД'],
       ['PD-USGov-CIA-WF','CIA World Factbook'],
       ['PD-USGov-USGS','Геолошки топографски институт САД']
       ],
      'OtherGovLicense' :
       [
       ['ЈВ-акти Србије', 'Државни акти Србије'],
       ['ЈВ-акти Црне Горе', 'Државни акти Црне Горе']
       ],
      'IneligibleLicense' :
       [
       ['', 'изаберите једну од опција...'],
       ['PD-shape','Дјело се састоји искључиво од једноставних геометријских облика'],
       ['PD-text','Дјело се састоји само од неколико појединачних ријечи или слова'],
       ['PD-textlogo','Лого или слично дјело које се састоји искључиво од слова и једноставних геометријских облика'],
       ['PD-chem','Хемијска структурална формула'],
       ['PD-ineligible','Друга врста дјела које не садржи оригинално ауторство']
       ],
      'NFSubjectLicense' :
       [
       ['', 'изаберите једну од опција...'],
       ['Non-free 2D art', '2-димензионално умјетничко дјело (слика, цртеж итд.)'], 
       ['Non-free historic image', 'Јединствена историјска фотографија'], 
       ['Non-free fair use in', 'нешто друго (опишите у пољу за кратак опис 2. корака изнад)']
       ],
      'NF3DLicense' :
       [
       ['', 'изаберите једну од опција...'],
       ['Non-free architectural work', 'Архитектонско дјело'], 
       ['Non-free 3D art', 'Друго 3-димензионално креативно дјело (скулптура итд.)']
       ],
      'NFCoverLicense' :
         [
         ['', 'изаберите једну од опција...'],
         ['Non-free book cover', 'Корица књиге'], 
         ['Non-free album cover', 'Омот звучног записа (албум, сингл, пјесма, ЦД)'], 
         ['Non-free game cover', 'Омот видео/рачунарске игре'], 
         ['Non-free magazine cover', 'Насловна страна часописа'], 
         ['Non-free video cover', 'Омот видео-траке'], 
         ['Non-free software cover', 'Омот софтверског производа'], 
         ['Non-free product cover', 'Омот неког комерцијалног производа'], 
         ['Non-free title-card', 'Уводна шпица ТВ програма'], 
         ['Non-free movie poster', 'Филмски постер'], 
         ['Non-free poster', 'Званични постер догађаја'], 
         ['Non-free fair use in', 'нешто друго (опишите у пољу за кратак опис 2. корака изнад)']
         ],
      'NFExcerptLicense' :
         [
         ['', 'изаберите једну од опција...'],
         ['Non-free television screenshot', 'Снимак екрана ТВ програма'], 
         ['Non-free film screenshot', 'Снимак екрана филма'], 
         ['Non-free game screenshot', 'Снимак екрана игре'], 
         ['Non-free video screenshot', 'Снимак екрана видеа'], 
         ['Non-free music video screenshot', 'Снимак екрана музичког видеа'], 
         ['Non-free software screenshot', 'Снимак екрана софтвера'], 
         ['Non-free web screenshot', 'Снимак екрана веб-сајта'], 
         ['Non-free speech', 'Аудио-исјечак говора'], 
         ['Non-free audio sample', 'Звучни одломак аудио-снимка'], 
         ['Non-free video sample', 'Исјечак видеа'], 
         ['Non-free sheet music', 'Ноте које представљају музичко дјело'], 
         ['Non-free comic', 'Дио стрипа, графички роман, манга итд.'], 
         ['Non-free computer icon', 'Рачунарска икона'], 
         ['Non-free newspaper image', 'Страница новина'], 
         ['Non-free fair use in', 'нешто друго (опишите у пољу за кратак опис 2. корака изнад)']
         ],      
      'NFLogoLicense' :
         [
         ['Non-free logo', 'Лого компаније, организације итд.'], 
         ['Non-free seal', 'Званични печат, грб итд.'], 
         ['Non-free symbol', 'Други званични симбол']
         ],
      'NFMiscLicense' :
         [
         ['Non-free fair use in', 'нешто друго (опишите у пољу за кратак опис 2. корака изнад)'], 
         ['Non-free historic image', 'Историјска фотографија'], 
         ['Non-free 2D art', '2-димензионално умјетничко дјело (слика, цртеж итд.)'], 
         ['Non-free currency', 'Депикција валуте (новчанице, кованице итд.)'], 
         ['Non-free architectural work', 'Архитектонско дјело'], 
         ['Non-free 3D art', 'Друго 3-димензионално креативно дјело (скулптура итд.)'], 
         ['Non-free book cover', 'Корица књиге'], 
         ['Non-free album cover', 'Омот звучног записа (албум, сингл, пјесма, ЦД)'], 
         ['Non-free game cover', 'Омот видео/рачунарске игре'], 
         ['Non-free magazine cover', 'Насловна страна часописа'], 
         ['Non-free video cover', 'Омот видео-траке'], 
         ['Non-free software cover', 'Омот софтверског производа'], 
         ['Non-free product cover', 'Омот неког комерцијалног производа'], 
         ['Non-free title-card', 'Уводна шпица ТВ програма'], 
         ['Non-free movie poster', 'Филмски постер'], 
         ['Non-free poster', 'Званични постер догађаја'], 
         ['Non-free television screenshot', 'Снимак екрана ТВ програма'], 
         ['Non-free film screenshot', 'Снимак екрана филма'], 
         ['Non-free game screenshot', 'Снимак екрана игре'], 
         ['Non-free video screenshot', 'Снимак екрана видеа'], 
         ['Non-free music video screenshot', 'Снимак екрана музичког видеа'], 
         ['Non-free software screenshot', 'Снимак екрана софтвера'], 
         ['Non-free web screenshot', 'Снимак екрана веб-сајта'], 
         ['Non-free speech', 'Аудио-исјечак говора'], 
         ['Non-free audio sample', 'Звучни одломак аудио-снимка'], 
         ['Non-free video sample', 'Исјечак видеа'], 
         ['Non-free sheet music', 'Ноте које представљају музичко дјело'], 
         ['Non-free comic', 'Дио стрипа, графички роман, манга итд.'], 
         ['Non-free computer icon', 'Рачунарска икона'], 
         ['Non-free newspaper image', 'Страница новина'], 
         ['Non-free logo', 'Лого компаније, организације итд.'], 
         ['Non-free seal', 'Званични печат, грб итд.'], 
         ['Non-free symbol', 'Други званични симбол'], 
         ['Non-free sports uniform', 'Спортска униформа'], 
         ['Non-free stamp', 'Поштанска марка'] 
         ],
      'NFExtraLicense' :
         [
         ['', 'празно'],
         ['Ауторска права Круне и други владини извори'],
         ['Non-free Crown copyright', 'Ауторско право Круне УК'],
         ['Non-free New Zealand Crown Copyright', 'Ауторско право Круне НЗ'],
         ['Non-free Canadian Crown Copyright', 'Ауторско право Круне Канаде'],
         ['Non-free AUSPIC', 'AUSPIC (Сликовна база података Аустралијског парламента)'],
         ['Non-free Philippines government', 'Филипинска влада'],
         ['Non-free Finnish Defence Forces', 'Финске одбрамбене снаге'],
         [],
         ['Остали појединачни извори'],
         ['Non-free Denver Public Library image', 'Денверска јавна библиотека'],
         ['Non-free ESA media', 'ЕСА (Европска свемирска агенција)'],
         [],
         ['Могуће јавно власништво у другим земљама'],
         ['Non-free Old-50', 'Аутор умро прије више од 50 година'],
         ['Non-free Old-70', 'Аутор умро прије више од 70 година'],
         ['ЈВ-Босна и Херцеговина', 'Босна и Херцеговина'],
         ['ЈВ-Босна и Херцеговина-изузетак', 'Босна и Херцеговина (изузетак)'],
         ['ЈВ-Израел', 'Израел'],
         ['ЈВ-Италија', 'Италија'],
         ['ЈВ-Пољска', 'Пољска'],
         ['ЈВ-Русија', 'Русија'],
         ['ЈВ-САД', 'САД'],
         ['ЈВ-САД-1923-иностранство', 'САД (иностранство 1923)'],
         ['ЈВ-САД пре 1978.', 'САД (пре 1978)'],
         ['ЈВ-Србија', 'Србија'],
         ['ЈВ-Хрватска', 'Хрватска'],
         ['ЈВ-Хрватска-изузетак', 'Хрватска (изузетак)'],
         ['ЈВ-Црна Гора', 'Црна Гора'],
         [],
         ['Неке дозволе дате, али није потпуно слободно'],
         ['Non-free promotional', 'Из промотивног прес-кита'],
         ['Non-free with NC', 'Дозвола дата, али само за образовне и/или некомерцијалне сврхе'],
         ['Non-free with ND', 'Дозвола дата, али прерађивање дјела није дозвољено'],
         ['Non-free with permission', 'Дозвола дата, али само за Википедију'],
         []
         ]
   };
   for (var group in licenseLists) {
      fuwMakeSelection(group, licenseLists[group]);
   }


   this.knownCommonsLicenses = {
      'self|GFDL|cc-by-sa-all|migration=redundant' : 1,
      'self|Cc-zero' : 1,
      'PD-self' : 1,
      'self|GFDL|cc-by-sa-4.0|migration=redundant' : 1,
      'self|GFDL|cc-by-4.0|migration=redundant' : 1,
      'self|GFDL|cc-by-sa-3.0|migration=redundant' : 1,
      'self|GFDL|cc-by-3.0|migration=redundant' : 1,
      'self|cc-by-sa-4.0' : 1,
      'self|cc-by-sa-3.0' : 1,
      'cc-by-sa-4.0' : 1,
      'cc-by-sa-3.0' : 1,
      'cc-by-sa-2.5' : 1,
      'cc-by-4.0' : 1,
      'cc-by-3.0' : 1,
      'cc-by-2.5' : 1,
      'FAL' : 1,
      'PD-old-100' : 1,
      'PD-old' : 1,
      'PD-Art' : 1,
      'PD-US' : 1,
      'PD-USGov' : 1,
      'PD-USGov-NASA' : 1,
      'PD-USGov-Military-Navy' : 1,
      'PD-ineligible' : 1,
      'attribution' : 1,
      'copyrighted free use' : 1
   };


   // textfields that don't react directly
   // to user input and are used only for assembling stuff:
   if (fuwTesting) {
      fuwMakeTextfield('SandboxSummary', function(){void(0);});
      fuwMakeTextarea('SandboxText', function(){void(0);});
      fuwGet('SandboxSummary').disabled="онемогућено";
      fuwGet('SandboxText').disabled="онемогућено";
      fuwGet('SandboxText').rows = 12;
   }

   // set links to "_blank" target, so we don't accidentally leave the page,
   // because on some browsers that would destroy all the input the user has already entered
   $('.fuwOutLink a').each(function() {
      this.target = '_blank';
   });

   // make main area visible
   fuwSetVisible('UploadScriptArea', true);

}
// ====================================== 
// end of fuwGlobal constructor function
// ======================================



function fuwRadioClick(e) {
   var ev = e || event;
   var src = ev.target || ev.srcElement;
   //alert('onclick event from ' + src + ' (' + src.value + ')');
   fuwUpdateOptions();
   return true;
}

/* 
* =============================================================
* function fuwUpdateOptions
* =============================================================
* This is the onchange event handler for most of the input
* elements in the main form. It changes visibility and disabled
* status for the various sections of the input form in response
* to which options are chosen.
*/
function fuwUpdateOptions() {

   var fuw = window.fuw;
   var warn = fuw.warn;
   var opts = fuw.opts = { };
   opts.InputFilename = $('#TargetForm input#file').val();

   var widgets = fuw.ScriptForm.elements;
   for (i = 0; i < widgets.length; i++) {
      var w = widgets[i];
      if (w.type == "radio") {
         var nm = w.name;
         var id = w.id;
         var vl = w.checked && !w.disabled && fuwIsVisible(w);
         opts[id] = vl;
         if (vl) opts[nm] = id;
      }
      else {
         var id = w.id;
         var active = !w.disabled && fuwIsVisible(w);
         if (active) {
            var value = ((type == 'checkbox') ? w.checked : w.value);
            opts[id] = value;         
         }
      }
   };
   opts.MainOption = opts.FreeOptions || opts.NonFreeOptions;
   
   // some parts of the input form are re-used across sections
   // and must be moved into the currently active input section:

   // minimality section is shared between all NF sections
   fuwMove('NFMinimalitySection', 'detailsNFSubject', (opts.OptionNFSubject)) ||
   fuwMove('NFMinimalitySection', 'detailsNF3D', (opts.OptionNF3D)) ||
   fuwMove('NFMinimalitySection', 'detailsNFExcerpt', (opts.OptionNFExcerpt)) ||
   fuwMove('NFMinimalitySection', 'detailsNFCover', (opts.OptionNFCover)) ||
   fuwMove('NFMinimalitySection', 'detailsNFLogo', (opts.OptionNFLogo)) ||
   fuwMove('NFMinimalitySection', 'detailsNFPortrait', (opts.OptionNFPortrait)) ||
   fuwMove('NFMinimalitySection', 'detailsNFMisc', true);

   // AnyOtherInfo section is shared between all
   fuwMove('AnyOtherInfo', 'detailsOwnWork', opts.OptionOwnWork) ||
   fuwMove('AnyOtherInfo', 'detailsThirdParty', opts.OptionThirdParty) ||
   fuwMove('AnyOtherInfo', 'detailsFreeWebsite', opts.OptionFreeWebsite) ||
   fuwMove('AnyOtherInfo', 'detailsPDOld', opts.OptionPDOld) ||
   fuwMove('AnyOtherInfo', 'detailsPDOther', opts.OptionPDOther) ||
   fuwMove('AnyOtherInfo', 'detailsNFSubject', opts.OptionNFSubject) ||
   fuwMove('AnyOtherInfo', 'detailsNF3D', opts.OptionNF3D) ||
   fuwMove('AnyOtherInfo', 'detailsNFExcerpt', opts.OptionNFExcerpt) ||
   fuwMove('AnyOtherInfo', 'detailsNFCover', opts.OptionNFCover) ||
   fuwMove('AnyOtherInfo', 'detailsNFLogo', opts.OptionNFLogo) ||
   fuwMove('AnyOtherInfo', 'detailsNFPortrait', opts.OptionNFPortrait) ||
   fuwMove('AnyOtherInfo', 'detailsNFMisc', opts.OptionNFMisc);

   // author input field is shared between all sections except "Own Work".
   // (will serve for the immediate/photographic author, in those cases where there
   // are two author fields)
   fuwMove('Author', 'placeholderFreeWebsiteAuthor', (opts.OptionFreeWebsite)) ||
   fuwMove('Author', 'placeholderPDOldAuthor', (opts.OptionPDOld)) ||
   fuwMove('Author', 'placeholderPDOtherAuthor', (opts.OptionPDOther)) ||
   fuwMove('Author', 'placeholderNFSubjectAuthor', (opts.OptionNFSubject)) ||
   fuwMove('Author', 'placeholderNF3DAuthor', (opts.OptionNF3D)) ||
   fuwMove('Author', 'placeholderNFExcerptAuthor', (opts.OptionNFExcerpt)) ||
   fuwMove('Author', 'placeholderNFCoverAuthor', (opts.OptionNFCover)) ||
   fuwMove('Author', 'placeholderNFPortraitAuthor', (opts.OptionNFPortrait)) ||
   fuwMove('Author', 'placeholderNFMiscAuthor', (opts.OptionNFMisc)) ||
   fuwMove('Author', 'placeholderAuthor', true);

   // source input field is shared between all sections except "Own Work".
   // (will serve for immediate/web source, in those cases where there are two
   // source fields involved)
   fuwMove('Source', 'placeholderFreeWebsiteSource', (opts.OptionFreeWebsite)) ||
   fuwMove('Source', 'placeholderPDOldSource', (opts.OptionPDOld)) ||
   fuwMove('Source', 'placeholderPDOtherSource', (opts.OptionPDOther)) ||
   fuwMove('Source', 'placeholderNFSubjectSource', (opts.OptionNFSubject)) ||
   fuwMove('Source', 'placeholderNF3DSource', (opts.OptionNF3D)) ||
   fuwMove('Source', 'placeholderNFExcerptSource', (opts.OptionNFExcerpt)) ||
   fuwMove('Source', 'placeholderNFCoverSource', (opts.OptionNFCover)) ||
   fuwMove('Source', 'placeholderNFLogoSource', (opts.OptionNFLogo)) ||
   fuwMove('Source', 'placeholderNFPortraitSource', (opts.OptionNFPortrait)) ||
   fuwMove('Source', 'placeholderNFMiscSource', (opts.OptionNFMisc)) ||
   fuwMove('Source', 'placeholderSource', true);

   // date input field is shared between all sections except "Logo", which doesn't need it.
   // will serve for derived/photographic date in the case of 3D items
   fuwMove('Date', 'placeholderFreeWebsiteDate', (opts.OptionFreeWebsite)) ||
   fuwMove('Date', 'placeholderThirdPartyDate', (opts.OptionThirdParty)) ||
   fuwMove('Date', 'placeholderPDOldDate', (opts.OptionPDOld)) ||
   fuwMove('Date', 'placeholderPDOtherDate', (opts.OptionPDOther)) ||
   fuwMove('Date', 'placeholderNFSubjectDate', (opts.OptionNFSubject)) ||
   fuwMove('Date', 'placeholderNF3DDate', (opts.OptionNF3D)) ||
   fuwMove('Date', 'placeholderNFExcerptDate', (opts.OptionNFExcerpt)) ||
   fuwMove('Date', 'placeholderNFCoverDate', (opts.OptionNFCover)) ||
   fuwMove('Date', 'placeholderNFPortraitDate', (opts.OptionNFPortrait)) ||
   fuwMove('Date', 'placeholderNFMiscDate', (opts.OptionNFMisc)) ||
   fuwMove('Date', 'placeholderDate', true);
   
   // permission field is shared between ThirdParty and FreeWebsite sections
   fuwMove('Permission', 'placeholderFreeWebsitePermission', (opts.OptionFreeWebsite)) ||
   fuwMove('Permission', 'placeholderPermission', true);

   // publication field is shared between PDOld, NFPortrait and NFMisc
   fuwMove('Publication', 'placeholderNFPortraitPublication', (opts.OptionNFPortrait)) ||
   fuwMove('Publication', 'placeholderNFMiscPublication', (opts.OptionNFMisc)) ||
   fuwMove('Publication', 'placeholderPublication', true);

   // Purpose, Commercial, Replaceable and ReplaceableText FUR fields are shared
   // between some but not all of the non-free sections
   fuwMove('NFPurpose', 'placeholderNFExcerptPurpose', (opts.OptionNFExcerpt)) ||
   fuwMove('NFPurpose', 'placeholderNFPurpose');
   fuwMove('NFCommercial', 'placeholderNFPortraitCommercial', (opts.OptionNFPortrait)) ||
   fuwMove('NFCommercial', 'placeholderNFCommercial');
   fuwMove('NFReplaceable', 'placeholderNFPortraitReplaceable', (opts.OptionNFPortrait)) ||
   fuwMove('NFReplaceable', 'placeholderNFReplaceable');
   fuwMove('NFReplaceableText', 'placeholderNFExcerptReplaceable', (opts.OptionNFExcerpt)) ||
   fuwMove('NFReplaceableText', 'placeholderNFReplaceableText', true);

   // submit button goes to Step1 if user has chosen a plain overwrite of an existing file,
   // and to the active section of Step3 if otherwise
   fuwMove('fuwSubmit', 'UploadScriptStep1', (warn.ImageExists && opts.OverwriteSame)) ||
   fuwMove('fuwSubmit', 'detailsOwnWork', opts.OptionOwnWork) ||
   fuwMove('fuwSubmit', 'detailsThirdParty', opts.OptionThirdParty) ||
   fuwMove('fuwSubmit', 'detailsFreeWebsite', opts.OptionFreeWebsite) ||
   fuwMove('fuwSubmit', 'detailsPDOld', opts.OptionPDOld) ||
   fuwMove('fuwSubmit', 'detailsPDOther', opts.OptionPDOther) ||
   fuwMove('fuwSubmit', 'detailsNFSubject', opts.OptionNFSubject) ||
   fuwMove('fuwSubmit', 'detailsNF3D', opts.OptionNF3D) ||
   fuwMove('fuwSubmit', 'detailsNFExcerpt', opts.OptionNFExcerpt) ||
   fuwMove('fuwSubmit', 'detailsNFCover', opts.OptionNFCover) ||
   fuwMove('fuwSubmit', 'detailsNFLogo', opts.OptionNFLogo) ||
   fuwMove('fuwSubmit', 'detailsNFPortrait', opts.OptionNFPortrait) ||
   fuwMove('fuwSubmit', 'fuwSubmitHost', true);


   // Show and hide warnings:

   // filename-related warnings:
   fuwSetVisible('warningIllegalChars', warn.IllegalChars);
   fuwSetVisible('warningBadFilename',  warn.BadFilename);
   fuwSetVisible('warningImageOnCommons', warn.ImageOnCommons);
   fuwSetVisible('warningImageExists', warn.ImageExists);
   fuwMove('warningImageThumb', 'warningImageOnCommons', warn.ImageOnCommons, true) ||
   fuwMove('warningImageThumb', 'warningImageExists', true, true);


   // notices related to the top-level options:
   fuwSetVisible('warningWhyNotCommons', opts.OptionFree);
   fuwSetVisible('warningNF', opts.OptionNonFree);
   fuwSetVisible('warningNoGood', opts.OptionNoGood);

   // warnings related to non-free "used in" article
   fuwSetVisible('warningNFArticleNotFound', warn.NFArticleNotFound);
   fuwSetVisible('warningNFArticleNotMainspace', warn.NFArticleNotMainspace);
   fuwSetVisible('warningUserspaceDraft', warn.UserspaceDraft);
   fuwSetVisible('warningNFArticleDab', warn.NFArticleDab);
   fuwSetVisible('NFArticleOK', warn.NFArticleOK);

   // warnings depending on user status:
   if (fuw.userStatus.match(/problem|newbie|notAutoconfirmed/)) {
      fuwSetVisible('warningFreeWebsite', opts.OptionFreeWebsite);
      fuwSetVisible('warningOwnWork', opts.OptionOwnWork);
      fuwSetVisible('warningPDOther', opts.OptionPDOther);
      fuwSetVisible('warningNFSubject', opts.OptionNFSubject);
   }

   // hide main sections in case of intended plain overwrite:   
   fuwSetVisible('UploadScriptStep2', !(warn.ImageExists && opts.OverwriteSame));
   fuwSetVisible('UploadScriptStep3', !(warn.ImageExists && opts.OverwriteSame));

   // show/hide top-level options
   fuwSetVisible('detailsFreeStatus', opts.OptionFree);
   fuwSetVisible('sendToCommons', opts.OptionFree);

   // show/hide details sections
   fuwSetVisible('detailsNFArticle', opts.OptionNonFree);
   fuwSetVisible('detailsNFWorkType', opts.OptionNonFree);
   fuwSetVisible('detailsOwnWork', opts.OptionOwnWork);
   fuwSetVisible('detailsThirdParty', opts.OptionThirdParty);
   fuwSetVisible('detailsFreeWebsite', opts.OptionFreeWebsite);
   fuwSetVisible('detailsPDOld', opts.OptionPDOld);
   fuwSetVisible('detailsPDOther', opts.OptionPDOther);
   fuwSetVisible('detailsNFSubject', opts.OptionNFSubject);
   fuwSetVisible('detailsNF3D', opts.OptionNF3D);
   fuwSetVisible('detailsNFExcerpt', opts.OptionNFExcerpt);
   fuwSetVisible('detailsNFCover', opts.OptionNFCover);
   fuwSetVisible('detailsNFLogo', opts.OptionNFLogo);
   fuwSetVisible('detailsNFPortrait', opts.OptionNFPortrait);
   fuwSetVisible('detailsNFMisc', opts.OptionNFMisc);

   fuwSetVisible('EditSummaryDiv', opts.OverwriteSame || opts.OverwriteDifferent);

   // set enabled/disabled
   // It might be useful to adapt this to be more liberal about
   // the order of input, at least for experienced users.

   //fuwSetEnabled('Artist3D', opts.PD3D);
   //fuwSetEnabled('Country3D', opts.FOP3D);
   fuwSetEnabled('ThirdPartyEvidenceLink', opts.ThirdPartyEvidenceOptionLink);
   fuwSetEnabled('ThirdPartyOTRSTicket', opts.ThirdPartyEvidenceOptionOTRS);
   fuwSetEnabled('NFSubjectPurpose', opts.NFSubjectCheckDiscussed);
   fuwSetEnabled('NF3DPurpose', opts.NF3DCheckDiscussed);
   fuwSetEnabled('NF3DPermission', opts.NF3DOptionFree);
   fuwSetEnabled('USGovLicense', opts.PDOtherUSGov);
   fuwSetEnabled('OtherGovLicense', opts.PDOtherGov);
   fuwSetEnabled('PDOfficialPermission', opts.PDOtherOfficial);
   fuwSetEnabled('IneligibleLicense', opts.PDOtherSimple);
   fuwSetEnabled('PDOtherPermission', opts.PDOtherOther);
   fuwSetEnabled('AnyOther', true);

   // need to re-collect the remaining (non-radiobutton) input into the opts object again,
   // preparing for validation:
   for (i = 0; i < widgets.length; i++) {
      var w = widgets[i];
      var type = w.type;

      if (type != "radio") {
         var id = w.id;
         var active = !w.disabled && fuwIsVisible(w);
         if (active) {
            var value = ((type == 'checkbox') ? w.checked : w.value);
            opts[id] = value;         
         }
      }
   };

   // final step of validation: check if input is sufficient for
   // setting the submit buttons active
   var valid = fuw.validateInput();
   var validForCommons = valid && opts.OptionFree && !(opts.OverwriteSame || opts.OverwriteDifferent)
         && !opts.ThirdPartyEvidenceOptionNone;
   fuwSetVisible('sendToCommons', opts.OptionFree);
   fuwSetEnabled('CommonsButton', validForCommons);
   fuwGet('fuwSubmitText').innerHTML = opts.OptionFree ? 
         ("<b>Не</b>, желим да ову датотеку отпремим овдје, само на ову Википедију.<br/>" + 
          "<small>Овако ће се датотека моћи користити само на Википедији на српском језику. Међутим, неко " +
          "други би могао да је копира на Оставу и потом је користи негдје друго. Ако Ви " +
          "не желите да се ова датотека копира на Оставу а потом обрише овдје, у поље за другу лиценцу додајте " +
          "„{{keep local}}”.</small>") :
         "Отпреми ову датотеку.";
   fuwGet('SubmitButton').value = validForCommons ? "Отпреми локално" : "Отпреми";   
   fuwSetEnabled('EditSummary', true);
   fuwSetEnabled('SubmitButton', valid && (fuw.userStatus != 'notAutoconfirmed'));
   if (fuwTesting) {
      fuwSetEnabled('SandboxButton', valid);
   }

   // if we're in testing mode, update the Sandbox display fields
   // after each input change. In normal mode, collectInput() will
   // only be needed on submit.
   if (fuwTesting) {
      fuw.collectInput();
      fuw.formatOutput(false);
      fuwSetVisible('placeholderTestForm', true);
   }  
}

// ============================================================
// methods of the global fuw object
// ============================================================

// ============================================================
// report validation status of filename information
// ============================================================
// This is called from within fuw.validateInput(), i.e. every
// time anything in the whole form is changed. It only reports
// results that have previously been cached in the opts and warn
// objects. The actual checking is done in the event handler
// of the file input boxes.
fuwGlobal.prototype.hasValidFilename = function() {
   var opts = this.opts;
   var warn = this.warn;
   var valid =   
      opts.InputName &&
      opts.InputFilename &&
      !warn.BadFilename &&
      !warn.ImageOnCommons &&
      // if image exists on enwiki, accept only if user has confirmed overwrite:
      !(warn.ImageExists && !(opts.OverwriteSame || opts.OverwriteDifferent));
   //alert("HasValidFilename: " + valid);
   return valid;
};

// ============================================================
// validation status for common input elements for all free
// options
// ============================================================
fuwGlobal.prototype.hasValidCommonFreeInput = function() {
   var opts = this.opts;
   var warn = this.warn;
   var valid = opts.InputDesc;
   //alert("HasValidCommonFreeInput: " + valid);
   return valid;
};
// ============================================================
// validation status for common input elements for all non-free
// options
// ============================================================
fuwGlobal.prototype.hasValidCommonNFInput = function() {
   var opts = this.opts;
   var warn = this.warn;
   var valid =
      opts.OptionNonFree &&
      opts.InputDesc && 
      opts.NFArticle &&
      opts.Source &&
      opts.NFMinimality &&
      !warn.NFArticleNotFound &&
      !warn.NFArticleNotMainspace &&
      !warn.NFArticleDab;
   //alert("hasValidCommonNFInput: " + valid);
   return valid;
};
// ============================================================
// Main validation routine. Modify this to tweak which fields
// are to be considered obligatory for each case group
// ============================================================
fuwGlobal.prototype.validateInput = function() {
   var opts = this.opts;
   var warn = this.warn;
   var valid = (
      this.hasValidFilename()
      &&
      (! (opts.OverwriteDifferent && ! opts.EditSummary))
      &&
      (
       ( // overwriting is okay if there is an edit summary
        opts.OverwriteSame && opts.EditSummary
       )
       ||
       ( // free options
         this.hasValidCommonFreeInput() &&
         (
          (opts.OptionOwnWork &&
           opts.Date &&
           opts.OwnWorkLicense)
          ||
          (opts.OptionThirdParty &&
           opts.Author &&
           opts.Source &&
           opts.Permission &&
           (opts.ThirdPartyOtherLicense || opts.ThirdPartyLicense) &&
           ((opts.ThirdPartyEvidenceOptionLink && opts.ThirdPartyEvidenceLink) ||
            opts.ThirdPartyEvidenceOptionOTRS ||
            opts.ThirdPartyEvidenceOptionOTRSForthcoming ||
            opts.ThirdPartyEvidenceOptionNone))
          ||
          (opts.OptionFreeWebsite &&
           opts.Author &&
           opts.Source &&
           (opts.FreeWebsiteOtherLicense || opts.FreeWebsiteLicense) &&
           opts.Permission)
          ||
          (opts.OptionPDOld &&
           opts.Author &&
           opts.PDOldAuthorLifetime &&
           opts.Publication &&
           opts.Date &&
           opts.Source &&
           opts.PDOldOptions && 
           (! (opts.PDOldOther && ! opts.PDOldPermission)))
          ||
          (opts.OptionPDOther &&
           opts.Author &&
           opts.Source &&
           ((opts.PDOtherUSGov && opts.USGovLicense) ||
            (opts.PDOtherGov && opts.OtherGovLicense) ||
            (opts.PDOtherOfficial && opts.PDOfficialPermission) ||
            (opts.PDOtherSimple && opts.IneligibleLicense) ||
            (opts.PDOtherOther && opts.PDOtherPermission)))
        )
       ) // end of free options
       ||
       ( // non-free options
         this.hasValidCommonNFInput() &&
         (
          (opts.OptionNFSubject &&
           opts.NFSubjectLicense &&
           opts.Author &&
           (opts.NFSubjectCheckDedicated ||
           (opts.NFSubjectCheckDiscussed && opts.NFSubjectPurpose)))
          ||
          (opts.OptionNF3D &&
           opts.NF3DLicense &&
           opts.NF3DCreator &&
           opts.Author &&
           (opts.NF3DOptionSame ||
           (opts.NF3DOptionFree || opts.NF3DPermission)) && 
           (opts.NF3DCheckDedicated ||
            (opts.NF3DCheckDiscussed && opts.NF3DPurpose)))
          ||
          (opts.OptionNFExcerpt &&
           opts.NFExcerptLicense &&
           opts.Author &&
           opts.NFPurpose)
          ||
          (opts.OptionNFCover &&
           opts.NFCoverLicense &&
           opts.Author &&
           opts.NFCoverCheckDedicated 
          )
          ||
          (opts.OptionNFLogo &&
           opts.NFLogoLicense &&
           opts.NFLogoCheckDedicated
          )
          ||
          (opts.OptionNFPortrait &&
           opts.Publication &&
           opts.NFPortraitDeceased &&
           opts.Author &&
           opts.NFPortraitCheckDedicated &&
           opts.NFReplaceable &&
           opts.NFCommercial)
          ||
          (opts.OptionNFMisc &&
           opts.NFMiscLicense &&
           opts.Author &&
           opts.Publication &&
           opts.NFPurpose &&
           opts.NFReplaceableText &&
           opts.NFReplaceable &&
           opts.NFCommercial)
         )
       ) // end of non-free options
      )
   );
   return valid;
};

// =============================================================
// return which template name will be used as the main
// description template
// =============================================================
fuwGlobal.prototype.getDescriptionTemplateName = function() {
   // standard "Information" template for free files:
   if (this.opts.OptionFree) return "Information";
   // experimental new version of fair-use rationale template,
   // designed to fit the fields used in the wizard
   else if (this.opts.OptionNonFree) return "Non-free use rationale 2";
   return undefined;
};

// =============================================================
// get the license tag code from the appropriate input element
// =============================================================

fuwGlobal.prototype.getStandardLicense = function() {
   var opts = this.opts;
   
}

fuwGlobal.prototype.getLicense = function() {
   var opts = this.opts;
      // ThirdParty and FreeWebsite have alternative input fields
      // for manual entry of other licenses:
   var license = {};
   if (opts.PDOtherOther || opts.PDOldOther) {
      license.special = opts.PDOtherOther ? opts.PDOtherPermission : opts.PDOldPermission;
      if (! (license.special.match(/^\s*\{\{.+\}\}\s*$/))) {
         license.special = '{{PD-because|' + license.special + '}}';
      }
   }
   else {
      license.special = 
         opts.ThirdPartyOtherLicense || 
         opts.FreeWebsiteOtherLicense ||
         (opts.PDOtherOfficial ? ('{{PD-because|званично дјело правно изузето од ауторских права у земљи свог поријекла}}') : null) ||
         (opts.OptionNFPortrait ? ('{{non-free biog-pic|' + opts.NFArticle + '}}') : null);
   }   
   if (! license.special) {
      // standard, non-parametrized tag licenses from dropdownbox.
      var simpleLicense = (opts.OptionOwnWork ? opts.OwnWorkLicense : null) ||
          (opts.OptionThirdParty ? opts.ThirdPartyLicense : null) ||
          (opts.OptionFreeWebsite ? opts.FreeWebsiteLicense : null) ||
          (opts.OptionNFSubject ? opts.NFSubjectLicense : null) ||
          (opts.OptionNF3D ? opts.NF3DLicense : null) ||
          (opts.OptionNFExcerpt ? opts.NFExcerptLicense : null) ||
          (opts.OptionNFCover ? opts.NFCoverLicense : null) ||
          (opts.OptionNFLogo ? opts.NFLogoLicense : null) ||
          (opts.OptionNFMisc ? opts.NFMiscLicense : null) ||
          (opts.PDOtherUSGov ? opts.USGovLicense : null) ||
          (opts.PDOtherGov ? opts.OtherGovLicense : null) ||
          (opts.PDOtherSimple ? opts.IneligibleLicense : null) ||
          (opts.PDUS1923 ? 'PD-US-1923' : null) ||
          (opts.PDURAA   ? 'PD-URAA' : null) ||
          (opts.PDFormality ? 'PD-US' : null);

       // "PD-author" needs parameter, at least on Commons
       if (simpleLicense == 'PD-author') {
          license.special = '{{PD-author|' + opts.Author + '}}';
       }
       else if (this.knownCommonsLicenses[simpleLicense]) {
       // make sure we send only those licenses as "standard" licenses
       // that exist in the Commons license dropdown box
          license.standard = simpleLicense;
       }
       else {
          license.special = '\{\{' + simpleLicense + '\}\}';
       }
   }
   return license;
};

function fuwSubst(template) {
   return '{{subst:' + template + '}}';
}

// ===================================================================
// Produce code for local tracking categories
// ===================================================================
fuwGlobal.prototype.getTrackingCategory = function() {
   var opts = this.opts;
   var cat = "";
   if (opts.OptionFreeWebsite) { cat = "Датотеке из слободно лиценцираних спољашњих извора"; }
   else if (opts.OptionThirdParty) { cat = "Датотеке лиценциране од стране трећих лица"; }
   else if (opts.PDOtherOther || opts.PDOldOther) { cat = "Датотеке са нестандардним изјавама јавног власништва"; }
   else if (opts.OptionNFSubject || opts.OptionNF3D) { cat = "Неслободне датотеке отпремљене за сврху коментара"; }
   if (cat) {
      cat = "\n\{\{category ordered by date|" + cat + "|" + 
      fuwSubst("CURRENTYEAR") + "|" + fuwSubst("CURRENTMONTH") + "|" + fuwSubst("CURRENTDAY2") + "\}\}";
   }
   return cat;
};

// ===================================================================
// Get or create an edit summary for the upload
// ===================================================================
// Note: if we work with the api.php interface, we can have separate
// data for the edit summary and the description page, which is far
// better than the way the index.php interface does it.
// TO DO: need to actually define an input element for a manually
// entered edit summary. Must be obligatory when overwriting files.
// In other cases we'll use an automatic edit summary.
// ===================================================================
fuwGlobal.prototype.getEditSummary = function() {
   var opts = this.opts;
   return (
      (opts.EditSummary ? (opts.EditSummary + ' ([[' + mw.config.get('wgPageName') + '|Водич за отпремање]])') : null)||
      ("отпремање " +
       (
        (opts.OptionOwnWork ? 'личне датотеке ' : false) ||
        (opts.OptionThirdParty ? 'слободне датотеке некога другог ' : false) ||
        (opts.OptionFreeWebsite ? 'датотеке из слободно објављеног извора ' : false) ||
        (opts.OptionPDOld       ? 'старог дјела у јавном власништву ' : false) ||
        (opts.OptionPDOther     ? 'дјела у јавном власништву ' : false) ||
        (opts.OptionNFSubject   ? 'неслободног дјела као предмета расправе ' : false) ||
        (opts.OptionNF3D        ? 'депикције неслободног 3Д дјела ' : false) ||
        (opts.OptionNFExcerpt   ? 'исјечка неслободног дјела ' : false) ||
        (opts.OptionNFCover     ? 'неслободног омота ' : false) ||
        (opts.OptionNFLogo      ? 'неслободног логоа ' : false) ||
        (opts.OptionNFPortrait    ? 'неслободног историјског портрета ' : false) ||
        (opts.OptionNFMisc      ? 'неслободне датотеке ' : "")
       )
       + 
       ("путем [[" + mw.config.get('wgPageName') + "|Водича за отпремање]]")
      ));
};


function fuwPackInfo(text, forCommons) {
   if (forCommons) {
      // reformat wikilinks embedded in description fields to adapt them for Commons
      text = text.replace(/\[\[([^\]]+)\]\]/g, 
         function(str, p1, offset, s) {

            // mark File links as local
            if (p1.match(/^:(File|Image|Датотека|Слика|Datoteka|Slika):/)) {
               return "[[:sr" + p1 + "]]";
            }      
            // leave prefixed links unchanged:
            else if (p1.match(/^:[\w\-]+:/)) {
               return str;
            }
            // if the link is piped, add a prefix only
            else if (p1.match(/.+\|/)) {
               return "[[:sr:" + p1 + "]]";
            }
            // introduce a pipe
            else {
               return "[[:sr:" + p1 + "|" + p1 + "]]";
            }
         }
      );
      return "{{sr|" + text + "}}";
   } else return text;
}

// ================================================================
// This is the main method called by the event handler for the 
// (experimental) submit button. Its main task is to collect the 
// input into a single string of wikitext for the description page.
// ================================================================
fuwGlobal.prototype.collectInput = function() {
   var opts = this.opts;

   // object representing template fields for filling in
   // the description template. Pre-loaded with some
   // standard settings:
   var descFields = this.descFields = { 
      'Description' : opts.InputDesc,
      'Author'      : opts.Author,
      'Date'        : opts.Date,
      'Source'      : opts.Source
   };
   // "other information" (outside the template)
   this.otherInfo = null;
   
   if (opts.OptionNonFree) {
      descFields.Article = opts.NFArticle;
   }
   
   // add/modify option-specific fields:
   switch (opts.MainOption) {
      case 'OptionOwnWork':
      
         // use standard "source" field for optional "how created?" and 
         // "previously published" input fields.
         descFields.Source = fuwAppendLines([
            (opts.OwnWorkCreation || "{{own}}"), 
            "<br/>\n", 
            fuwSurroundString("'''Претходно објављено:''' ", opts.OwnWorkPublication)]);
         var username = mw.user.getName();
         descFields.Author = '[[User:' + username + '|' + username + ']]';
         break;

      case 'OptionThirdParty':
      
         // use standard "permission" field for a compilation of the
         // "permission" input field and the various "evidence" options
         var evidence = (
            opts.ThirdPartyEvidenceOptionLink ? 
               ("Изјава о лиценци може се пронаћи онлајн на: " + opts.ThirdPartyEvidenceLink) :
               (opts.ThirdPartyEvidenceOptionOTRS ? 
               ("Споразум о лиценци прослијеђен је на [[Википедија:OTRS|OTRS]]." + 
                  fuwSurroundString(" Тикет: ", opts.ThirdPartyOTRSTicket) + "\{\{OTRS pending|year=" + fuwSubst("CURRENTYEAR") + 
                                                                              "|month=" + fuwSubst("CURRENTMONTH") + 
                                                                              "|day=" + fuwSubst("CURRENTDAY2") + "\}\}") :
               (opts.ThirdPartyEvidenceOptionOTRSForthcoming ? 
               "Споразум о лиценци биће ускоро прослијеђен на [[Википедија:OTRS|OTRS]]. \{\{OTRS pending|year=" + fuwSubst("CURRENTYEAR") + 
                                                                              "|month=" + fuwSubst("CURRENTMONTH") + 
                                                                              "|day=" + fuwSubst("CURRENTDAY2") + "\}\}" :
               (opts.ThirdPartyEvidenceOptionNone ?
               "Биће обезбијеђено на захтјев." : null))));
         descFields.Permission = fuwAppendLines([
            opts.ThirdPartyPermission,
            "<br/>\n",
            fuwSurroundString("'''Доказ:''' ", evidence)]);
         break;
         
      case 'OptionFreeWebsite':
         descFields.Permission = opts.Permission;
         break;
         
      case 'OptionPDOld':
         // add "lifetime" input to "author" field
         descFields.Author = fuwAppendLines([
            opts.Author,
            "<br/>\n",
            fuwSurroundString("(Животни вијек: ", opts.PDOldAuthorLifetime, ")")
         ]);
         
         // combine original and direct source into standard "source" field: 
         descFields.Source = fuwAppendLines([
            fuwSurroundString("'''Оригинално објављивање''': ", opts.Publication),
            "<br/>\n",
            fuwSurroundString("'''Непосредни извор''': ", opts.Source)
         ]);
         
         // no standard tag available for "lack-of-registration" PD-US. Need
         // to put this into the "permission" field
         if (opts.PDFormality) 
            descFields.Permission = 
               "Ауторска права су истекла јер је дјело објављено без напомене " +
               "о истима и/или без неопходне регистрације истих.";
      
         // add optional "explanation" input to "permission" field
         if (opts.PDOldPermission) {
            descFields.Permission = fuwAppendLines([
               descFields.Permission,
               "\n\n",
               opts.PDOldPermission
            ]);
         }
         break;
         
      case 'OptionPDOther':
         // Need "permission" field in case of "official item" option
         if (opts.PDOtherOfficial) 
            descFields.Permission = opts.PDOfficialPermission;
         break; 

      case 'OptionNFSubject':
         // most FUR elements can be automatically provided:
         descFields.Purpose = (
            opts.NFSubjectCheckDedicated ? 
             ("За визуелну идентификацију објекта чланка. " +
              "Чланак у цјелини посвећен је баш расправи о овом дјелу.") :
            (opts.NFSubjectCheckDiscussed ?
             ("Да се подржи енциклопедијска расправа о овом дјелу у чланку у питању. " +
              "Илустрација је неопходна да подржи сљедећи специфични навод: " +
              "<br/>\n" + opts.NFSubjectPurpose) : null)
         );
         // I hate FURs filled with trivial/predictable/redundant verbiage,
         // so we'll just cut it short. And don't anybody dare complain that
         // that's not a valid FUR.
         descFields.Replaceability = "Н/Д";
         descFields.Commercial     = "Н/Д";
         break;

      case 'OptionNF3D':
         // complex case: we need to assemble attribution and FUR both for the 
         // original 3D work and for the photographic depiction. Both might be 
         // non-free.
         descFields.Author = fuwAppendLines([
            fuwSurroundString("'''Оригинално дјело:''' ", opts.NF3DCreator),
            "<br/>\n",
            fuwSurroundString("'''Депикција:''' ", opts.Author)
         ]);
         descFields.Date = fuwAppendLines([
            fuwSurroundString("'''Оригинално дјело:''' ", opts.NF3DOrigDate),
            "<br/>\n",
            fuwSurroundString("'''Депикција:''' ", opts.Date)
         ]);
         descFields.Purpose = (
            opts.NF3DCheckDedicated ? 
             ("За визуелну идентификацију објекта чланка. " +
              "Чланак у цјелини посвећен је баш расправи о овом дјелу.") :
            (opts.NF3DCheckDiscussed ? 
             ("Да се подржи енциклопедијска расправа о овом дјелу у чланку у питању. " +
              "Илустрација је неопходна да подржи сљедећи специфични навод: " +
              "<br/>\n" + opts.NF3DPurpose) : null)
         );
         descFields.Replaceability = "Н/Д";
         descFields.Commercial    = "Н/Д";
         descFields["Other information"] = (
            opts.NF3DOptionSame ?
            ("Слику је направио и објавио исти аутор који посједује " +
             "ауторска права за оригинално дјело (објекат) и није " +
             "могуће сврсисходно створити алтернативни приказ.") :
            ("Аутор слике објавио је фотографско дјело под " +
             "слободном лиценцом, или је иста у јавном власништву: " + opts.NF3DPermission)
         );
         break; 
         
      case 'OptionNFExcerpt':
         // FURs for screenshots etc. don't normally need to bother
         // about replaceability (with free images) and with commercial role,
         // but do need to bother about purpose and about replaceability with text.
         descFields.Purpose        = opts.NFPurpose;
         descFields.Replaceability_text = opts.NFReplaceableText;
         descFields.Replaceability = "Н/Д";
         descFields.Commercial     = "Н/Д";
         break;
         
      case 'OptionNFCover':
         // cover art gets standard rationales.
         descFields.Purpose = 
            "да служи као примарно средство визуелне идентификације " +
            "при врху чланка посвећеног дјелу у питању.";
         descFields.Replaceability = "Н/Д";
         descFields.Commercial     = "Н/Д";
         break;
 
      case 'OptionNFLogo':
         // logos get standard rationales.
         descFields.Purpose = 
            "да служи као примарно средство визуелне идентификације " +
            "при врху чланка посвећеног ентитету у питању.";
         descFields.Replaceability = "Н/Д";
         descFields.Commercial     = "Н/Д";
         break;

      case 'OptionNFPortrait':
         // as with other historic photographs, it is useful to have both
         // original publication and direct source
         descFields.Source = fuwAppendLines([
            fuwSurroundString("'''Оригинално објављивање''': ", opts.Publication),
            "<br/>\n",
            fuwSurroundString("'''Непосредни извор''': ", opts.Source)
         ]);   
         descFields.Purpose = 
            "за визуелну идентификацију особе у питању, " +
            "при врху његовог/њеног биографског чланка";
         descFields.Replaceability = opts.NFReplaceable;
         descFields.Commercial = opts.NFCommercial;
         descFields['Other information'] = 
            "Субјекат на фотографији је покојник/ца од: " + opts.NFPortraitDeceased;
         break;
         
      case 'OptionNFMisc':
         descFields.Source = fuwAppendLines([
            fuwSurroundString(
               "'''Оригинално објављивање''': ", 
               opts.Publication,
               "<br/>\n'''Непосредни извор:''' "),
            "",
            opts.Source
         ]);   
         descFields.Purpose = opts.NFPurpose;
         descFields.Replaceability = opts.NFReplaceable;
         descFields.Replaceability_text = opts.NFReplaceable_text;
         descFields.Commercial = opts.NFCommercial; 
         break;     
   };

   if (opts.OptionNonFree) {
      // common stuff for all non-free files:
      
      // Minimality field (same for all NF options):
      descFields.Minimality = opts.NFMinimality;
      
      // append optional "extra license" selector and "AnyOther" fields
      // to "Other information" field:
      descFields['Other information'] = fuwAppendLines([
         descFields['Other information'],
         "<br/>\n",
         fuwSurroundString('\{\{', opts.NFExtraLicense, '\}\}'),
         "<br/>\n",
         opts.AnyOther
      ]);
   }
   else {
      // common stuff for all free files:
      descFields.Other_versions = ''
      this.otherInfo = fuwAppendLines([this.otherInfo, "\n\n", opts.AnyOther]);
   
   }

};

fuwGlobal.prototype.formatOutput = function(forCommons) {
   var baseForm = this.ScriptForm;
   var targetForm = this.TargetForm;
   if (fuwTesting) {
      var testForm   = this.TestForm;
   }
   var opts = this.opts;
   var otherInfo = this.otherInfo;
   var descFields = this.descFields;

   var summary = "{{" + this.getDescriptionTemplateName();

   // assemble all fields into the wikitext of the description page:
   var fieldOrder = [
      'Source', 'Date', 'Author', 'Permission', 'Other_versions',
      'Article', 'Purpose', 'Replaceability', 'Replaceability_text', 
      'Minimality', 'Commercial', 'Other information'
   ];
   summary += "\n|Description = " + fuwPackInfo(descFields['Description'], forCommons);
   for (var i = 0; i < fieldOrder.length; i++) {
      if (descFields[fieldOrder[i]]) {
         summary += "\n|" + fieldOrder[i] + " = " + descFields[fieldOrder[i]];
      }
   }
   summary += "\n}}\n";
   if (otherInfo) {
      summary += "\n;Остале информације:\n" + fuwPackInfo(otherInfo, forCommons) + "\n";
   }

   var editSummary = this.getEditSummary();
   
   var license = this.getLicense();
   
   if (forCommons) {
      // pack our description info into an url pointing to the 
      // standard Commons Special:Upload
      // with pre-loaded description fields

      summary = fuwSubst("Ознаку отпремања је додао ЧО sr.wp") + "\n" + summary;
      summary = summary.replace(/\{\{OTRS pending\}\}/g, fuwSubst("OP"));

      if (license.special) {
         // manually format the whole description page including the license tag, if it
         // isn't one of the bare standard licenses in the dropdown box. Otherwise,
         // submit description summary and license as two separate url parameters.
         summary = summary + "\n\n" + license.special;
      }
      return (fuwGetCommonsURL() +
         "?title=Special:Upload" +
         "&wpUploadDescription=" +
         encodeURIComponent(summary) +
         (license.standard ? 
          ("&wpLicense=" + encodeURIComponent(license.standard)) : '') +
         "&wpDestFile=" + 
         encodeURIComponent(opts.InputName));
   }
   else {
      // pack all description into a single "text" parameter to be submitted
      // to the local api.php upload.
      summary = "==Опис==\n" + 
         summary + 
         "\n==Лиценцирање==\n" + 
         (license.standard ? ("\{\{" + license.standard + "\}\}") : license.special) +
         this.getTrackingCategory();
         
      if (fuwTesting) {
         // Testing mode: show our data in the dummy form
         // at the bottom of the page.
         fuwGet('placeholderSandboxFilename').innerHTML = opts.InputName;
         this.TestForm.SandboxSummary.value = editSummary;
         this.TestForm.SandboxText.value = summary;
         fuwSetVisible('placeholderTestForm', true);
      }
      // write output parameters into target form
      // I can't believe IE7 is too stupid to simply understand "this.TargetForm.filename.value".
      ($('#TargetForm [name="filename"]')[0]).value = opts.InputName;
      ($('#TargetForm [name="text"]'    )[0]).value = summary;
      ($('#TargetForm [name="comment"]' )[0]).value = editSummary;
      ($('#TargetForm [name="token"]'   )[0]).value = mw.user.tokens.get('editToken');

   }
   
};

function fuwHasUserGroup(group) {
   // workaround because old IE versions don't have array.indexOf :-(
   for (i = 0; i < mw.config.get('wgUserGroups').length; i++) {
      if (mw.config.get('wgUserGroups')[i] == group) {
         return true;
      }
   }
   return false
}

fuwGlobal.prototype.getUserStatus = function() {
   // function to determine the experience status and userrights of the current user:
   // 'anon': not logged in; can't use script.
   // 'notAutoconfirmed': can't use local upload, but may use script to prepare upload for Commons
   // 'newbie': autoconfirmed but editcount < 100 
   //    (may be used in future to adapt instructions more to newbie needs)
   // 'problem': autoconfirmed but has 3 or more image-related warnings or deletion notifications among recent user talk entries
   //    (may be used in future to produce more strongly worded instructions)
   // 'autoconfirmed': regular user
   // 'sysop'

   if (mw.config.get('wgUserName')) {
      if (fuwHasUserGroup('sysop')) {
         this.userStatus = 'sysop';
      }
      else if (fuwHasUserGroup('autoconfirmed') || fuwHasUserGroup('confirmed')) {
         this.userStatus = 'autoconfirmed';
         $.ajax({
            url     : mw.util.wikiScript( 'api' ),
            type    : 'GET',
            dataType: 'xml',
            traditional : true,
            data:   {
                     format: 'xml',
                     action: 'query',
                     meta  : 'userinfo',
                     uiprop: 'editcount',
                     prop  : 'revisions',
                     titles: 'User talk' + mw.config.get('wgUserName'),
                     rvprop: 'comment|user',
                     rvlimit: 30
                    },      
            success: function(data) {
            // callback func     
               var fuw = window.fuw;
               if (data) {
                  var ui = data.getElementsByTagName('userinfo');
                  if (ui) {
                     var editcount = ui[0].getAttribute('editcount');
                     if (editcount < 100) {
                        fuw.userStatus = 'newbie';
                     }
                  }
                  var revs = data.getElementsByTagName('rev');
                  var countWarn = 0;
                  for (i = 0; i < revs.length; i++) {
                     var rev = revs[i];
                     var usr = rev.getAttribute('user');
                     var cmt = rev.getAttribute('comment');
                     if ((usr == 'ImageTaggingBot') ||
                         (cmt.search(/(означавање за брисање \[\[Датотека)|(недостају датотеке за отпремање)|(Датотека (извор и )?проблем са лиценцирањем ауторских права)|(Номиновање за брзо брисање \[\[Датотека)|(Обавјештење: стављање на списак \[\[могуће неслободне датотеке)/) >= 0)) {
                        countWarn += 1;   
                     }
                  }
                  if (countWarn >= 3) {
                     fuw.userStatus = 'problem';
                  }
               }
            }
         });
      }
      else {
         this.userStatus = 'notAutoconfirmed';
      }
   }
   else {
      this.userStatus = 'anon';
   }
};

// =================================================================
// Convenience function for getting the regular index.php
// interface of Commons. Not very elegant.
// =================================================================
function fuwGetCommonsURL() {
   if (document.URL.match(/^https:/)) 
      return "https://commons.wikimedia.org/w/index.php";
   else
      return "http://commons.wikimedia.org/w/index.php";
}  

// ==================================================================
// functions for building form elements
// ==================================================================
fuwMakeRadiobutton = function(group, option, checked, event) {
   // Stupid IE7 doesn't get "value" attribute unless it's created in this convoluted way.
   // Annoying.   
   var node = $('<input type="radio" id="' + option + '" name="' + group + '" value="' + option + '"></input>')[0];
   if (checked) node.checked = true;
   node.onclick = event || fuwRadioClick;
   node.onclick = event || fuwRadioClick;
   fuwAppendInput(option, node);
};
fuwMakeTextfield = function(label, event) {
   var node  = document.createElement('input');
   node.type = 'text';
   node.name = label;
   node.size = fuwDefaultTextboxLength;
   node.onchange = event || fuwUpdateOptions;
   // only for testing:
   //node.value = label;
   fuwAppendInput(label, node);
};
fuwMakeTextarea = function(label, event) {
   var node  = document.createElement('textarea');
   node.name = label;
   node.rows = fuwDefaultTextareaLines;
   node.style.width = fuwDefaultTextareaWidth;
   node.onchange = event || fuwUpdateOptions;
   //only for testing:
   //node.innerHTML = label;
   fuwAppendInput(label, node);
};
fuwMakeCheckbox = function(label, checked, event) {
   var node  = document.createElement('input');
   node.name = label;
   node.type = 'checkbox';
   //only for testing:
   //node.title= label;
   node.checked = checked;
   node.onchange = event || fuwUpdateOptions;
   fuwAppendInput(label, node);
}
fuwMakeHiddenfield = function(name, value, id) {
   var node   = document.createElement('input');
   node.name  = name;
   node.type  = 'hidden';
   node.value = value;
   fuwAppendInput((id || name), node);
};
fuwMakeAnchor = function(label, href, content) {
   var node   = document.createElement('a');
   node.name  = label;
   node.target= "_blank";
   node.href  = href;
   node.innerHTML = content;
   fuwAppendInput(label, node);
};
fuwMakeSelection = function(name, values) {
   var root = document.createElement('select');
   var current = root;
   try {
      for (i=0; i<values.length; i++) {
         var line = values[i];
         var entry;
         if (line.length == 0) {
            current = root;
         }
         else if (line.length == 1) {
            entry = document.createElement('optgroup');
            entry.setAttribute('label', line[0]);
            root.appendChild(entry);
            current = entry;
         }
         else {
            entry = document.createElement('option');
            entry.setAttribute('value', line[0]);
            entry.setAttribute('title', '{{' + line[0] + '}}');
            entry.innerHTML = line[1];
            if (line.length > 2) {
               entry.setAttribute('selected', 'selected');
            } 
            current.appendChild(entry);
         }
      }
   } catch (e) { alert("Назив: " + name + ", i=" + i); }
   root.name = name;
   root.onchange = fuwUpdateOptions;
   fuwAppendInput(name, root);
};
function fuwMakeWikilink(place, target, redlink, display) {
   
   place = fuwGet(place);
   var id = place.id;
   var anchor;
   if (place.tagName == 'A') {
      anchor = place;
   }
   else {
      anchor = document.createElement('a');
      place.appendChild(anchor);
   }
   anchor.href = mw.util.getUrl(target);
   anchor.title = target;
   anchor.innerHTML = target;
   anchor.className = (redlink ? 'new' : null);
}

function fuwAppendInput(label, content) {
   // append a newly created input element to an existing
   // span element marked as id="placeholderXYZ"
   var node = fuwGet('placeholder' + label);
   var old  = fuwGet(label);
   if (old) {
      old.parentNode.removeChild(old);
   }
   content.id = content.id || label;
   if (node) {
      while (node.hasChildNodes()) {
         node.removeChild(node.firstChild);
      }
      node.appendChild(content);
   }
}

// ======================================================
// move an element away from its current position
// and append it to a target element if condition is true
// ======================================================
function fuwMove(mv, tg, condition, toStart) {
   if (condition) {
      move   = fuwGet(mv);
      target = fuwGet(tg);
      if (move && target) {
         var parent = move.parentNode;
         if (! (target===parent)) {
            parent.removeChild(move);
            if (toStart) {
               target.insertBefore(move, target.firstChild);
            }
            else {
               target.appendChild(move);
            }
         }
      }
      else {
         alert("Непронађени елементи: move=" + mv + "(" + move + "), target=" + tg + "(" + target + ")");
      } 
   }
   return condition;
}

// ===================================================
// make an element visible/invisible
// ===================================================
function fuwSetVisible(tg, condition) {
   target = fuwGet(tg);
   if (target) {
      if (condition) {
         $(target).show();
      }
      else {
         $(target).hide();
      }
   }
   else {
      alert("Непронађени елемент: " +  (tg.nodeType ? tg.id : tg));
   }
}

// ===================================================
// set enabled/disabled status for an element and/or
// all input controls contained in it.
// ===================================================
function fuwSetEnabled(tg, condition) {
   target = fuwGet(tg);
   try {
      var elements = (target.tagName.match(/^(input|textarea|select|button|a)$/i) ? 
         [target] :
         $('#' + target.id + ' *'));
      for (i = 0; i<elements.length; i++) {
         if (elements[i].tagName.match(/^(input|textarea|select|button|a)$/i)) {
            elements[i].disabled = (condition ? null : "онемогућено");
         }
      }
   } catch (e) { alert("Непронађени елемент: " +  (tg.nodeType ? tg.id : tg)); }
}

// ===================================================
// convenience function to check whether a given
// element is currenly visible. Needs to check display
// property of the element and its ancestors
// ===================================================
function fuwIsVisible(el) {
   element = fuwGet(el);
   if (!element) return false;
   el = element.id;
   
   var visible = true;
   while (! (element === document.body)) {
      if (element.style.display == "none") {
         visible = false;
         break;
      }
      element = element.parentNode;
   }
   return visible;
}

// ===================================================
// cleanup filename
// ===================================================
function fuwCleanFilename() {
   var nameBox = window.fuw.ScriptForm.InputName;
   var oldname = name = $.trim(nameBox.value);

   if (name) {
      // strip accidentally added [[   ]] or [[:  ]] brackets
      name = name.replace(/(^\[\[:?)|(\]\]$)/g, "");
      // strip accidentally added "File:" prefix
      name = name.replace(/^(File|Image|Датотека|Слика|Datoteka|Slika):/, "");
      // replace underscores with spaces
      name = name.replace(/_/g, " ");
      // uppercase first letter
      name = name.charAt( 0 ).toUpperCase() + name.slice(1);
   }
   if (oldname != name) {
      nameBox.value = name;
   }
   // always return true so the next validation step will proceed:
   return true;
}


// ==================================================
// check filename for technically illegal 
// characters, trying to fix them automatically
// ==================================================
function fuwCheckLegalFilename() {
   var nameBox = window.fuw.ScriptForm.InputName;
   var oldname = name = $.trim(nameBox.value);

   if (name) {
      // resolve accidentally entered html entities and URI-encoded %XX character codes
      name = name.replace(/\&[a-z]+;/g, fuwHtmlEntityDecode);
      name = name.replace(/(\%[A-F0-9]{2,2})/g, decodeURI);
      // remove illegal characters # < > [ ] | { } /:
      // using a best guess for an acceptable replacement
      name = name.replace(/[<\[\{]/g, "(");
      name = name.replace(/[>\]\}]/g, ")");
      name = name.replace(/[#:\|]/g,  ",");
      name = name.replace(/\//g, "-");
      // remove sequences of tildes
      name = name.replace(/\~{3,}/g, "---");
      // remove initial slash
      name = name.replace(/^\//, "");
   }
   
   if (oldname != name) {
      window.fuw.warn.IllegalChars = true;
      nameBox.value = name;
      return false;
   }
   else {
      window.fuw.warn.IllegalChars = false;
      return true;
   }
}
function fuwHtmlEntityDecode(str) {
   // hack to translate accidentally entered html entity code
   // into actual characters
   var ta=document.createElement('textarea');
   ta.innerHTML=str.replace(/</g,'<').replace(/>/g,'>');
   return ta.value;
}

// =======================================================
// Check against various common patterns of poorly chosen
// filenames (too short / too generic)
// =======================================================
function fuwCheckPoorFilename() {
   var nameBox = window.fuw.ScriptForm.InputName;
   var name = $.trim(nameBox.value);
	name = name.replace(/\.(png|gif|jpg|jpeg|xcf|pdf|mid|ogg|ogv|svg|djvu|tiff|tif|oga)$/i, "");

   // name should be at least 10 characters long, excluding file type extension
   var tooShort = (name.length < 10);
   
   // common generic filename patterns: 
   // IMG......jpg
   // Image....jpg
   // DSC......jpg
   // Picture......jpg
   // Pic..........jpg
   // anything that has fewer than 3 alphabetic letters and then just numbers
   var pattern = /^(img|image|dsc|picture|pic)?(\\s*|\\_*|[a-z]{,3})?\\d+$/i;
   var auto = name.match(pattern);

   window.fuw.warn.BadFilename = (tooShort || auto);
   return !tooShort && !auto;
}

// =======================================================
// check if file extensions match between local filename
// and target filename input box. Automatically append 
// appropriate extension to target filename if they don't.
// =======================================================
function fuwCheckFileExtension() {
   var nameBox = window.fuw.ScriptForm.InputName;
   var name = $.trim(nameBox.value);
   var fileBox = window.fuw.TargetForm.file;
   var file = fileBox.value;
   
   // cancel check if no filename has been provided yet
   if (!file || !name) return true;
   
   var extensions = /.+\.(png|gif|jpg|jpeg|xcf|pdf|mid|ogg|ogv|svg|djvu|tiff|tif|oga)$/i;
   var mimetypes = {
      "png"  : "image/png",
      "gif"  : "image/gif",
      "jpg"  : "image/jpeg",
      "jpeg" : "image/jpeg",
      "xcf"  : "image/x-xcf",
      "pdf"  : "application/pdf",
      "mid"  : "audio/rtp-midi",
      "ogg"  : "audio/ogg",
      "ogv"  : "video/ogg",
      "svg"  : "image/svg+xml",
      "djvu" : "image/vnd.djvu",
      "tiff" : "image/tiff",
      "tif"  : "image/tiff",
      "oga"  : "video/ogg"
   };   

   var found = extensions.exec(file);
   var fileExt = found ? found[1].toLowerCase() : "";
   found = extensions.exec(name);
   var nameExt = found ? found[1].toLowerCase() : "";
   var mime = mimetypes[fileExt]; 
   
   if (fileExt && mime && (mimetypes[nameExt] != mime)) {
      nameBox.value = name.replace(/\.?$/, ('.' + fileExt));
   }
   return true;
}

// ============================================================
// Check if a file under the chosen name already exists,
// either locally or on Commons.
// Store results in the fuw.warn object, so warnings will
// be displayed on the next fuwUpdateOptions() call
// ============================================================
function fuwCheckFileExists() {
   // this is an asynchronous AJAX function.
   // results won't yet be present when this function returns.

   var nameBox = window.fuw.ScriptForm.InputName;
   var name = $.trim(nameBox.value);

   // using the jQuery wrapper for the Ajax functionality:
   $.ajax({
      url     : mw.util.wikiScript( 'api' ),
      type    : 'GET',
      dataType: 'xml',
      traditional : true,
      data:   {
               format: 'xml',
               action: 'query',
               titles: 'Датотека:' + name,
               prop  : 'imageinfo',
               iiprop: 'url|user',
               iiurlwidth: 120
              },      
      success: function(resp) {
      // callback function, called when API query has succeeded:
         // see if the request has returned info from an existing image:
         var foundlist = resp.getElementsByTagName('ii');
         var exists = (foundlist.length >= 1);
         var isCommons = false;
         if (exists) {

            // extract description data from http response.
            // see https://www.mediawiki.org/wiki/API:Properties#imageinfo_.2F_ii 
            // for structure of API response
            var foundImg = foundlist[0];
            isCommons = (foundImg.parentNode.parentNode.getAttribute('imagerepository')=='shared');

            // need this data for creating our own image thumb link
            var width = foundImg.getAttribute('thumbwidth');
            var height = foundImg.getAttribute('thumbheight');
            var thumbURL = foundImg.getAttribute('thumburl');
            var lastUser = foundImg.getAttribute('user');
            var descURL = foundImg.getAttribute('descriptionurl');

            // API returns link to local description page even for Commons images.
            // However, we want a direct link to Commons.
            if (isCommons) {
               descURL = descURL.replace(/sr\.wikipedia\.org/, "commons.wikimedia.org");
               descURL = descURL.replace(/\/\/secure\.wikimedia\.org\/wikipedia\/sr/, "commons.wikimedia.org");
            }

            // build the image info into the warning section of our page:
            thumbDiv = fuwGet('warningImageThumb');
            if (thumbDiv) {
            
               // make all links point to description page:
               var thumbA = thumbDiv.getElementsByTagName('a');
               for (i = 0; i<thumbA.length; i++) {
                  thumbA[i].setAttribute('href', descURL);
               }
               // insert the image itself:
               var thumbImg = thumbDiv.getElementsByTagName('img');
               if (thumbImg.length > 0) {
                  thumbImg = thumbImg[0];
                  thumbImg.setAttribute('src', thumbURL);
                  thumbImg.setAttribute('width', width);
                  thumbImg.setAttribute('height', height);
               }
               // insert the name of the last uploader:
               var thumbSpan = fuwGet('existingImageUploader');
               // TO DO: turn this into a proper link
               if (thumbSpan) thumbSpan.innerHTML = lastUser;
            }

            
         }
         warn = window.fuw.warn;
         warn.ImageOnCommons = exists && isCommons;
         warn.ImageExists    = exists && !isCommons;

         fuwUpdateOptions();
      }
   });
}

// ===========================================================
// onchange event handler for the local filename box
// ===========================================================
fuwValidateFile = function() {
   fuwCheckFileExtension();
   fuwUpdateOptions();
}

// ===========================================================
// onchange event handler for the name input box
// ===========================================================
fuwValidateFilename = function() {
   fuwCleanFilename();
   if (
      fuwCheckLegalFilename() &&
      fuwCheckPoorFilename() &&
      fuwCheckFileExtension()) {
      // after fuwCheckFileExists(),
      // fuwUpdateOptions will be triggered
      // by the callback function after Ajax completion
      fuwCheckFileExists();
   }
   else {
      // if there's been no Ajax call.
      fuwUpdateOptions();
   }
};

// ==========================================================
// function fuwValidateNFArticle()
// ==========================================================
// This is the validation routine for the obligatory
// article-to-be-used-in field for non-free files. It queries
// api.php about the target article through an Ajax call.
// It will store error info in the fuw.warn object,
// triggering the following error on the next updateOptions():
// * warningNFArticleNotFound : target page doesn't exist.
// * warningNFArticleNotMainspace : target is not an article. 
// * warningNFArticleDab : target is a disambiguation page.
// Redirects will automatically be substituted.
// ==========================================================
fuwValidateNFArticle = function() {
   
   var nameBox = window.fuw.ScriptForm.NFArticle;
   oldname = name = nameBox.value;
   
   // cleanup article name:
   // automatically fix accidentally added [[ ... ]] and
   // regularize underscores
   name = $.trim(name);
   name = name.replace(/(^\[\[)|(\]\]$)/g, "");
   // automatically fix article names entered as full urls:
   name = name.replace(/^https?:\/\/sr\.wikipedia\.org\/wiki\//, "");
   name = name.replace(/^https?:\/\/sr\.wikipedia\.org\/w\/index\.php\?title=/, "");
   name = name.replace(/_/g, " ");
   if (name != oldname) nameBox.value = name;
   
   // do nothing more if field was blank
   if (!name) return;

   // using the jQuery wrapper for the Ajax functionality:
   $.ajax({
      url     : mw.util.wikiScript( 'api' ),
      type    : 'GET',
      dataType: 'xml',
      traditional : true,
      data:   {
               format: 'xml',
               action: 'query',
               titles: name,
               prop  : 'info|categories|links'
              },      
      success: function(resp) {
      // callback function, called when API query has succeeded:
         var errorType = 0;
         var pg = resp.getElementsByTagName('page')[0];
         var title = pg.getAttribute('title');
         var target = title;
         if (pg.getAttribute('missing') != null) {
            // no page found under this title.
            errorType = 1;
         }           
         else {
            var userspace = false;
            var ns = pg.getAttribute('ns');
            var rd = pg.getAttribute('redirect');
            if (ns != 0) {
               // not a mainspace page!
               errorType = 2;

               // try to detect if the target might be a user space draft:               
               if (title.match(new RegExp("User( talk)?:" + mw.config.get('wgUserName')))) {
                  userspace = true;
               }
            }
            else if (rd != null) {
               // redirect page
               // API returns an empty redirect="" attribute if
               // the page is a redirect
               var targets = pg.getElementsByTagName('pl');
               for (i=0; i<targets.length; i++) {
                  var link = targets[i];
                  if (link.getAttribute('ns')==0) {
                     target = link.getAttribute('title');
                     errorType = 3;
                     break;
                  }
               }
            }
            else {
               // check for disambiguation categories
               var cats = pg.getElementsByTagName('cl');
               for (i=0; i<cats.length; i++) {
                  var cat = cats[i];
                  if (cat.getAttribute('title') == "Категорија:Вишезначна одредница") {
                     errorType = 4;
                     break;
                  }
               }  
            }
         }
         warn = window.fuw.warn;
         warn.NFArticleNotFound = (errorType==1);
         warn.NFArticleNotMainspace = (errorType==2);
         warn.UserspaceDraft = ((errorType==2) && userspace);
         warn.NFArticleDab = (errorType==4);
         warn.NFArticleOK  = (errorType==0);

         // fix links in error messages:
         if (warn.NFArticleNotFound) {
            fuwMakeWikilink(fuwGet('warningNFArticleNotFound').getElementsByTagName('A')[0], target, true);
         }
         else if (warn.NFArticleNotMainspace) {
            fuwMakeWikilink(fuwGet('warningNFArticleNotMainspace').getElementsByTagName('A')[0], target);
         }
         else if (warn.NFArticleDab) {
            fuwMakeWikilink(fuwGet('warningNFArticleDab').getElementsByTagName('A')[0], target);
         }
         else if (warn.NFArticleOK) {
            fuwMakeWikilink(fuwGet('NFArticleOK').getElementsByTagName('A')[0], target);
         }
                       
         if (errorType==3) {
            // automatically replace title with redirect target
            window.fuw.ScriptForm.NFArticle.value = target;
            // need to recursively call validation again now
            //if (confirm(name + " је преусмјерење. Пратите га до " + target + "?")) {
               fuwValidateNFArticle();
            //}
         }
         else {
            fuwUpdateOptions();
         }          
      }
   });
};

// ================================================
// manually reload script (just for testing)
// ================================================
function fuwReload() {
   mw.loader.load( 'http://localhost/script/uploadscript.js' );
   fuwReset();
}

// ================================================
// reset forms
// TO DO: add a button that actually triggers this.
// ================================================
function fuwReset() {
   var forms = mw.util.$content[0].getElementsByTagName('form');
   for (i = 0; i < forms.length; i++) {
      forms[i].reset();
      window.fuw.warn = { };
      window.fuw.opts = { };
   }
   fuwSetVisible('UploadScriptArea', true);
   fuwSetVisible('fuwSuccess', false);
   fuwSetVisible('fuwWaiting', false);
   fuwUpdateOptions();
}

// ===============================================
// convenience functions for string handling
// ===============================================
function fuwAppendLines(parts) {
   // assemble a string from an array of strings.
   // treat every second element as a conditional
   // separator that will be included only if 
   // surrounding elements are non-empty.
   var build = "";
   for (var i = 0; i < parts.length; i += 2) {
      if (parts[i]) {
         if (build) build += parts[i - 1];
         build += parts[i];
      }
   }
   return build;
}
function fuwSurroundString(prefix, content, suffix) {
   // put a prefix and a suffix on a string, 
   // if the input string is non-empty.
   if (content) 
      return (prefix ? prefix : "") + content + (suffix ? suffix : ""); 
   else return "";
}

// ========================================================
// convenience function for accessing the contents of the
// dummy TargetIFrame
// ========================================================
function fuwGetDocumentFromIFrame(iframe) {
   var doc = (iframe.contentDocument ? iframe.contentDocument : iframe.contentWindow.document);
   if (doc.XMLDocument) {
      doc = doc.XMLDocument;
   }
   return doc;
}
// ========================================================
// event handler for the dummy TargetIFrame's onload event.
// TO DO: expand stub to add real notification of success,
// link to new file page, instructions about how to include
// file in articles, etc.
// ========================================================
function fuwUploadCompleted() {
   var doc = fuwGetDocumentFromIFrame(fuwGet('TargetIFrame'));
   if (doc) {
      //alert(doc);
      fuwSetVisible('successThumb', false);

      var fuw = window.fuw;
      var name = fuw.opts.InputName;

      var uploads = doc.getElementsByTagName('upload');
      var success = false;
      for (i = uploads.length-1; i>=0; i--) {
         if (uploads[i].getAttribute('result') == 'Success') {
            success = true;
            // need to get the real resulting filename here; might be different from the requested one in some cases.
            name = uploads[i].getAttribute('filename');
            break;
         }
      }
      if (success) {

         // need another ajax call to check the file is actually there,
         // and to retrieve its direct thumb img url:
         $.ajax({
            url     : mw.util.wikiScript( 'api' ),
            type    : 'GET',
            dataType: 'xml',
            traditional : true,
            data:   {
                     format: 'xml',
                     action: 'query',
                     titles: 'Датотека:' + name,
                     prop  : 'imageinfo',
                     iiprop: 'url',
                     iiurlwidth: 120
                    },      
            success: function(resp) {
               // callback function, called when API query has succeeded:
               // see if the request has returned info from an existing image:

               var foundImg = resp.getElementsByTagName('ii')[0];
               if (foundImg) {

                  // need this data for creating our own image thumb link
                  var width = foundImg.getAttribute('thumbwidth');
                  var height = foundImg.getAttribute('thumbheight');
                  var thumbURL = foundImg.getAttribute('thumburl');
                  var lastUser = foundImg.getAttribute('user');
                  var descURL = foundImg.getAttribute('descriptionurl');

                  // build the thumbnail in the success message:
                  thumbDiv = fuwGet('successThumb');
                  
                  // make link point to description page:
                  var thumbA = thumbDiv.getElementsByTagName('a')[0];
                  thumbA.href = descURL;

                  // insert the image itself:
                  var thumbImg = thumbDiv.getElementsByTagName('img')[0];
                  thumbImg.setAttribute('src', thumbURL);
                  thumbImg.setAttribute('width', width);
                  thumbImg.setAttribute('height', height);
                  
                  fuwSetVisible(thumbDiv, true);
               }
            }
         });
         fuwMakeWikilink(
            fuwGet('fuwSuccessLink2').getElementsByTagName('a')[0],
            'Датотека:' + name);
         fuwGet('placeholderExFilename1').innerHTML = name;
         fuwGet('placeholderExFilename2').innerHTML = name;
         fuwSetVisible('fuwSuccess', true);
         fuwSetVisible('fuwWaiting', false);
      }
      else {
         var err = doc.getElementsByTagName('error');
         if (err) {
            var info = err[0].getAttribute('info');
            var details = err[0].getElementsByTagName('detail');
            var add = "";
            for (i = 0; i < details.length; i++) {
               if (add.length > 0) add += ", ";
               add += details[i].textContent;
            }
            if (add) {
               info = info + " (" + add + ")";
            }
            alert("Отпремање није успјело: " + info);
         }
         else {
            alert("Непозната грешка: Отпремање можда није успјело.");
         }
      }
   }
}

// ========================================================
// clean out dummy IFrame before submitting a request
// ========================================================
function fuwResetTargetIFrame() {
   var doc = fuwGetDocumentFromIFrame(fuwGet('TargetIFrame'));
   if (doc) {
      while (doc.hasChildNodes()) {
         doc.removeChild(doc.firstChild);
      }
   }
}

// ========================================================
// Event handler for the real submit button
// ========================================================
function fuwSubmitUpload() {
   
   var fuw = window.fuw;
   var frm = fuw.TargetForm;

   fuw.collectInput();
   fuw.formatOutput(false);

   // we will use the iframe's onload event to trigger a function that
   // adds success notification etc.
   fuwResetTargetIFrame();
   var ifr = fuwGet('TargetIFrame');
   if (ifr.attachEvent) {
      // workaround for IE, according to 
      // http://www.nczonline.net/blog/2009/09/15/iframes-onload-and-documentdomain/
      ifr.attachEvent("onload", fuwUploadCompleted);
   }
   else {
      // all other browsers
      ifr.onload = fuwUploadCompleted;
   }

   if (fuwTesting) {
      fuwSetVisible('placeholderTestForm', false);
   }
   fuwSetVisible('UploadScriptArea', false);

   fuwMakeWikilink(
     fuwGet('fuwSuccessLink').getElementsByTagName('a')[0], 'Датотека:' + fuw.opts.InputName);
   fuwSetVisible('fuwWaiting', true);

   frm.submit();
   var opts = window.fuw.opts;
   // the API won't overwrite the description page text while overwriting
   // a file, which is really, really, really annoying and stupid.
   // So in the opts.OverwriteDifferent scenario, we need to edit
   // the description page through a separate ajax call. Dang.
   if (opts.OverwriteDifferent) {
      $.ajax({
         url   : mw.util.wikiScript('api'),
         type  : 'POST',
         dataType : 'xml',
         data  : {
                  format : 'xml',
                  action : 'edit',
                  title  : 'Датотека:' + opts.InputName,
                  token  : mw.user.tokens.get('editToken'),
                  summary : opts.EditSummary,
                  text   : ($('#TargetForm .[name="text"]')[0]).value

                 }
      });
   }
}

// =======================================================
// Event handler for the Commons submit button
// =======================================================
function fuwSubmitCommons() {
   var fuw = window.fuw;
   fuw.collectInput();
   var url = fuw.formatOutput(true);
   alert("Сада ћете бити преусмјерени на Оставу. \nКористите образац за отпремање на Остави да бисте додали категорије у опис датотеке коју отпремате, а потом завршите отпремање.");
   window.location = url;
}

// =======================================================
// Event handler for the test submit button
// (write description string to sandbox only)
// =======================================================
function fuwSubmitSandbox() {
   var frm = window.fuw.TestForm;
   $.ajax({
      url     : mw.util.wikiScript( 'api' ),
      type    : 'POST',
      dataType: 'xml',
      data:   {
               format: 'xml',
               action: 'edit',
               title : mw.config.get('wgPageName') + "/sandbox",
               token : mw.user.tokens.get('editToken'),
               recreate : 1,
               summary  : frm.SandboxSummary.value,
               text     : frm.SandboxText.value
              },      
      success: function(resp) {
         alert("Уређена страница пијеска!");
      }
   });
}



// ========================================================
// convenience wrapper function to replace calls to
// document.getElementById() 
// to avoid browser incompatibility
// ========================================================
function fuwGet(target) {
   if (target && target.nodeType) return target;
   else {
      var found = $('#' + target);
      if (found) return found[0];
   }
   return undefined;
}

// ========================================================
// onload hook function, loading this script
// ========================================================
$(function() { 
   if (fuwGet('UploadScriptArea')) {
      window.fuw = new fuwGlobal();
      fuwUpdateOptions();
   }
});

Ако не буде радило покушаћу поправити.  Обсусер 11:06, 29. мај 2017. (CEST)Одговори

@Ранко Николић: Можеш ли додати thumbA[i].setAttribute('title', 'Датотека:' .. name); испод thumbA[i].setAttribute('href', descURL); и thumbA.title = 'Датотека:' .. name; испод thumbA.href = descURL; неће ли се промијенити онај ховер текст „Датотека:Example sr-ijek.svg” дефинисан у атрибуту title тага a? Надам се да не треба + умјесто ...   Обсусер 03:18, 30. мај 2017. (CEST)Одговори
Такође треба замијенити Ознаку отпремања је додао ЧО sr.wp са Upload marker added by sr.wp UW јер је ово име шаблона на Остави који сам управо направио.  Обсусер 03:03, 3. јун 2017. (CEST)Одговори
@Obsuser: Мислим да је све ово урађено. — Ранко   Нико лић   11:46, 19. јул 2017. (CEST)Одговори

Дорада 2

@Ранко Николић Ако можеш изврши следеће замене:

  • ... image/vnd.djvu,audio/ogg,video/ogg,audio/rtp-midi → ... image/vnd.djvu,audio/ogg,video/ogg,audio/rtp-midi,audio/wav
  • png|gif|jpg|jpeg|xcf|pdf|mid|ogg|ogv|svg|djvu|tiff|tif|ogapng|gif|jpg|jpeg|xcf|pdf|mid|ogg|ogv|svg|djvu|tiff|tif|oga|wav ×2
  • "oga"  : "video/ogg""oga"  : "video/ogg", па у новом реду "wav"  : "audio/wav" са оним размацима из кода а не одавде са СЗР

Овиме би требало да се аутоматски додају наставци и за wav формат итд.   Обсусер 05:39, 8. август 2017. (CEST)Одговори

Врати ме на страницу „FileUploadWizard.js/Архива 1”.