<commit_before>﻿define(function(require) {
    var system = require('../system'),
        viewModel = require('../viewModel');

    var routesByPath = {},
        allRoutes = ko.observableArray([]),
        visibleRoutes = ko.observableArray([]),
        ready = ko.observable(false),
        isNavigating = ko.observable(false),
        sammy,
        router,
        previousRoute,
        previousModule,
        cancelling = false,
        activeItem = viewModel.activator(),
        navigationDefaultRoute;

    //NOTE: Sammy.js is not required by the core of Durandal. 
    //However, this plugin leverages it to enable navigation.

    activeItem.settings.areSameItem = function(currentItem, newItem, activationData) {
        return false;
    };

    function activateRoute(routeInfo, params, module, forceStopNavigation) {
        params.routeInfo = routeInfo;
        params.router = router;

        system.log('Activating Route', routeInfo, module, params);

        activeItem.activateItem(module, params).then(function(succeeded) {
            if (succeeded) {
                document.title = routeInfo.name;
                previousModule = module;
                previousRoute = sammy.last_location[1].replace('/', '');

                if (forceStopNavigation) {
                    isNavigating(false);
                }
            } else {
                cancelling = true;
                system.log('Cancelling Navigation');
                sammy.setLocation(previousRoute);
                cancelling = false;
                isNavigating(false);
            }

            if (router.dfd) {
                ready(true);
                router.dfd.resolve();

                delete router.dfd;
            }
        });
    }
    
    function shouldStopNavigation() {
        return cancelling || (sammy.last_location[1].replace('/', '') == previousRoute);
    }

    function ensureRoute(route, params) {
        var routeInfo = routesByPath[route];
        
        if (shouldStopNavigation()) {
            return;
        }

        if (!routeInfo) {
            if (!router.autoConvertRouteToModuleId) {
                router.handleInvalidRoute(route, params);
                return;
            }

            routeInfo = {
                moduleId: router.autoConvertRouteToModuleId(route, params),
                name: router.convertRouteToName(route)
            };
        }
        
        isNavigating(true);

        system.acquire(routeInfo.moduleId).then(function(module) {
            if (typeof module == 'function') {
                activateRoute(routeInfo, params, new module());
            } else {
                activateRoute(routeInfo, params, module, previousModule == module);
            }
        });
    }

    function handleDefaultRoute() {
        ensureRoute(navigationDefaultRoute, this.params || {});
    }
    
    function handleMappedRoute() {
        ensureRoute(this.app.last_route.path.toString(), this.params || {});
    }

    function handleWildCardRoute() {
        var params = this.params || {}, route;

        if (router.autoConvertRouteToModuleId) {
            var fragment = this.path.split('#/');

            if (fragment.length == 2) {
                var parts = fragment[1].split('/');
                route = parts[0];
                var splat = parts.splice(1);
                if (splat.length > 0) {
                    params.splat = splat;
                }
                ensureRoute(route, params);
                return;
            }
        }

        router.handleInvalidRoute(this.app.last_location[1], params);
    }

    function configureRoute(routeInfo) {
        router.prepareRouteInfo(routeInfo);

        routesByPath[routeInfo.url] = routeInfo;
        allRoutes.push(routeInfo);

        if (routeInfo.visible) {
            routeInfo.isActive = ko.computed(function() {
                return ready() && activeItem() && activeItem().__moduleId__ == routeInfo.moduleId;
            });

            visibleRoutes.push(routeInfo);
        }

        return routeInfo;
    }

    return router = {
        ready: ready,
        allRoutes: allRoutes,
        visibleRoutes: visibleRoutes,
        isNavigating: isNavigating,
        activeItem: activeItem,
        afterCompose: function() {
            isNavigating(false);
        },
        useConvention: function (rootPath) {
            rootPath = rootPath || 'viewmodels';
            rootPath += '/';
            router.convertRouteToModuleId = function(url) {
                return rootPath + router.stripParameter(url);
            };
        },
        stripParameter: function(val) {<commit_msg>Allow router to use empty string root path.<commit_after>﻿define(function(require) {
    var system = require('../system'),
        viewModel = require('../viewModel');

    var routesByPath = {},
        allRoutes = ko.observableArray([]),
        visibleRoutes = ko.observableArray([]),
        ready = ko.observable(false),
        isNavigating = ko.observable(false),
        sammy,
        router,
        previousRoute,
        previousModule,
        cancelling = false,
        activeItem = viewModel.activator(),
        navigationDefaultRoute;

    //NOTE: Sammy.js is not required by the core of Durandal. 
    //However, this plugin leverages it to enable navigation.

    activeItem.settings.areSameItem = function(currentItem, newItem, activationData) {
        return false;
    };

    function activateRoute(routeInfo, params, module, forceStopNavigation) {
        params.routeInfo = routeInfo;
        params.router = router;

        system.log('Activating Route', routeInfo, module, params);

        activeItem.activateItem(module, params).then(function(succeeded) {
            if (succeeded) {
                document.title = routeInfo.name;
                previousModule = module;
                previousRoute = sammy.last_location[1].replace('/', '');

                if (forceStopNavigation) {
                    isNavigating(false);
                }
            } else {
                cancelling = true;
                system.log('Cancelling Navigation');
                sammy.setLocation(previousRoute);
                cancelling = false;
                isNavigating(false);
            }

            if (router.dfd) {
                ready(true);
                router.dfd.resolve();

                delete router.dfd;
            }
        });
    }
    
    function shouldStopNavigation() {
        return cancelling || (sammy.last_location[1].replace('/', '') == previousRoute);
    }

    function ensureRoute(route, params) {
        var routeInfo = routesByPath[route];
        
        if (shouldStopNavigation()) {
            return;
        }

        if (!routeInfo) {
            if (!router.autoConvertRouteToModuleId) {
                router.handleInvalidRoute(route, params);
                return;
            }

            routeInfo = {
                moduleId: router.autoConvertRouteToModuleId(route, params),
                name: router.convertRouteToName(route)
            };
        }
        
        isNavigating(true);

        system.acquire(routeInfo.moduleId).then(function(module) {
            if (typeof module == 'function') {
                activateRoute(routeInfo, params, new module());
            } else {
                activateRoute(routeInfo, params, module, previousModule == module);
            }
        });
    }

    function handleDefaultRoute() {
        ensureRoute(navigationDefaultRoute, this.params || {});
    }
    
    function handleMappedRoute() {
        ensureRoute(this.app.last_route.path.toString(), this.params || {});
    }

    function handleWildCardRoute() {
        var params = this.params || {}, route;

        if (router.autoConvertRouteToModuleId) {
            var fragment = this.path.split('#/');

            if (fragment.length == 2) {
                var parts = fragment[1].split('/');
                route = parts[0];
                var splat = parts.splice(1);
                if (splat.length > 0) {
                    params.splat = splat;
                }
                ensureRoute(route, params);
                return;
            }
        }

        router.handleInvalidRoute(this.app.last_location[1], params);
    }

    function configureRoute(routeInfo) {
        router.prepareRouteInfo(routeInfo);

        routesByPath[routeInfo.url] = routeInfo;
        allRoutes.push(routeInfo);

        if (routeInfo.visible) {
            routeInfo.isActive = ko.computed(function() {
                return ready() && activeItem() && activeItem().__moduleId__ == routeInfo.moduleId;
            });

            visibleRoutes.push(routeInfo);
        }

        return routeInfo;
    }

    return router = {
        ready: ready,
        allRoutes: allRoutes,
        visibleRoutes: visibleRoutes,
        isNavigating: isNavigating,
        activeItem: activeItem,
        afterCompose: function() {
            isNavigating(false);
        },
        useConvention: function (rootPath) {
            rootPath = rootPath == null ? 'viewmodels' : rootPath;
            if (rootPath) rootPath += '/';
            router.convertRouteToModuleId = function(url) {
                return rootPath + router.stripParameter(url);
            };
        },
        stripParameter: function(val) {
{'fraction_non_alphanumeric': 0.10894982993197279, 'fraction_numerical': 0.0017006802721088435, 'mean_word_length': 1.7312046444121916, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5874924', 'n_tokens_mistral': 2511, 'n_tokens_neox': 2370, 'n_words': 455}