"use strict";
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (_) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getServerSideProps = void 0;
var jsx_runtime_1 = require("react/jsx-runtime");
var antd_1 = require("antd");
var footer_1 = __importDefault(require("components/landing/footer"));
var A_1 = __importDefault(require("components/misc/A"));
var header_1 = __importDefault(require("components/landing/header"));
var content_1 = __importDefault(require("components/landing/content"));
var with_customize_1 = __importDefault(require("lib/with-customize"));
var customize_1 = require("lib/customize");
var sign_in_1 = __importDefault(require("components/landing/sign-in"));
var info_1 = __importDefault(require("components/landing/info"));
var pitch_1 = __importDefault(require("components/landing/pitch"));
var head_1 = __importDefault(require("components/landing/head"));
var latex_1 = __importDefault(require("components/landing/latex"));
var backups_1 = __importDefault(require("components/landing/backups"));
var compare_1 = __importDefault(require("components/landing/compare"));
var icon_1 = require("@cocalc/frontend/components/icon");
var jupyter_logo_svg_1 = __importDefault(require("/public/features/jupyter-logo.svg"));
var cocalc_jupyter2_20170508_png_1 = __importDefault(require("/public/features/cocalc-jupyter2-20170508.png"));
var cocalc_real_time_jupyter_png_1 = __importDefault(require("/public/features/cocalc-real-time-jupyter.png"));
var cocalc_jupyter_nbgrader_overview_png_1 = __importDefault(require("/public/features/cocalc-jupyter-nbgrader-overview.png"));
var cocalc_chat_jupyter_20171120_2_png_1 = __importDefault(require("/public/features/cocalc-chat-jupyter-20171120-2.png"));
var cocalc_jupyter_kernels_png_1 = __importDefault(require("/public/features/cocalc-jupyter-kernels.png"));
var jupyter_lab_png_1 = __importDefault(require("/public/features/jupyter-lab.png"));
var cocalc_jupyter2_memory_cpu_png_1 = __importDefault(require("/public/features/cocalc-jupyter2-memory-cpu.png"));
var cocalc_jupyter_share_nasa_png_1 = __importDefault(require("/public/features/cocalc-jupyter-share-nasa.png"));
function JupyterNotebook(_a) {
    var customize = _a.customize;
    function pitchNoSetup() {
        return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("h2", { children: ["No software setup: ", (0, jsx_runtime_1.jsx)("small", { children: "100% online" })] }), (0, jsx_runtime_1.jsxs)("p", { children: ["CoCalc is an online web service where you can", " ", (0, jsx_runtime_1.jsxs)("strong", { children: ["run ", (0, jsx_runtime_1.jsx)(A_1.default, __assign({ href: "http://jupyter.org/" }, { children: "Jupyter notebooks" })), " right inside your browser"] }), ". You can privately share your notebook with your", " ", (0, jsx_runtime_1.jsx)(A_1.default, __assign({ href: "https://doc.cocalc.com/project-settings.html#about-collaborators" }, { children: "project collaborators" })), " ", "\u2013 all changes are", " ", (0, jsx_runtime_1.jsx)(A_1.default, __assign({ href: "#a-realtimesync" }, { children: (0, jsx_runtime_1.jsx)("strong", { children: "synchronized in real-time" }) })), "."] }), (0, jsx_runtime_1.jsxs)("p", { children: ["You no longer have to worry about setting up your Python environment, installing/updating/maintaining your libraries, or backing up files. CoCalc manages everything for you!", " "] })] }));
    }
    function pitchTeaching() {
        return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h2", { children: "Jupyter Notebooks made for teaching!" }), (0, jsx_runtime_1.jsxs)("ul", { children: [(0, jsx_runtime_1.jsxs)("li", { children: ["A sophisticated", " ", (0, jsx_runtime_1.jsx)("strong", { children: (0, jsx_runtime_1.jsx)(A_1.default, __assign({ href: "/features/teaching" }, { children: "course management system" })) }), " ", "keeps track of all notebooks of all students. It manages distributing and collecting files as well as grading."] }), (0, jsx_runtime_1.jsxs)("li", { children: ["The", " ", (0, jsx_runtime_1.jsx)(A_1.default, __assign({ href: "/features/whiteboard" }, { children: "Jupyter collaborative whiteboard" })), " ", "supports presentations that mix Jupyter cells, mathematical notation, and sketching with a pen and other tools."] }), (0, jsx_runtime_1.jsxs)("li", { children: ["CoCalc", "'", "s Jupyter Notebooks fully support", " ", (0, jsx_runtime_1.jsx)(A_1.default, __assign({ href: "https://doc.cocalc.com/teaching-nbgrader.html" }, { children: (0, jsx_runtime_1.jsx)("strong", { children: "very flexible automatic grading via nbgrader" }) })), "! The teacher", "'", "s notebook contains exercise cells for students and test cells, some of which students can also run to get immediate feedback. Once collected, you tell CoCalc to automatically run the full test suite across all student notebooks and tabulate the results."] })] }), (0, jsx_runtime_1.jsxs)("p", { children: ["CoCalc supports many kernels right out of the box: several Python environments, ", (0, jsx_runtime_1.jsx)(A_1.default, __assign({ href: "http://www.sagemath.org/" }, { children: "SageMath" })), ",", " ", (0, jsx_runtime_1.jsx)(A_1.default, __assign({ href: "http://www.r-project.org/" }, { children: "R Statistical Software" })), "Octave, ", (0, jsx_runtime_1.jsx)(A_1.default, __assign({ href: "/features/julia" }, { children: "Julia" })), " and many more.", " "] })] }));
    }
    return ((0, jsx_runtime_1.jsxs)(customize_1.Customize, __assign({ value: customize }, { children: [(0, jsx_runtime_1.jsx)(head_1.default, { title: "Online Jupyter Notebooks" }), (0, jsx_runtime_1.jsxs)(antd_1.Layout, { children: [(0, jsx_runtime_1.jsx)(header_1.default, { page: "features", subPage: "jupyter-notebook" }), (0, jsx_runtime_1.jsxs)(antd_1.Layout.Content, { children: [(0, jsx_runtime_1.jsx)("div", __assign({ style: { backgroundColor: "#c7d9f5" } }, { children: (0, jsx_runtime_1.jsx)(content_1.default, { startup: "Jupyter", logo: jupyter_logo_svg_1.default, title: "Online Jupyter Notebooks", subtitle: "CoCalc's own collaborative, fully compatible and supercharged notebooks.", subtitleBelow: true, image: cocalc_jupyter2_20170508_png_1.default, alt: "Using Pandas and Tensorflow in a Jupyter notebook" }) })), (0, jsx_runtime_1.jsx)(pitch_1.default, { col1: pitchTeaching(), col2: pitchNoSetup(), ext: "ipynb" }), (0, jsx_runtime_1.jsx)(sign_in_1.default, { startup: "Jupyter" }), (0, jsx_runtime_1.jsxs)(info_1.default, __assign({ title: "Collaborative editing", icon: "users", image: cocalc_real_time_jupyter_png_1.default, anchor: "a-realtimesync", alt: "Two browser windows editing the same Jupyter notebook" }, { children: [(0, jsx_runtime_1.jsxs)("p", { children: ["You can share your Jupyter notebooks privately with project collaborators. All modifications are", " ", (0, jsx_runtime_1.jsx)("strong", { children: "synchronized in real time" }), ", where you can see the cursors of others while they edit the document. You are also notified about the presence of collaborators."] }), (0, jsx_runtime_1.jsxs)("p", { children: ["Edit text between code cells using", " ", (0, jsx_runtime_1.jsx)(A_1.default, __assign({ href: "https://doc.cocalc.com/markdown.html" }, { children: "markdown or our collaborative rich text editor" })), "."] }), (0, jsx_runtime_1.jsxs)("p", { children: ["We have extended ipywidgets so that sliders, menus and knobs of", " ", (0, jsx_runtime_1.jsx)(A_1.default, __assign({ href: "https://ipywidgets.readthedocs.io/en/stable/examples/Widget%20Basics.html" }, { children: "interactive widgets" })), " ", "are also fully synchronized among all collaborators."] }), (0, jsx_runtime_1.jsx)("p", { children: "Additionally, the status and results of all computations in the currently running kernel session are also synchronized, because the session runs remotely in CoCalc's cluster." }), (0, jsx_runtime_1.jsx)("p", { children: "Together, everyone involved experiences the notebook in the same way." })] })), (0, jsx_runtime_1.jsx)(info_1.default.Heading, __assign({ description: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: ["The following are some more specific features of Jupyter notebooks in CoCalc.", (0, jsx_runtime_1.jsx)("br", {}), "There is also more", " ", (0, jsx_runtime_1.jsx)(A_1.default, __assign({ href: "https://doc.cocalc.com/jupyter.html" }, { children: "comprehensive documentation" })), "."] }) }, { children: "Feature Overview" })), (0, jsx_runtime_1.jsxs)(info_1.default, __assign({ anchor: "a-timetravel", title: "TimeTravel", icon: "history", video: [
                                    "features/cocalc-jupyter2-timetravel-20170515-3x.webm",
                                    "features/cocalc-jupyter2-timetravel-20170515-3x.mp4",
                                ], alt: "Video showing the TimeTravel slider in a SageMath Jupyter notebook" }, { children: [(0, jsx_runtime_1.jsxs)("p", { children: [(0, jsx_runtime_1.jsx)("strong", { children: (0, jsx_runtime_1.jsx)(A_1.default, __assign({ href: "https://doc.cocalc.com/time-travel.html" }, { children: "TimeTravel" })) }), " ", "is a powerful feature of the CoCalc platform. It records all your changes in your Jupyter notebook in fine detail. You can go back and forth in time across thousands of changes to see all previous edits."] }), (0, jsx_runtime_1.jsx)("p", { children: "This allows you to easily recover anything from previous versions of your notebook by copy and pasting." }), (0, jsx_runtime_1.jsx)("p", { children: "You can also browse the entire process of creating the notebook from the start. This lets you discover how you arrived at a particular solution and see what you (or your students) tried to get there." })] })), (0, jsx_runtime_1.jsxs)(info_1.default, __assign({ anchor: "a-nbgrader", title: "NBGrader: automatically grading assignments in Jupyter notebooks", icon: "graduation-cap", image: cocalc_jupyter_nbgrader_overview_png_1.default, alt: "Creating an NBGrader-enhanced Jupyter notebook" }, { children: [(0, jsx_runtime_1.jsxs)("p", { children: ["CoCalc's Jupyter Notebooks fully support both", " ", (0, jsx_runtime_1.jsx)("strong", { children: "automatic" }), " and ", (0, jsx_runtime_1.jsx)("strong", { children: "manual grading" }), "!"] }), (0, jsx_runtime_1.jsx)("p", { children: "When using NBGrader, the teacher's notebook contains exercise cells for students and test cells, some of which students run to get immediate feedback. Once collected, you tell CoCalc to automatically run the full test suite across all student notebooks and tabulate the results." }), (0, jsx_runtime_1.jsxs)("p", { children: ["Learn more about", " ", (0, jsx_runtime_1.jsx)(A_1.default, __assign({ href: "https://doc.cocalc.com/teaching-nbgrader.html" }, { children: "NBGrader in CoCalc" })), ".", " "] })] })), (0, jsx_runtime_1.jsxs)(info_1.default, __assign({ anchor: "a-chat", title: "Chat about your Jupyter notebook", icon: "comment", image: cocalc_chat_jupyter_20171120_2_png_1.default, alt: "Chatting about a Jupyter notebook" }, { children: [(0, jsx_runtime_1.jsxs)("p", { children: ["A", " ", (0, jsx_runtime_1.jsx)("strong", { children: (0, jsx_runtime_1.jsx)(A_1.default, __assign({ href: "https://doc.cocalc.com/chat.html" }, { children: "chat to the side" })) }), " ", "of each Jupyter notebook lets you discuss the content of your notebook with colleagues or students. You can drag and drop or paste images and files into chat, use ", (0, jsx_runtime_1.jsx)(latex_1.default, {}), " math formulas, and fix typos in messages."] }), (0, jsx_runtime_1.jsx)("p", { children: "Collaborators who are not online will be notified about new messages the next time they sign in or you can @mention them so they get emailed." }), (0, jsx_runtime_1.jsxs)("p", { children: ["Chat fully supports markdown formatting and ", (0, jsx_runtime_1.jsx)(latex_1.default, {}), " formulas.", " "] })] })), (0, jsx_runtime_1.jsxs)(info_1.default, __assign({ anchor: "a-kernels", title: "Managed Jupyter kernels", icon: "python", image: cocalc_jupyter_kernels_png_1.default, alt: "Dropdown menu showing a large number of preinstalled Jupyter kernels" }, { children: [(0, jsx_runtime_1.jsxs)("p", { children: ["CoCalc makes sure that your desired computational environment is available and ready to work with. Select from many pre-installed and ", (0, jsx_runtime_1.jsx)("strong", { children: "fully managed kernels" }), ". You can also create your own", " ", (0, jsx_runtime_1.jsx)(A_1.default, __assign({ href: "https://doc.cocalc.com/howto/custom-jupyter-kernel.html" }, { children: "custom kernel" })), "."] }), (0, jsx_runtime_1.jsxs)("p", { children: ["Look at our ", (0, jsx_runtime_1.jsx)(A_1.default, __assign({ href: "/software" }, { children: "list of available software" })), " for more about what is available."] })] })), (0, jsx_runtime_1.jsxs)(info_1.default, __assign({ anchor: "a-kernels", title: "JupyterLab and Jupyter Classic", icon: "server", image: jupyter_lab_png_1.default, alt: "Running JupyterLab inside a CoCalc Project", wide: true }, { children: [(0, jsx_runtime_1.jsxs)("p", { children: ["CoCalc's Jupyter is a ", (0, jsx_runtime_1.jsx)("strong", { children: "complete rewrite" }), " of the classical ", (0, jsx_runtime_1.jsx)(A_1.default, __assign({ href: "http://jupyter.org/" }, { children: "Jupyter notebook" })), " ", "interface and backend server. It is tightly integrated into CoCalc and adds realtime collaboration, TimeTravel history and", " ", (0, jsx_runtime_1.jsx)(A_1.default, __assign({ href: "http://blog.sagemath.com/jupyter/2017/05/05/jupyter-rewrite-for-smc.html" }, { children: "more" })), ". This rewrite does not change the underlying Jupyter notebook file format; you can download your ", (0, jsx_runtime_1.jsx)("code", { children: "*.ipynb" }), " file at any time and continue working in another environment."] }), (0, jsx_runtime_1.jsxs)("p", { children: ["In addition, CoCalc also", " ", (0, jsx_runtime_1.jsx)(A_1.default, __assign({ href: "https://doc.cocalc.com/jupyter.html#alternatives-plain-jupyter-server-and-jupyterlab-server" }, { children: "fully supports running" })), " ", "standard JupyterLab (with realtime collaboration enabled) and Jupyter Classic notebook servers from any CoCalc project! You can still use all libraries and extension that might rely on specifics of one of those implementations. Moreover,", " ", (0, jsx_runtime_1.jsx)("strong", { children: "you can fully use your CoCalc project via the powerful JupyterLab interface!" })] }), (0, jsx_runtime_1.jsxs)("p", { children: ["CoCalc also supports", " ", (0, jsx_runtime_1.jsx)(A_1.default, __assign({ href: "https://doc.cocalc.com/jupyter.html#collaboration-with-classical-jupyter" }, { children: "using Jupyter Classic with collaborative editing and chat" })), "."] })] })), (0, jsx_runtime_1.jsxs)(info_1.default, __assign({ anchor: "a-monitoring", title: "CPU and memory monitoring for each notebook", icon: "line-chart", image: cocalc_jupyter2_memory_cpu_png_1.default, alt: "Jupyter notebook showing CPU and memory indicators" }, { children: [(0, jsx_runtime_1.jsx)("p", { children: "Long running notebook sessions or intense computations might deplete available CPU or memory resources. This slows down all calculations or even causes an unexpected termination of the current session." }), (0, jsx_runtime_1.jsxs)("p", { children: ["CoCalc's per-notebook CPU and memory indicators helps you to", " ", (0, jsx_runtime_1.jsx)("strong", { children: "keep an eye on the notebook's memory and CPU consumption" }), ".", " "] }), (0, jsx_runtime_1.jsxs)("p", { children: ["You can even close your browser during long running computations, and check on the results later.", " ", (0, jsx_runtime_1.jsx)("strong", { children: "Output will not be lost" }), " while your browser is closed."] })] })), (0, jsx_runtime_1.jsx)(backups_1.default, {}), (0, jsx_runtime_1.jsxs)(info_1.default, __assign({ anchor: "a-publishing", title: "Publishing your notebooks", icon: "bullhorn", image: cocalc_jupyter_share_nasa_png_1.default, alt: "Jupyter notebook hosted on the CoCalc share server" }, { children: [(0, jsx_runtime_1.jsxs)("p", { children: ["CoCalc helps you", " ", (0, jsx_runtime_1.jsx)(A_1.default, __assign({ href: "/share" }, { children: (0, jsx_runtime_1.jsx)("strong", { children: "share your work with the world" }) })), ". It offers its own hosting of shared documents, which includes Jupyter notebooks and any other associated data files."] }), (0, jsx_runtime_1.jsxs)("p", { children: ["Under the hood, CoCalc uses a novel renderer which generates a static HTML representation of your notebook (sanitized to prevent XSS attacks) on the server, which includes pre-rendered ", (0, jsx_runtime_1.jsx)(latex_1.default, {}), " ", "formulas. This approach is very efficient and lightweight compared to solutions based on", " ", (0, jsx_runtime_1.jsx)(A_1.default, __assign({ href: "https://nbconvert.readthedocs.io" }, { children: "nbconvert" })), ".", " "] })] })), (0, jsx_runtime_1.jsx)(compare_1.default, { name: "jupyter", disclaimer: true, title: (0, jsx_runtime_1.jsxs)("h2", __assign({ style: { textAlign: "center" } }, { children: [(0, jsx_runtime_1.jsx)(icon_1.Icon, { name: "bolt" }), " Jupyter notebooks in CoCalc versus the competition"] })) }), (0, jsx_runtime_1.jsx)(sign_in_1.default, { startup: "Jupyter" })] }), (0, jsx_runtime_1.jsx)(footer_1.default, {})] })] })));
}
exports.default = JupyterNotebook;
function getServerSideProps(context) {
    return __awaiter(this, void 0, void 0, function () {
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0: return [4 /*yield*/, (0, with_customize_1.default)({ context: context })];
                case 1: return [2 /*return*/, _a.sent()];
            }
        });
    });
}
exports.getServerSideProps = getServerSideProps;
//# sourceMappingURL=jupyter-notebook.js.map