МУРОМ является долговечным игровым редактором, работающим в браузере | MUROM is a durable game editor working in a browser http://opengamestudio.org/murom
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

766 lines
26KB

  1. /*
  2. *
  3. * Внешний вид
  4. *
  5. */
  6. function задатьВнешнийВид()
  7. {
  8. var вид = document.createElement("style");
  9. document.head.appendChild(вид);
  10. вид.innerHTML =
  11. `
  12. .муром-кнопка
  13. {
  14. padding: 0.5em 2em 0.5em 2em;
  15. margin-right: 0.5em;
  16. float: right;
  17. color: #222;
  18. font-family: sans-serif;
  19. border: 1px solid #ddd;
  20. background-color: transparent;
  21. cursor: pointer;
  22. text-transform: uppercase;
  23. -webkit-transition-duration: 0.2s; /* Safari */
  24. transition-duration: 0.2s;
  25. }
  26. .муром-кнопка:hover
  27. {
  28. border: 1px solid #222;
  29. }
  30. .муром-отступ-по-сторонам
  31. {
  32. margin-left: 0.5em;
  33. margin-right: 0.5em;
  34. }
  35. `;
  36. }
  37. /*
  38. *
  39. * Список модулей
  40. *
  41. */
  42. function СписокМодулей()
  43. {
  44. var я = this;
  45. this.создатьИнтерфейс();
  46. this.задатьВид();
  47. this.выбрали = new Уведомитель();
  48. this.выбрали.подписать(function(){
  49. я.отобразитьВыбор();
  50. });
  51. }
  52. СписокМодулей.prototype.создатьИнтерфейс = function()
  53. {
  54. // Помещаем таблицу в div для реализации промотки.
  55. this.иф = document.createElement("div");
  56. this.таблица = document.createElement("table");
  57. this.иф.appendChild(this.таблица);
  58. };
  59. СписокМодулей.prototype.задатьВид = function()
  60. {
  61. this.иф.style.cssText =
  62. `
  63. overflow: auto;
  64. height: 18.5em;
  65. border: 1px solid #ddd;
  66. /*
  67. padding: 0.5em;
  68. margin: 0.5em;
  69. */
  70. `;
  71. this.таблица.style.cssText =
  72. `
  73. color: #666666;
  74. font-family: sans-serif;
  75. cursor: default;
  76. border-collapse: collapse;
  77. `;
  78. };
  79. СписокМодулей.prototype.очистить = function()
  80. {
  81. while (this.таблица.rows.length)
  82. {
  83. this.таблица.deleteRow(0);
  84. };
  85. };
  86. СписокМодулей.prototype.добавитьЭлемент = function(статус, имя)
  87. {
  88. var статусHTML = "";
  89. if (статус)
  90. {
  91. статусHTML = "checked";
  92. }
  93. var ряд = this.таблица.insertRow();
  94. var ячейка = 0;
  95. var номер = ряд.insertCell(ячейка++);
  96. номер.innerHTML = this.таблица.rows.length - 1;
  97. номер.style.cssText = "padding: 0.5em;";
  98. var вкл = ряд.insertCell(ячейка++);
  99. вкл.innerHTML = `<input type="checkbox" disabled ` + статусHTML + `></input>`;
  100. var название = ряд.insertCell(ячейка++);
  101. название.innerHTML = имя;
  102. название.style.cssText = "padding: 0.5em; width: 100%;";
  103. };
  104. СписокМодулей.prototype.отобразитьСписок = function(список)
  105. {
  106. this.очистить();
  107. for (var номер in список)
  108. {
  109. var элемент = список[номер];
  110. var статус = элемент[0];
  111. var имя = элемент[1];
  112. this.добавитьЭлемент(статус, имя);
  113. }
  114. };
  115. СписокМодулей.prototype.улавливатьВыборЭлемента = function(номер)
  116. {
  117. var я = this;
  118. var ряд = this.таблица.rows[номер]
  119. ряд.onclick = function()
  120. {
  121. я.выборРанее = я.выбор;
  122. я.выбор = номер;
  123. я.выбрали.уведомить();
  124. };
  125. };
  126. СписокМодулей.prototype.улавливатьВыбор = function()
  127. {
  128. this.выборРанее = null;
  129. this.выбор = null;
  130. for (var номер = 0; номер < this.таблица.rows.length; ++номер)
  131. {
  132. this.улавливатьВыборЭлемента(номер);
  133. }
  134. };
  135. СписокМодулей.prototype.отобразитьВыбор = function()
  136. {
  137. if (this.выборРанее != null)
  138. {
  139. var ряд = this.таблица.rows[this.выборРанее];
  140. ряд.style.backgroundColor = null;
  141. }
  142. var ряд = this.таблица.rows[this.выбор];
  143. ряд.style.backgroundColor = "#eee";
  144. };
  145. СписокМодулей.prototype.задатьСписок = function(список)
  146. {
  147. this.отобразитьСписок(список);
  148. this.улавливатьВыбор();
  149. };
  150. СписокМодулей.prototype.выбрать = function(номер)
  151. {
  152. var ряд = this.таблица.rows[номер];
  153. ряд.scrollIntoView();
  154. ряд.onclick();
  155. };
  156. СписокМодулей.prototype.обновитьЭлемент = function(номер, статус, имя)
  157. {
  158. var ряд = this.таблица.rows[номер];
  159. ряд.cells[1].childNodes[0].checked = статус;
  160. ряд.cells[2].innerHTML = имя;
  161. };
  162. СписокМодулей.prototype.удалитьЭлемент = function(номер)
  163. {
  164. var ряд = this.таблица.rows[номер];
  165. ряд.parentNode.removeChild(ряд);
  166. }
  167. /*
  168. *
  169. * Тест списка модулей
  170. *
  171. */
  172. function ТестСпискаМодулей()
  173. {
  174. this.создатьИнтерфейс();
  175. }
  176. ТестСпискаМодулей.prototype.создатьИнтерфейс = function()
  177. {
  178. var я = this;
  179. this.иф = document.createElement("div");
  180. this.список = new СписокМодулей();
  181. this.иф.appendChild(this.список.иф);
  182. var модули = [
  183. [true, "муром.загрузка_1.0.0"],
  184. [true, "муром.uuid_1.0.0"],
  185. [true, "Уведомитель_1.0.0"],
  186. [false, "uikit_3.2.0.css"],
  187. [false, "uikit_3.2.0.js"],
  188. [false, "ПанельУправления.UIKit"],
  189. [false, "ПанельУправления_1.0.0"],
  190. ];
  191. this.список.задатьСписок(модули);
  192. this.список.выбрать(0);
  193. this.создатьКнопку("Выбрать последний", function(){
  194. console.log("выбрать");
  195. я.список.выбрать(модули.length - 1);
  196. });
  197. this.создатьКнопку("Обновить последний", function(){
  198. я.список.обновитьЭлемент(модули.length - 1, true, "Новое имя");
  199. });
  200. this.создатьКнопку("Удалить последний", function(){
  201. я.список.удалитьЭлемент(модули.length - 1);
  202. });
  203. this.создатьКнопку("Добавить", function(){
  204. я.список.добавитьЭлемент(true, "Новый-599");
  205. var номер = я.список.таблица.rows.length - 1;
  206. я.список.улавливатьВыборЭлемента(номер);
  207. я.список.выбрать(номер);
  208. });
  209. };
  210. ТестСпискаМодулей.prototype.создатьКнопку = function(имя, реакция)
  211. {
  212. var кнопка = document.createElement("button");
  213. кнопка.innerHTML = имя;
  214. this.иф.appendChild(кнопка);
  215. кнопка.onclick = реакция;
  216. };
  217. /*
  218. *
  219. * Свойства модуля
  220. *
  221. */
  222. function СвойстваМодуля()
  223. {
  224. this.создатьИнтерфейс();
  225. this.изменилиНомер = new Уведомитель();
  226. this.настроитьНомер();
  227. this.изменилиИмя = new Уведомитель();
  228. this.настроитьИмя();
  229. this.изменилиСтатус = new Уведомитель();
  230. this.настроитьСтатус();
  231. this.удалить = new Уведомитель();
  232. this.настроитьУдаление();
  233. }
  234. СвойстваМодуля.prototype.создатьИнтерфейс = function()
  235. {
  236. this.иф = document.createElement("div");
  237. this.иф.style.cssText =
  238. `
  239. border: 1px solid #ddd;
  240. /*
  241. padding: 0.5em;
  242. margin: 0.5em;
  243. */
  244. color: #666666;
  245. font-family: sans-serif;
  246. `;
  247. this.таблица = document.createElement("table");
  248. this.иф.appendChild(this.таблица);
  249. };
  250. Object.defineProperty(СвойстваМодуля.prototype, "номер", {
  251. get: function()
  252. {
  253. return Number(this.полеНомер.value);
  254. },
  255. set: function(значение)
  256. {
  257. this.полеНомер.value = значение;
  258. }
  259. });
  260. СвойстваМодуля.prototype.настроитьНомер = function()
  261. {
  262. var я = this;
  263. var ряд = this.таблица.insertRow();
  264. var ячейка = 0;
  265. var ключ = ряд.insertCell(ячейка++);
  266. ключ.innerHTML = "Номер:";
  267. ключ.style.cssText = "padding: 0.5em;";
  268. var значение = ряд.insertCell(ячейка++);
  269. this.полеНомер = document.createElement("input");
  270. this.полеНомер.type = "number";
  271. this.полеНомер.min = 0;
  272. значение.style.cssText = "width: 100%; padding: 0.5em;";
  273. this.полеНомер.style.cssText = "width: 100%;";
  274. значение.appendChild(this.полеНомер);
  275. this.полеНомер.oninput = function()
  276. {
  277. я.изменилиНомер.уведомить();
  278. };
  279. };
  280. Object.defineProperty(СвойстваМодуля.prototype, "имя", {
  281. get: function()
  282. {
  283. return this.полеИмя.value;
  284. },
  285. set: function(значение)
  286. {
  287. this.полеИмя.value = значение;
  288. }
  289. });
  290. СвойстваМодуля.prototype.настроитьИмя = function()
  291. {
  292. var я = this;
  293. var ряд = this.таблица.insertRow();
  294. var ячейка = 0;
  295. var ключ = ряд.insertCell(ячейка++);
  296. ключ.innerHTML = "Имя:";
  297. ключ.style.cssText = "padding: 0.5em;";
  298. var значение = ряд.insertCell(ячейка++);
  299. this.полеИмя = document.createElement("input");
  300. значение.style.cssText = "width: 100%; padding: 0.5em;";
  301. this.полеИмя.style.cssText = "width: 100%;";
  302. значение.appendChild(this.полеИмя);
  303. this.полеИмя.oninput = function()
  304. {
  305. я.изменилиИмя.уведомить();
  306. };
  307. };
  308. Object.defineProperty(СвойстваМодуля.prototype, "статус", {
  309. get: function()
  310. {
  311. return this.переключатель.checked;
  312. },
  313. set: function(значение)
  314. {
  315. this.переключатель.checked = значение;
  316. }
  317. });
  318. СвойстваМодуля.prototype.настроитьСтатус = function()
  319. {
  320. var я = this;
  321. var ряд = this.таблица.insertRow();
  322. var ячейка = 0;
  323. var ключ = ряд.insertCell(ячейка++);
  324. ключ.innerHTML = "Исполнять:";
  325. ключ.style.cssText = "padding: 0.5em;";
  326. var значение = ряд.insertCell(ячейка++);
  327. this.переключатель = document.createElement("input");
  328. this.переключатель.type = "checkbox";
  329. this.переключатель.style.cssText = "padding: 0.5em;";
  330. значение.appendChild(this.переключатель);
  331. this.переключатель.onchange = function()
  332. {
  333. я.изменилиСтатус.уведомить();
  334. };
  335. ключ.onclick = function()
  336. {
  337. я.переключатель.checked = !я.переключатель.checked;
  338. я.изменилиСтатус.уведомить();
  339. };
  340. };
  341. СвойстваМодуля.prototype.настроитьУдаление = function()
  342. {
  343. var я = this;
  344. var ряд = this.таблица.insertRow();
  345. var ячейка = 0;
  346. ряд.insertCell(ячейка++);
  347. var значение = ряд.insertCell(ячейка++);
  348. this.кнопкаУдалить = document.createElement("button");
  349. this.кнопкаУдалить.innerHTML = "Удалить";
  350. this.кнопкаУдалить.classList.add("муром-кнопка");
  351. значение.appendChild(this.кнопкаУдалить);
  352. this.кнопкаУдалить.onclick = function()
  353. {
  354. я.удалить.уведомить();
  355. };
  356. };
  357. /*
  358. *
  359. * Тест свойства модуля
  360. *
  361. */
  362. function ТестСвойстваМодуля()
  363. {
  364. this.создатьИнтерфейс();
  365. }
  366. ТестСвойстваМодуля.prototype.создатьИнтерфейс = function()
  367. {
  368. var я = this;
  369. this.иф = document.createElement("div");
  370. this.свойства = new СвойстваМодуля();
  371. this.иф.appendChild(this.свойства.иф);
  372. this.свойства.изменилиНомер.подписать(function(){
  373. console.log("номер: '" + я.свойства.номер + "'");
  374. });
  375. this.свойства.изменилиИмя.подписать(function(){
  376. console.log("имя: '" + я.свойства.имя + "'");
  377. });
  378. this.свойства.изменилиСтатус.подписать(function(){
  379. console.log("статус: '" + я.свойства.статус + "'");
  380. });
  381. this.свойства.удалить.подписать(function(){
  382. console.log("удалить модуль '" + я.свойства.имя + "'");
  383. });
  384. };
  385. /*
  386. *
  387. * Модули
  388. *
  389. */
  390. function Модули()
  391. {
  392. }
  393. Модули.prototype.свойства = function(номер)
  394. {
  395. return murom.moduleProperties(номер);
  396. };
  397. Модули.prototype.задатьСвойства = function(номер, свойства)
  398. {
  399. var м = муром.модули[номер];
  400. м[2] = свойства;
  401. };
  402. Модули.prototype.статус = function(номер)
  403. {
  404. return murom.moduleStatus(номер);
  405. };
  406. Модули.prototype.задатьСтатус = function(номер, статус)
  407. {
  408. var св = this.свойства(номер);
  409. св["status"] = статус;
  410. this.задатьСвойства(номер, св);
  411. };
  412. Модули.prototype.задатьИмя = function(номер, имя)
  413. {
  414. var м = муром.модули[номер];
  415. м[0] = имя;
  416. };
  417. Модули.prototype.задатьНомер = function(старый, новый)
  418. {
  419. //console.log("задать номер. '" + старый + "' -> '" + новый + "'");
  420. var модуль = муром.модули[старый];
  421. // Удаляем старую запись.
  422. муром.модули.splice(старый, 1);
  423. // Добавляем модуль в новую позицию.
  424. муром.модули.splice(новый, 0, модуль);
  425. };
  426. /*
  427. *
  428. * Панель управления
  429. *
  430. */
  431. function ПанельУправления()
  432. {
  433. this.модули = new Модули();
  434. this.создатьОснову();
  435. this.создатьСохранениеСкачиваниеДобавление();
  436. this.создатьСписокМодулей();
  437. this.создатьСвойстваМодуля();
  438. }
  439. ПанельУправления.prototype.создатьОбёрткуЯчейку = function()
  440. {
  441. var обёртка = document.createElement("table");
  442. обёртка.style.cssText = "width: 100%;";
  443. var ряд = обёртка.insertRow();
  444. var ячейка = ряд.insertCell();
  445. return [обёртка, ячейка];
  446. };
  447. ПанельУправления.prototype.создатьОснову = function()
  448. {
  449. this.иф = document.createElement("table");
  450. this.иф.style.cssText = "width: 100%;";
  451. var ряд = this.иф.insertRow();
  452. this.лево = ряд.insertCell();
  453. this.лево.style.cssText = "width: 100%;";
  454. var право = ряд.insertCell();
  455. право.style.cssText = "height: 100%;";
  456. this.кнопки = document.createElement("table");
  457. this.кнопки.style.cssText = "height: 100%;";
  458. право.appendChild(this.кнопки);
  459. ряд = this.иф.insertRow();
  460. this.низ = ряд.insertCell();
  461. this.низ.colSpan = 2;
  462. };
  463. ПанельУправления.prototype.создатьСписокМодулей = function()
  464. {
  465. this.список = new СписокМодулей();
  466. this.список.задатьСписок(this.списокМодулей());
  467. var оя = this.создатьОбёрткуЯчейку();
  468. this.лево.appendChild(оя[0]);
  469. оя[1].appendChild(this.список.иф);
  470. };
  471. ПанельУправления.prototype.создатьСвойстваМодуля = function()
  472. {
  473. this.свойства = new СвойстваМодуля();
  474. оя = this.создатьОбёрткуЯчейку();
  475. this.низ.appendChild(оя[0]);
  476. оя[1].appendChild(this.свойства.иф);
  477. };
  478. ПанельУправления.prototype.списокМодулей = function()
  479. {
  480. var список = [];
  481. for (var номер in муром.модули)
  482. {
  483. var м = муром.модули[номер];
  484. var статус = this.модули.статус(номер);
  485. var имя = м[0];
  486. var элемент = [статус, имя];
  487. список.push(элемент);
  488. }
  489. return список;
  490. };
  491. ПанельУправления.prototype.создатьКнопку = function(имя, уведомитель)
  492. {
  493. var кнопка = document.createElement("button");
  494. кнопка.innerHTML = имя;
  495. кнопка.style.cssText = "width: 100%;";
  496. кнопка.classList.add("муром-кнопка");
  497. кнопка.onclick = function()
  498. {
  499. уведомитель.уведомить();
  500. };
  501. return кнопка;
  502. };
  503. ПанельУправления.prototype.создатьСохранениеСкачиваниеДобавление = function()
  504. {
  505. var я = this;
  506. var ряд = this.кнопки.insertRow();
  507. var ячейка = ряд.insertCell();
  508. this.сохранить = new Уведомитель();
  509. this.кнопкаСохранить = this.создатьКнопку("Сохранить", this.сохранить);
  510. ячейка.appendChild(this.кнопкаСохранить);
  511. ряд = this.кнопки.insertRow();
  512. ячейка = ряд.insertCell();
  513. this.скачать = new Уведомитель();
  514. this.кнопкаСкачать = this.создатьКнопку("Скачать", this.скачать);
  515. ячейка.appendChild(this.кнопкаСкачать);
  516. // Пробел.
  517. ряд = this.кнопки.insertRow();
  518. ячейка = ряд.insertCell();
  519. ячейка.style.cssText = "height: 100%;";
  520. ряд = this.кнопки.insertRow();
  521. ячейка = ряд.insertCell();
  522. this.добавить = new Уведомитель();
  523. this.кнопкаДобавить = this.создатьКнопку("Добавить", this.добавить);
  524. ячейка.appendChild(this.кнопкаДобавить);
  525. };
  526. ПанельУправления.prototype.имяФайла = function()
  527. {
  528. var путь = window.location.pathname;
  529. var имя = путь.split("/").pop();
  530. return decodeURI(имя);
  531. };
  532. function запуститьПУ()
  533. {
  534. var пу = new ПанельУправления();
  535. муром.пу = пу;
  536. var области = муром.создатьЛевуюПравуюОбласти();
  537. var по = области[1];
  538. по.appendChild(пу.иф);
  539. муром.создатьРедакторВЛевойОбласти();
  540. var список = пу.список;
  541. var свойства = пу.свойства;
  542. var модули = пу.модули;
  543. function отобразитьКодВыбранногоМодуля()
  544. {
  545. var модуль = муром.модули[список.выбор];
  546. var код = муром.atob(модуль[1]);
  547. муром.редактор.session.setValue(код);
  548. }
  549. function отобразитьСвойстваВыбранногоМодуля()
  550. {
  551. var модуль = муром.модули[список.выбор];
  552. свойства.номер = список.выбор;
  553. свойства.имя = модуль[0];
  554. свойства.статус = пу.модули.статус(список.выбор);
  555. }
  556. список.выбрали.подписатьМного([
  557. отобразитьКодВыбранногоМодуля,
  558. отобразитьСвойстваВыбранногоМодуля,
  559. ]);
  560. function обновитьСтатусМодуля()
  561. {
  562. var номер = список.выбор;
  563. var имя = свойства.имя;
  564. var статус = свойства.статус;
  565. модули.задатьСтатус(номер, статус);
  566. список.обновитьЭлемент(номер, статус, имя);
  567. }
  568. свойства.изменилиСтатус.подписать(обновитьСтатусМодуля);
  569. function обновитьИмяМодуля()
  570. {
  571. var номер = список.выбор;
  572. var имя = свойства.имя;
  573. var статус = свойства.статус;
  574. модули.задатьИмя(номер, имя);
  575. список.обновитьЭлемент(номер, статус, имя);
  576. }
  577. свойства.изменилиИмя.подписать(обновитьИмяМодуля);
  578. function обновитьНомерМодуля()
  579. {
  580. var старый = список.выбор;
  581. var новый = свойства.номер;
  582. if (старый == новый)
  583. {
  584. return;
  585. }
  586. if (новый > муром.модули.length - 1)
  587. {
  588. новый = муром.модули.length - 1;
  589. }
  590. модули.задатьНомер(старый, новый);
  591. список.задатьСписок(пу.списокМодулей());
  592. список.выбрать(новый);
  593. }
  594. свойства.изменилиНомер.подписать(обновитьНомерМодуля);
  595. function добавитьМодуль()
  596. {
  597. var число = Math.floor(Math.random() * Math.floor(1000));
  598. var имя = "новый-" + число;
  599. var код = `console.log("НАДО Добавить код в модуль '` + имя + `'");`;
  600. var модуль = [имя, муром.btoa(код)];
  601. муром.модули.push(модуль);
  602. var модули = пу.списокМодулей();
  603. список.задатьСписок(модули);
  604. список.выбрать(модули.length - 1);
  605. }
  606. пу.добавить.подписать(добавитьМодуль);
  607. function удалитьМодуль()
  608. {
  609. var номер = список.выбор;
  610. var статус = пу.модули.статус(номер);
  611. if (статус)
  612. {
  613. alert("ОШИБКА Удалить можно лишь неисполняемый модуль");
  614. return;
  615. }
  616. // Удалить выбранный модуль.
  617. муром.модули.splice(номер, 1);
  618. --номер;
  619. if (номер < 0)
  620. {
  621. номер = 0;
  622. }
  623. var модули = пу.списокМодулей();
  624. список.задатьСписок(модули);
  625. список.выбрать(номер);
  626. }
  627. свойства.удалить.подписать(удалитьМодуль);
  628. function сохранитьВыбранныйМодуль()
  629. {
  630. var модуль = муром.модули[список.выбор];
  631. var код = муром.редактор.session.getValue();
  632. модуль[1] = муром.btoa(код);
  633. }
  634. function сохранить()
  635. {
  636. пу.кнопкаСохранить.disabled = true;
  637. localforage.setItem("modules", муром.модули, function(ошибка, значение){
  638. пу.кнопкаСохранить.disabled = false;
  639. if (ошибка)
  640. {
  641. console.error("Не удалось сохранить модули: '" + ошибка + "'");
  642. }
  643. });
  644. }
  645. пу.сохранить.подписатьМного([
  646. сохранитьВыбранныйМодуль,
  647. сохранить,
  648. ]);
  649. // How to create a file in memory for user to download, but not through server?
  650. // https://stackoverflow.com/a/18197341
  651. function скачать()
  652. {
  653. var содержимое = муром.файл.начало;
  654. for (var номер in муром.модули)
  655. {
  656. var модуль = муром.модули[номер];
  657. var имя = модуль[0];
  658. var код64 = модуль[1];
  659. var свойства = модули.свойства(номер);
  660. содержимое +=
  661. `
  662. [
  663. "` + имя + `",
  664. "` + код64 + `",
  665. `
  666. +
  667. JSON.stringify(свойства)
  668. +
  669. `
  670. ],
  671. `
  672. ;
  673. }
  674. содержимое += муром.файл.конец;
  675. содержимое = муром.btoa(содержимое);
  676. var ссыль = document.createElement("a");
  677. ссыль.setAttribute("href", "data:text/html;charset=utf-8;base64," + содержимое);
  678. var имя = пу.имяФайла();
  679. ссыль.setAttribute("download", имя);
  680. ссыль.style.display = "none";
  681. document.body.appendChild(ссыль);
  682. ссыль.click();
  683. document.body.removeChild(ссыль);
  684. }
  685. пу.скачать.подписать(скачать);
  686. // При запуске.
  687. список.выбрать(0);
  688. }
  689. /*
  690. *
  691. * Пуск
  692. *
  693. */
  694. if (window.location.search == "?0")
  695. {
  696. console.debug("Запуск панели управления");
  697. задатьВнешнийВид();
  698. запуститьПУ();
  699. console.debug("Панель управления запущена")
  700. }