大專案中網頁多語系的維護方式

也許在許多專案上我們所說的Multi Language僅有繁體中文、簡體中文和英文,但在比較大型且跨國的專案上,可能會涉及更多的語言,例如:日文、俄文、德文、法文、西班牙文…等等,通常這些軟體內容的翻譯,需要經過更專業的單位來進行,也許這個單位不僅僅需要具備有這些國家的語言能力,也要具備有相當的軟體知識,才能配合當地民情翻譯出正確的文字,這部分往往需要專業的翻譯單位來進行。

而專業的翻譯單位通常並不具有軟體的製作能力,所以在軟體上要如何快速地進行協同作業,就變成一項非常重要的工作,而在許多專案上,我們會讓翻譯單位透過Excel來提供各國語系的翻譯文字,我們則透過軟體進行轉換,將其轉換至軟體能快速讀取的格式,講白一點就是將Excel檔案轉換成XML格式,並提供其他軟體進行讀取。

整體流程會如上圖所示,在拿到一個翻譯社提供所有語系的Excel資料後,我們會進行轉換,將文字轉換成多個XML檔案,並打包成一個ZIP檔讓轉換者進行下載。

今天我們主要來分享上圖藍色部分的處理程序,也就是那一隻轉換程式的結構和做法,我們將轉換程式設計成網頁版本,藉此提升易用性,而轉換程式操作Flow大致如下:

  1. 使用者上傳檔案(限制僅能上傳Excel檔案)
  2. 給出ZIP下載連結(提供使用者下載所有語系的XML檔)

操作上非常簡單,僅有上述這兩個步驟,而程式設計上採用JSP架構其運作邏輯如下:

  1. 檢查上傳檔案的格式、容量及相關資訊
  2. 擷取Excel中第一張工作表(也可以依照工作表名稱擷取)
  3. 將Excel中第一列視為語系標題,並當作存檔名稱(例如:English.xml)
  4. 將剩下來的每一列轉換為該檔案的語系資料,並建立XML檔案
  5. 將所有建立好的XML檔案進行打包(ZIP)
  6. 更新頁面產生ZIP檔下載路徑

在該轉換程式中,另外有利用到下述的JAVA Library:

  1. Apache POI – 處理與解析Excel檔案
  2. DOM4J – 建立XML檔案
  3. Apache Commons – 處理檔案上傳

以下是轉換的程式碼:

<%@ page contentType="text/html; charset=UTF-8"%>

<%@ page import="java.io.File"%>
<%@ page import="java.text.*" %>
<%@ page import="java.util.*" %>
<%@ page import="java.util.Iterator"%>
<%@ page import="java.util.List"%>
<%@ page import="org.apache.commons.fileupload.*"%>
<%@ page import="org.apache.commons.io.FilenameUtils"%>

<%@ page import="java.util.zip.ZipEntry"%>
<%@ page import="java.util.zip.ZipOutputStream"%>

<%@ page import="java.io.FileInputStream"%>
<%@ page import="java.io.FileOutputStream"%>
<%@ page import="java.io.IOException"%>
<%@ page import="java.io.OutputStreamWriter"%>
<%@ page import="java.nio.charset.Charset"%>

<%@ page import="org.apache.poi.hssf.usermodel.HSSFRow"%>
<%@ page import="org.apache.poi.hssf.usermodel.HSSFSheet"%>
<%@ page import="org.apache.poi.hssf.usermodel.HSSFWorkbook"%>

<%@ page import="org.dom4j.io.OutputFormat"%>
<%@ page import="org.dom4j.io.XMLWriter"%>
<%@ page import="org.dom4j.Document"%>
<%@ page import="org.dom4j.DocumentHelper"%>
<%@ page import="org.dom4j.Element"%>


<%!
    //允許上傳的檔案
  String allowedFileTypes = ".xls";
  
  //建立目錄
    public void newFolder(String folderPath) {
        try {
            String filePath = folderPath;
            filePath = filePath.toString();
            java.io.File myFilePath = new java.io.File(filePath);
            if (!myFilePath.exists()) {
                myFilePath.mkdir();
            }
        }
        catch(Exception e) {
            System.out.println("建立目錄錯誤");
            //e.printStackTrace();
        }
    }
   
   // 轉換XLS為XML的主程式 ; 參數1.欲轉換的Excel工作表編號; 參數2.轉換的檔案路徑與檔名; 參數3.XML儲存的檔案路徑;
   public static String convertSheet(int sheetNumber, String conversionFile, String conversionXMLFilePath) {
     
     String convertStatus = "0"; // 輸出轉換狀態 ; 0 是失敗; 1是成功
     String conversionXMLFileName = null; // XML檔名
     String conversionXMLFile = null; // XML完整路徑與檔名
     
     // 產生儲存XML檔案的資料夾
     File file = new File(conversionXMLFilePath);
     if(!file.exists()){
         file.mkdirs();
     }
     
     // 開始讀取XLS檔案
     HSSFWorkbook book = null;
     try {
       book = new HSSFWorkbook(new FileInputStream(conversionFile));
     } catch (IOException e) {
       System.out.println("IOException : " + e);
     }
     
     HSSFSheet sheet = book.getSheetAt(sheetNumber); // 打開對應編號的工作表
     HSSFRow row = sheet.getRow(0);// 取得工作表的第一列資料
     String cell;
     int totalRows = sheet.getPhysicalNumberOfRows(); // 取得工作表中所有的列數
     int totalCol = row.getPhysicalNumberOfCells(); // 取的工作表中所有的欄數
     
     // 開始建立XML檔並將XLS內容建入
     for (int j = 1; j < totalCol; j++){
       Document document = DocumentHelper.createDocument();
       Element root = document.addElement("root");
       
       for (int i = 0; i < totalRows; i++){
         row = sheet.getRow(i);
         try {
           cell = row.getCell(j).toString();
           if(i==0) {
             conversionXMLFileName = cell;
             conversionXMLFile = conversionXMLFilePath + conversionXMLFileName + ".xml";
           }else {
             root.addElement("row_" + (i+1)).addCDATA(cell);
             /*
             if(sheetNumber == 0) {
               root.addElement("tag_" + (i-1), cell);
             }else {
               root.addElement(xmlKeyboardTitle[(i-1)], cell);
             }
             */
           }
         } catch (NullPointerException e) {
           break;
         }
       }
       
       File storedFile = new File(conversionXMLFile);
       
       if(storedFile.exists())
         storedFile.delete();

       FileOutputStream fos = null;
       OutputStreamWriter osw = null;
       XMLWriter writer = null;
       try {
         storedFile.createNewFile();
         OutputFormat format = OutputFormat.createPrettyPrint();  
               format.setEncoding("utf-8");
               fos = new FileOutputStream(storedFile);
               osw = new OutputStreamWriter(fos, Charset.forName("utf-8"));
               writer = new XMLWriter(osw, format);
               writer.write(document);
       } catch (IOException e) {
         System.out.println("IOException : " + e);
       } finally {
         try {
           if(writer != null) writer.close();
           if(osw != null) osw.close();
           if(fos != null) fos.close();
           convertStatus = "1";
         } catch (IOException e) {
           System.out.println("IOException : " + e);
         }
       }
     }
     return convertStatus; // 回覆轉換狀態
   }
   
   List<String> filesListInDir = new ArrayList<String>();
   
   public void zipDirectory(File dir, String zipDirName) {
     
     filesListInDir = new ArrayList<String>();
     
        try {
          
            populateFilesList(dir);
            //now zip files one by one
            //create ZipOutputStream to write to the zip file
            FileOutputStream fos = new FileOutputStream(zipDirName);
            ZipOutputStream zos = new ZipOutputStream(fos);
            for(String filePath : filesListInDir){
                System.out.println("Zipping "+filePath);
                //for ZipEntry we need to keep only relative file path, so we used substring on absolute path
                ZipEntry ze = new ZipEntry(filePath.substring(dir.getAbsolutePath().length()+1, filePath.length()));
                zos.putNextEntry(ze);
                //read the file and write to ZipOutputStream
                FileInputStream fis = new FileInputStream(filePath);
                byte[] buffer = new byte[1024];
                int len;
                while ((len = fis.read(buffer)) > 0) {
                    zos.write(buffer, 0, len);
                }
                zos.closeEntry();
                fis.close();
            }
            zos.close();
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
   
   private void populateFilesList(File dir) throws IOException {
        File[] files = dir.listFiles();
        for(File file : files){
            if(file.isFile()) filesListInDir.add(file.getAbsolutePath());
            else populateFilesList(file);
        }
    }
  
%>

<%

String messageReturn = "";
  
try{
  
    request.setCharacterEncoding("utf-8");
    DiskFileUpload fileUpload = new DiskFileUpload();
  List<FileItem> fileItems = fileUpload.parseRequest(request);
  FileItem fileItem = fileItems.get(0);
  
    //原始上傳檔案名稱
  String originalFileName = fileItem.getName();
    //out.print("originalFileName : " + originalFileName + "<br>");
    
  if (originalFileName != null && !"".equals(originalFileName)) {

        originalFileName = FilenameUtils.getName(originalFileName);
        String extension = FilenameUtils.getExtension(originalFileName);
        
    //判斷檔案格式是否允許
    //out.print("extension : " + extension + "<br>");
        if (allowedFileTypes.indexOf(extension.toLowerCase()) != -1) {
            String filePath = this.getServletContext().getRealPath(request.getRequestURI().substring(request.getContextPath().length()));
            String savePath = new File(filePath).getParent() + "/upload";
          //out.println("savePath = " + savePath + "<br>");
      newFolder(savePath);
      
          String savePathAndName = savePath + "/" + originalFileName;
            //out.print(savePathAndName);
      
          File f = new File(savePathAndName);
          if(!f.exists()){
            f.createNewFile();
          }
          fileItem.write(f);
            
            //messageReturn += "File path : " + savePath + "<br>";
            
             String xmlSavePath = savePath + "/xml/";
             //messageReturn += "xmlSavePath : " + xmlSavePath + "<br>";
            
            if("1".equals(convertSheet(0, savePathAndName , xmlSavePath))){
              messageReturn += "File converted successfully.<br>";
        }else{
          messageReturn += "File conversion failed.<br>";
        };
        
        /*
        xmlSavePath = savePath + "/xml/keyboard/";
        
        if("1".equals(convertSheet(1, savePathAndName , xmlSavePath))){
              messageReturn += "Keyboard sheet conversion succeeded.<br>";
        }else{
          messageReturn += "Keyboard sheet conversion fail.<br>";
        };
        */
      
        java.io.File myDelFile = new java.io.File(savePath + "/All.zip");
        myDelFile.delete();
        
        zipDirectory(new File(savePath + "/xml/"), savePath + "/All.zip");
        
        messageReturn += "<a href='upload/All.zip' target='_blank'>Download Link</a><br>";

        } else {
          messageReturn += "上傳錯誤 : 上傳的檔案不能是" + extension + ",僅允許xls格式<br>";
        }
    }
}catch(Exception e){
  //e.printStackTrace();
}

%>

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>AIOT CC Multi-Language Convertion Tool</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
    <style>
        *{
            font-family: 微軟正黑體;
        }
        h2{
            text-align: center;
        }
        .marginBottom20{
            margin-bottom: 20px;
        }
        #uploadBtn{
            margin: auto;
            display: block;
        }
        #messageDiv{
          color: red;
          text-align:center;
        }
    </style>
</head>

<body>

    <div class="container">
        <h2 class="marginBottom20">AIOT CC Multi-Language Convertion Tool</h2>
        <div class="form-group text-center">
          <form name="upload" enctype="multipart/form-data" method="post" action="index.jsp" onsubmit="return check_select()">
            <input type="file" name="file" id="file" size="60" maxlength="20" placeholder="*.xls" class="marginBottom20">
            <input id="uploadBtn" type="submit" value="轉換" class="btn btn-primary">
        </form>
      </div>
      <div id="messageDiv"><% out.print(messageReturn); %></div>
    </div>
    
</body>

</html>
<script>
    function check_select(form) {
        if (file.value == "") {
            alert("請選擇檔案");
            return false;
        } else {
            // document.getElementById("uploadBtn").disabled = true;
            //document.getElementById("msgDiv").innerHTML = "檔案上傳中,請稍候";
            return true;
        }
    }
</script>

You may also like...

104,615 Responses

  1. Профессиональный сервисный центр по ремонту бытовой техники с выездом на дом.
    Мы предлагаем:сервис центры бытовой техники москва
    Наши мастера оперативно устранят неисправности вашего устройства в сервисе или с выездом на дом!

  2. trimoxazole ds sulfamethoxazole trimethoprim

  3. Профессиональный сервисный центр по ремонту бытовой техники с выездом на дом.
    Мы предлагаем:сервисные центры в москве
    Наши мастера оперативно устранят неисправности вашего устройства в сервисе или с выездом на дом!

  4. Dwayneseisa表示:

    Cialis 20mg price in USA TadalafilEasyBuy.com TadalafilEasyBuy.com

  5. TerryDus表示:

    http://tadalafileasybuy.com/# Buy Tadalafil 5mg

  6. 1xbet_ntPi表示:

    1xbet – лучший выбор для ставок, сейчас же.

    Добро пожаловать в мир ставок с 1xbet, используйте.

    Уникальные бонусы от 1xbet, в ближайшее время.

    Скорее ставьте на свои любимые команды с 1xbet, получайте.

    1xbet – ваш портал в мир лайв-ставок, вы всегда на шаг впереди.

    1xbet – это огромное количество спортивных событий, создавайте.

    1xbet – это выбор на любой вкус, от любимых команд до редких событий.

    1xbet дарит вам возможность следить за играми, сделайте вашу ставку.

    Деньги на вашем счете с 1xbet за считанные минуты, действуйте быстро.

    1xbet – аналитика ставок для вас, поможем вам оставаться в курсе.

    Ставьте с уверенностью на 1xbet, мы ценим вашу конфиденциальность.

    Промокоды и специальные предложения на 1xbet, получайте больше от каждой ставки.

    Выигрывайте и наслаждайтесь с 1xbet, выберите правильный путь.

    Чат поддержки 24/7 на 1xbet, мы рядом, чтобы помочь.

    Регулярные турниры и конкурсы на 1xbet, примите участие.

    Ставьте в любое время и в любом месте с 1xbet, удобно и быстро.

    Ставьте на основе данных с 1xbet, это умная игра.

    Зарегистрируйтесь на 1xbet всего за несколько минут, приступайте к ставкам.

    1xbet – это азарт, который ждет вас, реализуйте свои мечты.

    Не упустите уникальные возможности на 1xbet, ставьте с умом.
    app 1xbet app 1xbet .

  7. Готовы к захватывающей игре? Добро пожаловать в Hype Casino! Здесь вас ждут лучшие слоты, рулетка, покер и блэкджек, а также щедрые поощрения для постоянных игроков. https://kishertskoe.ru/.

    Почему тысячи игроков выбирают Hype Casino?

    Надежные и безопасные финансовые операции без задержек.
    Широкий ассортимент развлечений, включая последние новинки.
    Специальные предложения, улучшающие ваш игровой опыт.

    Регистрируйтесь в Hype Casino и наслаждайтесь игрой без ограничений!

  8. Kennethslity表示:

    http://generic100mgeasy.com/# Generic100mgEasy

  9. Откройте для себя мир азартных игр и удивительных выигрышей в Booi Casino. Мы предлагаем вам разнообразие игр, включая популярные слоты, рулетку, покер и игры с живыми дилерами. Не пропустите акции и бонусы, которые принесут вам дополнительные шансы на выигрыши.

    Почему стоит выбрать Booi Casino? Мы гарантируем безопасность ваших данных и быстрые выплаты. Простой интерфейс и высокий уровень сервиса делают вашу игру максимально комфортной.

    Когда начать свой путь в Booi Casino? Зарегистрируйтесь сейчас и получите сразу же доступ ко всем игровым возможностям и бонусам. Вот что вас ждет:

    Щедрые бонусы для новых игроков.
    Участвуйте в турнирах и получайте шанс выиграть крупные призы.
    Обновления ассортимента игр каждый месяц.

    Каждый момент в Booi Casino — это возможность для большого выигрыша и незабываемых впечатлений. https://koliaskirostov.ru/

  10. 1xbet_bgPi表示:

    1xbet – лучший выбор для ставок, рекомендуем.

    1xbet – ваши ставки под контролем, в интернете.

    Уникальные бонусы от 1xbet, не упустите возможность.

    Скорее ставьте на свои любимые команды с 1xbet, от игры.

    1xbet – ваш портал в мир лайв-ставок, вы всегда на шаг впереди.

    Всё для ваших ставок на 1xbet, и будьте на коне.

    1xbet – это выбор на любой вкус, от спорта до киберспорта.

    Смотрите матчи в режиме реального времени с 1xbet, погрузитесь в атмосферу.

    1xbet – получите свои выигрыши мгновенно, действуйте быстро.

    1xbet – аналитика ставок для вас, будьте всегда на шаг впереди.

    Ставьте с уверенностью на 1xbet, это важно.

    Промокоды и специальные предложения на 1xbet, максимизируйте свой выигрыш.

    Ставьте смело с 1xbet, это ваш шанс на успех.

    1xbet – поддержка, когда она нужна, никогда не оставайтесь в одиночестве.

    1xbet – это не только ставки, но и конкурсы, примите участие.

    1xbet в вашем кармане, удобно и быстро.

    Дайте себе преимущества с 1xbet, анализируйте каждый шаг.

    Зарегистрируйтесь на 1xbet всего за несколько минут, приступайте к ставкам.

    Откройте новый уровень азартных игр с 1xbet, реализуйте свои мечты.

    Не упустите уникальные возможности на 1xbet, развивайте свои навыки.
    ????? ????? 1xbet https://1xbet-login-egypt.com/ .

  11. 1xbet_onPi表示:

    1xbet – лучший выбор для ставок, прямо сейчас.

    Ставки на спорт с 1xbet, эксклюзивные бонусы.

    Получите бонусы на первую ставку с 1xbet, сегодня.

    Скорее ставьте на свои любимые команды с 1xbet, получайте.

    Лайв-ставки с 1xbet – это захватывающе, сделайте каждую секунду важной.

    Всё для ваших ставок на 1xbet, находите.

    1xbet – это выбор на любой вкус, от спорта до киберспорта.

    1xbet – живые трансляции ваших любимых матчей, погрузитесь в атмосферу.

    1xbet – получите свои выигрыши мгновенно, не ждите.

    Обзоры и прогнозы на 1xbet, дайте себе преимущество.

    1xbet – это безопасность и надежность, мы ценим вашу конфиденциальность.

    Скидки и бонусы только для вас с 1xbet, воспользуйтесь шансом.

    Выигрывайте и наслаждайтесь с 1xbet, выберите правильный путь.

    Получите помощь в любое время на 1xbet, вы всегда не одни.

    Регулярные турниры и конкурсы на 1xbet, будьте в курсе событий.

    1xbet в вашем кармане, удобно и быстро.

    Дайте себе преимущества с 1xbet, это умная игра.

    Простая регистрация на 1xbet, доступ к азарту.

    1xbet – это азарт, который ждет вас, попробуйте свои силы.

    1xbet – это место для настоящих игроков, ваш шанс на успех.
    ????? 1xbet https://1xbet-login-egypt.com/ .

  12. TerryDus表示:

    http://tadalafileasybuy.com/# Buy Cialis online

  13. 1xbet_poPi表示:

    1xbet – лучший выбор для ставок, рекомендуем.

    Добро пожаловать в мир ставок с 1xbet, в индустрии.

    Получите бонусы на первую ставку с 1xbet, поспешите воспользоваться.

    Скорее ставьте на свои любимые команды с 1xbet, используйте.

    Присоединяйтесь к 1xbet для живых ставок, вы всегда на шаг впереди.

    Всё для ваших ставок на 1xbet, выбирайте.

    На 1xbet найдётся ставку для каждого, от спорта до киберспорта.

    Смотрите матчи в режиме реального времени с 1xbet, наслаждайтесь просмотром.

    1xbet – получите свои выигрыши мгновенно, открывайте возможности.

    Получите инсайдерскую информацию с 1xbet, будьте всегда на шаг впереди.

    1xbet – это безопасность и надежность, это важно.

    Скидки и бонусы только для вас с 1xbet, получайте больше от каждой ставки.

    1xbet – ваш надежный партнер в мире беттинга, выберите правильный путь.

    Получите помощь в любое время на 1xbet, вы всегда не одни.

    Регулярные турниры и конкурсы на 1xbet, примите участие.

    Ставьте в любое время и в любом месте с 1xbet, удобно и быстро.

    Ставьте на основе данных с 1xbet, это умная игра.

    Простая регистрация на 1xbet, приступайте к ставкам.

    1xbet – это азарт, который ждет вас, реализуйте свои мечты.

    Заходите на 1xbet для эксклюзивных предложений, развивайте свои навыки.
    ????? 1xbet ????? 1xbet .

  14. 1xbet_cwPi表示:

    Откройте для себя мир ставок с 1xbet, прямо сейчас.

    Добро пожаловать в мир ставок с 1xbet, лучшие предложения.

    Получите бонусы на первую ставку с 1xbet, в ближайшее время.

    Скорее ставьте на свои любимые команды с 1xbet, от ставок.

    Лайв-ставки с 1xbet – это захватывающе, вы всегда на шаг впереди.

    1xbet – это огромное количество спортивных событий, свои стратегии.

    Обширные рынки на 1xbet, от футбола до тенниса.

    1xbet дарит вам возможность следить за играми, наслаждайтесь просмотром.

    Деньги на вашем счете с 1xbet за считанные минуты, действуйте быстро.

    Получите инсайдерскую информацию с 1xbet, дайте себе преимущество.

    Ваши данные в безопасности с 1xbet, вы можете быть спокойны.

    Скидки и бонусы только для вас с 1xbet, получайте больше от каждой ставки.

    Выигрывайте и наслаждайтесь с 1xbet, это ваш шанс на успех.

    Чат поддержки 24/7 на 1xbet, вы всегда не одни.

    Участвуйте в конкурсах и выигрывайте с 1xbet, примите участие.

    Ставьте в любое время и в любом месте с 1xbet, всегда под рукой.

    Ставьте на основе данных с 1xbet, будьте стратегом.

    Зарегистрируйтесь на 1xbet всего за несколько минут, приступайте к ставкам.

    1xbet – это азарт, который ждет вас, начните выигрывать.

    Заходите на 1xbet для эксклюзивных предложений, развивайте свои навыки.
    x 1xbet https://1xbet-login-egypt.com/ .

  15. WillieSor表示:

    кракен – kra30.at, кракен вход

  16. WillieSor表示:

    kra at – kra31, Kra30.cc

  17. Профессиональный сервисный центр по ремонту бытовой техники с выездом на дом.
    Мы предлагаем:сервисные центры в москве
    Наши мастера оперативно устранят неисправности вашего устройства в сервисе или с выездом на дом!

  18. 1xbet_kxPi表示:

    Откройте для себя мир ставок с 1xbet, уже сегодня.

    Ставки на спорт с 1xbet, используйте.

    Уникальные бонусы от 1xbet, предложения.

    Скорее ставьте на свои любимые команды с 1xbet, удовольствие.

    1xbet – ваш портал в мир лайв-ставок, сделайте каждую секунду важной.

    1xbet предлагает широкую линейку ставок, и преуспевайте.

    1xbet – это выбор на любой вкус, от любимых команд до редких событий.

    Смотрите матчи в режиме реального времени с 1xbet, погрузитесь в атмосферу.

    Быстрые выводы выигрышей с 1xbet, не ждите.

    Получите инсайдерскую информацию с 1xbet, поможем вам оставаться в курсе.

    Ставьте с уверенностью на 1xbet, это важно.

    Скидки и бонусы только для вас с 1xbet, максимизируйте свой выигрыш.

    1xbet – ваш надежный партнер в мире беттинга, выберите 1xbet для своей игры.

    1xbet – поддержка, когда она нужна, никогда не оставайтесь в одиночестве.

    Участвуйте в конкурсах и выигрывайте с 1xbet, будьте в курсе событий.

    Ставьте в любое время и в любом месте с 1xbet, всегда под рукой.

    Дайте себе преимущества с 1xbet, это умная игра.

    Простая регистрация на 1xbet, не теряйте время.

    1xbet – это ваше окно в мир ставок, реализуйте свои мечты.

    Не упустите уникальные возможности на 1xbet, ваш шанс на успех.
    1xbet ????? ????? https://1xbet-login-egypt.com/ .

  19. GregoryJough表示:

    buy generic 100mg viagra online: Generic100mgEasy – best price for viagra 100mg

  20. WillieSor表示:

    kra30.at – kraken32, kraken32

  21. WilliamNop表示:

    Tadalafil Easy Buy: п»їcialis generic – Tadalafil Easy Buy

  22. 1win_isOi表示:

    зайти в 1вин https://1win6018.ru/ .

  23. ILooklWat表示:

    Нужна арматура оптом в Москве – вам на armatura-v-mosmow.ru за выгодными ценами за метр и тонну.

  24. Dwayneseisa表示:

    Kamagra Kopen kamagra 100mg kopen Kamagra Kopen

  25. TerryDus表示:

    https://kamagrakopen.pro/# kamagra jelly kopen

  26. 1xbet_gtPi表示:

    Откройте для себя мир ставок с 1xbet, рекомендуем.

    1xbet – ваши ставки под контролем, в интернете.

    Уникальные бонусы от 1xbet, обязательно проверьте.

    1xbet – идеальное место для спортивных ставок, адреналин.

    Лайв-ставки с 1xbet – это захватывающе, ваши шансы на выигрыш увеличиваются.

    1xbet предлагает широкую линейку ставок, выбирайте.

    На 1xbet найдётся ставку для каждого, от футбола до тенниса.

    Смотрите матчи в режиме реального времени с 1xbet, наслаждайтесь просмотром.

    1xbet – получите свои выигрыши мгновенно, открывайте возможности.

    Получите инсайдерскую информацию с 1xbet, дайте себе преимущество.

    Ваши данные в безопасности с 1xbet, вы можете быть спокойны.

    Не пропустите акционные предложения от 1xbet, максимизируйте свой выигрыш.

    Ставьте смело с 1xbet, выберите 1xbet для своей игры.

    Получите помощь в любое время на 1xbet, вы всегда не одни.

    Участвуйте в конкурсах и выигрывайте с 1xbet, примите участие.

    1xbet в вашем кармане, всегда под рукой.

    Используйте статистику и аналитику на 1xbet, анализируйте каждый шаг.

    Простая регистрация на 1xbet, приступайте к ставкам.

    1xbet – это ваше окно в мир ставок, попробуйте свои силы.

    1xbet – это место для настоящих игроков, ставьте с умом.
    ????? 1xbet https://1xbet-login-egypt.com/ .

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。