1xbet Azərbaycan: 100 Dollar Bonus, Tətbiqetmə, Apk, Qeydiyyat

1xbet Azerbaycan Yükle Mobil Az Indir Android Ios Modern Group Of Institutions Jhansi

kimi kriptovalyutalardan istifadə edə bilərlər. Azərbaycandan olan oyunçular üçün böyük üstünlük ondan ibarətdir ki, bukmeker kontoru əməliyyatlar üçün əlavə komissiya təyin etmir. Oyunçular rubl, dollar, qrivna, avro və ya manat kimi valyutalardan istifadə edə bilərlər.

Şirkət bu sahədə yaranan ilk şirkətlərdən biridir, pul oyunları üçün əlverişli şərait təklif edir. Mobil telefon üçün 1XBET web saytına asanca endirib yükləyə bilərsiniz. Sürətli mərc rejimi müştərinin müəyyən etdiyi məbləğdə mərci seçilmiş nəticənin əmsalına bir kliklə yerləşdirməyə imkan verir. Mövcud qaydalar 1xbet mərc şirkətinin mərc qəbulu və uduşların ödənilməsini tənzimləyir (sonraki mətndə qayda olaraq göstəriləcəkdir). Pulsuz mərc hər hansı və ya müəyyən əmsalla yerləşdirilə bilən pulsuz mərcdir.

Bet Apk Tətbiqini Indirin

Hesab Rusiya Federasiyası xaricində bir ölkədə qeydiyyata alınmalı və IP ünvanı seçilmiş vəziyyətə dəyişdirilməlidir. Metod buxarlanır və səy göstərməyə dəyməz, buna görə də 1xBet’i bir güzgüdən yükləmək daha yaxşıdır. Bukmeker kontorunun işləyən güzgüsü oyunçuların VPN-i açmadan cihazlarına mobil tətbiq yükləməsinə imkan verir.

Daha sonra bir e-poçt vasitəsilə hesabınızı aktivləşdirmək üçün bir hyperlink alacaqsınız. 1xbet mobil yükle -də depozit etmək üçün bir çox əmanətləmə və ödəniş metodları mövcuddur. Kartlar, e-pul servisləri və kripto valyutalar kimi çeşitli seçimlər mövcuddur. 1XBET yalnız bir mobil tətbiq deyil, eyni zamanda masa üstü bahis tətbiqi de uma daxildir.

Bet Azerbaycan Qeydiyyat Mobi Az Yukle Elaqe Nomresi 614

biləcəyiniz bir neçə min hadisə mövcuddur. Oyunçular 1500 futbol mərc bazarından istədiyini seçə edə bilər, buna görə də mərclər olduqca dəyişkən olacaq. Asiya idman hadisələri və ya Afrika turnirləri də daxil olmaqla ekzotik hadisələrə mərc edə bilərsiniz http://1xbet-azerbaijan2.com/.

yetirdiyi təqdirdə depozitə əlavə vəsait almaq imkanı təklif edir. Oyunçular idmana mərc etməyi üstün tuturlarsa, oxşar şərtlər altında qeydiyyatdan keçmək üçün 100 dollar və 150 ​​pulsuz fırlanma əldə edə bilərlər.

Bet Bukmeker Veb Saytında Qeydiyyatdan Keçmə

Proqnozlaşdırmaq üçün təklif olunan döyüşləri idman növlərinə görə qruplaşdıra bilərəm. 1xBet rəqibləri tez-tez yalnız sürətli mərclər, tək mərclər və sistemlər təklif edirlər. 1xBet platformasında hansı proqnozları verəcəyimi seçmək üçün tam sərbəstliyim var.

bilərsiniz. Qeydiyyat üçün eyni dərəcədə vacib bir tələb, kazinonun istənilən bölməsində real pul üçün mərc etmək imkanıdır. Qurumun bütün üstünlüklərindən yararlanmaq üçün yoxlamadan keçməlisiniz

Bet Azerbaycan Bukmeker Kompaniyasinin Üstünlükləri Nə Ilə Əlaqəlidir?

Minimum hesab doldurulmasının məbləği 50-dir AZN butün ödəniş üsulları üçün. Vous pouvez utiliser Visa, Mastercard, Principal, Visa Qiwi Wallet pour les systèmes Beeline, MTS, Tele2 et Megafon. Bu ways, idman təlimatlarına, onlayn kazinolara və ikramiylərə dəstək göstərilir. 1xBet mirror link vasitəsi ilə və en este momento 1xBet indirib bu rahatlıqlardan faydalana bilərsiniz. Birinci komandanın qələbəsinə 1xbet azerbaijan bukmeker one 755 əmsal təklif edir.

Depoziti təsdiqlədikdən sonra məbləğ bir neçə dəqiqə ərzində hesabınıza daxil olacaq. Gecikmə varsa, şirkətin və ya ödəmə sisteminizin texniki dəstək heyəti ilə əlaqə saxlayın. Onlardan birini seçmədən əvvəl bonus mərc qaydaları ilə tanış olmağınızı məsləhət görürük. 1xBet bütün əməliyyat sistemləri üçün mobil tətbiqetmələr təklif edir.

Bet Az, 1xbet Az Saytı

seçə və ya AppStore-a baş çəkə bilərsiniz. Quraşdırma fayllarını yüklədikdən sonra oyunçuların mövcud parametrlərə əlavə və dəyişikliklər etməyə ehtiyacı yoxdur.

1xbet yaradıcıları, bukmeykerin ofisinin yalnız sübut edilmiş analoqlarını ziyarət etməyi tövsiyə edirlər. 1xbet mobil tətbiqində promokoddan istifadə etmək üçün tətbiqin ‘Hesabıma gir’ bölməsindən giriş edin və hesabınızı açın. 1xBet pulsuz mərc, actual pul, electronics və avtomobillərin rəsmləri ilə mövcud oyunçular üçün promosyonlar təşkil edin. 1xbet mobil tətbiqini yükləmək üçün 1xbet resmi veb saytına daxil olun və mobil tətbiqlərin yükləndiyi bölməyə keçin. 1xbet mobil tətbiqində hesabınıza giriş etmək üçün tətbiqin ana səhifəsində ‘Giriş’ düyməsini seçin və hesabınıza support olan məlumatları daxil edin. Bukmeker kontorunun saytının mobil versiyasında 1x bet Bir çox variant varifr?

Bet Dəstəyi Ilə Necə Əlaqə Qurmaq Olar?

Bu şirkət lazımi lisenziyaları 1xbet ünvanında fəaliyyət göstərir. Bu cür proqramların inkişaf etdiriciləri aylıq abunəçiləri təmin edir. Qumar müəssisələrinin qadağan olunduğu yalnız bu ölkələri təklif edir. ” Asanlıqla oyunun qalibi olur və ödənilən mükafat adətən həmin oyun üçün 1xbet bingo kartlarının satışından əldə edilən pulun faizidir. ” Qaliblər arasında eyni sayda hədiyyələr bərabər bölünəcək və hamısı qalib olacaq. 1xbet slotunun ən maraqlı cəhətlərindən biri onun oynamaq çox asan olması və heç bir xüsusi təlim tələb etməməsidir.

Yeni müştərilərin bu an üçün yalnız Alman konuşabildiğimiz təqdirdə Türkçe olaraq qəbul edildiyinin deyildiyi çox şey var. Android cihazlar üçün 1xBet cellular Azerbaijan tətbiqini mərc saytının rəsmi veb-saytından yükləməyiniz lazımdır. Applikasiyaların diqqətçəkici bölmələrindən biri də “Abunəlikləri idarə et” bölməsidir. Vəsaitləri Visa, Mastercard, Maestro, Visa Qiwi Wallet ödəniş sistemləri və Beeline, MTS, Tele2 və Megafon mobil operatorları vasitəsilə çıxarmaq olar. Minimum pul çixarmaq məbləği 100AZN-dir bütün odeme üsullari üçün.

Vtomobil Xbet – Ən Yaxşı Idman Bahis Tətbiqi

Proqramı yükləmək üçün, rəsmi 1xbet web ünvanını və ya rəsmi mobil telefonu ünvanını ziyarət etməlisiniz. Bu platformaya daxil etdikdə, ağıllı telefon simvoluna və ya “Mobil Mobil Tətbiq nişanı tıklayarak endirməyə başlaya bilərsiniz. Mobil brauzerinizin rəsmi 1xbet mobil ünvanını (bk1x.mobi) yazmanız lazımdır, sonra 1xbet mobil ünvanına avtomatik olaraq bağlana. Digər bir üsul də 1xbet yazaraq bir axtarış mühərrikinə girməkdir. Kompüterinizi qurmağa və ya yalnız telefonunuzdan daxil olmağa ehtiyac yoxdur. Bonuslardan istifadə edərkən mütləq bonuslardan istifadənin şərtlərinə və müddətinə diqqət yetirmək lazımdır.

1Xbet az mobil tətbiqinin oyun və bahislər üzərində üstünlükləri vardır. Sayta daxil olmaq və sabit İnternet bağlantısı ilə bazarlaşmaq üçün mobil tətbiqi yükləyin. Əgər onlayn – mərc etmək istəyirsinizsə, 1xBet ARIZONA zerkalo ən gözəl seçimlərdən biridir. Bütün xırda detallar, sadə və rahat dizayn bir sözlə hər şey istifadəçilərin rahatlığı üçün ayarlanıb. 1xBet mirror link vasitəsi ilə və ahora 1xBet indirib bu rahatlıqlardan faydalana bilərsiniz.

Bet Şəxsi Hesabınıza Daxil Olun

Azərbaycanlı istifadəçilər bu applikasiyanı əlavə tənzimləmələrə ehtiyac olmadan asanlıqla quraşdıra bilərlər. Platforma idman növləri 60-dan yuxarıdır – Ən məşhur (Futbol və Tennis) -dən az populyarlığa (Bilyard və Surf) qədər. Brend eyni zamanda canlı bahislər təklif edir (əksər idman tədbirləri üçün). Ondan istifadə etmək üçün nəticəni kupona əlavə etmək kifayətdir, burada pulsuz mərc seçimini seçirsiniz 1xbet azerbaycan. Təcrübəli müştərilər statistikanın təhlili ilə birləşərək, qazanma şansını artırır. Qiymətli bonuslarla idmana bahis etmək istəyirsinizsə, bloklama ətrafında bir yol tapın.

“E Sports” bölməsində Oyunçu-üzv həmçinin virtual futbol matçlarını “canlı mərc”bölməsində izləyə bilər. Bundan əlavə, Android və iOS cihazları üçün 1xbet mobil proqramının yüklənməsinin mövcudluğu oyun oyunçular üçün sorunsuz edir. Bukmeker kontorunun saytının mobil versiyasında 1x bet Bir çox variant var, amma etmək üçünMərc etmək üçün qeydiyyat prosedurundan keçməlisiniz.

Bet Güzgü: Giriş Üçün Bütün Yollar

1xBet AZERBAYCAN bukmeker kontoru tək, ekspress, sistem, zəncir tipli mərcləri təqdim edir. 1xBet mobil saytda ziyarətcilərə idman mərcləri, hava mərcləri, 1xbet az şirkətin bloqu, aksiyaları, 1xbet kazinonun xüsusi təklifləri təqdim olunur. Bu proqramın ölçüsü çox kiçikdir və istifadəçilər bu proqramı asanlıqla yükləyə və qura bilərlər.

Dünyanın bir çox ölkəsində mərc xidmətləri göstərən 1xbet, geniş üzvlərinə çatdı və bahis bazarında yerini aldı. Ən yüksək canlı bahis əmsallarını təklif edən 1xbet AZ , pulsuz bahis promosyonları ilə itkilərinizi minimuma endirir. Bir bettor şübhəsi varsa, sərmayə qoyulan pulun üçdə birini götürür. 1xbetin bloklanması ümumiyyətlə bahis fəaliyyəti üçün tələblərin pozulması ilə əlaqələndirilir.

Bet Apk Tətbiqini Indirin

1xbet mobile oyunlarda futbol mərclərinin bir çox üstünlükləri var. Ölkəni və istədiyiniz valyutanı göstərin.Qeydiyyat haqqında ətraflı məlumat əldə edin 1xBet. Bu applikasiya bir çox parametrlərdə Android üçün olan tətbiqlə bənzərliyə sahibdir. 1xbet mobi yukle Mobildən sonra gəlir yoxdur, qəfil ödəniş və ya silinmə, üzvlük haqqından istifadə edilmir. 1xbet yukle prosesində fərqli marka və modellərin tabletlərində istifadə edilə bilər, bu da bütün smartfonlarda belədir.

Ən böyük illik hadisələr halında, 1XBet az-də bazar ortalamalarından bir qədər yuxarı olan nisbəti tapmaq mümkündür. Canlı axın və canlı oyunları baxımından 1XBet az-ə görə çox yüksək hesab vermək ədalətli deyil. Bu bukmekerin həqiqətən üstün olduğu başqa bir sahədir və ənənəvi kitablardan daha çox təklif edir. Müştərilərə bir satırda ən azı 20 mərc oyunları müvəffəqiyyətsiz olması halında müştərilərə $ 100 pulsuz mərc təklif edir … bir az zərbəni yumşaldır. Advancebet, 1XBet az müştəriləri arasında daha çox məşhur bir xüsusiyyətdir.

Bet Az Mərc Oyunları

çoxlu sayda basketbol, ​​xokkey və ya tennis matçları da mövcuddur. Bukmeker kontorunun saytında ən yaxşı NHL oyunları üçün 1000-ə qədər bazarı görə bilərsiniz Aşağı bölmələr üçün bukmeker kontoru ən azı 300 bazar təklif edir.

Bir əmanət etmək üçün istifadəçi adınızı daxil etməyiniz xahiş olunur. Android cihazlar üçün 1xBet mobile Azerbaijan tətbiqini mərc saytının rəsmi veb-saytından yükləməyiniz lazımdır. 1XBet az , 40-dan çox dildə mərc oyunları xidmətlərini təklif edərək dünya üzərində qeyd etdi.

Bet Azərbaycan: Rəsmi Saytın Nəzərdən Keçirilməsi

StarJackpot promosyonu da var ki, bu oyunçuları hər gün mütərəqqi bir məbləğ qazanma imkanı verir. Hadisələrlə və uduşların əmsalları ilə Xətt və লাইভ səhifələrində tanış ola bilərsiniz. Döngələrin, sıraların və ödəniş xətlərinin sayı qazana biləcəyiniz yolların sayına təsir göstərir. Oynaya biləcəyiniz minlərlə müxtəlif slot oyunu va, lakin hamısı eyni işləyir, lakin definir fərqlidir.

Problem ondadır ki, daha sonra şəxsi hesabınızdakı məlumatları əlavə etməli və yoxlamadan keçməlisiniz. Ancaq şəxsiyyəti təsdiqləmədən balansı doldura və mərc edə bilərsiniz. 1xBet iPhone tətbiqi 196MB yaddaş və iOS 11.0 və ya daha yüksək tələb edir.

Android-də 1xbet Necə Qurulur?

Qeydiyyatdan keçə, mövcud məlumatları istifadə edərək daxil ola, habelə qumarxanada mərc və ya hər hansı bir qumar oynaya bilərsiniz. Bu anda Android üçün 1xBet tətbiqini yalnız 4.1 və ya daha yüksək bir əməliyyat sistemi olan istifadəçilər yükləyə bilər. Xeyr, şirkət tətbiqi ağıllı telefonlarına quraşdıran istifadəçilərə bonuslar vermir.

Bukmeker kontorunun saytının mobil versiyasında 1x bet Bir çox alternative var, amma etmək üçünMərc etmək üçün qeydiyyat prosedurundan keçməlisiniz. Proqram pul bahisinin miqdarını təhlil edir və digər bahis mağazalarının içərisində vəziyyəti də izləyir. Menyunun alt hissəsində keçmiş oyunların nəticələri, canlı dəstək və ayarlar yerləşdirilib. IPhone tətbiqetməsində 1xbet yükləndikdən sonra bütün üzvlərin eyni nailiyyətləri var. 1xbet Az yukle tətbiqi hələ google play mağazasında olmadığından, 1xbet Azerbaycan yukle saytına daxil olub oradan yükləməlisiniz. Bu şəkildə, lazımlı şərtləri sağlayabiliyorsanız, kuponunuzu ya weil bahisinizi pul çəkmə imkanınız vardır.

Bet Azərbaycan Bukmekeri: Rəsmi Saytın Nəzərdən Keçirilməsi

Yerləşdirilmiş mərclər üçün şirkət “Cash Out” erkən nağdlaşdırma təklif edə bilər. Tez-tez qeydiyyat növləri də daxil olmaqla bir hesab yaratmağın sadə yolları var. 1xbet mobil yükle -də pul çıxarmaq üçün də çoxlu ödəniş metodları mövcuddur. Hesabınıza giriş edib pul çıxarmaq istədiyiniz metodun seçilməli və lazım olan məlumatlar doldurulmalıdır. 1xbet mobil yükle, yeni istifadəçilərə depozit etmələri üçün bonus təklif edir. Bu bonusdan istifadə etmək üçün belə tələblər olacaq ki, bonusun qaytarılması üçün tələbə məbləği üzləşən məbləğin 5 dəfəsi qədər olmalıdır.

Mobil Choix Səhifə Şirkət məzmununa və az qala bütün bahis xidmətlərinə mobil cihazlar üzərindən gedə bilərsiniz. Beləcə, yeni üzvlərə verilən ilk 1000 AZN depozit bonusu yerinə 1300 TLə qədər% 200 Hoşgeldin bonusu alacaqsınız. 1XBET Promosyon Kodu Necə istifadə 1XBET araşdırma sualları cavabını məqaləmizdə tapadera bilərsiniz. Xeyr, mərc saytı mobil istifadəçilər üçün xüsusi bonus kampaniyasına sahib deyil. Həmçinin, mobil tətbiq sayəsində canlı bahis oynamaq da mümkündür.

(function () { var searchreplace = (function () { 'use strict'; var Cell = function (initial) { var value = initial; var get = function () { return value; }; var set = function (v) { value = v; }; var clone = function () { return Cell(get()); }; return { get: get, set: set, clone: clone }; }; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var global$1 = tinymce.util.Tools.resolve('tinymce.util.Tools'); function isContentEditableFalse(node) { return node && node.nodeType === 1 && node.contentEditable === 'false'; } function findAndReplaceDOMText(regex, node, replacementNode, captureGroup, schema) { var m; var matches = []; var text, count = 0, doc; var blockElementsMap, hiddenTextElementsMap, shortEndedElementsMap; doc = node.ownerDocument; blockElementsMap = schema.getBlockElements(); hiddenTextElementsMap = schema.getWhiteSpaceElements(); shortEndedElementsMap = schema.getShortEndedElements(); function getMatchIndexes(m, captureGroup) { captureGroup = captureGroup || 0; if (!m[0]) { throw new Error('findAndReplaceDOMText cannot handle zero-length matches'); } var index = m.index; if (captureGroup > 0) { var cg = m[captureGroup]; if (!cg) { throw new Error('Invalid capture group'); } index += m[0].indexOf(cg); m[0] = cg; } return [ index, index + m[0].length, [m[0]] ]; } function getText(node) { var txt; if (node.nodeType === 3) { return node.data; } if (hiddenTextElementsMap[node.nodeName] && !blockElementsMap[node.nodeName]) { return ''; } txt = ''; if (isContentEditableFalse(node)) { return '\n'; } if (blockElementsMap[node.nodeName] || shortEndedElementsMap[node.nodeName]) { txt += '\n'; } if (node = node.firstChild) { do { txt += getText(node); } while (node = node.nextSibling); } return txt; } function stepThroughMatches(node, matches, replaceFn) { var startNode, endNode, startNodeIndex, endNodeIndex, innerNodes = [], atIndex = 0, curNode = node, matchLocation = matches.shift(), matchIndex = 0; out: while (true) { if (blockElementsMap[curNode.nodeName] || shortEndedElementsMap[curNode.nodeName] || isContentEditableFalse(curNode)) { atIndex++; } if (curNode.nodeType === 3) { if (!endNode && curNode.length + atIndex >= matchLocation[1]) { endNode = curNode; endNodeIndex = matchLocation[1] - atIndex; } else if (startNode) { innerNodes.push(curNode); } if (!startNode && curNode.length + atIndex > matchLocation[0]) { startNode = curNode; startNodeIndex = matchLocation[0] - atIndex; } atIndex += curNode.length; } if (startNode && endNode) { curNode = replaceFn({ startNode: startNode, startNodeIndex: startNodeIndex, endNode: endNode, endNodeIndex: endNodeIndex, innerNodes: innerNodes, match: matchLocation[2], matchIndex: matchIndex }); atIndex -= endNode.length - endNodeIndex; startNode = null; endNode = null; innerNodes = []; matchLocation = matches.shift(); matchIndex++; if (!matchLocation) { break; } } else if ((!hiddenTextElementsMap[curNode.nodeName] || blockElementsMap[curNode.nodeName]) && curNode.firstChild) { if (!isContentEditableFalse(curNode)) { curNode = curNode.firstChild; continue; } } else if (curNode.nextSibling) { curNode = curNode.nextSibling; continue; } while (true) { if (curNode.nextSibling) { curNode = curNode.nextSibling; break; } else if (curNode.parentNode !== node) { curNode = curNode.parentNode; } else { break out; } } } } function genReplacer(nodeName) { var makeReplacementNode; if (typeof nodeName !== 'function') { var stencilNode_1 = nodeName.nodeType ? nodeName : doc.createElement(nodeName); makeReplacementNode = function (fill, matchIndex) { var clone = stencilNode_1.cloneNode(false); clone.setAttribute('data-mce-index', matchIndex); if (fill) { clone.appendChild(doc.createTextNode(fill)); } return clone; }; } else { makeReplacementNode = nodeName; } return function (range) { var before; var after; var parentNode; var startNode = range.startNode; var endNode = range.endNode; var matchIndex = range.matchIndex; if (startNode === endNode) { var node_1 = startNode; parentNode = node_1.parentNode; if (range.startNodeIndex > 0) { before = doc.createTextNode(node_1.data.substring(0, range.startNodeIndex)); parentNode.insertBefore(before, node_1); } var el = makeReplacementNode(range.match[0], matchIndex); parentNode.insertBefore(el, node_1); if (range.endNodeIndex < node_1.length) { after = doc.createTextNode(node_1.data.substring(range.endNodeIndex)); parentNode.insertBefore(after, node_1); } node_1.parentNode.removeChild(node_1); return el; } before = doc.createTextNode(startNode.data.substring(0, range.startNodeIndex)); after = doc.createTextNode(endNode.data.substring(range.endNodeIndex)); var elA = makeReplacementNode(startNode.data.substring(range.startNodeIndex), matchIndex); for (var i = 0, l = range.innerNodes.length; i < l; ++i) { var innerNode = range.innerNodes[i]; var innerEl = makeReplacementNode(innerNode.data, matchIndex); innerNode.parentNode.replaceChild(innerEl, innerNode); } var elB = makeReplacementNode(endNode.data.substring(0, range.endNodeIndex), matchIndex); parentNode = startNode.parentNode; parentNode.insertBefore(before, startNode); parentNode.insertBefore(elA, startNode); parentNode.removeChild(startNode); parentNode = endNode.parentNode; parentNode.insertBefore(elB, endNode); parentNode.insertBefore(after, endNode); parentNode.removeChild(endNode); return elB; }; } text = getText(node); if (!text) { return; } if (regex.global) { while (m = regex.exec(text)) { matches.push(getMatchIndexes(m, captureGroup)); } } else { m = text.match(regex); matches.push(getMatchIndexes(m, captureGroup)); } if (matches.length) { count = matches.length; stepThroughMatches(node, matches, genReplacer(replacementNode)); } return count; } var FindReplaceText = { findAndReplaceDOMText: findAndReplaceDOMText }; var getElmIndex = function (elm) { var value = elm.getAttribute('data-mce-index'); if (typeof value === 'number') { return '' + value; } return value; }; var markAllMatches = function (editor, currentIndexState, regex) { var node, marker; marker = editor.dom.create('span', { 'data-mce-bogus': 1 }); marker.className = 'mce-match-marker'; node = editor.getBody(); done(editor, currentIndexState, false); return FindReplaceText.findAndReplaceDOMText(regex, node, marker, false, editor.schema); }; var unwrap = function (node) { var parentNode = node.parentNode; if (node.firstChild) { parentNode.insertBefore(node.firstChild, node); } node.parentNode.removeChild(node); }; var findSpansByIndex = function (editor, index) { var nodes; var spans = []; nodes = global$1.toArray(editor.getBody().getElementsByTagName('span')); if (nodes.length) { for (var i = 0; i < nodes.length; i++) { var nodeIndex = getElmIndex(nodes[i]); if (nodeIndex === null || !nodeIndex.length) { continue; } if (nodeIndex === index.toString()) { spans.push(nodes[i]); } } } return spans; }; var moveSelection = function (editor, currentIndexState, forward) { var testIndex = currentIndexState.get(); var dom = editor.dom; forward = forward !== false; if (forward) { testIndex++; } else { testIndex--; } dom.removeClass(findSpansByIndex(editor, currentIndexState.get()), 'mce-match-marker-selected'); var spans = findSpansByIndex(editor, testIndex); if (spans.length) { dom.addClass(findSpansByIndex(editor, testIndex), 'mce-match-marker-selected'); editor.selection.scrollIntoView(spans[0]); return testIndex; } return -1; }; var removeNode = function (dom, node) { var parent = node.parentNode; dom.remove(node); if (dom.isEmpty(parent)) { dom.remove(parent); } }; var find = function (editor, currentIndexState, text, matchCase, wholeWord) { text = text.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&'); text = text.replace(/\s/g, '[^\\S\\r\\n]'); text = wholeWord ? '\\b' + text + '\\b' : text; var count = markAllMatches(editor, currentIndexState, new RegExp(text, matchCase ? 'g' : 'gi')); if (count) { currentIndexState.set(-1); currentIndexState.set(moveSelection(editor, currentIndexState, true)); } return count; }; var next = function (editor, currentIndexState) { var index = moveSelection(editor, currentIndexState, true); if (index !== -1) { currentIndexState.set(index); } }; var prev = function (editor, currentIndexState) { var index = moveSelection(editor, currentIndexState, false); if (index !== -1) { currentIndexState.set(index); } }; var isMatchSpan = function (node) { var matchIndex = getElmIndex(node); return matchIndex !== null && matchIndex.length > 0; }; var replace = function (editor, currentIndexState, text, forward, all) { var i, nodes, node, matchIndex, currentMatchIndex, nextIndex = currentIndexState.get(), hasMore; forward = forward !== false; node = editor.getBody(); nodes = global$1.grep(global$1.toArray(node.getElementsByTagName('span')), isMatchSpan); for (i = 0; i < nodes.length; i++) { var nodeIndex = getElmIndex(nodes[i]); matchIndex = currentMatchIndex = parseInt(nodeIndex, 10); if (all || matchIndex === currentIndexState.get()) { if (text.length) { nodes[i].firstChild.nodeValue = text; unwrap(nodes[i]); } else { removeNode(editor.dom, nodes[i]); } while (nodes[++i]) { matchIndex = parseInt(getElmIndex(nodes[i]), 10); if (matchIndex === currentMatchIndex) { removeNode(editor.dom, nodes[i]); } else { i--; break; } } if (forward) { nextIndex--; } } else if (currentMatchIndex > currentIndexState.get()) { nodes[i].setAttribute('data-mce-index', currentMatchIndex - 1); } } currentIndexState.set(nextIndex); if (forward) { hasMore = hasNext(editor, currentIndexState); next(editor, currentIndexState); } else { hasMore = hasPrev(editor, currentIndexState); prev(editor, currentIndexState); } return !all && hasMore; }; var done = function (editor, currentIndexState, keepEditorSelection) { var i, nodes, startContainer, endContainer; nodes = global$1.toArray(editor.getBody().getElementsByTagName('span')); for (i = 0; i < nodes.length; i++) { var nodeIndex = getElmIndex(nodes[i]); if (nodeIndex !== null && nodeIndex.length) { if (nodeIndex === currentIndexState.get().toString()) { if (!startContainer) { startContainer = nodes[i].firstChild; } endContainer = nodes[i].firstChild; } unwrap(nodes[i]); } } if (startContainer && endContainer) { var rng = editor.dom.createRng(); rng.setStart(startContainer, 0); rng.setEnd(endContainer, endContainer.data.length); if (keepEditorSelection !== false) { editor.selection.setRng(rng); } return rng; } }; var hasNext = function (editor, currentIndexState) { return findSpansByIndex(editor, currentIndexState.get() + 1).length > 0; }; var hasPrev = function (editor, currentIndexState) { return findSpansByIndex(editor, currentIndexState.get() - 1).length > 0; }; var Actions = { done: done, find: find, next: next, prev: prev, replace: replace, hasNext: hasNext, hasPrev: hasPrev }; var get = function (editor, currentIndexState) { var done = function (keepEditorSelection) { return Actions.done(editor, currentIndexState, keepEditorSelection); }; var find = function (text, matchCase, wholeWord) { return Actions.find(editor, currentIndexState, text, matchCase, wholeWord); }; var next = function () { return Actions.next(editor, currentIndexState); }; var prev = function () { return Actions.prev(editor, currentIndexState); }; var replace = function (text, forward, all) { return Actions.replace(editor, currentIndexState, text, forward, all); }; return { done: done, find: find, next: next, prev: prev, replace: replace }; }; var Api = { get: get }; var open = function (editor, currentIndexState) { var last = {}, selectedText; editor.undoManager.add(); selectedText = global$1.trim(editor.selection.getContent({ format: 'text' })); function updateButtonStates() { win.statusbar.find('#next').disabled(Actions.hasNext(editor, currentIndexState) === false); win.statusbar.find('#prev').disabled(Actions.hasPrev(editor, currentIndexState) === false); } function notFoundAlert() { editor.windowManager.alert('Could not find the specified string.', function () { win.find('#find')[0].focus(); }); } var win = editor.windowManager.open({ layout: 'flex', pack: 'center', align: 'center', onClose: function () { editor.focus(); Actions.done(editor, currentIndexState); editor.undoManager.add(); }, onSubmit: function (e) { var count, caseState, text, wholeWord; e.preventDefault(); caseState = win.find('#case').checked(); wholeWord = win.find('#words').checked(); text = win.find('#find').value(); if (!text.length) { Actions.done(editor, currentIndexState, false); win.statusbar.items().slice(1).disabled(true); return; } if (last.text === text && last.caseState === caseState && last.wholeWord === wholeWord) { if (!Actions.hasNext(editor, currentIndexState)) { notFoundAlert(); return; } Actions.next(editor, currentIndexState); updateButtonStates(); return; } count = Actions.find(editor, currentIndexState, text, caseState, wholeWord); if (!count) { notFoundAlert(); } win.statusbar.items().slice(1).disabled(count === 0); updateButtonStates(); last = { text: text, caseState: caseState, wholeWord: wholeWord }; }, buttons: [ { text: 'Find', subtype: 'primary', onclick: function () { win.submit(); } }, { text: 'Replace', disabled: true, onclick: function () { if (!Actions.replace(editor, currentIndexState, win.find('#replace').value())) { win.statusbar.items().slice(1).disabled(true); currentIndexState.set(-1); last = {}; } } }, { text: 'Replace all', disabled: true, onclick: function () { Actions.replace(editor, currentIndexState, win.find('#replace').value(), true, true); win.statusbar.items().slice(1).disabled(true); last = {}; } }, { type: 'spacer', flex: 1 }, { text: 'Prev', name: 'prev', disabled: true, onclick: function () { Actions.prev(editor, currentIndexState); updateButtonStates(); } }, { text: 'Next', name: 'next', disabled: true, onclick: function () { Actions.next(editor, currentIndexState); updateButtonStates(); } } ], title: 'Find and replace', items: { type: 'form', padding: 20, labelGap: 30, spacing: 10, items: [ { type: 'textbox', name: 'find', size: 40, label: 'Find', value: selectedText }, { type: 'textbox', name: 'replace', size: 40, label: 'Replace with' }, { type: 'checkbox', name: 'case', text: 'Match case', label: ' ' }, { type: 'checkbox', name: 'words', text: 'Whole words', label: ' ' } ] } }); }; var Dialog = { open: open }; var register = function (editor, currentIndexState) { editor.addCommand('SearchReplace', function () { Dialog.open(editor, currentIndexState); }); }; var Commands = { register: register }; var showDialog = function (editor, currentIndexState) { return function () { Dialog.open(editor, currentIndexState); }; }; var register$1 = function (editor, currentIndexState) { editor.addMenuItem('searchreplace', { text: 'Find and replace', shortcut: 'Meta+F', onclick: showDialog(editor, currentIndexState), separator: 'before', context: 'edit' }); editor.addButton('searchreplace', { tooltip: 'Find and replace', onclick: showDialog(editor, currentIndexState) }); editor.shortcuts.add('Meta+F', '', showDialog(editor, currentIndexState)); }; var Buttons = { register: register$1 }; global.add('searchreplace', function (editor) { var currentIndexState = Cell(-1); Commands.register(editor, currentIndexState); Buttons.register(editor, currentIndexState); return Api.get(editor, currentIndexState); }); function Plugin () { } return Plugin; }()); })();