function intro()

in modules/ui/intro/intro.js [58:208]


    function intro(selection) {
        context.enter(modeBrowse(context));

        // Save current map state
        var osm = context.connection();
        var history = context.history().toJSON();
        var hash = window.location.hash;
        var center = context.map().center();
        var zoom = context.map().zoom();
        var background = context.background().baseLayerSource();
        var overlays = context.background().overlayLayerSources();
        var opacity = d3_selectAll('#map .layer-background').style('opacity');
        var caches = osm && osm.caches();
        var baseEntities = context.history().graph().base().entities;

        // Block saving
        context.inIntro(true);

        // Load semi-real data used in intro
        if (osm) { osm.toggle(false).reset(); }
        context.history().reset();
        context.history().merge(Object.values(coreGraph().load(introGraph).entities));
        context.history().checkpoint('initial');

        // Setup imagery
        var imagery = context.background().findSource(INTRO_IMAGERY);
        if (imagery) {
            context.background().baseLayerSource(imagery);
        } else {
            context.background().bing();
        }
        overlays.forEach(function(d) {
            context.background().toggleOverlayLayer(d);
        });

        // Setup data layers (only OSM)
        var layers = context.layers();
        layers.all().forEach(function(item) {
            // if the layer has the function `enabled`
            if (typeof item.layer.enabled === 'function') {
                item.layer.enabled(item.id === 'osm');
            }
        });


        d3_selectAll('#map .layer-background').style('opacity', 1);

        var curtain = uiCurtain();
        selection.call(curtain);

        // Store that the user started the walkthrough..
        context.storage('walkthrough_started', 'yes');

        // Restore previous walkthrough progress..
        var storedProgress = context.storage('walkthrough_progress') || '';
        var progress = storedProgress.split(';').filter(Boolean);

        var chapters = chapterFlow.map(function(chapter, i) {
            var s = chapterUi[chapter](context, curtain.reveal)
                .on('done', function() {
                    context.presets().init();  // clear away "recent" presets

                    buttons.filter(function(d) {
                        return d.title === s.title;
                    }).classed('finished', true);

                    if (i < chapterFlow.length - 1) {
                        var next = chapterFlow[i + 1];
                        d3_select('button.chapter-' + next)
                            .classed('next', true);
                    }

                    // Store walkthrough progress..
                    progress.push(chapter);
                    context.storage('walkthrough_progress', utilArrayUniq(progress).join(';'));
                });
            return s;
        });

        chapters[chapters.length - 1].on('startEditing', function() {
            // Store walkthrough progress..
            progress.push('startEditing');
            context.storage('walkthrough_progress', utilArrayUniq(progress).join(';'));

            // Store if walkthrough is completed..
            var incomplete = utilArrayDifference(chapterFlow, progress);
            if (!incomplete.length) {
                context.storage('walkthrough_completed', 'yes');
            }

            curtain.remove();
            navwrap.remove();
            d3_selectAll('#map .layer-background').style('opacity', opacity);
            if (osm) { osm.toggle(true).reset().caches(caches); }
            context.history().reset().merge(Object.values(baseEntities));
            context.background().baseLayerSource(background);
            overlays.forEach(function(d) { context.background().toggleOverlayLayer(d); });
            if (history) { context.history().fromJSON(history, false); }
            context.map().centerZoom(center, zoom);
            window.location.replace(hash);
            context.inIntro(false);
        });

        var navwrap = selection
            .append('div')
            .attr('class', 'intro-nav-wrap fillD');

        navwrap
            .append('svg')
            .attr('class', 'intro-nav-wrap-logo')
            .append('use')
            .attr('xlink:href', '#iD-logo-walkthrough');

        var buttonwrap = navwrap
            .append('div')
            .attr('class', 'joined')
            .selectAll('button.chapter');

        var buttons = buttonwrap
            .data(chapters)
            .enter()
            .append('button')
            .attr('class', function(d, i) { return 'chapter chapter-' + chapterFlow[i]; })
            .on('click', enterChapter);

        buttons
            .append('span')
            .text(function(d) { return t(d.title); });

        buttons
            .append('span')
            .attr('class', 'status')
            .call(svgIcon((textDirection === 'rtl' ? '#iD-icon-backward' : '#iD-icon-forward'), 'inline'));

        enterChapter(chapters[0]);


        function enterChapter(newChapter) {
            if (_currChapter) { _currChapter.exit(); }
            context.enter(modeBrowse(context));

            _currChapter = newChapter;
            _currChapter.enter();

            buttons
                .classed('next', false)
                .classed('active', function(d) {
                    return d.title === _currChapter.title;
                });
        }
    }