databricksedu 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- databricksedu/__init__.py +24 -0
- databricksedu/_content/catalog.json +1923 -0
- databricksedu/_content/nb/agents-tools.json.gz +0 -0
- databricksedu/_content/nb/ai-bi-dashboards.json.gz +0 -0
- databricksedu/_content/nb/ai-functions-gateway.json.gz +0 -0
- databricksedu/_content/nb/asset-bundles-cicd.json.gz +0 -0
- databricksedu/_content/nb/asset-bundles-recap.json.gz +0 -0
- databricksedu/_content/nb/auto-loader-copy-into.json.gz +0 -0
- databricksedu/_content/nb/cdc-data.json.gz +0 -0
- databricksedu/_content/nb/cdc-scd.json.gz +0 -0
- databricksedu/_content/nb/change-data-feed.json.gz +0 -0
- databricksedu/_content/nb/chunking-parsing.json.gz +0 -0
- databricksedu/_content/nb/churn-data.json.gz +0 -0
- databricksedu/_content/nb/data-privacy-recap.json.gz +0 -0
- databricksedu/_content/nb/data-quality-expectations.json.gz +0 -0
- databricksedu/_content/nb/declarative-pipelines-recap.json.gz +0 -0
- databricksedu/_content/nb/declarative-pipelines.json.gz +0 -0
- databricksedu/_content/nb/deletion-vectors.json.gz +0 -0
- databricksedu/_content/nb/delta-acid-concurrency.json.gz +0 -0
- databricksedu/_content/nb/delta-dml-merge.json.gz +0 -0
- databricksedu/_content/nb/delta-optimization.json.gz +0 -0
- databricksedu/_content/nb/delta-sharing.json.gz +0 -0
- databricksedu/_content/nb/delta-table-anatomy.json.gz +0 -0
- databricksedu/_content/nb/delta-time-travel-vacuum.json.gz +0 -0
- databricksedu/_content/nb/delta-transaction-log.json.gz +0 -0
- databricksedu/_content/nb/devops-essentials-recap.json.gz +0 -0
- databricksedu/_content/nb/embeddings-vector-search.json.gz +0 -0
- databricksedu/_content/nb/exam-data-analyst-associate.json.gz +0 -0
- databricksedu/_content/nb/exam-data-engineer-associate.json.gz +0 -0
- databricksedu/_content/nb/exam-data-engineer-professional.json.gz +0 -0
- databricksedu/_content/nb/exam-genai-engineer-associate.json.gz +0 -0
- databricksedu/_content/nb/exam-ml-associate.json.gz +0 -0
- databricksedu/_content/nb/exam-ml-professional.json.gz +0 -0
- databricksedu/_content/nb/exam-spark-developer-associate.json.gz +0 -0
- databricksedu/_content/nb/feature-engineering.json.gz +0 -0
- databricksedu/_content/nb/genai-evaluation.json.gz +0 -0
- databricksedu/_content/nb/genie-spaces.json.gz +0 -0
- databricksedu/_content/nb/hr-data.json.gz +0 -0
- databricksedu/_content/nb/hyperparameter-tuning.json.gz +0 -0
- databricksedu/_content/nb/iot-data.json.gz +0 -0
- databricksedu/_content/nb/lakeflow-connect-recap.json.gz +0 -0
- databricksedu/_content/nb/lakeflow-jobs-recap.json.gz +0 -0
- databricksedu/_content/nb/lakeflow-jobs.json.gz +0 -0
- databricksedu/_content/nb/lakehouse-architecture.json.gz +0 -0
- databricksedu/_content/nb/lineage-system-tables.json.gz +0 -0
- databricksedu/_content/nb/llm-basics.json.gz +0 -0
- databricksedu/_content/nb/medallion-architecture.json.gz +0 -0
- databricksedu/_content/nb/metric-views.json.gz +0 -0
- databricksedu/_content/nb/ml-lifecycle.json.gz +0 -0
- databricksedu/_content/nb/mlflow-tracking.json.gz +0 -0
- databricksedu/_content/nb/model-monitoring.json.gz +0 -0
- databricksedu/_content/nb/model-serving.json.gz +0 -0
- databricksedu/_content/nb/models-in-unity-catalog.json.gz +0 -0
- databricksedu/_content/nb/parquet-files.json.gz +0 -0
- databricksedu/_content/nb/performance-optimization-recap.json.gz +0 -0
- databricksedu/_content/nb/prompt-engineering.json.gz +0 -0
- databricksedu/_content/nb/rag-architecture.json.gz +0 -0
- databricksedu/_content/nb/retail-data.json.gz +0 -0
- databricksedu/_content/nb/row-filters-column-masks.json.gz +0 -0
- databricksedu/_content/nb/schema-enforcement-evolution.json.gz +0 -0
- databricksedu/_content/nb/spark-architecture.json.gz +0 -0
- databricksedu/_content/nb/spark-joins-shuffles.json.gz +0 -0
- databricksedu/_content/nb/sql-warehouses.json.gz +0 -0
- databricksedu/_content/nb/streaming-pipelines-recap.json.gz +0 -0
- databricksedu/_content/nb/structured-streaming-basics.json.gz +0 -0
- databricksedu/_content/nb/support-data.json.gz +0 -0
- databricksedu/_content/nb/uc-privileges.json.gz +0 -0
- databricksedu/_content/nb/unity-catalog-basics.json.gz +0 -0
- databricksedu/_content/nb/watermarks-stateful-streaming.json.gz +0 -0
- databricksedu/_content/web/agents-tools.b64 +1 -0
- databricksedu/_content/web/ai-bi-dashboards.b64 +1 -0
- databricksedu/_content/web/ai-functions-gateway.b64 +1 -0
- databricksedu/_content/web/asset-bundles-cicd.b64 +1 -0
- databricksedu/_content/web/asset-bundles-recap.b64 +1 -0
- databricksedu/_content/web/auto-loader-copy-into.b64 +1 -0
- databricksedu/_content/web/cdc-data.b64 +1 -0
- databricksedu/_content/web/cdc-scd.b64 +1 -0
- databricksedu/_content/web/change-data-feed.b64 +1 -0
- databricksedu/_content/web/chunking-parsing.b64 +1 -0
- databricksedu/_content/web/churn-data.b64 +1 -0
- databricksedu/_content/web/data-privacy-recap.b64 +1 -0
- databricksedu/_content/web/data-quality-expectations.b64 +1 -0
- databricksedu/_content/web/declarative-pipelines-recap.b64 +1 -0
- databricksedu/_content/web/declarative-pipelines.b64 +1 -0
- databricksedu/_content/web/deletion-vectors.b64 +1 -0
- databricksedu/_content/web/delta-acid-concurrency.b64 +1 -0
- databricksedu/_content/web/delta-dml-merge.b64 +1 -0
- databricksedu/_content/web/delta-optimization.b64 +1 -0
- databricksedu/_content/web/delta-sharing.b64 +1 -0
- databricksedu/_content/web/delta-table-anatomy.b64 +1 -0
- databricksedu/_content/web/delta-time-travel-vacuum.b64 +1 -0
- databricksedu/_content/web/delta-transaction-log.b64 +1 -0
- databricksedu/_content/web/devops-essentials-recap.b64 +1 -0
- databricksedu/_content/web/embeddings-vector-search.b64 +1 -0
- databricksedu/_content/web/exam-data-analyst-associate.b64 +1 -0
- databricksedu/_content/web/exam-data-engineer-associate.b64 +1 -0
- databricksedu/_content/web/exam-data-engineer-professional.b64 +1 -0
- databricksedu/_content/web/exam-genai-engineer-associate.b64 +1 -0
- databricksedu/_content/web/exam-ml-associate.b64 +1 -0
- databricksedu/_content/web/exam-ml-professional.b64 +1 -0
- databricksedu/_content/web/exam-spark-developer-associate.b64 +1 -0
- databricksedu/_content/web/feature-engineering.b64 +1 -0
- databricksedu/_content/web/genai-evaluation.b64 +1 -0
- databricksedu/_content/web/genie-spaces.b64 +1 -0
- databricksedu/_content/web/hr-data.b64 +1 -0
- databricksedu/_content/web/hyperparameter-tuning.b64 +1 -0
- databricksedu/_content/web/iot-data.b64 +1 -0
- databricksedu/_content/web/lakeflow-connect-recap.b64 +1 -0
- databricksedu/_content/web/lakeflow-jobs-recap.b64 +1 -0
- databricksedu/_content/web/lakeflow-jobs.b64 +1 -0
- databricksedu/_content/web/lakehouse-architecture.b64 +1 -0
- databricksedu/_content/web/lineage-system-tables.b64 +1 -0
- databricksedu/_content/web/llm-basics.b64 +1 -0
- databricksedu/_content/web/medallion-architecture.b64 +1 -0
- databricksedu/_content/web/metric-views.b64 +1 -0
- databricksedu/_content/web/ml-lifecycle.b64 +1 -0
- databricksedu/_content/web/mlflow-tracking.b64 +1 -0
- databricksedu/_content/web/model-monitoring.b64 +1 -0
- databricksedu/_content/web/model-serving.b64 +1 -0
- databricksedu/_content/web/models-in-unity-catalog.b64 +1 -0
- databricksedu/_content/web/parquet-files.b64 +1 -0
- databricksedu/_content/web/performance-optimization-recap.b64 +1 -0
- databricksedu/_content/web/prompt-engineering.b64 +1 -0
- databricksedu/_content/web/rag-architecture.b64 +1 -0
- databricksedu/_content/web/retail-data.b64 +1 -0
- databricksedu/_content/web/row-filters-column-masks.b64 +1 -0
- databricksedu/_content/web/schema-enforcement-evolution.b64 +1 -0
- databricksedu/_content/web/spark-architecture.b64 +1 -0
- databricksedu/_content/web/spark-joins-shuffles.b64 +1 -0
- databricksedu/_content/web/sql-warehouses.b64 +1 -0
- databricksedu/_content/web/streaming-pipelines-recap.b64 +1 -0
- databricksedu/_content/web/structured-streaming-basics.b64 +1 -0
- databricksedu/_content/web/support-data.b64 +1 -0
- databricksedu/_content/web/uc-privileges.b64 +1 -0
- databricksedu/_content/web/unity-catalog-basics.b64 +1 -0
- databricksedu/_content/web/watermarks-stateful-streaming.b64 +1 -0
- databricksedu/_version.py +1 -0
- databricksedu/app.py +192 -0
- databricksedu/assets/app.css +1 -0
- databricksedu/assets/app.js +353 -0
- databricksedu/assets/dbx.css +1 -0
- databricksedu/assets/quiz.js +47 -0
- databricksedu/assets/viz.css +1 -0
- databricksedu/assets/viz.js +84 -0
- databricksedu/catalog.py +95 -0
- databricksedu/data/__init__.py +58 -0
- databricksedu/data/_core.py +339 -0
- databricksedu/data/cdc.py +75 -0
- databricksedu/data/churn.py +74 -0
- databricksedu/data/hr.py +58 -0
- databricksedu/data/iot.py +86 -0
- databricksedu/data/retail.py +77 -0
- databricksedu/data/support.py +128 -0
- databricksedu/workspace.py +157 -0
- databricksedu-0.1.0.dist-info/METADATA +131 -0
- databricksedu-0.1.0.dist-info/RECORD +158 -0
- databricksedu-0.1.0.dist-info/WHEEL +4 -0
- databricksedu-0.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
html,body{margin:0;padding:0;height:auto;background:transparent}#dbe{--navy:#1B3139;--accent:#FF3621;--blue:#2272B4;--purple:#7C4DFF;--teal:#00A3A1;--bg:#F4F2EE;--muted:#6B7280;--line:#E5E7EB;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;color:#1F2937;background:var(--bg);display:flex;flex-direction:column;border-radius:14px;overflow:hidden;position:relative;border:1px solid #D6D3CD;box-sizing:border-box;width:100%;min-width:0}#dbe *{box-sizing:border-box}#dbe.fs{border-radius:0;border:0;height:100vh!important}#dbe button{font-family:inherit}.top{display:flex;align-items:center;gap:10px;padding:9px 16px;background:var(--navy);color:#fff;flex:none;z-index:5}.brand{display:flex;align-items:center;gap:8px;font-weight:800;letter-spacing:.01em;cursor:pointer;border:0;background:transparent;color:#fff;font-size:15px;padding:4px 6px;border-radius:8px}.brand:hover{background:rgba(255,255,255,.1)}.brand .lg{display:inline-flex;width:26px;height:26px;border-radius:8px;background:linear-gradient(135deg,#FF3621,#7C4DFF);align-items:center;justify-content:center;font-size:15px}.brand em{font-style:normal;color:#FF8A7A}.crumb{color:#94A3B8;font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1;min-width:0}.crumb b{color:#E2E8F0;font-weight:600}.seg{display:inline-flex;background:rgba(255,255,255,.1);border-radius:999px;padding:3px;flex:none}.seg button{border:0;background:transparent;color:#CBD5E1;padding:6px 14px;border-radius:999px;cursor:pointer;font-size:13px;white-space:nowrap}.seg button.on{background:#fff;color:var(--navy);font-weight:700}.hbtn{border:1px solid rgba(255,255,255,.25);background:transparent;color:#E2E8F0;border-radius:8px;padding:6px 10px;cursor:pointer;font-size:13px;white-space:nowrap;flex:none}.hbtn:hover{background:rgba(255,255,255,.12)}.hbtn.pri{background:linear-gradient(135deg,#FF3621,#c2410c);border-color:transparent;color:#fff;font-weight:700}#bar{height:3px;background:linear-gradient(90deg,var(--accent),var(--purple),var(--teal));width:0;transition:width .35s ease;flex:none}#main{flex:1;min-height:0;position:relative;display:flex;flex-direction:column}#home{flex:1;overflow:auto;padding:18px 22px 26px}.hhero{position:relative;overflow:hidden;border-radius:18px;padding:26px 30px;color:#fff;background:linear-gradient(120deg,#1B3139,#22425a,#2a2f6b,#1B3139);background-size:300% 300%;animation:dbxGrad 14s ease infinite}.hhero .blob{position:absolute;border-radius:50%;filter:blur(34px);opacity:.55;animation:dbxFloat 9s ease-in-out infinite}.hhero .b1{width:260px;height:260px;background:#FF3621;right:-50px;top:-90px}.hhero .b2{width:200px;height:200px;background:#7C4DFF;right:220px;bottom:-120px;animation-delay:-3s}.hhero .b3{width:160px;height:160px;background:#00A3A1;left:-50px;bottom:-70px;animation-delay:-6s}.hhero>div{position:relative}.hhero h1{margin:0 0 6px;font-size:30px;font-weight:800;letter-spacing:-.01em}.hhero h1 em{font-style:normal;color:#FF8A7A}.hhero p{margin:0;color:#E2E8F0;font-size:15px;max-width:760px;line-height:1.5}.hstats{display:flex;gap:10px;flex-wrap:wrap;margin-top:14px}.hstats span{background:rgba(255,255,255,.14);border:1px solid rgba(255,255,255,.25);padding:4px 12px;border-radius:999px;font-size:13px}.hrow{display:flex;gap:10px;align-items:center;margin:16px 0 4px;flex-wrap:wrap}.cats{display:flex;gap:8px;flex-wrap:wrap;flex:1}.cat{border:1px solid var(--line);background:#fff;color:#334155;border-radius:999px;padding:8px 14px;cursor:pointer;font-size:14px;font-weight:600;display:inline-flex;gap:7px;align-items:center;transition:all .2s}.cat:hover{border-color:var(--accent);transform:translateY(-1px)}.cat.on{background:var(--navy);color:#fff;border-color:var(--navy);box-shadow:0 6px 16px rgba(27,49,57,.25)}.cat i{font-style:normal;font-size:12px;background:rgba(100,116,139,.18);border-radius:999px;padding:1px 7px}.cat.on i{background:rgba(255,255,255,.2)}#q{border:1px solid var(--line);border-radius:999px;padding:9px 14px;font-size:14px;min-width:210px;outline:none;font-family:inherit;background:#fff}#q:focus{border-color:var(--purple);box-shadow:0 0 0 3px rgba(124,77,255,.15)}.cdesc{color:var(--muted);font-size:14px;margin:8px 2px 2px;display:flex;gap:10px;align-items:center;flex-wrap:wrap}.cdesc button{margin-left:auto;border:1px solid var(--line);background:#fff;border-radius:999px;padding:6px 14px;cursor:pointer;font-size:13px;font-weight:600;color:var(--navy)}.cdesc button:hover{border-color:var(--accent);color:var(--accent)}.gtitle{font-size:12px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:#94A3B8;margin:18px 2px 8px}.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(270px,1fr));gap:14px}.mcard{background:#fff;border-radius:16px;padding:16px 16px 12px;cursor:pointer;border:2px solid transparent;box-shadow:0 4px 14px rgba(27,49,57,.07);transition:transform .2s,border-color .2s,box-shadow .2s;display:flex;flex-direction:column;animation:dbxRise .45s both;animation-delay:calc(var(--i,0)*35ms)}.mcard:hover{transform:translateY(-3px);border-color:var(--accent);box-shadow:0 12px 28px rgba(27,49,57,.14)}.mcard .mh{display:flex;gap:10px;align-items:flex-start}.mcard .mi{font-size:26px;line-height:1;flex:none;width:44px;height:44px;border-radius:12px;background:linear-gradient(135deg,#FFF4F1,#F5F3FF);display:flex;align-items:center;justify-content:center}.mcard .mt{font-weight:800;color:var(--navy);font-size:15.5px;line-height:1.25}.mcard .ms{color:#475569;font-size:13px;line-height:1.45;margin:8px 0 10px;flex:1}.mchips{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:10px}.mchips span{font-size:11.5px;background:#F1F5F9;color:#475569;border-radius:999px;padding:2px 9px;white-space:nowrap}.mact{display:flex;gap:6px}.mact button{flex:1;border:1px solid var(--line);background:#fff;border-radius:9px;padding:7px 4px;cursor:pointer;font-size:12.5px;font-weight:700;color:var(--navy);white-space:nowrap}.mact button:hover{border-color:var(--accent);color:var(--accent)}.mact button.go{background:linear-gradient(135deg,#FF3621,#7C4DFF);border:0;color:#fff}.empty{color:var(--muted);padding:30px;text-align:center}.hfoot{margin-top:22px;display:flex;gap:14px;flex-wrap:wrap}.hfoot .cta{flex:2 1 380px;margin:0}.hfoot .pip{flex:1 1 260px;background:#fff;border-radius:16px;padding:16px 18px;border:1px solid var(--line);font-size:13px;color:#475569}.hfoot .pip code{display:block;background:#0D1117;color:#E6EDF3;border-radius:8px;padding:8px 10px;margin-top:6px;font-size:12px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;white-space:pre-wrap}#player{flex:1;min-height:0;display:none;flex-direction:column}#slides{flex:1;display:flex;flex-direction:column;min-height:0;padding:14px 18px 8px;position:relative}.stage{flex:1;position:relative;min-height:0;perspective:1400px}.slide{position:absolute;inset:0;background:#fff;border-radius:18px;box-shadow:0 14px 40px rgba(27,49,57,.14);overflow:auto;padding:26px 44px 30px}.slide.enter-r{animation:inR .45s cubic-bezier(.2,.8,.2,1) both}.slide.enter-l{animation:inL .45s cubic-bezier(.2,.8,.2,1) both}@keyframes inR{from{opacity:0;transform:translateX(60px) rotateY(-6deg)}to{opacity:1;transform:none}}@keyframes inL{from{opacity:0;transform:translateX(-60px) rotateY(6deg)}to{opacity:1;transform:none}}.slide .dbx{max-width:none;font-size:17px}.slide .dbx .sec-head h2{font-size:29px}.slide .dbx table{font-size:15px}.slide .dbx .code pre{font-size:13.5px}.slide .dbx>*{animation:dbxRise .55s cubic-bezier(.2,.7,.2,1) both;animation-delay:calc(var(--i,0)*80ms + 100ms)}.slide.title{padding:0;overflow:hidden;background:transparent}.slide.title .dbx{height:100%;display:flex;flex-direction:column;position:relative}.slide.title .hero{flex:1;margin:0;border-radius:18px;display:flex;align-items:center;padding:40px 60px 130px}.slide.title .hero h1{font-size:46px}.slide.title .sub{font-size:19px}.slide.title .b1{width:420px;height:420px}.slide.title .b2{width:340px;height:340px}.slide.title .b3{width:300px;height:300px}.slide.title .idea{position:absolute;left:60px;right:60px;bottom:30px;font-size:17px;background:rgba(255,255,255,.96)}.slide.title .dbx>:not(.hero):not(.idea){display:none}.controls{display:flex;align-items:center;gap:12px;padding-top:10px;flex:none}.controls .nav{border:1px solid var(--line);background:#fff;border-radius:10px;min-width:44px;height:36px;cursor:pointer;font-size:15px;font-weight:700;color:var(--navy);padding:0 12px}.controls .nav:hover{border-color:var(--accent);color:var(--accent)}.controls .nav.next{background:linear-gradient(135deg,#FF3621,#7C4DFF);color:#fff;border:0}.dots{display:flex;gap:6px;flex:1;justify-content:center;flex-wrap:wrap}.dots button{width:10px;height:10px;border-radius:50%;border:0;background:#CBD5E1;cursor:pointer;padding:0;transition:all .25s}.dots button.on{background:var(--accent);width:28px;border-radius:6px}.count{color:var(--muted);font-size:13px;min-width:52px;text-align:right}.hint{color:#94A3B8;font-size:12px;white-space:nowrap}#overview{position:absolute;inset:0;background:rgba(244,242,238,.97);z-index:4;display:none;overflow:auto;padding:22px}#overview.on{display:block;animation:dbxRise .3s both}.ogrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:12px}.ocard{background:#fff;border-radius:14px;padding:14px;cursor:pointer;border:2px solid transparent;box-shadow:0 4px 14px rgba(0,0,0,.06);transition:all .2s}.ocard:hover{transform:translateY(-3px);border-color:var(--accent)}.ocard .n{font-size:12px;color:var(--muted);font-weight:700}.ocard .i{font-size:26px;margin:4px 0}.ocard .t{font-weight:700;color:var(--navy);font-size:14px}#doc{flex:1;display:none;min-height:0}#player.docmode #slides{display:none}#player.docmode #doc{display:flex}#toc{width:250px;flex:none;overflow:auto;padding:16px 12px;border-right:1px solid var(--line);background:#fff}#toc a{display:flex;gap:8px;align-items:center;padding:7px 10px;border-radius:9px;color:#334155;text-decoration:none;font-size:13px;margin:2px 0;cursor:pointer}#toc a:hover{background:#F1F5F9}#toc a.on{background:#FFF1EE;color:#C62D1A;font-weight:700}#toc .rawbtn{margin-top:12px;width:100%;border:1px dashed #CBD5E1;background:#fff;border-radius:9px;padding:8px;cursor:pointer;font-size:12.5px;color:#475569}#docScroll{flex:1;overflow:auto;padding:20px 28px 60px}.dsec{background:#fff;border-radius:16px;padding:22px 28px;margin:0 auto 16px;max-width:1000px;box-shadow:0 4px 18px rgba(27,49,57,.06)}.dsec.herosec{padding:0;background:transparent;box-shadow:none}.dsec .dbx{max-width:none}.dsec .dbx>*{animation:none}.rawmd{max-width:1000px;margin:0 auto;background:#0D1117;color:#E6EDF3;border-radius:14px;padding:18px 20px;font-size:12.5px;line-height:1.55;white-space:pre-wrap;word-break:break-word;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.quiz{max-width:820px}.dbx .code .copy{display:inline-block;margin-left:auto;border:1px solid #30363D;background:#21262D;color:#C9D1D9;border-radius:6px;font-size:11px;padding:2px 8px;cursor:pointer}.dbx .code .run+.copy{margin-left:10px}.fin{text-align:center;padding:10px 0}.fin .big{font-size:60px;animation:vzPop .6s both}.fin h2{font-size:30px;color:var(--navy);margin:6px 0}.fin p{color:var(--muted);margin:0 0 16px}.fcards{display:flex;gap:12px;flex-wrap:wrap;justify-content:center;text-align:left;margin-bottom:14px}.fcard{flex:1 1 220px;max-width:330px;background:#F8FAFC;border:1px solid var(--line);border-radius:14px;padding:14px 16px;cursor:pointer;transition:all .2s}.fcard:hover{border-color:var(--accent);transform:translateY(-2px)}.fcard b{display:block;color:var(--navy);margin-bottom:2px}.fcard span{font-size:13.5px;color:#475569}#modal{position:absolute;inset:0;background:rgba(15,23,42,.55);z-index:20;display:none;align-items:center;justify-content:center;padding:20px}#modal.on{display:flex;animation:dbxRise .25s both}.mbox{background:#fff;border-radius:18px;max-width:640px;width:100%;max-height:100%;overflow:auto;padding:22px 24px;box-shadow:0 30px 80px rgba(0,0,0,.35)}.mbox h3{margin:0 0 6px;color:var(--navy);font-size:20px}.mbox p{color:#475569;font-size:14px;line-height:1.5;margin:6px 0}.mbox ul{margin:6px 0;padding-left:20px;color:#334155;font-size:14px}.cmd{display:flex;gap:8px;align-items:stretch;margin:8px 0}.cmd code{flex:1;background:#0D1117;color:#E6EDF3;border-radius:10px;padding:10px 12px;font-size:12.5px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;white-space:pre-wrap;word-break:break-all}.cmd button,.mclose{border:0;border-radius:10px;padding:0 14px;cursor:pointer;font-weight:700;background:linear-gradient(135deg,#FF3621,#7C4DFF);color:#fff;font-size:13px}.mclose{padding:9px 18px;margin-top:10px;background:#E5E7EB;color:#374151}.tip{background:#ECFDF3;border:1px solid #A7F3D0;border-radius:10px;padding:9px 12px;font-size:13.5px;color:#065F46;margin:8px 0}#err{position:absolute;left:10px;right:10px;bottom:10px;background:#FEF2F2;border:1px solid #FCA5A5;color:#991B1B;border-radius:10px;padding:8px 12px;font-size:12px;z-index:30;display:none;white-space:pre-wrap}.confetti{position:absolute;top:-20px;font-size:22px;z-index:9;animation:fall 2.6s linear forwards;pointer-events:none}@keyframes fall{to{transform:translateY(900px) rotate(720deg);opacity:.7}}.loading{padding:60px;text-align:center;color:var(--muted)}@media (max-width:820px){.slide{padding:18px}.slide.title .hero{padding:26px 26px 150px}.slide.title .hero h1{font-size:30px}.slide.title .idea{left:16px;right:16px}#toc{display:none}.crumb{display:none}.hint{display:none}.seg button{padding:6px 9px}}@media (prefers-reduced-motion: reduce){*,*::before,*::after{animation:none!important;transition:none!important}}
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
/* databricksedu: the in-notebook app (home, slides, document view). */
|
|
2
|
+
(function () {
|
|
3
|
+
var D = window.DBE, cfg = D.cfg || {}, root = document.getElementById('dbe');
|
|
4
|
+
var CTA_URL = 'https://goldhandacademy.com';
|
|
5
|
+
var mods = {}, cats = {};
|
|
6
|
+
D.categories.forEach(function (c) {
|
|
7
|
+
cats[c.id] = c;
|
|
8
|
+
c.modules.forEach(function (m, n) { m.cat = c; m.pos = n; mods[m.id] = m; });
|
|
9
|
+
});
|
|
10
|
+
var S = { cat: D.categories[0].id, q: '', mod: null, mode: 'slides', idx: 0, slides: [], data: null };
|
|
11
|
+
var cache = {};
|
|
12
|
+
function esc(s) { return String(s == null ? '' : s).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"'); }
|
|
13
|
+
function $(id) { return document.getElementById(id); }
|
|
14
|
+
function showErr(msg) { var e = $('err'); e.style.display = 'block'; e.textContent = 'databricksedu: ' + msg; }
|
|
15
|
+
window.onerror = function (m, src, line) { showErr(m + ' (line ' + line + ')'); };
|
|
16
|
+
root.innerHTML =
|
|
17
|
+
'<div class="top">' +
|
|
18
|
+
'<button class="brand" id="bHome" title="All modules"><span class="lg">🎓</span><span>databricks<em>edu</em></span></button>' +
|
|
19
|
+
'<div class="crumb" id="crumb"></div>' +
|
|
20
|
+
'<div class="seg" id="seg" style="display:none"><button id="bSlides" class="on">🎞️ Slides</button><button id="bDoc">📄 Document</button></div>' +
|
|
21
|
+
'<button class="hbtn" id="bOver" title="Slide overview (O)" style="display:none">▦</button>' +
|
|
22
|
+
'<button class="hbtn pri" id="bSave" style="display:none">💾 Save to workspace</button>' +
|
|
23
|
+
'<button class="hbtn" id="bSize" title="Window height">↕</button>' +
|
|
24
|
+
'<button class="hbtn" id="bFull" title="Full screen (F)" style="display:none">⛶</button>' +
|
|
25
|
+
'</div><div id="bar"></div>' +
|
|
26
|
+
'<div id="main">' +
|
|
27
|
+
'<div id="home"></div>' +
|
|
28
|
+
'<div id="player">' +
|
|
29
|
+
'<section id="slides"><div class="stage" id="stage"></div>' +
|
|
30
|
+
'<div class="controls"><button class="nav" id="prev" title="Previous (←)">←</button><div class="dots" id="dots"></div>' +
|
|
31
|
+
'<span class="hint">← → to move · O overview · D document</span><span class="count" id="count"></span>' +
|
|
32
|
+
'<button class="nav next" id="next" title="Next (→)">Next →</button></div>' +
|
|
33
|
+
'<div id="overview"><div class="ogrid" id="ogrid"></div></div></section>' +
|
|
34
|
+
'<section id="doc"><nav id="toc"></nav><div id="docScroll"></div></section>' +
|
|
35
|
+
'</div>' +
|
|
36
|
+
'<div id="modal"></div><div id="err"></div>' +
|
|
37
|
+
'</div>';
|
|
38
|
+
// ---------------------------------------------------------------- content loading
|
|
39
|
+
function inflate(b64) {
|
|
40
|
+
var bin = atob(b64), bytes = new Uint8Array(bin.length);
|
|
41
|
+
for (var i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);
|
|
42
|
+
if (typeof DecompressionStream === 'undefined') {
|
|
43
|
+
return Promise.reject(new Error('this browser cannot unpack the content. Run databricksedu.start(compress=False) instead.'));
|
|
44
|
+
}
|
|
45
|
+
var stream = new Blob([bytes]).stream().pipeThrough(new DecompressionStream('gzip'));
|
|
46
|
+
return new Response(stream).text().then(JSON.parse);
|
|
47
|
+
}
|
|
48
|
+
function load(id) {
|
|
49
|
+
if (cache[id]) return Promise.resolve(cache[id]);
|
|
50
|
+
var c = D.content[id];
|
|
51
|
+
if (!c) return Promise.reject(new Error('no content for ' + id));
|
|
52
|
+
return (c.j ? Promise.resolve(c.j) : inflate(c.z)).then(function (data) { cache[id] = data; return data; });
|
|
53
|
+
}
|
|
54
|
+
// ---------------------------------------------------------------- helpers
|
|
55
|
+
function copyText(text, btn) {
|
|
56
|
+
function done() { if (btn) { var t = btn.textContent; btn.textContent = 'copied ✓'; setTimeout(function () { btn.textContent = t; }, 1400); } }
|
|
57
|
+
function fallback() {
|
|
58
|
+
var ta = document.createElement('textarea');
|
|
59
|
+
ta.value = text; ta.style.position = 'fixed'; ta.style.opacity = '0';
|
|
60
|
+
document.body.appendChild(ta); ta.select();
|
|
61
|
+
try { document.execCommand('copy'); done(); } catch (e) { }
|
|
62
|
+
ta.remove();
|
|
63
|
+
}
|
|
64
|
+
if (navigator.clipboard && navigator.clipboard.writeText) navigator.clipboard.writeText(text).then(done, fallback);
|
|
65
|
+
else fallback();
|
|
66
|
+
}
|
|
67
|
+
function wire(el) {
|
|
68
|
+
el.querySelectorAll('.code').forEach(function (c) {
|
|
69
|
+
var b = c.querySelector('.copy');
|
|
70
|
+
if (b) b.onclick = function () { copyText(c.querySelector('pre').innerText, b); };
|
|
71
|
+
});
|
|
72
|
+
el.querySelectorAll('.dbx>*').forEach(function (n, i) { n.style.setProperty('--i', i); });
|
|
73
|
+
}
|
|
74
|
+
function confetti() {
|
|
75
|
+
var e = ['🎉', '✨', '🎊', '⭐', '🧡', '💜'];
|
|
76
|
+
for (var i = 0; i < 36; i++) {
|
|
77
|
+
var s = document.createElement('div');
|
|
78
|
+
s.className = 'confetti'; s.textContent = e[i % e.length];
|
|
79
|
+
s.style.left = Math.random() * 100 + '%'; s.style.animationDelay = Math.random() * .8 + 's';
|
|
80
|
+
root.appendChild(s);
|
|
81
|
+
setTimeout(function (n) { return function () { n.remove(); }; }(s), 3600);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function ctaHtml(strong) {
|
|
85
|
+
return '<div class="cta"><span class="big">🎯</span><div><b>' + (strong ? 'Ready to test yourself?' : 'Preparing for a certification?') +
|
|
86
|
+
'</b><br><span>Practice exams are available at GoldHandAcademy.com</span></div>' +
|
|
87
|
+
'<a href="' + CTA_URL + '" target="_blank" rel="noopener">Practice exams →</a></div>';
|
|
88
|
+
}
|
|
89
|
+
// ---------------------------------------------------------------- home
|
|
90
|
+
function chips(m) {
|
|
91
|
+
var c = [];
|
|
92
|
+
if (m.level) c.push(esc(m.level));
|
|
93
|
+
if (m.minutes) c.push('⏱ ' + m.minutes + ' min');
|
|
94
|
+
c.push('🎞️ ' + m.slides + ' slides');
|
|
95
|
+
if (m.demo) c.push('🧪 demo');
|
|
96
|
+
if (m.exercises) c.push('✍️ ' + m.exercises + ' exercise' + (m.exercises > 1 ? 's' : ''));
|
|
97
|
+
if (m.quiz) c.push('🎯 quiz');
|
|
98
|
+
return c.map(function (x) { return '<span>' + x + '</span>'; }).join('');
|
|
99
|
+
}
|
|
100
|
+
function card(m, i) {
|
|
101
|
+
return '<div class="mcard" data-id="' + m.id + '" style="--i:' + i + '"><div class="mh"><div class="mi">' + m.icon + '</div>' +
|
|
102
|
+
'<div class="mt">' + esc(m.title) + '</div></div><div class="ms">' + esc(m.summary) + '</div>' +
|
|
103
|
+
'<div class="mchips">' + chips(m) + '</div><div class="mact">' +
|
|
104
|
+
'<button class="go" data-a="slides">▶ Start</button><button data-a="doc">📖 Read</button><button data-a="save">💾 Save</button></div></div>';
|
|
105
|
+
}
|
|
106
|
+
function renderHome() {
|
|
107
|
+
var total = Object.keys(mods).length, h = '';
|
|
108
|
+
h += '<div class="dbx" style="max-width:none"><div class="hhero"><div class="blob b1"></div><div class="blob b2"></div><div class="blob b3"></div><div>' +
|
|
109
|
+
'<h1>databricks<em>edu</em></h1><p>Bite-sized Databricks lessons that run inside your notebook: animated slides, readable notes, ' +
|
|
110
|
+
'hands-on notebooks with exercises, and seeded demo data. Pick a module and press <b>Start</b>.</p>' +
|
|
111
|
+
'<div class="hstats"><span>📚 ' + total + ' modules</span><span>🗂️ ' + D.categories.length + ' tracks</span>' +
|
|
112
|
+
'<span>🧪 seeded demo data</span><span>v' + esc(D.version) + '</span></div></div></div>';
|
|
113
|
+
h += '<div class="hrow"><div class="cats">' + D.categories.map(function (c) {
|
|
114
|
+
return '<button class="cat' + (c.id === S.cat && !S.q ? ' on' : '') + '" data-cat="' + c.id + '">' + c.icon + ' ' + esc(c.title) + ' <i>' + c.modules.length + '</i></button>';
|
|
115
|
+
}).join('') + '</div><input id="q" placeholder="🔎 Search all modules" value="' + esc(S.q) + '"></div>';
|
|
116
|
+
var list, cat = cats[S.cat];
|
|
117
|
+
if (S.q) {
|
|
118
|
+
var needle = S.q.toLowerCase();
|
|
119
|
+
list = Object.keys(mods).map(function (k) { return mods[k]; }).filter(function (m) {
|
|
120
|
+
return (m.title + ' ' + m.summary + ' ' + (m.tags || []).join(' ') + ' ' + m.group).toLowerCase().indexOf(needle) >= 0;
|
|
121
|
+
});
|
|
122
|
+
h += '<div class="cdesc">' + list.length + ' module(s) match “' + esc(S.q) + '”</div>';
|
|
123
|
+
} else {
|
|
124
|
+
list = cat.modules;
|
|
125
|
+
h += '<div class="cdesc"><span>' + esc(cat.desc) + '</span><button data-savecat="' + cat.id + '">💾 Save this whole track</button></div>';
|
|
126
|
+
}
|
|
127
|
+
if (!list.length) h += '<div class="empty">Nothing found. Try another word.</div>';
|
|
128
|
+
var group = null, i = 0;
|
|
129
|
+
list.forEach(function (m) {
|
|
130
|
+
var g = S.q ? m.cat.title : (m.group || '');
|
|
131
|
+
if (g !== group) { if (group !== null) h += '</div>'; group = g; if (g) h += '<div class="gtitle">' + esc(g) + '</div>'; h += '<div class="grid">'; }
|
|
132
|
+
h += card(m, i++);
|
|
133
|
+
});
|
|
134
|
+
if (group !== null) h += '</div>';
|
|
135
|
+
h += '<div class="hfoot">' + ctaHtml(!S.q && cat.cta) + '<div class="pip"><b>Take it with you</b><br>Every module saves to your workspace as notebooks.' +
|
|
136
|
+
'<code>databricksedu.save("all")</code></div></div></div>';
|
|
137
|
+
var home = $('home');
|
|
138
|
+
home.innerHTML = h;
|
|
139
|
+
home.querySelectorAll('.cat').forEach(function (b) { b.onclick = function () { S.cat = b.getAttribute('data-cat'); S.q = ''; renderHome(); }; });
|
|
140
|
+
home.querySelectorAll('.mcard').forEach(function (c) {
|
|
141
|
+
var id = c.getAttribute('data-id');
|
|
142
|
+
c.onclick = function (e) {
|
|
143
|
+
var a = e.target.getAttribute && e.target.getAttribute('data-a');
|
|
144
|
+
if (a === 'save') return saveDialog(id);
|
|
145
|
+
openModule(id, a === 'doc' ? 'doc' : 'slides');
|
|
146
|
+
};
|
|
147
|
+
});
|
|
148
|
+
var sc = home.querySelector('[data-savecat]');
|
|
149
|
+
if (sc) sc.onclick = function () { saveDialog(sc.getAttribute('data-savecat')); };
|
|
150
|
+
var qi = $('q'), t = null;
|
|
151
|
+
qi.oninput = function () {
|
|
152
|
+
clearTimeout(t);
|
|
153
|
+
t = setTimeout(function () { S.q = qi.value.trim(); renderHome(); var n = $('q'); n.focus(); n.setSelectionRange(n.value.length, n.value.length); }, 220);
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
function showHome() {
|
|
157
|
+
S.mod = null;
|
|
158
|
+
$('player').style.display = 'none'; $('home').style.display = 'block';
|
|
159
|
+
['seg', 'bOver', 'bSave'].forEach(function (id) { $(id).style.display = 'none'; });
|
|
160
|
+
$('crumb').innerHTML = ''; $('bar').style.width = '0';
|
|
161
|
+
renderHome();
|
|
162
|
+
}
|
|
163
|
+
// ---------------------------------------------------------------- save dialog
|
|
164
|
+
function saveDialog(id) {
|
|
165
|
+
var m = mods[id], c = cats[id], title, items = '', what;
|
|
166
|
+
if (m) {
|
|
167
|
+
title = m.title; what = 'this module';
|
|
168
|
+
items = '<ul>' + m.notebooks.map(function (n) { return '<li>📓 ' + esc(n) + '</li>'; }).join('') + '<li>📝 notes as Markdown</li></ul>';
|
|
169
|
+
} else if (c) { title = c.title; what = 'all ' + c.modules.length + ' modules of this track'; }
|
|
170
|
+
else { id = 'all'; title = 'everything'; what = 'every module'; }
|
|
171
|
+
var cmd = 'import databricksedu\ndatabricksedu.save("' + id + '")';
|
|
172
|
+
var h = '<div class="mbox"><h3>💾 Save “' + esc(title) + '” to your workspace</h3>' +
|
|
173
|
+
'<p>Copies ' + what + ' into <b>/Workspace/Users/<you>/databricksedu/</b> as notebooks you can run and edit.</p>' + items;
|
|
174
|
+
if (cfg.bar) h += '<div class="tip">👆 Fastest: in the <b>Save to workspace</b> bar above this window choose <b>' + esc(title) + '</b> and press the button.</div>';
|
|
175
|
+
h += '<p>' + (cfg.bar ? 'Or run' : 'Run') + ' this in a notebook cell:</p><div class="cmd"><code>' + esc(cmd) + '</code><button id="mcopy">copy</button></div>' +
|
|
176
|
+
'<button class="mclose" id="mclose">Close</button></div>';
|
|
177
|
+
var modal = $('modal');
|
|
178
|
+
modal.innerHTML = h; modal.classList.add('on');
|
|
179
|
+
$('mcopy').onclick = function () { copyText(cmd, $('mcopy')); };
|
|
180
|
+
$('mclose').onclick = function () { modal.classList.remove('on'); };
|
|
181
|
+
modal.onclick = function (e) { if (e.target === modal) modal.classList.remove('on'); };
|
|
182
|
+
}
|
|
183
|
+
// ---------------------------------------------------------------- player
|
|
184
|
+
function openModule(id, mode, at, vstep) {
|
|
185
|
+
var m = mods[id];
|
|
186
|
+
if (!m) return showErr('unknown module ' + id);
|
|
187
|
+
S.mod = m; S.mode = mode || 'slides'; S.idx = 0;
|
|
188
|
+
$('home').style.display = 'none'; $('player').style.display = 'flex';
|
|
189
|
+
['seg', 'bSave'].forEach(function (x) { $(x).style.display = ''; });
|
|
190
|
+
$('crumb').innerHTML = esc(m.cat.title) + ' › <b>' + esc(m.title) + '</b>';
|
|
191
|
+
$('stage').innerHTML = '<div class="loading">Loading…</div>';
|
|
192
|
+
load(id).then(function (data) {
|
|
193
|
+
if (S.mod !== m) return;
|
|
194
|
+
S.data = data;
|
|
195
|
+
S.slides = data.slides.map(function (s) { return { t: s.t, i: s.i, h: s.h, title: !!s.hero }; });
|
|
196
|
+
if (data.quiz && data.quiz.length) S.slides.push({ t: 'Check yourself', i: '🎯', quiz: true,
|
|
197
|
+
h: '<div class="sec-head"><span class="sec-num">' + String(S.slides.length).padStart(2, '0') + '</span><span class="sec-icon">🎯</span><h2>Check yourself</h2></div><div class="quiz"></div>' });
|
|
198
|
+
S.slides.push({ t: 'Where next?', i: '🎉', fin: true, h: finHtml(m) });
|
|
199
|
+
buildDots(); buildOverview(); buildDoc();
|
|
200
|
+
S.idx = Math.max(0, Math.min(at || 0, S.slides.length - 1));
|
|
201
|
+
setMode(S.mode);
|
|
202
|
+
for (var k = 0; k < (vstep || 0); k++) { var vz = DBXViz.pending($('stage'), 1); if (vz) DBXViz.step(vz, 1); }
|
|
203
|
+
}, function (e) { showErr(e.message); });
|
|
204
|
+
}
|
|
205
|
+
function nextModule(m) { return m.cat.modules[m.pos + 1] || null; }
|
|
206
|
+
function finHtml(m) {
|
|
207
|
+
var nx = nextModule(m), h = '<div class="fin"><div class="big">🎉</div><h2>You finished “' + esc(m.title) + '”</h2><p>Nice work. Here is what you can do next.</p><div class="fcards">';
|
|
208
|
+
if (nx) h += '<div class="fcard" data-go="' + nx.id + '"><b>▶ Next: ' + nx.icon + ' ' + esc(nx.title) + '</b><span>' + esc(nx.summary) + '</span></div>';
|
|
209
|
+
h += '<div class="fcard" data-save="1"><b>💾 Save the notebooks</b><span>' + m.notebooks.map(esc).join(' · ') + '</span></div>';
|
|
210
|
+
h += '<div class="fcard" data-home="1"><b>🗂️ Back to all modules</b><span>' + esc(m.cat.title) + ' has ' + m.cat.modules.length + ' modules.</span></div></div>';
|
|
211
|
+
return h + ctaHtml(!!m.cat.cta) + '</div>';
|
|
212
|
+
}
|
|
213
|
+
function wireFin(el) {
|
|
214
|
+
el.querySelectorAll('[data-go]').forEach(function (c) { c.onclick = function () { openModule(c.getAttribute('data-go'), 'slides'); }; });
|
|
215
|
+
el.querySelectorAll('[data-save]').forEach(function (c) { c.onclick = function () { saveDialog(S.mod.id); }; });
|
|
216
|
+
el.querySelectorAll('[data-home]').forEach(function (c) { c.onclick = showHome; });
|
|
217
|
+
}
|
|
218
|
+
function mountQuiz(el) { dbxQuiz(el, S.data.quiz, function (score, total) { if (score === total) confetti(); }); }
|
|
219
|
+
function buildDots() {
|
|
220
|
+
var dots = $('dots'); dots.innerHTML = '';
|
|
221
|
+
S.slides.forEach(function (s, i) {
|
|
222
|
+
var b = document.createElement('button'); b.title = s.t;
|
|
223
|
+
b.onclick = function () { go(i); }; dots.appendChild(b);
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
function buildOverview() {
|
|
227
|
+
var g = $('ogrid'); g.innerHTML = '';
|
|
228
|
+
S.slides.forEach(function (s, i) {
|
|
229
|
+
var c = document.createElement('div'); c.className = 'ocard';
|
|
230
|
+
c.innerHTML = '<div class="n">' + (i + 1) + '</div><div class="i">' + s.i + '</div><div class="t">' + s.t + '</div>';
|
|
231
|
+
c.onclick = function () { $('overview').classList.remove('on'); go(i); };
|
|
232
|
+
g.appendChild(c);
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
function renderSlide(dir) {
|
|
236
|
+
var s = S.slides[S.idx], stage = $('stage');
|
|
237
|
+
var el = document.createElement('div');
|
|
238
|
+
el.className = 'slide ' + (dir < 0 ? 'enter-l' : 'enter-r') + (s.title ? ' title' : '');
|
|
239
|
+
el.innerHTML = '<div class="dbx">' + s.h + '</div>';
|
|
240
|
+
stage.innerHTML = ''; stage.appendChild(el);
|
|
241
|
+
wire(el);
|
|
242
|
+
DBXViz.init(el);
|
|
243
|
+
if (s.quiz) mountQuiz(el.querySelector('.quiz'));
|
|
244
|
+
if (s.fin) wireFin(el);
|
|
245
|
+
$('dots').querySelectorAll('button').forEach(function (b, i) { b.classList.toggle('on', i === S.idx); });
|
|
246
|
+
$('count').textContent = (S.idx + 1) + ' / ' + S.slides.length;
|
|
247
|
+
$('bar').style.width = ((S.idx + 1) / S.slides.length * 100) + '%';
|
|
248
|
+
$('next').textContent = S.idx === S.slides.length - 1 ? '✓ Done' : 'Next →';
|
|
249
|
+
}
|
|
250
|
+
function go(i, dir) {
|
|
251
|
+
if (i < 0 || i >= S.slides.length) return;
|
|
252
|
+
var d = dir || (i < S.idx ? -1 : 1);
|
|
253
|
+
S.idx = i; renderSlide(d);
|
|
254
|
+
}
|
|
255
|
+
function advance(dir) {
|
|
256
|
+
var cur = $('stage').querySelector('.slide');
|
|
257
|
+
var vz = cur && DBXViz.pending(cur, dir);
|
|
258
|
+
if (vz) { DBXViz.step(vz, dir); vz.scrollIntoView({ block: 'nearest', behavior: 'smooth' }); return; }
|
|
259
|
+
if (dir > 0 && S.idx === S.slides.length - 1) return showHome();
|
|
260
|
+
go(S.idx + dir, dir);
|
|
261
|
+
}
|
|
262
|
+
function buildDoc() {
|
|
263
|
+
var toc = $('toc'), sc = $('docScroll'), m = S.mod;
|
|
264
|
+
toc.innerHTML = ''; sc.innerHTML = '';
|
|
265
|
+
S.slides.forEach(function (s, i) {
|
|
266
|
+
if (s.fin) return;
|
|
267
|
+
var sec = document.createElement('div');
|
|
268
|
+
sec.className = 'dsec' + (s.title ? ' herosec' : ''); sec.id = 'dsec' + i;
|
|
269
|
+
sec.innerHTML = '<div class="dbx">' + s.h + '</div>';
|
|
270
|
+
sc.appendChild(sec); wire(sec);
|
|
271
|
+
if (s.quiz) mountQuiz(sec.querySelector('.quiz'));
|
|
272
|
+
var a = document.createElement('a');
|
|
273
|
+
a.innerHTML = '<span>' + s.i + '</span><span>' + s.t + '</span>';
|
|
274
|
+
a.onclick = function () { $('raw') && $('raw').remove(); sc.querySelectorAll('.dsec').forEach(function (d) { d.style.display = ''; }); sec.scrollIntoView({ behavior: 'smooth', block: 'start' }); };
|
|
275
|
+
toc.appendChild(a);
|
|
276
|
+
});
|
|
277
|
+
var end = document.createElement('div');
|
|
278
|
+
end.className = 'dsec'; end.innerHTML = '<div class="dbx">' + ctaHtml(!!m.cat.cta) + '</div>';
|
|
279
|
+
sc.appendChild(end);
|
|
280
|
+
var rb = document.createElement('button');
|
|
281
|
+
rb.className = 'rawbtn'; rb.textContent = '⧉ Raw Markdown';
|
|
282
|
+
rb.onclick = function () {
|
|
283
|
+
if ($('raw')) { $('raw').remove(); sc.querySelectorAll('.dsec').forEach(function (d) { d.style.display = ''; }); return; }
|
|
284
|
+
sc.querySelectorAll('.dsec').forEach(function (d) { d.style.display = 'none'; });
|
|
285
|
+
var w = document.createElement('div'); w.id = 'raw';
|
|
286
|
+
w.innerHTML = '<div style="max-width:1000px;margin:0 auto 10px;text-align:right"><button class="rawbtn" style="width:auto;padding:8px 16px" id="rawcopy">copy Markdown</button></div><pre class="rawmd"></pre>';
|
|
287
|
+
w.querySelector('pre').textContent = S.data.md;
|
|
288
|
+
sc.insertBefore(w, sc.firstChild); sc.scrollTop = 0;
|
|
289
|
+
$('rawcopy').onclick = function () { copyText(S.data.md, $('rawcopy')); };
|
|
290
|
+
};
|
|
291
|
+
toc.appendChild(rb);
|
|
292
|
+
sc.onscroll = function () {
|
|
293
|
+
var best = 0, top = sc.getBoundingClientRect().top;
|
|
294
|
+
sc.querySelectorAll('.dsec').forEach(function (d, i) { if (d.getBoundingClientRect().top - top < 120) best = i; });
|
|
295
|
+
toc.querySelectorAll('a').forEach(function (a, i) { a.classList.toggle('on', i === best); });
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
function setMode(mode) {
|
|
299
|
+
S.mode = mode;
|
|
300
|
+
$('player').classList.toggle('docmode', mode === 'doc');
|
|
301
|
+
$('bSlides').classList.toggle('on', mode !== 'doc'); $('bDoc').classList.toggle('on', mode === 'doc');
|
|
302
|
+
$('bOver').style.display = mode === 'doc' ? 'none' : '';
|
|
303
|
+
$('overview').classList.remove('on');
|
|
304
|
+
if (mode === 'doc') { $('bar').style.width = '100%'; DBXViz.init($('docScroll'), { autoplay: true }); $('docScroll').onscroll(); }
|
|
305
|
+
else renderSlide(1);
|
|
306
|
+
}
|
|
307
|
+
// ---------------------------------------------------------------- chrome
|
|
308
|
+
$('bHome').onclick = showHome;
|
|
309
|
+
$('bSlides').onclick = function () { setMode('slides'); };
|
|
310
|
+
$('bDoc').onclick = function () { setMode('doc'); };
|
|
311
|
+
$('bOver').onclick = function () { $('overview').classList.toggle('on'); };
|
|
312
|
+
$('bSave').onclick = function () { saveDialog(S.mod.id); };
|
|
313
|
+
$('prev').onclick = function () { advance(-1); };
|
|
314
|
+
$('next').onclick = function () { advance(1); };
|
|
315
|
+
var sizes = [680, 820, 980], H = cfg.height || 820;
|
|
316
|
+
function setH(h) {
|
|
317
|
+
H = h; root.style.height = h + 'px';
|
|
318
|
+
try { if (window.frameElement && window.frameElement.hasAttribute('data-dbe')) window.frameElement.style.height = (h + 4) + 'px'; } catch (e) { }
|
|
319
|
+
}
|
|
320
|
+
setH(H);
|
|
321
|
+
$('bSize').onclick = function () {
|
|
322
|
+
var next = sizes.filter(function (s) { return s > H; })[0] || sizes[0];
|
|
323
|
+
setH(next);
|
|
324
|
+
};
|
|
325
|
+
var fsOk = document.fullscreenEnabled || document.webkitFullscreenEnabled;
|
|
326
|
+
if (fsOk) {
|
|
327
|
+
$('bFull').style.display = '';
|
|
328
|
+
$('bFull').onclick = toggleFs;
|
|
329
|
+
document.addEventListener('fullscreenchange', function () { root.classList.toggle('fs', !!document.fullscreenElement); });
|
|
330
|
+
}
|
|
331
|
+
function toggleFs() {
|
|
332
|
+
if (!fsOk) return;
|
|
333
|
+
if (document.fullscreenElement) document.exitFullscreen();
|
|
334
|
+
else (root.requestFullscreen || root.webkitRequestFullscreen).call(root);
|
|
335
|
+
}
|
|
336
|
+
document.addEventListener('keydown', function (e) {
|
|
337
|
+
if (/INPUT|TEXTAREA/.test((e.target.tagName || ''))) return;
|
|
338
|
+
if (e.key === 'Escape') { $('modal').classList.remove('on'); $('overview').classList.remove('on'); return; }
|
|
339
|
+
if (!S.mod) return;
|
|
340
|
+
if (e.key === 'd' || e.key === 'D') return setMode(S.mode === 'doc' ? 'slides' : 'doc');
|
|
341
|
+
if (e.key === 'f' || e.key === 'F') return toggleFs();
|
|
342
|
+
if (S.mode === 'doc') return;
|
|
343
|
+
if (e.key === 'ArrowRight' || e.key === 'PageDown' || e.key === ' ') { e.preventDefault(); advance(1); }
|
|
344
|
+
else if (e.key === 'ArrowLeft' || e.key === 'PageUp') { e.preventDefault(); advance(-1); }
|
|
345
|
+
else if (e.key === 'o' || e.key === 'O') $('overview').classList.toggle('on');
|
|
346
|
+
else if (e.key === 'Home') go(0);
|
|
347
|
+
else if (e.key === 'End') go(S.slides.length - 1);
|
|
348
|
+
});
|
|
349
|
+
// ---------------------------------------------------------------- start
|
|
350
|
+
var r = String(cfg.route || 'home').split('/');
|
|
351
|
+
if ((r[0] === 'slides' || r[0] === 'doc') && mods[r[1]]) { S.cat = mods[r[1]].cat.id; openModule(r[1], r[0], +r[2] || 0, +r[3] || 0); }
|
|
352
|
+
else { if (r[0] === 'cat' && cats[r[1]]) S.cat = r[1]; showHome(); }
|
|
353
|
+
})();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.dbx{--navy:#1B3139;--accent:#FF3621;--blue:#2272B4;--teal:#00A3A1;--purple:#7C4DFF;--amber:#FFAB00;--ink:#1F2937;--muted:#6B7280;--line:#E5E7EB;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;color:var(--ink);font-size:15px;line-height:1.6;max-width:1100px}.dbx *{box-sizing:border-box}.dbx>*{animation:dbxRise .55s cubic-bezier(.2,.7,.2,1) both}.dbx>*:nth-child(2){animation-delay:.06s}.dbx>*:nth-child(3){animation-delay:.12s}.dbx>*:nth-child(4){animation-delay:.18s}.dbx>*:nth-child(5){animation-delay:.24s}.dbx>*:nth-child(6){animation-delay:.3s}.dbx>*:nth-child(n+7){animation-delay:.36s}@keyframes dbxRise{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}@keyframes dbxGrad{0%{background-position:0% 50%}50%{background-position:100% 50%}100%{background-position:0% 50%}}@keyframes dbxFloat{0%,100%{transform:translate(0,0) scale(1)}50%{transform:translate(18px,-14px) scale(1.08)}}@keyframes dbxLine{from{width:0}to{width:100%}}@keyframes dbxPulse{0%,100%{box-shadow:0 0 0 0 rgba(255,54,33,.25)}50%{box-shadow:0 0 0 8px rgba(255,54,33,0)}}.dbx .hero{position:relative;overflow:hidden;border-radius:18px;padding:38px 40px 34px;margin:4px 0 18px;color:#fff;background:linear-gradient(120deg,#1B3139,#22425a,#2a2f6b,#1B3139);background-size:300% 300%;animation:dbxGrad 14s ease infinite,dbxRise .6s both}.dbx .blob{position:absolute;border-radius:50%;filter:blur(30px);opacity:.55;animation:dbxFloat 9s ease-in-out infinite}.dbx .b1{width:220px;height:220px;background:#FF3621;right:-40px;top:-60px}.dbx .b2{width:180px;height:180px;background:#7C4DFF;right:160px;bottom:-90px;animation-delay:-3s}.dbx .b3{width:140px;height:140px;background:#00A3A1;left:-40px;bottom:-50px;animation-delay:-6s}.dbx .hero-in{position:relative}.dbx .kicker{text-transform:uppercase;letter-spacing:.14em;font-size:12px;color:#FFC4BA;font-weight:700}.dbx .hero h1{font-size:34px;line-height:1.15;margin:8px 0 14px;color:#fff;font-weight:800}.dbx .kicker-inline{display:inline-block;font-size:.5em;vertical-align:middle;background:var(--accent);padding:4px 10px;border-radius:999px;margin-right:10px;letter-spacing:.08em;text-transform:uppercase}.dbx .chips{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:12px}.dbx .chip{background:rgba(255,255,255,.14);border:1px solid rgba(255,255,255,.25);padding:4px 12px;border-radius:999px;font-size:13px;color:#fff}.dbx .chip strong{color:#fff}.dbx .sub{color:#E2E8F0;font-size:16px;margin:0;max-width:820px}.dbx .sub strong,.dbx .sub b{color:#FFD7CF}.dbx .sub code{background:rgba(255,255,255,.16);color:#fff}.dbx .idea{display:flex;gap:14px;align-items:flex-start;background:linear-gradient(135deg,#FFF4F1,#FFF);border:1px solid #FFD0C7;border-left:5px solid var(--accent);border-radius:14px;padding:16px 18px;margin:14px 0;animation:dbxRise .55s both,dbxPulse 3s ease-in-out 1s 2}.dbx .idea-icon{font-size:26px;line-height:1}.dbx .idea b{color:#C62D1A}.dbx .sec-head{display:flex;align-items:center;gap:12px;margin:6px 0 14px;position:relative;padding-bottom:10px}.dbx .sec-head:after{content:"";position:absolute;left:0;bottom:0;height:3px;border-radius:3px;background:linear-gradient(90deg,var(--accent),var(--purple),var(--teal));animation:dbxLine .9s ease-out both}.dbx .sec-num{font-weight:800;font-size:13px;color:#fff;background:linear-gradient(135deg,var(--accent),#ff7a59);padding:5px 10px;border-radius:9px;letter-spacing:.05em}.dbx .sec-icon{font-size:26px;line-height:1}.dbx .sec-head h2{margin:0;font-size:25px;color:var(--navy);font-weight:800;border:0}.dbx h3{color:var(--navy);margin:18px 0 8px}.dbx p{margin:8px 0}.dbx a{color:var(--blue)}.dbx code{background:#EEF2FF;color:#3730A3;padding:1px 6px;border-radius:6px;font-size:.88em;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.dbx .tbl{overflow-x:auto;border-radius:12px;border:1px solid var(--line);box-shadow:0 2px 10px rgba(27,49,57,.06);margin:12px 0;background:#fff}.dbx table{border-collapse:collapse;width:100%;font-size:14px}.dbx th{background:linear-gradient(135deg,#1B3139,#2B4F63);color:#fff;text-align:left;padding:10px 12px;font-weight:600}.dbx td{padding:9px 12px;border-top:1px solid var(--line);vertical-align:top}.dbx tr:nth-child(even) td{background:#F8FAFC}.dbx tr:hover td{background:#FFF4F1}.dbx td:first-child{font-weight:600;color:var(--navy)}.dbx ul,.dbx ol{padding-left:22px;margin:8px 0}.dbx li{margin:5px 0}.dbx li::marker{color:var(--accent)}.dbx li.bad,.dbx li.good{list-style:none;margin:8px 0 8px -22px;padding:10px 14px;border-radius:10px}.dbx li.bad{background:#FFF1F0;border:1px solid #FFCDC7}.dbx li.good{background:#ECFDF3;border:1px solid #B7EBC9}.dbx blockquote.callout{margin:14px 0;padding:12px 16px 12px 46px;border-radius:12px;background:linear-gradient(135deg,#E8F1FF,#F5F9FF);border:1px solid #C7DBFF;position:relative;color:#1E3A5F}.dbx blockquote.callout:before{content:"ℹ️";position:absolute;left:14px;top:11px;font-size:18px}.dbx blockquote.callout p{margin:4px 0}.dbx .code{border-radius:12px;overflow:hidden;margin:12px 0;box-shadow:0 8px 24px rgba(15,23,42,.18);background:#0D1117}.dbx .code-bar{display:flex;align-items:center;gap:6px;padding:8px 12px;background:#161B22;border-bottom:1px solid #30363D}.dbx .code-bar i{width:11px;height:11px;border-radius:50%;background:#FF5F57;display:inline-block}.dbx .code-bar i:nth-child(2){background:#FEBC2E}.dbx .code-bar i:nth-child(3){background:#28C840}.dbx .lang{margin-left:8px;color:#8B949E;font-size:11px;letter-spacing:.1em;font-weight:700}.dbx .run{margin-left:auto;color:#3FB950;font-size:11px;font-weight:700}.dbx .copy{display:none}.dbx .code pre{margin:0;padding:14px 16px;color:#E6EDF3;font-size:13px;line-height:1.55;overflow-x:auto;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;background:transparent}.dbx pre.diagram{background:linear-gradient(135deg,#F8FAFC,#EEF2FF);border:1px dashed #A5B4FC;border-radius:12px;padding:14px 16px;font-size:13px;color:#312E81;overflow-x:auto;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.dbx .tryit{display:flex;gap:12px;align-items:center;background:linear-gradient(135deg,#ECFDF3,#F0FDFA);border:1px solid #A7F3D0;border-radius:12px;padding:12px 16px;margin:12px 0}.dbx .tryit b{color:#047857}.dbx .present{display:flex;gap:16px;align-items:center;border-radius:14px;padding:16px 20px;background:linear-gradient(120deg,#2a2f6b,#7C4DFF);color:#fff;box-shadow:0 10px 30px rgba(124,77,255,.3)}.dbx .present b{font-size:17px}.dbx .present span{color:#E9E5FF}.dbx .present .big{font-size:34px}.dbx .footer{margin-top:10px;padding:14px 18px;border-radius:12px;background:#F8FAFC;border:1px solid var(--line);color:var(--muted);font-size:13px}.dbx .hero-icon{margin-right:12px}.dbx .run.todo{color:#FBBF24}.dbx details.solution{margin:12px 0;border:1px dashed #C4B5FD;border-radius:12px;padding:4px 14px;background:#FAF5FF}.dbx details.solution summary{cursor:pointer;font-weight:700;color:#6D28D9;padding:8px 0}.dbx details.solution[open]{padding-bottom:10px}.dbx .exercise{display:flex;gap:12px;align-items:center;background:linear-gradient(135deg,#FFFBEB,#FFF7ED);border:1px solid #FCD34D;border-radius:12px;padding:12px 16px;margin:12px 0}.dbx .exercise b{color:#B45309}.dbx .cta{display:flex;gap:18px;align-items:center;flex-wrap:wrap;border-radius:16px;padding:20px 24px;margin:14px 0;color:#fff;background:linear-gradient(120deg,#0F172A,#7C2D12,#B45309);background-size:220% 220%;animation:dbxGrad 10s ease infinite;box-shadow:0 12px 34px rgba(180,83,9,.3)}.dbx .cta .big{font-size:40px}.dbx .cta b{font-size:19px;color:#fff}.dbx .cta span{color:#FDE68A}.dbx .cta a{margin-left:auto;background:#FBBF24;color:#1F2937;font-weight:800;padding:10px 20px;border-radius:999px;text-decoration:none;white-space:nowrap}.dbx .dataset{border:1px solid #BFDBFE;border-radius:14px;background:linear-gradient(135deg,#EFF6FF,#fff);padding:14px 16px;margin:12px 0}.dbx .ds-head{display:flex;gap:12px;align-items:center;flex-wrap:wrap}.dbx .ds-head>div{flex:1;min-width:240px}.dbx .ds-head span{color:var(--muted);font-size:.9em}.dbx .ds-icon{font-size:30px;color:inherit}.dbx .ds-call{white-space:nowrap}.dbx .ds-tables{display:flex;gap:12px;flex-wrap:wrap;margin-top:12px}.dbx .ds-table{flex:1;min-width:210px;background:#fff;border:1px solid var(--line);border-radius:12px;overflow:hidden;box-shadow:0 2px 8px rgba(27,49,57,.06)}.dbx .ds-th{background:linear-gradient(135deg,#1B3139,#2B4F63);color:#fff;font-weight:700;padding:7px 12px;font-size:.92em}.dbx .ds-cm{color:var(--muted);font-size:.8em;padding:5px 12px;border-bottom:1px solid var(--line)}.dbx .ds-col{display:flex;gap:8px;align-items:center;padding:3px 12px;font-size:.84em;border-bottom:1px solid #F1F5F9}.dbx .ds-col code{background:transparent;padding:0;color:var(--navy)}.dbx .ds-col .ty{color:#94A3B8;font-size:.86em;margin-left:auto}.dbx .k{font-size:.72em;font-weight:800;padding:1px 6px;border-radius:6px;white-space:nowrap}.dbx .k.pk{background:#FEF3C7;color:#92400E}.dbx .k.fk{background:#DBEAFE;color:#1E40AF}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
function dbxQuiz(root, questions, onDone) {
|
|
2
|
+
if (typeof root === 'string') root = document.getElementById(root);
|
|
3
|
+
var i = 0, score = 0, picked = null, shown = false, done = false;
|
|
4
|
+
function esc(s) { return String(s).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/`([^`]+)`/g, '<code style="background:#EEF2FF;color:#3730A3;padding:1px 6px;border-radius:6px">$1</code>'); }
|
|
5
|
+
function btn(label, primary) { return '<button style="margin-top:16px;padding:10px 22px;border-radius:10px;border:none;cursor:pointer;font-weight:700;background:' + (primary ? 'linear-gradient(135deg,#FF3621,#7C4DFF)' : '#E5E7EB') + ';color:' + (primary ? '#fff' : '#6B7280') + ';font-size:0.95em;box-shadow:' + (primary ? '0 6px 18px rgba(124,77,255,.3)' : 'none') + '">' + label + '</button>'; }
|
|
6
|
+
var box = 'padding:22px 24px;border-radius:16px;background:#fff;border:1px solid #E5E7EB;box-shadow:0 8px 28px rgba(27,49,57,.08);animation:dbxQ .4s ease both';
|
|
7
|
+
var style = '<style>@keyframes dbxQ{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}</style>';
|
|
8
|
+
function bar() {
|
|
9
|
+
var h = '<div style="display:flex;gap:6px;margin-bottom:14px">';
|
|
10
|
+
for (var k = 0; k < questions.length; k++) h += '<div style="flex:1;height:6px;border-radius:6px;background:' + (k < i ? 'linear-gradient(90deg,#FF3621,#7C4DFF)' : k === i ? '#C4B5FD' : '#E5E7EB') + '"></div>';
|
|
11
|
+
return h + '</div>';
|
|
12
|
+
}
|
|
13
|
+
function render() {
|
|
14
|
+
if (i >= questions.length) {
|
|
15
|
+
var pct = Math.round(score / questions.length * 100), msg = pct === 100 ? 'Perfect! 🎉' : pct >= 60 ? 'Nice work! 💪' : 'Worth another look 📖';
|
|
16
|
+
root.innerHTML = style + '<div style="' + box + ';text-align:center"><div style="font-size:48px">' + (pct === 100 ? '🏆' : pct >= 60 ? '🌟' : '🔁') + '</div><div style="font-size:1.6em;font-weight:800;color:#1B3139">' + score + ' / ' + questions.length + '</div><div style="color:#6B7280;margin-top:4px">' + msg + '</div>' + btn('Retake', true) + '</div>';
|
|
17
|
+
root.querySelector('button').onclick = function () { i = 0; score = 0; picked = null; shown = false; done = false; render(); };
|
|
18
|
+
if (!done && onDone) { done = true; onDone(score, questions.length); }
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
var Q = questions[i], h = style + '<div style="' + box + '">' + bar();
|
|
22
|
+
h += '<div style="color:#7C4DFF;font-size:0.8em;font-weight:800;letter-spacing:.08em;text-transform:uppercase;margin-bottom:6px">Question ' + (i + 1) + ' of ' + questions.length + '</div>';
|
|
23
|
+
h += '<div style="font-weight:700;color:#1B3139;margin-bottom:14px;line-height:1.5;font-size:1.05em">' + esc(Q.q) + '</div>';
|
|
24
|
+
Q.o.forEach(function (t, k) {
|
|
25
|
+
var bg = '#fff', bd = '#E5E7EB', mark = String.fromCharCode(65 + k);
|
|
26
|
+
if (shown && k === Q.c) { bg = '#ECFDF3'; bd = '#22C55E'; mark = '✓'; }
|
|
27
|
+
else if (shown && k === picked) { bg = '#FFF1F0'; bd = '#EF4444'; mark = '✗'; }
|
|
28
|
+
else if (!shown && k === picked) { bg = '#F5F3FF'; bd = '#7C4DFF'; }
|
|
29
|
+
h += '<div data-k="' + k + '" style="display:flex;gap:12px;align-items:center;padding:11px 14px;margin:8px 0;border:2px solid ' + bd + ';background:' + bg + ';border-radius:12px;cursor:' + (shown ? 'default' : 'pointer') + ';color:#1F2937;transition:all .15s">' +
|
|
30
|
+
'<span style="flex:none;width:28px;height:28px;border-radius:8px;display:inline-flex;align-items:center;justify-content:center;font-weight:800;font-size:.85em;background:' + (bd === '#E5E7EB' ? '#F1F5F9' : bd) + ';color:' + (bd === '#E5E7EB' ? '#64748B' : '#fff') + '">' + mark + '</span><span>' + esc(t) + '</span></div>';
|
|
31
|
+
});
|
|
32
|
+
if (shown) {
|
|
33
|
+
var ok = picked === Q.c;
|
|
34
|
+
h += '<div style="margin-top:14px;padding:14px 16px;border-radius:12px;background:' + (ok ? '#ECFDF3' : '#FFF7ED') + ';border:1px solid ' + (ok ? '#A7F3D0' : '#FED7AA') + ';color:#1F2937;animation:dbxQ .3s both"><strong>' + (ok ? '✅ Correct.' : '💡 Not quite.') + '</strong> ' + esc(Q.e) + '</div>' + btn(i + 1 < questions.length ? 'Next →' : 'See score', true);
|
|
35
|
+
} else {
|
|
36
|
+
h += btn('Submit', picked !== null);
|
|
37
|
+
}
|
|
38
|
+
root.innerHTML = h + '</div>';
|
|
39
|
+
if (!shown) root.querySelectorAll('[data-k]').forEach(function (el) { el.onclick = function () { picked = +el.getAttribute('data-k'); render(); }; });
|
|
40
|
+
root.querySelector('button').onclick = function () {
|
|
41
|
+
if (!shown) { if (picked === null) return; if (picked === Q.c) score++; shown = true; }
|
|
42
|
+
else { i++; picked = null; shown = false; }
|
|
43
|
+
render();
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
render();
|
|
47
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@keyframes vzPop{0%{opacity:0;transform:scale(.92) translateY(8px)}60%{transform:scale(1.03)}100%{opacity:1;transform:none}}@keyframes vzDot{0%{left:-6px;opacity:0}15%{opacity:1}85%{opacity:1}100%{left:100%;opacity:0}}@keyframes vzGlow{0%,100%{box-shadow:0 0 0 0 rgba(34,197,94,.45)}50%{box-shadow:0 0 0 7px rgba(34,197,94,0)}}@keyframes vzFade{to{opacity:.25}}.dbx .vz{border:1px solid var(--line);border-radius:16px;background:linear-gradient(180deg,#fff,#F8FAFC);padding:14px 16px;margin:14px 0;box-shadow:0 6px 22px rgba(27,49,57,.08)}.dbx .vz *{box-sizing:border-box}.dbx .vz [data-state=hide],.dbx .vz [data-state=gone]{display:none!important}.dbx .vz-top{display:flex;align-items:center;gap:10px;margin-bottom:10px;min-height:30px}.dbx .vz-title{font-weight:800;color:var(--navy);font-size:.98em}.dbx .vz-title:empty{display:none}.dbx .vz-ctl{margin-left:auto;display:flex;align-items:center;gap:6px}.dbx .vz-ctl button{border:1px solid var(--line);background:#fff;border-radius:8px;min-width:32px;height:30px;cursor:pointer;font-size:14px;color:var(--navy);font-family:inherit}.dbx .vz-ctl button:hover{border-color:var(--accent);color:var(--accent)}.dbx .vz-ctl button.play{background:linear-gradient(135deg,#FF3621,#7C4DFF);color:#fff;border:0;padding:0 12px;font-weight:700}.dbx .vz-ctl .cnt{font-size:.8em;color:var(--muted);min-width:44px;text-align:center}.dbx .vz-notes{margin-top:10px}.dbx .vz-note{display:flex;gap:10px;align-items:flex-start;padding:9px 12px;border-radius:10px;background:#F1F5F9;margin-top:6px;font-size:.93em}.dbx .vz-note b{color:var(--navy)}.dbx .vz-note b.vz-lb{display:inline-block;background:var(--navy);color:#fff;border-radius:7px;padding:0 9px;margin-right:4px;font-size:.9em}.dbx .vz-n{flex:none;width:24px;height:24px;border-radius:50%;background:linear-gradient(135deg,#FF3621,#7C4DFF);color:#fff;font-weight:800;font-size:.78em;display:inline-flex;align-items:center;justify-content:center}.dbx .vz.js .vz-note{display:none}.dbx .vz.js .vz-note.on{display:flex;animation:dbxRise .35s both;background:linear-gradient(135deg,#FFF4F1,#F5F3FF);border:1px solid #FFD0C7}.dbx .vz-cap{margin-top:8px;color:var(--muted);font-size:.86em;text-align:center}.dbx .c-bronze{--c:#B45309;--cb:#FEF3E2}.dbx .c-silver{--c:#64748B;--cb:#F1F5F9}.dbx .c-gold{--c:#CA8A04;--cb:#FEF9C3}.dbx .c-red{--c:#DC2626;--cb:#FEE2E2}.dbx .c-blue{--c:#2563EB;--cb:#DBEAFE}.dbx .c-teal{--c:#0D9488;--cb:#CCFBF1}.dbx .c-purple{--c:#7C3AED;--cb:#EDE9FE}.dbx .c-amber{--c:#D97706;--cb:#FEF3C7}.dbx .c-green{--c:#16A34A;--cb:#DCFCE7}.dbx .c-navy{--c:#1B3139;--cb:#E2E8F0}.dbx .c-gray{--c:#6B7280;--cb:#F3F4F6}.dbx .c-pink{--c:#DB2777;--cb:#FCE7F3}.dbx .vz-ic{font-size:26px;line-height:1.1}.dbx .vz-flow{display:flex;align-items:stretch;gap:0;flex-wrap:wrap;justify-content:center}.dbx .vz-node{flex:1 1 130px;max-width:260px;background:var(--cb);border:2px solid var(--c);border-radius:14px;padding:12px 12px 10px;text-align:center;animation:vzPop .5s both;animation-delay:calc(var(--i)*.14s);transition:transform .3s,opacity .3s,box-shadow .3s}.dbx .vz-node b{display:block;color:var(--c);font-size:1.02em;margin-top:4px}.dbx .vz-node>span{display:block;color:#475569;font-size:.84em;line-height:1.35}.dbx .vz-node ul{text-align:left;margin:6px 0 0;padding-left:18px;font-size:.82em;color:#334155}.dbx .vz-node li{margin:2px 0}.dbx .vz-node[data-state=dim]{opacity:.38}.dbx .vz-node[data-state=hl]{transform:translateY(-4px) scale(1.04);box-shadow:0 10px 26px rgba(27,49,57,.2)}.dbx .vz-edge{flex:0 0 64px;display:flex;flex-direction:column;justify-content:center;align-items:center;padding:0 4px}.dbx .vz-edge em{font-size:.72em;color:var(--muted);font-style:normal;text-align:center;line-height:1.2;margin-bottom:4px;min-height:1em}.dbx .vz-line{position:relative;width:100%;height:4px;border-radius:4px;background:#CBD5E1;overflow:visible}.dbx .vz-line:after{content:"";position:absolute;right:-2px;top:-5px;border-left:9px solid #94A3B8;border-top:7px solid transparent;border-bottom:7px solid transparent}.dbx .vz-line i{position:absolute;top:-3px;width:10px;height:10px;border-radius:50%;background:var(--accent);animation:vzDot 2.1s linear infinite}.dbx .vz-line i:nth-child(2){animation-delay:.7s;background:var(--purple)}.dbx .vz-line i:nth-child(3){animation-delay:1.4s;background:var(--teal)}.dbx .vz-group{border:1px solid var(--line);border-radius:12px;background:#fff;margin-bottom:8px;overflow:hidden}.dbx .vz-group.log{border-color:#DDD6FE;background:#FAF5FF}.dbx .vz-dir{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.84em;font-weight:700;color:var(--navy);padding:6px 12px;background:rgba(27,49,57,.05)}.dbx .vz-file{display:flex;align-items:center;gap:8px;padding:5px 12px;border-top:1px solid #F1F5F9;font-size:.86em;transition:opacity .3s,background .3s}.dbx .vz-file .fn{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;color:#0F172A;word-break:break-all}.dbx .vz-tag{font-size:.82em;background:#EEF2FF;color:#3730A3;border-radius:999px;padding:1px 9px;white-space:nowrap}.dbx .vz-tag[data-state=new]{animation:vzPop .45s both;background:#FEF3C7;color:#92400E}.dbx .vz-file .fs{margin-left:auto;font-size:.72em;font-weight:800;border-radius:999px;padding:1px 9px;white-space:nowrap}.dbx .vz-group:not(.log) .vz-file .fs:after{content:"active";color:#15803D}.dbx .vz-group:not(.log) .vz-file .fs{background:#DCFCE7}.dbx .vz-file[data-state=new]{animation:vzPop .5s both;background:#F0FDF4}.dbx .vz-file[data-state=new] .fi{animation:vzGlow 1.2s 2;border-radius:50%}.dbx .vz-file[data-state=tomb],.dbx .vz-file[data-state=tombnew]{background:#F8FAFC}.dbx .vz-file[data-state=tomb] .fn,.dbx .vz-file[data-state=tombnew] .fn{text-decoration:line-through;color:#94A3B8}.dbx .vz-group:not(.log) .vz-file[data-state=tomb] .fs,.dbx .vz-group:not(.log) .vz-file[data-state=tombnew] .fs{background:#E2E8F0}.dbx .vz-group:not(.log) .vz-file[data-state=tomb] .fs:after,.dbx .vz-group:not(.log) .vz-file[data-state=tombnew] .fs:after{content:"removed (tombstone)";color:#475569}.dbx .vz-file[data-state=tombnew]{animation:vzPop .45s both;background:#FFF7ED}.dbx .vz-file[data-state=del]{background:#FEF2F2;animation:vzFade 1.2s .3s both}.dbx .vz-file[data-state=del] .fn{text-decoration:line-through;color:#B91C1C}.dbx .vz-group:not(.log) .vz-file[data-state=del] .fs{background:#FEE2E2}.dbx .vz-group .vz-file[data-state=del] .fs:after{content:"deleted from storage";color:#B91C1C}.dbx .vz-legend{display:flex;gap:14px;flex-wrap:wrap;font-size:.76em;color:var(--muted);margin-top:4px}.dbx .lg:before{content:"";display:inline-block;width:10px;height:10px;border-radius:3px;margin-right:5px;vertical-align:-1px}.dbx .lg.on:before{background:#22C55E}.dbx .lg.tomb:before{background:#94A3B8}.dbx .lg.log:before{background:#A78BFA}.dbx .vz-table .tbl{margin:0}.dbx .vz-table td{transition:background .3s}.dbx .vz-table td i{color:#94A3B8}.dbx .vz-table tr[data-state=new] td{background:#DCFCE7!important;animation:vzPop .45s both}.dbx .vz-table tr[data-state=upd] td{background:#FEF9C3!important}.dbx .vz-table tr[data-state=hl] td{background:#DBEAFE!important}.dbx .vz-table tr[data-state=del] td,.dbx .vz-table tr[data-state=delnew] td{background:#FEE2E2!important;text-decoration:line-through;color:#991B1B}.dbx .vz-table tr[data-state=del] td{opacity:.55}.dbx .vz-table td span[data-state=new]{display:inline-block;animation:vzPop .45s both;background:#FDE047;border-radius:5px;padding:0 5px;font-weight:700}.dbx pre.vz-code{margin:0;background:#0D1117;color:#E6EDF3;border-radius:12px;padding:12px 0;font-size:12.5px;line-height:1.6;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;white-space:pre-wrap;word-break:break-all;overflow-x:auto}.dbx .vz-ln{display:block;padding:0 14px 0 46px;position:relative;border-left:3px solid transparent;transition:opacity .3s,background .3s}.dbx .vz-ln>i{position:absolute;left:0;width:34px;text-align:right;color:#6E7681;font-style:normal;user-select:none}.dbx .vz.js .vz-ln[data-state=dim]{opacity:.32}.dbx .vz.js .vz-ln[data-state=hl]{background:rgba(255,214,10,.13);border-left-color:#FBBF24}.dbx .vz-cards{display:flex;gap:12px;flex-wrap:wrap}.dbx .vz-card{flex:1 1 200px;background:#fff;border:1px solid var(--line);border-top:5px solid var(--c);border-radius:14px;padding:14px;animation:vzPop .5s both;animation-delay:calc(var(--i)*.14s)}.dbx .vz-card b{display:block;color:var(--c);font-size:1.05em;margin-top:4px}.dbx .vz-card>span{display:block;color:var(--muted);font-size:.85em;min-height:1.2em}.dbx .vz-card ul{list-style:none;padding:0;margin:8px 0 0;font-size:.88em}.dbx .vz-card li{margin:5px 0;padding:5px 9px;border-radius:8px;background:#F8FAFC;list-style:none}.dbx .vz-card li.good{background:#ECFDF3;border:0;margin:5px 0;padding:5px 9px}.dbx .vz-card li.bad{background:#FFF1F0;border:0;margin:5px 0;padding:5px 9px}.dbx .vz-foot{margin-top:8px;font-size:.82em;color:var(--c);font-weight:700}.dbx .vz-tls{display:flex;gap:0;flex-wrap:wrap;position:relative;padding-top:4px}.dbx .vz-tl{flex:1 1 110px;text-align:center;position:relative;padding:0 6px 4px;animation:vzPop .45s both;animation-delay:calc(var(--i)*.1s)}.dbx .vz-tl:before{content:"";position:absolute;top:17px;left:0;right:0;height:4px;background:#E2E8F0;z-index:0}.dbx .vz-dot{position:relative;z-index:1;display:inline-flex;align-items:center;justify-content:center;min-width:38px;height:38px;padding:0 8px;border-radius:999px;background:var(--c);color:#fff;font-weight:800;font-size:.82em;box-shadow:0 4px 12px rgba(27,49,57,.2)}.dbx .vz-tl b{display:block;color:var(--navy);font-size:.88em;margin-top:6px;line-height:1.25}.dbx .vz-tl>span:last-child{display:block;color:var(--muted);font-size:.78em;line-height:1.3}.dbx .vz .vz-tl[data-state=hide]{display:block!important;visibility:hidden}.dbx .vz-tl[data-state=new] .vz-dot{animation:vzGlow 1.2s 2;transform:scale(1.15)}.dbx .vz-layers{display:flex;flex-direction:column;gap:8px}.dbx .vz-layer{display:flex;align-items:center;gap:12px;background:var(--cb);border-left:6px solid var(--c);border-radius:12px;padding:10px 14px;animation:vzPop .5s both;animation-delay:calc(var(--i)*.14s)}.dbx .vz-lt{flex:0 0 30%;min-width:150px}.dbx .vz-lt b{display:block;color:var(--c)}.dbx .vz-lt em{font-style:normal;color:#475569;font-size:.84em}.dbx .vz-li{display:flex;gap:6px;flex-wrap:wrap;flex:1}.dbx .vz-li span{background:#fff;border:1px solid rgba(0,0,0,.08);border-radius:999px;padding:3px 11px;font-size:.84em;color:#334155}.dbx ul.vz-tree,.dbx ul.vz-tree ul{list-style:none;margin:0;padding-left:26px;position:relative}.dbx ul.vz-tree{padding-left:0}.dbx ul.vz-tree li{margin:6px 0;position:relative;list-style:none}.dbx ul.vz-tree ul li:before{content:"";position:absolute;left:-16px;top:-6px;width:14px;height:24px;border-left:2px solid #CBD5E1;border-bottom:2px solid #CBD5E1;border-bottom-left-radius:8px}.dbx .vz-tn{display:inline-flex;align-items:center;gap:8px;background:var(--cb);border:1.5px solid var(--c);border-radius:10px;padding:5px 12px;animation:vzPop .45s both;animation-delay:calc(var(--i)*.08s)}.dbx .vz-tn .vz-ic{font-size:18px}.dbx .vz-tn b{color:var(--c)}.dbx .vz-tn em{font-style:normal;color:#475569;font-size:.84em}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/* Step-through visualizations. Elements carry data-st="0:state,2:state"; a step sets data-state. */
|
|
2
|
+
(function () {
|
|
3
|
+
if (window.DBXViz) return;
|
|
4
|
+
function parse(el) {
|
|
5
|
+
if (!el._st) {
|
|
6
|
+
el._st = el.getAttribute('data-st').split(',').map(function (p) {
|
|
7
|
+
var i = p.indexOf(':');
|
|
8
|
+
return [+p.slice(0, i), p.slice(i + 1)];
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
return el._st;
|
|
12
|
+
}
|
|
13
|
+
function apply(vz, k) {
|
|
14
|
+
vz._k = k;
|
|
15
|
+
vz.querySelectorAll('[data-st]').forEach(function (el) {
|
|
16
|
+
var m = parse(el), s = m[0][1];
|
|
17
|
+
for (var i = 0; i < m.length; i++) if (m[i][0] <= k) s = m[i][1];
|
|
18
|
+
if (el.getAttribute('data-state') !== s) el.setAttribute('data-state', s);
|
|
19
|
+
});
|
|
20
|
+
vz.querySelectorAll('.vz-note').forEach(function (n) {
|
|
21
|
+
n.classList.toggle('on', +n.getAttribute('data-step') === k);
|
|
22
|
+
});
|
|
23
|
+
if (vz._cnt) vz._cnt.textContent = (k + 1) + ' / ' + vz._n;
|
|
24
|
+
if (vz._play) vz._play.textContent = k >= vz._n - 1 ? '↻ Replay' : (vz._timer ? '⏸ Pause' : '▶ Play');
|
|
25
|
+
}
|
|
26
|
+
function stop(vz) {
|
|
27
|
+
if (vz._timer) { clearInterval(vz._timer); vz._timer = null; }
|
|
28
|
+
}
|
|
29
|
+
function step(vz, dir) {
|
|
30
|
+
var k = vz._k + dir;
|
|
31
|
+
if (k < 0 || k >= vz._n) return false;
|
|
32
|
+
apply(vz, k);
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
function play(vz, ms) {
|
|
36
|
+
stop(vz);
|
|
37
|
+
if (vz._k >= vz._n - 1) apply(vz, 0);
|
|
38
|
+
vz._timer = setInterval(function () {
|
|
39
|
+
if (!step(vz, 1) || vz._k >= vz._n - 1) { stop(vz); apply(vz, vz._k); }
|
|
40
|
+
}, ms || 2200);
|
|
41
|
+
apply(vz, vz._k);
|
|
42
|
+
}
|
|
43
|
+
function setup(vz, opts) {
|
|
44
|
+
if (vz._n) return;
|
|
45
|
+
vz._n = +vz.getAttribute('data-steps');
|
|
46
|
+
vz.classList.add('js');
|
|
47
|
+
var ctl = vz.querySelector('.vz-ctl');
|
|
48
|
+
function btn(label, title, cls, fn) {
|
|
49
|
+
var b = document.createElement('button');
|
|
50
|
+
b.type = 'button'; b.textContent = label; b.title = title; if (cls) b.className = cls;
|
|
51
|
+
b.onclick = function (e) { e.stopPropagation(); fn(); };
|
|
52
|
+
ctl.appendChild(b);
|
|
53
|
+
return b;
|
|
54
|
+
}
|
|
55
|
+
btn('◀', 'Previous step', '', function () { stop(vz); step(vz, -1); apply(vz, vz._k); });
|
|
56
|
+
vz._cnt = document.createElement('span'); vz._cnt.className = 'cnt'; ctl.appendChild(vz._cnt);
|
|
57
|
+
btn('▶', 'Next step', '', function () { stop(vz); step(vz, 1); apply(vz, vz._k); });
|
|
58
|
+
vz._play = btn('▶ Play', 'Play all steps', 'play', function () {
|
|
59
|
+
if (vz._timer) { stop(vz); apply(vz, vz._k); } else play(vz);
|
|
60
|
+
});
|
|
61
|
+
apply(vz, 0);
|
|
62
|
+
if (opts && opts.autoplay && 'IntersectionObserver' in window) {
|
|
63
|
+
var io = new IntersectionObserver(function (entries) {
|
|
64
|
+
if (entries[0].isIntersecting) { io.disconnect(); setTimeout(function () { if (vz._k === 0) play(vz); }, 700); }
|
|
65
|
+
}, { threshold: 0.6 });
|
|
66
|
+
io.observe(vz);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
window.DBXViz = {
|
|
70
|
+
init: function (root, opts) {
|
|
71
|
+
(root || document).querySelectorAll('.vz[data-steps]').forEach(function (vz) { setup(vz, opts); });
|
|
72
|
+
},
|
|
73
|
+
step: function (vz, dir) { stop(vz); var ok = step(vz, dir); apply(vz, vz._k); return ok; },
|
|
74
|
+
pending: function (root, dir) {
|
|
75
|
+
var list = Array.prototype.slice.call(root.querySelectorAll('.vz[data-steps]'));
|
|
76
|
+
if (dir < 0) list.reverse();
|
|
77
|
+
for (var i = 0; i < list.length; i++) {
|
|
78
|
+
var vz = list[i];
|
|
79
|
+
if (vz._n && (dir > 0 ? vz._k < vz._n - 1 : vz._k > 0)) return vz;
|
|
80
|
+
}
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
})();
|