/* Точка входа: монтируем Shell в #root, обёрнутый общим стором. Babel ждёт загрузки всех text/babel скриптов? Нет — поэтому стартуем из последнего скрипта, когда RD.modules.Shell уже определён. */ (function () { var attempts = 0; var maxAttempts = 100; function boot() { attempts++; // Debug logging if (attempts === 1 || attempts % 10 === 0) { console.log('[boot] Attempt ' + attempts + ':', { hasRD: !!window.RD, hasShell: !!(window.RD && window.RD.modules && window.RD.modules.Shell), hasStoreProvider: !!(window.RD && window.RD.core && window.RD.core.StoreProvider), hasReact: typeof React !== 'undefined', hasReactDOM: typeof ReactDOM !== 'undefined' }); } if (attempts > maxAttempts) { console.error('[boot] FAILED after ' + maxAttempts + ' attempts'); document.getElementById('root').innerHTML = '
' + '

❌ Ошибка загрузки

' + '

Не удалось загрузить модули. Откройте консоль (F12) для деталей.

' + '
'; return; } if (!window.RD || !RD.modules.Shell || !RD.core.StoreProvider) { return setTimeout(boot, 30); } console.log('[boot] SUCCESS! Mounting app...'); var root = ReactDOM.createRoot(document.getElementById('root')); root.render(React.createElement(RD.core.StoreProvider, null, React.createElement(RD.modules.Shell))); } boot(); })(); /* === Как встроить ОДИН модуль в другую вашу страницу ===
... perms, store, Estimate ... Каждый модуль самодостаточен: данные/права/тема — из общего стора. */