<!DOCTYPE html>
<html>
<html>
  <head>
    <!-- Set the base href -->
    <script>document.write('<base href="' + document.location + '" />');</script>
    <title>Router Sample</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="styles.css">

    <!-- Polyfill(s) for older browsers -->
    <script src="https://npmcdn.com/core-js/client/shim.min.js"></script>

    <script src="https://npmcdn.com/zone.js@0.6.12?main=browser"></script>
    <script src="https://npmcdn.com/reflect-metadata@0.1.3"></script>
    <script src="https://npmcdn.com/systemjs@0.19.27/dist/system.src.js"></script>

    <script src="systemjs.config.js"></script>
    <script>
      System.import('app')
            .catch(function(err){ console.error(err); });
    </script>
  </head>

  <body>
    <my-app>loading...</my-app>
  </body>

</html>
/* Master Styles */
h1 {
  color: #369;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 250%;
}
h2, h3 {
  color: #444;
  font-family: Arial, Helvetica, sans-serif;
  font-weight: lighter;
}
body {
  margin: 2em;
}
body, input[text], button {
  color: #888;
  font-family: Cambria, Georgia;
}
a {
  cursor: pointer;
  cursor: hand;
}
button {
  font-family: Arial;
  background-color: #eee;
  border: none;
  padding: 5px 10px;
  border-radius: 4px;
  cursor: pointer;
  cursor: hand;
}
button:hover {
  background-color: #cfd8dc;
}
button:disabled {
  background-color: #eee;
  color: #aaa;
  cursor: auto;
}

/* Navigation link styles */
nav a {
  padding: 5px 10px;
  text-decoration: none;
  margin-top: 10px;
  display: inline-block;
  background-color: #eee;
  border-radius: 4px;
}
nav a:visited, a:link {
  color: #607D8B;
}
nav a:hover {
  color: #039be5;
  background-color: #CFD8DC;
}
nav a.active {
  color: #039be5;
}

/* items class */
.items {
  margin: 0 0 2em 0;
  list-style-type: none;
  padding: 0;
  width: 24em;
}
.items li {
  cursor: pointer;
  position: relative;
  left: 0;
  background-color: #EEE;
  margin: .5em;
  padding: .3em 0;
  height: 1.6em;
  border-radius: 4px;
}
.items li:hover {
  color: #607D8B;
  background-color: #DDD;
  left: .1em;
}
.items li.selected:hover {
  background-color: #BBD8DC;
  color: white;
}
.items .text {
  position: relative;
  top: -3px;
}
.items {
  margin: 0 0 2em 0;
  list-style-type: none;
  padding: 0;
  width: 24em;
}
.items li {
  cursor: pointer;
  position: relative;
  left: 0;
  background-color: #EEE;
  margin: .5em;
  padding: .3em 0;
  height: 1.6em;
  border-radius: 4px;
}
.items li:hover {
  color: #607D8B;
  background-color: #DDD;
  left: .1em;
}
.items li.selected {
  background-color: #CFD8DC;
  color: white;
}

.items li.selected:hover {
  background-color: #BBD8DC;
}
.items .text {
  position: relative;
  top: -3px;
}
.items .badge {
  display: inline-block;
  font-size: small;
  color: white;
  padding: 0.8em 0.7em 0 0.7em;
  background-color: #607D8B;
  line-height: 1em;
  position: relative;
  left: -1px;
  top: -4px;
  height: 1.8em;
  margin-right: .8em;
  border-radius: 4px 0 0 4px;
}
/* everywhere else */
* {
  font-family: Arial, Helvetica, sans-serif;
}


/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/
/**
 * PLUNKER VERSION (based on systemjs.config.js in angular.io)
 * System configuration for Angular 2 samples
 * Adjust as necessary for your application needs.
 */
(function(global) {

  var ngVer = '@2.0.0-rc.5'; // lock in the angular package version; do not let it float to current!
  var routerVer = '@3.0.0-rc.1'; // lock router version
  var formsVer = '@0.3.0'; // lock forms version
  var routerDeprecatedVer = '@2.0.0-rc.2'; // temporarily until we update all the guides

  //map tells the System loader where to look for things
  var map = {
    'app':                        'app',

    '@angular':                   'https://npmcdn.com/@angular', // sufficient if we didn't pin the version
    '@angular/router':            'https://npmcdn.com/@angular/router' + routerVer,
    '@angular/forms':             'https://npmcdn.com/@angular/forms' + formsVer,
    '@angular/router-deprecated': 'https://npmcdn.com/@angular/router-deprecated' + routerDeprecatedVer,
    'angular2-in-memory-web-api': 'https://npmcdn.com/angular2-in-memory-web-api', // get latest
    'rxjs':                       'https://npmcdn.com/rxjs@5.0.0-beta.6',
    'ts':                         'https://npmcdn.com/plugin-typescript@4.0.10/lib/plugin.js',
    'typescript':                 'https://npmcdn.com/typescript@1.9.0-dev.20160409/lib/typescript.js',
 };

  //packages tells the System loader how to load when no filename and/or no extension
  var packages = {
    'app':                        { main: 'main.ts',  defaultExtension: 'ts' },
    'rxjs':                       { defaultExtension: 'js' },
    'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' },
  };

  var ngPackageNames = [
    'common',
    'compiler',
    'core',
    'http',
    'platform-browser',
    'platform-browser-dynamic',
    'upgrade',
  ];

  // Add map entries for each angular package
  // only because we're pinning the version with `ngVer`.
  ngPackageNames.forEach(function(pkgName) {
    map['@angular/'+pkgName] = 'https://npmcdn.com/@angular/' + pkgName + ngVer;
  });

  // Add package entries for angular packages
  ngPackageNames.concat(['forms', 'router', 'router-deprecated']).forEach(function(pkgName) {

    // Bundled (~40 requests):
    packages['@angular/'+pkgName] = { main: '/bundles/' + pkgName + '.umd.js', defaultExtension: 'js' };

    // Individual files (~300 requests):
    //packages['@angular/'+pkgName] = { main: 'index.js', defaultExtension: 'js' };
  });

  var config = {
    // DEMO ONLY! REAL CODE SHOULD NOT TRANSPILE IN THE BROWSER
    transpiler: 'ts',
    typescriptOptions: {
      tsconfig: true
    },
    meta: {
      'typescript': {
        "exports": "ts"
      }
    },
    map: map,
    packages: packages
  };

  System.config(config);

})(this);


/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/
{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": true,
    "suppressImplicitAnyIndexErrors": true
  }
}
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app.module';

platformBrowserDynamic().bootstrapModule(AppModule);
import { Routes, RouterModule } from '@angular/router';

const appRoutes: Routes = [
  {
    path: '',
    pathMatch: 'full',
    redirectTo: 'lazy-named'
  },
  {
    path: 'lazy-named',
    loadChildren: 'app/lazy-named/lazy-named.module',
  }
];

export const routing = RouterModule.forRoot(appRoutes, {useHash: true});
import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
    <h1 class="title">Lazy routes bug</h1>
    <nav>
      <a routerLink="lazy-named" routerLinkActive="active">Lazy Named</a>
    </nav>
    <router-outlet></router-outlet>
    <problems-component></problems-component>
  `
})
export class AppComponent {
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { routing } from './app.routing';
import { SharedModule } from './shared/shared.module';
import { ProblemsComponent } from './problems.component';

@NgModule({
  imports: [
    BrowserModule,
    FormsModule,
    routing,
    SharedModule
  ],
  declarations: [
    AppComponent,
      ProblemsComponent
  ],
  bootstrap: [AppComponent]
})
export class AppModule {
}
import { RouterModule } from '@angular/router';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { Level2Component } from './level2.component';
import { Level1Component } from './level1.component';
import { EmptyComponent } from './empty.component';
import { OutletsComponent } from './outlets.component';

@NgModule({
  imports: [
    RouterModule
  ],
  declarations: [EmptyComponent, OutletsComponent, Level1Component, Level2Component],
  exports: [
    CommonModule,
    RouterModule,
    FormsModule,

    EmptyComponent,
    OutletsComponent,
    Level1Component,
    Level2Component
  ]
})

export class SharedModule {

}
import { Component }  from '@angular/core';

@Component({
  template: `
    <div style="background: rgba(205, 63, 34, 0.18); padding:5px;">
      <h4>Level 1</h4>
      <router-outlet></router-outlet>
      <router-outlet name="outlet_1"></router-outlet>
    </div>
  `
})
export class Level1Component {

  constructor() {}
}
import { Component }  from '@angular/core';

@Component({
  template: `
    <div style="background: rgba(109, 250, 105, 0.3); padding:5px;">
      <h5>Level 2</h5>
      <empty-component></empty-component>
    </div>
  `
})
export class Level2Component {

  constructor() {}
}
import { Component }  from '@angular/core';

@Component({
  moduleId: module.id,
  selector: 'problems-component',
  template: `
  <div style="background: #eee; color:#777; padding:5px; margin:5px; ">
    <p>Preface:</p>
    <ul>
      <li>OutletA:Level1 works in 'Default+Named' component</li>
      <li>OutletB:Level2 works in 'Default+Named' component</li>
      <li>OutletA:Level1/Level2 works in 'Default+Named' component</li>
      <li>In 'Default+Named' empty button cleans outlet</li>
      <li>This is lazy loaded module. Load children works for primary outlet</li>
    </ul>
    <p>Bugs in 'Lazy':</p>
    <ul>
      <li>empty button navigates to 'lazy-named'</li>
    </ul>
    <p>Bugs in 'Lazy-named':</p>
    <ul>
      <li>loadChildren for outletA:Level1 not works</li>
      <li>loadChildren for outletB:Level2 not works</li>
      <li>empty button not works</li>
    </ul>
    <p>Other bugs:</p>
    <ul>
      <li>(path:'', component:EmptyComponent) required in children, even if children contains only named outles routes</li>
     </ul>
  </div>
  `
})
export class ProblemsComponent {

  constructor() {}
}
import { Router, ActivatedRoute, UrlTree } from '@angular/router';

export abstract class BaseNavigationComponent {
  constructor(protected router: Router, protected activatedRoute: ActivatedRoute) {}

  openLink(path: string, outlet?: string) {
    let urlTree: UrlTree;
    if (outlet) {
      let outlets = {};
      outlets[outlet] = path == '' ? null : path;
      urlTree = this.router.createUrlTree([{outlets: outlets}], {relativeTo: this.activatedRoute});
    } else {
      urlTree = this.router.createUrlTree([path], {relativeTo: this.activatedRoute});
    }
    console.warn('navigate to ', this.router.serializeUrl(urlTree));
    this.router.navigateByUrl(urlTree);
  }
}
import { Component }  from '@angular/core';

@Component({
  moduleId: module.id,
  selector: 'outlets-component',
  template: `
  <div>
      <div style="background: rgba(55, 67, 110, 0.25); margin:10px; padding:5px; color:#fff; width:30%; display:inline-block; vertical-align: top">
        <span>Primary outlet </span>
        <router-outlet></router-outlet>
      </div>
      
      <div style="background: rgba(55, 67, 110, 0.25); margin:10px; padding:5px; color:#fff; width:30%; display:inline-block; vertical-align: top">
        <span>Outlet A</span>
        <router-outlet name="outletA"></router-outlet>
      </div>
      
      <div style="background: rgba(55, 67, 110, 0.25); margin:10px; padding:5px; color:#fff; width:30%; display:inline-block; vertical-align: top">
        <span>Outlet B</span>
        <router-outlet name="outletB"></router-outlet>
      </div>
  </div>
  `
})
export class OutletsComponent {

  constructor() {}
}
import { Component } from '@angular/core';

@Component({
  moduleId:module.id,
  selector:'empty-component',
  template: `
    <div style="background: rgb(81, 81, 81); padding:2px;">
      <h5 style="color:#eee">Empty Component</h5>
    </div>
  `
})
export class EmptyComponent {

  constructor() {}
}
import { Component } from '@angular/core';
import { Router, ActivatedRoute, UrlTree } from '@angular/router';
import { BaseNavigationComponent } from '../base-navigation.component';

@Component({
  template: `
    <div style="background: rgba(200,150,0,0.3); padding:5px;">
      <h2>Lazy Named Outlet Component</h2>
      <div>
        <span>Primary:</span>
        <button (click)="openLink('')">Empty</button>
        <button (click)="openLink('level1')">Level1</button>
        <button (click)="openLink('level2')">Level2</button>
        <!--<button (click)="openLink('level1/level2')">Level1/Level2</button>-->
      </div>
      <div style="padding-top: 5px">
        <span>Outlet A:</span>
        <button (click)="openLink('', 'outletA')">Empty</button>
        <button (click)="openLink('level1', 'outletA')">Level1</button>
        <button (click)="openLink('level2', 'outletA')">Level2</button>
        <!--<button (click)="openLink('level1/level2', 'outletA')">Level1/Level2</button>-->
      </div>
      <div style="padding-top: 5px">
        <span>Outlet B:</span>
        <button (click)="openLink('', 'outletB')">Empty</button>
        <button (click)="openLink('level1', 'outletB')">Level1</button>
        <button (click)="openLink('level2', 'outletB')">Level2</button>
        <!--<button (click)="openLink('level1/level2', 'outletB')">Level1/Level2</button>-->
      </div>
      <outlets-component></outlets-component>
    </div>
  `
})
export class LazyNamedComponent extends BaseNavigationComponent {

  constructor(router: Router, activatedRoute: ActivatedRoute) {
    super(router, activatedRoute);
  }
}
import { NgModule } from '@angular/core';
import { SharedModule } from '../shared/shared.module';
import { LazyNamedComponent } from './lazy-named.component';
import { lazyNamedRouting } from './lazy-named.routing';

@NgModule({
  imports: [
    SharedModule,
    lazyNamedRouting
  ],
  declarations: [LazyNamedComponent],
  exports: [LazyNamedComponent]
})
export default class LazyNamedModule {
}
import { Routes, RouterModule } from '@angular/router';
import { LazyNamedComponent } from './lazy-named.component';
import { EmptyComponent } from '../shared/empty.component';

const outletARoutes: Routes = [
  {
    path: 'level1',
    outlet: 'outletA',
    loadChildren: 'app/lazy-named/lazy-named-level1/lazy-named-level1.module'
  },
  {
    path: 'level2',
    outlet: 'outletA',
    loadChildren: 'app/lazy-named/lazy-named-level2/lazy-named-level2.module'
  }
];

const outletBRoutes: Routes = [
  {
    path: 'level1',
    outlet: 'outletB',
    loadChildren: 'app/lazy-named/lazy-named-level1/lazy-named-level1.module'
  },
  {
    path: 'level2',
    outlet: 'outletB',
    loadChildren: 'app/lazy-named/lazy-named-level2/lazy-named-level2.module'
  }
];

const lazyNamedRoutes: Routes = [
  {
    path: '',
    component: LazyNamedComponent,
    children: [
      {
        path: '',
        component: EmptyComponent
      },
      {
        path: 'level1',
        loadChildren: 'app/lazy-named/lazy-named-level1/lazy-named-level1.module'
      },
      {
        path: 'level2',
        loadChildren: 'app/lazy-named/lazy-named-level2/lazy-named-level2.module'
      },
      ...outletARoutes,
      ...outletBRoutes
    ]
  }
];

export const lazyNamedRouting = RouterModule.forChild(lazyNamedRoutes);
import { NgModule } from '@angular/core';
import { SharedModule } from '../../shared/shared.module';
import { lazyNamedLevel1Routing } from './lazy-named-level1.routing';

@NgModule({
  imports: [
    SharedModule,
    lazyNamedLevel1Routing
  ],
  declarations: [],
  providers: []
})

export default class LazyNamedLevel1Module {

}
import { Routes, RouterModule } from '@angular/router';
import { Level1Component } from '../../shared/level1.component';

const lazyNamedLevel1Routes: Routes = [
  {
    path: '',
    component: Level1Component
  }
];

export const lazyNamedLevel1Routing = RouterModule.forChild(lazyNamedLevel1Routes);
import { NgModule } from '@angular/core';
import { SharedModule } from '../../shared/shared.module';
import { lazyNamedLevel2Routing } from './lazy-named-level2.routing';

@NgModule({
  imports: [
    SharedModule,
    lazyNamedLevel2Routing
  ],
  declarations: [],
  providers: []
})

export default class LazyNamedLevel2Module {

}
import { Routes, RouterModule } from '@angular/router';
import { Level2Component } from '../../shared/level2.component';

const lazyNamedLevel2Routes: Routes = [
  {
    path: '',
    component: Level2Component
  }
];

export const lazyNamedLevel2Routing = RouterModule.forChild(lazyNamedLevel2Routes);