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

    שלוחה-404

    @שלוחה-404

    71
    מוניטין
    49
    צפיות בפרופיל
    322
    פוסטים
    3
    עוקבים
    0
    עוקב אחרי
    תאריך הצטרפות
    נראה לאחרונה

    שלוחה-404 הפסקת מעקב מעקב

    הפוסטים הטובים ביותר שנוצרו על ידי שלוחה-404

    • ממשק HTML לאקסס פילטר

      אתמול לראשונה הצטרכתי למודל אקסס פילטר והסתבכתי אם ההגדרות שלו החלטתי לתת לגימיני לבנות ממשק 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>
      

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

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

      פורסם בטיפים עצות והדגמות מהמשתמשים
      ש
      שלוחה-404
    • חיוג מהיר ומסודר למספרים באתרי אינטרנט עם הזיהוי של המערכת שלכם (תוסף לדפדפן)

      בעקבות המדריך המעולה של @cubase כאן, פיתחתי בעזרת ה-AI כלי עזר משלים ונוח במיוחד: סקריפט חכם שהופך כל מספר טלפון שמופיע בדפדפן ללחצן חיוג מהיר!

      ברגע שלוחצים על מספר טלפון בכל אתר אינטרנט, המערכת מחייגת אליכם באופן מיידי, ומעבירה אתכם ישירות לשיחה עם המספר שלחצם עליו מתוך הזיהוי של המערכת שלכם.

      💡 איך זה עובד בדיוק?
      חדש:
      התקנה אוטומטית
      ניתן להתקין בלחיצת כפתור כאן

      התקנה ידנית

      התקנת התוסף: מתקינים את תוסף Tampermonkey מחנות התוספים של הדפדפן (כרום / אדג' וכו').

      הוספת הסקריפט: יוצרים סקריפט חדש בתוסף, מוחקים את הקוד ברירת המחדל שמופיע שם ומדביקים את הקוד המלא המצורף למטה (בתוך הספוילר). שמרו את הקוד (Ctrl + S).

      הגדרות ראשוניות: בפעם הראשונה שתפתחו דף אינטרנט רגיל שיש בו מספרי טלפון, יקפוץ לכם אוטומטית חלון הגדרות מעוצב במרכז המסך. תתבקשו להזין בו:

      טוקן המערכת, @cubase זו שלוחה sistem/A">נתיב שלוחה לעדכון,
      מספר זיהוי יוצא,װ שם רשימת הצינתוקים.

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

      טיפ קטן: רוצים לשנות את ההגדרות בעתיד? לחצו על סמל התוסף בדף פעיל ויופיע לכם כפתור עריכה
      38bd6eda-68a6-47bb-b0d7-187b768aa6d1-image.jpeg

      📜 קוד הסקריפט (להעתקה):

      // ==UserScript==
      // @name         חיוג מהיר ומערכת צינתוקים - ימות המשיח (PRO Security)
      // @namespace    http://tampermonkey.net/
      // @version      2.6.0
      // @description  בחירת מכשיר אישי, בחירת זיהוי יוצא אינטראקטיבית, עדכון שלוחות מקביל וחסימות אבטחה
      // @match        *://*/*
      // @exclude      *://docs.google.com/*
      // @exclude      *://github.com/*
      // @grant        GM_setValue
      // @grant        GM_getValue
      // @grant        GM_registerMenuCommand
      // @grant        GM_xmlhttpRequest
      // @connect      call2all.co.il
      // @updateURL    https://github.com/Extension-404/Speed-dial/raw/refs/heads/main/Speed-dial.user.js
      // @downloadURL  https://github.com/Extension-404/Speed-dial/raw/refs/heads/main/Speed-dial.user.js
      // @run-at       document-idle
      // ==/UserScript==
      
      (function() {
          'use strict';
      
          // ==========================================
          // 1. הגדרות וניהול גרסאות
          // ==========================================
          const CURRENT_VERSION = "2.6.0";
          const CONFIG_KEYS = {
              TOKEN: 'ym_token',
              PATH: 'ym_path',
              CALLER_ID: 'ym_caller_id',
              PROMPT_CALLER_ID: 'ym_prompt_caller_id',
              ALL_APPROVED_IDS: 'ym_all_approved_ids',
              ACTIVE_CALLER_IDS: 'ym_active_ids',
              LIST_NAME: 'ym_list_name',
              // חדש: הגדרות המכשיר האישי
              USER_PATH: 'ym_user_path',
              MY_PHONES: 'ym_my_phones',
              DEFAULT_MY_PHONE: 'ym_default_my_phone',
              PROMPT_MY_PHONE: 'ym_prompt_my_phone',
              VERSION: 'ym_script_version'
          };
      
          function getSettings() {
              return {
                  token: GM_getValue(CONFIG_KEYS.TOKEN, ''),
                  path: GM_getValue(CONFIG_KEYS.PATH, 'ivr2:/'),
                  callerId: GM_getValue(CONFIG_KEYS.CALLER_ID, ''),
                  promptCallerId: GM_getValue(CONFIG_KEYS.PROMPT_CALLER_ID, false),
                  allApprovedIds: JSON.parse(GM_getValue(CONFIG_KEYS.ALL_APPROVED_IDS, '[]')),
                  activeCallerIds: JSON.parse(GM_getValue(CONFIG_KEYS.ACTIVE_CALLER_IDS, '[]')),
                  listName: GM_getValue(CONFIG_KEYS.LIST_NAME, ''),
                  
                  userPath: GM_getValue(CONFIG_KEYS.USER_PATH, ''),
                  myPhones: JSON.parse(GM_getValue(CONFIG_KEYS.MY_PHONES, '[]')),
                  defaultMyPhone: GM_getValue(CONFIG_KEYS.DEFAULT_MY_PHONE, ''),
                  promptMyPhone: GM_getValue(CONFIG_KEYS.PROMPT_MY_PHONE, false)
              };
          }
      
          // מעטפת להבטחת עבודה מהירה ומסודרת מול ימות המשיח (Promise wrapper)
          function ymFetch(url) {
              return new Promise((resolve, reject) => {
                  GM_xmlhttpRequest({
                      method: "GET",
                      url: url,
                      onload: function(response) {
                          if (response.status === 200) {
                              resolve(response.responseText);
                          } else {
                              reject("HTTP Error " + response.status);
                          }
                      },
                      onerror: function() {
                          reject("Network Error");
                      }
                  });
              });
          }
      
          // משיכת מספרי זיהוי יוצא מהשרת
          function fetchApprovedCallerIdsFromApi(token, callback) {
              if (!token) return callback(false, "יש להזין טוקן תחילה!");
              const url = `https://www.call2all.co.il/ym/api/GetApprovedCallerIDs?token=${encodeURIComponent(token)}`;
              
              ymFetch(url).then(res => {
                  const data = JSON.parse(res);
                  let ids = [];
                  if (data.call) {
                      ids = [...(data.call.callerIds || []), ...(data.call.secondaryDids || [])];
                  } else if (Array.isArray(data.callerIds)) {
                      ids = data.callerIds;
                  }
                  ids = [...new Set(ids)].map(id => id.replace(/^(\+)?972/, '0'));
                  
                  if (ids.length > 0) {
                      GM_setValue(CONFIG_KEYS.ALL_APPROVED_IDS, JSON.stringify(ids));
                      callback(true, ids);
                  } else {
                      callback(false, "לא נמצאו מספרים מאושרים בחשבון זה.");
                  }
              }).catch(err => callback(false, "שגיאת תקשורת מול שרתי ימות המשיח."));
          }
      
          // ==========================================
          // 3. ממשק משתמש (UI) - חלון הגדרות מעוצב ומחולק
          // ==========================================
          function openSettingsModal() {
              const existingModal = document.getElementById('ym-settings-modal');
              if (existingModal) existingModal.remove();
      
              const current = getSettings();
              
              let callerIdOptions = `<option value="">-- ברירת מחדל של המערכת --</option>`;
              current.allApprovedIds.forEach(id => {
                  const selected = (id === current.callerId) ? 'selected' : '';
                  callerIdOptions += `<option value="${id}" ${selected}>${id}</option>`;
              });
              if (current.callerId && !current.allApprovedIds.includes(current.callerId)) {
                  callerIdOptions += `<option value="${current.callerId}" selected>${current.callerId} (ידני)</option>`;
              }
      
              const modalHtml = `
                  <div id="ym-settings-modal" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.6); z-index: 999999; display: flex; align-items: center; justify-content: center; font-family: Arial, sans-serif; direction: rtl;">
                      <div style="background: #fff; padding: 25px; border-radius: 12px; width: 480px; max-width: 95%; max-height: 90vh; overflow-y: auto; box-shadow: 0 5px 25px rgba(0,0,0,0.3); text-align: right; position: relative;">
                          <h3 style="margin-top: 0; color: #333; border-bottom: 2px solid #0066cc; padding-bottom: 10px;">⚙️ הגדרות מערכת צינתוקים (PRO)</h3>
                          
                          <label style="display: block; margin-top: 15px; font-weight: bold; font-size: 13px; color: #555;">טוקן המערכת (מוסתר):</label>
                          <div style="position: relative; width: 100%; margin-top: 5px;">
                              <input type="password" id="ym-input-token" value="${current.token}" placeholder="077xxxxxxx:123456" style="width: 100%; padding: 8px; padding-left: 35px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; direction: ltr; text-align: left; font-family: monospace;">
                              <span id="ym-toggle-token" style="position: absolute; left: 10px; top: 50%; transform: translateY(-50%); cursor: pointer; font-size: 16px;" title="הצג/הסתר">👁️</span>
                          </div>
      
                          <label style="display: block; margin-top: 15px; font-weight: bold; font-size: 13px; color: #555;">שם רשימת הצינתוקים - טריגר (חובה):</label>
                          <input type="text" id="ym-input-listname" value="${current.listName}" placeholder="לדוגמה: vip או test" style="width: 100%; padding: 8px; margin-top: 5px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box;">
      
                          <!-- שלב 1: יעד החיוג -->
                          <div style="background: #f8f9fa; padding: 12px; border-radius: 8px; border: 1px solid #e9ecef; margin-top: 15px;">
                              <h4 style="margin: 0 0 10px 0; color: #0056b3; font-size: 14px;">📞 שלב 1: יעדי החיוג (למי מתקשרים)</h4>
                              
                              <label style="display: block; font-weight: bold; font-size: 12px; color: #555;">נתיב שלוחת היעד לעדכון (ניתוביה):</label>
                              <input type="text" id="ym-input-path" value="${current.path}" placeholder="ivr2:/ או /" style="width: 100%; padding: 8px; margin-top: 5px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; direction: ltr; text-align: left;">
      
                              <label style="display: block; margin-top: 10px; font-weight: bold; font-size: 12px; color: #555;">זיהוי יוצא קבוע (Caller ID):</label>
                              <div style="display: flex; gap: 5px; margin-top: 5px;">
                                  <select id="ym-select-callerid" style="flex-grow: 1; padding: 8px; border: 1px solid #ccc; border-radius: 4px; background: #fff; font-size: 14px;">
                                      ${callerIdOptions}
                                  </select>
                                  <button id="ym-btn-fetch-ids" style="background: #17a2b8; color: #fff; border: none; padding: 0 12px; border-radius: 4px; cursor: pointer; font-weight: bold; font-size: 12px; white-space: nowrap;">🔄 מול ימות</button>
                              </div>
      
                              <label style="display: flex; align-items: center; cursor: pointer; font-weight: bold; font-size: 12px; color: #0056b3; margin-top: 10px;">
                                  <input type="checkbox" id="ym-check-prompt" ${current.promptCallerId ? 'checked' : ''} style="margin-left: 8px; width: 16px; height: 16px;">
                                  🔔 שאל אותי באיזה זיהוי יוצא להשתמש לפני כל חיוג
                              </label>
                              
                              <div id="ym-pool-container" style="display: ${current.promptCallerId ? 'block' : 'none'}; margin-top: 10px; padding-top: 8px; border-top: 1px dashed #ccc;">
                                  <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px;">
                                      <span style="font-size: 11px; color: #555; font-weight: bold;">📋 בחר אילו מספרים יופיעו בחלון לבחירה מהירה:</span>
                                      <div style="display: flex; gap: 4px;">
                                          <button type="button" id="ym-btn-select-all" style="background: #e2e3e5; border: 1px solid #ccc; padding: 2px 6px; border-radius: 4px; font-size: 11px; cursor: pointer; font-weight: bold;">☑️ בחר הכל</button>
                                          <button type="button" id="ym-btn-clear-all" style="background: #e2e3e5; border: 1px solid #ccc; padding: 2px 6px; border-radius: 4px; font-size: 11px; cursor: pointer; font-weight: bold;">⬜ נקה</button>
                                      </div>
                                  </div>
                                  <div id="ym-checkbox-list" style="max-height: 100px; overflow-y: auto; background: #fff; border: 1px solid #ddd; padding: 6px; border-radius: 6px; display: grid; grid-template-columns: 1fr 1fr; gap: 6px;"></div>
                              </div>
                          </div>
      
                          <!-- שלב 2: המכשיר האישי -->
                          <div style="background: #e6f2ff; padding: 12px; border-radius: 8px; border: 1px solid #b8daff; margin-top: 15px;">
                              <h4 style="margin: 0 0 10px 0; color: #004085; font-size: 14px;">📱 שלב 2: המכשיר שלך (לאן המערכת תחייג אליך)</h4>
                              
                              <label style="display: block; font-weight: bold; font-size: 12px; color: #555;">נתיב שלוחה לעדכון הטלפון שלך (אופציונלי):</label>
                              <input type="text" id="ym-input-user-path" value="${current.userPath}" placeholder="לדוגמה: ivr2:/my_phone" style="width: 100%; padding: 8px; margin-top: 5px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; direction: ltr; text-align: left;">
                              
                              <label style="display: block; margin-top: 10px; font-weight: bold; font-size: 12px; color: #555;">רשימת המכשירים שלך (מופרדים בפסיק):</label>
                              <input type="text" id="ym-input-my-phones" value="${current.myPhones.join(', ')}" placeholder="0501234567, 0771234567" style="width: 100%; padding: 8px; margin-top: 5px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box;">
                              
                              <label style="display: block; margin-top: 10px; font-weight: bold; font-size: 12px; color: #555;">מכשיר ברירת מחדל אליך:</label>
                              <select id="ym-select-default-my-phone" style="width: 100%; padding: 8px; margin-top: 5px; border: 1px solid #ccc; border-radius: 4px; background: #fff; font-size: 14px;"></select>
                              
                              <label style="display: flex; align-items: center; cursor: pointer; font-weight: bold; font-size: 12px; color: #004085; margin-top: 10px;">
                                  <input type="checkbox" id="ym-check-prompt-my-phone" ${current.promptMyPhone ? 'checked' : ''} style="margin-left: 8px; width: 16px; height: 16px;">
                                  🔔 שאל אותי לאיזה מכשיר לחייג אליי לפני כל שיחה
                              </label>
                          </div>
      
                          <div style="margin-top: 25px; display: flex; justify-content: space-between;">
                              <button id="ym-btn-save" style="background: #28a745; color: #fff; border: none; padding: 10px 20px; border-radius: 5px; cursor: pointer; font-weight: bold; flex-grow: 1; margin-left: 10px;">💾 שמור הגדרות</button>
                              <button id="ym-btn-close" style="background: #dc3545; color: #fff; border: none; padding: 10px 15px; border-radius: 5px; cursor: pointer; font-weight: bold;">ביטול</button>
                          </div>
                          <div id="ym-save-status" style="margin-top: 10px; text-align: center; font-weight: bold; font-size: 14px; min-height: 20px;"></div>
                      </div>
                  </div>
              `;
      
              document.body.insertAdjacentHTML('beforeend', modalHtml);
      
              // רינדור רשימות המספרים
              function renderCheckboxList(allIds, activeIds) {
                  const container = document.getElementById('ym-checkbox-list');
                  if (allIds.length === 0) {
                      container.style.gridTemplateColumns = "1fr";
                      container.innerHTML = `<div style="color: #dc3545; font-size: 12px;">לא נמצאו מספרים במאגר. לחץ על "🔄 מול ימות".</div>`;
                      return;
                  }
                  container.style.gridTemplateColumns = "1fr 1fr";
                  container.innerHTML = allIds.map(id => {
                      const isChecked = activeIds.includes(id) ? 'checked' : '';
                      return `
                          <label style="display: flex; align-items: center; font-size: 12px; color: #333; background: #f1f3f5; padding: 4px 6px; border-radius: 4px; cursor: pointer; user-select: none;">
                              <input type="checkbox" class="ym-pool-item" value="${id}" ${isChecked} style="margin-left: 6px; cursor: pointer;">
                              <span style="direction: ltr;">${id}</span>
                          </label>
                      `;
                  }).join('');
              }
      
              function populateMyPhonesSelect() {
                  const inputVal = document.getElementById('ym-input-my-phones').value;
                  const phones = inputVal.split(',').map(p => p.trim()).filter(p => p);
                  const select = document.getElementById('ym-select-default-my-phone');
                  const currentVal = select.value || current.defaultMyPhone;
                  
                  select.innerHTML = '<option value="">-- בחר מכשיר אישי --</option>' + 
                      phones.map(p => `<option value="${p}" ${p === currentVal ? 'selected' : ''}>${p}</option>`).join('');
              }
      
              renderCheckboxList(current.allApprovedIds, current.activeCallerIds);
              document.getElementById('ym-input-my-phones').addEventListener('input', populateMyPhonesSelect);
              populateMyPhonesSelect();
      
              // מאזיני לחיצות
              document.getElementById('ym-btn-select-all').addEventListener('click', () => document.querySelectorAll('.ym-pool-item').forEach(cb => cb.checked = true));
              document.getElementById('ym-btn-clear-all').addEventListener('click', () => document.querySelectorAll('.ym-pool-item').forEach(cb => cb.checked = false));
              
              document.getElementById('ym-check-prompt').addEventListener('change', function() {
                  document.getElementById('ym-pool-container').style.display = this.checked ? 'block' : 'none';
              });
      
              document.getElementById('ym-toggle-token').addEventListener('click', function() {
                  const input = document.getElementById('ym-input-token');
                  input.type = (input.type === 'password') ? 'text' : 'password';
                  this.innerText = (input.type === 'password') ? '👁️' : '🔒';
              });
      
              document.getElementById('ym-btn-close').addEventListener('click', () => document.getElementById('ym-settings-modal').remove());
      
              document.getElementById('ym-btn-fetch-ids').addEventListener('click', function() {
                  const token = document.getElementById('ym-input-token').value.trim();
                  const statusEl = document.getElementById('ym-save-status');
                  this.innerText = "⏳"; this.disabled = true;
      
                  fetchApprovedCallerIdsFromApi(token, (success, result) => {
                      this.innerText = "🔄 מול ימות"; this.disabled = false;
                      if (success) {
                          const selectEl = document.getElementById('ym-select-callerid');
                          const currentVal = selectEl.value;
                          selectEl.innerHTML = `<option value="">-- ברירת מחדל --</option>` + 
                              result.map(id => `<option value="${id}" ${id === currentVal ? 'selected' : ''}>${id}</option>`).join('');
                          renderCheckboxList(result, []);
                          statusEl.style.color = 'green';
                          statusEl.innerText = '✅ המספרים סונכרונו! בחר כעת את המספרים הרצויים ב-V.';
                      } else {
                          statusEl.style.color = 'red'; statusEl.innerText = '❌ ' + result;
                      }
                  });
              });
      
              document.getElementById('ym-btn-save').addEventListener('click', () => {
                  const token = document.getElementById('ym-input-token').value.trim();
                  const path = document.getElementById('ym-input-path').value.trim();
                  const callerId = document.getElementById('ym-select-callerid').value;
                  const promptCallerId = document.getElementById('ym-check-prompt').checked;
                  const listName = document.getElementById('ym-input-listname').value.trim();
                  
                  const userPath = document.getElementById('ym-input-user-path').value.trim();
                  const myPhonesArr = document.getElementById('ym-input-my-phones').value.split(',').map(p => p.trim()).filter(p => p);
                  const defaultMyPhone = document.getElementById('ym-select-default-my-phone').value;
                  const promptMyPhone = document.getElementById('ym-check-prompt-my-phone').checked;
      
                  const selectedActiveIds = [];
                  document.querySelectorAll('.ym-pool-item:checked').forEach(cb => selectedActiveIds.push(cb.value));
      
                  if (!token || !listName || !path) {
                      document.getElementById('ym-save-status').style.color = 'red';
                      document.getElementById('ym-save-status').innerText = '❌ יש למלא טוקן, נתיב מטרה ושם רשימה!';
                      return;
                  }
      
                  GM_setValue(CONFIG_KEYS.TOKEN, token);
                  GM_setValue(CONFIG_KEYS.PATH, path);
                  GM_setValue(CONFIG_KEYS.CALLER_ID, callerId);
                  GM_setValue(CONFIG_KEYS.PROMPT_CALLER_ID, promptCallerId);
                  GM_setValue(CONFIG_KEYS.ACTIVE_CALLER_IDS, JSON.stringify(selectedActiveIds));
                  GM_setValue(CONFIG_KEYS.LIST_NAME, listName);
                  
                  GM_setValue(CONFIG_KEYS.USER_PATH, userPath);
                  GM_setValue(CONFIG_KEYS.MY_PHONES, JSON.stringify(myPhonesArr));
                  GM_setValue(CONFIG_KEYS.DEFAULT_MY_PHONE, defaultMyPhone);
                  GM_setValue(CONFIG_KEYS.PROMPT_MY_PHONE, promptMyPhone);
                  
                  GM_setValue(CONFIG_KEYS.VERSION, CURRENT_VERSION);
      
                  document.getElementById('ym-save-status').style.color = 'green';
                  document.getElementById('ym-save-status').innerText = '✅ ההגדרות נשמרו בהצלחה!';
      
                  setTimeout(() => document.getElementById('ym-settings-modal').remove(), 1200);
              });
          }
      
          GM_registerMenuCommand("⚙️ הגדרות חיוג מהיר (ימות המשיח)", openSettingsModal);
      
          // ==========================================
          // 4. חלון בחירה מהיר חכם (Smart Quick Dial Modal)
          // ==========================================
          function openQuickDialModal(phoneNumber, targetElement, onExecute) {
              const config = getSettings();
              const existingModal = document.getElementById('ym-quick-dial-modal');
              if (existingModal) existingModal.remove();
      
              const promptCallerId = config.promptCallerId;
              const promptMyPhone = config.promptMyPhone && config.myPhones.length > 0;
              const callerIdsToDisplay = (config.activeCallerIds.length > 0) ? config.activeCallerIds : config.allApprovedIds;
      
              let modalInner = '';
      
              if (promptCallerId && promptMyPhone) {
                  // תפריט בחירה כפול ומקצועי
                  let callerIdOpts = `<option value="">🌐 ברירת מחדל של המערכת</option>` + callerIdsToDisplay.map(id => `<option value="${id}">${id}</option>`).join('');
                  let myPhoneOpts = config.myPhones.map(id => `<option value="${id}">${id}</option>`).join('');
                  
                  modalInner = `
                      <div style="text-align: right; margin-bottom: 15px;">
                          <label style="font-size: 13px; font-weight: bold; color: #555;">📱 לאיזה מכשיר לחייג אליך?</label>
                          <select id="q-my-phone" style="width:100%; padding:8px; margin-top:3px; border-radius:4px; font-size:14px; border:1px solid #ccc;">${myPhoneOpts}</select>
                      </div>
                      <div style="text-align: right; margin-bottom: 20px;">
                          <label style="font-size: 13px; font-weight: bold; color: #555;">📞 איזה זיהוי יוצא להציג ליעד?</label>
                          <select id="q-caller-id" style="width:100%; padding:8px; margin-top:3px; border-radius:4px; font-size:14px; border:1px solid #ccc;">${callerIdOpts}</select>
                      </div>
                      <button id="q-execute-btn" style="background:#28a745; color:#fff; border:none; padding:10px; width:100%; border-radius:5px; font-weight:bold; cursor:pointer; font-size:15px; margin-bottom:10px;">🚀 הוצא שיחה עכשיו!</button>
                  `;
              } else if (promptCallerId) {
                  // כפתורי לחיצה אחת - רק זיהוי יוצא
                  let btns = callerIdsToDisplay.map(id => `<button class="ym-quick-btn" data-type="callerid" data-val="${id}">📞 ${id}</button>`).join('');
                  modalInner = `
                      <p style="font-size: 13px; color: #666; margin-bottom: 10px;">בחר זיהוי יוצא להוצאת השיחה:</p>
                      <div style="display: flex; flex-direction: column; gap: 8px; max-height: 260px; overflow-y: auto; margin-bottom: 15px;">
                          <button class="ym-quick-btn" data-type="callerid" data-val="">🌐 ברירת מחדל של המערכת</button>
                          ${btns}
                      </div>
                  `;
              } else if (promptMyPhone) {
                  // כפתורי לחיצה אחת - רק לבחירת הטלפון שלי
                  let btns = config.myPhones.map(id => `<button class="ym-quick-btn" data-type="myphone" data-val="${id}">📱 ${id}</button>`).join('');
                  modalInner = `
                      <p style="font-size: 13px; color: #666; margin-bottom: 10px;">לאיזה מכשיר שלך לחייג עכשיו?</p>
                      <div style="display: flex; flex-direction: column; gap: 8px; max-height: 260px; overflow-y: auto; margin-bottom: 15px;">
                          ${btns}
                      </div>
                  `;
              }
      
              const modalHtml = `
                  <div id="ym-quick-dial-modal" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 9999999; display: flex; align-items: center; justify-content: center; font-family: Arial, sans-serif; direction: rtl;">
                      <div style="background: #fff; padding: 20px; border-radius: 12px; width: 340px; max-width: 90%; box-shadow: 0 5px 25px rgba(0,0,0,0.3); text-align: center; border-top: 4px solid #0066cc;">
                          <h4 style="margin: 0 0 15px 0; color: #333; font-size: 16px;">חיוג מהיר אל: <span style="color: #0066cc; direction: ltr; display: inline-block;">${phoneNumber}</span></h4>
                          ${modalInner}
                          <button id="ym-quick-cancel" style="background: #dc3545; color: #fff; border: none; padding: 8px 20px; border-radius: 5px; cursor: pointer; font-weight: bold; font-size: 13px; width: 100%;">ביטול חיוג</button>
                      </div>
                  </div>
              `;
      
              document.body.insertAdjacentHTML('beforeend', modalHtml);
      
              if (promptCallerId && promptMyPhone) {
                  document.getElementById('q-execute-btn').addEventListener('click', () => {
                      const sMyPhone = document.getElementById('q-my-phone').value;
                      const sCallerId = document.getElementById('q-caller-id').value;
                      document.getElementById('ym-quick-dial-modal').remove();
                      onExecute(sCallerId, sMyPhone);
                  });
              } else {
                  document.querySelectorAll('.ym-quick-btn').forEach(btn => {
                      btn.style.cssText = "background: #f8f9fa; border: 1px solid #ced4da; padding: 10px; border-radius: 6px; cursor: pointer; font-weight: bold; font-size: 15px; color: #0056b3; transition: all 0.2s;";
                      if(btn.getAttribute('data-val') === '') { btn.style.background = '#e2e3e5'; btn.style.color = '#383d41'; }
                      
                      btn.addEventListener('mouseover', function() { this.style.background = '#e6f2ff'; this.style.borderColor = '#80bdff'; });
                      btn.addEventListener('mouseout', function() { this.style.background = (this.getAttribute('data-val') === '') ? '#e2e3e5' : '#f8f9fa'; this.style.borderColor = '#ced4da'; });
                      
                      btn.addEventListener('click', function() {
                          const type = this.getAttribute('data-type');
                          const val = this.getAttribute('data-val');
                          document.getElementById('ym-quick-dial-modal').remove();
                          
                          if (type === 'callerid') {
                              onExecute(val, config.defaultMyPhone);
                          } else {
                              onExecute(config.callerId, val);
                          }
                      });
                  });
              }
      
              document.getElementById('ym-quick-cancel').addEventListener('click', () => {
                  document.getElementById('ym-quick-dial-modal').remove();
                  resetElement(targetElement, phoneNumber);
              });
          }
      
          // ==========================================
          // 5. ניהול קריאות מבוסס תורים (Sequential API)
          // ==========================================
          function triggerDial(phoneNumber, targetElement) {
              const config = getSettings();
              
              if (!config.token || !config.path || !config.listName) {
                  alert("❌ חסרים פרטי הגדרות. אנא הגדר את המערכת בחלון שיפתח כעת.");
                  openSettingsModal(); return;
              }
      
              const cleanPhone = phoneNumber.replace(/\D/g, '');
              const originalText = targetElement.innerText;
              targetElement.innerText = "⏳ מכין חיוג...";
              targetElement.style.pointerEvents = "none";
      
              const promptCallerId = config.promptCallerId;
              const promptMyPhone = config.promptMyPhone && config.myPhones.length > 0;
      
              if (promptCallerId || promptMyPhone) {
                  openQuickDialModal(phoneNumber, targetElement, (selectedCallerId, selectedMyPhone) => {
                      executeCall(cleanPhone, selectedCallerId, selectedMyPhone, targetElement, originalText);
                  });
              } else {
                  executeCall(cleanPhone, config.callerId, config.defaultMyPhone, targetElement, originalText);
              }
          }
      
          async function executeCall(cleanPhone, callerIdToUse, myPhoneToUse, targetElement, originalText) {
              const config = getSettings();
              try {
                  // עדכון היעד
                  targetElement.innerText = "⏳ מעדכן יעד...";
                  const url1 = `https://www.call2all.co.il/ym/api/UpdateExtension?token=${encodeURIComponent(config.token)}&path=${encodeURIComponent(config.path)}&nitoviya_dial_to=${encodeURIComponent(cleanPhone)}`;
                  await ymFetch(url1);
      
                  // עדכון המכשיר האישי (רק אם הוזן נתיב מיוחד למכשיר)
                  if (config.userPath && myPhoneToUse) {
                      targetElement.innerText = "⏳ מעדכן מכשיר...";
                      const url2 = `https://www.call2all.co.il/ym/api/UpdateExtension?token=${encodeURIComponent(config.token)}&path=${encodeURIComponent(config.userPath)}&nitoviya_dial_to=${encodeURIComponent(myPhoneToUse)}`;
                      await ymFetch(url2);
                  }
      
                  // הפעלת הצינתוק
                  targetElement.innerText = "⏳ מצנתק...";
                  const callerIdParam = callerIdToUse ? `&callerId=${encodeURIComponent(callerIdToUse)}` : '&callerId=';
                  const tzintukUrl = `https://www.call2all.co.il/ym/api/RunTzintuk?token=${encodeURIComponent(config.token)}${callerIdParam}&TzintukTimeOut=9&sayInfoOnAnswer=true&phones=tzl:${encodeURIComponent(config.listName)}`;
                  await ymFetch(tzintukUrl);
      
                  targetElement.innerText = "✅ שיחה יצאה!";
                  targetElement.style.color = "green";
              } catch (e) {
                  targetElement.innerText = "❌ שגיאה בחיוג";
                  console.error("Yemot API Error:", e);
              }
              resetElement(targetElement, originalText);
          }
      
          function resetElement(element, text) {
              setTimeout(() => {
                  element.innerText = text; element.style.pointerEvents = "auto"; element.style.color = "";
              }, 3000);
          }
      
          // ==========================================
          // 6. סריקת DOM ויעילות (TreeWalker + Observer)
          // ==========================================
          const PHONE_REGEX = /(?:(?:(\+?972|\b0)(?:[-.\s]?\d){8,9})|\b(1[78]00|1599)(?:[-.\s]?\d){6}\b|\*\d{3,4}\b)/g;
          const IGNORE_TAGS = new Set(['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT', 'A', 'BUTTON']);
      
          function scanAndReplace(rootNode) {
              const walker = document.createTreeWalker(rootNode, NodeFilter.SHOW_TEXT, {
                  acceptNode: function(node) {
                      if (!node.parentNode || IGNORE_TAGS.has(node.parentNode.nodeName)) return NodeFilter.FILTER_REJECT;
                      if (node.parentNode.hasAttribute('data-ym-dialer')) return NodeFilter.FILTER_REJECT;
                      if (node.parentNode.closest && node.parentNode.closest('#ym-settings-modal, #ym-quick-dial-modal')) return NodeFilter.FILTER_REJECT;
                      return PHONE_REGEX.test(node.nodeValue) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
                  }
              });
      
              const nodesToProcess = [];
              let currentNode;
              while (currentNode = walker.nextNode()) nodesToProcess.push(currentNode);
      
              nodesToProcess.forEach(node => {
                  const text = node.nodeValue;
                  const fragment = document.createDocumentFragment();
                  let lastIndex = 0, match;
                  PHONE_REGEX.lastIndex = 0;
      
                  while ((match = PHONE_REGEX.exec(text)) !== null) {
                      if (match.index > lastIndex) fragment.appendChild(document.createTextNode(text.slice(lastIndex, match.index)));
                      const phoneNumber = match[0];
                      const dialBadge = document.createElement('span');
                      dialBadge.innerText = phoneNumber;
                      dialBadge.title = "לחץ לחיוג מהיר באמצעות ימות המשיח";
                      dialBadge.setAttribute('data-ym-dialer', 'true');
                      dialBadge.style.cssText = "color: #0066cc; text-decoration: underline; cursor: pointer; font-weight: bold; background-color: #e6f2ff; padding: 0 3px; border-radius: 3px; margin: 0 1px;";
                      dialBadge.addEventListener('click', (e) => { e.preventDefault(); e.stopPropagation(); triggerDial(phoneNumber, dialBadge); });
                      fragment.appendChild(dialBadge);
                      lastIndex = PHONE_REGEX.lastIndex;
                  }
                  if (lastIndex < text.length) fragment.appendChild(document.createTextNode(text.slice(lastIndex)));
                  if (node.parentNode) node.parentNode.replaceChild(fragment, node);
              });
          }
      
          scanAndReplace(document.body);
      
          let debounceTimer = null;
          const observer = new MutationObserver((mutations) => {
              if (debounceTimer) clearTimeout(debounceTimer);
              debounceTimer = setTimeout(() => {
                  mutations.forEach(mutation => {
                      mutation.addedNodes.forEach(node => {
                          if (node.nodeType === Node.ELEMENT_NODE && !IGNORE_TAGS.has(node.nodeName)) {
                              if (node.id === 'ym-settings-modal' || node.id === 'ym-quick-dial-modal') return;
                              scanAndReplace(node);
                          } else if (node.nodeType === Node.TEXT_NODE && node.parentNode && !IGNORE_TAGS.has(node.parentNode.nodeName)) {
                              if (PHONE_REGEX.test(node.nodeValue)) scanAndReplace(node.parentNode);
                          }
                      });
                  });
              }, 400);
          });
          observer.observe(document.body, { childList: true, subtree: true });
      })();
      

      אין צורך לומר אבל בכל זאת הטוקן המידע האישי שלכם נמצא רק אצלכם אין לי שום גישה לזה

      עריכה: הקוד שודרג יש כפתור לטעון את כל מספרי המשנה המאושרים במערכת ניתן לבחור האם הזיהוי יוצא קבוע או לשאול לפני כל חיוג ניתן לבחור איזה מספרים הוא יציע
      מי שמחליף זיהוי יוצא שים לב לסדר את הפילטר בשלוחה ראשית ככה שיפנה לשלוחה המתאימה
      צילום מסך 2026-07-29 110929.png
      הקוד שודרג כך שניתן לבחור לאיזה טלפון להזמין את השיחה בתמונה שלי A זה השלוחה שממנה אני מחייג שלוחה B זה השלוחה שמחייגת אלי אפשר להגדיר חיוג קבוע למספר שלך וניתן לבחור לפני כל חיוג לאיזה מספר להזמין שיחה

      פורסם בטיפים עצות והדגמות מהמשתמשים
      ש
      שלוחה-404
    • RE: כמות רשומים לרשימת תפוצה עזרה!!! 🙏🙏🙏

      @לימוד-בתורת-מרן עיין פה

      אם פלוס לא מעוניין לדבר איתך למה אתה חייב להזכיר אותו בכל פוסט?

      פורסם בשאלות ועזרה הדדית
      ש
      שלוחה-404
    • רכישת יחידות

      האם יש מישהו שמוכר יחידות יותר זול מימות המשיח?
      אני צריך 10,000 יחידות

      פורסם בעזרה הדדית למשתמשים מתקדמים
      ש
      שלוחה-404
    • RE: הודעה אישית / ניהולו 🪧📣👨‍💼

      @פלוס אם יש שגיאה כנראה הגעת לשלוחה שלא מוגדרת או שלא קיימת זה בדרך כלל השגיאה הזאת
      אם אתה נכנס אם זיהוי לא נכון זה אומר משהו אחר
      תנסה להגדיר את שלוחה B ידנית ותבדוק מה קורה

      type=playfile 
      folder_to_play=/נתיב הודעות אישיות/Phone/05555123456
      

      תשנה נתיב ומספר תקין

      @פלוס כתב:
      ואצליך צריך לשכפל את הישנים מה שאיני יכול לעשות מריבוי ההודעות...

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

      פורסם בעזרה הדדית למשתמשים מתקדמים
      ש
      שלוחה-404
    • RE: אני רוצה לעסות סקר אם שאלה אחת שמתאפסת

      @דוד-חטוקה מה הקשר לפורום API ?
      תסביר יותר ברור מה אתה רוצה לעשות

      פורסם בפורום מפתחים API
      ש
      שלוחה-404
    • מערכת סינון ספאם

      לתועלת הציבור יצרתי מערכת לסינון צינתוקי ספאם
      מערכת סינון צינתוקים
      אתה מגדיר הפניה ללא תנאי רק לשיחות אם תפוס
      אתה מגדיר בטלפון רשימה לבנה לשיחות נכנסות רק אנשי קשר
      שיחה נכנסת שהיא לא באנשי קשר נדחית ומופנה למערכת המערכת מבקשת ממנו להקיש ספרה רנדומלית אם הוא מקיש את הספרה הוא נוסף לרשימה לבנה ועובר לחיוג בפעם הבאה הוא לא יצטרך להקיש ספרה
      אין דרך שתראה את המספר על הצג כי אין דרך להפריד בין השיחות לפני אימות לאחרי אימות
      במצב לא להפריע בטלפונים תומכים ניתן שהמספר יופיע כי שיחה ראשונה הטלפון דוחה שיחה שנייה הוא מקבל אז הוא חוזר מהמערכת אם הזיהוי שלו והוא מחייג אצלך
      יש שלוחת ניהול טלפונית שמה אתה יכול לשמוע את המספר האחרון שחייג לחייג אליו לקבל את כל רשימת השיחות למייל וכו'
      אם יש עוד שאלות אשמח להסביר
      עריכה: נוסף אופציה של תא קולי חכם ההקלטה מתומללת ונשלח למייל גם קובץ שמע וגם טקסט
      02/06/2026
      עריכה: בעקבות המעבר של מודל תור לתשלום בימות המשיח המערכת נסגרת
      מי שרוצה בתשלום ניתן ליצור קשר דרך יצירת קשר
      התא קולי ממשיך לעבוד כרגיל
      ניתן להגדיר רק תא קולי פשוט להפנות למספר של התא קולי

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

      @שיחה-ממתינה מאז שעשו עידכון לפורום אני עשיתי שיהיה לי התראות ואין וגם אף פעם אין לי הודעות שלא נקראו
      יש לי משתמש ישן ובו כן יש

      פורסם בעל הפורום
      ש
      שלוחה-404
    • RE: שליחת צינתוק ממספר שאינו ממספר המערכת

      @יצחק-י. בשיגור הודעות או במרכזיה עיסקית בשינוי זיהוי יוצא יש הוסף מספר ספיישל אתה מאמת אותו אם שיחה או SMS לא צריך משהו חיצוני

      פורסם בעזרה הדדית למשתמשים מתקדמים
      ש
      שלוחה-404
    • RE: הגבלת ניהול הקו = משתמש יוכל להיכנס למערכת לאן שאני נותן הרשאה

      @1668 @lavitoren-הטי-ל יש פאנל ניהול מבוסס טוקן מוגבל לניהול שלוחה 1 בלבד

      פורסם בשאלות ועזרה הדדית
      ש
      שלוחה-404

    פוסטים אחרונים שנוצרו על ידי שלוחה-404

    • RE: חיוג מהיר ומסודר למספרים באתרי אינטרנט עם הזיהוי של המערכת שלכם (תוסף לדפדפן)

      @מעבדת-בין-הסדרים עדכנתי את הקוד למעלה
      תבדוק גם לי זה כתב שגיאה אבל זה עדכן לא הצלחתי להבין למה השגיאה הזו
      בכל מקרה שלחתי את זה לגוגל לעשות תוסף רשמי בחנות שזה יחזור מהבדיקה אני יעלה את זה לפה

      פורסם בטיפים עצות והדגמות מהמשתמשים
      ש
      שלוחה-404
    • RE: SIP מחובר, אבל לא עובד, קרה למישהו בשנה האחרונה

      @דוד-נחום אני נתקלתי בבעיה דומה לכאורה זו בעיית IP אם מתחלף IP אז השרת לא מוצא את התוכנה תנסה לבקש מהספק שלך IP קבוע

      פורסם בטלפונים ומערכות SIP
      ש
      שלוחה-404
    • RE: ברירת מחדל - כשכותבים באשכול אין מעקב אחריו משום מה! מדוע?

      @שיחה-ממתינה מאז שעשו עידכון לפורום אני עשיתי שיהיה לי התראות ואין וגם אף פעם אין לי הודעות שלא נקראו
      יש לי משתמש ישן ובו כן יש

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

      @יעקב-יצחק בפילטר מכניסים מספר רץ ולא מזהה קמפיין

      פורסם בעזרה הדדית למשתמשים מתקדמים
      ש
      שלוחה-404
    • RE: הגדרתי חדר ועידה בצורה הזו אבל אין אפשרות לסיסמה מנהל ועידה

      @שמול אוקי כמה מנהלים יש ? רק 1 או שאתה רוצה כמה ?
      דווקא סיסמה אתה רוצה ? נניח רשימת תפוצה משהו כזה לא טוב ?

      פורסם בשאלות ועזרה הדדית
      ש
      שלוחה-404
    • RE: הגדרתי חדר ועידה בצורה הזו אבל אין אפשרות לסיסמה מנהל ועידה

      @שמול מה אתה רוצה שיהיה בסוף ?
      שכל מי שמקיש את הסיסמה יעבור לניהול ? הראשון יעבור לניהול כל השאר ימתינו ?

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

      @שחלק-מחכמתו תנסה M1032

      פורסם בשאלות ועזרה הדדית
      ש
      שלוחה-404
    • RE: חיוג מהיר ומסודר למספרים באתרי אינטרנט עם הזיהוי של המערכת שלכם (תוסף לדפדפן)

      @מעבדת-בין-הסדרים נכון, עדכנתי בגיטהב אתה יכול להוריד משם
      אם לא יותר מאוחר אני יעלה גם לפה

      פורסם בטיפים עצות והדגמות מהמשתמשים
      ש
      שלוחה-404
    • RE: חיוג מהיר ומסודר למספרים באתרי אינטרנט עם הזיהוי של המערכת שלכם (תוסף לדפדפן)

      @avrham לא התכוונתי התוסף עצמו השיחות מהתוסף עולות יחידות

      פורסם בטיפים עצות והדגמות מהמשתמשים
      ש
      שלוחה-404
    • RE: חיוג מהיר ומסודר למספרים באתרי אינטרנט עם הזיהוי של המערכת שלכם (תוסף לדפדפן)

      @י.ע גם עכשיו זה מעדכן גירסאות
      אני לא מבין בזה הכול זה גימיני אם יש איפשהו מדריך אני יכול לנסות

      פורסם בטיפים עצות והדגמות מהמשתמשים
      ש
      שלוחה-404