Don't click here unless you want to be banned.

LSL Wiki : ZenMondo

HomePage :: PageIndex :: RecentChanges :: RecentlyCommented :: UserSettings :: You are crawl338.us.archive.org
ZenMondo Wormser styles himself a code poet.

///////////////////////////
// Caledon Library Book Server 2.61 by ZenMondo Wormser
// Developed for Caledon Library System
//
//  Takes a patron to an aetheric address to read
//  a book or chapter of a book.
//
//  The Titles and URLs are stored on a configuration notecard.
//
// The Format of the notecard is as follows
//  A Line with the Title of the book or chapter,
//  followed by a line with the URL of the book or chapter.
//
//  The notecard can be named anything, I suggesst descriptive names such as
//  "The Book of Houshold Management by Mrs. Isabella Beeton"  and not something
//  vaugue such as "urls".
//
//
//  A book or object containing this script is limited to one reader at a time.
//////////////////////


///////////////////////////
// This work is licensed under the Creative Commons Attribution-Noncommercial-Share 
// Alike 3.0 License. To view a copy of this license, visit 
// http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative 
// Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
//
// Attribution: 
//  If unmodified you must keep the filename intact
//  If a derivative work you must say "Based on the CodePoetry of ZenMondo Wormser"
//////////////////////////

//Global Variables
integer position = 0;
string notecard;
key query;

integer handle;
integer UserChan = 11811;

integer titleCounter = 0;
list titleData = [];
list urlData = [];


integer menuPage;
integer lastMenu;

key currentPatron = NULL_KEY;
integer reading = FALSE;

//Functions

//Compact function to put buttons in "correct" human-readable order ~ Redux
//Taken from /lslwiki/wakka.php?wakka=llDialog
list order_buttons(list buttons)
{
    return llList2List(buttons, -3, -1) + llList2List(buttons, -6, -4) + llList2List(buttons, -9, -7) + llList2List(buttons, -12, -10);
}

//Function to Display the pages of the Menu
// Instead of defining my menus ahead of time
// (and in so doing putting a limit on the number of items)
// I build the pages of the menu dynamicaly
DisplayMenuPage(key id)
{
    
 
    //These are the buttons, they will be numbers
    // Based on what page of the menu we are on.
    
    string b1 = (string) (menuPage *9 +1);
    string b2 = (string) (menuPage *9 +2);
    string b3 = (string) (menuPage *9 +3);
    string b4 = (string) (menuPage *9 +4);
    string b5 = (string) (menuPage *9 +5);
    string b6 = (string) (menuPage *9 +6);
    string b7 = (string) (menuPage *9 +7);
    string b8 = (string) (menuPage *9 +8);
    string b9 = (string) (menuPage *9 +9);
 
    
    list menu = [b1, b2, b3, b4, b5, b6, b7, b8, b9, "<<PREV", "Bibl.", "NEXT>>"]; //will use the order_buttons function to put these in a good order for llDialog
    
    list menu_text = llList2List(titleData, menuPage * 9, menuPage * 9  + 8); //This is the part of the list for menu text for this page.
    
    integer menu_length = llGetListLength(menu_text);
    
    if(menu_length < 9) //Don't Need all the buttons
    {
        menu = llDeleteSubList(menu, menu_length, 8); //Trim the menu buttons
    }
    
    llDialog(id, llDumpList2String(menu_text, "\n"), order_buttons(menu), UserChan); //Display the Menu
}

default
{
    state_entry()
    {   
        menuPage = 0;
        
        UserChan = -((integer)llFrand(2147483646.0) + 1); //Choose a random  negative channel to use to aoid crossttalk with other books
        
       notecard = llGetInventoryName(INVENTORY_NOTECARD, 0);
                     
       if(llGetInventoryType(notecard) == INVENTORY_NOTECARD)
        {
            llWhisper(0, "Reading Configuration Notecard.");
            query = llGetNotecardLine(notecard, position);
        }
        
        else
        {
            llWhisper(0, "Configuration notecard is not present in the object's inventory.");
        }
       
        
    }

    touch_start(integer total_number)
    {
       if(reading) //Book in use
       {
            if(currentPatron != llDetectedKey(0))
            {
                //Communicate using llDialog we are in a library after all
                // and its even quieter than a whisper.
                llDialog(llDetectedKey(0), "I'm sorry another patron is reading me at this time, please wait a moment and try again.", ["OK"], 1181111811); 
            }
            
            else // Our reader
            {
                DisplayMenuPage(currentPatron); //Give the menu again but not more time
                                                // This is in case they accidently hit "ignore"
            }
        }
        
        else //Book is available and ready for use
        {
            currentPatron = llDetectedKey(0);
            reading = TRUE;
            handle = llListen(UserChan, "", currentPatron, "");
            llSetTimerEvent(90); //90 Second limit to make a choice or reset if walk away
            DisplayMenuPage(currentPatron);
        }
        
        
    }
    
    listen(integer channel, string name, key id, string message)
    {
        if(message == "Bibl.") //Give them the notecard and they can look up the URLS on thier own
        {
            llGiveInventory(id, notecard);
            
            //We will assume they are done, as another menu would obstruct the dialog
            // To accept the notecard from the book.
            llSetTimerEvent(0);
            llListenRemove(handle);
            reading = FALSE;
            currentPatron = NULL_KEY;
            menuPage = 0; 
            
        }
        
        else if(message == "<<PREV")
        {
            menuPage--;
            if(menuPage == -1)
            {
                menuPage = lastMenu;
            }
            
            DisplayMenuPage(currentPatron);
        }
        
        else if(message == "NEXT>>")
        {
            menuPage++;
            if(menuPage > lastMenu)
            {
                menuPage = 0;
            }
            
            DisplayMenuPage(currentPatron);
        }
        
        else //Patron Chose a Number
        {
            llSetTimerEvent(0);
            llListenRemove(handle);
            
            integer GoUrl = (integer) message;
            GoUrl--; //Humans like to count from 1, but computers like 0 better.    
            
            llLoadURL(currentPatron, "Would you like to visit the aetheric version of " + llList2String(titleData, GoUrl) + "?", llList2String(urlData, GoUrl));
            
            reading = FALSE;
            currentPatron = NULL_KEY;
            menuPage = 0;
            

        }
    }
    
    timer()
    {
        llSetTimerEvent(0);
        llListenRemove(handle);
        llDialog(currentPatron, "I'm sorry time has expired to make a menu choice." , ["OK"], 1181111811);
        reading = FALSE;
        currentPatron = NULL_KEY;
        menuPage = 0;   
    }
    
    changed(integer change)
    {
        if(change & CHANGED_INVENTORY) 
        {
            //asuming the notecard has been edited or swapped out. If it wasn't that,
            // WHAT ELSE ARE YOU PUTTING IN? DON'T DO THAT! ONLY THE SCRIPT AND NOTECARD!
            llResetScript();
        }  
        
        
    }
    
    


    dataserver(key request, string data)
    {
        if(query == request)
        {
            if(data == EOF) //Then end of the notecard 
            {
                if(titleCounter % 9 == 0) //Multiples of 9 won't round down right.
                {
                    --titleCounter;
                }
                
                lastMenu = llFloor(titleCounter / 9.0);  //How Many Pages of Menus we will use
                llWhisper(0, "Ready");
                //End of notecard!
            }
            else
            {
                //Do something with the data
                
                if (position % 2) // These lines 1,3,5,7... and so on will be URLs
                {
                    urlData += (list)(data);
                }
                else
                {
                    titleData += (list)((string)(++titleCounter) + ") " + data);
                
                }
                
                //llSay(0, "Added " + data +" to access list.");
                
                //Increase the position variable and
                ++position;
                //Continue reading the next lines.
                query = llGetNotecardLine(notecard, position);
            }
        }
    }
    
    on_rez(integer start_param)
    {
        llResetScript();
    }
}

/////////////////////////////////////////
// ZenMondo's Object Giver 2.21 by ZenMondo Wormser
// Developed for Caledon Library System
//  
// Menu-Driven Item Giver.
// Can be Used by one person at a time.
//////////////////////////////////////

///////////////////////////
// This work is licensed under the Creative Commons Attribution-Noncommercial-Share 
// Alike 3.0 License. To view a copy of this license, visit 
// http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative 
// Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
//
// Attribution: 
//  If unmodified you must keep the filename intact
//  If a derivative work you must say "Based on the CodePoetry of ZenMondo Wormser"
//////////////////////////

//Global Variables

//Folder Name for when patron selects "Get All"
string folder_name = "From the Caledon Library";

//Text that will float over object
string float_text = "From the Caledon Libary\n Pray, touch and receive.";

integer object_counter=0;
list inventory_list = [];
list menu_list = [];

integer menu_page;
integer last_menu;

integer handle;
integer UserChan = -11811;

key current_user = NULL_KEY;

integer using;

//Functions

//Compact function to put buttons in "correct" human-readable order ~ Redux
//Taken from /lslwiki/wakka.php?wakka=llDialog
list order_buttons(list buttons)
{
    return llList2List(buttons, -3, -1) + llList2List(buttons, -6, -4) + llList2List(buttons, -9, -7) + llList2List(buttons, -12, -10);
}


//Function to Build the two lists we will use
// Could have put it all in state_entry but may be a handy function
// to use in another similar script so I put it here.
BuildLists()
{
    integer counter=0;
    integer inventory_num = llGetInventoryNumber(INVENTORY_OBJECT);
        
    while(counter < inventory_num)
    {
        string object_name = llGetInventoryName(INVENTORY_OBJECT, counter);
        
        inventory_list = (inventory_list=[]) + inventory_list + object_name;
        menu_list = (menu_list=[]) + menu_list + [(string) (++counter) + ")" + object_name];   //Incrimenting the the counter in this line.  Probably bad practice
                //But it solves two problems, incrimenting the counter in the loop
                // and making a human readale list startign at "1" instead of "0"

    }
      
    if(counter % 9 == 0) //Multiples of 9 won't round down right.
    {
        --counter;
    }
    
    last_menu = llFloor(counter / 9.0); //I say 9.0 so it treats it like a float
                                        // and will round down correctly.
    
    
    
}


//Function to Display the pages of the Menu
// Instead of defining my menus ahead of time
// (and in so doing putting a limit on the number of items)
// I build the pages of the menu dynamicaly
DisplayMenu(key id)
{
    //These are the buttons, they will be numbers
    // Based on what page of the menu we are on.
    
    string b1 = (string) (menu_page *9 +1);
    string b2 = (string) (menu_page *9 +2);
    string b3 = (string) (menu_page *9 +3);
    string b4 = (string) (menu_page *9 +4);
    string b5 = (string) (menu_page *9 +5);
    string b6 = (string) (menu_page *9 +6);
    string b7 = (string) (menu_page *9 +7);
    string b8 = (string) (menu_page *9 +8);
    string b9 = (string) (menu_page *9 +9);
 
    
       list menu = [b1, b2, b3, b4, b5, b6, b7, b8, b9, "<<PREV", "Get All", "NEXT>>"]; //will use the order_buttons function to put these in a good order for llDialog
    
    list menu_text = llList2List(menu_list, menu_page * 9, menu_page * 9  + 8); //This is the part of the list for menu text for this page.
    
    integer menu_length = llGetListLength(menu_text);
    
    if(menu_length < 9) //Don't Need all the buttons
    {
        menu = llDeleteSubList(menu, menu_length, 8); //Trim the menu buttons
    }
    
    llDialog(id, llDumpList2String(menu_text, "\n"), order_buttons(menu), UserChan); //Display the Menu
     
}



default
{
    state_entry()
    {
        menu_page = 0;
        
        UserChan = -((integer)llFrand(2147483646.0) + 1); //Choose a random  negative channel to use to avoid crossttalk with other books 

        BuildLists();
        
        llSetText(float_text, <0, 1, 1>, 1.0);
    }

    touch_start(integer total_number)
    {if(using) //Object in use
       {
            if(current_user != llDetectedKey(0))
            {
                //Communicate using llDialog we are in a library after all
                // and its even quieter than a whisper.
                llDialog(llDetectedKey(0), "I'm sorry another patron is using me at this time, please wait a moment and try again.", ["OK"], 1181111811); 
            }
            
            else // Our user
            {
                DisplayMenu(current_user); //Give the menu again but not more time
                                        // This is in case they accidently hit "ignore"
            }
        }
        
        else //Giver is available and ready for use
        {
            current_user = llDetectedKey(0);
            using = TRUE;
            handle = llListen(UserChan, "", current_user, "");
            llSetTimerEvent(90); //90 Second limit to make a choice or reset if walk away
            DisplayMenu(current_user);
            llSetText("Currently in Use, \nplease wait a moment...", <1,0,0>, 1.0);
        }
        
          
    }
    
    
    listen(integer channel, string name, key id, string message)
    {
        if(message == "Get All") //Give them all the contents
        {
             llGiveInventoryList(current_user, folder_name, inventory_list);  
            
            //We will assume they are done, as another menu would obstruct the dialog
            // To accept the folder from the object.
            llSetTimerEvent(0);
            llListenRemove(handle);
            using = FALSE;
            current_user = NULL_KEY;
            menu_page = 0; 
            llSetText(float_text, <0, 1, 1>, 1.0);
            
        }
        
        else if(message == "<<PREV")
        {
            menu_page--;
            if(menu_page == -1)
            {
                menu_page = last_menu;
            }
            
            DisplayMenu(current_user);
        }
        
        else if(message == "NEXT>>")
        {
            menu_page++;
            if(menu_page > last_menu)
            {
                menu_page = 0;
            }
            
            DisplayMenu(current_user);
        }
        
        else //Patron Chose a Number
        {
            llSetTimerEvent(0);
            llListenRemove(handle);
            
            integer get_item = (integer) message;
            get_item--; //Humans like to count from 1, but computers like 0 better.    
            
            llGiveInventory(current_user, llList2String(inventory_list, get_item));
            
            
            using = FALSE;
            current_user = NULL_KEY;
            menu_page = 0;
            llSetText(float_text, <0, 1, 1>, 1.0);

        }
    }
        
    
    
    timer()
    {
        llSetTimerEvent(0);
        llListenRemove(handle);
        llDialog(current_user, "I'm sorry time has expired to make a menu choice." , ["OK"], 1181111811);
        using= FALSE;
        current_user = NULL_KEY;
        menu_page = 0; 
        llSetText(float_text, <0, 1, 1>, 1.0);  
    }
    
    changed(integer change)
    {
        if(change & CHANGED_INVENTORY) 
        {
            llResetScript();
        }  
        
        
    }
    
        
}

///////////////////////////
// ZenMondo's URL Go-to-er master 2.0 by ZenMondo Wormser
// Developed for Caledon Library System
//
//  Takes a patron to an aetheric address to read
//  a book or chapter of a book.
//
//  The Titles and URLs are stored on a configuration notecard.
//
// The Format of the notecard is as follows
//  A Line with the Title of the book or chapter,
//  followed by a line with the URL of the book or chapter.
//
//  The notecard can be named anything, I suggesst descriptive names such as
//  "The Book of Houshold Management by Mrs. Isabella Beeton"  and not something
//  vaugue such as "urls".
//
//  This script allows access to a maximum of 12 titles.
//
//  A book or object containing this script can be used by many simultaeneous users.
//
//  This script must be in the same prim as the script
//  ZenMondo's URL Go-to-er slave to work properly.
///////////////////////////

///////////////////////////
// This work is licensed under the Creative Commons Attribution-Noncommercial-Share 
// Alike 3.0 License. To view a copy of this license, visit 
// http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative 
// Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
//
// Attribution: 
//  If unmodified you must keep the filename intact
//  If a derivative work you must say "Based on the CodePoetry of ZenMondo Wormser"
//////////////////////////




integer position = 0;
string notecard;
key query;

integer handle;
integer UserChan = 11811;

integer titleCounter = 0;
list titleData = [];
list urlData = [];

list MENU = ["1", "2", "3", "4", "5", "6", "7","8", "9", "10", "11", "12"];

//Compact function to put buttons in "correct" human-readable order ~ Redux
//Taken from /lslwiki/wakka.php?wakka=llDialog
list order_buttons(list buttons)
{
    return llList2List(buttons, -3, -1) + llList2List(buttons, -6, -4) + llList2List(buttons, -9, -7) + llList2List(buttons, -12, -10);
}

default
{
    state_entry()
    {   
        
        UserChan = -((integer)llFrand(2147483646.0) + 1); 
        
        handle = llListen(UserChan, "", NULL_KEY, "");
        llListenControl(handle, FALSE);
        
        notecard = llGetInventoryName(INVENTORY_NOTECARD, 0);
       
       
       
       if(llGetInventoryType(notecard) == INVENTORY_NOTECARD)
        {
            llWhisper(0, "Reading Configuration Notecard.");
            query = llGetNotecardLine(notecard, position);
        }
        
        else
        {
            llWhisper(0, "Configuration notecard is not present in the object's inventory.");
        }
       
        
    }

    touch_start(integer total_number)
    {
        llListenControl(handle, TRUE);
        llDialog(llDetectedKey(0), "Please choose a title\n" + llDumpList2String(titleData, "\n"), order_buttons(MENU), UserChan);
        llSetTimerEvent(60); //User has 60 seconds to make a choice then the listen goes away to be less laggy.
        
    }
    
    
    listen(integer channel, string name, key id, string message)
    {
       if (llListFindList(MENU , [message]) != -1)  // verify dialog choice
        {
            llSetTimerEvent(0);
            llListenControl(handle, FALSE); //Turn off listen, we don't need it now.
            
            integer GoUrl = (integer) message;
            GoUrl--; //Humans like to count from 1, but computers like 0 better.
            
            string linkMessageString = "Would you like to visit the aetheric version of " + llList2String(titleData, GoUrl) + "?::" + llList2String(urlData, GoUrl);
            
            llMessageLinked(LINK_THIS, 0, linkMessageString, id); //Pass message and url to slave script to avoid 10 sec delay penalty.
             
        }
    }
    
    timer()
    {
        llSetTimerEvent(0);
        llListenControl(handle, FALSE);
        llWhisper(0, "I'm sorry time for a choice has expired.");
    }
    
    changed(integer change)
    {
        if(change & CHANGED_INVENTORY)
        {
            llResetScript(); //We do this if the notecard is changed or edited to reload it.
        }  
        
        
    }
    
    on_rez(integer start_param)
    {
        llResetScript();
    }


    dataserver(key request, string data)
    {
        if(query == request)
        {
            if(data == EOF || position == 24) //the end of the notecard or max titles
            {
                if(titleCounter < 12) //Trim Menu
                {
                    MENU = llDeleteSubList(MENU, titleCounter, 11); //Remove uneeded buttons.
                }
                
                llWhisper(0, "Ready");
                //End of notecard!
            }
            else
            {
                //Do something with the data
                
                if (position % 2) // These lines 1,3,5,7... and so on will be URLs
                {
                    urlData += (list)(data);
                }
                else
                {
                    titleData += (list)((string)(++titleCounter) + ") " + data);
                
                }
                
                //llSay(0, "Added " + data +" to list.");
                
                //Increase the position variable and
                ++position;
                //Continue reading the next lines.
                query = llGetNotecardLine(notecard, position);
            }
        }
    }
}

///////////////////////////
// ZenMondo's URL Go-to-er slave by ZenMondo Wormser
// Developed for Caledon Library System
//
//  Takes a patron to an aetheric address to read
//  a book or chapter of a book.
//
//
//  This script must be in the same prim as the script
//  ZenMondo's URL Go-to-er master to work properly.
///////////////////////////

///////////////////////////
// This work is licensed under the Creative Commons Attribution-Noncommercial-Share 
// Alike 3.0 License. To view a copy of this license, visit 
// http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative 
// Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
//
// Attribution: 
//  If unmodified you must keep the filename intact
//  If a derivative work you must say "Based on the CodePoetry of ZenMondo Wormser"
//////////////////////////

default
{
    link_message(integer sender_num, integer num, string str, key id)
    {
        //The message and url are passed from ZenMondo's URL Go-to-er master
        // Divided by a double colon (::) we split the string by dividing it
        // into two list elements then extracting them as strings.
        // id is the key of the patron making the request also passed from
        // ZenMondo's URL Go-to-er master.
        
        list cmds = llParseString2List(str, ["::"], []); 
       
        string message = llList2String(cmds, 0);
        string url = llList2String(cmds, 1);
        
        llLoadURL(id, message, url);
    }
      
  
}


////////////////////////
// Function GetNewInventoryName by ZenMondo Wormser
// 
// This function returns a list of the names of 
// inventory items added to an object's inventory
// since the last time the function was called.
//
// This function works by keeping a list of inventory items
// and comparing against that list as inventory changes.
//
// NOTE: If items are deleted between calls and nothing is added
// this function will return an empty list.
////////////////////////

list gOld_Inventory;    //This stores the Inventory since the last function call.
                        //It is global so it persists between function calls.
                        //It may also be handy to have a list of your object's inventory.

list GetNewInventoryName()
{
    list found_new = [];  //This list will contain the names of New Inventory items.
    integer inventory_type = INVENTORY_ALL; //Change to look at inventory type you want.
   
    integer inventory_num = llGetInventoryNumber(inventory_type);
   
   
    list new_inventory = []; //This list will contain the current inventory.
    integer counter = 0;
   
    while(counter < inventory_num)
    {
        new_inventory = (new_inventory=[]) + new_inventory + llGetInventoryName(inventory_type, counter);
            counter ++;
    }
    
    integer list_length = llGetListLength(new_inventory);
    
    counter = 0;
    
    list scratch;
    
    while(counter < list_length)
    {
        scratch = llList2List(new_inventory, counter, counter);
        
        if(llListFindList(gOld_Inventory, scratch) == -1) //New Inventory Object
        {
               
               found_new += llList2String(scratch,0); //Add the name of the new inventory item to the found_new list
        }
        
        counter ++;
        
               
    }
    
    gOld_Inventory = new_inventory; //Store the Inventory List to be compared the next time the function is called.
    return found_new;   //Return a list of the new inventory items.
}

default
{
    state_entry()
    {
        GetNewInventoryName(); //Populate the list on reset.
    }

    touch_start(integer num_detected)
    {
        ///////////
        // Example Use in touch_start()
        // Because Multiple Items could have been
        // added between calls we work through 
        // the list that is retunred.
        ///////////
        
        list new_inv = GetNewInventoryName();
            
        llSay(0, "New Inventory Items:");
            
        integer list_len = llGetListLength(new_inv);
            
        integer counter;
            
        for(counter = 0; counter < list_len; counter++)
        {
           llSay(0, llList2String(new_inv, counter));
        } 
    }
    
    changed(integer mask)
    {
        //////////////////
        // Example Used in changed()
        // This is much simpler, as changed()
        // will be triggered each time something
        // is added to the object's inventory
        // resulting in only one result in the
        // returned list from GetNewInventoryName()
        ////////////////////
        
        if(mask & CHANGED_INVENTORY)
        {
            list new_inv = GetNewInventoryName();
            
            llSay(0, "New Inventory Item:" + llList2String(new_inv, 0));
        }
    }
    
}

A simple script to light up a prim in a linkset when touched, and unlight the last one touced using llSetLinkPrimitiveParams

default
{
    

    touch_start(integer total_number)
    {
        llSetPrimitiveParams([PRIM_FULLBRIGHT, ALL_SIDES, TRUE]);
        llSetLinkPrimitiveParams(LINK_ALL_OTHERS, [PRIM_FULLBRIGHT, ALL_SIDES, FALSE]);
        
    }
}


Jasa SEO Murah Jasa SEO Jasa Google Adwords Jasa Adwords Google Adwords Sepatu Safety Sepatu Futsal Cheapes Hostgator Coupon Link Booking Televisori offerte Notebook Offerte Govr Edo Ziedo Portatile Apple RDAnet Lorks Karikatur Bisnis Modal Kecil Bisnis UKM Berita Terbaru Iklan Baris Jasa SEO Murah SEO Indonesia Konsultan SEO SEO Belajar SEO Penumbuh Rambut Kursus SEO Jam Tangan Casio Grosir Baju Bisnis Online Kerupuk Kulit Social Bookmark Kumpulan Puisi WBC Wonogiri Penumbuh Rambut Jam Tangan Murah Jam Tangan Murah Jam Tangan Casio Penumbuh Rambut Kerupuk Kulit Alat Kantor Laku.com Belanja Online Grosir Eceran Murah dan Aman Jasa SEO Model Jilbab Fine Tableware Permanent Hair Removal island investment development professional makeup artist bali private villa sewa mobil jakarta murah Jual rumah Jakarta Contact Lens Technology
There is no comment on this page. [Display comments/form]