• דף הבית
    • אינדקס קישורים
    • פוסטים אחרונים
    • משתמשים
    • חיפוש בהגדרות המתקדמות
    • חיפוש גוגל בפורום
    • ניהול המערכת
    • ניהול המערכת - שרת private
    • הרשמה
    • התחברות
    1. דף הבית
    2. lavitoren הטי"ל
    L מנותק
    • פרופיל
    • עוקב אחרי 3
    • עוקבים 2
    • נושאים 26
    • פוסטים 333
    • קבוצות 0

    lavitoren הטי"ל

    @lavitoren הטי"ל

    141
    מוניטין
    99
    צפיות בפרופיל
    333
    פוסטים
    2
    עוקבים
    3
    עוקב אחרי
    תאריך הצטרפות
    נראה לאחרונה
    מיקום כמעט וירטואלי

    lavitoren הטי"ל הפסקת מעקב מעקב

    הפוסטים הטובים ביותר שנוצרו על ידי lavitoren הטי"ל

    • שמיעת כמות המספרים ששמעו הודעה 🎰🎧📡 רישום אמיתי 📊📉✔

      במודול השמעת קבצים כאשר שומעים הודעה ניתן להגדיר שע"י מקש מסויים יהיה ניתן
      לשמוע כמה כבר שמעו את ההודעה הזו (שאתה עליו)

      והבעיה היא שכולנו שומעים כל הזמן את כמות השומעים ששמעו אפילו לשניה אחת
      ולכן זה לא משקף נתוני אמת (כמה באמת האזינו מעל כמות זמן מסויים)
      אז באתי בתחינה לעוסקים בעניין באם אפשר להוסיף למודול הקיים
      של

      control_play_(morea)?=say_listening_data_amount
      save_listening_data=yes
      

      (כמבואר כאן ואז על זה השמעת נתוני האזנה לקובץ)

      איזה תוסף שיהיה ניתן להגדיר שמאז ששמע המאזין מעל X זמן ⏱⏳ (שגם את זה יהיה אפשר להגדיר)
      על כל השמעה בשלוחה הוא ייספר ויירשם כאחד ששמע

      ואני מוסיף פה את הערתו החשובה של @מוטי-מוטי-מוטי

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

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

      תודה לכולם ול"ימות המשיח" על כל הטוב שהם נותנים לכולם 👍📠😉

      פורסם בבקשות לפיתוח
      L
      lavitoren הטי"ל
    • הגיע הזמן לומר תודה!!!! 😃🙏

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

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

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

      אז אהיה הנחשון

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

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

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

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

      אני רוצה להגיד תודה ענקית לצוות של "ימות המשיח" 🙏. לא כי הכל תמיד מושלם, אלא כי נתתם לנו כלי ששינה לנו את היכולות. נתתם לנו לגדול מהבסיס, מהוואצאפ-פון וההגדרות הטלפוניות, ועד להקמת אימפריות של תוכן 🌍✨.

      אז זה הסיפור שלי – מהוואצאפ-פון ועד לאתר 📱 ⬅️ 💻. מה הסיפור שלכם? אל תשארו בחוץ, שתפו שיהיה כוח לכולם! 🎤🔥

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

      פורסם בשאלות ועזרה הדדית
      L
      lavitoren הטי"ל
    • הצעת ייעול: שליטה על כמות הדילוג במקש 8 במהלך השמעה 🎧⏩ (לניווט מהיר בשלוחות עמוסות!)

      לכל חברי הפורום שלום וברכה,

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

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

      📂 האתגר: ניווט בשלוחות עם אלפי הודעות
      כיום, ישנן שלוחות (כמו שיעורים, עדכונים או קווי תוכן) שמגיעות לכמויות אדירות של קבצים – לעיתים גם 40,000 הודעות ומעלה.

      כאשר מאזין רוצה להגיע להודעה ספציפית שנמצאת "רחוק" (למשל, לדלג מהודעה 1 להודעה 39,000), הניווט הקיים הופך למשימה כמעט בלתי אפשרית.
      🔢 הפתרון המוצע: הגדרת כמות הדילוג במקש 8
      אני מציע להוסיף הגדרה במערכת שתאפשר למנהל השלוחה לקבוע את "ערך הדילוג" של מקש 8.
      במקום דילוג סטנדרטי, המערכת תאפשר:
      הגדרה מותאמת אישית: לקבוע שמקש 8 ידלג X הודעות קדימה (למשל 1,000 הודעות בכל לחיצה).
      ניווט מהיר: קיצור הדרך להגיע לקבצים ישנים או חדשים בשלוחות ענק.
      אפשרות טכנית: אולי ניתן לבסס זאת על מנגנון דומה ל"הפעלה רנדומלית", אך כזה שמקפיץ את המאזין קדימה בצורה מבוקרת.
      לסיכום:
      אני מאמין ששדרוג כזה יחסוך זמן יקר למאזינים ויהפוך את המערכות של ימות המשיח לידידותיות עוד יותר למשתמש הקצה, במיוחד בקווי התוכן הגדולים. ☎
      אני בטוח שצוות הפיתוח המקצועי של ימות המשיח יבחן את האפשרות הזו בחיוב, כפי שהם קשובים תמיד לצרכי הקהילה 🙏
      גם לכם זה חסר?
      אשמח לשמוע את דעתכם בתגובות 😉
      אם גם אתם חושבים שזה שדרוג נחוץ – תנו לייק 👍 כדי שנוכל להראות לימות המשיח כמה הפונקציה הזו מבוקשת!
      תודה רבה לכולם!
      נ.ב. - @ימות-המשיח , נשמח מאוד לשמוע אם פיתוח כזה נמצא בתכנון או אם ניתן ליישם אותו בעתיד הקרוב.

      פורסם בבקשות לפיתוח
      L
      lavitoren הטי"ל
    • 🚀 הכירו את הטי"ל V1.0: המהפכה התורנית בקו שלכם כבר כאן!

      בפניכם יצירת השנה

      שלום לכל חברי קהילת "ימות המשיח" היקרים!

      מי מאיתנו לא חלם להפוך את הקו הטלפוני שלו לספריה תורנית אדירה? מי לא רצה להקים שלוחת ש"ס מלאה, תנ"ך לפי פרקים, או שולחן ערוך מפורט?

      עד היום, זה אמר דבר אחד: שבועות של עבודה ידנית סיזיפית. פתיחת אלפי שלוחות, הגדרת קבצי ext.ini אחד-אחד, חישוב ספרות (digits), ריפוד אפסים (001, 01) ובניית היררכיה מסובכת.
      היום, כל זה נגמר.

      אני שמח להגיש לכם את "הטי"ל V1.0" (הכלי הטלפוני ליצירת ספריות) – כלי עוצמתי, יוקרתי ובלתי נתפס שיעשה עבורכם את כל העבודה השחורה בכמה דקות של "קסם" טכנולוגי.

      מה הטי"ל יודע לעשות? (תחזיקו חזק):

      ✅ ש"ס בבלי וירושלמי: הקמת כל המסכתות והדפים (כולל פיצול לעמוד א' וב'!) בלחיצת כפתור.

      ✅ חמישה חומשי תורה: מבנה גאוני של חומש -> פרשיות השבוע -> 8 עליות (מראשון עד מפטיר).

      ✅ תנ"ך מלא: כ"ד ספרים מחולקים לפרקים בצורה מושלמת.

      ✅ שולחן ערוך ורמב"ם: הקמת כל הסימנים וההלכות, כולל אפשרות לפיצול אוטומטי לסעיפים.

      ✅ משניות: כל ששת סדרי משנה עם חלוקה לפרקים ותתי-משניות.

      למה זה הכלי הכי חזק שראיתם?

      💎 ממשק Premium: עיצוב Dark-Mode יוקרתי שמרגיש כמו תוכנת עריכה מקצועית.

      💎 אוטומציה מלאה של פקודות: המערכת מזריקה לבד פקודות digits ו-type לפי ההקשר, כדי שהמאזינים שלכם יוכלו להקיש מספרים בטלפון והקו יגיב בשבריר שנייה.

      💎 שליטה מוחלטת: אתם בוחרים אם השלוחה תהיה להשמעה (playfile) או להקלטה (record).

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

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

      מוגש באהבה לכל העוסקים במלאכת הקוד!

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

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

      להלן הקוד המצורף עם הוראות הכנה"

      <!DOCTYPE html>
      <html lang="he" dir="rtl">
      <head>
          <meta charset="UTF-8">
          <title>הטי"ל - הכלי הטלפוני ליצירת ספריות v1.3</title>
          <style>
              :root {
                  --bg-dark: #121212;
                  --surface: #1e1e1e;
                  --surface-light: #2d2d2d;
                  --primary: #3b82f6;
                  --primary-hover: #2563eb;
                  --accent: #f59e0b;
                  --danger: #ef4444;
                  --text-main: #e2e8f0;
                  --text-dim: #94a3b8;
                  --border: #334155;
                  --success: #10b981;
              }
      
              body { 
                  font-family: 'Segoe UI', system-ui, -apple-system, sans-serif; 
                  background-color: var(--bg-dark); 
                  color: var(--text-main); 
                  margin: 0; 
                  padding: 20px; 
                  line-height: 1.5;
                  text-align: right;
              }
      
              .wrapper { max-width: 1200px; margin: 0 auto; }
      
              header { 
                  border-bottom: 1px solid var(--border); 
                  padding-bottom: 20px; 
                  margin-bottom: 30px; 
                  display: flex; 
                  justify-content: space-between; 
                  align-items: center; 
              }
      
              h1 { margin: 0; font-size: 22px; font-weight: 800; color: var(--accent); letter-spacing: -0.5px; }
              .version { font-size: 14px; background: var(--border); padding: 4px 10px; border-radius: 4px; color: #fff; margin-right: 10px; }
      
              .dashboard { display: grid; grid-template-columns: 350px 1fr; gap: 20px; }
      
              .card { 
                  background: var(--surface); 
                  border: 1px solid var(--border); 
                  border-radius: 12px; 
                  padding: 20px; 
                  box-shadow: 0 4px 20px rgba(0,0,0,0.5);
              }
      
              .lib-selector { 
                  display: grid; 
                  grid-template-columns: 1fr; 
                  gap: 10px; 
                  margin-bottom: 20px; 
              }
      
              .lib-btn { 
                  background: var(--surface-light); 
                  border: 1px solid var(--border); 
                  color: var(--text-main); 
                  padding: 12px; 
                  border-radius: 8px; 
                  cursor: pointer; 
                  text-align: right; 
                  font-weight: 600; 
                  transition: all 0.2s;
                  display: flex;
                  align-items: center;
                  gap: 10px;
                  font-size: 15px;
              }
      
              .lib-btn:hover { border-color: var(--primary); background: #252525; }
              .lib-btn.active { background: var(--primary); border-color: var(--primary); color: white; }
      
              .form-group { margin-bottom: 15px; }
              label { display: block; font-size: 13px; color: var(--text-dim); margin-bottom: 6px; font-weight: 600; }
              
              input, select { 
                  width: 100%; 
                  background: var(--bg-dark); 
                  border: 1px solid var(--border); 
                  border-radius: 6px; 
                  padding: 10px; 
                  color: white; 
                  box-sizing: border-box;
                  outline: none;
                  font-family: inherit;
              }
      
              input:focus { border-color: var(--primary); }
      
              .options-panel { 
                  background: #1a202c; 
                  border-right: 4px solid var(--accent); 
                  padding: 15px; 
                  border-radius: 6px; 
                  margin-bottom: 20px; 
              }
      
              .scroll-area { 
                  height: 500px; 
                  overflow-y: auto; 
                  border: 1px solid var(--border); 
                  background: var(--bg-dark); 
                  padding: 10px; 
                  border-radius: 8px; 
                  display: grid; 
                  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); 
                  gap: 8px; 
              }
      
              .masechet-item { 
                  background: var(--surface-light); 
                  padding: 8px; 
                  border-radius: 4px; 
                  display: flex; 
                  align-items: center; 
                  gap: 8px; 
                  font-size: 13px;
              }
              .masechet-item input { width: auto; cursor: pointer; }
      
              .seder-title { 
                  grid-column: 1 / -1; 
                  background: var(--border); 
                  padding: 4px 10px; 
                  font-size: 12px; 
                  font-weight: 800; 
                  color: var(--accent); 
                  margin-top: 10px;
                  border-radius: 4px;
                  display: flex;
                  justify-content: space-between;
                  align-items: center;
              }
      
              .seder-checkbox {
                  width: auto !important;
                  margin: 0;
                  cursor: pointer;
              }
      
              .btn-run { 
                  background: var(--primary); color: white; border: none; padding: 15px; border-radius: 8px; 
                  font-weight: 800; cursor: pointer; width: 100%; font-size: 17px; box-shadow: 0 4px 10px rgba(59, 130, 246, 0.3);
              }
              .btn-stop { background: var(--danger); color: white; border: none; padding: 15px; border-radius: 8px; font-weight: 800; cursor: pointer; width: 100%; display: none; font-size: 17px; }
      
              .progress-wrapper { margin-top: 20px; }
              .progress-bar-bg { background: var(--surface-light); height: 14px; border-radius: 7px; overflow: hidden; }
              .progress-bar-fill { background: linear-gradient(90deg, var(--success), #34d399); height: 100%; width: 0%; transition: width 0.3s; }
              .progress-status { font-size: 12px; color: var(--text-dim); margin-top: 8px; display: flex; justify-content: space-between; }
      
              .log-container { 
                  margin-top: 20px; background: #000; color: #00ff00; font-family: 'Consolas', monospace; 
                  font-size: 12px; padding: 15px; border-radius: 8px; height: 220px; overflow-y: auto; border: 1px solid var(--border);
                  direction: ltr; text-align: left;
              }
      
              ::-webkit-scrollbar { width: 8px; }
              ::-webkit-scrollbar-track { background: var(--bg-dark); }
              ::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; }
          </style>
      </head>
      <body>
      
      <div class="wrapper">
          <header>
              <h1>פתיחת ספריה תורנית מטורפת עצומת מימדים לקו שלכם <span class="version">הטי"ל V1.3</span></h1>
              <div id="connectionStatus" style="color: var(--success); font-size: 13px;">● מוכן לביצוע</div>
          </header>
      
          <div class="dashboard">
              <div class="card">
                  <label>סוג תוכן להקמה</label>
                  <div class="lib-selector">
                      <button class="lib-btn active" onclick="loadLibrary('bavli', this)">📖 ש"ס בבלי</button>
                      <button class="lib-btn" onclick="loadLibrary('yerushalmi', this)">🕍 ש"ס ירושלמי</button>
                      <button class="lib-btn" onclick="loadLibrary('torah', this)">📜 תורה (חומשים ופרשיות)</button>
                      <button class="lib-btn" onclick="loadLibrary('chagim', this)">🎉 חגים ומועדים</button>
                      <button class="lib-btn" onclick="loadLibrary('tanakh', this)">📚 תנ"ך (כ"ד ספרים)</button>
                      <button class="lib-btn" onclick="loadLibrary('mishnah', this)">🗳️ משניות</button>
                      <button class="lib-btn" onclick="loadLibrary('rambam', this)">⚖️ רמב"ם (היד החזקה)</button>
                      <button class="lib-btn" onclick="loadLibrary('shulchan', this)">🖋️ שולחן ערוך</button>
                  </div>
      
                  <div class="form-group">
                      <label>סוג שלוחת הקצה (היחידה הקטנה ביותר)</label>
                      <select id="endFolderType">
                          <option value="playfile">השמעת קבצים (playfile)</option>
                          <option value="record">הקלטת הודעות (record)</option>
                      </select>
                  </div>
      
                  <div class="form-group" id="groupHierarchical" style="display:none;">
                      <input type="checkbox" id="hierarchicalSedarim" style="width:auto; margin-left:10px;"> 
                      <label style="display:inline; color: white;" for="hierarchicalSedarim">הקם לפי סדרים (יוצר תת-תיקיות לפי סדרים)</label>
                  </div>
      
                  <div class="form-group">
                      <label>טוקן גישה API</label>
                      <input type="text" id="token" placeholder="0770000000:123456">
                  </div>
      
                  <div class="form-group">
                      <label>נתיב יעד (תיקייה בקו)</label>
                      <input type="text" id="targetPath" placeholder="למשל: 1/5">
                  </div>
      
                  <div class="form-group">
                      <label>מספר שלוחה להתחלה</label>
                      <input type="number" id="startNum" value="1">
                  </div>
      
                  <button class="btn-run" id="startBtn" onclick="process()">🚀 התחל הקמה</button>
                  <button class="btn-stop" id="cancelBtn" onclick="abort()">🛑 עצור פעולה</button>
      
                  <div class="progress-wrapper" id="progWrapper" style="display:none;">
                      <div class="progress-bar-bg"><div class="progress-bar-fill" id="progBar"></div></div>
                      <div class="progress-status"><span id="progText">0%</span><span id="progCounts">0 / 0</span></div>
                  </div>
              </div>
      
              <div class="card">
                  <div id="optionsPanel" class="options-panel">
                      <div id="shasOptions">
                          <input type="checkbox" id="splitAmudim" style="width:auto; margin-left:10px;"> 
                          <label style="display:inline; color: white;" for="splitAmudim">פצל דפים לעמוד א' וב'</label>
                      </div>
                      <div id="torahOptions" style="display:none;">
                          <input type="checkbox" id="noAliyot" style="width:auto; margin-left:10px;"> 
                          <label style="display:inline; color: white;" for="noAliyot">ללא עליות לתורה (פרשה היא השמעת קבצים ישירה)</label>
                      </div>
                      <div id="mishnahOptions" style="display:none;">
                          <label style="color: white;">כמות תתי-שלוחות (משניות/הלכות/פסוקים):</label>
                          <input type="number" id="mishCount" value="0" style="width:100px;">
                      </div>
                      <div id="shulchanOptions" style="display:none;">
                          <label style="color: white;">כמות סעיפים בכל סימן (0 לסימנים בלבד):</label>
                          <input type="number" id="seifimCount" value="0" style="width:100px;">
                      </div>
                  </div>
      
                  <div style="display:flex; justify-content: space-between; margin-bottom: 15px;">
                      <label>בחירת ספרים / מסכתות</label>
                      <div>
                          <button onclick="selectAll(true)" style="background:none; border:1px solid var(--border); color:var(--text-dim); cursor:pointer; padding:2px 10px; border-radius:4px; font-size:11px;">בחר הכל</button>
                          <button onclick="selectAll(false)" style="background:none; border:1px solid var(--border); color:var(--text-dim); cursor:pointer; padding:2px 10px; border-radius:4px; font-size:11px; margin-right:5px;">נקה הכל</button>
                      </div>
                  </div>
      
                  <div class="scroll-area" id="masechtotList"></div>
                  <div class="log-container" id="logBox">ממתין לפקודה...</div>
              </div>
          </div>
      </div>
      
      <script>
          let isAborted = false;
          let currentLib = 'bavli';
      
          const fullDb = {
              torah: [{ seder: "חמישה חומשי תורה", items: [
                  { n: "בראשית", p: ["בראשית", "נח", "לך לך", "וירא", "חיי שרה", "תולדות", "ויצא", "וישלח", "וישב", "מקץ", "ויגש", "ויחי"] },
                  { n: "שמות", p: ["שמות", "וארא", "בא", "בשלח", "יתרו", "משפטים", "תרומה", "תצוה", "כי תשא", "ויקהל", "פקודי"] },
                  { n: "ויקרא", p: ["ויקרא", "צו", "שמיני", "תזריע", "מצורע", "אחרי מות", "קדושים", "אמור", "בהר", "בחקותי"] },
                  { n: "במדבר", p: ["במדבר", "נשא", "בהעלותך", "שלח", "קרח", "חקת", "בלק", "פינחס", "מטות", "מסעי"] },
                  { n: "דברים", p: ["דברים", "ואתחנן", "עקב", "ראה", "שופטים", "כי תצא", "כי תבוא", "נצבים", "וילך", "האזינו", "וזאת הברכה"] }
              ]}],
              chagim: [
                  { seder: "1. ימים נוראים וחגי תשרי", items: [
                      { n: "ראש השנה", p: ["ערב ראש השנה", "תפילות ראש השנה", "תקיעת שופר", "סימני ראש השנה"] },
                      { n: "עשרת ימי תשובה", p: ["סליחות", "שבת תשובה", "כפרות"] },
                      { n: "יום הכיפורים", p: ["ערב יום הכיפורים", "תפילת כל נדרי", "נעילה", "מוצאי יום הכיפורים"] },
                      { n: "סוכות", p: ["בניית סוכה", "ארבעת המינים", "הושענא רבא", "שמיני עצרת ושמחת תורה"] }
                  ]},
                  { seder: "2. חגים מדרבנן", items: [
                      { n: "חנוכה", p: ["הדלקת נרות", "מעוז צור", "ענייני חנוכה", "סביבון"] },
                      { n: "פורים", p: ["תענית אסתר", "קריאת המגילה", "משלוח מנות ומתנות לאביונים", "סעודת פורים"] }
                  ]},
                  { seder: "3. חגי ניסן וספירת העומר", items: [
                      { n: "פסח", p: ["בדיקת חמץ וביעורו", "הערב הסדר", "הגדה של פסח", "שביעי של פסח ואיסרו חג"] },
                      { n: "ספירת העומר ול\"ג בעומר", p: ["דיני ספירת העומר", "ימי העומר", "ל\"ג בעומר ומנהגיו"] },
                      { n: "שבועות", p: ["ערב שבועות", "תיקון ליל שבועות", "מגילת רות"] }
                  ]},
                  { seder: "4. בין המצרים ותעניות השנה", items: [
                      { n: "תעניות השנה", p: ["צום גדליה", "עשרה בטבת", "תענית אסתר", "שבעה עשר בתמוז"] },
                      { n: "בין המצרים ותשעה באב", p: ["שלושת השבועות", "תשעה באב ותיקון חצות", "קינות ומגילת איכה"] }
                  ]}
              ],
              tanakh: [{ seder: "תורה", items: [{ n: "בראשית", c: 50 }, { n: "שמות", c: 40 }, { n: "ויקרא", c: 27 }, { n: "במדבר", c: 36 }, { n: "דברים", c: 34 }]}, { seder: "נביאים", items: [{ n: "יהושע", c: 24 }, { n: "שופטים", c: 21 }, { n: "שמואל א", c: 31 }, { n: "שמואל ב", c: 24 }, { n: "מלכים א", c: 22 }, { n: "מלכים ב", c: 25 }, { n: "ישעיהו", c: 66 }, { n: "ירמיהו", c: 52 }, { n: "יחזקאל", c: 48 }, { n: "תרי עשר", c: 67 }]}, { seder: "כתובים", items: [{ n: "תהילים", c: 150 }, { n: "משלי", c: 31 }, { n: "איוב", c: 42 }, { n: "שיר השירים", c: 8 }, { n: "רות", c: 4 }, { n: "איכה", c: 5 }, { n: "קהלת", c: 12 }, { n: "אסתר", c: 10 }, { n: "דניאל", c: 12 }, { n: "עזרא", c: 10 }, { n: "נחמיה", c: 13 }, { n: "דברי הימים א", c: 29 }, { n: "דברי הימים ב", c: 36 }]}],
              mishnah: [{ seder: "סדר זרעים", items: [{ n: "ברכות", c: 9 }, { n: "פאה", c: 8 }, { n: "דמאי", c: 7 }, { n: "כלאיים", c: 9 }, { n: "שביעית", c: 10 }, { n: "תרומות", c: 11 }, { n: "מעשרות", c: 5 }, { n: "מעשר שני", c: 5 }, { n: "חלה", c: 4 }, { n: "ערלה", c: 3 }, { n: "ביכורים", c: 3 }]}, { seder: "סדר מועד", items: [{ n: "שבת", c: 24 }, { n: "עירובין", c: 10 }, { n: "פסחים", c: 10 }, { n: "שקלים", c: 8 }, { n: "יומא", c: 8 }, { n: "סוכה", c: 5 }, { n: "ביצה", c: 5 }, { n: "ראש השנה", c: 4 }, { n: "תענית", c: 4 }, { n: "מגילה", c: 4 }, { n: "מועד קטן", c: 3 }, { n: "חגיגה", c: 3 }]}, { seder: "סדר נשים", items: [{ n: "יבמות", c: 16 }, { n: "כתובות", c: 13 }, { n: "נדרים", c: 11 }, { n: "נזיר", c: 9 }, { n: "סוטה", c: 9 }, { n: "גיטין", c: 9 }, { n: "קידושין", c: 4 }]}, { seder: "סדר נזיקין", items: [{ n: "בבא קמא", c: 10 }, { n: "בבא מציעא", c: 10 }, { n: "בבא בתרא", c: 10 }, { n: "סנהדרין", c: 11 }, { n: "מכות", c: 3 }, { n: "שבועות", c: 8 }, { n: "עדיות", c: 8 }, { n: "עבודה זרה", c: 5 }, { n: "אבות", c: 6 }, { n: "הוריות", c: 3 }]}, { seder: "סדר קדשים", items: [{ n: "זבחים", c: 14 }, { n: "מנחות", c: 13 }, { n: "חולין", c: 12 }, { n: "בכורות", c: 9 }, { n: "ערכין", c: 9 }, { n: "תמורה", c: 7 }, { n: "כריתות", c: 6 }, { n: "מעילה", c: 6 }, { n: "תמיד", c: 7 }, { n: "מידות", c: 5 }, { n: "קינים", c: 3 }]}, { seder: "סדר טהרות", items: [{ n: "כלים", c: 30 }, { n: "אהלות", c: 18 }, { n: "נגעים", c: 14 }, { n: "פרה", c: 12 }, { n: "טהרות", c: 10 }, { n: "מקואות", c: 10 }, { n: "נידה", c: 10 }, { n: "מכשירין", c: 6 }, { n: "זבים", c: 5 }, { n: "טבול יום", c: 4 }, { n: "ידיים", c: 4 }, { n: "עוקצין", c: 3 }]}],
              bavli: [{ seder: "ש\"ס בבלי", items: [{ n: "ברכות", c: 64 }, { n: "שבת", c: 157 }, { n: "עירובין", c: 105 }, { n: "פסחים", c: 121 }, { n: "שקלים", c: 22 }, { n: "יומא", c: 88 }, { n: "סוכה", c: 56 }, { n: "ביצה", c: 40 }, { n: "ראש השנה", c: 35 }, { n: "תענית", c: 31 }, { n: "מגילה", c: 32 }, { n: "מועד קטן", c: 29 }, { n: "חגיגה", c: 27 }, { n: "יבמות", c: 122 }, { n: "כתובות", c: 112 }, { n: "נדרים", c: 91 }, { n: "נזיר", c: 66 }, { n: "סוטה", c: 49 }, { n: "גיטין", c: 90 }, { n: "קידושין", c: 82 }, { n: "בבא קמא", c: 119 }, { n: "בבא מציעא", c: 119 }, { n: "בבא בתרא", c: 176 }, { n: "סנהדרין", c: 113 }, { n: "מכות", c: 24 }, { n: "שבועות", c: 49 }, { n: "עבודה זרה", c: 76 }, { n: "הוריות", c: 14 }, { n: "זבחים", c: 120 }, { n: "מנחות", c: 110 }, { n: "חולין", c: 142 }, { n: "בכורות", c: 61 }, { n: "ערכין", c: 34 }, { n: "תמורה", c: 34 }, { n: "כריתות", c: 28 }, { n: "מעילה", c: 22 }, { n: "תמיד", c: 33, s: 25 }, { n: "מידות", c: 37, s: 34 }, { n: "קינים", c: 25, s: 22 }, { n: "נידה", c: 73 }]}],
              yerushalmi: [{ seder: "ש\"ס ירושלמי", items: [{ n: "ברכות", c: 68 }, { n: "פאה", c: 37 }, { n: "דמאי", c: 34 }, { n: "כלאיים", c: 44 }, { n: "שביעית", c: 31 }, { n: "תרומות", c: 59 }, { n: "מעשרות", c: 26 }, { n: "מעשר שני", c: 33 }, { n: "חלה", c: 28 }, { n: "ערלה", c: 20 }, { n: "ביכורים", c: 13 }, { n: "שבת", c: 92 }, { n: "עירובין", c: 65 }, { n: "פסחים", c: 71 }, { n: "יומא", c: 42 }, { n: "שקלים", c: 33 }, { n: "סוכה", c: 26 }, { n: "ראש השנה", c: 22 }, { n: "ביצה", c: 22 }, { n: "תענית", c: 26 }, { n: "מגילה", c: 34 }, { n: "חגיגה", c: 22 }, { n: "מועד קטן", c: 19 }, { n: "יבמות", c: 85 }, { n: "סוטה", c: 47 }, { n: "כתובות", c: 72 }, { n: "נדרים", c: 40 }, { n: "גיטין", c: 54 }, { n: "נזיר", c: 44 }, { n: "קידושין", c: 48 }, { n: "בבא קמא", c: 44 }, { n: "בבא מציעא", c: 37 }, { n: "בבא בתרא", c: 34 }, { n: "סנהדרין", c: 68 }, { n: "מכות", c: 9 }, { n: "שבועות", c: 44 }, { n: "עבודה זרה", c: 37 }, { n: "הוריות", c: 19 }, { n: "נידה", c: 13 }]}],
              rambam: [{ seder: "רמב\"ם", items: [{ n: "מדע", c: 46 }, { n: "אהבה", c: 46 }, { n: "זמנים", c: 97 }, { n: "נשים", c: 51 }, { n: "קדושה", c: 54 }, { n: "הפלאה", c: 43 }, { n: "זרעים", c: 84 }, { n: "עבודה", c: 97 }, { n: "קרבנות", c: 45 }, { n: "טהרה", c: 172 }, { n: "נזיקין", c: 61 }, { n: "קניין", c: 74 }, { n: "משפטים", c: 75 }, { n: "שופטים", c: 81 }]}],
              shulchan: [{ seder: "שולחן ערוך", items: [{ n: "אורח חיים", c: 697 }, { n: "יורה דעה", c: 403 }, { n: "אבן העזר", c: 178 }, { n: "חושן משפט", c: 427 }]}]
          };
      
          function toHebrew(num) {
              if (num <= 0) return "";
              let str = "";
              const hundreds = ["", "ק", "ר", "ש", "ת"];
              const tens = ["", "י", "כ", "ל", "מ", "נ", "ס", "ע", "פ", "צ"];
              const realOnes = ["", "א", "ב", "ג", "ד", "ה", "ו", "ז", "ח", "ט"];
              if (num >= 100) { str += hundreds[Math.floor(num / 100)]; num %= 100; }
              if (num === 15) return str + "טו";
              if (num === 16) return str + "טז";
              str += tens[Math.floor(num / 10)];
              str += realOnes[num % 10];
              return str;
          }
      
          function selectAll(val) { document.querySelectorAll('#masechtotList input[type="checkbox"]').forEach(i => i.checked = val); }
      
          function toggleSeder(sourceCheckbox, sederName) {
              const checkboxes = document.querySelectorAll(`.masechet-item[data-seder="${sederName}"] input[type="checkbox"]`);
              checkboxes.forEach(cb => cb.checked = sourceCheckbox.checked);
          }
      
          function loadLibrary(libKey, btn) {
              currentLib = libKey;
              document.querySelectorAll('.lib-btn').forEach(b => b.classList.remove('active'));
              if(btn) btn.classList.add('active');
              
              document.getElementById('shasOptions').style.display = (libKey.includes('shas') || libKey.includes('bavli') || libKey.includes('yerushalmi')) ? 'block' : 'none';
              document.getElementById('torahOptions').style.display = (libKey === 'torah') ? 'block' : 'none';
              document.getElementById('mishnahOptions').style.display = (libKey === 'mishnah' || libKey === 'rambam' || libKey === 'tanakh') ? 'block' : 'none';
              document.getElementById('shulchanOptions').style.display = (libKey === 'shulchan') ? 'block' : 'none';
      
              const showHierarchical = (libKey === 'mishnah' || libKey === 'bavli' || libKey === 'yerushalmi');
              document.getElementById('groupHierarchical').style.display = showHierarchical ? 'block' : 'none';
              if(!showHierarchical) document.getElementById('hierarchicalSedarim').checked = false;
      
              const listDiv = document.getElementById('masechtotList');
              listDiv.innerHTML = "";
              let unitLabel = libKey.includes('shas') || libKey.includes('bavli') || libKey.includes('yerushalmi') ? "דפים" : (libKey === 'shulchan' ? "סימנים" : (libKey === 'torah' ? "פרשיות" : (libKey === 'chagim' ? "נושאים" : "פרקים")));
      
              fullDb[libKey].forEach(s => {
                  const title = document.createElement('div');
                  title.className = 'seder-title';
                  title.innerHTML = `<span>${s.seder}</span> <input type="checkbox" class="seder-checkbox" title="בחר הכל בסדר זה" onclick="toggleSeder(this, '${s.seder}')">`;
                  listDiv.appendChild(title);
                  
                  s.items.forEach(m => {
                      const item = document.createElement('div');
                      item.className = 'masechet-item';
                      item.setAttribute('data-seder', s.seder);
                      let countLabel = m.p ? m.p.length : m.c;
                      item.innerHTML = `<input type="checkbox" value="${m.n}" data-seder-name="${s.seder}" data-c="${m.c||0}" data-p='${JSON.stringify(m.p||[])}' data-s="${m.s||(libKey.includes('shas')?2:1)}"> <span>${m.n} (${countLabel} ${unitLabel})</span>`;
                      listDiv.appendChild(item);
                  });
              });
          }
      
          function abort() { isAborted = true; }
      
          async function process() {
              isAborted = false;
              const token = document.getElementById('token').value.trim();
              const startFolder = parseInt(document.getElementById('startNum').value);
              const endType = document.getElementById('endFolderType').value;
              const targetPath = document.getElementById('targetPath').value.trim().replace(/^\/|\/$/g, "");
              const hierarchical = document.getElementById('hierarchicalSedarim').checked;
              const selected = Array.from(document.querySelectorAll('#masechtotList .masechet-item input[type="checkbox"]:checked'));
      
              if(!token || selected.length === 0) return alert("הזן טוקן ובחר פריטים!");
      
              document.getElementById('startBtn').style.display = "none";
              document.getElementById('cancelBtn').style.display = "block";
              document.getElementById('progWrapper').style.display = "block";
              const log = document.getElementById('logBox');
              log.innerHTML = "🏁 מתחיל בתהליך...";
      
              let tasks = [];
              
              if (hierarchical) {
                  let sedarimMap = {};
                  selected.forEach(input => {
                      const sederName = input.dataset.sederName;
                      if (!sedarimMap[sederName]) sedarimMap[sederName] = [];
                      sedarimMap[sederName].push(input);
                  });
      
                  let sederKeys = Object.keys(sedarimMap);
                  let sederCounter = startFolder;
      
                  sederKeys.forEach((sederName, si) => {
                      const sederItems = sedarimMap[sederName];
                      const autoSederDigits = sederKeys.length >= 10 ? 2 : 1;
                      const sederFolderNum = String(sederCounter).padStart(autoSederDigits, '0');
                      const sederPath = targetPath ? `${targetPath}/${sederFolderNum}` : sederFolderNum;
      
                      tasks.push({ p: sederPath, t: sederName, b: `type=menu\ntitle=${sederName}\ndigits=${sederItems.length >= 10 ? 2 : 1}` });
      
                      let itemCounter = 1;
                      sederItems.forEach(input => {
                          const name = input.value;
                          const subItems = JSON.parse(input.dataset.p);
                          const count = parseInt(input.dataset.c);
                          const start = parseInt(input.dataset.s);
                          
                          const totalSubCount = subItems.length > 0 ? subItems.length : (count - start + 1);
                          const autoDigits = totalSubCount >= 10 ? 2 : 1;
      
                          const rootF = String(itemCounter).padStart(sederItems.length >= 10 ? 2 : 1, '0');
                          const rootP = `${sederPath}/${rootF}`;
      
                          tasks.push({ p: rootP, t: name, b: `type=menu\ntitle=${name}\ndigits=${autoDigits}` });
      
                          for (let i = start; i <= count; i++) {
                              const sf = String(i).padStart(autoDigits, '0');
                              const sp = `${rootP}/${sf}`;
                              const heb = toHebrew(i);
                              let title = (currentLib.includes('shas') || currentLib.includes('bavli') || currentLib.includes('yerushalmi')) ? `דף ${heb}` : `פרק ${heb}`;
                              
                              const splitS = document.getElementById('splitAmudim').checked && (currentLib.includes('shas') || currentLib.includes('bavli') || currentLib.includes('yerushalmi'));
                              const mishCount = parseInt(document.getElementById('mishCount').value);
                              let hasSub = splitS || (currentLib === 'mishnah' && mishCount > 0);
                              
                              tasks.push({ p: sp, t: title, b: `type=${hasSub?'menu':endType}\ntitle=${title}${hasSub ? '\ndigits='+(splitS ? 1 : 2) : ''}` });
      
                              if(splitS) {
                                  tasks.push({ p: `${sp}/1`, t: "עמוד א", b: `type=${endType}\ntitle=עמוד א` });
                                  tasks.push({ p: `${sp}/2`, t: "עמוד ב", b: `type=${endType}\ntitle=עמוד ב` });
                              }
                              if(currentLib === 'mishnah' && mishCount > 0) {
                                  for(let m=1; m<=mishCount; m++) tasks.push({ p: `${sp}/${String(m).padStart(m >= 10 ? 2 : 1, '0')}`, t: `משנה ${toHebrew(m)}`, b: `type=${endType}\ntitle=משנה ${toHebrew(m)}` });
                              }
                          }
                          itemCounter++;
                      });
                      sederCounter++;
                  });
      
              } else {
                  let counter = startFolder;
                  selected.forEach(input => {
                      const name = input.value;
                      const subItems = JSON.parse(input.dataset.p);
                      const count = parseInt(input.dataset.c);
                      const start = parseInt(input.dataset.s);
                      
                      const totalSubCount = subItems.length > 0 ? subItems.length : (count - start + 1);
                      const autoDigits = totalSubCount >= 10 ? 2 : 1;
      
                      const rootF = String(counter).padStart(selected.length > 9 ? 2 : 1, '0');
                      const rootP = targetPath ? `${targetPath}/${rootF}` : rootF;
      
                      tasks.push({ p: rootP, t: name, b: `type=menu\ntitle=${name}\ndigits=${autoDigits}` });
      
                      if (currentLib === 'torah') {
                          const noAliyotChecked = document.getElementById('noAliyot').checked;
                          subItems.forEach((pn, pi) => {
                              const pf = String(pi + 1).padStart(autoDigits, '0');
                              const pp = `${rootP}/${pf}`;
                              
                              if (noAliyotChecked) {
                                  tasks.push({ p: pp, t: `פרשת ${pn}`, b: `type=${endType}\ntitle=פרשת ${pn}` });
                              } else {
                                  tasks.push({ p: pp, t: `פרשת ${pn}`, b: `type=menu\ntitle=פרשת ${pn}\ndigits=1` });
                                  ["ראשון","שני","שלישי","רביעי","חמישי","שישי","שביעי","מפטיר"].forEach((aly, ai) => {
                                      tasks.push({ p: `${pp}/${ai+1}`, t: `עליה ${aly}`, b: `type=${endType}\ntitle=עליה ${aly}` });
                                  });
                              }
                          });
                      } else if (currentLib === 'chagim') {
                          subItems.forEach((subName, si) => {
                              const sf = String(si + 1).padStart(autoDigits, '0');
                              const sp = `${rootP}/${sf}`;
                              tasks.push({ p: sp, t: subName, b: `type=${endType}\ntitle=${subName}` });
                          });
                      } else {
                          for (let i = start; i <= count; i++) {
                              const sf = String(i).padStart(autoDigits, '0');
                              const sp = `${rootP}/${sf}`;
                              const heb = toHebrew(i);
                              let title = (currentLib.includes('shas') || currentLib.includes('bavli') || currentLib.includes('yerushalmi')) ? `דף ${heb}` : (currentLib === 'shulchan' ? `סימן ${heb}` : `פרק ${heb}`);
                              
                              const splitS = document.getElementById('splitAmudim').checked && (currentLib.includes('shas') || currentLib.includes('bavli') || currentLib.includes('yerushalmi'));
                              const seifim = parseInt(document.getElementById('seifimCount').value);
                              const mishCount = parseInt(document.getElementById('mishCount').value);
                              
                              let hasSub = splitS || (currentLib === 'shulchan' && seifim > 0) || (['mishnah','rambam','tanakh'].includes(currentLib) && mishCount > 0);
                              
                              tasks.push({ p: sp, t: title, b: `type=${hasSub?'menu':endType}\ntitle=${title}${hasSub ? '\ndigits='+(splitS ? 1 : 2) : ''}` });
      
                              if(splitS) {
                                  tasks.push({ p: `${sp}/1`, t: "עמוד א", b: `type=${endType}\ntitle=עמוד א` });
                                  tasks.push({ p: `${sp}/2`, t: "עמוד ב", b: `type=${endType}\ntitle=עמוד ב` });
                              }
                              if(currentLib === 'shulchan' && seifim > 0) {
                                  for(let s=1; s<=seifim; s++) tasks.push({ p: `${sp}/${String(s).padStart(s >= 10 ? 2 : 1, '0')}`, t: `סעיף ${toHebrew(s)}`, b: `type=${endType}\ntitle=סעיף ${toHebrew(s)}` });
                              }
                              if(['mishnah','rambam','tanakh'].includes(currentLib) && mishCount > 0) {
                                  let subL = currentLib === 'mishnah' ? "משנה" : (currentLib === 'rambam' ? "הלכה" : "פסוק");
                                  for(let m=1; m<=mishCount; m++) tasks.push({ p: `${sp}/${String(m).padStart(m >= 10 ? 2 : 1, '0')}`, t: `${subL} ${toHebrew(m)}`, b: `type=${endType}\ntitle=${subL} ${toHebrew(m)}` });
                              }
                          }
                      }
                      counter++;
                  });
              }
      
              for (let i = 0; i < tasks.length; i++) {
                  if (isAborted) break;
                  const ok = await upload(token, tasks[i].p, tasks[i].b);
                  if(ok) log.innerHTML += `<div>✓ SUCCESS: ${tasks[i].p}</div>`;
                  else log.innerHTML += `<div style="color:red">✗ FAILED: ${tasks[i].p}</div>`;
                  let pct = Math.round(((i + 1) / tasks.length) * 100);
                  document.getElementById('progBar').style.width = pct + "%";
                  document.getElementById('progText').innerText = pct + "%";
                  document.getElementById('progCounts').innerText = `${i+1} / ${tasks.length}`;
                  log.scrollTop = log.scrollHeight;
              }
      
              document.getElementById('startBtn').style.display = "block";
              document.getElementById('cancelBtn').style.display = "none";
          }
      
          async function upload(token, path, body) {
              const fd = new FormData();
              fd.append('token', token);
              fd.append('path', `ivr2:${path}/ext.ini`);
              fd.append('qqfile', new Blob([body], { type: 'text/plain;charset=utf-8' }), 'ext.ini');
              try {
                  const r = await fetch(`https://www.call2all.co.il/ym/api/UploadFile`, { method: 'POST', body: fd });
                  const d = await r.json();
                  return d && (d.responseStatus === "OK" || d.status === "OK");
              } catch(e) { return false; }
          }
      
          loadLibrary('bavli');
      </script>
      
      </body>
      </html>>
      

      כדי שכולם יוכלו להשתמש בכלי המטורף הזה בקלות, הנה הוראות ההכנה וההפעלה צעד אחר צעד, כתובות בצורה ברורה ופשוטה (בדיוק מה שצריך להדביק בפורום או לשלוח לחברים):

      📋 הוראות הכנה והפעלה ל"הטי"ל V1.0"

      כדי להפוך את הקוד שקיבלתם לתוכנה חיה שעובדת אצלכם במחשב, בצעו את הפעולות הבאות:

      שלב 1: יצירת הקובץ

      העתיקו את כל הקוד (מהמילה <!DOCTYPE html> ועד הסוף).
      פתחו במחשב את התוכנה "פנקס רשימות" (Notepad).
      הדביקו את הקוד בתוך פנקס הרשימות.
      לחצו על תפריט קובץ (File) -> שמור בשם (Save As).

      זה השלב הכי חשוב:

      תחת "שם הקובץ", כתבו: hatil.html (חובה להוסיף את הסיומת .html).
      תחת "שמור כסוג" (Save as type), בחרו ב-"כל הקבצים" (All Files).
      לחצו על שמור.

      שלב 2: פתיחת התוכנה

      גשו לתיקייה שבה שמרתם את הקובץ.
      לחצו עליו פעמיים (הוא אמור להיפתח בדפדפן כרום או אדג' שלכם).
      מזל טוב! אתם בתוך ממשק ה-Premium של הטי"ל.

      שלב 3: הגדרות והקמה (איך יוצרים את הספריה?)

      טוקן (API Token): הכניסו את הטוקן שלכם מימות המשיח (המספר של הקו, נקודתיים, והסיסמה האישית. למשל: 0771234567:123456).
      נתיב יעד: אם אתם רוצים שהספריה תיפתח בתוך שלוחה קיימת, כתבו את מספרה (למשל: 1/5). אם תשאירו ריק, הספריה תיפתח בשורש של הקו.
      בחירת תוכן: לחצו על הכפתורים בצד ימין (ש"ס, תורה, שו"ע וכו'). הרשימה תתעדכן אוטומטית.
      סימון: סמנו ב-V את המסכתות או הספרים שאתם רוצים להקים (אפשר להשתמש בכפתור "בחר הכל").
      סוג שלוחה: בחרו אם אתם רוצים שהשלוחות יהיו "השמעת קבצים" או "הקלטה".

      שלב 4: שיגור!

      לחצו על הכפתור הכחול והגדול: "🚀 התחל הקמה".
      בצד שמאל למטה ייפתח לכם ה-Log (יומן הפעולות). אתם תראו בזמן אמת איך המערכת מקימה שלוחה אחרי שלוחה בשיא המהירות.
      בסיום, תקבלו הודעה ירוקה: "הקמת הספריה הושלמה בהצלחה!".
      💡 טיפ חשוב:
      אם בחרתם להקים ספריה ענקית (כמו כל הש"ס), זה יכול לקחת כמה דקות בגלל הכמות האדירה של השלוחות. אל תסגרו את הדף עד לסיום הפעולה.
      בהצלחה ובהנאה!

      תגובות כאן

      פורסם בהסברים מסודרים ממשתמשים
      L
      lavitoren הטי"ל
    • "ומתן שכרה בצידה"💰💵 משהו ש-קל! למייבינים🧐 במקצת ומעלה🔝

      הציע לי חברי רעיון מבריק ואולי מרוויח והוא כדלהלן:

      יצירת קו אשר יש בו שלוחה שאליו מקליטים הקלטה והתמלול נשלח למייל של המקליט
      (וכמובן שהוא בחר מתחילה את המייל ע"י הקלדה) ואולי שיהיה אפשר לשמור מייל
      וזה יביא תועלת עצומה לאולי אפילו עשרות אלפי (!!) אברכים ושאינם במקום לכתוב שעות ידברו דקות
      ו..זהו זה אצלהם במייל...
      ולמה התכוונתי מרוויח אז ככה:
      אם יעשו חיוב חד פעמי של עד 30 ש"ח לתמיד (ככה אני משער לעצמי)
      ומאז יש שימוש ללא הגבלה. לדעתי זה ירוץ וחוץ מזה מן הסתם גם יתרמו לזה
      ובסייעתא דשמיא המתמללים הרובוטים היום השתדרגו משהו משהו אני משתמש ב - עברית
      וזה 99% מדוייק ובד"כ 100%
      אבל מוגבל שם ל3 שעות (180 דקות) בחודש בחינם אולי יש אחרים אבל אם אין, פשוט התרומות יכסו
      בקיצור לדעתי רעיון ע-נ-ק!!

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

      נ.ב.

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

      פורסם בשאלות ועזרה הדדית
      L
      lavitoren הטי"ל
    • חמש הצעות למהפכה הבאה בימות המשיח: מבינה מלאכותית ועד "מצב חברותא" 🚀💎

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

      1. "תקציר מנהלים" בלחיצת כפתור 📝🤖
        הבעיה: בקווי תוכן רבים יש שיעורים והרצאות של שעה ומעלה. למאזין אין תמיד זמן לשמוע הכל רק כדי לדעת אם התוכן רלוונטי עבורו.
        ההצעה: הוספת מנגנון AI שיודע לסרוק את הקובץ. במהלך ההשמעה, לחיצה על מקש (למשל 9) תשמיע למאזין סיכום קולי של 2 דקות עם הנקודות העיקריות.
        החידוש: הנגשת תוכן ארוך בצורה מהירה ויעילה, בלי לאבד את המאזינים בדרך.

      2. "מצב נהיגה" חכם (Adaptive IVR) 🚗🔇
        הבעיה: הקשה על מקשים תוך כדי נהיגה (או רכיבה על אופניים ברוח) היא מסוכנת ולא נוחה.
        ההצעה: המערכת תזהה רעשי רקע של נסיעה או רוח, ותציע לעבור ל"מצב ידיים חופשיות".
        איך זה עובד? במקום להקיש, המאזין יוכל לומר פקודות כמו "כן", "הבא" או "חזור". אם המערכת תזהה חוסר תגובה, היא תעבור אוטומטית ל"השמעה רציפה" כדי למנוע התעסקות עם המכשיר.
        החידוש: בטיחות מעל הכל וחוויית שימוש חלקה בכל תנאי שטח.

      3. "מצב חברותא" – האזנה מסונכרנת 🎧🤝
        הקונספט: מאפשר לשני מאזינים (או יותר) להאזין לאותו קובץ שמע בו-זמנית, בסנכרון מלא.
        איך זה עובד? מאזין א' פותח "חדר" ומקבל קוד. מאזין ב' מקיש את הקוד. מעכשיו, שניהם שומעים יחד. אם אחד עוצר או מדלג – זה קורה אצל שניהם בו-זמנית.
        למה זה חסר? ללמידה משותפת מרחוק, להורים שמשמיעים סיפור לילד שנמצא במקום אחר, או לקבוצות דיון.

      4. חלוקה ל"פרקים" בתוך קובץ שמע 📑📌
        הבעיה: קשה מאוד לנווט בתוך קבצים ארוכים. הדילוג כיום הוא "על עיוור".
        ההצעה: מנהל המערכת יוכל להגדיר נקודות זמן בקובץ (דרך ה-ext.ini). לחיצה על מקש מסוים תקפיץ את המאזין ישר לפרק הבא (למשל: "מעבר לחלק ההלכתי של השיעור").
        החידוש: שליטה מלאה בתוכן, בדומה לפלטפורמות הפודקאסטים והיוטיוב המובילות בעולם.
        (לא סימניות אלא חלוקה)

      5. "עקוב אחריי" בין-מערכתי (Global Follow) 🏃‍♂️📞
        הבעיה: לכל מאזין יש מספר מערכות שהוא אוהב, והוא צריך להתקשר לכל אחת בנפרד כדי לבדוק מה התחדש.
        ההצעה: פיצ'ר "המועדפים שלי". מאזין יוכל לסמן שלוחות ממערכות שונות כ"מועדפות". בפעם הבאה שיתקשר למערכת הבית שלו, הוא יקבל עדכון: "בקו 'המאורות' עלה שיעור חדש, למעבר הקש 1".
        החידוש: הפיכת ימות המשיח לרשת חברתית-תוכנית אחת גדולה, מה שיגדיל משמעותית את זמן השהייה במערכות.

      לסיכום,
      אני מאמין שהכלים הללו יהפכו את המערכת של ימות המשיח למתקדמת ונגישה עוד יותר. אני בטוח שצוות הפיתוח המדהים יוכל לקחת את הרעיונות הללו ולהפוך אותם למציאות, כפי שעשו פעמים רבות בעבר 🙏
      מה דעתכם? איזה פיצ'ר הכי הייתם רוצים לראות במערכת שלכם?
      אשמח לשמוע אתכם בתגובות! 😉
      אם אהבתם את הרעיונות – תנו לייק 👍 כדי שהפוסט יגיע למפתחים ונוכל להוביל יחד את השינוי!
      תודה רבה לכולם!
      נ.ב. - @ימות-המשיח , נשמח מאוד לשמוע את דעתכם המקצועית על ההצעות.

      פורסם בבקשות לפיתוח
      L
      lavitoren הטי"ל
    • RE: יש חיפוש בתוך שלוחת השמעת קבצים בחינם?

      @פלוס מה עלבון בביטקוין אפשר לקנות כמה דברים (מאז שטראמפ הכריז ע"ז כמטבע ממשלתי משהו באמריצ'קע) אבל ב'מטבעות זהב'?! ספר נא לי מה אפשר לקנות🤑
      אהה!! עכשיו נזכרתי אפשר לקנות את הארון החלוד של זעליג בן גיטה שפרייכל וטינהג פלגם הא??!😁

      פורסם בשאלות ועזרה הדדית
      L
      lavitoren הטי"ל
    • 🚀 מדריך למשתמש: מחולל השלוחות המתקדם של "יהונייסען מערכות"

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

      אם אי פעם מצאתם את עצמכם פותחים עשרות (או מאות) שלוחות במערכת הטלפונית אחת-אחת, מעלים קבצי ext.ini ידנית ומגדירים הגדרות דומות שוב ושוב – הכלי הזה נוצר במיוחד עבורכם.

      🔥 מה זה "יהונייסען מערכות" ולמה זה קריטי עבורכם?

      מערכת זו היא מחולל שלוחות רב-שכבתי. היא מאפשרת לכם לבנות מבנה שלם של מערכת טלפונית (עד 3 שכבות עומק) תוך שניות בודדות.

      התועלת המרכזית:

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

      אוטומציה חכמה: יצירת כותרות אוטומטיות (א, ב, ג... או 1, 2, 3...) וסידור אפסים מובילים (01, 02) בלחיצת כפתור.

      גמישות מקסימלית: תמיכה בכל סוגי השלוחות (תפריטים, השמעת קבצים, חדרי ועידה, API ועוד).

      👤 למי התוכנה מיועדת?

      מנהלי מערכות תוכן: המקימים קווי מידע, שיעורי תורה או מערכות מורכבות.

      מפתחים: הזקוקים להקמה מהירה של תשתית לזיהוי נתונים או שלוחות API.

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

      🛠️ הוראות הפעלה – צעד אחר צעד

      שלב 1: חיבור למערכת
      טוקן גישה: הזינו את הטוקן של המערכת שלכם (למשל 0770000000:123456). זהו המפתח שמאפשר לתוכנה "לדבר" עם השרת של ימות המשיח.
      כתובת השלוחה: ציינו איפה אתם רוצים שהשלוחות ייפתחו. אם תשאירו ריק, הן ייפתחו בשורש (התפריט הראשי). אם תכתבו 1/5, השלוחות החדשות ייפתחו בתוך שלוחה 5 שביחידה 1.

      שלב 2: הגדרת השלוחות הראשיות (השכבה הראשונה)
      סוג כותרת (Title): בחרו איך המערכת תזהה את השלוחה. תוכלו לבחור בגימטריה (א', ב'), מספרים, אנגלית, או טקסט חופשי משולב.
      סוג השלוחה (Type): בחרו את תפקוד השלוחה (למשל menu לתפריט או playfile להשמעה).
      טווח שלוחות: הגדירו מאיזה מספר להתחיל ובאיזה לסיים (למשל מ-1 עד 10).
      שורות קוד נוספות: כאן ניתן להוסיף הגדרות ספציפיות שיופיעו בכל השלוחות (למשל: say_zman_today=yes).

      שלב 3: הוספת תת-שלוחות (אופציונלי - הקסם האמיתי!)
      סימון ה-V בתיבת "יצירת תת-שלוחות" יפתח לכם אפשרות להקים בתוך כל שלוחה ראשית, סדרה נוספת של שלוחות פנימיות.
      דוגמה: אם יצרתם שלוחות 1-5, ובכל אחת הגדרתם תת-שלוחות 1-3, התוכנה תייצר אוטומטית 15 שלוחות מוגדרות מראש!
      ניתן לרדת עד לשכבה שלישית (תת-תת-שלוחה) ליצירת מבנה עומק מורכב.

      שלב 4: ביצוע ומעקב
      לחצו על הכפתור המוזהב "🚀 התחל פתיחת שלוחות".
      בצד ימין יופיע לוג (יומן פעולות) שיעדכן אתכם בזמן אמת על כל שלוחה שנוצרת.
      במרכז תראו פס התקדמות שיציג כמה אחוזים מהמשימה הושלמו.
      💡 טיפים למקצוענים:
      אפסים מובילים: אם אתם פותחים יותר מ-10 שלוחות, מומלץ להגדיר "כמות ספרות" ל-2. כך השלוחות ייראו כך: 01, 02... 10 והסדר בשרת יישמר.
      כותרת משולבת: ניתן לבחור "שילוב: טקסט ידני לפני" ולכתוב "שיעור מספר". התוצאה תהיה כותרות כמו: "שיעור מספר א", "שיעור מספר ב" וכו'.
      בטיחות: אם טעיתם, ניתן ללחוץ על "ביטול פעולה" בכל שלב כדי לעצור את התהליך.
      זהו, אתם מוכנים!
      השתמשו בכלי בחוכמה, והפכו את ניהול המערכת שלכם לקל, מהיר ומקצועי הרבה יותר.
      בהצלחה!
      יהונייסען מערכות – כי הזמן שלכם שווה יותר.

      הנה הקוד המצורף לתגובות כאן

      <!DOCTYPE html>
      <html lang="he" dir="rtl">
      <head>
          <meta charset="UTF-8">
          <title>יהונייסען מערכות - מחולל שלוחות רב-שכבתי מתקדם</title>
          <style>
              :root {
                  --primary: #f0c965; 
                  --primary-light: #fbe8a6;
                  --primary-dark: #b89728; 
                  --danger: #ff5252; 
                  --danger-hover: #ff1744; 
                  --bg: #0d0e12; 
                  --card-bg: #16181d; 
                  --input-bg: #101216;
                  --dark: #e4e6eb; 
                  --border: #2a2e39; 
                  --accent: #f0c965;
                  --shadow: 0 12px 40px rgba(0, 0, 0, 0.6);
              }
              * { box-sizing: border-box; }
              body { 
                  font-family: 'Segoe UI', system-ui, -apple-system, sans-serif; 
                  margin: 0; 
                  background: radial-gradient(circle at top, #1a1e29 0%, var(--bg) 100%);
                  color: var(--dark); 
                  text-align: right; 
                  min-height: 100vh;
                  display: flex;
                  flex-direction: column;
                  justify-content: center;
                  padding: 20px 0;
              }
              .wrapper { width: 100%; max-width: 980px; margin: 0 auto; padding: 0 20px; }
              .card { 
                  background: var(--card-bg); 
                  padding: 35px; 
                  border-radius: 14px; 
                  box-shadow: var(--shadow); 
                  margin-bottom: 25px; 
                  border: 1px solid var(--border); 
                  position: relative;
                  overflow: hidden;
              }
              .card::before {
                  content: '';
                  position: absolute;
                  top: 0; right: 0; left: 0;
                  height: 3px;
                  background: linear-gradient(90deg, var(--primary-dark), var(--primary), var(--primary-light));
              }
              .header-container {
                  border-bottom: 1px solid var(--border);
                  padding-bottom: 18px;
                  margin-bottom: 25px;
                  display: flex;
                  justify-content: space-between;
                  align-items: center;
              }
              h2 { 
                  margin: 0; 
                  color: #ffffff; 
                  font-size: 26px; 
                  font-weight: 800;
                  letter-spacing: -0.5px;
                  display: flex;
                  align-items: center;
                  gap: 10px;
              }
              .brand-subtitle {
                  font-size: 11px;
                  color: var(--primary);
                  font-family: 'Segoe UI', Tahoma, sans-serif;
                  font-weight: 700;
                  letter-spacing: 1.5px;
                  text-transform: uppercase;
                  background: rgba(240, 201, 101, 0.1);
                  padding: 6px 12px;
                  border-radius: 20px;
                  border: 1px solid rgba(240, 201, 101, 0.2);
              }
              .grid { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; margin-top: 20px; }
              .input-group { display: flex; flex-direction: column; gap: 8px; }
              label { font-weight: 600; font-size: 13.5px; color: #b0b3b8; display: flex; align-items: center; gap: 6px; }
              input, select, textarea { 
                  padding: 12px 14px; 
                  border: 1px solid var(--border); 
                  border-radius: 8px; 
                  font-size: 14px; 
                  outline: none; 
                  transition: all 0.25s ease; 
                  font-family: inherit; 
                  background: var(--input-bg); 
                  color: #ffffff;
              }
              input:hover, select:hover, textarea:hover {
                  border-color: #3f4656;
              }
              input:focus, select:focus, textarea:focus { 
                  border-color: var(--accent); 
                  background: #14171f;
                  box-shadow: 0 0 0 3px rgba(240, 201, 101, 0.15); 
              }
              .full-width { grid-column: 1 / -1; }
      
              /* Info Box */
              .info-box {
                  background: linear-gradient(135deg, rgba(240, 201, 101, 0.05) 0%, rgba(240, 201, 101, 0.02) 100%);
                  border: 1px solid rgba(240, 201, 101, 0.2);
                  padding: 14px 18px;
                  border-radius: 8px;
                  margin-bottom: 22px;
                  font-size: 13.5px;
                  color: #fbe8a6;
                  display: flex;
                  align-items: center;
                  gap: 12px;
                  line-height: 1.5;
              }
      
              /* Fancy Gold Buttons */
              .btn-main { 
                  background: linear-gradient(135deg, #f0c965 0%, #d4af37 100%);
                  color: #0d0e12; 
                  border: none; 
                  padding: 14px 20px; 
                  border-radius: 8px; 
                  cursor: pointer; 
                  font-size: 16px; 
                  font-weight: 700; 
                  width: 100%; 
                  transition: all 0.3s ease; 
                  margin-top: 10px;
                  box-shadow: 0 4px 20px rgba(212, 175, 55, 0.25);
                  display: flex;
                  align-items: center;
                  justify-content: center;
                  gap: 8px;
              }
              .btn-main:hover { 
                  background: linear-gradient(135deg, #fbe8a6, #e6c553);
                  transform: translateY(-2px);
                  box-shadow: 0 6px 25px rgba(212, 175, 55, 0.4);
              }
              .btn-main:active { transform: translateY(0); }
              .btn-main:disabled { 
                  background: #2a2e39; 
                  color: #6c757d;
                  cursor: not-allowed; 
                  box-shadow: none;
                  transform: none;
              }
      
              .btn-cancel { 
                  background: linear-gradient(135deg, #ff5252 0%, #d32f2f 100%);
                  color: white; 
                  border: none; 
                  padding: 14px 20px; 
                  border-radius: 8px; 
                  cursor: pointer; 
                  font-size: 16px; 
                  font-weight: 700; 
                  width: 100%; 
                  transition: all 0.3s ease; 
                  margin-top: 15px; 
                  display: none; 
                  box-shadow: 0 4px 15px rgba(211, 47, 47, 0.3);
              }
              .btn-cancel:hover { 
                  background: linear-gradient(135deg, #ff6b6b, #c62828);
              }
      
              .progress-wrapper { margin-top: 25px; display: none; }
              .progress-container { width: 100%; background: var(--input-bg); height: 26px; border-radius: 8px; overflow: hidden; position: relative; border: 1px solid var(--border); }
              .progress-bar { height: 100%; width: 0%; background: linear-gradient(90deg, #d4af37, #fbe8a6); transition: width 0.3s ease; }
              .progress-text { position: absolute; width: 100%; text-align: center; top: 0; line-height: 26px; color: #0d0e12; font-weight: 800; font-size: 12.5px; text-shadow: 0 0 2px rgba(255,255,255,0.4); }
              
              .log-box { 
                  background: #08090c; 
                  color: #00e676; 
                  padding: 18px; 
                  border-radius: 8px; 
                  font-family: 'Consolas', monospace; 
                  height: 280px; 
                  overflow-y: auto; 
                  font-size: 12.5px; 
                  line-height: 1.6; 
                  border: 1px solid var(--border);
                  box-shadow: inset 0 2px 8px rgba(0,0,0,0.9);
              }
              .log-info { color: #64b5f6; }
              .log-success { color: #00e676; font-weight: bold; }
              .log-error { color: #ff5252; }
              .log-warn { color: #ffb74d; }
              .section-box { 
                  background: #111318; 
                  padding: 22px; 
                  border-radius: 10px; 
                  border: 1px solid var(--border); 
                  margin-top: 5px; 
                  transition: all 0.3s ease;
              }
      
              /* Tooltip Styles */
              .tooltip-container {
                  position: relative;
                  display: inline-block;
                  cursor: help;
                  border-bottom: 1px dashed var(--accent);
                  color: var(--accent);
                  font-weight: 600;
              }
              .tooltip-container .tooltip-text {
                  visibility: hidden;
                  width: 250px;
                  background-color: #1e222d;
                  color: #fff;
                  text-align: center;
                  border-radius: 8px;
                  padding: 12px;
                  position: absolute;
                  z-index: 100;
                  bottom: 135%;
                  left: 50%;
                  transform: translateX(-50%);
                  opacity: 0;
                  transition: opacity 0.3s ease, transform 0.3s ease;
                  font-size: 12.5px;
                  font-weight: normal;
                  border: 1px solid var(--border);
                  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.7);
              }
              .tooltip-container .tooltip-text::after {
                  content: "";
                  position: absolute;
                  top: 100%;
                  left: 50%;
                  margin-left: -5px;
                  border-width: 5px;
                  border-style: solid;
                  border-color: #1e222d transparent transparent transparent;
              }
              .tooltip-container:hover .tooltip-text {
                  visibility: visible;
                  opacity: 1;
                  transform: translateX(-50%) translateY(-2px);
              }
          </style>
      </head>
      <body>
      
      <div class="wrapper">
          <div class="card">
              <div class="header-container">
                  <div>
                      <h2>✨ יהונייסען מערכות</h2>
                      <div style="font-size: 13px; color: #8a8f98; margin-top: 4px;">מחולל שלוחות רב-שכבתי מתקדם</div>
                  </div>
                  <div class="brand-subtitle">TYL Pro Version</div>
              </div>
              
              <div class="info-box">
                  <span style="font-size: 18px;">💡</span>
                  <div>
                      <strong>למה הכלי הזה עוזר לך?</strong> חוסך שעות של עבודה ידנית וטונות של טירחה בפתיחת שלוחות אחת-אחת בשרת, ומייעל את ניהול הזמן בצורה משמעותית.
                  </div>
              </div>
      
              <div class="grid">
                  <div class="input-group full-width">
                      <label>
                          🔑 טוקן גישה:
                          <span class="tooltip-container">❓ הסבר
                              <span class="tooltip-text">קוד זיהוי ייחודי המקשר את התוכנה למערכת הטלפונית שלך (לדוגמא 0770000000:123456).</span>
                          </span>
                      </label>
                      <input type="text" id="token" placeholder="הכנס טוקן מערכת (לדוגמא 0770000000:123456)">
                  </div>
                  <div class="input-group full-width">
                      <label>
                          📂 כתובת השלוחה (ללא סלש בהתחלה):
                          <span class="tooltip-container">❓ הסבר
                              <span class="tooltip-text">המיקום במערכת שבו ייפתחו השלוחות, יש להזין ללא סלש בהתחלה (למשל: 1 או 1/2. השאר ריק עבור שורש המערכת).</span>
                          </span>
                      </label>
                      <input type="text" id="targetPath" placeholder="לדוגמה: 1 (הקפד להזין ללא סלש בהתחלה, או השאר ריק לשורש)">
                  </div>
      
                  <!-- הגדרות שלוחה ראשית -->
                  <div class="input-group">
                      <label>
                          🏷️ סוג כותרת (Title) לשלוחות הראשיות:
                          <span class="tooltip-container">❓ הסבר
                              <span class="tooltip-text">הצורה שבה המערכת תקריא או תציג את שם השלוחה (אותיות עבריות, מספרים, או אנגלית).</span>
                          </span>
                      </label>
                      <select id="namingType" onchange="checkNamingCustom('namingType', 'namingCustomContainer')">
                          <option value="hebrew_extended">עברית רגילה (א, b... י, יא...)</option>
                          <option value="hebrew_strict">עברית עד ת' בלבד (ואז מספרים)</option>
                          <option value="numbers">מספרים (1, 2, 3...)</option>
                          <option value="english">אותיות באנגלית (A, B, C...)</option>
                          <option value="empty">ריק (ללא כותרת בכלל)</option>
                          <option value="custom_only">הכנסה ידנית בלבד</option>
                          <option value="combined_before">שילוב: טקסט ידני לפני המספר/אות</option>
                          <option value="combined_after">שילוב: טקסט ידני אחרי המספר/אות</option>
                      </select>
                      <div id="namingCustomContainer" style="display:none; margin-top:8px;">
                          <input type="text" id="namingCustomText" placeholder="הכנס טקסט ידני (ניתן לשלב רווחים)">
                      </div>
                  </div>
      
                  <div class="input-group">
                      <label>
                          ⚙️ סוג השלוחה הראשית (type):
                          <span class="tooltip-container">❓ הסבר
                              <span class="tooltip-text">ההגדרה המקצועית של התפקיד שהשלוחה תמלא במערכת הטלפונית (כגון תפריט, השמעת קבצים וכו').</span>
                          </span>
                      </label>
                      <select id="folderType" onchange="checkCustomType('folderType', 'customFolderType')">
                          <optgroup label="שלוחות בשימוש גבוה (הבסיס לכל מערכת)">
                              <option value="menu">menu - יצירת תפריט בחירה (הקש 1 ל..., הקש 2 ל...)</option>
                              <option value="playfile">playfile - השמעת קבצי שמע למאזינים</option>
                              <option value="record">record - שלוחת הקלטת הודעות (תא קולי או הקלטות)</option>
                              <option value="confbridge">confbridge - חדר ועידה רב-משתתפים או שידור חי</option>
                              <option value="routing">routing - ניתוב השיחה למספר טלפון חיצוני</option>
                              <option value="api">api - שלוחה למפתחים המקשרת לשרת חיצוני</option>
                              <option value="template_add_number">template_add_number - הוספה מרשימת תפוצה</option>
                              <option value="template_remove_number">template_remove_number - הסרה מרשימת תפוצה</option>
                          </optgroup>
                          <optgroup label="שלוחות בשימוש בינוני (פיצ'רים פופולריים)">
                              <option value="recording_and_entering_data">recording_and_entering_data - קליטת נתונים (ת.ז, גיל) והקלטות</option>
                              <option value="tzintuk">tzintuk - הפעלת שירות צינתוקים (צילצול וניתוק)</option>
                              <option value="last_play">last_play - חזרה לנקודה האחרונה בה המאזין עצר</option>
                              <option value="zmanim">zmanim - השמעת זמני היום לפי מיקום גיאוגרפי</option>
                              <option value="trivia_questions">trivia_questions - משחקי טריוויה (שאלות ותשובות)</option>
                              <option value="daily_message">daily_message - השמעת הודעה המשתנה לפי תאריך</option>
                              <option value="music_on_hold">music_on_hold - מוזיקה בהמתנה או רדיו חי</option>
                          </optgroup>
                          <optgroup label="שלוחות בשימוש נמוך / ייעודי">
                              <option value="queue">queue - ניהול תור נציגים למוקדי שירות</option>
                              <option value="seker">seker - עריכת סקרים טלפוניים ושמיעת תוצאות</option>
                              <option value="approval_number">approval_number - חלוקת מספרי אישור להגרלות</option>
                              <option value="time_keeper">time_keeper - מערכת שעון נוכחות לעובדים</option>
                              <option value="sale_products">sale_products - מכירת מוצרים או כסאות</option>
                              <option value="points_edit">points_edit - ניהול וצבירת נקודות למאזינים</option>
                              <option value="chapter_receive">chapter_receive - חלוקת פרקי לימוד</option>
                              <option value="codes">codes - חלוקת קודים או קופונים</option>
                              <option value="access_filter">access_filter - סינון כניסה לשלוחות לפי זמנים</option>
                              <option value="checking_units">checking_units - בדיקת יתרת יחידות בקו</option>
                              <option value="admin_login">admin_login - כניסה טלפונית לניהול המערכת</option>
                              <option value="hangup">hangup - ניתוק השיחה באופן אוטומטי</option>
                          </optgroup>
                          <option value="custom">הכנסה ידנית...</option>
                      </select>
                      <input type="text" id="customFolderType" placeholder="הכנס שם סוג שלוחה ידנית" style="display:none; margin-top:8px;">
                  </div>
      
                  <div class="input-group">
                      <label>
                          ▶️ מספר שלוחה התחלתי:
                          <span class="tooltip-container">❓ הסבר
                              <span class="tooltip-text">המספר שממנו תתחיל יצירת השלוחות בשרת (למשל מתחילים בשלוחה 1).</span>
                          </span>
                      </label>
                      <input type="number" id="startNum" value="1" min="0">
                  </div>
                  <div class="input-group">
                      <label>
                          ⏹️ מספר שלוחה סופי בשרת:
                          <span class="tooltip-container">❓ הסבר
                              <span class="tooltip-text">המספר שבו תסתיים סדרת פתיחת השלוחות הראשית.</span>
                          </span>
                      </label>
                      <input type="number" id="endNum" value="5" min="1">
                  </div>
                  <div class="input-group full-width">
                      <label>
                          🔢 כמות ספרות לשלוחה ראשית (אפסים מובילים):
                          <span class="tooltip-container">❓ הסבר
                              <span class="tooltip-text">קביעת מבנה אחיד למספרי השלוחות על ידי הוספת אפסים משמאל (לדוגמה: עבור 2 ספרות, שלוחה 1 תהפוך ל-01).</span>
                          </span>
                      </label>
                      <input type="number" id="digitsCount" value="1" min="1" max="6">
                  </div>
      
                  <div class="input-group full-width">
                      <label>
                          📝 שורות קוד נוספות לקובץ ext.ini (שלוחות ראשיות בלבד):
                          <span class="tooltip-container">❓ הסבר
                              <span class="tooltip-text">הגדרות מתקדמות נוספות שיוכנסו אוטומטית לקובץ ההגדרות של השלוחה (ext.ini).</span>
                          </span>
                      </label>
                      <textarea id="extraCodeMain" rows="2" placeholder="לדוגמה:&#10;enter_id=yes"></textarea>
                  </div>
      
                  <!-- הגדרות תת-שלוחה -->
                  <div class="input-group full-width section-box">
                      <div style="display: flex; align-items: center; gap: 10px; margin-bottom: 12px;">
                          <input type="checkbox" id="subFoldersCheck" onchange="toggleSubFolders()" style="width: 18px; height: 18px; cursor: pointer; accent-color: var(--accent);">
                          <label for="subFoldersCheck" style="cursor: pointer; color: var(--dark); font-size: 15px; font-weight: 700;">📁 יצירת תת-שלוחות</label>
                      </div>
                      <div id="subConfig" class="grid" style="display: none; margin: 0;">
                          <div class="input-group">
                              <label>🏷️ סוג כותרת לתת-השלוחות:</label>
                              <select id="subNamingType" onchange="checkNamingCustom('subNamingType', 'subNamingCustomContainer')">
                                  <option value="hebrew_matrix">מטריצת עברית (אא, אב, אג... או בא, בב...)</option>
                                  <option value="hebrew_extended">עברית רגילה (א, ב... י, יא...)</option>
                                  <option value="numbers">מספרים (1, 2, 3...)</option>
                                  <option value="english">אותיות באנגלית (A, B, C...)</option>
                                  <option value="empty">ריק (ללא כותרת בכלל)</option>
                                  <option value="custom_only">הכנסה ידנית בלבד</option>
                                  <option value="combined_before">שילוב: טקסט ידני לפני</option>
                                  <option value="combined_after">שילוב: טקסט ידני אחרי</option>
                              </select>
                              <div id="subNamingCustomContainer" style="display:none; margin-top:8px;">
                                  <input type="text" id="subNamingCustomText" placeholder="הכנס טקסט ידני לתת-שלוחה">
                              </div>
                          </div>
                          <div class="input-group">
                              <label>⚙️ סוג השלוחה לתת-השלוחות (type):</label>
                              <select id="subFolderType" onchange="checkCustomType('subFolderType', 'customSubFolderType')">
                                  <optgroup label="שלוחות בשימוש גבוה">
                                      <option value="menu">menu - תפריט בחירה</option>
                                      <option value="playfile">playfile - השמעת קבצי שמע</option>
                                      <option value="record">record - הקלטת הודעות</option>
                                      <option value="confbridge">confbridge - חדר ועידה</option>
                                      <option value="routing">routing - ניתוב שיחה</option>
                                      <option value="api">api - שלוחת מפתחים</option>
                                  </optgroup>
                                  <optgroup label="שלוחות בשימוש בינוני">
                                      <option value="recording_and_entering_data">recording_and_entering_data - קליטת נתונים</option>
                                      <option value="tzintuk">tzintuk - צינתוקים</option>
                                      <option value="zmanim">zmanim - זמני היום</option>
                                      <option value="trivia_questions">trivia_questions - טריוויה</option>
                                  </optgroup>
                                  <optgroup label="שלוחות בשימוש נמוך / ייעודי">
                                      <option value="queue">queue - ניהול תור</option>
                                      <option value="seker">seker - סקרים</option>
                                      <option value="approval_number">approval_number - מספרי אישור</option>
                                      <option value="time_keeper">time_keeper - שעון נוכחות</option>
                                      <option value="codes">codes - קודים וקופונים</option>
                                      <option value="access_filter">access_filter - סינון כניסה</option>
                                      <option value="hangup">hangup - ניתוק</option>
                                  </optgroup>
                                  <option value="custom">הכנסה ידנית...</option>
                              </select>
                              <input type="text" id="customSubFolderType" placeholder="הכנס שם סוג שלוחה ידנית" style="display:none; margin-top:8px;">
                          </div>
                          <div class="input-group">
                              <label>▶️ מאיזה שלוחה:</label>
                              <input type="number" id="subStartRange" value="1" min="1">
                          </div>
                          <div class="input-group">
                              <label>⏹️ איזה שלוחה:</label>
                              <input type="number" id="subEndRange" value="10" min="1">
                          </div>
                          <div class="input-group full-width">
                              <label>🔢 כמות ספרות לתת-שלוחה (אפסים מובילים):</label>
                              <input type="number" id="subDigitsCount" value="1" min="1" max="6">
                          </div>
                          <div class="input-group full-width">
                              <label>📝 שורות קוד נוספות לקובץ ext.ini (תת-שלוחות בלבד):</label>
                              <textarea id="extraCodeSub" rows="2" placeholder="לדוגמה:&#10;play_welcome=yes"></textarea>
                          </div>
                      </div>
                  </div>
      
                  <!-- הגדרות תת-תת-שלוחה -->
                  <div class="input-group full-width section-box">
                      <div style="display: flex; align-items: center; gap: 10px; margin-bottom: 12px;">
                          <input type="checkbox" id="subSubFoldersCheck" onchange="toggleSubSubFolders()" style="width: 18px; height: 18px; cursor: pointer; accent-color: var(--accent);">
                          <label for="subSubFoldersCheck" style="cursor: pointer; color: var(--dark); font-size: 15px; font-weight: 700;">📂 יצירת תת-תת-שלוחות (שכבה שלישית)</label>
                      </div>
                      <div id="subSubConfig" class="grid" style="display: none; margin: 0;">
                          <div class="input-group">
                              <label>🏷️ סוג כותרת לתת-תת-השלוחות:</label>
                              <select id="subSubNamingType">
                                  <option value="hebrew_matrix_triple">מטריצה משולשת (אאא, אאב, אאג...)</option>
                                  <option value="hebrew_extended">עברית רגילה (א, b... י, יא...)</option>
                                  <option value="numbers">מספרים (1, 2, 3...)</option>
                                  <option value="english">אותיות באנגלית (A, B, C...)</option>
                              </select>
                          </div>
                          <div class="input-group">
                              <label>⚙️ סוג השלוחה לתת-תת-השלוחות (type):</label>
                              <select id="subSubFolderType" onchange="checkCustomType('subSubFolderType', 'customSubSubFolderType')">
                                  <optgroup label="שלוחות בשימוש גבוה">
                                      <option value="playfile">playfile - השמעת קבצי שמע</option>
                                      <option value="menu">menu - יצירת תפריט בחירה</option>
                                      <option value="record">record - שלוחת הקלטת הודעות</option>
                                      <option value="confbridge">confbridge - חדר ועידה</option>
                                  </optgroup>
                                  <optgroup label="שלוחות בשימוש בינוני">
                                      <option value="recording_and_entering_data">recording_and_entering_data - קליטת נתונים</option>
                                      <option value="zmanim">zmanim - זמני היום</option>
                                      <option value="trivia_questions">trivia_questions - טריוויה</option>
                                  </optgroup>
                                  <optgroup label="שלוחות בשימוש נמוך / ייעודי">
                                      <option value="queue">queue - ניהול תור</option>
                                      <option value="seker">seker - סקרים</option>
                                      <option value="approval_number">approval_number - מספרי אישור</option>
                                      <option value="codes">codes - קודים וקופונים</option>
                                      <option value="hangup">hangup - ניתוק</option>
                                  </optgroup>
                                  <option value="custom">הכנסה ידנית...</option>
                              </select>
                              <input type="text" id="customSubSubFolderType" placeholder="הכנס שם סוג שלוחה ידנית" style="display:none; margin-top:8px;">
                          </div>
                          <div class="input-group">
                              <label>▶️ מאיזה שלוחה:</label>
                              <input type="number" id="subSubStartRange" value="1" min="1">
                          </div>
                          <div class="input-group">
                              <label>⏹️ איזה שלוחה:</label>
                              <input type="number" id="subSubEndRange" value="5" min="1">
                          </div>
                          <div class="input-group full-width">
                              <label>🔢 כמות ספרות לתת-תת-שלוחה (אפסים מובילים):</label>
                              <input type="number" id="subSubDigitsCount" value="1" min="1" max="6">
                          </div>
                          <div class="input-group full-width">
                              <label>📝 שורות קוד נוספות לקובץ ext.ini (תת-תת-שלוחות בלבד):</label>
                              <textarea id="extraCodeSubSub" rows="2" placeholder="לדוגמה:&#10;record_file=yes"></textarea>
                          </div>
                      </div>
                  </div>
      
                  <div class="full-width">
                      <button id="startBtn" class="btn-main" onclick="startProcess()">🚀 התחל פתיחת שלוחות</button>
                      <button id="cancelBtn" class="btn-cancel" onclick="cancelProcess()">❌ ביטול פעולה</button>
                  </div>
              </div>
      
              <div class="progress-wrapper" id="progBox">
                  <div class="progress-container">
                      <div class="progress-bar" id="progBar"></div>
                      <div class="progress-text" id="progText">0%</div>
                  </div>
              </div>
          </div>
      
          <div class="card">
              <div class="log-box" id="logBox">⏳ ממתין לתחילת ביצוע...</div>
          </div>
      </div>
      
      <script>
          let abortController = null;
      
          function checkCustomType(selectId, inputId) {
              const val = document.getElementById(selectId).value;
              const input = document.getElementById(inputId);
              input.style.display = val === 'custom' ? 'block' : 'none';
          }
      
          function checkNamingCustom(selectId, containerId) {
              const val = document.getElementById(selectId).value;
              const container = document.getElementById(containerId);
              if (val === 'empty') {
                  container.style.display = 'none';
              } else {
                  container.style.display = (val === 'custom_only' || val === 'combined_before' || val === 'combined_after') ? 'block' : 'none';
              }
          }
      
          function getHebrewTitle(index, mode) {
              if (mode === 'strict' && index > 22) {
                  return String(index);
              }
              const ones = ['', 'א', 'ב', 'ג', 'ד', 'ה', 'ו', 'ז', 'ח', 'ט'];
              const tens = ['', 'י', 'כ', 'ל', 'מ', 'נ', 'ס', 'ע', 'פ', 'צ'];
              const hundreds = ['', 'ק', 'ר', 'ש', 'ת'];
      
              if (index <= 0) return String(index);
              if (index < 10) return ones[index];
              if (index < 100) {
                  let t = Math.floor(index / 10);
                  let o = index % 10;
                  if (index === 15) return 'טו';
                  if (index === 16) return 'טז';
                  return tens[t] + ones[o];
              } else if (index < 500) {
                  let h = Math.floor(index / 100);
                  let rem = index % 100;
                  let t = Math.floor(rem / 10);
                  let o = rem % 10;
                  let res = hundreds[h];
                  if (rem === 15) res += 'טו';
                  else if (rem === 16) res += 'טז';
                  else {
                      if (t > 0) res += tens[t];
                      if (o > 0) res += ones[o];
                  }
                  return res;
              }
              return String(index);
          }
      
          function getMatrixTitle(mainIndex, subIndex) {
              let mainLetter = getHebrewTitle(mainIndex, 'extended');
              let subLetter = getHebrewTitle(subIndex, 'extended');
              return mainLetter + subLetter;
          }
      
          function getTripleMatrixTitle(mainIndex, subIndex, subSubIndex) {
              let mainLetter = getHebrewTitle(mainIndex, 'extended');
              let subLetter = getHebrewTitle(subIndex, 'extended');
              let subSubLetter = getHebrewTitle(subSubIndex, 'extended');
              return mainLetter + subLetter + subSubLetter;
          }
      
          function toggleSubFolders() {
              const isChecked = document.getElementById('subFoldersCheck').checked;
              document.getElementById('subConfig').style.display = isChecked ? 'grid' : 'none';
              if (!isChecked) {
                  document.getElementById('subSubFoldersCheck').checked = false;
                  toggleSubSubFolders();
              }
          }
      
          function toggleSubSubFolders() {
              const isChecked = document.getElementById('subSubFoldersCheck').checked;
              if (isChecked) {
                  document.getElementById('subFoldersCheck').checked = true;
                  toggleSubFolders();
              }
              document.getElementById('subSubConfig').style.display = isChecked ? 'grid' : 'none';
          }
      
          function addLog(msg, type = "info") {
              const logBox = document.getElementById('logBox');
              logBox.innerHTML += `<div class="log-${type}">> ${msg}</div>`;
              logBox.scrollTop = logBox.scrollHeight;
          }
      
          function cancelProcess() {
              if (abortController) {
                  abortController.abort();
                  addLog("הפעולה הופסקה על ידי המשתמש.", "warn");
                  document.getElementById('startBtn').disabled = false;
                  document.getElementById('cancelBtn').style.display = 'none';
              }
          }
      
          function buildTitleString(type, index, mainIndex = 1, subIndex = 1, subSubIndex = 1, customText = "") {
              let baseTitle = "";
              if (type === 'numbers') {
                  baseTitle = String(index);
              } else if (type === 'hebrew_extended' || type === 'hebrew') {
                  baseTitle = getHebrewTitle(index, 'extended');
              } else if (type === 'hebrew_strict') {
                  baseTitle = getHebrewTitle(index, 'strict');
              } else if (type === 'hebrew_matrix') {
                  baseTitle = getMatrixTitle(mainIndex, index);
              } else if (type === 'hebrew_matrix_triple') {
                  baseTitle = getTripleMatrixTitle(mainIndex, subIndex, index);
              } else if (type === 'english') {
                  if (index > 0 && index <= 26) {
                      baseTitle = String.fromCharCode(64 + index);
                  } else {
                      baseTitle = String(index);
                  }
              } else if (type === 'empty') {
                  return "";
              } else if (type === 'custom_only') {
                  return customText || "";
              }
      
              if (type === 'combined_before') {
                  return (customText ? customText + " " : "") + baseTitle;
              } else if (type === 'combined_after') {
                  return baseTitle + (customText ? " " + customText : "");
              }
      
              return baseTitle;
          }
      
          function getAutomaticDigitsParam(count) {
              if (count > 100) {
                  return "digits=3";
              } else if (count > 10) {
                  return "digits=2";
              }
              return "";
          }
      
          async function startProcess() {
              const token = document.getElementById('token').value.trim();
              let targetPath = document.getElementById('targetPath').value.trim().replace(/^\/|\/$/g, "");
              const namingType = document.getElementById('namingType').value;
              const namingCustomText = document.getElementById('namingCustomText').value.trim();
              
              let folderType = document.getElementById('folderType').value;
              if (folderType === 'custom') folderType = document.getElementById('customFolderType').value.trim();
      
              const hasSub = document.getElementById('subFoldersCheck').checked;
              const hasSubSub = document.getElementById('subSubFoldersCheck').checked;
      
              const extraCodeMain = document.getElementById('extraCodeMain').value.trim();
              const extraCodeSub = document.getElementById('extraCodeSub').value.trim();
              const extraCodeSubSub = document.getElementById('extraCodeSubSub').value.trim();
      
              if (!token) {
                  alert("נא להזין טוקן!");
                  return;
              }
      
              const startNum = parseInt(document.getElementById('startNum').value);
              const endNum = parseInt(document.getElementById('endNum').value);
              const digitsCount = parseInt(document.getElementById('digitsCount').value);
      
              if (isNaN(startNum) || isNaN(endNum) || startNum > endNum) {
                  alert("טווח השלוחות אינו תקין!");
                  return;
              }
      
              let tasks = [];
              let subNamingType = document.getElementById('subNamingType').value;
              let subNamingCustomText = document.getElementById('subNamingCustomText').value.trim();
              let subFolderType = document.getElementById('subFolderType').value;
              if (subFolderType === 'custom') subFolderType = document.getElementById('customSubFolderType').value.trim();
              let subStartRange = parseInt(document.getElementById('subStartRange').value) || 1;
              let subEndRange = parseInt(document.getElementById('subEndRange').value) || 10;
              let subDigitsCount = parseInt(document.getElementById('subDigitsCount').value) || 1;
      
              let subSubNamingType = document.getElementById('subSubNamingType').value;
              let subSubFolderType = document.getElementById('subSubFolderType').value;
              if (subSubFolderType === 'custom') subSubFolderType = document.getElementById('customSubSubFolderType').value.trim();
              let subSubStartRange = parseInt(document.getElementById('subSubStartRange').value) || 1;
              let subSubEndRange = parseInt(document.getElementById('subSubEndRange').value) || 5;
              let subSubDigitsCount = parseInt(document.getElementById('subSubDigitsCount').value) || 1;
      
              const mainCount = (endNum - startNum) + 1;
              const subCount = (subEndRange - subStartRange) + 1;
              const subSubCount = (subSubEndRange - subSubStartRange) + 1;
      
              const mainAutoDigits = getAutomaticDigitsParam(mainCount);
              const subAutoDigits = getAutomaticDigitsParam(subCount);
              const subSubAutoDigits = getAutomaticDigitsParam(subSubCount);
      
              for (let i = startNum; i <= endNum; i++) {
                  let folderName = String(i).padStart(digitsCount, '0');
                  let mainPath = targetPath ? `${targetPath}/${folderName}` : folderName;
                  let mainIndex = (i - startNum) + 1;
                  
                  let titleText = buildTitleString(namingType, mainIndex, mainIndex, 1, 1, namingCustomText);
                  
                  let mainExtExtra = extraCodeMain;
                  if (hasSub && mainAutoDigits) {
                      mainExtExtra = mainExtExtra ? mainAutoDigits + "\n" + mainExtExtra : mainAutoDigits;
                  }
                  tasks.push({ path: mainPath, title: titleText, type: folderType, extra: mainExtExtra });
      
                  if (hasSub) {
                      for (let j = subStartRange; j <= subEndRange; j++) {
                          let subFolderName = String(j).padStart(subDigitsCount, '0'); 
                          let subPath = `${mainPath}/${subFolderName}`;
                          let subTitleText = buildTitleString(subNamingType, j, mainIndex, j, 1, subNamingCustomText);
                          
                          let subExtExtra = extraCodeSub;
                          if (hasSubSub && subAutoDigits) {
                              subExtExtra = subExtExtra ? subAutoDigits + "\n" + subExtExtra : subAutoDigits;
                          }
                          tasks.push({ path: subPath, title: subTitleText, type: subFolderType, extra: subExtExtra });
      
                          if (hasSubSub) {
                              for (let k = subSubStartRange; k <= subSubEndRange; k++) {
                                  let subSubFolderName = String(k).padStart(subSubDigitsCount, '0');
                                  let subSubPath = `${subPath}/${subSubFolderName}`;
                                  let subSubTitleText = buildTitleString(subSubNamingType, k, mainIndex, j, k, "");
                                  
                                  let subSubExtExtra = extraCodeSubSub;
                                  if (subSubAutoDigits) {
                                      subSubExtExtra = subSubExtExtra ? subSubAutoDigits + "\n" + subSubExtExtra : subSubAutoDigits;
                                  }
                                  tasks.push({ path: subSubPath, title: subSubTitleText, type: subSubFolderType, extra: subSubExtExtra });
                              }
                          }
                      }
                  }
              }
      
              const totalToCreate = tasks.length;
              document.getElementById('startBtn').disabled = true;
              document.getElementById('cancelBtn').style.display = 'block';
              document.getElementById('progBox').style.display = 'block';
              document.getElementById('logBox').innerHTML = "";
      
              abortController = new AbortController();
              addLog(`מתחיל ביצירת סך הכל ${totalToCreate} שלוחות ותת-שלוחות...`, "info");
      
              let completed = 0;
      
              for (let task of tasks) {
                  if (abortController.signal.aborted) break;
      
                  let extContent = `type=${task.type}`;
                  if (task.title !== "") {
                      extContent += `\ntitle=${task.title}`;
                  }
                  if (task.extra) {
                      extContent += `\n${task.extra}`;
                  }
                  
                  try {
                      const success = await uploadExtIni(token, task.path, extContent, abortController.signal);
                      if (success) {
                          addLog(`שלוחה ${task.path}` + (task.title ? ` (כותרת: ${task.title})` : ` (ללא כותרת)`) + ` נוצרה בהצלחה`, "success");
                      } else {
                          addLog(`שגיאה ביצירת שלוחה ${task.path}`, "error");
                      }
                  } catch (err) {
                      if (err.name === 'AbortError') break;
                      addLog(`שגיאת תקשורת בשלוחה ${task.path}: ${err.message}`, "error");
                  }
      
                  completed++;
                  const pct = Math.round((completed / totalToCreate) * 100);
                  document.getElementById('progBar').style.width = pct + '%';
                  document.getElementById('progText').innerText = `${pct}% (${completed}/${totalToCreate})`;
              }
      
              if (!abortController.signal.aborted) {
                  addLog("כל הפעולות הושלמו בהצלחה!", "success");
              }
      
              document.getElementById('startBtn').disabled = false;
              document.getElementById('cancelBtn').style.display = 'none';
              abortController = null;
          }
      
          async function uploadExtIni(token, folderPath, content, signal) {
              const fd = new FormData();
              fd.append('token', token);
              fd.append('path', `ivr2:${folderPath}/ext.ini`);
              fd.append('qqfile', new Blob([content], { type: 'text/plain;charset=utf-8' }), 'ext.ini');
      
              const response = await fetch(`https://www.call2all.co.il/ym/api/UploadFile`, {
                  method: 'POST',
                  body: fd,
                  signal: signal
              });
      
              const data = await response.json();
              return data && (data.responseStatus === "OK" || data.status === "OK");
          }
      </script>
      
      </body>
      </html>
      

      טעם ליצירת התוכנה:

      א. אני עצמי בעבר נתקלתי ביצירת מאות שלוחות ידנית
      ב. קו אוצר ספרים של ישיבתי רצתה לפתוח ספריה טלפונית וכעת לפתוח אלפי שלוחות לפי ספריה שכל שלוחה יקראו לה באות שלו ממש משגע ולכן עשיתי מטריצה עבור כאולו דברים (ובהמשך מקווה להזריק גם הקראה של טי טי אס של תוכן השלוחות
      ג. היה לי חבר שהיה זקוק לפתוח על פי חשבונו כ- 1800 שלוחות והלך למפתח שהסכים במחיר של 200 ש"ח אז החלטתי לעזור

      ד. בקו של @פלוס יש שלוחה הנקראת פלוספונים (שלוחות אישיות כאלו) ונצרך היה בעבר לפתוח כמאה שלוחות מה שהאט מלא דברים וייאש כל מיני אנשים...

      פורסם בהסברים מסודרים ממשתמשים
      L
      lavitoren הטי"ל
    • RE: תגובות | פיתוח פרטי | 🎙📲 מודול הקלטה וניתוב חכם Pro – הגרסה המשודרגת!

      @יהודה-צ.-כ. בבדיקה רגע

      פורסם בעזרה הדדית למשתמשים מתקדמים
      L
      lavitoren הטי"ל
    • העלאת תקיות שלימות בצורה מסודרת להפליא בלי להתאמץ😏🎮🕹🥱

      יש לי רעיון אדיר! (לדעתי לפחות)
      אבל זה ל "יודעים" בלבד כי לי אין שמץ מושג כיצד מפתחים כנראה צריך לזה ידע בAPI , פייטון וכו'
      והרעיון כדלהלן:
      כאשר יש לי במחשב תקיה מסודרת עם דברים לצורך הדוגמא
      יש לי כך זה לפי שם
      נגיד תקיית 🎸 שירים תקית 📖 סיפורים תקית ✍ שיעורים 💣 ואפקטים לפי הסדר הנ"ל
      וכעת בתוך כל תקיה כזו יש מלא תקיות
      וגם בתקיות יש תקיות ואין לי כח לפתוח בקו שלי שלוחות בתוך שלוחות
      וכל פעם להעלות קבצים אז הצעתי היא שיהא בוט, שרת, תוכנה, או איך שלא קוראים לזה
      שיעלה אותם לפי הסדר באופן שאיך שזה מסודר במחשב כך הוא פותח שלוחה
      במרה דלעיל אוטומטית הוא יפתח שלוחות כך

      1. שירים 🎸
      2. סיפורים📖
      3. שיעורים✍
      4. אפקטים💣
        ואת השם העברי יכניס אוטומטי לטייטל ויחליפהו למספר
        וכן בתוך השלוחות יפתח לפי מה שיש בתקיה
        וכן שיקריא בקובץ tts את התוכן של כל תפריט

      נ. ב. צריך לזכור שכשיש מעל עשרה שלוחות הוא יעשה תפריט של שתי ספרות ויעשה שלוחות של 01,02,03...

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

      פורסם בבקשות לפיתוח
      L
      lavitoren הטי"ל

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

    • RE: רוצים להתעדכן בדברים החדשים בפורום דרך הפלאפון? עכשיו זה אפשרי!

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

      פורסם בטיפים עצות והדגמות מהמשתמשים
      L
      lavitoren הטי"ל
    • RE: תגובות הטי"ל

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

      פורסם בעזרה הדדית למשתמשים מתקדמים
      L
      lavitoren הטי"ל
    • RE: תגובות הטי"ל

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

      פורסם בעזרה הדדית למשתמשים מתקדמים
      L
      lavitoren הטי"ל
    • RE: תגובות הטי"ל

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

      מטורף לגמרי מה יש שם שכ"כ מעניין אותם
      חוץ מלדבר
      איזה תכנים טובים וכשרים?
      (באחד הקווים שבדקתי היה שירי נשים ב"חדשות הפורום" רח"ל ה' ישמרנו)

      פורסם בעזרה הדדית למשתמשים מתקדמים
      L
      lavitoren הטי"ל
    • RE: תגובות הטי"ל

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

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

      לחצי פורום

      לכל המאזינים למעט בודדים

      פורסם בעזרה הדדית למשתמשים מתקדמים
      L
      lavitoren הטי"ל
    • RE: תגובות הטי"ל

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

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

      פורסם בעזרה הדדית למשתמשים מתקדמים
      L
      lavitoren הטי"ל
    • RE: תגובות הטי"ל

      ואני לא זוכר

      פורסם בעזרה הדדית למשתמשים מתקדמים
      L
      lavitoren הטי"ל
    • RE: תגובות הטי"ל

      @לימוד-בתורת-מרן כרגע אין לי בינה

      פורסם בעזרה הדדית למשתמשים מתקדמים
      L
      lavitoren הטי"ל
    • RE: תגובות הטי"ל

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

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

      ולמה אתה לא עונה בשלוחה שלך מממממממממממ?

      אין לי כח וזמן כרגע אני עובר להתעסק עם משהו נוסף אז לילה טוב

      פורסם בעזרה הדדית למשתמשים מתקדמים
      L
      lavitoren הטי"ל
    • RE: תגובות הטי"ל

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

      פורסם בעזרה הדדית למשתמשים מתקדמים
      L
      lavitoren הטי"ל