Open main menu

UESPWiki β

User:Kalevala/sandbox5

< User:Kalevala

PoggerEdit

A page offering code for a Pogger program/web-page to be used for pogging UESP maps. Anyone interested should copy the section, paste it into a .txt document, and then save it as an .html document on their computer. It is potentially useful.

But first read this:

POGGER 1.06.2Edit

A short JavaScript,CSS, and HTML page to help UESP "poggers" find the x, y for pogs on a map. It writes out Image templates for up to 6 pogs. The template works in a per mille fashion upon whatever map is presented in a fixed width, the current default being 384 pixels on a side.

DISCLAIMEREdit

This web page code is offered to editors of UESP for their personal use. It will NOT work from within the UESP wiki. The prospective user will have to copy and paste the code into a .txt document which they will then need to save with an .html extension, all before loading it into a browser.
The code was developed in Firefox, so it may need adjustments for other browsers. Its intent is to produce text for UESP templates for pogging maps. Editors using such text will still need to use "Show Preview" for their edits. There is no guarantee that the text produced will function as expected. Use of the page and code is strictly and completely at the user's risk.
The code itself draws from tutorials on w3schools.com, and represents fair use of them. The code contains neither patent-able nor patented algorithms. The presentation is fully open source for inspection by a prospective user. It does not include or use either cookies or tracking routines. Alteration of the code by a user is strictly and completely at the user's risk. The UESP has no obligation to update or maintain the code. The UESP may change templates at any time with or without notice which may result in the code not working. The UESP is not responsible for any consequential or collateral damages resulting from the use of the code.
DO NOT USE THE CODE if after reading the code and directions you do not understand it and what it does.
DO NOT USE THE CODE if you do not completely agree with everything in this DISCLAIMER and with everything in the COPYRIGHTS section. YOUR USE OF THE CODE OR ANY PORTION OF THE CODE CONSTITUTES COMPLETE AGREEMENT.

COPYRIGHTSEdit

This code was created for use on components taken from the Elder Scrolls series of video games or from websites created and owned by Bethesda Softworks. The copyright for the components is held by Bethesda Softworks while the copyright for this particular code is held by UESP. It is available for use under the same Attribution-ShareAlike 2.5 License as our other content. For further details, see the UESP copyright policy.

POGGER AND POGWRITER CODEEdit

There are two pages, one for the actual pogging (Pogger) and one for writing the template in a format that is easy to copy (PogWriter.) The two work together, Pogger calls upon PogWriter to present a clean and complete Perk Tree template.

Here is Pogger, click, copy and paste it into a text editor (e.g. Notepad) but save as with the extension: .html.
    To copy Pogger. Click [ Show ]    >   >   >


<!DOCTYPE html>
<html dir="ltr" lang="en-US">  <!-- left to right - U.S.A. English     -->

<head>
    <meta charset="UTF-8">     <!-- set of characters used from a font -->
    <title >Pogger 1.06.2</title>
</head>

<!--                    POGGER 1.06.2                                                               -->
<!-- A webpage using javascript, css, and html to help UESP editors ("poggers") find the            -->
<!-- the x and y coordinates used for pogs displayed by the Perk Tree templates.                    -->
<!-- It writes out Image Mark templates for up to 6 pogs. The Perk Tree template has variable sized -->
<!-- OVERLAYs (usually 1000 x 1000) for whatever map is presented using the conventional            -->
<!-- fixed width of 384 pixels on a side.                                                           -->

<!-- User required actions:                                                                         -->
<!-- 1. loading & copy-pasting of the map file in the same folder with this HTML page               -->
<!--    or knowing the local path to the map file that was copied and pasted in the user's computer.-->
<!--    or right clicking the "Original file" link to read the UESP's /NN/N/ images folder path.    -->
<!-- 2. copying the output of Pog Writer to create an entire Perk Tree "pogging" template to paste  -->
<!--    into the edit of any UESP page using the map.                                               -->

<!-- Needs:                                                                                         -->
<!-- 1. further testing since it was only tested in:  Firefox                                       -->

<!-- Future:                                                                                        -->
<!-- 1. user help                                                                                   -->
<!-- 2. preferrences: a. change map square size from 384, b. save map's stored default path         -->
<!-- 3. browse UESP for map file (cross domain) (403 forbidden)                                     -->
<!-- 4. WYSIWYG at some point (round pogs with numeric labels) correctly colored                    -->
<!-- 5. figure out why not all OVERLAYs are 1000 x 1000 as template's /doc  has it?                 -->

<!------------------------------------------ DISCLAIMER ------------------------------------------- -->
<!-- 
        This web page code is offered to editors of UESP for their personal use. It will NOT work 
        from within the UESP wiki. The prospective user will have to copy and paste the code into a
        .txt document which they will then need to save with an .html extension, all before loading
        it into a browser.

        The code was developed in Firefox, so it may need adjustments for other browsers. Its intent 
        is to produce text for UESP templates for pogging maps. Editors using such text will still 
        need to use "Show Preview" for their edits. There is no guarentee that the text produced will 
        function as expected. Use of the page and code is strictly and completely at the user's risk.

        The code itself draws from tutorials on w3schools.com, and represents fair use of them. The
        code contains neither patentable nor patented algorithms. The presentation is fully open source 
        for inspection by a prospective user. It does not include or use either cookies or tracking 
        routines. Alteration of the code by a user is strictly and completely at the user's risk. The 
        UESP has no obligation to update or maintain the code. The UESP may change templates at any  
        time with or without notice which may result in the code not working. The UESP is not 
        responsible for any consequential or collateral damages resulting from the use of the code.

        DO NOT USE THE CODE if after reading the code and directions you do not understand it and what
        it does.

        DO NOT USE THE CODE if you do not completely agree with everyting in this DISCLAIMER and with
        everything in the COPYRIGHTS section. YOUR USE OF THE CODE OR ANY PORTION OF THE CODE 
        CONSTITUTES COMPLETE AGREEMENT.
-->

<!-------------------------- COPYRIGHTS  ------------------------------------------------------->
<!-- 
    This code was created for use on components taken from the Elder Scrolls series of video 
        games or from websites created and owned by Bethesda Softworks. The copyright for the 
        components is held by Bethesda Softworks while the copyright for this particular code
        is held by UESP. It is available for use under the same Attribution-ShareAlike 2.5 License 
        as our other content. For further details, see the UESP copyright policy.      
-->

<style>
        /*  the viewport div holding the map awaiting mouse moves and clicks  */
        #screen-log{
                                width:          385px;
                                height:         385px;
                                background-color: White;
                                top:            1px;
                                left:           1px;
                                position: fixed;
                        }
        /*  the div holding the form for file name and location & instructions */
        #getFile{
                                width:          420px;
                                height:         360px;
                                background-color: rgb(255, 199, 127);
                                border:         2px solid red;
                                top:            9px;
                                left:           400px;
                                position:       fixed;
                        }
        /*  the div holding the input lines for previous, next, color, label, info, & position,*/
        #pogButtons{ 
                                width:          1100px;
                                height:         24px;
                                background-color: white;
                                border:         1px solid blue;
                                top:            386px;
                                left:           1px;
                                position: relative;
                                z-index:        -1;
                        }
        /*  the div holding write erase toggle button and its status*/
        #eraseToggleButton{
                                width:  67px; 
                                height: 23px; 
                                top:    386px; 
                                left:   2px; 
                                position:relative;
                                z-index: 3;
                        }
        /*  the div showing status of erase and the current Pogs number (1-6) */
        #showCount{
                                width:  77px;
                                height: 20px;
                                background-color: white;
                                border: 1px solid blue;
                                top:    364px;
                                left:   78px;
                                position:relative;
                                z-index: -1;
                        }
        /*  the div showing the cursor's x & y positions within the viewport*/
        #report {
                                width:  200px;
                                height: 20px;
                                background-color: aqua;
                                border: 1px solid blue;
                                top:    342px;
                                left:   270px;
                                position: relative;
                                z-index: -1;
                        }
        /*  the 6 div's one per pog that show the code for each Image Mark */
        #pog1   {
                                width:  1100px;
                                height:  20px;
                                background-color: pink;
                                border: 1px solid black;
                                top:    346px;    
                                left:     4px;
                                position: relative;
                                z-index: -2;
                        }
        #pog2   {
                                width:  1100px;
                                height:  20px;
                                background-color: LightGreen;
                                border: 1px solid black;
                                top:    346px;
                                left:     4px;
                                position: relative;
                                z-index: -2; 
                        }
        #pog3   {
                                width:  1100px;
                                height:  20px;
                                background-color: pink;
                                border: 1px solid black;
                                top:    346px;     
                                left:     4px;
                                position: relative;
                                z-index: -2;
                        }
        #pog4   {
                                width:  1100px;
                                height:  20px;
                                background-color:  LightGreen;
                                border: 1px solid black;
                                top:      346px; 
                                left:       4px;
                                position: relative;
                                z-index: -2;
                        }
        #pog5   {
                                width:  1100px;
                                height:  20px;
                                background-color: pink;
                                border: 1px solid black;
                                top:      346px;    
                                left:       4px;
                                position: relative;
                                z-index: -2;
                        }
        #pog6   {
                                width:  1100px;
                                height:  20px;
                                background-color:  LightGreen;
                                border: 1px solid black;
                                top:      346px;    
                                left:       4px;
                                position: relative;
                                z-index: -2;
                        }
        /*  the 6 div's one per pog that can be moved around the viewport to visualize pog locations */
        #mark1{
                                width:  11px;
                                height:  11px;
                                position: relative;
                                background-color: white;
                                border: 1px solid red;
                                text-align:center;
                                color:black;
                                font-size:10px;
                                z-index: +1;
                        }
        #mark2{
                                width:  11px;
                                height:  11px;
                                position: relative;
                                background-color: white;
                                border: 1px solid red;
                                text-align:center;
                                color:black;
                                font-size:10px;
                                z-index: +1;
                        }
        #mark3  {
                                width:  11px;
                                height:  11px;
                                position: relative;
                                background-color: white;
                                border: 1px solid red;
                                text-align:center;
                                color:black;
                                font-size:10px;
                                z-index: +1;
                        }
        #mark4  {
                                width:  11px;
                                height:  11px;
                                position: relative;
                                background-color: white;
                                border: 1px solid red;
                                text-align:center;
                                color:black;
                                font-size:10px;
                                z-index: +1;
                        }
        #mark5  {
                                width:  11px;
                                height:  11px;
                                position: relative;
                                background-color: white;
                                border: 1px solid red;
                                text-align:center;
                                color:black;
                                font-size:10px;
                                z-index: +1;
                        }
        #mark6  {
                                width:  11px;
                                height:  11px;
                                position: relative;
                                background-color: white;
                                border: 1px solid red;
                                text-align:center;
                                color:black;
                                font-size:10px;
                                z-index: +1;
                        }
        /*  the div that holds the button to record the information and launch its display page */
        #store{
                                height:24px;
                                width:350px;
                                position:fixed;
                                top:420px;
                                left:600px;
                        }
</style>

<script language="JavaScript" charset="UTF-8">
    //////////////////////////////  CONSTANTS //////////////////////////////////
    const MaxPogs = 6;         // if more are needed, run multiple times and paste the results together
    const offset= -1;          // calculated off-set of the div from screen :UL = (1, 1)

    ///////////////////////////  GLOBALS INITIALIZED ///////////////////////////
    var count = 1;            // number of the current pog being set 
    var erase = false;        // writing mode
    var listening = false;    // status of viewport
    var advance = true;       // increase the number of the working pog or else decrease it
    var newAltText = false;   // default no new template content
    var newPogLabel = false;  // default no new template content
    var newPlacement = false; // default no new template content
    var newColor = false;     // default no new template content

    var defaultHeader = '{{Perk Tree Setup|width=384|mark_width=12|mark_color=yellow}}{{Image Mark|x=00';
    var defaultMiddle = '|y=00';
    var defaultTrailer= '|label=A pog|mark_alt=no further description|position=bottom}}';
    var defaultPogText= defaultHeader + defaultMiddle + defaultTrailer;
    let pogText = ['0','X','X','X','X','X','X'];  // use [1] through [6]
    var ratio;
    var UESPwide;      // 1280, usually 1000, 800

     ///////////////////////////  GLOBALS MODIFICATION //////////////////////////
    function initialize(){
       var i=1; // ignore [0]th element 
       for (i=1; i<=(MaxPogs); i++) {
                        pogText[i]=defaultPogText;
       } // end loop  - default pog text for 1 - 6
       numberTheMarks();               
       return;
     }

     function getTemplateWidth(){ //sets the OVERLAY square's width
        var templateWidth= document.getElementById("perkTreeWidth"); // 1000, 1280 or 800
        UESPwide = templateWidth.value; //global
        ratio = UESPwide/384;    // get rid of magic 384 move to constant?
        return;
     }

     function numberTheMarks(){
        var mark = document.getElementById("mark1");
        mark.innerText = '1';
        mark = document.getElementById("mark2");
        mark.innerText = '2';
        mark = document.getElementById("mark3");
        mark.innerText = '3';
        mark = document.getElementById("mark4");
        mark.innerText = '4';
        mark = document.getElementById("mark5");
        mark.innerText = '5';
        mark = document.getElementById("mark6");
        mark.innerText = '6';
        return;
     }
 
     // Perk Tree template uses a map/graphic reference OVERLAY of 1000 x 1000 for most maps.
     // this overlays the map graphic which is fitted into a 384 x 384 box.
     // occasionally it uses a map reference overlay 1280 x 1280. Right now there is no
     // easy way to find out.  You have to pog it and view the results.

     ///////////////////////////////  DEBUGGERS  /////////////////////////////////  
     //  console.log() with control-shift-j   &  alert('message');

     ///////////////////////  STRING WRANGLING ROUTINES //////////////////////////
     function findFirstPos(Xstr, Ystr){
        // within Xstr, find Ystr
        if( Ystr.length > Xstr.length) {//ERROR: looking tree larger than forest
            console.log(Ystr,' cannot be in this small string');// tell someone
            return -1;//note the stupidity and leave
        }//end if error: sought srt longer than zone searched - impossible
        var i=0;  // outer index
        var j=0;  // inner index
        var foundStr="";
        var strSize=Xstr.length;  // base length
        var tarSize=Ystr.length;  // size of searched for string
        var searchZone = strSize - tarSize; //last place to look

        var location = -1;        // pessimistic assumption  - failed to find
        for (i=0; i<searchZone; i++){  // where to begin building a test string
            foundStr=""; // build the found string
            for (j = 0; j < tarSize; j++){
                foundStr = foundStr + Xstr[i+j];
            }//end inner build loop
            if (foundStr == Ystr) { // yields rightmost if many instances
                location = i;
            }//remember the location of the find
        }//end outer search loop     

        if( location < 0) {
            console.log(Ystr,' not found');// tell someone the search failed & leave
            return location;
        }//end error check
        return location; // where target begins in searched string (0-searchZone)
     }  //end function findFirstPos

     function findLastPos(X, Y){ 
     // within Xstr, find Ystr
        var Last = -1;
        var First = findFirstPos(X, Y);
        if( First < 0){
            console.log(Ystr,' not found');// tell someone the search failed & leave
            return(-1); // failed to find the First
        }               
        Last = First + Y.length;//location of last letter of the Start extraction token
        return Last;
     }  //end findLastPos

     function extract(Base, Start, End){ 
        //find the information within Target string, going FromPos to ToPos
        var FromPos = findLastPos(Base, Start );
        var ToPos   = findFirstPos(Base, End );
        var i=0;
        var Build=""; // whatever is between the tokens
        for( i=FromPos; i<ToPos; i++){
             Build = Build + Base[i];
        }
        return Build;
     }  //end extract information (not remove it)

    /////////////////  INDEPENDENT FUNCTIONS   //////////////////////////////////
        
       // forcing the marks to see screen-log viewport as their parent
        // thus the x and y (left and top) refer back to screen-log for (0,0)
        function setParent(el, newParent) {
           newParent.appendChild(el);
           return;
    }


        function displayMark(markX, markY) {
                var mark; // getting an element by ID does not change the count
                if (count == 1) { mark = document.getElementById("mark1");}
                if (count == 2) { mark = document.getElementById("mark2");}
                if (count == 3) { mark = document.getElementById("mark3");}
                if (count == 4) { mark = document.getElementById("mark4");}
                if (count == 5) { mark = document.getElementById("mark5");}
                if (count == 6) { mark = document.getElementById("mark6");}
                setParent(mark, document.getElementById("screen-log") );// force paternity
                // change the div in line to allow pog color changes 
                mark.style.position = "fixed"; // refer to the parent's 0,0 when placing Pog
                mark.style.color = "black";    // change to contrast with Pog color
                mark.style.innerText = count;  // which Pog it is shows inside div
                mark.style.border = "1px solid red"; //border may match Pog color
                mark.style.borderRadius = "6px"; // makes the little div look round
                mark.style.zIndex = "1"; // stay on top in viewport div
                mark.width = "11px";   // size of Pog's display div
                mark.height= "11px";   //   "   "  "     "       "
                mark.style.fontSize = "10px";  // size of Pog's number shown
                // convert the per mille (per 1000, per whatever) format back to pixels
                markY = (markY-offset)/ratio-6; //-6 is middle of 11x11
                markX = (markX-offset)/ratio-6;
                mark.style.top  = markY+"px";// store it's place
                mark.style.left = markX+"px";
                return;
        }// end display marks function

     // increases and tracks the number of the Pog being worked on
     // shows it in white background in the Pog list (or if erasing, in orange)
     function displayCount(){
        var cnt2   = document.getElementById("showCount");
        if (!erase){
            cnt2.style.backgroundColor = "White";
            cnt2.innerText =  `Writing ${count}`;
        }else{
            cnt2.style.backgroundColor = "Orange";
            cnt2.innerText =  `Erasing ${count}`;           
        }// end else
     } //end displayCount

     function displayPogLines(){
                //color all 6 backgrounds their default alternating values
                var pog  = document.getElementById("pog1");
                pog.style.backgroundColor='LightBlue';                  
                if(extract(pogText[1],"|x=","|y=") == "000") {pog.style.backgroundColor='Pink';}
                pog  = document.getElementById("pog2");
                pog.style.backgroundColor='LightGreen';
                if(extract(pogText[2],"|x=","|y=") == "000") {pog.style.backgroundColor='Pink';}
                pog  = document.getElementById("pog3");
                pog.style.backgroundColor='LightBlue';
                if(extract(pogText[3],"|x=","|y=") == "000") {pog.style.backgroundColor='Pink';}
                pog  = document.getElementById("pog4");
                pog.style.backgroundColor='LightGreen';
                if(extract(pogText[3],"|x=","|y=") == "000") {pog.style.backgroundColor='Pink';}               
                pog  = document.getElementById("pog5");
                pog.style.backgroundColor='LightBlue';
                if(extract(pogText[5],"|x=","|y=") == "000") {pog.style.backgroundColor='Pink';}                
                pog  = document.getElementById("pog6");
                pog.style.backgroundColor='LightGreen';
                if(extract(pogText[6],"|x=","|y=") == "000") {pog.style.backgroundColor='Pink';}
                //get current pog by count 
                if (count == 1) {  pog  = document.getElementById("pog1");} 
                if (count == 2) {  pog  = document.getElementById("pog2");}
                if (count == 3) {  pog  = document.getElementById("pog3");}
                if (count == 4) {  pog  = document.getElementById("pog4");}
                if (count == 5) {  pog  = document.getElementById("pog5");}
                if (count == 6) {  pog  = document.getElementById("pog6");}
                // change current line to background-color:white  or orange if erased
                pog.style.backgroundColor="white";
                if (erase) {
                        pog.style.backgroundColor="orange";
                }// end if erase
     } //end displayPogLines

     function advanceCount() {       // increase clicked enters here, read mouse here
        if(advance){ count++;
        }else{       count--;
        }// end advance or decrease
        // correct roll over or under
        if (count < 1){ //count roll over
            count = MaxPogs;
        }
        if (count > MaxPogs){ // count roll under
            count = 1; 
        }
        displayCount();   // the count has changed so show it
        displayPogLines();// one of them has changed (it is now the focus) so show it
        return;
     } //end advanceCount

     function toggleEraseMode() {
        var eraseButtonStatus  = document.getElementById("eraseButton");
        erase = !erase;// the actual toggle
        if(erase){
           eraseButtonStatus.innerText="To_Write";
        }else {
           eraseButtonStatus.innerText="To_Erase";
        }
        displayCount();   // the display has changed so re-display the rest
        displayPogLines();//
        return;
     } //end toggleEraseMode

     ///////////////////////  URL FORM HANDLING   ///////////////////////////////////////
     // concatenating the inputs from the HTML form
     function makeURL(){
        // URL input elements - must be local to the function
        var URL = "";
        var TheMap = "";
        var path   = document.getElementById("Path-Option");
        var space  = document.getElementById("Name-Space");
        var uesp   = document.getElementById("UESP-Type");
        var name   = document.getElementById("Map-Name");
        var ext    = document.getElementById("Extension");
        URL = path.value + space.value + uesp.value;
        TheMap = name.value;
        // replacing spaces in the map name with underscores 
        var L = TheMap.length;
        var Build="";
        var i;
        for (i=0; i<L; i++) { 
            if (TheMap[i]==" ") {
                Build = Build + "_"; 
            }else{ 
                Build = Build + TheMap[i]; 
            }
        }//end loop changing spaces to underscores
        URL = URL + Build + ext.value;// properly tarted up
        return(URL);
     } //end makeURL

     // load a requested Map perhaps replacing the current occupant;
     // if its a bad URL the div's innertext says "missing map" etc.
     function changeImage(){
        // the viewport starts off blank so a map must be loaded to start by button click
        // and any new map must be loaded on request by button click
        var image = document.getElementById("mapLoad");// the image within the viewport 
        image.src = makeURL();
                console.log(image.src);// sets/resets the image's source
        getTemplateWidth(); // first or new map, needs to set an OVERLAY width
        return;                     
     } //end changeImage

    //////////////////////  VIEWPORT HANDLER AND ITS SUB-FUNCTIONS  /////////////////////
        // opens up <div> "screen-log" to be "viewport" listening for clicks & mouse movements
    function readMouse(){
       // keeps reporting x and y values for as many pogs as you want
       listening = true;
       var pog  = document.getElementById("pog1");             
       screenLog = document.querySelector('#screen-log');  //where to listen for events
       document.getElementById("screen-log").addEventListener('mousemove', logKey );//to logKey
       document.getElementById("screen-log").addEventListener('click', clickKey );  //to lickKey
           // a sub-function  that deals with mouse movements in ViewPort
       function logKey(e){
          // function reports the X,Y location of searching mouse to the element --->
          var elem = document.getElementById("report");
          var fx=Math.floor(e.clientX*ratio+offset);
          var gy=Math.floor(e.clientY*ratio+offset);
          fx = Math.min(fx,UESPwide);
          gy = Math.min(gy,UESPwide);
          fx = Math.max(1, fx);
          gy = Math.max(1, gy);
          elem.innerText = '{{Image Mark|x=' + fx + '|y=' + gy ;
       }// end logKey

       // a sub-function  that deals with clicks in ViewPort;
       //      &    updates the template information and screen-log
       function clickKey(e) {
          // get click location for sub funtion
          var fx=Math.floor(e.clientX*ratio+offset);
          var gy=Math.floor(e.clientY*ratio+offset);
          fx = Math.min(fx,UESPwide);
          gy = Math.min(gy,UESPwide);
          fx = Math.max(1, fx);
          gy = Math.max(1, gy);
          // default values assigned for inserting into Pog's string
          var insertPog = "pog " + count;
          var insertAlt = "no further description";
          var insertColor = "yellow";
          var insertPlacement = "Bottom ";
          // assign <div> for current click
          if (count == 1) {  pog  = document.getElementById("pog1");} // show Pog in Viewport
          if (count == 2) {  pog  = document.getElementById("pog2");} //  at (fx, gy)
          if (count == 3) {  pog  = document.getElementById("pog3");}
          if (count == 4) {  pog  = document.getElementById("pog4");}
          if (count == 5) {  pog  = document.getElementById("pog5");}
          if (count == 6) {  pog  = document.getElementById("pog6");}
          //   BUILDING INFORMATION STRING AS OUTPUT 
          if (pogText[count].length > 20){   // assigning values to the inserts
              if( newColor) {   // if there is a new color accept it
                  newColor = false;
                  insertColor = pogColor.value;
              } else { // otherwise extract the old value
                  insertColor = extract( pogText[count], 'color=', '}}{{' );
              }
              if( newPlacement ) {  // if there is a new placement accept it
                  newPlacement = false;
                  insertPlacement = labelPlacement.value;
              } else {              // otherwise extract the old value
                   var searchString = pogText[count].slice(49,pogText[count].length);//get the 2nd time
                   insertPlacement = extract( searchString, 'position=', '}' );
              }
              if ( newPogLabel ){  // if there is a new label accept it
                   newPogLabel = false;
                   insertPog = labelInfo.value;
              } else {             // otherwise extract the old value
                   insertPog = extract( pogText[count], '|label=', '|mark_alt=' );
              }                   
              if ( newAltText ) {  // if there is a new alt text accept it
                   newAltText = false;
                   insertAlt = altInfo.value;
              } else {             // otherwise extract the old value
                   insertAlt = extract( pogText[count], '|mark_alt=', '|position=');
              }
              // insert latest versions (some of which may be old & unchanged)
              pogText[count]= '{{Perk Tree Setup|width=384|mark_width=12|mark_color=' + insertColor +
                              '}}{{Image Mark|x=' + fx + '|y=' + gy + 
                              '|label=' + insertPog + 
                              '|mark_alt=' + insertAlt + '|position=' + insertPlacement + '}}';                       
          }else{ //length <=20, 0 it is a virgin with no old values,
              if( pogText.length==0){ 
                  pogText[count]=defaultHeader + fx + defaultMiddle + gy + defaultTrailer;
              }//end if len = 0
              //length is 1-20 leave it alone : old erase here was really an omission
          }//end else:  0<= len <=20

          /// show it with any changes in the pog div or show it as a start over default
          if (!erase){// not an erasure - save the hard work
              pog.innerText = pogText[count]; // show stored info
          }else { //erase: stuff string[i] with default, display default, toggle out off erase
              pogText[count] = defaultHeader+'000'+defaultMiddle+'000'+defaultTrailer;
              pog.innerText = pogText[count]; // replaced with dummy default
              toggleEraseMode();// i.e. turn it off
          }// end erase is true
          displayMark(fx,gy);  // send current location and move mark div to that pixel location         
       }// end clickKey (mouse click sub function)
    }// end readMouse

     // write the entire template to localStorage
     function writePerkTree(){  // fails if URL name has extra periods
        var URL = makeURL();
        // clipping off the path
        var mapName = extract(URL, "SR-", ".");
        var letterCount = URL.length;
        mapName = "SR-" + mapName + URL.substring(letterCount-4, letterCount);// from SR-map- xxxxx .jpg"
        // building the perk tree's elements as strings
        var setupPerk = "{{Perk Tree Setup|width=384|mark_width=12|mark_color=yellow}} ";
        var startPerkTree ="{{Perk Tree|label={{PAGENAME}} Map|" + mapName + "|optional comment|left|perks=";

        var i = 1; // loop index
        for (i=1; i<=MaxPogs; i++){ // making all of the pogs into strings
            var erasedTest = extract(pogText[i], "|x=","|y=");
            if ( (erasedTest == "000") || (erasedTest == "00") || (erasedTest == "00000") ){
               pogText[i] ="<!--NONE---  Reload this page. "+">"; // was erased or never set or both
            }else{
               var theLabel = extract(pogText[i], "|label=", "|mark");
               var pogComment = "<!--" + theLabel.toUpperCase() + "          ---"+">"; //ok
               pogText[i] = pogComment + pogText[i];
            }
        }//end loop
        var endTree = "}}";
        var myStorage = window.localStorage;
        localStorage.clear();
        localStorage.setItem('setUp',setupPerk);
        localStorage.setItem('startTree',startPerkTree); // ok to here
        for (i=1; i<=MaxPogs; i++){
            if(pogText[i].substring(0,7)=="<!--NONE"){  //do nothing
            } else {
                 localStorage.setItem('pog'+i,pogText[i]); 
            }
        }
        localStorage.setItem('endTree',endTree);
        // change button message for users returning, call in PogWriter
        var perkWriteButton = document.getElementById("perkTreeButton");
        perkWriteButton.innerText = "Template written - Reload this page.";
        window.location.href="PogWriter.html";// call the new page to write out the Template
        // localStorage must be used or saved in a .txt NOW, it can be overwritten later!
        // but the tabbed page stays until the tab is closed, or browser shut down
    }//end writePerkTree function

</script>

<body style="background-color:rgba(225, 199, 137,.6);"
      onLoad="console.clear(); initialize(); readMouse(); return;" >
        <div id="screen-log">  <!-- setting up a "viewport"  --->
                <img id ="mapLoad" 
                     width="384" alt=" No map! fill in: map name & (if not in the folder) path ==˃" loading="eager" >
        </div>    
        <div id="pogButtons" style="white-space: nowrap;" >
                <button id="decreaseButton" onclick="advance=false;advanceCount();"> ˂˂ Back </button>
                <button id="advanceButton"  onclick="advance=true;advanceCount() ;">Next Pog ˃˃</button>
                 Pog Color:
                                <select id="pogColor" onChange="newColor=true;">
                        <option value="yellow" selected style="color:black; background:yellow;" >yellow</option>
                        <option value="white" style="color:black; background:white;">white</option>
                        <!---<option value="gray" style="color:black; background:gray;">gray</option> --->                    
                        <option value="red"style="color:white; background:red">red</option>
                        <option value="magenta" style="color:white; background:magenta;">magenta</option>                       
                        <option value="orange" style="color:black; background:orange;">orange</option>
                        <option value="green" style="color:white; background:green;">green</option>
                        <option value="cyan" style="color:black; background:cyan;">cyan</option>
                        <option value="blue" style="color:white; background:blue;">blue</option>
                        <option value="black "style="color:white; background:black;">black</option>
                </select>
                 
                <label for="Label" 
                       style="display:inline; color:red; position:relative; top:0; left:500;">
                       Label:</label>
                <input id="labelInfo" name="labelInfo"type="text" size="14" style="color:red;"
                                        value="***Pog name***" onChange="newPogLabel=true;"></input>
                  
                <label for="Alt" style="color:green;">Info:</label>
                <input id="altInfo" name="altInfo" type="text" size=33 style="color:green;" 
                                        value="**********more info**********" onChange="newAltText=true;"></input>
                 Label placement:
                <select id="labelPlacement" onChange="newPlacement=true;">
                        <option value="bottom" selected >˅ Bottom ˅</option>
                        <option value="left">˂ Left ˂</option>
                        <option value="top">˄ Top ˄</option>
                        <option value="right">˃ Right ˃</option>
                        <option value="on">~ On ~</option>
                        <option value="topleft">topleft╔═</option>
                        <option value="topright">═╗topright</option>
                        <option value="bottomleft">bottomleft╚═ </option>
                        <option value="bottomright">═╝bottomright</option>
                        
                        
                </select>
        </div>
        <div id="eraseToggleButton" ><!--  toggle between write and erase  --->
           <button id="eraseButton" onclick="toggleEraseMode();"  >To_Erase</button>
        </div>
        <div id="showCount">
                Writing 1
        </div>
        <div id="report">.</div><!-- tell where mouse is at the moment--->
        <div id="pog1">1</div>  <!-- x,y output box for pog 1-->
        <div id="pog2">2</div>  <!-- x,y output box for pog 2-->
        <div id="pog3">3</div>  <!-- x,y output box for pog 3-->
        <div id="pog4">4</div>  <!-- x,y output box for pog 4-->
        <div id="pog5">5</div>  <!-- x,y output box for pog 5-->
        <div id="pog6">6</div>  <!-- x,y output box for pog 6-->

        <div>  <!-- initial display of tiny marks for the pogs  -->
                <div id="mark1"></div>
                <div id="mark2"></div>
                <div id="mark3"></div>
                <div id="mark4"></div>
                <div id="mark5"></div>
                <div id="mark6"></div>
        </div>

        <div id="getFile">  <!--  using a form to get the new map's URL --->
                <form>
                        <label for="Path-Option" > Optional Path</label>
                        <input type="text" id="Path-Option" name="Path-Option" size="40" value="" ><br/>

                        <label for="Name-Space"> Name Space: </label>
                        <input type="text" id="Name-Space" name="Name-Space" value="SR-" size="4"><br/>

                        <label for ="UESP-Type"> UESP Type:  </label>
                        <input type="text" id="UESP-Type" name="UESP-Type" value="map-" size="5"><br/>

                        <label for ="Map-Name"> Map Name:   </label>
                        <input type="text" id="Map-Name" name="Map-Name"  size="40" value=""><br/>

                        <label for ="Extension"> Extension:     </label>
                        <input type="text" id="Extension" name="Extension" value=".jpg" size="6"><br/>

                                                         Set the map's overlay width:    
                        <select id="perkTreeWidth">
                                <option value="1280">1280</option>
                                <option value="1000" selected>1000</option>                         
                                <option value="800">800</option>
                        </select>
                        <br/> The LAST thing to do is click:    
                        <input type="button" value="Load Map" id="createURL" name="createURL" 
                                onclick="changeImage(); return;">

                        <!--  Add Browse to find map file? Cannot because of /x/xx/ & 403 forbidden --->
                        <br/>
                        <br/> Path Example --> File:///C:\Users\MyName\Desktop\
                        <br/> Path Example --> https://images.uesp.net<b style="color:green;">/2/24/</b>
                        <br/> To find a path with the UESP's <b style="color:green;">/N/NN/</b> part:
                        <br/> 1. Go to map in File: category (File:SR-map-■ ■ ■ ■ ■.jpg) 
                        <br/> 2. Right click "Original file" underneath map and Copy-Link.
                        <br/> (If none, copy & paste map into Pogger's folder. Omit path.)
                        <br/>
                        <br/> <b>PLACE THE POG AFTER CHANGES TO SAVE THEM.</b>
                        <br/> Changes to pog color, label, info, or label position require
                        <br/> at least one pog placement (click on the map) to be saved.
                </form>
        </div>
    <div id="store">
          <button id="perkTreeButton"; onclick="writePerkTree();">Save PerkTree Code</button> from these pogs: 
    </div>
</body>

</html>


Here is PogWriter, click, copy and paste it into a text editor (e.g. Notepad) but save as with the extension: .html.

The two pages need to be in the same folder together on your computer.
    To copy PogWriter. Click [ Show ]    >   >   >


<!DOCTYPE html>
<!-- Reads local storage & prints it out to copy and  paste into UESP's map edit page --->
<html dir="ltr" lang="en-US">  <!-- left to right - U.S.A. English -->
                               <!-- After running this you CANNOT GO BACK to Pogger   --->
                                                           <!-- you have to RE-LOAD Pogger for it to work         --->
                                                           
<head>
    <meta charset="UTF-8">      <!-- which of the world's alphabets is used           --->
    <title >Pog Writer</title>  <!-- tested with Pogger 1.06                          --->
</head>

<script language="JavaScript"> 
    MaxPogs = 6;
        function writeTree(){
                var myStorage = window.localStorage;
                let pogText = ['X','X','X','X','X','X'];
        // instructions
                document.write("&LT;!-- COPY AND PASTE THE FOLLOWING INTO THE UESP EDIT PAGE FOR THE MAP ---&GT;");
                document.write("<br/>");// works
                // Perk Tree Setup
                var setupPerk = myStorage.getItem('setUp');//null
                document.write(setupPerk);
                document.write("<br/>");
                // Perk Tree
                var startPerkTree = myStorage.getItem('startTree');
                document.write(startPerkTree);
                document.write("<br/>");
                //naked !--Comments---  &  Perk Tree Setup+Image Mark 's
                var i;
                for (i=1; i<=MaxPogs; i++){          
                        pogText[i] = myStorage.getItem('pog'+i);
                        //split recorded information into <comment> and {Perk Tree Setup} + {Image Mark}
                        var templateStart = pogText[i].indexOf("{{");
                        var commentText = pogText[i].substring(0,templateStart-1);
                        if(commentText.length > 0) {  //if something is there, write it out
                                document.write("&LT;" + commentText.substring(1) + "&GT;" );
                                document.write("<br/>");                  
                                var template = pogText[i].substring(templateStart);
                                document.write(template);
                                document.write("<br/>");
                        }//end if
                }//end loop     
                // End of Perk Tree Template token (double end-braces)
                var endTemplate = localStorage.getItem('endTree');
                document.write(endTemplate);
                document.write("<br/>");
        }//end function
</script>

<body onLoad="console.clear(); writeTree();">
   failed printing out the template
</body>

</html>

Thanks for downloading it. Please leave any bug reports or suggestions on my talk page. Bugs & suggestions.