• דף הבית
    • אינדקס קישורים
    • פוסטים אחרונים
    • משתמשים
    • חיפוש בהגדרות המתקדמות
    • חיפוש גוגל בפורום
    • ניהול המערכת
    • ניהול המערכת - שרת private
    • הרשמה
    • התחברות
    1. דף הבית
    2. אריה AI
    3. פוסטים
    א מנותק
    • פרופיל
    • עוקב אחרי 54
    • עוקבים 4
    • נושאים 4
    • פוסטים 114
    • קבוצות 0

    פוסטים

    פוסטים אחרונים הגבוה ביותר שנוי במחלוקת
    • RE: עבודה עם Google Sheets ו-Apps Script מאפס

      @יעקב-יצחק זה לא כל-כך קשור לפורום...

      פורסם בטיפים עצות והדגמות מהמשתמשים
      א
      אריה AI
    • RE: עיוות קול

      @יהודי-מענין כתב:

      תגובה: עיוות קול לא עובד
      אשמח אם מישהו יסביר בצורה ברורה איך העיוות קול עובד,
      האם מגדירים אותו בהקלטות? או בשלוחת השמעת הקבצים?

      בשלוחת ההקלטות...

      פורסם בעזרה הדדית למשתמשים מתקדמים
      א
      אריה AI
    • RE: tts שודרג!

      @זאביק כתב:

      @אריה-AI איזה סוג קול מוגדר אצלך?

      בקול הזה:

      voice=Elik_2100
      tts_voice=Elik_2100
      
      פורסם בשאלות ועזרה הדדית
      א
      אריה AI
    • RE: חדש!!! VoiceMaster אתר קריינות משוכלל!!!

      הספקתי לסדר ממש קצת מהבעיות באתר שלי, בעקבות שיש כאלה שבבין הזמנים יצטרכו את זה העליתי לכאן את הקובץ.
      אחד מהדברים שסודרו זה העיצוב שלא עובד בכל הדרכים...
      תפתחו פנקס רשימות ואז תשמרו את זה על שם index.html ותפתחו אותו...
      בהצלחה!!!!

      <!DOCTYPE html>
      <html lang="he" dir="rtl">
      <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>VoiceMaster AI Studio ✨</title>
          <script src="https://cdn.tailwindcss.com"></script>
          <style>
              @import url('https://fonts.googleapis.com/css2?family=Assistant:wght@300;400;600;700;800&display=swap');
              body { font-family: 'Assistant', sans-serif; background: #f1f5f9; transition: background-color 0.3s ease, color 0.3s ease; }
              .dark-mode { background: #020617; color: #f8fafc; }
              .card { background: white; border: 1px solid #e2e8f0; transition: all 0.3s ease; }
              .dark-mode .card { background: #1e293b; border-color: #334155; }
              .loading-spinner { border: 2px solid rgba(255,255,255,0.3); border-top: 2px solid currentColor; border-radius: 50%; width: 16px; height: 16px; animation: spin 0.8s linear infinite; }
              @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
              .ai-glow { box-shadow: 0 0 25px rgba(99, 102, 241, 0.15); }
              .feature-badge { background: linear-gradient(90deg, #4f46e5, #9333ea); color: white; padding: 2px 8px; border-radius: 99px; font-size: 10px; font-weight: bold; }
              
              /* התאמת רכיבי שמע למכשירים ניידים */
              audio {
                  max-width: 100%;
                  height: 36px;
              }
          </style>
      </head>
      <body class="min-h-screen py-4 sm:py-8 px-3 sm:px-6 md:px-8 transition-colors duration-500" id="bodyTag">
          <div class="max-w-7xl mx-auto">
              <header class="flex flex-wrap justify-between items-center gap-4 mb-6 sm:mb-8 pb-4 border-b border-slate-200 dark:border-slate-800">
                  <div class="flex items-center gap-3 sm:gap-4">
                      <div class="bg-indigo-600 p-2.5 sm:p-3 rounded-2xl text-white shadow-xl flex-shrink-0">
                          <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 sm:h-8 sm:w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 11a7 7 0 01-7 7m0 0a7 7 0 01-7-7m7 7v4m0 0H8m4 0h4m-4-8a3 3 0 01-3-3V5a3 3 0 116 0v6a3 3 0 01-3 3z" />
                          </svg>
                      </div>
                      <div>
                          <h1 class="text-2xl sm:text-3xl font-black text-slate-800 dark:text-white tracking-tight leading-none uppercase">Voice<span class="text-indigo-600">Master</span></h1>
                          <p class="text-[10px] sm:text-xs font-bold text-slate-400 uppercase tracking-widest mt-1">AI Smart Narration Hub</p>
                      </div>
                  </div>
                  
                  <div class="flex items-center gap-2">
                      <div class="relative">
                          <button id="apiKeyBtn" class="p-2.5 sm:p-3 rounded-xl card shadow-sm hover:scale-105 transition-all flex items-center gap-2 text-xs font-bold text-slate-600 dark:text-slate-300">
                              <svg class="w-4 h-4 sm:w-5 sm:h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z"/></svg>
                              <span id="apiKeyStatus" class="hidden sm:inline">הגדר מפתח</span>
                          </button>
                          <div id="apiKeyPopover" class="hidden absolute left-0 sm:left-auto right-0 sm:right-0 mt-2 w-72 sm:w-80 p-4 card rounded-2xl shadow-2xl z-50">
                              <h4 class="font-bold text-sm mb-2 dark:text-white">Gemini API Key</h4>
                              <input id="apiKeyInput" type="password" class="w-full p-2.5 text-xs bg-slate-50 dark:bg-slate-800 rounded-lg border border-slate-200 dark:border-slate-700 outline-none focus:ring-2 focus:ring-indigo-500 mb-2 dark:text-white" placeholder="AIzaSy...">
                              <div class="flex gap-2">
                                  <button id="saveApiKey" class="flex-1 py-2 bg-indigo-600 text-white text-[11px] font-bold rounded-lg hover:bg-indigo-700 active:scale-95 transition-all">שמור מפתח</button>
                                  <button id="clearApiKey" class="flex-1 py-2 bg-red-50 text-red-600 text-[11px] font-bold rounded-lg hover:bg-red-100 active:scale-95 transition-all">מחק</button>
                              </div>
                          </div>
                      </div>
      
                      <button id="toggleDark" class="p-2.5 sm:p-3 rounded-xl card shadow-sm hover:scale-105 active:scale-95 transition-all">
                          <svg class="h-5 w-5 sm:h-6 sm:w-6 text-slate-600 dark:text-indigo-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"/>
                          </svg>
                      </button>
                  </div>
              </header>
      
              <div class="grid grid-cols-1 lg:grid-cols-12 gap-6 lg:gap-8">
                  <div class="lg:col-span-5 space-y-6">
                      <div class="card p-4 sm:p-6 rounded-2xl sm:rounded-[2rem] shadow-lg ai-glow border-indigo-100 dark:border-indigo-900/30">
                          <div class="flex items-center justify-between mb-3 sm:mb-4">
                              <h3 class="font-bold text-sm sm:text-base text-indigo-900 dark:text-indigo-300">יצירת תוכן חכמה</h3>
                          </div>
                          <div class="flex gap-2 mb-3 sm:mb-4">
                              <input id="promptInput" type="text" class="flex-grow p-3 bg-slate-50 dark:bg-slate-800 rounded-xl text-xs sm:text-sm border-none outline-none focus:ring-2 focus:ring-indigo-500 dark:text-white" placeholder="תאר מה לכתוב (למשל: פרסומת לשירות חדש)...">
                              <button id="magicWriteBtn" class="p-3 bg-indigo-600 text-white rounded-xl hover:bg-indigo-700 active:scale-95 transition-all flex items-center justify-center min-w-[48px] sm:min-w-[50px]">
                                  <span id="magicIcon">✨</span>
                                  <div id="magicLoader" class="loading-spinner hidden"></div>
                              </button>
                          </div>
                          <div class="grid grid-cols-2 sm:grid-cols-3 gap-2">
                              <button onclick="smartEdit('הפוך את הטקסט ליותר רגוע ונעים')" class="text-[11px] font-bold py-2 px-1 bg-slate-100 dark:bg-slate-800 rounded-lg hover:bg-indigo-50 dark:hover:bg-indigo-950/40 dark:text-slate-200 active:scale-95 transition-all truncate">✨ ריכוך</button>
                              <button onclick="smartEdit('הפוך את הטקסט ליותר שיווקי ואנרגטי')" class="text-[11px] font-bold py-2 px-1 bg-slate-100 dark:bg-slate-800 rounded-lg hover:bg-indigo-50 dark:hover:bg-indigo-950/40 dark:text-slate-200 active:scale-95 transition-all truncate">✨ שיווקי</button>
                              <button onclick="smartEdit('קצר את הטקסט ב-30% מבלי לאבד משמעות')" class="text-[11px] font-bold py-2 px-1 bg-slate-100 dark:bg-slate-800 rounded-lg hover:bg-indigo-50 dark:hover:bg-indigo-950/40 dark:text-slate-200 active:scale-95 transition-all truncate">✨ קיצור</button>
                              <button onclick="translateText()" class="text-[11px] font-bold py-2 px-1 bg-indigo-50 dark:bg-indigo-900/40 text-indigo-700 dark:text-indigo-300 rounded-lg hover:bg-indigo-100 active:scale-95 transition-all truncate">✨ תרגם לאנגלית</button>
                              <button onclick="generatePodcastScript()" class="text-[11px] font-bold py-2 px-1 bg-indigo-50 dark:bg-indigo-900/40 text-indigo-700 dark:text-indigo-300 rounded-lg hover:bg-indigo-100 active:scale-95 transition-all truncate">✨ תסריט פודקאסט</button>
                              <button onclick="summarizeText()" class="text-[11px] font-bold py-2 px-1 bg-indigo-50 dark:bg-indigo-900/40 text-indigo-700 dark:text-indigo-300 rounded-lg hover:bg-indigo-100 active:scale-95 transition-all truncate">✨ סיכום נקודות</button>
                          </div>
                      </div>
      
                      <div class="card p-4 sm:p-7 rounded-2xl sm:rounded-[2.5rem] shadow-xl border-none">
                          <div class="flex flex-wrap justify-between items-center gap-2 mb-2">
                              <label class="text-xs sm:text-sm font-bold text-slate-500 dark:text-slate-400">טקסט לקריינות</label>
                              <button id="analyzeToneBtn" class="text-[10px] sm:text-[11px] font-bold text-indigo-600 bg-indigo-50 dark:bg-indigo-900/30 px-2.5 py-1 rounded-full hover:bg-indigo-100 active:scale-95 transition-all flex items-center gap-1">
                                  <span>✨ התאם סגנון אוטומטית</span>
                                  <div id="toneLoader" class="loading-spinner hidden !w-3 !h-3"></div>
                              </button>
                          </div>
                          <textarea id="textInput" rows="5" class="w-full p-3 sm:p-4 bg-slate-50 dark:bg-slate-800/50 rounded-xl sm:rounded-2xl outline-none border-2 border-transparent focus:border-indigo-500 transition-all text-base sm:text-lg dark:text-white resize-y" placeholder="הטקסט יופיע כאן..."></textarea>
                          
                          <div class="flex gap-2 mt-3 mb-5">
                              <button id="vocalizeBtn" class="flex-1 py-2.5 sm:py-3 bg-slate-50 dark:bg-slate-800 text-slate-600 dark:text-slate-300 rounded-xl text-xs font-bold hover:bg-indigo-50 dark:hover:bg-indigo-900/20 active:scale-95 transition-all flex items-center justify-center gap-2 border border-slate-100 dark:border-slate-700">
                                  <span>✨ ניקוד אוטומטי</span>
                                  <div id="vocalizeLoader" class="loading-spinner hidden"></div>
                              </button>
                          </div>
      
                          <div class="grid grid-cols-1 sm:grid-cols-2 gap-3 sm:gap-4 mb-6">
                              <div>
                                  <label class="text-[10px] font-bold text-slate-400 uppercase mr-1 block mb-1">קול</label>
                                  <select id="voiceSelect" class="w-full p-3 bg-slate-100 dark:bg-slate-800 dark:text-white rounded-xl text-xs sm:text-sm font-bold border-none outline-none cursor-pointer">
                                      <optgroup label="גברים (Male)">
                                          <option value="Zephyr">Zephyr (קליל)</option>
                                          <option value="Fenrir">Fenrir (עמוק)</option>
                                          <option value="Puck">Puck (שובב)</option>
                                          <option value="Charon">Charon (סמכותי)</option>
                                          <option value="Orus">Orus (קלאסי)</option>
                                          <option value="Enceladus">Enceladus (צעיר)</option>
                                          <option value="Iapetus">Iapetus (חם)</option>
                                          <option value="Algieba">Algieba (נמרץ)</option>
                                          <option value="Rasalgethi">Rasalgethi (בוגר)</option>
                                          <option value="Achernar">Achernar (יציב)</option>
                                          <option value="Alnilam">Alnilam (בהיר)</option>
                                          <option value="Schedar">Schedar (נעים)</option>
                                          <option value="Achird">Achird (שידור)</option>
                                          <option value="Zubenelgenubi">Zubenelgenubi (עמוק מאוד)</option>
                                          <option value="Sadachbia">Sadachbia (רך)</option>
                                          <option value="Sadaltager">Sadaltager (טבעי)</option>
                                          <option value="Sulafat">Sulafat (עוצמתי)</option>
                                      </optgroup>
                                      <optgroup label="נשים (Female)">
                                          <option value="Kore" selected>Kore (מקצועי)</option>
                                          <option value="Leda">Leda (עדין)</option>
                                          <option value="Aoede">Aoede (רך)</option>
                                          <option value="Callirrhoe">Callirrhoe (רהוט)</option>
                                          <option value="Autonoe">Autonoe (אנרגטי)</option>
                                          <option value="Umbriel">Umbriel (מסתורי)</option>
                                          <option value="Despina">Despina (מהיר)</option>
                                          <option value="Erinome">Erinome (ידידותי)</option>
                                          <option value="Algenib">Algenib (חדשותי)</option>
                                          <option value="Laomedeia">Laomedeia (מרגיע)</option>
                                          <option value="Gacrux">Gacrux (אלגנטי)</option>
                                          <option value="Pulcherrima">Pulcherrima (עשיר)</option>
                                          <option value="Vindemiatrix">Vindemiatrix (סבלני)</option>
                                      </optgroup>
                                  </select>
                              </div>
                              <div>
                                  <label class="text-[10px] font-bold text-slate-400 uppercase mr-1 block mb-1">סגנון והגשה</label>
                                  <select id="styleSelect" class="w-full p-3 bg-slate-100 dark:bg-slate-800 dark:text-white rounded-xl text-xs sm:text-sm font-bold border-none outline-none cursor-pointer">
                                      <option value="natural">טבעי (Natural)</option>
                                      <option value="cheerful">שמח (Cheerful)</option>
                                      <option value="serious">רציני (Serious)</option>
                                      <option value="whisper">לחישה (Whisper)</option>
                                      <option value="excited">נרגש (Excited)</option>
                                      <option value="calm">רגוע (Calm)</option>
                                      <option value="authoritative">סמכותי (Authoritative)</option>
                                      <option value="friendly">ידידותי (Friendly)</option>
                                      <option value="professional">מקצועי (Professional)</option>
                                      <option value="storytelling">מספר סיפורים (Storytelling)</option>
                                      <option value="shouting">צעקה (Shouting)</option>
                                      <option value="terrified">מבועת (Terrified)</option>
                                      <option value="sad">עצוב (Sad)</option>
                                      <option value="angry">כועס (Angry)</option>
                                      <option value="hopeful">מלא תקווה (Hopeful)</option>
                                  </select>
                              </div>
                          </div>
      
                          <button id="generateBtn" class="w-full bg-indigo-600 hover:bg-indigo-700 active:scale-[0.98] text-white font-bold py-3.5 sm:py-4 rounded-xl sm:rounded-2xl shadow-lg transition-all flex items-center justify-center gap-3">
                              <span id="btnText" class="text-sm sm:text-base">הפק קריינות עכשיו</span>
                              <div id="btnLoader" class="loading-spinner hidden !border-t-white"></div>
                          </button>
                      </div>
                  </div>
      
                  <div class="lg:col-span-7">
                      <div class="flex justify-between items-center mb-4">
                          <h2 class="text-lg sm:text-xl font-bold dark:text-white">הקלטות אחרונות</h2>
                          <button id="clearTracks" class="text-xs text-slate-400 hover:text-red-500 font-bold transition-colors">נקה הכל</button>
                      </div>
                      <div id="tracksContainer" class="space-y-3 sm:space-y-4">
                          <div id="noTracks" class="text-center py-16 sm:py-24 border-2 border-dashed border-slate-300 dark:border-slate-800 rounded-2xl sm:rounded-[2.5rem] text-slate-400 font-bold text-sm sm:text-base">
                              היסטוריית הקריינות שלך תישמר כאן
                          </div>
                      </div>
                  </div>
              </div>
          </div>
      
          <div id="toast" class="fixed bottom-4 sm:bottom-8 left-4 sm:left-8 right-4 sm:right-auto px-4 sm:px-6 py-3 rounded-xl shadow-2xl opacity-0 transition-all pointer-events-none z-50 transform translate-y-4 flex items-center justify-center sm:justify-start gap-2 max-w-md">
              <span id="toastIcon"></span>
              <span id="toastMessage" class="text-xs sm:text-sm font-semibold"></span>
          </div>
      
          <script>
              // Global State & Config
              let currentApiKey = localStorage.getItem('gemini_api_key') || "";
              const modelText = "gemini-3.5-flash";
              const modelAudio = "gemini-2.5-flash-preview-tts";
      
              const els = {
                  textInput: document.getElementById('textInput'),
                  promptInput: document.getElementById('promptInput'),
                  generateBtn: document.getElementById('generateBtn'),
                  magicWriteBtn: document.getElementById('magicWriteBtn'),
                  analyzeToneBtn: document.getElementById('analyzeToneBtn'),
                  voiceSelect: document.getElementById('voiceSelect'),
                  styleSelect: document.getElementById('styleSelect'),
                  tracksContainer: document.getElementById('tracksContainer'),
                  noTracks: document.getElementById('noTracks'),
                  body: document.getElementById('bodyTag'),
                  toast: document.getElementById('toast'),
                  toastMessage: document.getElementById('toastMessage'),
                  // API Key elements
                  apiKeyBtn: document.getElementById('apiKeyBtn'),
                  apiKeyPopover: document.getElementById('apiKeyPopover'),
                  apiKeyInput: document.getElementById('apiKeyInput'),
                  saveApiKey: document.getElementById('saveApiKey'),
                  clearApiKey: document.getElementById('clearApiKey'),
                  apiKeyStatus: document.getElementById('apiKeyStatus')
              };
      
              // Initialize UI
              function updateApiStatus() {
                  if (currentApiKey) {
                      els.apiKeyStatus.innerText = "מפתח מוגדר ✅";
                      els.apiKeyStatus.classList.add('text-green-600');
                      els.apiKeyInput.value = currentApiKey;
                  } else {
                      els.apiKeyStatus.innerText = "הגדר מפתח ⚠️";
                      els.apiKeyStatus.classList.remove('text-green-600');
                      els.apiKeyInput.value = "";
                  }
              }
              updateApiStatus();
      
              // API Key Popover Toggle
              els.apiKeyBtn.onclick = (e) => {
                  e.stopPropagation();
                  els.apiKeyPopover.classList.toggle('hidden');
              };
      
              els.saveApiKey.onclick = () => {
                  const key = els.apiKeyInput.value.trim();
                  if (key) {
                      currentApiKey = key;
                      localStorage.setItem('gemini_api_key', key);
                      updateApiStatus();
                      els.apiKeyPopover.classList.add('hidden');
                      showToast("מפתח ה-API נשמר בהצלחה", "success");
                  }
              };
      
              els.clearApiKey.onclick = () => {
                  currentApiKey = "";
                  localStorage.removeItem('gemini_api_key');
                  updateApiStatus();
                  showToast("מפתח ה-API נמחק");
              };
      
              document.addEventListener('click', () => els.apiKeyPopover.classList.add('hidden'));
              els.apiKeyPopover.onclick = (e) => e.stopPropagation();
      
              // Utility: API Caller with retry logic
              async function apiCall(model, payload, retries = 5) {
                  if (!currentApiKey) {
                      showToast("אנא הגדר מפתח API בתפריט למעלה");
                      els.apiKeyPopover.classList.remove('hidden');
                      throw new Error("Missing API Key");
                  }
      
                  const url = `https://generativelanguage.googleapis.com/v1beta/models/${model}:${model.includes('tts') ? 'generateContent' : 'generateContent'}?key=${currentApiKey}`;
                  
                  for (let i = 0; i < retries; i++) {
                      try {
                          const response = await fetch(url, {
                              method: 'POST',
                              headers: { 'Content-Type': 'application/json' },
                              body: JSON.stringify(payload)
                          });
                          const data = await response.json();
                          if (response.ok) return data;
                          if (response.status === 429) {
                              await new Promise(r => setTimeout(r, Math.pow(2, i) * 1000));
                          } else if (response.status === 403 || response.status === 401) {
                              showToast("מפתח ה-API אינו תקין");
                              throw new Error("Invalid API Key");
                          } else {
                              throw new Error(data.error?.message || "Communication Error");
                          }
                      } catch (e) {
                          if (i === retries - 1) throw e;
                      }
                  }
              }
      
              function showToast(msg, type = 'error') {
                  els.toastMessage.innerText = msg;
                  els.toast.className = `fixed bottom-4 sm:bottom-8 left-4 sm:left-8 right-4 sm:right-auto px-4 sm:px-6 py-3 rounded-xl shadow-2xl transition-all z-50 transform translate-y-0 opacity-100 ${type === 'error' ? 'bg-red-600' : 'bg-indigo-600'} text-white max-w-md flex items-center justify-center sm:justify-start gap-2`;
                  setTimeout(() => { els.toast.classList.add('opacity-0', 'translate-y-4'); }, 4000);
              }
      
              // --- LLM Features ---
      
              // ✨ Magic Write
              els.magicWriteBtn.onclick = async () => {
                  const prompt = els.promptInput.value.trim();
                  if (!prompt) return showToast("תאר מה לכתוב בתיבה");
                  
                  toggleLoader('magic', true);
                  try {
                      const data = await apiCall(modelText, {
                          contents: [{ parts: [{ text: `כתוב סקריפט קצר ומקצועי לקריינות בעברית עבור הנושא הבא: "${prompt}". החזר רק את הטקסט של הסקריפט ללא הסברים או כותרות.` }] }]
                      });
                      const result = data.candidates?.[0]?.content?.parts?.[0]?.text;
                      if (result) els.textInput.value = result.trim();
                  } catch (e) { if(e.message !== "Missing API Key") showToast(e.message); }
                  toggleLoader('magic', false);
              };
      
              // ✨ Smart Edit
              async function smartEdit(instruction) {
                  const text = els.textInput.value.trim();
                  if (!text) return showToast("הכנס קודם טקסט לתיבה");
                  
                  showToast("מעבד טקסט...", "success");
                  try {
                      const data = await apiCall(modelText, {
                          contents: [{ parts: [{ text: `${instruction} על הטקסט הבא: "${text}". החזר רק את הטקסט המעובד.` }] }]
                      });
                      const result = data.candidates?.[0]?.content?.parts?.[0]?.text;
                      if (result) els.textInput.value = result.trim();
                  } catch (e) { if(e.message !== "Missing API Key") showToast(e.message); }
              }
      
              // ✨ Translate
              async function translateText() {
                  const text = els.textInput.value.trim();
                  if (!text) return showToast("אין טקסט לתרגום");
                  showToast("מתרגם לאנגלית...", "success");
                  try {
                      const data = await apiCall(modelText, {
                          contents: [{ parts: [{ text: `Translate the following text to fluent English suitable for narration: "${text}". Return only the translation.` }] }]
                      });
                      const result = data.candidates?.[0]?.content?.parts?.[0]?.text;
                      if (result) els.textInput.value = result.trim();
                  } catch (e) { if(e.message !== "Missing API Key") showToast(e.message); }
              }
      
              // ✨ Podcast Script
              async function generatePodcastScript() {
                  const topic = els.promptInput.value.trim() || "Technology";
                  showToast("יוצר תסריט פודקאסט...", "success");
                  try {
                      const data = await apiCall(modelText, {
                          contents: [{ parts: [{ text: `Create a short podcast script dialogue between two people about: "${topic}". Return only the dialogue in Hebrew.` }] }]
                      });
                      const result = data.candidates?.[0]?.content?.parts?.[0]?.text;
                      if (result) els.textInput.value = result.trim();
                  } catch (e) { if(e.message !== "Missing API Key") showToast(e.message); }
              }
      
              // ✨ Summarize
              async function summarizeText() {
                  const text = els.textInput.value.trim();
                  if (!text) return showToast("אין טקסט לסיכום");
                  showToast("מסכם לנקודות...", "success");
                  try {
                      const data = await apiCall(modelText, {
                          contents: [{ parts: [{ text: `Summarize the following text into 3 clear key points for narration in Hebrew: "${text}".` }] }]
                      });
                      const result = data.candidates?.[0]?.content?.parts?.[0]?.text;
                      if (result) els.textInput.value = result.trim();
                  } catch (e) { if(e.message !== "Missing API Key") showToast(e.message); }
              }
      
              // ✨ Tone Analysis
              els.analyzeToneBtn.onclick = async () => {
                  const text = els.textInput.value.trim();
                  if (!text) return showToast("אין טקסט לניתוח");
                  
                  toggleLoader('tone', true);
                  try {
                      const data = await apiCall(modelText, {
                          contents: [{ parts: [{ text: `Analyze the sentiment of the following text and pick the best speaking style from this list: (natural, cheerful, serious, whisper, excited, calm, authoritative, friendly, professional, storytelling, shouting, terrified, sad, angry, hopeful). Return ONLY the English word. Text: "${text}"` }] }]
                      });
                      const choice = data.candidates?.[0]?.content?.parts?.[0]?.text?.trim().toLowerCase();
                      if (choice) {
                          const cleanChoice = choice.replace(/[^a-z]/g, '');
                          const option = Array.from(els.styleSelect.options).find(o => o.value === cleanChoice);
                          if (option) {
                              els.styleSelect.value = cleanChoice;
                              showToast(`הסגנון הותאם ל: ${option.text}`, "success");
                          }
                      }
                  } catch (e) { if(e.message !== "Missing API Key") showToast(e.message); }
                  toggleLoader('tone', false);
              };
      
              // ✨ Vocalization (Nikud)
              document.getElementById('vocalizeBtn').onclick = async () => {
                  const text = els.textInput.value.trim();
                  if (!text) return showToast("אין טקסט לניקוד");
                  toggleLoader('vocalize', true);
                  try {
                      const data = await apiCall(modelText, {
                          contents: [{ parts: [{ text: `הוסף ניקוד דקדוקי מלא ומדויק לטקסט הבא בעברית: "${text}". החזר רק את הטקסט המנוקד.` }] }]
                      });
                      const result = data.candidates?.[0]?.content?.parts?.[0]?.text;
                      if (result) els.textInput.value = result.trim();
                  } catch (e) { if(e.message !== "Missing API Key") showToast(e.message); }
                  toggleLoader('vocalize', false);
              };
      
              // --- TTS Core ---
              els.generateBtn.onclick = async () => {
                  const text = els.textInput.value.trim();
                  if (!text) return showToast("הכנס טקסט לקריינות");
                  
                  toggleLoader('btn', true);
                  try {
                      const result = await apiCall(modelAudio, {
                          contents: [{ parts: [{ text: `Say in a ${els.styleSelect.value} style: ${text}` }] }],
                          generationConfig: {
                              responseModalities: ["AUDIO"],
                              speechConfig: { 
                                  voiceConfig: { 
                                      prebuiltVoiceConfig: { 
                                          voiceName: els.voiceSelect.value 
                                      } 
                                  } 
                              }
                          }
                      });
      
                      const pcmData = result.candidates?.[0]?.content?.parts?.[0]?.inlineData?.data;
                      const mimeType = result.candidates?.[0]?.content?.parts?.[0]?.inlineData?.mimeType || "";
                      const sampleRate = parseInt(mimeType.split('rate=')[1]) || 24000;
      
                      if (pcmData) {
                          const blob = pcmToWav(pcmData, sampleRate);
                          addTrack(blob, text.substring(0, 30));
                          showToast("קריינות הופקה בהצלחה!", "success");
                      }
                  } catch (e) { if(e.message !== "Missing API Key") showToast(e.message); }
                  toggleLoader('btn', false);
              };
      
              // --- Helpers ---
              function toggleLoader(key, show) {
                  const l = document.getElementById(key + 'Loader');
                  const i = document.getElementById(key + 'Icon');
                  const t = document.getElementById(key + 'Text');
                  if (l) l.classList.toggle('hidden', !show);
                  if (i) i.classList.toggle('hidden', show);
                  if (t) t.innerText = show ? "מעבד..." : "הפק קריינות עכשיו";
                  if (key === 'btn') els.generateBtn.disabled = show;
              }
      
              function pcmToWav(base64, rate) {
                  const binary = atob(base64);
                  const bytes = new Uint8Array(binary.length);
                  for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
                  const header = new ArrayBuffer(44);
                  const v = new DataView(header);
                  const s = (off, str) => { for (let i = 0; i < str.length; i++) v.setUint8(off + i, str.charCodeAt(i)); };
                  s(0, 'RIFF'); v.setUint32(4, 36 + bytes.length, true); s(8, 'WAVE'); s(12, 'fmt '); v.setUint32(16, 16, true);
                  v.setUint16(20, 1, true); v.setUint16(22, 1, true); v.setUint32(24, rate, true); v.setUint32(28, rate * 2, true);
                  v.setUint16(32, 2, true); v.setUint16(34, 16, true); s(36, 'data'); v.setUint32(40, bytes.length, true);
                  return new Blob([header, bytes], { type: 'audio/wav' });
              }
      
              function addTrack(blob, title) {
                  els.noTracks.classList.add('hidden');
                  const url = URL.createObjectURL(blob);
                  const div = document.createElement('div');
                  div.className = "card p-3 sm:p-4 rounded-xl sm:rounded-2xl flex flex-col sm:flex-row items-start sm:items-center justify-between gap-3 shadow-sm border-slate-100 dark:border-slate-800";
                  div.innerHTML = `
                      <div class="flex-grow w-full sm:w-auto">
                          <div class="font-bold text-xs sm:text-sm truncate dark:text-white">${title}...</div>
                          <div class="text-[10px] text-slate-400 mt-0.5">${els.voiceSelect.value} | ${els.styleSelect.value}</div>
                      </div>
                      <div class="flex items-center justify-between sm:justify-end w-full sm:w-auto gap-2 border-t sm:border-t-0 pt-2 sm:pt-0 border-slate-100 dark:border-slate-800">
                          <audio src="${url}" controls class="w-full sm:w-48"></audio>
                          <a href="${url}" download="voice_${Date.now()}.wav" class="p-2 hover:bg-indigo-50 dark:hover:bg-slate-700 rounded-lg text-indigo-600 flex-shrink-0">
                              <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"/></svg>
                          </a>
                      </div>
                  `;
                  els.tracksContainer.prepend(div);
              }
      
              document.getElementById('toggleDark').onclick = () => els.body.classList.toggle('dark-mode');
              document.getElementById('clearTracks').onclick = () => {
                  els.tracksContainer.querySelectorAll('.card').forEach(c => c.remove());
                  els.noTracks.classList.remove('hidden');
              };
          </script>
      </body>
      </html>
      
      פורסם בעזרה הדדית למשתמשים מתקדמים
      א
      אריה AI
    • RE: תגובות כל כלי הקריינות וה-AI (והטקסט לדיבור) במקום אחד

      @1668 אשמח שתשנה את הקישור למעלה ל-קישור הזה..
      תודה רבה...

      פורסם בשאלות ועזרה הדדית
      א
      אריה AI
    • RE: tts שודרג!

      תודה מיוחדת לחברת @ימות-המשיח על הקול הרובטי החדשני המיוחד...
      היה שווה להמתין...

      עריכה: נכון לעכשיו זה לא תקף...
      זה היה למספר שעות כולנו מקווים שזה יחזור

      פורסם בשאלות ועזרה הדדית
      א
      אריה AI
    • RE: אתר קריינות AI עם הרבה פונקציות כולל הד!!

      @amram כתב:

      למה נטפרי חסמו את זה בגלל הקול הנשי?

      בטוח???,
      ומה עם האתר שלי???
      למה אתה חושב שהוא פתוח???

      פורסם בטיפים עצות והדגמות מהמשתמשים
      א
      אריה AI
    • RE: אתר קריינות AI עם הרבה פונקציות כולל הד!!

      @לימוד-בתורת-מרן אבל זה חסום בנטפרי..

      פורסם בטיפים עצות והדגמות מהמשתמשים
      א
      אריה AI
    • RE: אתר קריינות AI עם הרבה פונקציות כולל הד!!

      @לימוד-בתורת-מרן עדין לא הבאתם את ה-HTML של האתר כי הרי נטפרי...
      חבל על הזמן....
      ⌛⏳⏰

      3a024db3-ac3f-4873-8f9a-98e56d7e4e85-image.jpeg

      פורסם בטיפים עצות והדגמות מהמשתמשים
      א
      אריה AI
    • RE: אתר קריינות AI עם הרבה פונקציות כולל הד!!

      @לימוד-בתורת-מרן כתב:

      ודאגתי גם למי שיש לו חסימה יש קוד html

      איפה זה ה-HTML?????
      כמובן המלא???

      יפה מאוד, אך זה חסום בנטפרי...

      פורסם בטיפים עצות והדגמות מהמשתמשים
      א
      אריה AI
    • RE: תוכנה מעניינת לניהול מערכות

      @IS יש מצב שתעלה את זה לאתר??

      בבקשה...

      פורסם בעזרה הדדית למשתמשים מתקדמים
      א
      אריה AI
    • RE: תוכנה מעניינת לניהול מערכות

      @IS כתב:

      יצרתי תוכנה (בAI) לניהול מערכות, אשמח להערות.
      ידוע לי שישנם כעת כמה באגים שאני באמצע תיקון.
      אשמח לרעיונות נוספים
      התוכנה

      מטורף!!!
      ממש יפה!!!!
      עם איזה AI בנית את זה? עם claude???
      בכל אופן מטורף!!!

      פורסם בעזרה הדדית למשתמשים מתקדמים
      א
      אריה AI
    • RE: חדש!!! VoiceMaster אתר קריינות משוכלל!!!

      @זרח כתב:

      אצלי האתר לא עובד. הוא לא קולט את המפתח api שלי.

      מעניין???

      פורסם בעזרה הדדית למשתמשים מתקדמים
      א
      אריה AI
    • RE: ממשק HTML לאקסס פילטר

      @שלוחה-404 כתב:

      אתמול לראשונה הצטרכתי למודל אקסס פילטר והסתבכתי אם ההגדרות שלו החלטתי לתת לגימיני לבנות ממשק HTML מונגש שמחזיר לך הגדרות לשלוחה
      מצורף קוד HTML בספוילר

      <!DOCTYPE html>
      <html lang="he" dir="rtl">
      <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>מחולל הגדרות מתקדם - פילטר גישה (Access Filter)</title>
          <style>
              :root {
                  --primary-color: #0284c7;
                  --primary-hover: #0369a1;
                  --secondary-color: #f1f5f9;
                  --border-color: #cbd5e1;
                  --text-main: #0f172a;
                  --text-muted: #475569;
                  --bg-main: #ffffff;
                  --card-bg: #f8fafc;
                  --danger: #ef4444;
                  --danger-hover: #dc2626;
                  --success-bg: #1e293b;
                  --success-text: #10b981;
              }
      
              * {
                  box-sizing: border-box;
              }
      
              body {
                  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
                  background-color: var(--secondary-color);
                  color: var(--text-main);
                  margin: 0;
                  padding: 20px;
                  line-height: 1.6;
              }
      
              h1, h2, h3, h4 {
                  color: var(--primary-color);
                  margin-top: 0;
              }
      
              .container {
                  max-width: 1200px;
                  margin: 0 auto;
                  background: var(--bg-main);
                  padding: 40px;
                  border-radius: 12px;
                  box-shadow: 0 4px 20px rgba(0,0,0,0.05);
              }
      
              .section {
                  background: var(--card-bg);
                  border: 1px solid var(--border-color);
                  padding: 25px;
                  border-radius: 10px;
                  margin-bottom: 30px;
              }
      
              .form-group {
                  margin-bottom: 20px;
              }
      
              .grid-2-col {
                  display: grid;
                  grid-template-columns: 1fr 1fr;
                  gap: 25px;
              }
      
              label {
                  display: block;
                  font-weight: 600;
                  margin-bottom: 8px;
                  color: var(--text-main);
              }
      
              .help-text {
                  display: block;
                  font-size: 0.85em;
                  color: var(--text-muted);
                  margin-top: 4px;
              }
      
              input[type="text"], 
              input[type="number"], 
              select, 
              input[type="time"], 
              input[type="date"], 
              input[type="datetime-local"] {
                  width: 100%;
                  padding: 12px;
                  border: 1px solid var(--border-color);
                  border-radius: 6px;
                  font-family: inherit;
                  font-size: 15px;
                  transition: border-color 0.2s;
              }
      
              input[type="text"]:focus, 
              input[type="number"]:focus, 
              select:focus {
                  border-color: var(--primary-color);
                  outline: none;
              }
      
              .checkbox-group {
                  display: flex;
                  flex-wrap: wrap;
                  gap: 12px;
                  background: var(--bg-main);
                  padding: 15px;
                  border: 1px solid var(--border-color);
                  border-radius: 8px;
              }
      
              .checkbox-group label {
                  display: flex;
                  align-items: center;
                  font-weight: normal;
                  background: #e2e8f0;
                  padding: 8px 16px;
                  border-radius: 20px;
                  cursor: pointer;
                  transition: all 0.2s;
                  margin: 0;
                  font-size: 14px;
              }
      
              .checkbox-group label:hover {
                  background: #cbd5e1;
              }
      
              .checkbox-group input[type="checkbox"], 
              .checkbox-group input[type="radio"] {
                  margin-left: 10px;
                  cursor: pointer;
              }
      
              .inline-group {
                  display: flex;
                  align-items: center;
                  gap: 15px;
                  background: var(--bg-main);
                  padding: 12px;
                  border: 1px solid var(--border-color);
                  border-radius: 8px;
              }
      
              .filter-card {
                  background: var(--bg-main);
                  border: 2px solid var(--primary-color);
                  padding: 30px;
                  border-radius: 10px;
                  margin-bottom: 30px;
                  position: relative;
              }
      
              .filter-header {
                  display: flex;
                  justify-content: space-between;
                  align-items: center;
                  border-bottom: 2px solid var(--secondary-color);
                  padding-bottom: 15px;
                  margin-bottom: 25px;
              }
      
              button {
                  cursor: pointer;
                  font-family: inherit;
                  transition: background-color 0.2s;
              }
      
              .primary-btn {
                  background-color: var(--primary-color);
                  color: white;
                  border: none;
                  padding: 14px 28px;
                  border-radius: 8px;
                  font-size: 16px;
                  font-weight: bold;
                  display: inline-flex;
                  align-items: center;
                  gap: 10px;
              }
      
              .primary-btn:hover {
                  background-color: var(--primary-hover);
              }
      
              .danger-btn {
                  background-color: var(--danger);
                  color: white;
                  border: none;
                  padding: 8px 16px;
                  border-radius: 6px;
                  font-size: 14px;
                  font-weight: bold;
              }
      
              .danger-btn:hover {
                  background-color: var(--danger-hover);
              }
      
              .dynamic-fields-container {
                  margin-top: 12px;
                  padding: 15px;
                  background: #e0f2fe;
                  border-radius: 8px;
                  border: 1px dashed #7dd3fc;
                  display: none;
              }
      
              .output-section {
                  background: var(--success-bg);
                  color: var(--success-text);
                  padding: 25px;
                  border-radius: 10px;
                  margin-top: 40px;
              }
      
              textarea {
                  width: 100%;
                  height: 350px;
                  background: #0f172a;
                  color: var(--success-text);
                  border: 1px solid #334155;
                  padding: 20px;
                  font-family: 'Courier New', Courier, monospace;
                  font-size: 16px;
                  resize: vertical;
                  direction: ltr;
                  text-align: left;
                  border-radius: 8px;
              }
          </style>
      </head>
      <body>
      
      <div class="container">
          <h1>מחולל פילטר גישה מורחב (Access Filter)</h1>
          <p>ממשק זה מאפשר יצירה ויזואלית של קובץ ה-<code>ext.ini</code>. סמן את האפשרויות, והקוד יתעדכן בזמן אמת בתחתית העמוד.</p>
      
          <div class="section">
              <h2>הגדרות בסיסיות וניתובים</h2>
              
              <div class="form-group">
                  <label>1. סוג ההטמעה (חובה):</label>
                  <div class="checkbox-group" style="background: transparent; border: none; padding: 0;">
                      <label><input type="radio" name="module_type" value="standalone" checked onchange="updateOutput()"> שלוחה בפני עצמה (type=access_filter)</label>
                      <label><input type="radio" name="module_type" value="embedded" onchange="updateOutput()"> הטמעה בתוך שלוחה אחרת (check_access_filter=yes)</label>
                  </div>
              </div>
      
              <div class="grid-2-col">
                  <div class="form-group">
                      <label>2. הגדרות זיהוי ולוג:</label>
                      <div class="checkbox-group">
                          <label><input type="checkbox" id="enter_id" onchange="updateOutput()"> רישום הגבלות לפי ת.ז (enter_id=yes)</label>
                          <label><input type="checkbox" id="log_save" onchange="updateOutput()"> שמירת קובץ לוג בשלוחה (access_filter_log_save=yes)</label>
                      </div>
                  </div>
      
                  <div class="form-group">
                      <label>3. נתיב שמירת קובץ הלוג (אופציונלי):</label>
                      <input type="text" id="log_folder" placeholder="לדוגמה: /1/1" oninput="updateOutput()" dir="ltr">
                  </div>
      
                  <div class="form-group">
                      <label>4. לאן לעבור אם מאושר (ברירת מחדל):</label>
                      <input type="text" id="yes_goto" placeholder="לדוגמה: /2" oninput="updateOutput()" dir="ltr">
                  </div>
      
                  <div class="form-group">
                      <label>5. לאן לעבור אם נחסם / אין הרשאה:</label>
                      <input type="text" id="no_goto" placeholder="לדוגמה: enter או /3" oninput="updateOutput()" dir="ltr">
                  </div>
              </div>
          </div>
      
          <div id="filters-container"></div>
          
          <button type="button" class="primary-btn" onclick="addFilter()">
              <span>+</span> הוסף תנאי פילטר נוסף (Access Filter Rule)
          </button>
      
          <div class="output-section">
              <h2 style="color: white; margin-top:0;">הקוד שלך (מוכן להעתקה):</h2>
              <textarea id="outputCode" readonly></textarea>
          </div>
      </div>
      
      <script>
          let filterCount = 0;
      
          const daysArray = [
              { val: 'sun', label: 'ראשון' }, { val: 'mon', label: 'שני' }, 
              { val: 'tue', label: 'שלישי' }, { val: 'wed', label: 'רביעי' },
              { val: 'thu', label: 'חמישי' }, { val: 'fri', label: 'שישי' }, 
              { val: 'sat', label: 'שבת' }
          ];
      
          const monthsGregorian = [
              { val: 'jan', label: 'ינואר' }, { val: 'feb', label: 'פברואר' }, 
              { val: 'mar', label: 'מרץ' }, { val: 'apr', label: 'אפריל' },
              { val: 'may', label: 'מאי' }, { val: 'jun', label: 'יוני' },
              { val: 'jul', label: 'יולי' }, { val: 'aug', label: 'אוגוסט' }, 
              { val: 'sep', label: 'ספטמבר' }, { val: 'oct', label: 'אוקטובר' },
              { val: 'nov', label: 'נובמבר' }, { val: 'dec', label: 'דצמבר' }
          ];
      
          const monthsHebrew = [
              { val: '01', label: 'תשרי' }, { val: '02', label: 'חשוון' }, 
              { val: '03', label: 'כסלו' }, { val: '04', label: 'טבת' },
              { val: '05', label: 'שבט' }, { val: '06', label: 'אדר (רגיל)' },
              { val: '07', label: 'ניסן' }, { val: '08', label: 'אייר' }, 
              { val: '09', label: 'סיוון' }, { val: '10', label: 'תמוז' }, 
              { val: '11', label: 'אב' }, { val: '12', label: 'אלול' },
              { val: '13', label: 'אדר א\'' }, { val: '14', label: 'אדר ב\'' }
          ];
      
          function addFilter() {
              filterCount++;
              const id = filterCount;
              
              let daysHtml = daysArray.map(d => `<label><input type="checkbox" class="chk-day-${id}" value="${d.val}" onchange="updateOutput()"> ${d.label}</label>`).join('');
              
              const filterHTML = `
                  <div class="filter-card" id="filter_${id}">
                      <div class="filter-header">
                          <h3>הגדרת זמנים - חוק מס' ${id} (access_filter_${id})</h3>
                          <button class="danger-btn" onclick="removeFilter(${id})">הסר חוק זה</button>
                      </div>
                      
                      <div class="grid-2-col">
                          <div class="form-group">
                              <label>1. סוג תאריך (חובה):</label>
                              <select id="v1_${id}" onchange="toggleCalType(${id}); updateOutput()">
                                  <option value="g">לועזי (g)</option>
                                  <option value="h">עברי (h)</option>
                              </select>
                          </div>
      
                          <div class="form-group">
                              <label>2. טווח שעות ביממה (חובה):</label>
                              <div class="inline-group">
                                  <input type="time" id="t_start_${id}" value="09:00" onchange="updateOutput()"> 
                                  <span>עד</span>
                                  <input type="time" id="t_end_${id}" value="17:00" onchange="updateOutput()">
                                  <label style="margin-right: auto;"><input type="checkbox" id="t_all_${id}" checked onchange="toggleInputs(['t_start_${id}', 't_end_${id}'], this.checked); updateOutput()"> כל היממה (*)</label>
                              </div>
                          </div>
                      </div>
      
                      <div class="form-group">
                          <label>3. ימי שבוע מורשים (חובה):</label>
                          <div class="checkbox-group">${daysHtml}</div>
                          <label style="margin-top:10px; display:inline-block;"><input type="checkbox" checked onchange="toggleCheckboxes('chk-day-${id}', this.checked); updateOutput()"> סמן הכל (*)</label>
                      </div>
      
                      <div class="grid-2-col">
                          <div class="form-group">
                              <label>4. ימים בחודש (חובה):</label>
                              <div class="inline-group">
                                  מיום: <input type="number" id="dm_start_${id}" min="1" max="31" placeholder="1" oninput="updateOutput()">
                                  עד יום: <input type="number" id="dm_end_${id}" min="1" max="31" placeholder="31" oninput="updateOutput()">
                                  <label><input type="checkbox" id="dm_all_${id}" checked onchange="toggleInputs(['dm_start_${id}', 'dm_end_${id}'], this.checked); updateOutput()"> הכל (*)</label>
                              </div>
                          </div>
      
                          <div class="form-group">
                              <label>6. שנות כניסה מורשות (חובה):</label>
                              <div class="inline-group">
                                  משנה: <input type="number" id="y_start_${id}" placeholder="לדוגמה: 2024" oninput="updateOutput()">
                                  עד שנה: <input type="number" id="y_end_${id}" placeholder="לדוגמה: 2025" oninput="updateOutput()">
                                  <label><input type="checkbox" id="y_all_${id}" checked onchange="toggleInputs(['y_start_${id}', 'y_end_${id}'], this.checked); updateOutput()"> הכל (*)</label>
                              </div>
                          </div>
                      </div>
      
                      <div class="form-group">
                          <label>5. חודשים מורשים בשנה (חובה):</label>
                          <div class="checkbox-group" id="months_container_${id}"></div>
                          <label style="margin-top:10px; display:inline-block;"><input type="checkbox" checked onchange="toggleCheckboxes('chk-month-${id}', this.checked); updateOutput()"> בחר כל השנה (*)</label>
                      </div>
      
                      <hr style="border:0; border-top:2px dashed var(--border-color); margin: 30px 0;">
                      <h3 style="margin-top:0;">הגבלות זמן מתקדמות לפי היסטוריית המשתמש (ערכים 7 עד 10)</h3>
                      
                      <div class="grid-2-col">
                          <div class="form-group">
                              <label>7. זמן המתנה בין כניסות (מתי ייתן לעבור שוב):</label>
                              <select id="v7_${id}" onchange="renderDynamicUi(this.value, 7, ${id}); updateOutput()">
                                  <option value="">פעם אחת בכל שיחה - ברירת מחדל (thiscall)</option>
                                  <option value="duration">משך זמן קצוב (שעות / ימים / חודשים)</option>
                                  <option value="datetime">עד תאריך ושעה מדויקים</option>
                                  <option value="date">עד תאריך ספציפי בחצות</option>
                                  <option value="time">היום עד שעה ספציפית</option>
                                  <option value="thisweek">עד סוף השבוע הנוכחי</option>
                                  <option value="thismonth">עד סוף חודש לועזי נוכחי</option>
                                  <option value="thismonth-x">עד יום ספציפי בחודש לועזי</option>
                                  <option value="thishebmonth">עד סוף חודש עברי נוכחי</option>
                                  <option value="thishebmonth-x">עד יום ספציפי בחודש עברי</option>
                                  <option value="23:59:59">עד סוף היום הנוכחי - חצות</option>
                                  <option value="none">חסימה קבועה לאחר כניסה (none)</option>
                              </select>
                              <div id="dyn_7_${id}" class="dynamic-fields-container"></div>
                          </div>
      
                          <div class="form-group">
                              <label>8. כמות כניסות מקסימלית למשתמש:</label>
                              <select id="v8_${id}" onchange="renderDynamicUi(this.value, 8, ${id}); updateOutput()">
                                  <option value="">פעם אחת בלבד (ברירת מחדל)</option>
                                  <option value="*">ללא הגבלת כמות פעמים (*)</option>
                                  <option value="custom">מספר כניסות מוגדר מראש</option>
                              </select>
                              <div id="dyn_8_${id}" class="dynamic-fields-container"></div>
                          </div>
      
                          <div class="form-group">
                              <label>9. איפוס הספירה (מתי יתחיל לספור מחדש?):</label>
                              <select id="v9_${id}" onchange="renderDynamicUi(this.value, 9, ${id}); updateOutput()">
                                  <option value="">אחרי חודש מהכניסה הראשונה (ברירת מחדל)</option>
                                  <option value="*">אחרי 12 חודשים / שנה (*)</option>
                                  <option value="duration">איפוס לאחר משך זמן קצוב (שעות / ימים / חודשים)</option>
                                  <option value="datetime">איפוס בתאריך ושעה מדויקים</option>
                                  <option value="date">איפוס בתאריך ספציפי בחצות</option>
                                  <option value="time">איפוס כל יום בשעה ספציפית</option>
                                  <option value="thisweek">איפוס בסוף השבוע הנוכחי</option>
                                  <option value="thismonth">איפוס בסוף חודש לועזי נוכחי</option>
                                  <option value="thismonth-x">איפוס ביום ספציפי בחודש לועזי</option>
                                  <option value="thishebmonth">איפוס בסוף חודש עברי נוכחי</option>
                                  <option value="thishebmonth-x">איפוס ביום ספציפי בחודש עברי</option>
                                  <option value="23:59:59">איפוס בסוף היום הנוכחי - חצות</option>
                                  <option value="none">ללא איפוס בכלל (none)</option>
                              </select>
                              <div id="dyn_9_${id}" class="dynamic-fields-container"></div>
                          </div>
      
                          <div class="form-group">
                              <label>10. זמן חסימה מוחלטת לשלוחה:</label>
                              <select id="v10_${id}" onchange="renderDynamicUi(this.value, 10, ${id}); updateOutput()">
                                  <option value="">ללא חסימה מוחלטת (ברירת מחדל)</option>
                                  <option value="duration">חסימה לאחר משך זמן קצוב מהכניסה הראשונה</option>
                                  <option value="datetime">חסימה מתאריך ושעה מדויקים</option>
                                  <option value="date">חסימה מתאריך ספציפי בחצות</option>
                                  <option value="time">חסימה היום משעה ספציפית</option>
                                  <option value="thisweek">חסימה בסוף השבוע בו בוצעה הכניסה</option>
                                  <option value="thismonth">חסימה בסוף החודש הלועזי הנוכחי</option>
                                  <option value="thismonth-x">חסימה ביום ספציפי בחודש לועזי</option>
                                  <option value="thishebmonth">חסימה בסוף החודש העברי הנוכחי</option>
                                  <option value="thishebmonth-x">חסימה ביום ספציפי בחודש עברי</option>
                                  <option value="23:59:59">חסימה מוחלטת בסוף היום (חצות)</option>
                              </select>
                              <div id="dyn_10_${id}" class="dynamic-fields-container"></div>
                          </div>
                      </div>
                      
                      <div class="form-group" style="margin-top:20px; background: var(--secondary-color); padding: 15px; border-radius: 8px;">
                          <label>ניתוב ספציפי (Divert) לעומדים בתנאי של חוק זה:</label>
                          <input type="text" id="spec_goto_${id}" placeholder="לדוגמה: /5 (ידרוס את הניתוב הכללי למאשרים)" oninput="updateOutput()" dir="ltr">
                      </div>
                  </div>
              `;
              
              document.getElementById('filters-container').insertAdjacentHTML('beforeend', filterHTML);
              
              toggleCalType(id);
              toggleInputs([`t_start_${id}`, `t_end_${id}`], true);
              toggleInputs([`dm_start_${id}`, `dm_end_${id}`], true);
              toggleInputs([`y_start_${id}`, `y_end_${id}`], true);
              
              updateOutput();
          }
      
          function removeFilter(id) {
              document.getElementById(`filter_${id}`).remove();
              updateOutput();
          }
      
          function toggleCalType(id) {
              const type = document.getElementById(`v1_${id}`).value;
              const container = document.getElementById(`months_container_${id}`);
              const activeArray = type === 'g' ? monthsGregorian : monthsHebrew;
              
              container.innerHTML = activeArray.map(m => 
                  `<label><input type="checkbox" class="chk-month-${id}" value="${m.val}" onchange="updateOutput()"> ${m.label}</label>`
              ).join('');
              
              toggleCheckboxes(`chk-month-${id}`, true);
          }
      
          function toggleInputs(ids, disable) {
              ids.forEach(id => { 
                  const el = document.getElementById(id); 
                  if(el) {
                      el.disabled = disable; 
                      if(disable) el.value = ''; 
                  }
              });
          }
      
          function toggleCheckboxes(className, isChecked) {
              document.querySelectorAll(`.${className}`).forEach(cb => { 
                  cb.checked = isChecked; 
                  cb.disabled = isChecked; 
              });
          }
      
          function renderDynamicUi(type, fieldNum, id) {
              const container = document.getElementById(`dyn_${fieldNum}_${id}`);
              
              if (!type || ['*', 'thiscall', 'thisweek', 'thismonth', 'thishebmonth', '23:59:59', 'none'].includes(type)) {
                  container.style.display = 'none';
                  container.innerHTML = '';
                  return;
              }
              
              container.style.display = 'block';
              
              if (type === 'duration') {
                  container.innerHTML = `
                      <div class="inline-group" style="border:none; padding:0; background:transparent;">
                          <input type="number" id="dyn_val_${fieldNum}_${id}" min="1" placeholder="כמות" style="width:120px;" oninput="updateOutput()">
                          <select id="dyn_unit_${fieldNum}_${id}" onchange="updateOutput()">
                              <option value="s">שניות (s)</option>
                              <option value="m">דקות (m)</option>
                              <option value="h">שעות (h)</option>
                              <option value="d">ימים (d)</option>
                              <option value="M">חודשים (M)</option>
                          </select>
                      </div>`;
              } else if (type === 'datetime') {
                  container.innerHTML = `<input type="datetime-local" id="dyn_val_${fieldNum}_${id}" step="1" oninput="updateOutput()">`;
              } else if (type === 'date') {
                  container.innerHTML = `<input type="date" id="dyn_val_${fieldNum}_${id}" oninput="updateOutput()">`;
              } else if (type === 'time') {
                  container.innerHTML = `<input type="time" id="dyn_val_${fieldNum}_${id}" step="1" oninput="updateOutput()">`;
              } else if (type === 'thismonth-x' || type === 'thishebmonth-x') {
                  let maxDays = type === 'thismonth-x' ? 31 : 30;
                  container.innerHTML = `
                      <div class="inline-group" style="border:none; padding:0; background:transparent;">
                          יום ספציפי בחודש: <input type="number" id="dyn_val_${fieldNum}_${id}" min="1" max="${maxDays}" placeholder="1" style="width:100px;" oninput="updateOutput()">
                      </div>`;
              } else if (type === 'custom') {
                  container.innerHTML = `<input type="number" id="dyn_val_${fieldNum}_${id}" min="1" placeholder="הכנס מספר מדוייק..." oninput="updateOutput()">`;
              }
          }
      
          function calculateRangeFromCheckboxes(className, masterArray) {
              const checkboxes = document.querySelectorAll(`.${className}:not(:disabled)`);
              if(checkboxes.length === 0) return '*'; 
              
              let checkedIndices = [];
              checkboxes.forEach((cb, index) => { 
                  if(cb.checked) checkedIndices.push(index); 
              });
              
              if(checkedIndices.length === 0) return '*';
              
              const minIndex = Math.min(...checkedIndices);
              const maxIndex = Math.max(...checkedIndices);
              
              if (minIndex === maxIndex) {
                  return `${masterArray[minIndex].val}-${masterArray[minIndex].val}`;
              }
              return `${masterArray[minIndex].val}-${masterArray[maxIndex].val}`;
          }
      
          function formatNumberRange(startId, endId, allCheckboxId) {
              if (document.getElementById(allCheckboxId).checked) return '*';
              
              const startVal = document.getElementById(startId).value;
              const endVal = document.getElementById(endId).value;
              
              if (!startVal && !endVal) return '*';
              
              const pad = (num) => (num && num.length === 1) ? '0' + num : num;
              
              if (startVal && !endVal) return `${pad(startVal)}-${pad(startVal)}`;
              if (!startVal && endVal) return `${pad(endVal)}-${pad(endVal)}`;
              
              return `${pad(startVal)}-${pad(endVal)}`;
          }
      
          function getDynamicFieldValue(fieldNum, id) {
              const selectType = document.getElementById(`v${fieldNum}_${id}`).value;
              
              if (!selectType) return "*"; 
              if (['*', 'thiscall', 'thisweek', 'thismonth', 'thishebmonth', '23:59:59', 'none'].includes(selectType)) {
                  return selectType;
              }
              
              const inputEl = document.getElementById(`dyn_val_${fieldNum}_${id}`);
              if (!inputEl || !inputEl.value) return "*";
      
              if (selectType === 'duration') {
                  const unit = document.getElementById(`dyn_unit_${fieldNum}_${id}`).value;
                  return inputEl.value + unit;
              } else if (selectType === 'datetime') {
                  let dt = inputEl.value.replace('T', ' ');
                  if (dt.length === 16) dt += ":00"; 
                  return dt;
              } else if (selectType === 'time') {
                  let t = inputEl.value;
                  if (t.length === 5) t += ":00"; 
                  return t;
              } else if (selectType === 'thismonth-x') {
                  return `thismonth-${inputEl.value}`;
              } else if (selectType === 'thishebmonth-x') {
                  return `thishebmonth-${inputEl.value}`;
              } else if (selectType === 'date' || selectType === 'custom') {
                  return inputEl.value;
              }
              
              return "*";
          }
      
          function updateOutput() {
              let code = "";
              
              code += "; --- הגדרות בסיסיות לפילטר ---\n";
              const isStandalone = document.querySelector('input[name="module_type"]:checked').value === 'standalone';
              code += isStandalone ? "type=access_filter\n" : "check_access_filter=yes\n";
              
              if (document.getElementById('enter_id').checked) {
                  code += "enter_id=yes\n";
              }
              
              if (document.getElementById('log_save').checked) {
                  code += "access_filter_log_save=yes\n";
              }
      
              const logFolder = document.getElementById('log_folder').value.trim();
              if (logFolder) {
                  code += `access_filter_log_time_folder=${logFolder}\n`;
              }
              
              const yesGoto = document.getElementById('yes_goto').value.trim();
              if (yesGoto) code += `access_filter_yes_goto=${yesGoto}\n`;
              
              const noGoto = document.getElementById('no_goto').value.trim();
              if (noGoto) code += `access_filter_no_goto=${noGoto}\n`;
              
              code += "\n; --- חוקי הפילטר (זמנים והגבלות) ---\n";
      
              const filterCards = document.querySelectorAll('.filter-card');
              filterCards.forEach((card, index) => {
                  const ruleNumber = index + 1; 
                  const id = card.id.split('_')[1]; 
      
                  const specificGoto = document.getElementById(`spec_goto_${id}`).value.trim();
                  if (specificGoto) {
                      code += `access_filter_${ruleNumber}_yes_goto=${specificGoto}\n`;
                  }
      
                  const v1 = document.getElementById(`v1_${id}`).value; 
                  
                  const v2 = document.getElementById(`t_all_${id}`).checked ? '*' : 
                             `${document.getElementById(`t_start_${id}`).value}-${document.getElementById(`t_end_${id}`).value}`;
                  
                  const v3 = calculateRangeFromCheckboxes(`chk-day-${id}`, daysArray);
                  const v4 = formatNumberRange(`dm_start_${id}`, `dm_end_${id}`, `dm_all_${id}`);
                  
                  const currentMonthsArray = v1 === 'g' ? monthsGregorian : monthsHebrew;
                  const v5 = calculateRangeFromCheckboxes(`chk-month-${id}`, currentMonthsArray);
                  
                  const v6 = formatNumberRange(`y_start_${id}`, `y_end_${id}`, `y_all_${id}`);
                  
                  const v7 = getDynamicFieldValue(7, id);
                  const v8 = getDynamicFieldValue(8, id);
                  const v9 = getDynamicFieldValue(9, id);
                  const v10 = getDynamicFieldValue(10, id);
      
                  let valuesArray = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10];
                  
                  for (let i = 0; i < valuesArray.length; i++) {
                      if (!valuesArray[i] || valuesArray[i] === "" || valuesArray[i] === "-") {
                          valuesArray[i] = "*";
                      }
                  }
      
                  // יצירת השורה עצמה: שים לב לנקודה בסוף המחרוזת כפי שביקשת
                  code += `access_filter_${ruleNumber}=${valuesArray.join('.')}.\n`;
              });
      
              document.getElementById('outputCode').value = code;
          }
      
          window.onload = () => {
              addFilter();
          };
      </script>
      
      </body>
      </html>
      

      אני בדקתי אותו בפונקציות לא מידי מורכבות מי שמשתמש ומבין אשמח לשמוע האם יש דברים לתקן

      מי שיותר נוח לו מצורף קישור לעבודה ישירה

      ממש יפה!!!!
      תודה על הקובץ...

      פורסם בטיפים עצות והדגמות מהמשתמשים
      א
      אריה AI
    • RE: הפניה למערכת אחרת א"א להקיש

      @795702821 כתב:

      הפניה ממערכת למערכת בימות
      ההפניה עובדת

      אך אי אפשר להקיש כלום אחרי שהופנה

      תודה שפתחת על זה נושא,
      יש גם בניהול המערכת במקש 6 לא עובד (בשרת החדש, כמובן:).
      @ימות-המשיח מתי יסדרו את התקלות בשרת החדש

      פורסם בעזרה הדדית למשתמשים מתקדמים
      א
      אריה AI
    • RE: שלוחת API

      @שלוחה-404 כתב:

      האם ייתכן שימות מכינים את השרתים לגבות כסף על מודל API ?

      רק שלא...

      פורסם בעל הפורום
      א
      אריה AI
    • RE: זיהוי דיבור לא עובד במערכות ימות המשיח!!!!!!!!!!!!!!!!

      @חסיד-חזק כתב:

      @אריה-AI
      לא,
      אמרתי זיהוי דיבור מובנה
      ניסיתי גם בקבלת נתונים וגם במכירות וגם ביצירת קבצי TTS

      מעניין...
      אבל איפה הזיהוי דיבור נמצא...

      פורסם בעזרה הדדית למשתמשים מתקדמים
      א
      אריה AI
    • RE: זיהוי דיבור לא עובד במערכות ימות המשיח!!!!!!!!!!!!!!!!

      @חסיד-חזק כתב:

      שימו לב אני מדבר על זיהוי דיבור מובנה מצד מערכות ימות המשיח

      יש לך את התמלול של @איל-משולש האם התכוננת לזה?

      פורסם בעזרה הדדית למשתמשים מתקדמים
      א
      אריה AI
    • RE: תקון השרת החדש

      @אלישבע יש גם בעיה בניתוב למערכת אחרת שההקשות לא עובדות..

      פורסם בבקשות לפיתוח
      א
      אריה AI
    • RE: תגובות | מדריך | איך להוציא שיחות בזיהוי מספר המערכת שלכם - בחינם!

      @CUBASE כתב:

      @אריה-AI מה זה אומר שיש בה הכל? גם ככה תהליך רישום המערכת לצינתוקים לא יכול להתבצע ב-API, והתהליך עצמו של החיוג - אחרי שמגדירים פעם אחת לא אמורים להתעסק עם זה עוד - אז מה כבר תוכל לעשות עם API?

      אז את זה יצטרכו לאשר לבד אבל חוץ מזה אפשר כל הפילטרים... (לאלו שמשתמשים עם זה...)

      פורסם בעזרה הדדית למשתמשים מתקדמים
      א
      אריה AI