Plugin Directory

Changeset 2896421


Ignore:
Timestamp:
04/10/2023 06:35:03 AM (3 years ago)
Author:
qalam
Message:

Push new version - update trunk files

Location:
qalam/trunk
Files:
8 added
4 edited

Legend:

Unmodified
Added
Removed
  • qalam/trunk/assets/css/qalamExtension.css

    r2594341 r2896421  
    11@font-face {
    2     font-family: "Cairo-Regular";
    3     src: URL("chrome-extension://__MSG_@@extension_id__/fonts/Cairo-Regular.e793edb5.ttf")
    4     format("truetype");
    5 }
     2  font-family: 'Tajawal';
     3  font-style: normal;
     4  font-weight: 400;
     5  src: URL('../fonts/Tajawal-Regular.woff') format('woff');
     6}
     7
     8@font-face {
     9  font-family: 'Tajawal';
     10  font-style: normal;
     11  font-weight: 300;
     12  src: URL('../fonts/Tajawal-Light.woff') format('woff');
     13}
     14
     15@font-face {
     16  font-family: 'Tajawal';
     17  font-style: normal;
     18  font-weight: 700;
     19  src: URL('../fonts/Tajawal-Bold.woff') format('woff');
     20}
     21
     22@font-face {
     23  font-family: 'Tajawal';
     24  font-style: normal;
     25  font-weight: 900;
     26  src: URL('../fonts/Tajawal-ExtraBold.woff') format('woff');
     27}
     28
    629qalam-wrapper {
    7     position: absolute;
    8     top: 0px;
    9     left: 0px;
     30  position: absolute;
     31  top: 0px;
     32  left: 0px;
    1033}
    1134qalam-extension {
    12     position: absolute;
    13     pointer-events: none;
    14     direction: ltr;
    15     z-index: 2147483647;
     35  position: absolute;
     36  pointer-events: none;
     37  direction: ltr;
     38  z-index: 998;
    1639}
    1740qalam-extension qalam-extension-cont {
    18     position: absolute;
    19     width: 100%;
    20     height: 100%;
    21     top: 0px;
    22     left: 0px;
    23     direction: ltr;
    24     overflow: hidden;
     41  position: absolute;
     42  width: 100%;
     43  height: 100%;
     44  top: 0px;
     45  left: 0px;
     46  direction: ltr;
     47  overflow: hidden;
    2548}
    2649qalam-extension qalam-extension-cont .qalam-highlights-cont {
    27     width: 100%;
    28     height: 100%;
    29     position: relative;
     50  width: 100%;
     51  height: 100%;
     52  position: relative;
    3053}
    3154qalam-extension qalam-extension-cont .qalam-highlights-cont qalam-label {
    32     position: absolute;
    33     cursor: pointer;
    34     pointer-events: all;
    35     overflow: hidden;
     55  position: absolute;
     56  cursor: pointer;
     57  pointer-events: all;
     58  overflow: hidden;
    3659}
    3760qalam-extension qalam-extension-cont .qalam-highlights-cont qalam-label.active {
    38     pointer-events: none;
    39     background-color: #ff000014;
     61  pointer-events: none;
     62  background-color: #ff000014;
    4063}
    4164qalam-extension
    42 qalam-extension-cont
    43 .qalam-highlights-cont
    44 qalam-label
    45 label-border {
    46     position: absolute;
    47     height: 1.5px;
    48     background-color: #ec2240;
    49     transition: all 0.5s ease-in;
    50     bottom: 0;
     65  qalam-extension-cont
     66  .qalam-highlights-cont
     67  qalam-label
     68  label-border {
     69  position: absolute;
     70  height: 1.5px;
     71  background-color: #ec2240;
     72  transition: all 0.5s ease-in;
     73  bottom: 0;
    5174}
    5275qalam-tashkeel-blk,
    5376qalam-quraan-blk {
    54     cursor: pointer !important;
    55     pointer-events: all !important;
    56     display: flex;
    57     position: absolute !important;
    58     flex-direction: row !important;
    59     align-items: center !important;
    60     justify-content: space-around !important;
    61     bottom: 7px !important;
    62     left: 60px;
    63     border-radius: 20px !important;
    64     width: 25px !important;
    65     height: 25px !important;
    66     background: #d9d2d2 !important;
     77  cursor: pointer !important;
     78  pointer-events: all !important;
     79  display: flex;
     80  position: absolute !important;
     81  flex-direction: row !important;
     82  align-items: center !important;
     83  justify-content: space-around !important;
     84  bottom: 7px !important;
     85  left: 60px;
     86  border-radius: 20px !important;
     87  width: 25px !important;
     88  height: 25px !important;
     89  background: #d9d2d2 !important;
    6790}
    6891qalam-quraan-blk {
    69     left: 90px;
     92  left: 90px;
    7093}
    7194qalam-tashkeel-blk:hover {
    72     background: #d9d2d2;
     95  background: #d9d2d2;
    7396}
    7497.qalam-tashkeel-icon {
    75     width: 25px !important;
    76     height: 25px !important;
    77     margin: 0 !important;
    78     padding: 0 !important;
    79     border-radius: 20px !important;
    80     background: rgb(217, 210, 210) !important;
    81     cursor: pointer !important;
     98  width: 25px !important;
     99  height: 25px !important;
     100  margin: 0 !important;
     101  padding: 0 !important;
     102  border-radius: 20px !important;
     103  background: rgb(217, 210, 210) !important;
     104  cursor: pointer !important;
    82105}
    83106.qalam-quraan-icon {
    84     width: 17px !important;
    85     height: 17px !important;
    86     margin: 0 !important;
    87     padding: 0 !important;
    88     border-radius: 20px !important;
    89     background: rgb(217, 210, 210) !important;
    90     cursor: pointer !important;
     107  width: 17px !important;
     108  height: 17px !important;
     109  margin: 0 !important;
     110  padding: 0 !important;
     111  border-radius: 20px !important;
     112  background: rgb(217, 210, 210) !important;
     113  cursor: pointer !important;
     114}
     115
     116.qalam-icons-loader {
     117  border: 3px solid #f3f3f3; /* Light grey */
     118  border-top: 3px solid #008677; /* Blue */
     119  border-radius: 50%;
     120  width: 100%;
     121  height: 100%;
     122  animation: spin 2s linear infinite;
     123  position: absolute;
     124}
     125
     126.disabled-tashkeel-tawtheeq {
     127  cursor: not-allowed !important;
     128  opacity: 0.6 !important;
     129  pointer-events: none !important;
    91130}
    92131qalam-wrapper qalam-button-cont {
    93     height: 26px !important;
    94     direction: ltr;
    95     position: absolute;
    96     cursor: pointer;
    97     pointer-events: all;
    98     display: flex;
    99     flex-direction: row;
    100     align-items: center;
    101     justify-content: space-around;
    102     box-sizing: border-box;
     132  height: 26px !important;
     133  direction: ltr;
     134  position: absolute;
     135  cursor: pointer;
     136  pointer-events: all;
     137  display: flex;
     138  flex-direction: row;
     139  align-items: center;
     140  justify-content: space-around;
     141  box-sizing: border-box;
    103142}
    104143qalam-wrapper qalam-button-cont:hover,
    105144qalam-wrapper qalam-button-cont.active {
    106     height: 26px !important;
    107     width: 70px !important;
    108     border-radius: 16px;
    109     background-color: #fff;
    110     box-shadow: 0 1px 8px 0 rgba(0, 0, 0, 0.1);
     145  height: 26px !important;
     146  width: 70px !important;
     147  border-radius: 16px;
     148  background-color: #fff;
     149  box-shadow: 0 1px 8px 0 rgba(0, 0, 0, 0.1);
    111150}
    112151qalam-wrapper qalam-button-cont:hover .separator,
     
    114153qalam-wrapper qalam-button-cont.active .separator,
    115154qalam-wrapper qalam-button-cont.active .disable-icon {
    116     display: block;
     155  display: block;
    117156}
    118157qalam-wrapper qalam-button-cont .qalam-button {
    119     width: 24px;
    120     height: 24px;
    121     background-size: 100%;
    122     margin-left: 3px;
    123     border-radius: 20px;
    124     background-color: #30827e;
    125     display: flex;
    126     align-items: center;
     158  width: 24px;
     159  height: 24px;
     160  background-size: 100%;
     161  margin-left: 3px;
     162  border-radius: 20px;
     163  background-color: #30827e;
     164  display: flex;
     165  align-items: center;
    127166}
    128167qalam-wrapper qalam-button-cont .qalam-button .errors {
    129     color: #ffffff;
    130     font-size: 15px;
    131     font-weight: bold;
    132     letter-spacing: 0;
    133     text-align: center;
    134     display: none;
    135     width: 24px;
    136     height: 24px;
    137     line-height: 24px;
    138     margin: 0;
    139     padding: 0;
    140     font-family: sans-serif !important;
     168  color: #ffffff;
     169  font-size: 15px;
     170  font-weight: bold;
     171  letter-spacing: 0;
     172  text-align: center;
     173  display: none;
     174  width: 24px;
     175  height: 24px;
     176  line-height: 24px;
     177  margin: 0;
     178  padding: 0;
     179  font-family: Tajawal, sans-serif !important;
    141180}
    142181qalam-wrapper qalam-button-cont:hover .qalam-button,
    143182qalam-wrapper qalam-button-cont.active .qalam-button {
    144     margin-left: 0;
     183  margin-left: 0;
    145184}
    146185qalam-wrapper qalam-button-cont .separator {
    147     height: 20px;
    148     width: 1px;
    149     border: 1px solid #000;
    150     opacity: 0.4;
    151     display: none;
    152     box-sizing: border-box;
     186  height: 20px;
     187  width: 1px;
     188  border: 1px solid #000;
     189  opacity: 0.4;
     190  display: none;
     191  box-sizing: border-box;
    153192}
    154193qalam-wrapper qalam-button-cont .disable-icon {
    155     display: none;
     194  display: none;
    156195}
    157196qalam-notification {
    158     position: fixed;
    159     top: 16px;
    160     right: -450px;
    161     -webkit-transition: all 750ms ease-in-out;
    162     -moz-transition: all 750ms ease-in-out;
    163     -o-transition: all 750ms ease-in-out;
    164     -ms-transition: all 750ms ease-in-out;
    165     transition: all 750ms ease-in-out;
    166     width: 412px;
    167     border-radius: 4px;
    168     background-color: #fff;
    169     box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.2);
    170     z-index: 2147483647;
    171     padding: 24px 32px;
    172     font-family: Cairo-Regular, sans-serif !important;
     197  position: fixed;
     198  top: 16px;
     199  right: -450px;
     200  -webkit-transition: all 750ms ease-in-out;
     201  -moz-transition: all 750ms ease-in-out;
     202  -o-transition: all 750ms ease-in-out;
     203  -ms-transition: all 750ms ease-in-out;
     204  transition: all 750ms ease-in-out;
     205  width: 412px;
     206  border-radius: 4px;
     207  background-color: #fff;
     208  box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.2);
     209  z-index: 2147483647;
     210  padding: 24px 32px;
     211  font-family: Tajawal, sans-serif !important;
    173212}
    174213qalam-notification .notification-inner-cont {
    175     display: flex;
    176     flex-direction: row;
    177     align-items: end;
    178     direction: rtl;
    179     justify-content: space-between;
     214  display: flex;
     215  flex-direction: row;
     216  align-items: end;
     217  direction: rtl;
     218  justify-content: space-between;
    180219}
    181220qalam-notification .notification-inner-cont .notification-close {
    182     position: absolute;
    183     cursor: pointer;
    184     top: 8px;
    185     right: 8px;
     221  position: absolute;
     222  cursor: pointer;
     223  top: 8px;
     224  right: 8px;
    186225}
    187226qalam-notification .notification-inner-cont .notification-rightside {
    188     max-width: 260px;
     227  max-width: 260px;
    189228}
    190229qalam-notification .notification-inner-cont .notification-logo {
    191     width: 62px;
    192     height: 62px;
     230  width: 62px;
     231  height: 62px;
    193232}
    194233qalam-notification
    195 .notification-inner-cont
    196 .notification-rightside
    197 .notification-title {
    198     color: #000;
    199     font-size: 18px;
    200     letter-spacing: 0;
    201     line-height: 36px;
    202     text-align: right;
    203     margin: 0 0 6px 0;
    204     font-family: Cairo-Regular, sans-serif !important;
     234  .notification-inner-cont
     235  .notification-rightside
     236  .notification-title {
     237  color: #000;
     238  font-size: 18px;
     239  letter-spacing: 0;
     240  line-height: 36px;
     241  text-align: right;
     242  margin: 0 0 6px 0;
     243  font-family: Tajawal, sans-serif !important;
    205244}
    206245qalam-notification
    207 .notification-inner-cont
    208 .notification-rightside
    209 .notification-desc {
    210     opacity: 0.6;
    211     color: #000;
    212     font-size: 14px;
    213     letter-spacing: 0;
    214     line-height: 28px;
    215     text-align: right;
    216     margin: 0;
    217     font-family: Cairo-Regular, sans-serif !important;
     246  .notification-inner-cont
     247  .notification-rightside
     248  .notification-desc {
     249  opacity: 0.6;
     250  color: #000;
     251  font-size: 14px;
     252  letter-spacing: 0;
     253  line-height: 28px;
     254  text-align: right;
     255  margin: 0;
     256  font-family: Tajawal, sans-serif !important;
    218257}
    219258qalam-notification .notification-inner-cont .notification-rightside button {
    220     float: right;
    221     width: 66px;
     259  float: right;
     260  width: 66px;
    222261}
    223262.qalam-btn {
    224     width: 100%;
    225     height: 32px;
    226     font-size: 14px;
    227     font-weight: 600;
    228     border-radius: 4px;
    229     margin: 16px 0 0 0;
    230     padding: 0;
    231     outline: none;
    232     border-style: solid;
    233     cursor: pointer;
    234     font-family: Cairo-Regular, sans-serif !important;
     263  width: 100%;
     264  height: 32px;
     265  font-size: 14px;
     266  font-weight: 600;
     267  border-radius: 4px;
     268  margin: 16px 0 0 0;
     269  padding: 0;
     270  outline: none;
     271  border-style: solid;
     272  cursor: pointer;
     273  font-family: Tajawal, sans-serif !important;
    235274}
    236275.qalam-btn.secondary-btn {
    237     border: 1px solid #30827e;
    238     color: #30827e;
    239     background-color: #fff;
     276  border: 1px solid #30827e;
     277  color: #30827e;
     278  background-color: #fff;
    240279}
    241280.qalam-btn.primary-btn {
    242     background-color: #30827e;
    243     color: #fff;
    244     border-color: #30827e;
     281  background-color: #30827e;
     282  color: #fff;
     283  border-color: #30827e;
    245284}
    246285
    247286qalam-container {
    248     display: block !important;
    249 }
     287  display: block !important;
     288}
     289
     290@keyframes spin {
     291  0% {
     292    transform: rotate(0deg);
     293  }
     294  100% {
     295    transform: rotate(360deg);
     296  }
     297}
  • qalam/trunk/assets/js/main.js

    r2594341 r2896421  
    1 const baseLink = "https://api.app.qalam.ai/";
    2 let doneCallback = null, API_LINK = "", TOKEN = "", shadowRoot = null, qalamDisablePrompt = null, isTextArea = null,
    3     triggerFlag = !0, SCServiceActive = null, qalamExtension = null, qalamExtensionCont = null,
    4     qalamHighlightsCont = null, qalamMirror = null, qalamSuggestions = null, element = null, withoutScrollDiff = 0,
    5     elementParent = null, typingStallCounter = 0, secondsCounter = null, resizeHoldCounter = null,
    6     currentTextSuggestions = [], ignoredSet = new Set, removeSuggestionsTimeout = null, selectedText = "",
    7     isTashkeelActive = null, isTawtheeqActive = null, isWriterAllowedToAddToDic = !1, activeFrameId = null,
    8     editorId = "", PATH_MODE = "PATH_MODE", QUERY_MODE = "QUERY_MODE";
    9 var cssId = "myCss", INTERSECTION_THRESHOLD = .7, REMOVE_SUGGESTION_DELAY = 300, TYPING_STALL = 1,
    10     ANIMATION_DELAY = 1e3, DUMMY_STRING = "@⻆@",
    11     STYLES_BLOCKING = new Set(["block", "flex", "flow-root", "grid", "list-item", "table", "table-caption", "table-cell", "table-footer-group", "table-header-group", "table-row", "table-row-group"]),
    12     example = "\nقلم للأعمال\nمساعد الكتابة الذكي للغة العربية\nعن قلم:\nقال تعالى: نون والقلم وما يسطرون\nوقال تعالى: إن الله وملائكته يصلون على النبي يا أيها الذين آمنوا صلوا عليه وسلموا تسليما\nقلم واحدة من شركات مجموعة موضوع. كوم (المجموعة)، وهي الراءدة في تطبيقات الذكاء الاصطناعي باللغة العربية داخل المجموعة . وبعد نجاح إستخدام هذه التطبيقات داخلياً ولدى بعض عملاءنا المقربون ، قررنا مشاركة التجربة مع الشركات، و المؤسسات، والوزارات الأخرى محليا داخل الأردنوخارجها.\nيعمل على تطوير قلم نخبة من الأخصائيون والخبراء في اللغة العربيه وحوسبتها، وفي علم البيانات والذكاء الاصطناعي، اضافه إلى مهندسو البرمجيات والحاسوب. جميعهم يعملون معاً لصناعة منتج ذكي، يخدم الكتابة بلغة الصاد.\nلماذا قلم؟\nنعلم أن كتابة المحتوي، وتدقيقه، والمحافظة على أسلوب الكتابة والنسق المتبع في شركتكم مهمة ليست بالهلة، خاصة حين يكون بصيغ مختلفة، وفي حجماً كبير، مثل:\nالتقارير بشتى أنواعها\nالأبحاث والنشر\nالعروض الفنية و المالية\nالمراسلاة والخطابات\nالرسائل الإلكترونية\nوغيرها\nومن هنا جاءت المهمه التي اضطلع بها قلم للأعمال أن يكون عوناً لكم في التخفيف من عبئ تدقيق المحتوى بشتى أنواعه، ومساعدة الكتّاب/الموظفين حتى ينتجو محتوى سليماً من الأخطائ الإملائية واللغوية والقواعدية، وتحسين الصياغة في اللغة العربية، بالإضافة إلى مساعدتهم في اتباع النسق وأسلوب الكتابة الخاص بالشركة.",
    13     STYLES_HIDDEN = new Set(["none", "table-column", "table-column-group"]),
    14     STYLES_WRAP = new Set(["pre", "pre-wrap", "pre-line"]), BUTTON_NORMAL_COLOR = "#30827E",
    15     BUTTON_ERROR_COLOR = "#EC2240", QALAM_TOOLBAR_STYLE = "",
    16     MIRROR_SHADOW_STYLE = "\nqalam-mirror {\n  border: 0px transparent;\n  text-shadow: none;\n  text-indent: 0px;\n  word-break: normal;\n  overflow-wrap: break-word;\n  word-spacing: 0px;\n  writing-mode: horizontal-tb;\n  white-space: pre-wrap;\n  vertical-align: baseline;\n  clear: both;\n  box-sizing: content-box;\n  position: fixed;\n  top: 0px;\n  left: 0px;\n  background: transparent;\n  pointer-events: none;\n  overflow: hidden;\n  color: transparent;\n  z-index: 1;\n  visibility: hidden;\n}\nqalam-disable-prompt {\n  position: fixed;\n  padding: 24px 32px;\n  border-radius: 4px;\n  background-color: #fff;\n  box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.2);\n  pointer-events: all;\n  width: 228px;\n  height: fit-content;\n  font-family: Tajawal-Regular, sans-serif !important;\n  box-sizing: border-box;\n  z-index: 2147483647;\n}\nqalam-disable-prompt .prompt-title {\n  color: #000;\n  font-size: 18px;\n  letter-spacing: 0;\n  line-height: 36px;\n  text-align: right;\n  margin: 0 0 8px 0;\n  padding: 0;\n  display: inline-block;\n  font-family: Tajawal-Regular, sans-serif !important;\n  width: 100%;\n}\n.qalam-btn {\n  width: 100%;\n  height: 32px;\n  font-size: 14px;\n  font-weight: 600;\n  border-radius: 4px;\n  margin: 16px 0 0 0;\n  padding: 0;\n  outline: none;\n  border-style: solid;\n  cursor: pointer;\n  font-family: Tajawal-Regular, sans-serif !important;\n}\n.qalam-btn.secondary-btn {\n  border: 1px solid #30827e;\n  color: #30827e;\n  background-color: #fff;\n}\n.qalam-btn.primary-btn {\n  background-color: #30827e;\n  color: #fff;\n  border-color: #30827e;\n}\nqalam-suggestions {\n  width: 175px;\n  border-radius: 4px;\n  background-color: #ffffff;\n  box-shadow: 0 1px 8px 0 rgba(0, 0, 0, 0.2);\n  position: fixed;\n  display: none;\n  cursor: pointer;\n  z-index: 2147483647;\n  pointer-events: all;\n}\nqalam-suggestions suggestions-cont > div:nth-of-type(1) {\n  border-top-right-radius: 4px;\n  border-top-left-radius: 4px;\n}\nqalam-suggestions suggestions-cont suggestion-item {\n  padding: 16px;\n  background-color: #fff;\n  width: 100%;\n  height: 56px;\n  display: flex;\n  align-items: center;\n  box-sizing: border-box;\n}\nqalam-suggestions suggestions-cont suggestion-item suggestion-text {\n  color: #108426;\n  font-family: Tajawal-Regular, sans-serif !important;\n  font-size: 20px;\n  font-weight: 600;\n  text-align: right;\n  width: 100%;\n  height: fit-content;\n  margin: -2px 0 0 0;\n  padding: 0;\n  direction: rtl;\n  display: inline-block;\n  text-overflow: ellipsis;\n  overflow: hidden;\n  white-space: nowrap;\n}\nqalam-suggestions suggestions-cont suggestion-item:hover {\n  background-color: #108426;\n}\nqalam-suggestions suggestions-cont suggestion-item:hover suggestion-text {\n  color: #fff;\n}\nqalam-suggestions .ignore-cont,qalam-suggestions .add-to-dic-cont {\n  direction: rtl;\n  display: flex;\n  flex-direction: row;\n  justify-content: space-between;\n  padding: 16px;\n  background-color: #fff;\n  border-bottom-left-radius: 4px;\n  border-bottom-right-radius: 4px;\n  align-items: center;\n  width: 100%;\n  height: 46px;\n  box-sizing: border-box;\n}\nqalam-suggestions .ignore-cont .ignore-icon, qalam-suggestions .add-to-dic-cont .add-to-dic-icon {\n  width: 15px;\n  height: 15px;\n}\nqalam-suggestions .ignore-cont .ignore-text, qalam-suggestions .add-to-dic-cont .add-to-dic-text{\n  opacity: 0.55;\n  color: #000;\n  font-family: Tajawal-Regular, sans-serif !important;\n  font-size: 14px;\n  margin: -2px 0 0 0;\n  padding: 0;\n  display: inline-block;\n}\nqalam-suggestions .ignore-cont:hover,qalam-suggestions .add-to-dic-cont:hover {\n  background-color: #e7e7e7;\n}\nqalam-suggestions .ignore-cont:hover .ignore-text,qalam-suggestions .add-to-dic-cont:hover .add-to-dic-text{\n  opacity: 0.7;\n}\n.d-none{\n  display:none;\n}\nqalam-container{\n  display:block !important;\n}\n",
    17     FLAT_RED = "#EC2240", FLAT_YELLOW = "#ffc940", FLAT_BLUE = "#1873D3", FLAT_GREEN = "#1DBC60",
    18     FLAT_BLUE_GREY = "#263238", FLAT_PURPLE = "#4a148c", FLAT_ORANGE = "#263238",
    19     TRANSPARENT_RED = "rgba(255, 0, 0, 0.08)", TRANSPARENT_YELLOW = "rgba(255, 201, 64, 0.27)",
    20     TRANSPARENT_BLUE = "rgba(0, 255, 255, 0.08)", TRANSPARENT_GREEN = "rgba(0, 255, 0, 0.08)",
    21     TRANSPARENT_FLAT_BLUE_GREY = "rgba(38, 50, 56, 0.08)", TRANSPARENT_FLAT_PURPLE = "rgba(74, 20, 140, 0.08)",
    22     TRANSPARENT_FLAT_ORANGE = "rgba(38, 50, 56, 0.08)", SC_LINE_COLOR = FLAT_RED, SC_LABEL_COLOR = TRANSPARENT_RED,
    23     NUM_LINE_COLOR = FLAT_YELLOW, NUM_LABEL_COLOR = TRANSPARENT_YELLOW, GRAMMAR_LINE_COLOR = FLAT_BLUE,
    24     GRAMMAR_LABEL_COLOR = TRANSPARENT_BLUE, T_LINE_COLOR = FLAT_GREEN, T_LABEL_COLOR = TRANSPARENT_GREEN,
    25     PHRASING_LINE_COLOR = FLAT_YELLOW, PHRASING_LABEL_COLOR = TRANSPARENT_YELLOW, TERM_LINE_COLOR = FLAT_PURPLE,
    26     TERM_LABEL_COLOR = TRANSPARENT_FLAT_PURPLE, TAFQEET_LINE_COLOR = FLAT_ORANGE,
    27     TAFQEET_LABEL_COLOR = TRANSPARENT_FLAT_ORANGE, $ = jQuery.noConflict(), scr = document.createElement("script"),
    28     head = document.head || document.getElementsByTagName("head")[0];
     1const baseLink = 'https://api.qalam.ai/';
     2let originalText = null,
     3  qalamAgent = 'Wordpress',
     4  type = null,
     5  doneCallback = null,
     6  API_LINK = '',
     7  TOKEN = '',
     8  shadowRoot = null,
     9  qalamDisablePrompt = null,
     10  isTextArea = null,
     11  triggerFlag = !0,
     12  SCServiceActive = null,
     13  qalamExtension = null,
     14  qalamExtensionCont = null,
     15  qalamHighlightsCont = null,
     16  qalamMirror = null,
     17  qalamSuggestions = null,
     18  wrongSuggestionItem = null,
     19  element = null,
     20  withoutScrollDiff = 0,
     21  elementParent = null,
     22  typingStallCounter = 0,
     23  secondsCounter = null,
     24  resizeHoldCounter = null,
     25  currentTextSuggestions = [],
     26  ignoredSet = new Set(),
     27  removeSuggestionsTimeout = null,
     28  selectedText = '',
     29  isTashkeelActive = null,
     30  isTawtheeqActive = null,
     31  isWriterAllowedToAddToDic = !1,
     32  activeFrameId = null,
     33  offset_indices = null,
     34  editorId = '',
     35  PATH_MODE = 'PATH_MODE',
     36  QUERY_MODE = 'QUERY_MODE';
     37var cssId = 'myCss',
     38  INTERSECTION_THRESHOLD = 0.7,
     39  REMOVE_SUGGESTION_DELAY = 300,
     40  TYPING_STALL = 1,
     41  ANIMATION_DELAY = 1e3,
     42  STYLES_BLOCKING = new Set([
     43    'block',
     44    'flex',
     45    'flow-root',
     46    'grid',
     47    'list-item',
     48    'table',
     49    'table-caption',
     50    'table-cell',
     51    'table-footer-group',
     52    'table-header-group',
     53    'table-row',
     54    'table-row-group',
     55  ]),
     56  example =
     57    '\nقلم للأعمال\nمساعد الكتابة الذكي للغة العربية\nعن قلم:\nقال تعالى: نون والقلم وما يسطرون\nوقال تعالى: إن الله وملائكته يصلون على النبي يا أيها الذين آمنوا صلوا عليه وسلموا تسليما\nقلم واحدة من شركات مجموعة موضوع. كوم (المجموعة)، وهي الراءدة في تطبيقات الذكاء الاصطناعي باللغة العربية داخل المجموعة . وبعد نجاح إستخدام هذه التطبيقات داخلياً ولدى بعض عملاءنا المقربون ، قررنا مشاركة التجربة مع الشركات، و المؤسسات، والوزارات الأخرى محليا داخل الأردنوخارجها.\nيعمل على تطوير قلم نخبة من الأخصائيون والخبراء في اللغة العربيه وحوسبتها، وفي علم البيانات والذكاء الاصطناعي، اضافه إلى مهندسو البرمجيات والحاسوب. جميعهم يعملون معاً لصناعة منتج ذكي، يخدم الكتابة بلغة الصاد.\nلماذا قلم؟\nنعلم أن كتابة المحتوي، وتدقيقه، والمحافظة على أسلوب الكتابة والنسق المتبع في شركتكم مهمة ليست بالهلة، خاصة حين يكون بصيغ مختلفة، وفي حجماً كبير، مثل:\nالتقارير بشتى أنواعها\nالأبحاث والنشر\nالعروض الفنية و المالية\nالمراسلاة والخطابات\nالرسائل الإلكترونية\nوغيرها\nومن هنا جاءت المهمه التي اضطلع بها قلم للأعمال أن يكون عوناً لكم في التخفيف من عبئ تدقيق المحتوى بشتى أنواعه، ومساعدة الكتّاب/الموظفين حتى ينتجو محتوى سليماً من الأخطائ الإملائية واللغوية والقواعدية، وتحسين الصياغة في اللغة العربية، بالإضافة إلى مساعدتهم في اتباع النسق وأسلوب الكتابة الخاص بالشركة.',
     58  STYLES_HIDDEN = new Set(['none', 'table-column', 'table-column-group']),
     59  STYLES_WRAP = new Set(['pre', 'pre-wrap', 'pre-line']),
     60  BUTTON_NORMAL_COLOR = '#008677',
     61  BUTTON_ERROR_COLOR = '#EC2240',
     62  QALAM_TOOLBAR_STYLE = '',
     63  MIRROR_SHADOW_STYLE =
     64    '\nqalam-mirror {\n  border: 0px transparent;\n  text-shadow: none;\n  text-indent: 0px;\n  word-break: normal;\n  overflow-wrap: break-word;\n  word-spacing: 0px;\n  writing-mode: horizontal-tb;\n  white-space: pre-wrap;\n  vertical-align: baseline;\n  clear: both;\n  box-sizing: content-box;\n  position: fixed;\n  top: 0px;\n  left: 0px;\n  background: transparent;\n  pointer-events: none;\n  overflow: hidden;\n  color: transparent;\n  z-index: 1;\n  visibility: hidden;\n}\nqalam-disable-prompt {\n  position: fixed;\n  padding: 24px 32px;\n  border-radius: 4px;\n  background-color: #fff;\n  box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.2);\n  pointer-events: all;\n  width: 228px;\n  height: fit-content;\n  font-family: Tajawal, sans-serif !important;\n  box-sizing: border-box;\n  z-index: 2147483647;\n}\nqalam-disable-prompt .prompt-title {\n  color: #000;\n  font-size: 18px;\n  letter-spacing: 0;\n  line-height: 36px;\n  text-align: right;\n  margin: 0 0 8px 0;\n  padding: 0;\n  display: inline-block;\n  font-family: Tajawal, sans-serif !important;\n  width: 100%;\n}\n.qalam-btn {\n  width: 100%;\n  height: 32px;\n  font-size: 14px;\n  font-weight: 600;\n  border-radius: 4px;\n  margin: 16px 0 0 0;\n  padding: 0;\n  outline: none;\n  border-style: solid;\n  cursor: pointer;\n  font-family: Tajawal, sans-serif !important;\n}\n.qalam-btn.secondary-btn {\n  border: 1px solid #008677;\n  color: #008677;\n  background-color: #fff;\n}\n.qalam-btn.primary-btn {\n  background-color: #008677;\n  color: #fff;\n  border-color: #008677;\n}\nqalam-suggestions {\n  width: 175px;\n  border-radius: 4px;\n  background-color: #ffffff;\n  box-shadow: 0 1px 8px 0 rgba(0, 0, 0, 0.2);\n  position: fixed;\n  display: none;\n  cursor: pointer;\n  z-index: 2147483647;\n  pointer-events: all;\n}\nqalam-suggestions suggestions-cont > div:nth-of-type(1) {\n  border-top-right-radius: 4px;\n  border-top-left-radius: 4px;\n}\nqalam-suggestions suggestions-cont suggestion-item {\n  padding: 16px;\n  background-color: #fff;\n  width: 100%;\n  height: 56px;\n  display: flex;\n  align-items: center;\n  box-sizing: border-box;\n}\nqalam-suggestions suggestions-cont suggestion-item suggestion-text {\n  color: #008677;\n  font-family: Tajawal, sans-serif !important;\n  font-size: 20px;\n  font-weight: 600;\n  text-align: right;\n  width: 100%;\n  height: fit-content;\n  margin: -2px 0 0 0;\n  padding: 0;\n  direction: rtl;\n  display: inline-block;\n  text-overflow: ellipsis;\n  overflow: hidden;\n  white-space: nowrap;\n}\nqalam-suggestions suggestions-cont suggestion-item:hover {\n  background-color: #008677;\n}\nqalam-suggestions suggestions-cont suggestion-item:hover suggestion-text {\n  color: #fff;\n}\nqalam-suggestions .ignore-cont{\n  position: relative;\n}\nqalam-suggestions .ignore-cont,qalam-suggestions .add-to-dic-cont, qalam-suggestions .wrong-suggestion-cont {\n  direction: rtl;\n  display: flex;\n  flex-direction: row;\n  justify-content: start;\n  padding: 12px;\n  background-color: #fff;\n  border-bottom-left-radius: 4px;\n  border-bottom-right-radius: 4px;\n  align-items: center;\n  width: 100%;\n  height: 46px;\n  box-sizing: border-box;\n}\nqalam-suggestions .ignore-cont .ignore-icon, qalam-suggestions .add-to-dic-cont .add-to-dic-icon,  qalam-suggestions .wrong-suggestion-cont .wrong-suggestion-icon {\n  width: 15px;\n  height: 15px;\n  margin-left: 10px;\n}\nqalam-suggestions .ignore-cont .ignore-text, qalam-suggestions .add-to-dic-cont .add-to-dic-text,  qalam-suggestions .wrong-suggestion-cont .wrong-suggestion-text{\n  opacity: 0.55;\n  color: #000;\n  font-family: Tajawal, sans-serif !important;\n  font-size: 14px;\n  margin: -2px 0 0 0;\n  padding: 0;\n  display: inline-block;\n}\nqalam-suggestions .ignore-cont:hover,qalam-suggestions .add-to-dic-cont:hover, qalam-suggestions .wrong-suggestion-cont:hover {\n  background-color: #e7e7e7;\n}\nqalam-suggestions .ignore-cont:hover .ignore-text,qalam-suggestions .add-to-dic-cont:hover .add-to-dic-text,  qalam-suggestions .wrong-suggestion-cont:hover .wrong-suggestion-text{\n  opacity: 0.7;\n}\n\nqalam-suggestions .wrong-suggestion-more-icon {\n\tposition: absolute;\n\tright: 85%;\n\tpadding: 4px;\n\tborder-radius: 10px\n  }\n  qalam-suggestions .wrong-suggestion-more-icon:hover {\n\tbackground-color: #9F9898;\n  }\n  \n  qalam-suggestions .wrong-suggestion-cont{\n\tposition: absolute;\n\tright: 100%;\n\ttop: 0;\n\tbox-shadow: 0 1px 8px 0 rgba(0, 0, 0, 0.2);\n\tborder-radius: 10px;\n  }\n.d-none{\n  display:none;\n}\nqalam-container{\n  display:block !important;\n}\n';
     65const FLAT_RED = '#EC2240',
     66  FLAT_YELLOW = '#ffc940',
     67  FLAT_BLUE = '#1873D3',
     68  FLAT_GREEN = '#1DBC60',
     69  FLAT_BLUE_GREY = '#263238',
     70  FLAT_PURPLE = '#4a148c',
     71  FLAT_ORANGE = '#263238',
     72  FLAT_GREY = '#7393B3',
     73  TRANSPARENT_RED = 'rgba(255, 0, 0, 0.08)',
     74  TRANSPARENT_YELLOW = 'rgba(255, 201, 64, 0.27)',
     75  TRANSPARENT_BLUE = 'rgba(0, 255, 255, 0.08)',
     76  TRANSPARENT_GREEN = 'rgba(0, 255, 0, 0.08)',
     77  TRANSPARENT_FLAT_BLUE_GREY = 'rgba(38, 50, 56, 0.08)',
     78  TRANSPARENT_FLAT_PURPLE = 'rgba(74, 20, 140, 0.08)',
     79  TRANSPARENT_FLAT_ORANGE = 'rgba(38, 50, 56, 0.08)',
     80  TRANSPARENT_GREY = '#b1b1b114',
     81  SC_LINE_COLOR = FLAT_RED,
     82  SC_LABEL_COLOR = TRANSPARENT_RED,
     83  OS_LINE_COLOR = '#7393B3',
     84  OS_LABEL_COLOR = '#b1b1b114',
     85  NUM_LINE_COLOR = '#ffc940',
     86  NUM_LABEL_COLOR = TRANSPARENT_YELLOW,
     87  GRAMMAR_LINE_COLOR = FLAT_BLUE,
     88  GRAMMAR_LABEL_COLOR = TRANSPARENT_BLUE,
     89  T_LINE_COLOR = FLAT_GREEN,
     90  T_LABEL_COLOR = TRANSPARENT_GREEN,
     91  PHRASING_LINE_COLOR = FLAT_YELLOW,
     92  PHRASING_LABEL_COLOR = TRANSPARENT_YELLOW,
     93  TERM_LINE_COLOR = FLAT_PURPLE,
     94  TERM_LABEL_COLOR = TRANSPARENT_FLAT_PURPLE,
     95  TAFQEET_LINE_COLOR = FLAT_ORANGE,
     96  TAFQEET_LABEL_COLOR = TRANSPARENT_FLAT_ORANGE,
     97  $ = jQuery.noConflict(),
     98  scr = document.createElement('script'),
     99  head = document.head || document.getElementsByTagName('head')[0];
    29100
    30101function setParams(e, t, n, a) {
    31     this.clientId = e, this.documentId = t, this.mode = n, this.modeValue = a
    32 }
    33 
     102  (this.clientId = e),
     103    (this.documentId = t),
     104    (this.mode = n),
     105    (this.modeValue = a);
     106}
    34107function activate(e, t) {
    35     SCServiceActive = !0, API_LINK = e, TOKEN = t, getConfig(), getTermsConfig(), init()
    36 }
    37 
     108  (SCServiceActive = !0),
     109    (API_LINK = e),
     110    (TOKEN = t),
     111    getConfig(),
     112    getTermsConfig(),
     113    setSDKVersion(),
     114    setInterval(function () {
     115      setSDKVersion();
     116    }, 1 * 1000 * 60 * 60 * 24),
     117    init();
     118}
     119function setSDKVersion() {
     120  $.ajax({
     121    dataType: 'json',
     122    url: baseLink + 'sdk/version',
     123    method: 'PUT',
     124    timeout: 0,
     125    headers: {
     126      'Content-Type': 'application/json',
     127      Authorization: `${clientId}`,
     128      'Qalam-Agent': qalamAgent,
     129      'sdk-version': '1.1.0-wp',
     130    },
     131    success: function () {},
     132    error: function () {},
     133  });
     134}
    38135function checkFocusedElement() {
    39     if ($(element).next().fadeOut(700), assignEditorIds(), SCServiceActive) {
    40         let e = $(document.activeElement);
    41         e.hasClass("gramm_editor") && e.attr("data-gramm_editor", "false"), e.hasClass("qalam_editor") && e.attr("data-qalam_editor", "false"), (e.is("textarea") || "true" == e.attr("contenteditable")) && listenerTriggered(document.activeElement)
     136  if ((assignEditorIds(), SCServiceActive)) {
     137    let e = $(document.activeElement);
     138    e.hasClass('gramm_editor') && e.attr('data-gramm_editor', 'false'),
     139      e.hasClass('qalam_editor') && e.attr('data-qalam_editor', 'false'),
     140      (e.is('textarea') || 'true' == e.attr('contenteditable')) &&
     141        listenerTriggered(document.activeElement);
     142  }
     143  clearInterval(resizeHoldCounter), (resizeHoldCounter = null);
     144}
     145function init() {
     146  function e(e, t) {
     147    var n = 0;
     148    return function () {
     149      var a = this,
     150        o = arguments;
     151      clearTimeout(n),
     152        (n = setTimeout(function () {
     153          e.apply(a, o);
     154        }, t || 0));
     155    };
     156  }
     157
     158  getCookie('qalam_user_id') || setCookie(),
     159    checkFocusedElement(),
     160    document.addEventListener('focus', checkFocusedElement, !0);
     161  let t = 0,
     162    n = 0,
     163    a = 0;
     164  var o = setInterval(function () {
     165    let l = document.querySelectorAll('iframe');
     166    if (0 != l.length) {
     167      for (var i = 0; i < l.length; ) {
     168        let s = l[i];
     169        if ((assignIframeEditorIds(s, i), s)) {
     170          let o =
     171            s.contentDocument && s.contentDocument.body
     172              ? s.contentDocument.body.parentElement.querySelector(
     173                  '[contenteditable]'
     174                ) || s.contentDocument.body.parentElement
     175              : null;
     176          if (o) {
     177            let l = s;
     178            s = s.contentDocument.querySelector('[contenteditable]');
     179            let i = o;
     180            $(i).on('click', function (e) {
     181              let t = tagIframe(l);
     182              activeFrameId !== t &&
     183                ((activeFrameId = t),
     184                setTimeout(function () {
     185                  listenerTriggered($(l)[0]);
     186                }, 10));
     187            }),
     188              $(i).on('mousemove', function (e) {
     189                if (isEventInsideElement(e, qalamSuggestions))
     190                  stopRemoveSuggestionsTimeout();
     191                else {
     192                  let t = $('qalam-label.active');
     193                  if (t.length) {
     194                    isInLabel = !1;
     195                    for (let n = 0; n < t.length; n++)
     196                      if (isEventInsideElement(e, t[n])) {
     197                        isInLabel = !0;
     198                        break;
     199                      }
     200                    isInLabel
     201                      ? stopRemoveSuggestionsTimeout()
     202                      : setRemoveSuggestionsTimeout();
     203                  }
     204                }
     205              }),
     206              $(i).unbind('keyup'),
     207              $(i).keyup(
     208                e(function (e) {
     209                  clearLabels(),
     210                    8 == e.keyCode
     211                      ? (clearTimeout(t),
     212                        SCServiceActive &&
     213                          (t = setTimeout(listenerTriggered($(l)[0]), 800)))
     214                      : (clearTimeout(n),
     215                        SCServiceActive &&
     216                          91 != e.keyCode &&
     217                          81 != e.keyCode &&
     218                          17 != e.keyCode &&
     219                          (n = setTimeout(listenerTriggered($(l)[0]), 600)));
     220                }, 1e3)
     221              ),
     222              i &&
     223                (i.onpaste = () => {
     224                  SCServiceActive &&
     225                    (clearTimeout(a),
     226                    (a = setTimeout(listenerTriggered($(l)[0]), 600)));
     227                  let e = 1;
     228                  e &&
     229                    setTimeout(() => {
     230                      spellCheckText(!0), (e = 0);
     231                    }, 1e3);
     232                });
     233          }
     234        }
     235        setTimeout(() => {
     236          clearInterval(o);
     237        }, 5e3),
     238          i++;
     239      }
     240      clearInterval(o);
    42241    }
    43     clearInterval(resizeHoldCounter), resizeHoldCounter = null
    44 }
    45 
    46 function init() {
    47     function e(e, t) {
    48         var n = 0;
    49         return function () {
    50             var a = this, o = arguments;
    51             clearTimeout(n), n = setTimeout(function () {
    52                 e.apply(a, o)
    53             }, t || 0)
     242  }, 5e3);
     243  $(document).on('click', function (e) {
     244    $(e.target).closest('qalam-button-cont').length ||
     245      isEventInsideElement(e, qalamDisablePrompt) ||
     246      removeDisablePrompt(),
     247      isEventInsideElement(e, qalamSuggestions) || removeQalamSuggestions(),
     248      clearInterval(resizeHoldCounter),
     249      (resizeHoldCounter = null);
     250  }),
     251    mobileCheck &&
     252      document.addEventListener(
     253        'touchstart',
     254        function (e) {
     255          'QALAM-LABEL' == e.target.tagName &&
     256            (e.target.classList.add('active'), renderQalamSuggestions(e)),
     257            'QALAM-LABEL' != e.target.tagName &&
     258              'QALAM-SUGGESTIONS' != e.target.tagName &&
     259              'SUGGESTION-ITEM' != e.target.tagName &&
     260              'SUGGESTION-TEXT' != e.target.tagName &&
     261              'QALAM-MIRROR-SHADOW' != e.target.tagName &&
     262              ($(qalamSuggestions).remove(),
     263              $(
     264                'qalam-extension .qalam-highlights-cont qalam-label'
     265              ).removeClass('active'));
     266        },
     267        !1
     268      ),
     269    $(document).on('mousemove', function (e) {
     270      if (
     271        isEventInsideElement(e, qalamSuggestions) ||
     272        isEventInsideElement(e, wrongSuggestionItem)
     273      )
     274        stopRemoveSuggestionsTimeout();
     275      else {
     276        let t = $('qalam-label.active');
     277        if (t.length) {
     278          isInLabel = !1;
     279          for (let n = 0; n < t.length; n++)
     280            if (isEventInsideElement(e, t[n])) {
     281              isInLabel = !0;
     282              break;
     283            }
     284          isInLabel
     285            ? stopRemoveSuggestionsTimeout()
     286            : setRemoveSuggestionsTimeout();
    54287        }
     288      }
     289    });
     290}
     291
     292function tagIframe(e) {
     293  if (e.getAttribute('data-qtag')) return e.getAttribute('data-qtag');
     294  const t = Math.random().toString(36).substring(5);
     295  return e.setAttribute('data-qtag', t), t;
     296}
     297
     298function isEventInsideElement(e, t) {
     299  if (null == t) return !1;
     300  let n = t.getBoundingClientRect();
     301  return (
     302    e.clientX >= n.left &&
     303    e.clientX <= n.right &&
     304    e.clientY >= n.top &&
     305    e.clientY <= n.bottom
     306  );
     307}
     308
     309function setRemoveSuggestionsTimeout() {
     310  null === removeSuggestionsTimeout &&
     311    (removeSuggestionsTimeout = setTimeout(function () {
     312      removeQalamSuggestions(), (removeSuggestionsTimeout = null);
     313    }, REMOVE_SUGGESTION_DELAY));
     314}
     315function stopRemoveSuggestionsTimeout() {
     316  null !== removeSuggestionsTimeout &&
     317    (clearTimeout(removeSuggestionsTimeout), (removeSuggestionsTimeout = null));
     318}
     319
     320function getText() {
     321  offset_indices = new Set();
     322  if (!element) {
     323    return '';
     324  }
     325  //IFRAME
     326  if (element.tagName == 'IFRAME') {
     327    let body = element.contentDocument.querySelector('[contenteditable]');
     328    let text = '';
     329    let stack = [{ element: body, parent: null }];
     330    editorId = element.getAttribute('data-qid');
     331    while (stack.length) {
     332      let currentNode = stack.pop();
     333      let parentNode = currentNode.parent;
     334      currentNode = currentNode.element;
     335      if (!currentNode) {
     336        continue;
     337      }
     338      if (currentNode.tagName == 'BR') {
     339        // Add a dummy newline
     340        if (text.length > 0 && !offset_indices.has(text.length - 1)) {
     341          offset_indices.add(text.length);
     342          text += '\n';
     343        }
     344      } else if (currentNode.nodeType == 3) {
     345        // TEXT NODE, GET TEXT CONTENT
     346
     347        let currentText = currentNode.textContent;
     348        // REPLACE NEWLINES WITH SPACES IF PARENT `WHITE-SPACE` STYLE DOESN'T RENDER NEWLINES
     349        if (
     350          !STYLES_WRAP.has(window.getComputedStyle(parentNode, null).whiteSpace)
     351        )
     352          currentText = currentText.replace(/\n/g, ' ');
     353
     354        text += currentText;
     355      } else {
     356        let displayStyle =
     357          typeof currentNode == Element
     358            ? window.getComputedStyle(currentNode, null).display
     359            : '';
     360
     361        // HIDDEN ELEMENT, SKIP
     362        if (STYLES_HIDDEN.has(displayStyle)) continue;
     363
     364        // Block element, to add a dummy newline after all child nodes
     365        if (STYLES_BLOCKING.has(displayStyle))
     366          stack.push({
     367            element: document.createElement('br'),
     368            parent: currentNode,
     369          });
     370
     371        // Push child nodes to stack
     372        let list = [];
     373        Array.from(currentNode.childNodes)
     374          .reverse()
     375          .forEach((childNode) => {
     376            list.push({ element: childNode, parent: currentNode });
     377          });
     378        stack.push(...list);
     379
     380        // Block element, to add a dummy newline before all child nodes
     381        if (STYLES_BLOCKING.has(displayStyle))
     382          stack.push({
     383            element: document.createElement('br'),
     384            parent: currentNode,
     385          });
     386      }
    55387    }
    56 
    57     getCookie("qalam_user_id") || setCookie(), checkFocusedElement(), document.addEventListener("focus", checkFocusedElement, !0);
    58     let t = 0, n = 0, a = 0;
    59     var o = setInterval(function () {
    60         let l = document.querySelectorAll("iframe");
    61         if (0 != l.length) {
    62             for (var i = 0; i < l.length;) {
    63                 let s = l[i];
    64                 if (assignIframeEditorIds(s, i), s) {
    65                     let o = s.contentDocument && s.contentDocument.body ? s.contentDocument.body.parentElement.querySelector("[contenteditable]") || s.contentDocument.body.parentElement : null;
    66                     if (o) {
    67                         let l = s;
    68                         s = s.contentDocument.querySelector("[contenteditable]");
    69                         let i = o;
    70                         $(i).on("click", function (e) {
    71                             let t = tagIframe(l);
    72                             activeFrameId !== t && (activeFrameId = t, setTimeout(function () {
    73                                 listenerTriggered($(l)[0])
    74                             }, 10))
    75                         }), $(i).on("mousemove", function (e) {
    76                             if (isEventInsideElement(e, qalamSuggestions)) stopRemoveSuggestionsTimeout(); else {
    77                                 let t = $("qalam-label.active");
    78                                 if (t.length) {
    79                                     isInLabel = !1;
    80                                     for (let n = 0; n < t.length; n++) if (isEventInsideElement(e, t[n])) {
    81                                         isInLabel = !0;
    82                                         break
    83                                     }
    84                                     isInLabel ? stopRemoveSuggestionsTimeout() : setRemoveSuggestionsTimeout()
    85                                 }
    86                             }
    87                         }), $(i).unbind("keyup"), $(i).keyup(e(function (e) {
    88                             clearLabels(), 8 == e.keyCode ? (clearTimeout(t), SCServiceActive && (t = setTimeout(listenerTriggered($(l)[0]), 800))) : (clearTimeout(n), SCServiceActive && 91 != e.keyCode && 81 != e.keyCode && 17 != e.keyCode && (n = setTimeout(listenerTriggered($(l)[0]), 600)))
    89                         }, 1e3)), i && (i.onpaste = (() => {
    90                             SCServiceActive && (clearTimeout(a), a = setTimeout(listenerTriggered($(l)[0]), 600));
    91                             let e = 1;
    92                             e && setTimeout(() => {
    93                                 spellCheckText(!0), e = 0
    94                             }, 1e3)
    95                         }))
    96                     }
    97                 }
    98                 setTimeout(() => {
    99                     clearInterval(o)
    100                 }, 5e3), i++
    101             }
    102             clearInterval(o)
     388    return text;
     389  }
     390
     391  //TEXTAREA
     392  if (isTextArea) {
     393    editorId = element.getAttribute('data-qid');
     394    return $(element).val() || $(element).text();
     395  }
     396
     397  // TRAVERSE THROUGH TREE OF DIV (DFS)
     398  let text = '';
     399  let stack = [{ element: element, parent: null }];
     400
     401  while (stack.length) {
     402    let currentNode = stack.pop();
     403    let parentNode = currentNode.parent;
     404    currentNode = currentNode.element;
     405
     406    if (currentNode.tagName == 'BR') {
     407      // Add a dummy newline
     408      if (text.length > 0 && !offset_indices.has(text.length - 1)) {
     409        offset_indices.add(text.length);
     410        text += '\n';
     411      }
     412    } else if (currentNode.nodeType == 3) {
     413      // Text node, get text content
     414
     415      let currentText = currentNode.textContent;
     416      // Replace newlines with spaces if parent `white-space` style doesn't render newlines
     417      let displayStyle =
     418        typeof currentNode == Element
     419          ? window.getComputedStyle(currentNode, null).whiteSpace
     420          : '';
     421      if (!STYLES_WRAP.has(displayStyle))
     422        currentText = currentText.replace(/\n/g, ' ');
     423
     424      text += currentText;
     425    } else {
     426      let displayStyle =
     427        typeof currentNode == Element
     428          ? window.getComputedStyle(currentNode, null).display
     429          : '';
     430      // Hidden element, skip
     431      if (STYLES_HIDDEN.has(displayStyle)) continue;
     432
     433      // Block element, to add a dummy newline after all child nodes
     434      if (STYLES_BLOCKING.has(displayStyle))
     435        stack.push({
     436          element: document.createElement('br'),
     437          parent: currentNode,
     438        });
     439
     440      // Push child nodes to stack
     441      let list = [];
     442      Array.from(currentNode.childNodes)
     443        .reverse()
     444        .forEach((childNode) => {
     445          list.push({ element: childNode, parent: currentNode });
     446        });
     447      stack.push(...list);
     448
     449      // Block element, to add a dummy newline before all child nodes
     450      if (STYLES_BLOCKING.has(displayStyle))
     451        stack.push({
     452          element: document.createElement('br'),
     453          parent: currentNode,
     454        });
     455    }
     456  }
     457  editorId = element.getAttribute('data-qid');
     458  return text;
     459}
     460
     461function listenerTriggered(e) {
     462  if ((assignEditorIds(), element != e || 'IFRAME' == e.tagName)) {
     463    if (
     464      (unmountQalamComponent(),
     465      (isTextArea =
     466        'TEXTAREA' == (element = e).tagName || 'IFRAME' == element.tagName))
     467    ) {
     468      let e = getText();
     469      $(element).val('');
     470      let t = parseFloat($(element).css('border-left-width').replace('px', '')),
     471        n = parseFloat($(element).css('border-right-width').replace('px', ''));
     472      (withoutScrollDiff = element.offsetWidth - element.clientWidth - t - n),
     473        $(element).val(e);
     474    }
     475    if (
     476      ($(element).attr('spellcheck', !1),
     477      (elementParent = element.parentNode),
     478      '0px' == $(elementParent).css('width') &&
     479        '0px' == $(elementParent).css('height') &&
     480        $(elementParent).css('position', 'unset'),
     481      renderQalamMirror(),
     482      renderQalamComponent(),
     483      'IFRAME' != element.tagName)
     484    )
     485      $(element).on('scroll', function () {
     486        handleReposition(!1);
     487      }),
     488        $(window).on('scroll', function () {
     489          handleReposition(!1);
     490        }),
     491        $(window).on('resize', function () {
     492          handleReposition(!0);
     493        });
     494    else {
     495      let e,
     496        t = $(element).contents();
     497      $(t).on('scroll', function () {
     498        !(function () {
     499          let e = $('qalam-extension .qalam-highlights-cont qalam-label');
     500          for (let t = 0; t < e.length; t++) {
     501            const n = e[t];
     502            n.style.display = 'none';
     503          }
     504        })(),
     505          clearTimeout(e),
     506          (e = setTimeout(function () {
     507            handleReposition(!0);
     508          }, 200));
     509      });
     510    }
     511    new ResizeObserver(function () {
     512      handleReposition(!0);
     513    }).observe(element),
     514      '' != getText().trim() && (languageChecker(), spellCheckText());
     515  }
     516}
     517
     518function handleReposition(e) {
     519  removeQalamSuggestions(),
     520    removeDisablePrompt(),
     521    repositionQalamButton(),
     522    $(qalamExtensionCont).scrollTop($(element).scrollTop()),
     523    $(qalamExtensionCont).scrollLeft($(element).scrollLeft()),
     524    e && SCServiceActive && drawLabels(!0);
     525}
     526
     527function repositionQalamButton() {
     528  let e = $('qalam-button-cont');
     529  if (
     530    (e.css('position', 'absolute'),
     531    (qalamExtensionCont ? qalamExtensionCont.getBoundingClientRect() : '')
     532      .height > 30)
     533  ) {
     534    let t = 0;
     535    if ('rtl' == $(element).css('direction')) {
     536      let e = parseFloat($(element).css('border-left-width').replace('px', '')),
     537        n = parseFloat($(element).css('border-right-width').replace('px', ''));
     538      t = element.offsetWidth - element.clientWidth - e - n;
     539    }
     540    e.css('left', 6 + t), e.css('bottom', 6), e.css('padding', 4);
     541  } else e.css('left', 6), e.css('bottom', 6), e.css('padding', 0);
     542}
     543
     544function renderQalamComponent() {
     545  if ((drawLabels(!0), !$(elementParent).find('qalam-container').length)) {
     546    let e = document.createElement('qalam-container');
     547    $(elementParent).append(e);
     548    let t = document.createElement('qalam-wrapper');
     549    (qalamExtension = document.createElement('qalam-extension')),
     550      (qalamExtensionCont = document.createElement('qalam-extension-cont')),
     551      ((qalamHighlightsCont = document.createElement('div')).className =
     552        'qalam-highlights-cont');
     553    let n = document.createElement('qalam-button-cont'),
     554      a = document.createElement('div');
     555    a.className = 'qalam-button';
     556    let o = document.createElement('p');
     557    (o.className = 'errors'),
     558      $(a).css('backgroundImage', `url(${settings.assetsPath}/images/128.png)`),
     559      isUrlDisabled()
     560        ? $(a).css('background-image', 'url(../images/disabled.png)')
     561        : $(a).css(
     562            'backgroundImage',
     563            `url(${settings.assetsPath}/images/128.png)`
     564          );
     565    let l = document.createElement('div');
     566    l.className = 'separator';
     567    let i = document.createElement('img');
     568    (i.className = 'disable-icon'),
     569      (i.src = `${settings.assetsPath}/images/disable.svg`),
     570      (i.title = 'تعطيل عمل قلم'),
     571      $(i).on('click', function (e) {
     572        showDisablePrompt();
     573      }),
     574      resizeQalamExtension();
     575    let s = document.createElement('qalam-tashkeel-blk');
     576    (s.className = 'qalam-tashkeel'), (s.style.display = 'none');
     577    let r = document.createElement('qalam-quraan-blk');
     578    (r.className = 'qalam-quraan'), (r.style.display = 'none');
     579    let c = document.createElement('img');
     580    (c.className = 'qalam-quraan-icon'),
     581      (c.src = `${settings.assetsPath}/images/quran_3.svg`);
     582    let m = document.createElement('img');
     583    if (
     584      ((m.className = 'qalam-tashkeel-icon'),
     585      (m.src = `${settings.assetsPath}/images/tashkeel.svg`),
     586      (qalamExtensionCont.style.width = '100%'),
     587      (qalamExtensionCont.style.height = '100%'),
     588      a.appendChild(o),
     589      n.appendChild(a),
     590      n.appendChild(l),
     591      n.appendChild(i),
     592      qalamExtensionCont.appendChild(qalamHighlightsCont),
     593      qalamExtension.appendChild(qalamExtensionCont),
     594      isTashkeelActive &&
     595        (s.appendChild(m),
     596        s.appendChild(document.createElement('div')),
     597        qalamExtension.appendChild(s)),
     598      isTawtheeqActive &&
     599        (r.appendChild(c),
     600        r.appendChild(document.createElement('div')),
     601        qalamExtension.appendChild(r)),
     602      'IFRAME' == element.tagName)
     603    ) {
     604      let e =
     605          element.contentDocument && element.contentDocument.body
     606            ? element.contentDocument.body.parentElement.querySelector(
     607                '[contenteditable]'
     608              ) || element.contentDocument.body.parentElement
     609            : null,
     610        t = element.contentWindow || element.contentDocument;
     611      $(e).mouseup(function () {
     612        (selectedText = getSelectedText(t)),
     613          showTashkeelAndTawtheeq(selectedText, s, r);
     614      });
     615    } else
     616      $(element).mouseup(function () {
     617        (selectedText = getSelectedText(window)),
     618          showTashkeelAndTawtheeq(selectedText, s, r);
     619      });
     620    $(s).on('mousedown', function (e) {
     621      $(this).prop('disabled') || controlSelection(e);
     622    }),
     623      $(r).on('mousedown', function (e) {
     624        $(this).prop('disabled') || controlSelection(e);
     625      }),
     626      $(element).on(
     627        isTextArea ? 'input propertychange' : 'DOMSubtreeModified',
     628        function () {
     629          triggerFlag &&
     630            ('IFRAME' != element.tagName &&
     631              $('qalam-tashkeel-blk') &&
     632              $('qalam-quraan-blk'),
     633            clearButton(),
     634            clearLabels(),
     635            resizeQalamExtension(),
     636            typedIn());
    103637        }
    104     }, 5e3);
    105     $(document).on("click", function (e) {
    106         $(e.target).closest("qalam-button-cont").length || isEventInsideElement(e, qalamDisablePrompt) || removeDisablePrompt(), isEventInsideElement(e, qalamSuggestions) || removeQalamSuggestions(), clearInterval(resizeHoldCounter), resizeHoldCounter = null
    107     }), mobileCheck && document.addEventListener("touchstart", function (e) {
    108         "QALAM-LABEL" == e.target.tagName && (e.target.classList.add("active"), renderQalamSuggestions(e)), "QALAM-LABEL" != e.target.tagName && "QALAM-SUGGESTIONS" != e.target.tagName && "SUGGESTION-ITEM" != e.target.tagName && "SUGGESTION-TEXT" != e.target.tagName && "QALAM-MIRROR-SHADOW" != e.target.tagName && ($(qalamSuggestions).remove(), $("qalam-extension .qalam-highlights-cont qalam-label").removeClass("active"))
    109     }, !1), $(document).on("mousemove", function (e) {
    110         if (isEventInsideElement(e, qalamSuggestions)) stopRemoveSuggestionsTimeout(); else {
    111             let t = $("qalam-label.active");
    112             if (t.length) {
    113                 isInLabel = !1;
    114                 for (let n = 0; n < t.length; n++) if (isEventInsideElement(e, t[n])) {
    115                     isInLabel = !0;
    116                     break
    117                 }
    118                 isInLabel ? stopRemoveSuggestionsTimeout() : setRemoveSuggestionsTimeout()
    119             }
    120         }
    121     })
    122 }
    123 
    124 function tagIframe(e) {
    125     if (e.getAttribute("data-qtag")) return e.getAttribute("data-qtag");
    126     const t = Math.random().toString(36).substring(5);
    127     return e.setAttribute("data-qtag", t), t
    128 }
    129 
    130 function isEventInsideElement(e, t) {
    131     if (null == t) return !1;
    132     let n = t.getBoundingClientRect();
    133     return e.clientX >= n.left && e.clientX <= n.right && e.clientY >= n.top && e.clientY <= n.bottom
    134 }
    135 
    136 function setRemoveSuggestionsTimeout() {
    137     null === removeSuggestionsTimeout && (removeSuggestionsTimeout = setTimeout(function () {
    138         removeQalamSuggestions(), removeSuggestionsTimeout = null
    139     }, REMOVE_SUGGESTION_DELAY))
    140 }
    141 
    142 function stopRemoveSuggestionsTimeout() {
    143     null !== removeSuggestionsTimeout && (clearTimeout(removeSuggestionsTimeout), removeSuggestionsTimeout = null)
    144 }
    145 
    146 function getText() {
    147     if ("IFRAME" == element.tagName) {
    148         let e = element.contentDocument.querySelector("[contenteditable]");
    149         editorId = e.getAttribute("data-qid");
    150         let t = "", n = [{element: e, parent: null}];
    151         for (; n.length;) {
    152             let e = n.pop(), a = e.parent;
    153             if ("BR" == (e = e.element).tagName) t += `\n${DUMMY_STRING}\n`; else if (3 == e.nodeType) {
    154                 let n = e.textContent;
    155                 STYLES_WRAP.has(window.getComputedStyle(a, null).whiteSpace) || (n = n.replace(/\n/g, " ")), t += n
    156             } else {
    157                 let t = window.getComputedStyle(e, null).display;
    158                 if (STYLES_HIDDEN.has(t)) continue;
    159                 STYLES_BLOCKING.has(t) && n.push({element: document.createElement("br"), parent: e});
    160                 let a = [];
    161                 Array.from(e.childNodes).reverse().forEach(t => {
    162                     a.push({element: t, parent: e})
    163                 }), n.push(...a), STYLES_BLOCKING.has(t) && n.push({element: document.createElement("br"), parent: e})
    164             }
    165         }
    166         return t
     638      ),
     639      t.append(qalamExtension),
     640      qalamExtension.appendChild(n),
     641      e.append(t);
     642  }
     643}
     644function getConfig() {
     645  $.ajax({
     646    url: baseLink + 'test/config',
     647    method: 'GET',
     648    timeout: 0,
     649    headers: {
     650      'Content-Type': 'application/json',
     651      Authorization: `${clientId}`,
     652      'Qalam-Agent': qalamAgent,
     653    },
     654    success: function (e) {
     655      let t = e.categories.filter((e) => 'tashkeel' == e.id),
     656        n = e.categories.filter((e) => 'tawtheeq' == e.id);
     657      'true' == t[0].value || $('.qalam-tashkeel').remove(),
     658        (isTashkeelActive = 'true' == t[0].value),
     659        (isTawtheeqActive = 'true' == n[0].value);
     660    },
     661    error: function () {},
     662  });
     663}
     664
     665function getTermsConfig() {
     666  $.ajax({
     667    dataType: 'json',
     668    url: baseLink + 'dictionaries/words?fields=config',
     669    type: 'GET',
     670    headers: {
     671      'Content-Type': 'application/json',
     672      Authorization: `${clientId}`,
     673      'Qalam-Agent': qalamAgent,
     674    },
     675    success: function (e) {
     676      isWriterAllowedToAddToDic =
     677        'true' == e.dictionaryConfig.writerAllowedToAddDictionary;
     678    },
     679    error: function () {},
     680  });
     681}
     682
     683function controlSelection(e) {
     684  e.preventDefault(), e.stopPropagation();
     685  let t = e.currentTarget,
     686    n = '';
     687  if (
     688    ((n =
     689      'qalam-tashkeel' == e.currentTarget.classList.value
     690        ? 'SC_service_tashkeel'
     691        : 'SC_service_tawtheeq'),
     692    'IFRAME' == element.tagName)
     693  ) {
     694    let e = element.contentWindow || element.contentDocument;
     695    selectedText = getSelectedText(e);
     696  } else selectedText = getSelectedText(window);
     697  if (!selectedText || isEmpty(selectedText))
     698    return void hideTashkeelAndTawtheeq();
     699  $('qalam-tashkeel-blk').prop('disabled', !0),
     700    $('qalam-quraan-blk').prop('disabled', !0),
     701    $(t).find('div').addClass('qalam-icons-loader');
     702  let a = getUuid(),
     703    o = { text: selectedText, docId: a };
     704  'SC_service_tashkeel' == n &&
     705    $.ajax({
     706      dataType: 'json',
     707      url: baseLink + 'qalam/tashkeel',
     708      type: 'POST',
     709      headers: {
     710        'Content-Type': 'application/json',
     711        Authorization: `${clientId}`,
     712        'Qalam-Agent': qalamAgent,
     713      },
     714      data: JSON.stringify(o),
     715      success: function (e) {
     716        var n = e && e.text ? e.text : '';
     717        'IFRAME' == element.tagName
     718          ? (element.contentDocument.execCommand('insertText', !1, n),
     719            spellCheckText(!0))
     720          : isTextArea
     721          ? document.execCommand('insertText', !1, n)
     722          : document.execCommand('insertHTML', !1, n),
     723          $('qalam-tashkeel-blk,qalam-quraan-blk').removeClass('disabled'),
     724          $('qalam-tashkeel-blk').prop('disabled', !1),
     725          $('qalam-quraan-blk').prop('disabled', !1),
     726          $(t).find('div').removeClass('qalam-icons-loader'),
     727          (selectedText = null);
     728      },
     729      error: function () {},
     730    }),
     731    'SC_service_tawtheeq' == n &&
     732      $.ajax({
     733        dataType: 'json',
     734        url: baseLink + 'quran/tawtheeq',
     735        type: 'POST',
     736        headers: {
     737          'Content-Type': 'application/json',
     738          Authorization: `${clientId}`,
     739          'Qalam-Agent': qalamAgent,
     740        },
     741        data: JSON.stringify(o),
     742        success: function (e) {
     743          isEmpty(e) || (enter = '\n');
     744          var n =
     745            e && e.suggestions
     746              ? e.suggestions[0].matchedTextAyaModern + enter
     747              : '';
     748          n &&
     749            '\n' != n &&
     750            ('IFRAME' == element.tagName
     751              ? (element.contentDocument.execCommand('insertText', !1, n),
     752                spellCheckText(!0))
     753              : isTextArea
     754              ? document.execCommand('insertText', !1, n)
     755              : document.execCommand('insertHTML', !1, n)),
     756            $('qalam-tashkeel-blk,qalam-quraan-blk').removeClass('disabled'),
     757            $('qalam-tashkeel-blk').prop('disabled', !1),
     758            $('qalam-quraan-blk').prop('disabled', !1),
     759            $(t).find('div').removeClass('qalam-icons-loader'),
     760            (selectedText = null);
     761        },
     762        error: function () {},
     763      });
     764}
     765function getSelectedText(e) {
     766  if (e.getSelection && e.getSelection().toString())
     767    return e.getSelection().toString();
     768  if (document.selection) return document.selection.createRange().text;
     769  {
     770    let e = $(element).get(0);
     771    return e && e.value && e.selectionStart
     772      ? e.value.substring(e.selectionStart, e.selectionEnd)
     773      : '';
     774  }
     775}
     776function showTashkeelAndTawtheeq(e, t, n) {
     777  e
     778    ? ((t.style.display = 'flex'), (n.style.display = 'flex'))
     779    : ((t.style.display = 'none'), (n.style.display = 'none'));
     780}
     781
     782function hideTashkeelAndTawtheeq() {
     783  $('qalam-quraan-blk').css('display', 'none'),
     784    $('qalam-tashkeel-blk').css('display', 'none');
     785}
     786
     787function renderQalamMirror() {
     788  if (!$('html').find('qalam-mirror-shadow').length) {
     789    let e = document.createElement('qalam-mirror-shadow');
     790    $('html').append(e), (shadowRoot = e.attachShadow({ mode: 'open' }));
     791    let t = document.createElement('style');
     792    (t.textContent = MIRROR_SHADOW_STYLE),
     793      shadowRoot.appendChild(t),
     794      isTextArea &&
     795        ((qalamMirror = document.createElement('qalam-mirror')),
     796        $(qalamMirror).css('padding', $(element).css('padding')),
     797        languageChecker(),
     798        setFontSpecsForQalamMirror(),
     799        resetQalamMirror(),
     800        shadowRoot.append(qalamMirror));
     801  }
     802}
     803
     804function setFontSpecsForQalamMirror() {
     805  let e =
     806    $(element).css('font-weight') +
     807    ' ' +
     808    $(element).css('font-size') +
     809    ' / ' +
     810    $(element).css('line-height') +
     811    ' ' +
     812    $(element).css('font-family');
     813  $(qalamMirror).css('font', e),
     814    $(qalamMirror).css('letter-spacing', $(element).css('letter-spacing'));
     815}
     816
     817function reflectToQalamMirror() {
     818  isTextArea && element && (resetQalamMirror(), $(qalamMirror).html(getText()));
     819}
     820
     821function resetQalamMirror() {
     822  setFontSpecsForQalamMirror();
     823  let e = parseFloat($(element).css('padding-left').replace('px', '')),
     824    t = parseFloat($(element).css('padding-right').replace('px', '')),
     825    n = parseFloat($(element).css('border-left-width').replace('px', '')),
     826    a = parseFloat($(element).css('border-right-width').replace('px', '')),
     827    o = element.offsetWidth - element.clientWidth - n - a;
     828  (o -= withoutScrollDiff), $(qalamMirror).css('left', o);
     829  let l = e + t + o + n + a;
     830  $(qalamMirror).css('width', element.getBoundingClientRect().width - l),
     831    $(qalamMirror).css('height', 'auto');
     832}
     833
     834function resizeQalamExtension() {
     835  let e = parseFloat($(element).css('border-top-width').replace('px', '')),
     836    t = parseFloat($(element).css('border-bottom-width').replace('px', '')),
     837    n = parseFloat($(element).css('border-left-width').replace('px', '')),
     838    a = parseFloat($(element).css('border-right-width').replace('px', '')),
     839    o = element.getBoundingClientRect();
     840  $(qalamExtension).css('height', o.height - e - t),
     841    $(qalamExtension).css('top', $(element).position().top + e),
     842    $(qalamExtension).css('margin', $(element).css('margin')),
     843    $(qalamExtension).css('width', o.width - n - a),
     844    $(qalamExtension).css('left', $(element).position().left + n),
     845    $(qalamExtension).css('position', 'absolute'),
     846    $('.qalam-highlights-cont').css('height', element.scrollHeight);
     847}
     848
     849function getUrlWithoutParams() {
     850  return [location.protocol, '//', location.host, location.pathname].join('');
     851}
     852
     853function disableUrl() {
     854  if (isUrlDisabled()) return;
     855  let e = JSON.parse(localStorage.getItem('urlsDisabled')) || [];
     856  e.push(getUrlWithoutParams()),
     857    localStorage.setItem('urlsDisabled', JSON.stringify(e));
     858}
     859
     860function enableUrl() {
     861  let e = JSON.parse(localStorage.getItem('urlsDisabled')) || [];
     862  (urlDisabledIndex = e.findIndex((e) => e === getUrlWithoutParams())),
     863    urlDisabledIndex > -1 &&
     864      (e.splice(urlDisabledIndex, 1),
     865      localStorage.setItem('urlsDisabled', JSON.stringify(e)));
     866}
     867
     868function isUrlDisabled() {
     869  let e = JSON.parse(localStorage.getItem('urlsDisabled')) || [];
     870  return (
     871    (urlsDisabledIndex = e.find((e) => e === getUrlWithoutParams())),
     872    !!urlsDisabledIndex
     873  );
     874}
     875
     876function showDisablePrompt() {
     877  if (!$(shadowRoot).find('qalam-disable-prompt').length) {
     878    qalamDisablePrompt = document.createElement('qalam-disable-prompt');
     879    let e = document.createElement('p');
     880    (e.innerHTML = 'تعطيل عمل “قلم”؟'), (e.className = 'prompt-title');
     881    let t = document.createElement('button');
     882    (t.innerHTML = 'تعطيل عمل قلم'),
     883      (t.className = 'qalam-btn secondary-btn'),
     884      $(t).attr('type', 'button'),
     885      $(t).on('click', function (e) {
     886        disableUrl(),
     887          drawLabels(!1),
     888          $('.qalam-highlights-cont qalam-label').remove(),
     889          $(element).next().addClass('d-none'),
     890          $('qalam-button-cont .qalam-button .errors').css('display', 'none'),
     891          $('qalam-button-cont .qalam-button').css(
     892            'background-image',
     893            `url(${settings.assetsPath}/images/disabled.png)`
     894          );
     895      });
     896    let n = document.createElement('button');
     897    (n.innerHTML = 'إبقاء قلم فعّالاً'),
     898      (n.className = 'qalam-btn primary-btn'),
     899      $(n).attr('type', 'button'),
     900      $(n).on('click', function () {
     901        enableUrl(),
     902          removeDisablePrompt(),
     903          spellCheckText(!0),
     904          $(element).next().removeClass('d-none'),
     905          $('qalam-button-cont .qalam-button').css('background-image', 'none');
     906      }),
     907      qalamDisablePrompt.appendChild(e),
     908      qalamDisablePrompt.appendChild(t),
     909      qalamDisablePrompt.appendChild(n),
     910      $(shadowRoot).append(qalamDisablePrompt);
     911    let a = $('qalam-button-cont')[0].getBoundingClientRect(),
     912      o = qalamDisablePrompt.getBoundingClientRect(),
     913      l = [
     914        { top: a.top + a.height - o.height, left: a.left + a.width },
     915        {
     916          top: a.top,
     917          left: a.left + a.width,
     918        },
     919        { top: a.top + a.height - o.height, left: a.left - o.width },
     920        { top: a.top, left: a.left - o.width },
     921      ];
     922    for (
     923      let e = 0;
     924      e < l.length &&
     925      ($(qalamDisablePrompt).css('top', l[e].top),
     926      $(qalamDisablePrompt).css('left', l[e].left),
     927      !isElementInViewport(qalamDisablePrompt));
     928      e++
     929    );
     930    $('qalam-button-cont').addClass('active');
     931  }
     932}
     933
     934function removeDisablePrompt() {
     935  $('qalam-button-cont').removeClass('active'), $(qalamDisablePrompt).remove();
     936}
     937
     938function mobileCheck() {
     939  let e = !1;
     940  var t;
     941  return (
     942    (t = navigator.userAgent || navigator.vendor || window.opera),
     943    (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(
     944      t
     945    ) ||
     946      /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(
     947        t.substr(0, 4)
     948      )) &&
     949      (e = !0),
     950    e
     951  );
     952}
     953
     954function removeQalamSuggestions() {
     955  mobileCheck() ||
     956    ($(qalamSuggestions).remove(),
     957    $('qalam-extension .qalam-highlights-cont qalam-label').removeClass(
     958      'active'
     959    ));
     960}
     961
     962function removeNotification() {
     963  $('qalam-notification').css('right', '-450px'),
     964    setTimeout(function () {
     965      $('qalam-notification').remove();
     966    }, 750);
     967}
     968
     969function typedIn() {
     970  (typingStallCounter = 0),
     971    languageChecker(),
     972    secondsCounter ||
     973      (secondsCounter = setInterval(function () {
     974        typingStallCounter >= TYPING_STALL &&
     975          ('' != getText().trim()
     976            ? spellCheckText()
     977            : (clearButton(), clearLabels()),
     978          clearInterval(secondsCounter),
     979          (typingStallCounter = 0),
     980          (secondsCounter = null)),
     981          typingStallCounter++;
     982      }, 500));
     983}
     984
     985function clearButton() {
     986  $('qalam-button-cont .qalam-button .errors').css('display', 'none'),
     987    isUrlDisabled()
     988      ? $('qalam-button-cont .qalam-button').css(
     989          'background-image',
     990          `url(${settings.assetsPath}/images/disabled.png)`
     991        )
     992      : $('qalam-button-cont .qalam-button').css(
     993          'background-image',
     994          `url(${settings.assetsPath}/images/128.png)`
     995        ),
     996    $('qalam-button-cont .qalam-button').css(
     997      'background-color',
     998      BUTTON_NORMAL_COLOR
     999    ),
     1000    clearLabels();
     1001}
     1002
     1003function languageChecker() {
     1004  isTextArea &&
     1005    (/[\u0600-\u06FF]/.test(getText())
     1006      ? $(element).css('direction', 'rtl')
     1007      : $(element).css('direction', 'ltr'));
     1008  let e = $(element).css('direction'),
     1009    t = 'rtl' == e ? 'right' : 'left';
     1010  $(qalamMirror).css('direction', e),
     1011    $(qalamMirror).css('text-align', t),
     1012    $(element).css('text-align', t);
     1013}
     1014
     1015function spellCheckText(e) {
     1016  let t = ANIMATION_DELAY;
     1017  e
     1018    ? (t = 0)
     1019    : (isUrlDisabled()
     1020        ? $('.qalam-button').css(
     1021            'background-image',
     1022            `url(${settings.assetsPath}/images/disabled.png)`
     1023          )
     1024        : $('qalam-button-cont .qalam-button').css(
     1025            'background-image',
     1026            `url(${settings.assetsPath}/images/logo.gif)`
     1027          ),
     1028      $('qalam-button-cont .qalam-button').css(
     1029        'background-image',
     1030        `url(${settings.assetsPath}/images/logo.gif)`
     1031      ),
     1032      $('qalam-button-cont .qalam-button .errors').css('display', 'none'));
     1033  let n = getText();
     1034  isUrlDisabled() || callService(n, t, e);
     1035}
     1036
     1037function fetchErrors(e, t) {
     1038  (currentTextSuggestions = e), drawLabels(t);
     1039}
     1040
     1041function drawLabels(e) {
     1042  reflectToQalamMirror(),
     1043    resizeQalamExtension(),
     1044    $('.qalam-highlights-cont qalam-label').remove();
     1045  let t = currentTextSuggestions.length;
     1046  t > 0
     1047    ? ($.each(currentTextSuggestions, function () {
     1048        let t = this.original;
     1049        type = this.type;
     1050        let n = this.from,
     1051          a = this.to,
     1052          o = this.lang,
     1053          l = this.replacement,
     1054          i = this.lineColor,
     1055          r = this.labelColor,
     1056          s = getRangeSpecs(n, a);
     1057        s &&
     1058          ($.each(s, function () {
     1059            labelCreator(o, t, type, n, a, l, i, r, this, e);
     1060          }),
     1061          handleReposition());
     1062      }),
     1063      setErrorsTotal(t))
     1064    : clearButton();
     1065}
     1066
     1067function detectBrowser() {
     1068  return -1 !=
     1069    (navigator.userAgent.indexOf('Opera') || navigator.userAgent.indexOf('OPR'))
     1070    ? 'Opera'
     1071    : -1 != navigator.userAgent.indexOf('Chrome')
     1072    ? 'Chrome'
     1073    : -1 != navigator.userAgent.indexOf('Safari')
     1074    ? 'Safari'
     1075    : -1 != navigator.userAgent.indexOf('Firefox')
     1076    ? 'Firefox'
     1077    : -1 != navigator.userAgent.indexOf('MSIE') || 1 == !!document.documentMode
     1078    ? 'IE'
     1079    : 'Unknown';
     1080}
     1081
     1082function detectBrowser() {
     1083  return -1 !=
     1084    (navigator.userAgent.indexOf('Opera') || navigator.userAgent.indexOf('OPR'))
     1085    ? 'Opera'
     1086    : -1 != navigator.userAgent.indexOf('Chrome')
     1087    ? 'Chrome'
     1088    : -1 != navigator.userAgent.indexOf('Safari')
     1089    ? 'Safari'
     1090    : -1 != navigator.userAgent.indexOf('Firefox')
     1091    ? 'Firefox'
     1092    : -1 != navigator.userAgent.indexOf('MSIE') || 1 == !!document.documentMode
     1093    ? 'IE'
     1094    : 'Unknown';
     1095}
     1096function labelCreator(e, t, n, a, o, l, i, r, s, u) {
     1097  let c = document.createElement('qalam-label');
     1098  (s.width = s.right - s.left),
     1099    (s.height = s.bottom - s.top),
     1100    $(c).css('width', s.width),
     1101    $(c).css('height', 1.05 * s.height),
     1102    'Firefox' == detectBrowser()
     1103      ? ($(c).css('top', s.top + 6 - 0.025 * s.height),
     1104        $(c).css('left', s.left + 12))
     1105      : ($(c).css('top', s.top - 0.025 * s.height), $(c).css('left', s.left)),
     1106    $(c).css('background-color', r),
     1107    $(c).on('mouseenter', function (e) {
     1108      renderQalamSuggestions(e, t, n), $(c).addClass('active');
     1109    });
     1110  let m = JSON.stringify(l);
     1111  $(c).attr('data-suggestions', m),
     1112    $(c).attr('data-start-index', a),
     1113    $(c).attr('data-end-index', o),
     1114    $(c).attr('data-lang', e);
     1115  let d = document.createElement('label-border');
     1116  $(d).css('left', s.left),
     1117    $(d).css('width', s.width),
     1118    $(d).css('background-color', i),
     1119    c.appendChild(d),
     1120    qalamHighlightsCont.appendChild(c),
     1121    u
     1122      ? $(d).css('left', '0')
     1123      : setTimeout(function () {
     1124          $(d).css('left', '0');
     1125        }, 10);
     1126}
     1127function getRangeInfo(e, t) {
     1128  let n = {};
     1129  if ('IFRAME' == element.tagName) {
     1130    let a = [element.contentDocument.activeElement],
     1131      o = 0;
     1132    for (; a.length; ) {
     1133      let l = a.pop();
     1134      if (3 == l.nodeType) {
     1135        for (let a = 0; a < l.textContent.length; a++)
     1136          e <= o + a &&
     1137            o + a <= t &&
     1138            (n[o + a] = {
     1139              node: l,
     1140              index: a,
     1141            });
     1142        if ((o += l.textContent.length) > t) break;
     1143      } else {
     1144        let displayStyle =
     1145          typeof currentNode == Element
     1146            ? window.getComputedStyle(l, null).display
     1147            : '';
     1148        if (STYLES_HIDDEN.has(displayStyle)) continue;
     1149        a.push(...Array.from(l.childNodes).reverse());
     1150      }
    1671151    }
    168     if (isTextArea) return editorId = element.getAttribute("data-qid"), $(element).val() || $(element).text();
    169     let e = "", t = [{element: element, parent: null}];
    170     for (; t.length;) {
    171         let n = t.pop(), a = n.parent;
    172         if ("BR" == (n = n.element).tagName) e += `\n${DUMMY_STRING}\n`; else if (3 == n.nodeType) {
    173             let t = n.textContent;
    174             STYLES_WRAP.has(window.getComputedStyle(a, null).whiteSpace) || (t = t.replace(/\n/g, " ")), e += t
    175         } else {
    176             let e = window.getComputedStyle(n, null).display;
    177             if (STYLES_HIDDEN.has(e)) continue;
    178             STYLES_BLOCKING.has(e) && t.push({element: document.createElement("br"), parent: n});
    179             let a = [];
    180             Array.from(n.childNodes).reverse().forEach(e => {
    181                 a.push({element: e, parent: n})
    182             }), t.push(...a), STYLES_BLOCKING.has(e) && t.push({element: document.createElement("br"), parent: n})
    183         }
     1152    return n;
     1153  }
     1154  if (isTextArea) {
     1155    let a = qalamMirror.childNodes[0];
     1156    for (let o = e; o <= t; o++) n[o] = { node: a, index: o };
     1157    return n;
     1158  }
     1159  let a = [element],
     1160    o = 0;
     1161  for (; a.length; ) {
     1162    let l = a.pop();
     1163    if (3 == l.nodeType) {
     1164      for (let a = 0; a < l.textContent.length; a++)
     1165        e <= o + a && o + a <= t && (n[o + a] = { node: l, index: a });
     1166      if ((o += l.textContent.length) > t) break;
     1167    } else {
     1168      let displayStyle =
     1169        typeof l == Element ? window.getComputedStyle(l, null).display : '';
     1170      if (STYLES_HIDDEN.has(displayStyle)) continue;
     1171      a.push(...Array.from(l.childNodes).reverse());
    1841172    }
    185     return editorId = element.getAttribute("data-qid"), e
    186 }
    187 
    188 function listenerTriggered(e) {
    189     if (assignEditorIds(), element != e || "IFRAME" == e.tagName) {
    190         if (unmountQalamComponent(), isTextArea = "TEXTAREA" == (element = e).tagName || "IFRAME" == element.tagName) {
    191             let e = getText();
    192             $(element).val("");
    193             let t = parseFloat($(element).css("border-left-width").replace("px", "")),
    194                 n = parseFloat($(element).css("border-right-width").replace("px", ""));
    195             withoutScrollDiff = element.offsetWidth - element.clientWidth - t - n, $(element).val(e)
    196         }
    197         if ($(element).attr("spellcheck", !1), elementParent = element.parentNode, "0px" == $(elementParent).css("width") && "0px" == $(elementParent).css("height") && $(elementParent).css("position", "unset"), renderQalamMirror(), renderQalamComponent(), "IFRAME" != element.tagName) $(element).on("scroll", function () {
    198             handleReposition(!1)
    199         }), $(window).on("scroll", function () {
    200             handleReposition(!1)
    201         }), $(window).on("resize", function () {
    202             handleReposition(!0)
    203         }); else {
    204             let e, t = $(element).contents();
    205             $(t).on("scroll", function () {
    206                 !function () {
    207                     let e = $("qalam-extension .qalam-highlights-cont qalam-label");
    208                     for (let t = 0; t < e.length; t++) {
    209                         const n = e[t];
    210                         n.style.display = "none"
    211                     }
    212                 }(), clearTimeout(e), e = setTimeout(function () {
    213                     handleReposition(!0)
    214                 }, 200)
    215             })
    216         }
    217         new ResizeObserver(function () {
    218             handleReposition(!0)
    219         }).observe(element), "" != getText().trim() && (languageChecker(), spellCheckText())
     1173  }
     1174  return n;
     1175}
     1176
     1177function getRangeSpecs(e, t) {
     1178  let n = getRangeInfo(e, t),
     1179    a = document.createRange(),
     1180    o = [],
     1181    l = 0,
     1182    i = 0,
     1183    s = element.getBoundingClientRect();
     1184  for (let r = e; r <= t; r++) {
     1185    try {
     1186      a.setStart(n[r].node, n[r].index), a.setEnd(n[r].node, n[r].index + 1);
     1187    } catch (e) {}
     1188    let e = a.getBoundingClientRect();
     1189    if (0 == e.width || 0 == e.height) continue;
     1190    let t = e.top - !isTextArea * (s.top - $(element).scrollTop()),
     1191      c = e.bottom - !isTextArea * (s.top - $(element).scrollTop()),
     1192      m = e.left - !isTextArea * s.left,
     1193      d = e.right - !isTextArea * s.left,
     1194      u = Math.min(c - t, i - l),
     1195      g = Math.min(i, c) - Math.max(l, t);
     1196    0 == o.length || g / u < INTERSECTION_THRESHOLD
     1197      ? o.push({
     1198          right: d,
     1199          left: m,
     1200          bottom: c,
     1201          top: t,
     1202        })
     1203      : ((o[o.length - 1].left = Math.min(o[o.length - 1].left, m)),
     1204        (o[o.length - 1].right = Math.max(o[o.length - 1].right, d)),
     1205        (o[o.length - 1].top = Math.min(o[o.length - 1].top, t)),
     1206        (o[o.length - 1].bottom = Math.max(o[o.length - 1].bottom, c))),
     1207      (l = t),
     1208      (i = c);
     1209  }
     1210  return o;
     1211}
     1212
     1213function clearLabels() {
     1214  (currentTextSuggestions = []),
     1215    $('.qalam-highlights-cont qalam-label').remove();
     1216}
     1217
     1218function setErrorsTotal(e) {
     1219  $('qalam-button-cont .qalam-button').css(
     1220    'background-color',
     1221    BUTTON_ERROR_COLOR
     1222  ),
     1223    $('qalam-button-cont .qalam-button').css('background-image', 'unset'),
     1224    $('qalam-button-cont .qalam-button .errors').css('display', 'block'),
     1225    $('qalam-button-cont .qalam-button .errors').text(e),
     1226    e > 99
     1227      ? $('qalam-button-cont .qalam-button .errors').css('font-size', '12px')
     1228      : $('qalam-button-cont .qalam-button .errors').css('font-size', '15px');
     1229}
     1230
     1231function decreaseTotalErrorsCount() {
     1232  let e = parseInt($('qalam-button-cont .qalam-button .errors').text());
     1233  e > 1
     1234    ? $('qalam-button-cont .qalam-button .errors').text(e - 1)
     1235    : clearButton();
     1236}
     1237
     1238function renderQalamSuggestions(e, t, n) {
     1239  removeQalamSuggestions();
     1240  let a = $(e.target).closest('qalam-label'),
     1241    o = JSON.parse($(a).attr('data-suggestions')),
     1242    l = $(a).attr('data-start-index'),
     1243    i = $(a).attr('data-end-index'),
     1244    r = $(a).attr('data-lang');
     1245  if (!$(shadowRoot).find('qalam-suggestions').length) {
     1246    qalamSuggestions = document.createElement('qalam-suggestions');
     1247    let e = document.createElement('suggestions-cont');
     1248    $.each(o, function () {
     1249      let t = this,
     1250        n = document.createElement('suggestion-item');
     1251      $(n).on('click', function () {
     1252        let e = $(element).scrollTop(),
     1253          n = $(window).scrollTop();
     1254        $(`qalam-label[data-start-index="${l}"]`).remove(),
     1255          removeQalamSuggestions(),
     1256          decreaseTotalErrorsCount(),
     1257          replaceOriginalText(t, l, i),
     1258          spellCheckText(!0),
     1259          $(element).scrollTop(e),
     1260          $(window).scrollTop(n),
     1261          mobileCheck() &&
     1262            ($(qalamSuggestions).remove(),
     1263            $('qalam-extension .qalam-highlights-cont qalam-label').removeClass(
     1264              'active'
     1265            ));
     1266      });
     1267      let a = document.createElement('suggestion-text');
     1268      'en' === r && ((a.style.direction = 'ltr'), (a.style.textAlign = 'left')),
     1269        '' === t.trim()
     1270          ? (a.innerHTML = '<i style="font-size:12px;"><مسافة زائدة><i>')
     1271          : (a.innerHTML = t),
     1272        n.appendChild(a),
     1273        e.appendChild(n);
     1274    });
     1275    let s = document.createElement('div');
     1276    (s.className = 'ignore-cont'),
     1277      $(s).on('click', function () {
     1278        wordGetter(l, i);
     1279        onDismissCallback([t], getContext(t, l, i)),
     1280          $(`qalam-label[data-start-index='${l}']`).remove(),
     1281          removeQalamSuggestions(),
     1282          spellCheckText(!0);
     1283      });
     1284    let u = document.createElement('img');
     1285    (u.className = 'ignore-icon'),
     1286      (u.src = `${settings.assetsPath}/images/ignore.svg`);
     1287    let c,
     1288      m = document.createElement('p');
     1289    if (
     1290      ((m.className = 'ignore-text'),
     1291      (m.innerHTML = 'تجاهل هذا التصحيح'),
     1292      s.appendChild(u),
     1293      s.appendChild(m),
     1294      isWriterAllowedToAddToDic && 'terms' != n)
     1295    ) {
     1296      (c = document.createElement('div')),
     1297        (c.className = 'add-to-dic-cont'),
     1298        $(c).on('click', function () {
     1299          onAddToDictionaryCallback([t], getContext(t, l, i)),
     1300            $(`qalam-label[data-start-index="${l}"]`).remove(),
     1301            removeQalamSuggestions(),
     1302            spellCheckText(!0);
     1303        });
     1304      let e = document.createElement('img');
     1305      (e.className = 'add-to-dic-icon'),
     1306        (e.src = `${settings.assetsPath}/images/add.svg`);
     1307      let n = document.createElement('p');
     1308      (n.className = 'add-to-dic-text'),
     1309        (n.innerHTML = 'إضافة إلى القاموس'),
     1310        c.appendChild(e),
     1311        c.appendChild(n);
    2201312    }
    221 }
    222 
    223 function handleReposition(e) {
    224     removeQalamSuggestions(), removeDisablePrompt(), repositionQalamButton(), $(qalamExtensionCont).scrollTop($(element).scrollTop()), $(qalamExtensionCont).scrollLeft($(element).scrollLeft()), e && SCServiceActive && drawLabels(!0)
    225 }
    226 
    227 function repositionQalamButton() {
    228     let e = $("qalam-button-cont");
    229     if (e.css("position", "absolute"), (qalamExtensionCont ? qalamExtensionCont.getBoundingClientRect() : "").height > 30) {
     1313    let d = document.createElement('img');
     1314    if (
     1315      ((d.className = 'wrong-suggestion-more-icon'),
     1316      (d.src = `${settings.assetsPath}/images/more.png`),
     1317      (d.width = '15'),
     1318      (d.height = '15'),
     1319      $(d).on('click', function (e) {
     1320        e.preventDefault(),
     1321          e.stopPropagation(),
     1322          (wrongSuggestionItem = document.createElement('div')),
     1323          (wrongSuggestionItem.className = 'wrong-suggestion-cont');
     1324        let n = document.createElement('img');
     1325        (n.className = 'wrong-suggestion-icon'),
     1326          (n.src = `${settings.assetsPath}/images/wrong-suggestion.svg`);
     1327        let a = document.createElement('p');
     1328        (a.className = 'wrong-suggestion-text'),
     1329          (a.innerHTML = 'هذا اقتراح خاطئ'),
     1330          wrongSuggestionItem.appendChild(n),
     1331          wrongSuggestionItem.appendChild(a),
     1332          $(wrongSuggestionItem).on('click', function () {
     1333            onWrongSuggestionCallback(t, getContext(t, l, i)),
     1334              $(`qalam-label[data-start-index="${l}"]`).remove(),
     1335              removeQalamSuggestions();
     1336          }),
     1337          s.appendChild(wrongSuggestionItem);
     1338      }),
     1339      qalamSuggestions.appendChild(e),
     1340      qalamSuggestions.appendChild(s),
     1341      'terms' != n && s.appendChild(d),
     1342      isWriterAllowedToAddToDic &&
     1343        'terms' != n &&
     1344        qalamSuggestions.appendChild(c),
     1345      $(shadowRoot).append(qalamSuggestions),
     1346      o.length > 0)
     1347    ) {
     1348      (labelBoundingBox = a[0].getBoundingClientRect()),
     1349        $(qalamSuggestions).css('display', 'block'),
     1350        (suggestionBoundingBox = qalamSuggestions.getBoundingClientRect());
     1351      let e = [
     1352        {
     1353          top: labelBoundingBox.top + labelBoundingBox.height,
     1354          left:
     1355            labelBoundingBox.left +
     1356            labelBoundingBox.width -
     1357            suggestionBoundingBox.width,
     1358        },
     1359        {
     1360          top: labelBoundingBox.top + labelBoundingBox.height,
     1361          left: labelBoundingBox.left,
     1362        },
     1363        {
     1364          top: labelBoundingBox.top - suggestionBoundingBox.height,
     1365          left:
     1366            labelBoundingBox.left +
     1367            labelBoundingBox.width -
     1368            suggestionBoundingBox.width,
     1369        },
     1370        {
     1371          top: labelBoundingBox.top - suggestionBoundingBox.height,
     1372          left: labelBoundingBox.left,
     1373        },
     1374      ];
     1375      for (
    2301376        let t = 0;
    231         if ("rtl" == $(element).css("direction")) {
    232             let e = parseFloat($(element).css("border-left-width").replace("px", "")),
    233                 n = parseFloat($(element).css("border-right-width").replace("px", ""));
    234             t = element.offsetWidth - element.clientWidth - e - n
    235         }
    236         e.css("left", 6 + t), e.css("bottom", 6), e.css("padding", 4)
    237     } else e.css("left", 6), e.css("bottom", 6), e.css("padding", 0)
    238 }
    239 
    240 function renderQalamComponent() {
    241     if (drawLabels(!0), !$(elementParent).find("qalam-container").length) {
    242         let e = document.createElement("qalam-container");
    243         $(elementParent).append(e);
    244         let t = document.createElement("qalam-wrapper");
    245         qalamExtension = document.createElement("qalam-extension"), qalamExtensionCont = document.createElement("qalam-extension-cont"), (qalamHighlightsCont = document.createElement("div")).className = "qalam-highlights-cont";
    246         let n = document.createElement("qalam-button-cont"), a = document.createElement("div");
    247         a.className = "qalam-button";
    248         let o = document.createElement("p");
    249             o.className = "errors", $(a).css("backgroundImage", `url(${settings.assetsPath}/images/128.png)`), isUrlDisabled() ? $(a).css("background-image", "url(../images/disabled.png)") : $(a).css("backgroundImage", `url(${settings.assetsPath}/images/128.png)`);
    250         let l = document.createElement("div");
    251         l.className = "separator";
    252         let i = document.createElement("img");
    253         i.className = "disable-icon", i.src = `${settings.assetsPath}/images/disable.svg`, i.title = "تعطيل عمل قلم", $(i).on("click", function (e) {
    254             showDisablePrompt()
    255         }), resizeQalamExtension();
    256         let s = document.createElement("qalam-tashkeel-blk");
    257         s.className = "qalam-tashkeel", s.style.display = "none";
    258         let r = document.createElement("qalam-quraan-blk");
    259         r.className = "qalam-quraan", r.style.display = "none";
    260         let c = document.createElement("img");
    261         c.className = "qalam-quraan-icon", c.src = `${settings.assetsPath}/images/quran_3.svg`;
    262         let m = document.createElement("img");
    263         if (m.className = "qalam-tashkeel-icon", m.src = `${settings.assetsPath}/images/tashkeel.svg`, qalamExtensionCont.style.width = "100%", qalamExtensionCont.style.height = "100%", a.appendChild(o), n.appendChild(a), n.appendChild(l), n.appendChild(i), qalamExtensionCont.appendChild(qalamHighlightsCont), qalamExtension.appendChild(qalamExtensionCont), isTashkeelActive && (s.appendChild(m), qalamExtension.appendChild(s)), isTawtheeqActive && (r.appendChild(c), qalamExtension.appendChild(r)), "IFRAME" == element.tagName) {
    264             let e = element.contentDocument && element.contentDocument.body ? element.contentDocument.body.parentElement.querySelector("[contenteditable]") || element.contentDocument.body.parentElement : null,
    265                 t = element.contentWindow || element.contentDocument;
    266             $(e).mouseup(function () {
    267                 showTashkeelAndTawtheeq(selectedText = getSelectedText(t), s, r)
    268             })
    269         } else $(element).mouseup(function () {
    270             showTashkeelAndTawtheeq(selectedText = getSelectedText(window), s, r)
     1377        t < e.length &&
     1378        ($(qalamSuggestions).css('top', e[t].top),
     1379        $(qalamSuggestions).css('left', e[t].left),
     1380        !isElementInViewport(qalamSuggestions));
     1381        t++
     1382      );
     1383    }
     1384  }
     1385  resizeQalamExtension();
     1386}
     1387function onAddToDictionaryCallback(e, t) {
     1388  $.ajax({
     1389    dataType: 'json',
     1390    url: baseLink + 'dictionaries/words',
     1391    type: 'POST',
     1392    headers: {
     1393      'Content-Type': 'application/json',
     1394      Authorization: `${clientId}`,
     1395      'Qalam-Agent': qalamAgent,
     1396    },
     1397    data: JSON.stringify({ words: e, context: t }),
     1398    success: function (e) {},
     1399    error: function () {},
     1400  });
     1401}
     1402function onWrongSuggestionCallback(e, t) {
     1403  $.ajax({
     1404    dataType: 'json',
     1405    url: `${baseLink}documents/${uuidV3Hash}/wrong/suggestions`,
     1406    type: 'POST',
     1407    headers: {
     1408      'Content-Type': 'application/json',
     1409      Authorization: `${clientId}`,
     1410      'Qalam-Agent': qalamAgent,
     1411    },
     1412    data: JSON.stringify({ words: e, context: t }),
     1413    success: function (e) {},
     1414    error: function () {},
     1415  });
     1416}
     1417function onDismissCallback(e, t) {
     1418  $.ajax({
     1419    dataType: 'json',
     1420    url: baseLink + 'documents/' + uuidV3Hash + '/dismissals',
     1421    method: 'POST',
     1422    timeout: 0,
     1423    headers: {
     1424      'Content-Type': 'application/json',
     1425      Authorization: `${clientId}`,
     1426      'Qalam-Agent': qalamAgent,
     1427    },
     1428    data: JSON.stringify({ words: e, context: t }),
     1429    success: function (e) {},
     1430    error: function () {},
     1431  });
     1432}
     1433
     1434function isElementInViewport(e) {
     1435  let t = e.getBoundingClientRect();
     1436  return (
     1437    t.top >= 0 &&
     1438    t.left >= 0 &&
     1439    t.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
     1440    t.right <= (window.innerWidth || document.documentElement.clientWidth)
     1441  );
     1442}
     1443
     1444function wordGetter(e, t) {
     1445  return $(element)
     1446    .val()
     1447    .substr(e, parseInt(t) - e + 1);
     1448}
     1449
     1450function replaceOriginalText(e, t, n) {
     1451  let a = getText().length;
     1452  if (isTextArea)
     1453    if ('IFRAME' == element.tagName) {
     1454      element.contentWindow.focus();
     1455      let e = getRangeInfo(t, n);
     1456      (range = element.contentDocument.createRange()),
     1457        range.setStart(e[t].node, e[t].index),
     1458        range.setEnd(e[n].node, e[n].index + 1),
     1459        (sel = element.contentDocument.getSelection()),
     1460        sel.removeAllRanges(),
     1461        sel.addRange(range);
     1462    } else
     1463      $(element).trigger('focus'),
     1464        ($(element)[0].selectionStart = t),
     1465        ($(element)[0].selectionEnd = parseInt(n) + 1);
     1466  else {
     1467    $(element).trigger('focus');
     1468    let e = getRangeInfo(t, n);
     1469    (range = document.createRange()),
     1470      range.setStart(e[t].node, e[t].index),
     1471      range.setEnd(e[n].node, e[n].index + 1),
     1472      (sel = window.getSelection()),
     1473      sel.removeAllRanges(),
     1474      sel.addRange(range);
     1475  }
     1476  (triggerFlag = !1),
     1477    'IFRAME' == element.tagName
     1478      ? element.contentDocument.execCommand('insertText', !1, e)
     1479      : document.execCommand('insertText', !1, e),
     1480    setTimeout(function () {
     1481      triggerFlag = !0;
     1482    }, 5);
     1483  let o = a - getText().length,
     1484    l = -1;
     1485  $.each(currentTextSuggestions, function (e, n) {
     1486    n.from == t
     1487      ? (l = e)
     1488      : n.from > t &&
     1489        ((currentTextSuggestions[e].from -= o),
     1490        (currentTextSuggestions[e].to -= o));
     1491  }),
     1492    -1 != l && currentTextSuggestions.splice(l, 1),
     1493    drawLabels(!0);
     1494}
     1495
     1496function unmountQalamComponent() {
     1497  $('qalam-container').remove(),
     1498    $('qalam-mirror-shadow').remove(),
     1499    null != qalamMirror && $(qalamMirror).remove(),
     1500    removeQalamSuggestions(),
     1501    (ignoredSet = new Set()),
     1502    (currentTextSuggestions = []);
     1503}
     1504
     1505function resetGlobalVariables() {
     1506  (shadowRoot = null),
     1507    (qalamDisablePrompt = null),
     1508    (isTextArea = null),
     1509    (triggerFlag = !0),
     1510    (SCServiceActive = null),
     1511    (qalamExtension = null),
     1512    (qalamExtensionCont = null),
     1513    (qalamHighlightsCont = null),
     1514    (qalamMirror = null),
     1515    removeDisablePrompt(),
     1516    removeQalamSuggestions(),
     1517    (qalamSuggestions = null),
     1518    $(element).off(),
     1519    (element = null),
     1520    (withoutScrollDiff = 0),
     1521    (elementParent = null),
     1522    (typingStallCounter = 0),
     1523    (secondsCounter = null),
     1524    (resizeHoldCounter = null),
     1525    (currentTextSuggestions = []),
     1526    clearInterval(secondsCounter),
     1527    clearInterval(resizeHoldCounter);
     1528}
     1529
     1530function turnOnSC() {
     1531  (SCServiceActive = !0), init();
     1532}
     1533
     1534function turnOffSC() {
     1535  (SCServiceActive = !1), unmountQalamComponent(), resetGlobalVariables();
     1536}
     1537
     1538function setCookie() {
     1539  let e = generateId(8);
     1540  document.cookie = 'qalam_user_id=' + e + '; path=/';
     1541}
     1542
     1543function getCookie(e) {
     1544  for (
     1545    var t = e + '=', n = document.cookie.split(';'), a = 0;
     1546    a < n.length;
     1547    a++
     1548  ) {
     1549    for (var o = n[a]; ' ' == o.charAt(0); ) o = o.substring(1, o.length);
     1550    if (0 == o.indexOf(t)) return o.substring(t.length, o.length);
     1551  }
     1552  return null;
     1553}
     1554
     1555function generateId(e) {
     1556  for (
     1557    var t = '',
     1558      n = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
     1559      a = n.length,
     1560      o = 0;
     1561    o < e;
     1562    o++
     1563  )
     1564    t += n.charAt(Math.floor(Math.random() * a));
     1565  return t;
     1566}
     1567
     1568function getUuid() {
     1569  let elementQalamId = $(element).attr('qalam-id');
     1570  if (elementQalamId) {
     1571    uuidV3Hash = uuidv5(elementQalamId, clientId);
     1572  } else if (documentId)
     1573    uuidV3Hash = uuid.v5(documentId + ':' + editorId, clientId);
     1574  else if (mode == PATH_MODE) {
     1575    var a = extractPathParamAt(modeValue);
     1576    a || (documentId = a = uuid.v4()),
     1577      (uuidV3Hash = uuid.v5(a + ':' + editorId, clientId));
     1578  } else if (mode == QUERY_MODE) {
     1579    var o = extractQueryParam(modeValue);
     1580    o || (documentId = o = uuid.v4()),
     1581      (uuidV3Hash = uuid.v5(o + ':' + editorId, clientId));
     1582  } else
     1583    (documentId = uuid.v4()),
     1584      (uuidV3Hash = uuid.v5(documentId + ':' + editorId, clientId));
     1585
     1586  return uuidV3Hash;
     1587}
     1588
     1589function callService(e, t, n) {
     1590  uuidV3Hash = getUuid();
     1591  var l = {
     1592    url: API_LINK,
     1593    method: 'POST',
     1594    timeout: 0,
     1595    headers: {
     1596      'Content-Type': 'application/json',
     1597      Authorization: `${clientId}`,
     1598      'Qalam-Agent': qalamAgent,
     1599    },
     1600    success: function () {},
     1601    error: function (e, t, n) {
     1602      e.status;
     1603    },
     1604    data: JSON.stringify({ text: e, docId: uuidV3Hash }),
     1605  };
     1606  setTimeout(function () {
     1607    $.ajax(l).done(function (t) {
     1608      let a = [];
     1609      extend(
     1610        a,
     1611        extractRest(
     1612          t.termSuggestions,
     1613          TERM_LINE_COLOR,
     1614          TERM_LABEL_COLOR,
     1615          'terms'
     1616        )
     1617      ),
     1618        extend(
     1619          a,
     1620          extractRest(
     1621            t.tafqeetSuggestions,
     1622            TAFQEET_LINE_COLOR,
     1623            TAFQEET_LABEL_COLOR,
     1624            'tafqeet'
     1625          )
     1626        ),
     1627        extend(
     1628          a,
     1629          extractResponse(
     1630            t.grammarResponse,
     1631            GRAMMAR_LINE_COLOR,
     1632            GRAMMAR_LABEL_COLOR,
     1633            'grammar'
     1634          )
     1635        ),
     1636        extend(
     1637          a,
     1638          extractResponse(
     1639            t.phrasingResponse,
     1640            PHRASING_LINE_COLOR,
     1641            PHRASING_LABEL_COLOR,
     1642            'phrasing'
     1643          )
     1644        ),
     1645        extend(
     1646          a,
     1647          extractResponse(
     1648            t.otherSuggestions,
     1649            OS_LINE_COLOR,
     1650            OS_LABEL_COLOR,
     1651            'otherSuggestions'
     1652          )
     1653        ),
     1654        extend(
     1655          a,
     1656          extractResponse(
     1657            t.spellCheckResponse,
     1658            SC_LINE_COLOR,
     1659            SC_LABEL_COLOR,
     1660            'spellChecker'
     1661          )
     1662        ),
     1663        $.each(t.numDate, function () {
     1664          extend(a, extractRest(this, NUM_LINE_COLOR, NUM_LABEL_COLOR));
     1665        }),
     1666        $.each(t.tashkeel, function () {
     1667          extend(a, extractRest(this, T_LINE_COLOR, T_LABEL_COLOR));
     1668        }),
     1669        $.each(t.punctuation, function () {
     1670          extend(a, extractRest(this, PUNC_LINE_COLOR, PUNC_LABEL_COLOR));
    2711671        });
    272         $(r).on("click", function (e) {
    273             controlSelection(e)
    274         }), $(s).on("click", function (e) {
    275             controlSelection(e)
    276         }), $(element).on(isTextArea ? "input propertychange" : "DOMSubtreeModified", function () {
    277             triggerFlag && ("IFRAME" != element.tagName && $("qalam-tashkeel-blk") && $("qalam-quraan-blk"), clearButton(), clearLabels(), resizeQalamExtension(), typedIn())
    278         }), t.append(qalamExtension), qalamExtension.appendChild(n), e.append(t)
    279     }
    280 }
    281 
    282 function getConfig() {
    283     $.ajax({
    284         dataType: "json", url: baseLink + "test/config", type: "GET", beforeSend: function (e) {
    285             e.setRequestHeader("Authorization", `${clientId}`), e.setRequestHeader("Content-Type", "application/json")
    286         }, success: function (e) {
    287             let t = e.categories.filter(e => "tashkeel" == e.id), n = e.categories.filter(e => "tawtheeq" == e.id);
    288             "true" == t[0].value || $(".qalam-tashkeel").remove(), isTashkeelActive = "true" == t[0].value, isTawtheeqActive = "true" == n[0].value
    289         }, error: function () {
    290         }
    291     })
    292 }
    293 
    294 function getTermsConfig() {
    295     $.ajax({
    296         dataType: "json",
    297         url: baseLink + "dictionaries/words?fields=config",
    298         type: "GET",
    299         beforeSend: function (e) {
    300             e.setRequestHeader("Authorization", `${clientId}`), e.setRequestHeader("Content-Type", "application/json")
    301         },
    302         success: function (e) {
    303             isWriterAllowedToAddToDic = "true" == e.dictionaryConfig.writerAllowedToAddDictionary
    304         },
    305         error: function () {
    306         }
    307     })
    308 }
    309 
    310 function controlSelection(e) {
    311     hideTashkeelAndTawtheeq();
    312     let t = "";
    313     t = "qalam-tashkeel" == e.currentTarget.classList.value ? "SC_service_tashkeel" : "SC_service_tawtheeq";
    314     let n = uuid.v5(documentId, clientId), a = {text: selectedText, docId: n};
    315     "SC_service_tashkeel" == t && $.ajax({
    316         dataType: "json",
    317         url: baseLink + "qalam/tashkeel",
    318         type: "POST",
    319         beforeSend: function (e) {
    320             e.setRequestHeader("Authorization", `${clientId}`), e.setRequestHeader("Content-Type", "application/json")
    321         },
    322         data: JSON.stringify(a),
    323         success: function (e) {
    324             var t = e.text;
    325             "IFRAME" == element.tagName ? (element.contentDocument.execCommand("insertText", !1, t), spellCheckText(!0)) : document.execCommand("insertHTML", !1, t), selectedText = null
    326         },
    327         error: function () {
    328         }
    329     }), "SC_service_tawtheeq" == t && $.ajax({
    330         dataType: "json",
    331         url: baseLink + "quran/tawtheeq",
    332         type: "POST",
    333         beforeSend: function (e) {
    334             e.setRequestHeader("Authorization", `${clientId}`), e.setRequestHeader("Content-Type", "application/json")
    335         },
    336         data: JSON.stringify(a),
    337         success: function (e) {
    338             isEmpty(e) || (enter = "\n");
    339             var t = e.suggestions[0].matchedTextAyaModern + enter;
    340             "IFRAME" == element.tagName ? (element.contentDocument.execCommand("insertText", !1, t), spellCheckText(!0)) : document.execCommand("insertText", !1, t), selectedText = null
    341         },
    342         error: function () {
    343         }
    344     })
    345 }
    346 
    347 function getSelectedText(e) {
    348     return e.getSelection ? e.getSelection().toString() : document.selection ? document.selection.createRange().text : ""
    349 }
    350 
    351 function showTashkeelAndTawtheeq(e, t, n) {
    352     e ? (t.style.display = "flex", n.style.display = "flex") : (t.style.display = "none", n.style.display = "none")
    353 }
    354 
    355 function hideTashkeelAndTawtheeq() {
    356     $("qalam-quraan-blk").css("display", "none"), $("qalam-tashkeel-blk").css("display", "none")
    357 }
    358 
    359 function renderQalamMirror() {
    360     if (!$("html").find("qalam-mirror-shadow").length) {
    361         let e = document.createElement("qalam-mirror-shadow");
    362         $("html").append(e), shadowRoot = e.attachShadow({mode: "open"});
    363         let t = document.createElement("style");
    364         t.textContent = MIRROR_SHADOW_STYLE, shadowRoot.appendChild(t), isTextArea && (qalamMirror = document.createElement("qalam-mirror"), $(qalamMirror).css("padding", $(element).css("padding")), languageChecker(), setFontSpecsForQalamMirror(), resetQalamMirror(), shadowRoot.append(qalamMirror))
    365     }
    366 }
    367 
    368 function setFontSpecsForQalamMirror() {
    369     let e = $(element).css("font-weight") + " " + $(element).css("font-size") + " / " + $(element).css("line-height") + " " + $(element).css("font-family");
    370     $(qalamMirror).css("font", e), $(qalamMirror).css("letter-spacing", $(element).css("letter-spacing"))
    371 }
    372 
    373 function reflectToQalamMirror() {
    374     isTextArea && element && (resetQalamMirror(), $(qalamMirror).html(getText()))
    375 }
    376 
    377 function resetQalamMirror() {
    378     setFontSpecsForQalamMirror();
    379     let e = parseFloat($(element).css("padding-left").replace("px", "")),
    380         t = parseFloat($(element).css("padding-right").replace("px", "")),
    381         n = parseFloat($(element).css("border-left-width").replace("px", "")),
    382         a = parseFloat($(element).css("border-right-width").replace("px", "")),
    383         o = element.offsetWidth - element.clientWidth - n - a;
    384     o -= withoutScrollDiff, $(qalamMirror).css("left", o);
    385     let l = e + t + o + n + a;
    386     $(qalamMirror).css("width", element.getBoundingClientRect().width - l), $(qalamMirror).css("height", "auto")
    387 }
    388 
    389 function resizeQalamExtension() {
    390     let e = parseFloat($(element).css("border-top-width").replace("px", "")),
    391         t = parseFloat($(element).css("border-bottom-width").replace("px", "")),
    392         n = parseFloat($(element).css("border-left-width").replace("px", "")),
    393         a = parseFloat($(element).css("border-right-width").replace("px", "")), o = element.getBoundingClientRect();
    394     $(qalamExtension).css("height", o.height - e - t), $(qalamExtension).css("top", $(element).position().top + e), $(qalamExtension).css("margin", $(element).css("margin")), $(qalamExtension).css("width", o.width - n - a), $(qalamExtension).css("left", $(element).position().left + n), $(qalamExtension).css("position", "absolute"), $(".qalam-highlights-cont").css("height", element.scrollHeight)
    395 }
    396 
    397 function getUrlWithoutParams() {
    398     return [location.protocol, "//", location.host, location.pathname].join("")
    399 }
    400 
    401 function disableUrl() {
    402     if (isUrlDisabled()) return;
    403     let e = JSON.parse(localStorage.getItem("urlsDisabled")) || [];
    404     e.push(getUrlWithoutParams()), localStorage.setItem("urlsDisabled", JSON.stringify(e))
    405 }
    406 
    407 function enableUrl() {
    408     let e = JSON.parse(localStorage.getItem("urlsDisabled")) || [];
    409     urlDisabledIndex = e.findIndex(e => e === getUrlWithoutParams()), urlDisabledIndex > -1 && (e.splice(urlDisabledIndex, 1), localStorage.setItem("urlsDisabled", JSON.stringify(e)))
    410 }
    411 
    412 function isUrlDisabled() {
    413     let e = JSON.parse(localStorage.getItem("urlsDisabled")) || [];
    414     return urlsDisabledIndex = e.find(e => e === getUrlWithoutParams()), !!urlsDisabledIndex
    415 }
    416 
    417 function showDisablePrompt() {
    418     if (!$(shadowRoot).find("qalam-disable-prompt").length) {
    419         qalamDisablePrompt = document.createElement("qalam-disable-prompt");
    420         let e = document.createElement("p");
    421         e.innerHTML = "تعطيل عمل “قلم”؟", e.className = "prompt-title";
    422         let t = document.createElement("button");
    423         t.innerHTML = "تعطيل عمل قلم", t.className = "qalam-btn secondary-btn", $(t).attr("type", "button"), $(t).on("click", function (e) {
    424             disableUrl(), drawLabels(!1), $(".qalam-highlights-cont qalam-label").remove(), $(element).next().addClass("d-none"), $("qalam-button-cont .qalam-button .errors").css("display", "none"), $("qalam-button-cont .qalam-button").css("background-image", `url(${settings.assetsPath}/images/disabled.png)`)
    425         });
    426         let n = document.createElement("button");
    427         n.innerHTML = "إبقاء قلم فعّالاً", n.className = "qalam-btn primary-btn", $(n).attr("type", "button"), $(n).on("click", function () {
    428             enableUrl(), removeDisablePrompt(), drawLabels(!0), $(element).next().removeClass("d-none"), $("qalam-button-cont .qalam-button").css("background-image", "none")
    429         }), qalamDisablePrompt.appendChild(e), qalamDisablePrompt.appendChild(t), qalamDisablePrompt.appendChild(n), $(shadowRoot).append(qalamDisablePrompt);
    430         let a = $("qalam-button-cont")[0].getBoundingClientRect(), o = qalamDisablePrompt.getBoundingClientRect(),
    431             l = [{top: a.top + a.height - o.height, left: a.left + a.width}, {
    432                 top: a.top,
    433                 left: a.left + a.width
    434             }, {top: a.top + a.height - o.height, left: a.left - o.width}, {top: a.top, left: a.left - o.width}];
    435         for (let e = 0; e < l.length && ($(qalamDisablePrompt).css("top", l[e].top), $(qalamDisablePrompt).css("left", l[e].left), !isElementInViewport(qalamDisablePrompt)); e++) ;
    436         $("qalam-button-cont").addClass("active")
    437     }
    438 }
    439 
    440 function removeDisablePrompt() {
    441     $("qalam-button-cont").removeClass("active"), $(qalamDisablePrompt).remove()
    442 }
    443 
    444 function mobileCheck() {
    445     let e = !1;
    446     var t;
    447     return t = navigator.userAgent || navigator.vendor || window.opera, (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(t) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(t.substr(0, 4))) && (e = !0), e
    448 }
    449 
    450 function removeQalamSuggestions() {
    451     mobileCheck() || ($(qalamSuggestions).remove(), $("qalam-extension .qalam-highlights-cont qalam-label").removeClass("active"))
    452 }
    453 
    454 function removeNotification() {
    455     $("qalam-notification").css("right", "-450px"), setTimeout(function () {
    456         $("qalam-notification").remove()
    457     }, 750)
    458 }
    459 
    460 function typedIn() {
    461     typingStallCounter = 0, languageChecker(), secondsCounter || (secondsCounter = setInterval(function () {
    462         typingStallCounter >= TYPING_STALL && ("" != getText().trim() ? spellCheckText() : (clearButton(), clearLabels()), clearInterval(secondsCounter), typingStallCounter = 0, secondsCounter = null), typingStallCounter++
    463     }, 500))
    464 }
    465 
    466 function clearButton() {
    467     $("qalam-button-cont .qalam-button .errors").css("display", "none"), isUrlDisabled() ? $("qalam-button-cont .qalam-button").css("background-image", `url(${settings.assetsPath}/images/disabled.png)`) : $("qalam-button-cont .qalam-button").css("background-image", `url(${settings.assetsPath}/images/128.png)`), $("qalam-button-cont .qalam-button").css("background-color", BUTTON_NORMAL_COLOR), clearLabels()
    468 }
    469 
    470 function languageChecker() {
    471     isTextArea && (/[\u0600-\u06FF]/.test(getText()) ? $(element).css("direction", "rtl") : $(element).css("direction", "ltr"));
    472     let e = $(element).css("direction"), t = "rtl" == e ? "right" : "left";
    473     $(qalamMirror).css("direction", e), $(qalamMirror).css("text-align", t), $(element).css("text-align", t)
    474 }
    475 
    476 function spellCheckText(e) {
    477     let t = ANIMATION_DELAY;
    478     e ? t = 0 : (isUrlDisabled() ? $(".qalam-button").css("background-image", `url(${settings.assetsPath}/images/disabled.png)`) : $("qalam-button-cont .qalam-button").css("background-image", `url(${settings.assetsPath}/images/logo.gif)`), $("qalam-button-cont .qalam-button").css("background-image", `url(${settings.assetsPath}/images/logo.gif)`), $("qalam-button-cont .qalam-button .errors").css("display", "none"));
    479     let n = getText();
    480     isUrlDisabled() || callService(n, t, e)
    481 }
    482 
    483 function fetchErrors(e, t) {
    484     currentTextSuggestions = e, drawLabels(t)
    485 }
    486 
    487 function drawLabels(e) {
    488     reflectToQalamMirror(), resizeQalamExtension(), $(".qalam-highlights-cont qalam-label").remove();
    489     let t = currentTextSuggestions.length;
    490     t > 0 ? ($.each(currentTextSuggestions, function () {
    491         let t = this.original, n = this.from, a = this.to, o = this.replacement, l = this.lineColor,
    492             i = this.labelColor, s = getRangeSpecs(n, a);
    493         s && ($.each(s, function () {
    494             labelCreator(t, n, a, o, l, i, this, e)
    495         }), handleReposition())
    496     }), setErrorsTotal(t)) : clearButton()
    497 }
    498 
    499 function detectBrowser() {
    500     return -1 != (navigator.userAgent.indexOf("Opera") || navigator.userAgent.indexOf("OPR")) ? "Opera" : -1 != navigator.userAgent.indexOf("Chrome") ? "Chrome" : -1 != navigator.userAgent.indexOf("Safari") ? "Safari" : -1 != navigator.userAgent.indexOf("Firefox") ? "Firefox" : -1 != navigator.userAgent.indexOf("MSIE") || 1 == !!document.documentMode ? "IE" : "Unknown"
    501 }
    502 
    503 function detectBrowser() {
    504     return -1 != (navigator.userAgent.indexOf("Opera") || navigator.userAgent.indexOf("OPR")) ? "Opera" : -1 != navigator.userAgent.indexOf("Chrome") ? "Chrome" : -1 != navigator.userAgent.indexOf("Safari") ? "Safari" : -1 != navigator.userAgent.indexOf("Firefox") ? "Firefox" : -1 != navigator.userAgent.indexOf("MSIE") || 1 == !!document.documentMode ? "IE" : "Unknown"
    505 }
    506 
    507 function labelCreator(e, t, n, a, o, l, i, s) {
    508     let r = document.createElement("qalam-label");
    509     i.width = i.right - i.left, i.height = i.bottom - i.top, $(r).css("width", i.width), $(r).css("height", 1.05 * i.height), "Firefox" == detectBrowser() ? ($(r).css("top", i.top + 6 - .025 * i.height), $(r).css("left", i.left + 12)) : ($(r).css("top", i.top - .025 * i.height), $(r).css("left", i.left)), $(r).css("background-color", l), $(r).on("mouseenter", function (t) {
    510         renderQalamSuggestions(t, e), $(r).addClass("active")
     1672      let o = [],
     1673        l = 0;
     1674      for (let t = 0; t < e.length; ++t)
     1675        offset_indices.has(t) && (l += 1), o.push(l);
     1676      for (let e = 0; e < a.length; ++e)
     1677        (a[e].from -= o[a[e].from]), (a[e].to -= o[a[e].to]);
     1678      e == getText() &&
     1679        ((flagged_tokens = []),
     1680        $.each(a, function () {
     1681          let e = JSON.stringify({
     1682            word: wordGetter(this.from, this.to),
     1683            suggestions: this.replacement,
     1684          });
     1685          ignoredSet.has(e) || flagged_tokens.push(this);
     1686        }),
     1687        0 == flagged_tokens.length
     1688          ? clearButton()
     1689          : fetchErrors(flagged_tokens, n));
    5111690    });
    512     let c = JSON.stringify(a);
    513     $(r).attr("data-suggestions", c), $(r).attr("data-start-index", t), $(r).attr("data-end-index", n);
    514     let m = document.createElement("label-border");
    515     $(m).css("left", i.left), $(m).css("width", i.width), $(m).css("background-color", o), r.appendChild(m), qalamHighlightsCont.appendChild(r), s ? $(m).css("left", "0") : setTimeout(function () {
    516         $(m).css("left", "0")
    517     }, 10)
    518 }
    519 
    520 function getRangeInfo(e, t) {
    521     let n = {};
    522     if ("IFRAME" == element.tagName) {
    523         let a = [element.contentDocument.activeElement], o = 0;
    524         for (; a.length;) {
    525             let l = a.pop();
    526             if (3 == l.nodeType) {
    527                 for (let a = 0; a < l.textContent.length; a++) e <= o + a && o + a <= t && (n[o + a] = {
    528                     node: l,
    529                     index: a
    530                 });
    531                 if ((o += l.textContent.length) > t) break
    532             } else {
    533                 if (STYLES_HIDDEN.has(window.getComputedStyle(l, null).display)) continue;
    534                 a.push(...Array.from(l.childNodes).reverse())
    535             }
    536         }
    537         return n
    538     }
    539     if (isTextArea) {
    540         let a = qalamMirror.childNodes[0];
    541         for (let o = e; o <= t; o++) n[o] = {node: a, index: o};
    542         return n
    543     }
    544     let a = [element], o = 0;
    545     for (; a.length;) {
    546         let l = a.pop();
    547         if (3 == l.nodeType) {
    548             for (let a = 0; a < l.textContent.length; a++) e <= o + a && o + a <= t && (n[o + a] = {node: l, index: a});
    549             if ((o += l.textContent.length) > t) break
    550         } else {
    551             if (STYLES_HIDDEN.has(window.getComputedStyle(l, null).display)) continue;
    552             a.push(...Array.from(l.childNodes).reverse())
    553         }
    554     }
    555     return n
    556 }
    557 
    558 function getRangeSpecs(e, t) {
    559     let n = getRangeInfo(e, t), a = document.createRange(), o = [], l = 0, i = 0, s = element.getBoundingClientRect();
    560     for (let r = e; r <= t; r++) {
    561         try {
    562             a.setStart(n[r].node, n[r].index), a.setEnd(n[r].node, n[r].index + 1)
    563         } catch (e) {
    564         }
    565         let e = a.getBoundingClientRect();
    566         if (0 == e.width || 0 == e.height) continue;
    567         let t = e.top - !isTextArea * (s.top - $(element).scrollTop()),
    568             c = e.bottom - !isTextArea * (s.top - $(element).scrollTop()), m = e.left - !isTextArea * s.left,
    569             d = e.right - !isTextArea * s.left, u = Math.min(c - t, i - l), g = Math.min(i, c) - Math.max(l, t);
    570         0 == o.length || g / u < INTERSECTION_THRESHOLD ? o.push({
    571             right: d,
    572             left: m,
    573             bottom: c,
    574             top: t
    575         }) : (o[o.length - 1].left = Math.min(o[o.length - 1].left, m), o[o.length - 1].right = Math.max(o[o.length - 1].right, d), o[o.length - 1].top = Math.min(o[o.length - 1].top, t), o[o.length - 1].bottom = Math.max(o[o.length - 1].bottom, c)), l = t, i = c
    576     }
    577     return o
    578 }
    579 
    580 function clearLabels() {
    581     currentTextSuggestions = [], $(".qalam-highlights-cont qalam-label").remove()
    582 }
    583 
    584 function setErrorsTotal(e) {
    585     $("qalam-button-cont .qalam-button").css("background-color", BUTTON_ERROR_COLOR), $("qalam-button-cont .qalam-button").css("background-image", "unset"), $("qalam-button-cont .qalam-button .errors").css("display", "block"), $("qalam-button-cont .qalam-button .errors").text(e), e > 99 ? $("qalam-button-cont .qalam-button .errors").css("font-size", "12px") : $("qalam-button-cont .qalam-button .errors").css("font-size", "15px")
    586 }
    587 
    588 function decreaseTotalErrorsCount() {
    589     let e = parseInt($("qalam-button-cont .qalam-button .errors").text());
    590     e > 1 ? $("qalam-button-cont .qalam-button .errors").text(e - 1) : clearButton()
    591 }
    592 
    593 function renderQalamSuggestions(e, t) {
    594     removeQalamSuggestions();
    595     let n = $(e.target).closest("qalam-label"), a = JSON.parse($(n).attr("data-suggestions")),
    596         o = $(n).attr("data-start-index"), l = $(n).attr("data-end-index");
    597     if (!$(shadowRoot).find("qalam-suggestions").length) {
    598         qalamSuggestions = document.createElement("qalam-suggestions");
    599         let e = document.createElement("suggestions-cont");
    600         $.each(a, function () {
    601             let t = this, n = document.createElement("suggestion-item");
    602             $(n).on("click", function () {
    603                 let e = $(element).scrollTop(), n = $(window).scrollTop();
    604                 $(`qalam-label[data-start-index='${o}']`).remove(), removeQalamSuggestions(), decreaseTotalErrorsCount(), replaceOriginalText(t, o, l), spellCheckText(!0), $(element).scrollTop(e), $(window).scrollTop(n), mobileCheck() && ($(qalamSuggestions).remove(), $("qalam-extension .qalam-highlights-cont qalam-label").removeClass("active"))
    605             });
    606             let a = document.createElement("suggestion-text");
    607             "" === t.trim() ? a.innerHTML = '<i style="font-size:12px;"><مسافة زائدة><i>' : a.innerHTML = t, n.appendChild(a), e.appendChild(n)
    608         });
    609         let i = document.createElement("div");
    610         i.className = "ignore-cont", $(i).on("click", function () {
    611             wordGetter(o, l);
    612             onDismissCallback([t]), $(`qalam-label[data-start-index='${o}']`).remove(), removeQalamSuggestions(), spellCheckText(!0)
    613         });
    614         let s = document.createElement("img");
    615         s.className = "ignore-icon", s.src = `${settings.assetsPath}/images/ignore.svg`;
    616         let r = document.createElement("p");
    617         if (r.className = "ignore-text", r.innerHTML = "تجاهل هذا التصحيح", i.appendChild(s), i.appendChild(r), isWriterAllowedToAddToDic) {
    618             addToDictionaryItem = document.createElement("div"), addToDictionaryItem.className = "add-to-dic-cont", $(addToDictionaryItem).on("click", function () {
    619                 onAddToDictionaryCallback([t]), $(`qalam-label[data-start-index='${o}']`).remove(), removeQalamSuggestions(), spellCheckText(!0)
    620             });
    621             let e = document.createElement("img");
    622             e.className = "add-to-dic-icon", e.src = `${settings.assetsPath}/images/add.svg`;
    623             let n = document.createElement("p");
    624             n.className = "add-to-dic-text", n.innerHTML = "إضافة إلى القاموس", addToDictionaryItem.appendChild(e), addToDictionaryItem.appendChild(n)
    625         }
    626         if (qalamSuggestions.appendChild(e), qalamSuggestions.appendChild(i), isWriterAllowedToAddToDic && qalamSuggestions.appendChild(addToDictionaryItem), $(shadowRoot).append(qalamSuggestions), a.length > 0) {
    627             labelBoundingBox = n[0].getBoundingClientRect(), $(qalamSuggestions).css("display", "block"), suggestionBoundingBox = qalamSuggestions.getBoundingClientRect();
    628             let e = [{
    629                 top: labelBoundingBox.top + labelBoundingBox.height,
    630                 left: labelBoundingBox.left + labelBoundingBox.width - suggestionBoundingBox.width
    631             }, {
    632                 top: labelBoundingBox.top + labelBoundingBox.height,
    633                 left: labelBoundingBox.left
    634             }, {
    635                 top: labelBoundingBox.top - suggestionBoundingBox.height,
    636                 left: labelBoundingBox.left + labelBoundingBox.width - suggestionBoundingBox.width
    637             }, {top: labelBoundingBox.top - suggestionBoundingBox.height, left: labelBoundingBox.left}];
    638             for (let t = 0; t < e.length && ($(qalamSuggestions).css("top", e[t].top), $(qalamSuggestions).css("left", e[t].left), !isElementInViewport(qalamSuggestions)); t++) ;
    639         }
    640     }
    641     resizeQalamExtension()
    642 }
    643 
    644 function onAddToDictionaryCallback(e) {
    645     $.ajax({
    646         dataType: "json", url: baseLink + "dictionaries/words", type: "POST", beforeSend: function (e) {
    647             e.setRequestHeader("Authorization", `${clientId}`), e.setRequestHeader("Content-Type", "application/json")
    648         }, data: JSON.stringify({words: e}), success: function (e) {
    649         }, error: function () {
    650         }
    651     })
    652 }
    653 
    654 function onDismissCallback(e) {
    655     $.ajax({
    656         dataType: "json",
    657         url: baseLink + "documents/" + uuidV3Hash + "/dismissals",
    658         type: "POST",
    659         beforeSend: function (e) {
    660             e.setRequestHeader("Authorization", `${clientId}`), e.setRequestHeader("Content-Type", "application/json")
    661         },
    662         data: JSON.stringify({words: e}),
    663         success: function (e) {
    664         },
    665         error: function () {
    666         }
    667     })
    668 }
    669 
    670 function isElementInViewport(e) {
    671     let t = e.getBoundingClientRect();
    672     return t.top >= 0 && t.left >= 0 && t.bottom <= (window.innerHeight || document.documentElement.clientHeight) && t.right <= (window.innerWidth || document.documentElement.clientWidth)
    673 }
    674 
    675 function wordGetter(e, t) {
    676     return $(element).val().substr(e, parseInt(t) - e + 1)
    677 }
    678 
    679 function replaceOriginalText(e, t, n) {
    680     let a = getText().length;
    681     if (isTextArea) if ("IFRAME" == element.tagName) {
    682         element.contentWindow.focus();
    683         let e = getRangeInfo(t, n);
    684         range = element.contentDocument.createRange(), range.setStart(e[t].node, e[t].index), range.setEnd(e[n].node, e[n].index + 1), sel = element.contentDocument.getSelection(), sel.removeAllRanges(), sel.addRange(range)
    685     } else $(element).trigger("focus"), $(element)[0].selectionStart = t, $(element)[0].selectionEnd = parseInt(n) + 1; else {
    686         $(element).trigger("focus");
    687         let e = getRangeInfo(t, n);
    688         range = document.createRange(), range.setStart(e[t].node, e[t].index), range.setEnd(e[n].node, e[n].index + 1), sel = window.getSelection(), sel.removeAllRanges(), sel.addRange(range)
    689     }
    690     triggerFlag = !1, "IFRAME" == element.tagName ? element.contentDocument.execCommand("insertText", !1, e) : document.execCommand("insertText", !1, e), setTimeout(function () {
    691         triggerFlag = !0
    692     }, 5);
    693     let o = a - getText().length, l = -1;
    694     $.each(currentTextSuggestions, function (e, n) {
    695         n.from == t ? l = e : n.from > t && (currentTextSuggestions[e].from -= o, currentTextSuggestions[e].to -= o)
    696     }), -1 != l && currentTextSuggestions.splice(l, 1), drawLabels(!0)
    697 }
    698 
    699 function unmountQalamComponent() {
    700     $("qalam-container").remove(), $("qalam-mirror-shadow").remove(), null != qalamMirror && $(qalamMirror).remove(), removeQalamSuggestions(), ignoredSet = new Set, currentTextSuggestions = []
    701 }
    702 
    703 function resetGlobalVariables() {
    704     shadowRoot = null, qalamDisablePrompt = null, isTextArea = null, triggerFlag = !0, SCServiceActive = null, qalamExtension = null, qalamExtensionCont = null, qalamHighlightsCont = null, qalamMirror = null, removeDisablePrompt(), removeQalamSuggestions(), qalamSuggestions = null, $(element).off(), element = null, withoutScrollDiff = 0, elementParent = null, typingStallCounter = 0, secondsCounter = null, resizeHoldCounter = null, currentTextSuggestions = [], clearInterval(secondsCounter), clearInterval(resizeHoldCounter)
    705 }
    706 
    707 function turnOnSC() {
    708     SCServiceActive = !0, init()
    709 }
    710 
    711 function turnOffSC() {
    712     SCServiceActive = !1, unmountQalamComponent(), resetGlobalVariables()
    713 }
    714 
    715 function setCookie() {
    716     let e = generateId(8);
    717     document.cookie = "qalam_user_id=" + e + "; path=/"
    718 }
    719 
    720 function getCookie(e) {
    721     for (var t = e + "=", n = document.cookie.split(";"), a = 0; a < n.length; a++) {
    722         for (var o = n[a]; " " == o.charAt(0);) o = o.substring(1, o.length);
    723         if (0 == o.indexOf(t)) return o.substring(t.length, o.length)
    724     }
    725     return null
    726 }
    727 
    728 function generateId(e) {
    729     for (var t = "", n = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", a = n.length, o = 0; o < e; o++) t += n.charAt(Math.floor(Math.random() * a));
    730     return t
    731 }
    732 
    733 function callService(e, t, n) {
    734     if (documentId) uuidV3Hash = uuid.v5(documentId + ":" + editorId, clientId); else if (mode == PATH_MODE) {
    735         var a = extractPathParamAt(modeValue);
    736         a || (documentId = a = uuid.v4()), uuidV3Hash = uuid.v5(a + ":" + editorId, clientId)
    737     } else if (mode == QUERY_MODE) {
    738         var o = extractQueryParam(modeValue);
    739         o || (documentId = o = uuid.v4()), uuidV3Hash = uuid.v5(o + ":" + editorId, clientId)
    740     } else documentId = uuid.v4(), uuidV3Hash = uuid.v5(documentId + ":" + editorId, clientId);
    741     var l = {
    742         url: API_LINK,
    743         method: "POST",
    744         timeout: 0,
    745         headers: {"Content-Type": "application/json", Authorization: `${clientId}`},
    746         success: function () {
    747         },
    748         error: function (e, t, n) {
    749             e.status
    750         },
    751         data: JSON.stringify({text: e, docId: uuidV3Hash})
    752     };
    753     setTimeout(function () {
    754         $.ajax(l).done(function (t) {
    755             let a = [];
    756             extend(a, extractRest(t.termSuggestions, TERM_LINE_COLOR, TERM_LABEL_COLOR)), extend(a, extractRest(t.tafqeetSuggestions, TAFQEET_LINE_COLOR, TAFQEET_LABEL_COLOR)), extend(a, extractResponse(t.grammarResponse, GRAMMAR_LINE_COLOR, GRAMMAR_LABEL_COLOR)), extend(a, extractResponse(t.phrasingResponse, PHRASING_LINE_COLOR, PHRASING_LABEL_COLOR)), extend(a, extractResponse(t.spellCheckResponse, SC_LINE_COLOR, SC_LABEL_COLOR)), $.each(t.numDate, function () {
    757                 extend(a, extractRest(this, NUM_LINE_COLOR, NUM_LABEL_COLOR))
    758             }), $.each(t.tashkeel, function () {
    759                 extend(a, extractRest(this, T_LINE_COLOR, T_LABEL_COLOR))
    760             }), $.each(t.punctuation, function () {
    761                 extend(a, extractRest(this, PUNC_LINE_COLOR, PUNC_LABEL_COLOR))
    762             });
    763             let o = [], l = 0;
    764             for (let t = 0; t < e.length; ++t) {
    765                 let n = t + DUMMY_STRING.length + 2;
    766                 n <= e.length && e.slice(t, n) == `\n${DUMMY_STRING}\n` && (l += DUMMY_STRING.length + 2), o.push(l)
    767             }
    768             for (let e = 0; e < a.length; ++e) a[e].from -= o[a[e].from], a[e].to -= o[a[e].to];
    769             e == getText() && (flagged_tokens = [], $.each(a, function () {
    770                 let e = JSON.stringify({word: wordGetter(this.from, this.to), suggestions: this.replacement});
    771                 ignoredSet.has(e) || flagged_tokens.push(this)
    772             }), 0 == flagged_tokens.length ? clearButton() : fetchErrors(flagged_tokens, n))
    773         })
    774     }, t)
    775 }
    776 
    777 function extractResponse(e, t, n) {
    778     if (null == e || jQuery.isEmptyObject(e)) return [];
    779     if (SCSuggestions = e.results.flagged_tokens, null == SCSuggestions) return [];
    780     let a = [];
    781     for (let e = 0; e < SCSuggestions.length; e++) token = SCSuggestions[e], a.push({
     1691  }, t);
     1692}
     1693
     1694function extractResponse(e, t, n, x) {
     1695  if (null == e || jQuery.isEmptyObject(e)) return [];
     1696  if (((SCSuggestions = e.results.flagged_tokens), null == SCSuggestions))
     1697    return [];
     1698  let a = [];
     1699  for (let e = 0; e < SCSuggestions.length; e++)
     1700    (token = SCSuggestions[e]),
     1701      a.push({
     1702        type: x,
    7821703        lineColor: t,
    7831704        labelColor: n,
    7841705        from: token.start_index,
    7851706        to: token.end_index,
     1707        lang: token.lang ? token.lang : 'ar',
    7861708        original: token.original_word,
    787         replacement: function (e) {
    788             let t = [];
    789             for (let n = 0; n < e.length; n++) t.push(e[n].text);
    790             return t
    791         }(token.suggestions)
     1709        replacement: (function (e) {
     1710          let t = [];
     1711          for (let n = 0; n < e.length; n++) t.push(e[n].text);
     1712          return t;
     1713        })(token.suggestions),
     1714      });
     1715  return a;
     1716}
     1717
     1718function extractRest(e, t, n, x) {
     1719  if (null == e) return [];
     1720  for (let a = 0; a < e.length; a++)
     1721    (e[a].type = x),
     1722      (e[a].replacement = [e[a].replacement]),
     1723      (e[a].to -= 1),
     1724      (e[a].lineColor = t),
     1725      (e[a].labelColor = n);
     1726  return e;
     1727}
     1728
     1729function isOverlapping(e, t, n, a) {
     1730  return n <= t && a >= e;
     1731}
     1732
     1733function extend(e, t) {
     1734  for (let n = 0; n < t.length; n++) {
     1735    let a = !0;
     1736    for (let o = 0; o < e.length; o++)
     1737      if (isOverlapping(t[n].from, t[n].to, e[o].from, e[o].to)) {
     1738        a = !1;
     1739        break;
     1740      }
     1741    a && e.push(t[n]);
     1742  }
     1743}
     1744
     1745async function shakel() {
     1746  selectedText = window.getSelection().toString();
     1747}
     1748
     1749function unshakel(e) {
     1750  return e && (selectedText = e.replace(/([\u064b-\u0653\u0670])/g, '')), e;
     1751}
     1752
     1753function isEmpty(e) {
     1754  return 0 === Object.keys(e).length;
     1755}
     1756
     1757function extractQueryParam(e) {
     1758  return new URLSearchParams(window.location.search).get(e);
     1759}
     1760
     1761function extractPathParamAt(e) {
     1762  if (0 != e) return window.location.pathname.split('/')[e];
     1763  console.error('Index should start from 1');
     1764}
     1765
     1766function assignEditorIds() {
     1767  document.querySelectorAll('[contenteditable]').forEach((e, t) => {
     1768    e.setAttribute('data-qid', 'ce:' + t);
     1769  }),
     1770    document.querySelectorAll('textarea').forEach((e, t) => {
     1771      e.setAttribute('data-qid', 'te:' + t);
    7921772    });
    793     return a
    794 }
    795 
    796 function extractRest(e, t, n) {
    797     if (null == e) return [];
    798     for (let a = 0; a < e.length; a++) e[a].replacement = [e[a].replacement], e[a].to -= 1, e[a].lineColor = t, e[a].labelColor = n;
    799     return e
    800 }
    801 
    802 function isOverlapping(e, t, n, a) {
    803     return n <= t && a >= e
    804 }
    805 
    806 function extend(e, t) {
    807     for (let n = 0; n < t.length; n++) {
    808         let a = !0;
    809         for (let o = 0; o < e.length; o++) if (isOverlapping(t[n].from, t[n].to, e[o].from, e[o].to)) {
    810             a = !1;
    811             break
    812         }
    813         a && e.push(t[n])
     1773}
     1774
     1775function assignIframeEditorIds(e, t) {
     1776  e.contentDocument.querySelectorAll('[contenteditable]').forEach((e, n) => {
     1777    e.setAttribute('data-qid', `fce:${t}:${n}`);
     1778  }),
     1779    e.contentDocument.querySelectorAll('textarea').forEach((e, n) => {
     1780      e.setAttribute('data-qid', `fte:${t}:${n}`);
     1781    });
     1782}
     1783
     1784function getContext(e, t, n) {
     1785  let a = getText(),
     1786    o = a
     1787      .replace(/\n/g, '')
     1788      .substring(0, t)
     1789      .split(' ')
     1790      .filter((e) => '' != e && ' ' != e),
     1791    l = a
     1792      .replace(/\n/g, '')
     1793      .substring(parseInt(n) + 1)
     1794      .split(' ')
     1795      .filter((e) => '' != e && ' ' != e);
     1796  return `\n\t\t\t${o.slice(o.length - 6).join(' ')} ${e} ${l
     1797    .slice(0, 5)
     1798    .join(' ')}`;
     1799}
     1800window.x || (x = {}),
     1801  (x.Selector = {}),
     1802  (x.Selector.getSelected = function () {
     1803    var e = '';
     1804    return (
     1805      window.getSelection
     1806        ? (e = window.getSelection())
     1807        : document.getSelection
     1808        ? (e = document.getSelection())
     1809        : document.selection && (e = document.selection.createRange().text),
     1810      e
     1811    );
     1812  }),
     1813  $(document).ready(function () {
     1814    (scr.src = `${settings.assetsPath}/js/uuid.js`),
     1815      (scr.async = !1),
     1816      head.insertBefore(scr, head.firstChild);
     1817    let e = document.querySelectorAll('textarea');
     1818    for (let a = 0; a < e.length; a++) {
     1819      const o = e[a];
     1820      var t = o.parentNode,
     1821        n = document.createElement('div');
     1822      n.classList.add('textarea-blk'), t.replaceChild(n, o), n.appendChild(o);
    8141823    }
    815 }
    816 
    817 async function shakel() {
    818     selectedText = window.getSelection().toString()
    819 }
    820 
    821 function unshakel(e) {
    822     return e && (selectedText = e.replace(/([\u064b-\u0653\u0670])/g, "")), e
    823 }
    824 
    825 function isEmpty(e) {
    826     return 0 === Object.keys(e).length
    827 }
    828 
    829 function extractQueryParam(e) {
    830     return new URLSearchParams(window.location.search).get(e)
    831 }
    832 
    833 function extractPathParamAt(e) {
    834     if (0 != e) return window.location.pathname.split("/")[e];
    835     console.error("Index should start from 1")
    836 }
    837 
    838 function assignEditorIds() {
    839     document.querySelectorAll("[contenteditable]").forEach((e, t) => {
    840         e.setAttribute("data-qid", "ce:" + t)
    841     }), document.querySelectorAll("textarea").forEach((e, t) => {
    842         e.setAttribute("data-qid", "te:" + t)
    843     })
    844 }
    845 
    846 function assignIframeEditorIds(e, t) {
    847     e.contentDocument.querySelectorAll("[contenteditable]").forEach((e, n) => {
    848         e.setAttribute("data-qid", `fce:${t}:${n}`)
    849     }), e.contentDocument.querySelectorAll("textarea").forEach((e, n) => {
    850         e.setAttribute("data-qid", `fte:${t}:${n}`)
    851     })
    852 }
    853 
    854 window.x || (x = {}), x.Selector = {}, x.Selector.getSelected = function () {
    855     var e = "";
    856     return window.getSelection ? e = window.getSelection() : document.getSelection ? e = document.getSelection() : document.selection && (e = document.selection.createRange().text), e
    857 }, $(document).ready(function () {
    858     scr.src = `${settings.assetsPath}/js/uuid.js`, scr.async = !1, head.insertBefore(scr, head.firstChild);
    859     let e = document.querySelectorAll("textarea");
    860     for (let a = 0; a < e.length; a++) {
    861         const o = e[a];
    862         var t = o.parentNode, n = document.createElement("div");
    863         n.classList.add("textarea-blk"), t.replaceChild(n, o), n.appendChild(o)
     1824    if (
     1825      (activate(baseLink + 'test/go', clientId),
     1826      !document.getElementById(cssId))
     1827    ) {
     1828      var a = document.getElementsByTagName('head')[0],
     1829        o = document.createElement('link');
     1830      (o.id = cssId),
     1831        (o.rel = 'stylesheet'),
     1832        (o.type = 'text/css'),
     1833        (o.href = `${settings.assetsPath}/css/qalamExtension.css`),
     1834        (o.media = 'all'),
     1835        a.appendChild(o);
    8641836    }
    865     if (activate(baseLink + "test/go", clientId), !document.getElementById(cssId)) {
    866         var a = document.getElementsByTagName("head")[0], o = document.createElement("link");
    867         o.id = cssId, o.rel = "stylesheet", o.type = "text/css", o.href = `${settings.assetsPath}/css/qalamExtension.css`, o.media = "all", a.appendChild(o)
    868     }
    869 });
     1837  });
  • qalam/trunk/qalam.php

    r2599982 r2896421  
    33 * Plugin Name:       Qalam
    44 * Description:       Qalam helps you to write clear, effective texts that are free from spelling and grammatical errors, using the latest artificial intelligence technologies and Arabic language processing.
    5  * Version:           1.0.0
     5 * Version:           1.0.1
    66 * Requires at least: 5.2
    77 * Requires PHP:      7.2
  • qalam/trunk/readme.txt

    r2594341 r2896421  
    44Donate link: https://www.qalam.ai/
    55Requires at least: 5.2
    6 Tested up to: 5.8
    7 Stable tag: 1.0.0
     6Tested up to: 6.2
     7Stable tag: 1.0.1
    88License: GPL v2
    99Requires PHP: 7.2
Note: See TracChangeset for help on using the changeset viewer.