<!DOCTYPE html>
<html>

  <head>
    <base href="." />
    <title>angular2 playground</title>
    <link data-require="leaflet@1.0.3" data-semver="1.0.3" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.3/leaflet.css" />
    <link href="https://rawgit.com/angular/material2-builds/9638a9655ad96e5207d144c6964380a684adaed4/prebuilt-themes/indigo-pink.css" rel="stylesheet">

    <script data-require="leaflet@1.0.3" data-semver="1.0.3" src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.3/leaflet.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="https://unpkg.com/core-js@2.4.1/client/shim.min.js"></script>
    <script src="https://unpkg.com/zone.js/dist/zone.js"></script>
    <script src="https://unpkg.com/zone.js/dist/long-stack-trace-zone.js"></script>
    <script src="https://unpkg.com/reflect-metadata@0.1.3/Reflect.js"></script>
    <script src="https://unpkg.com/systemjs@0.19.31/dist/system.js"></script>
    <script src="config.js"></script>
    <script>
    System.import('app')
      .catch(console.error.bind(console));
  </script>
  </head>

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

</html>
/* Styles go here */

.leaflet-map {
  height:600px;
  width:400px;
}
### Angular Starter Plunker - Typescript
System.config({
  //use typescript for compilation
  transpiler: 'typescript',
  //typescript compiler options
  typescriptOptions: {
    emitDecoratorMetadata: true
  },
  paths: {
    'npm:': 'https://unpkg.com/'
  },
  //map tells the System loader where to look for things
  map: {
    
    'app': './src',
    
    '@angular/core': 'npm:@angular/core@2.4.10/bundles/core.umd.js',
    '@angular/common': 'npm:@angular/common@2.4.10/bundles/common.umd.js',
    '@angular/compiler': 'npm:@angular/compiler@2.4.10/bundles/compiler.umd.js',
    '@angular/platform-browser': 'npm:@angular/platform-browser@2.4.10/bundles/platform-browser.umd.js',
    '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic@2.4.10/bundles/platform-browser-dynamic.umd.js',
    '@angular/http': 'npm:@angular/http@2.4.10/bundles/http.umd.js',
    '@angular/router': 'npm:@angular/router@3.4.10/bundles/router.umd.js',
    '@angular/forms': 'npm:@angular/forms@2.4.10/bundles/forms.umd.js',
    '@angular/material': 'npm:@angular/material@2.0.0-beta.2/bundles/material.umd.js',
    
    '@angular/core/testing': 'npm:@angular/core/bundles/core-testing.umd.js',
    '@angular/common/testing': 'npm:@angular/common/bundles/common-testing.umd.js',
    '@angular/compiler/testing': 'npm:@angular/compiler/bundles/compiler-testing.umd.js',
    '@angular/platform-browser/testing': 'npm:@angular/platform-browser/bundles/platform-browser-testing.umd.js',
    '@angular/platform-browser-dynamic/testing': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js',
    '@angular/http/testing': 'npm:@angular/http/bundles/http-testing.umd.js',
    '@angular/router/testing': 'npm:@angular/router/bundles/router-testing.umd.js',
    
    'rxjs': 'npm:rxjs',
    'typescript': 'npm:typescript@2.0.2/lib/typescript.js',
    
    //'leaflet': 'https://rawgit.com/Leaflet/Leaflet/e9cc3a3d73219ce1363c81317b9f83bb21f99da9/src',
  },
  //packages defines our app package
  packages: {
    app: {
      main: './main.ts',
      defaultExtension: 'ts'
    },
    rxjs: {
      defaultExtension: 'js'
    },
    // Need to specify the file extension to add to Leaflet imports.
    'https://rawgit.com/Leaflet/Leaflet/': {
      defaultExtension: 'js'
    }
  }
});
//main entry point
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {AppModule} from './app';

platformBrowserDynamic().bootstrapModule(AppModule)
//our root app component
import {Component, NgModule, ViewChild, AfterViewInit} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import { MaterialModule } from '@angular/material';

import { Component, OnInit, OnDestroy } from '@angular/core';

// Import Leaflet modules, similarly to src/Leaflet.js, but without the version from package.json (would probably require the SystemJS JSON plugin).
import {Map, map, tileLayer, featureGroup, control as Lcontrol, stamp, marker as Lmarker} from '../leaflet-systemjs.js';
import {subGroup} from '../leaflet.featuregroup.subgroup.js';

@Component({
  selector: 'minimap',
  template: `<div #mapDiv class=leaflet-map></div>`
})
export class MiniMap implements OnInit, OnDestroy, AfterViewInit {
  map: Map = null;
  
  @ViewChild('mapDiv') mapContainer;

  constructor() { 
    this.id = "map" + Date.now();
  }

  ngOnInit() {
    /*this.map = L.map(this.mapContainer.nativeElement).setView([54.5, -115.0], 13);
    L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
      maxZoom: 18,
      attribution:
      '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(this.map);*/
    
    this.map = map(this.mapContainer.nativeElement).setView([-37.82, 175.24], 11);
    tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
      maxZoom: 18,
      attribution:
      '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(this.map);
    
    
    
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // Example taken from https://github.com/ghybs/Leaflet.FeatureGroup.SubGroup/blob/master/debug/subGroup-controlLayers-nestedGroups.html
    // All L namespace references are removed (but we could patch it like done in leaflet.featuregroup.subgroup file) and control (from L.control)
    // and marker (from L.marker) have been aliased to Lcontrol and Lmarker respectively to avoid collision with the example control and marker variables.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
  	var parent = featureGroup(),
    		groupA = subGroup(parent),// use `L.featureGroup.subGroup(parentGroup)` instead of `L.featureGroup()` or `L.layerGroup()`!
    		groupB = subGroup(parent),
    		groupC = subGroup(parent),
    		groupD = subGroup(parent),
    		control = Lcontrol.layers(null, null, { collapsed: false });
  	// Trick to force order of listing in L.Control.Layers.
  	// See https://stackoverflow.com/questions/33655746/leaflet-how-to-specifiy-order-of-overlays-in-the-layers-control
  	stamp(parent);
  	stamp(groupA);
  	stamp(groupB);
  	stamp(groupC);
  	stamp(groupD);
  	parent.addTo(this.map);
  	var marker = Lmarker([-37.8, 175.2]).addTo(groupA).bindPopup("Marker at [-37.8, 175.2] in group A");
  	Lmarker([-37.8, 175.3]).addTo(groupB).bindPopup("Marker at [-37.8, 175.3] in group B");
  	Lmarker([-37.9, 175.2]).addTo(groupC).bindPopup("Marker at [-37.9, 175.2] in group C");
  	Lmarker([-37.9, 175.3]).addTo(groupD).bindPopup("Marker at [-37.9, 175.3] in group D");
  	control.addOverlay(parent, 'Parent');
  	control.addOverlay(groupA, 'Child A');
  	control.addOverlay(groupB, 'Child B');
  	control.addOverlay(groupC, 'Child C');
  	control.addOverlay(groupD, 'Child D');
  	control.addTo(this.map);
  	// Pre-add a few groups to the map.
  	parent.addTo(this.map);
  	groupA.addTo(this.map);
  	groupC.addTo(this.map);
  	
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // End of example
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  }
  
  ngAfterViewInit() {
    this.map.invalidateSize();
  }

  ngOnDestroy() { }
}

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Hello {{name}}</h2>
      <md-tab-group [selectedIndex]="2">
      <md-tab label="tab 1">
      tab 1 content
      </md-tab>
      <md-tab label="tab 2">
      tab 2 content
      </md-tab>
      <md-tab label="map tab">
      <minimap></minimap>
      </md-tab>
      </md-tab-group>
    </div>
  `,
})
export class App {
  name:string;
  constructor() {
    this.name = 'Angular2'
  }
}

@NgModule({
  imports: [ BrowserModule, MaterialModule.forRoot() ],
  declarations: [ App, MiniMap ],
  bootstrap: [ App ]
})
export class AppModule {}
// Import Leaflet modules, similarly to src/Leaflet.js,
// but without the version from package.json (would probably require the SystemJS JSON plugin).
// This would typically be a file in node_modules/leaflet/, that will load all the modules directly
// without any wrapping from Rollup.

// control
// Once this file is shipped along the package, the url's can be relative.
// Then the build tool must properly add the file extension
// (in the case of SystemJS, this must be done explictly, see file "config.js").
export * from 'https://rawgit.com/Leaflet/Leaflet/e9cc3a3d73219ce1363c81317b9f83bb21f99da9/src/control/index';

// core
export * from 'https://rawgit.com/Leaflet/Leaflet/e9cc3a3d73219ce1363c81317b9f83bb21f99da9/src/core/index';

// dom
export * from 'https://rawgit.com/Leaflet/Leaflet/e9cc3a3d73219ce1363c81317b9f83bb21f99da9/src/dom/index';

// geometry
export * from 'https://rawgit.com/Leaflet/Leaflet/e9cc3a3d73219ce1363c81317b9f83bb21f99da9/src/geometry/index';

// geo
export * from 'https://rawgit.com/Leaflet/Leaflet/e9cc3a3d73219ce1363c81317b9f83bb21f99da9/src/geo/index';

// layer
export * from 'https://rawgit.com/Leaflet/Leaflet/e9cc3a3d73219ce1363c81317b9f83bb21f99da9/src/layer/index';

// map
export * from 'https://rawgit.com/Leaflet/Leaflet/e9cc3a3d73219ce1363c81317b9f83bb21f99da9/src/map/index';
// Instead of adding a UMD wrapper, add the ES2015 module import for developers
// using build tools / ES2015 module loaders.
import {FeatureGroup, featureGroup, LayerGroup} from './leaflet-systemjs.js';

// Create a temporary L namespace to get the plugin source code compatibility.
var L = {
  FeatureGroup: FeatureGroup,
  featureGroup: featureGroup,
  LayerGroup: LayerGroup
};


// Note: with the current plugin code, we attach to FeatureGroup, but instead
// we could very well just export the created class.

///////////////////////////////////////////////////////////////////////////
// START OF PLUGIN SRC CODE
///////////////////////////////////////////////////////////////////////////

L.FeatureGroup.SubGroup = L.FeatureGroup.extend({

    /**
     * Instantiates a SubGroup.
     * @param parentGroup (L.LayerGroup) (optional)
     * @param layersArray (L.Layer[]) (optional)
     */
    initialize: function (parentGroup, layersArray) {
        L.FeatureGroup.prototype.initialize.call(this, layersArray);

        this.setParentGroup(parentGroup);
    },

    /**
     * Changes the parent group into which child markers are added to /
     * removed from.
     * @param parentGroup (L.LayerGroup)
     * @returns {SubGroup} this
     */
    setParentGroup: function (parentGroup) {
        var pgInstanceOfLG = parentGroup instanceof L.LayerGroup;

        this._parentGroup = parentGroup;

        // onAdd
        this.onAdd =
            pgInstanceOfLG ?
                (
                    typeof parentGroup.addLayers === "function" ?
                        this._onAddToGroupBatch :
                        this._onAddToGroup
                ) :
                this._onAddToMap;

        // onRemove
        this.onRemove =
            pgInstanceOfLG ?
                (
                    typeof parentGroup.removeLayers === "function" ?
                        this._onRemoveFromGroupBatch :
                        this._onRemoveFromGroup
                ) :
                this._onRemoveFromMap;

        // addLayer
        this.addLayer = pgInstanceOfLG ?
            this._addLayerToGroup :
            this._addLayerToMap;

        // removeLayer
        this.removeLayer = pgInstanceOfLG ?
            this._removeLayerFromGroup :
            this._removeLayerFromMap;

        return this;
    },

    /**
     * Removes the current sub-group from map before changing the parent
     * group. Re-adds the sub-group to map if it was before changing.
     * @param parentGroup (L.LayerGroup)
     * @returns {SubGroup} this
     */
    setParentGroupSafe: function (parentGroup) {
        var map = this._map;

        if (map) {
            map.removeLayer(this);
        }

        this.setParentGroup(parentGroup);

        if (map) {
            map.addLayer(this);
        }

        return this;
    },

    /**
     * Returns the current parent group.
     * @returns {*}
     */
    getParentGroup: function () {
        return this._parentGroup;
    },


    // For parent groups with batch methods (addLayers and removeLayers)
    // like MarkerCluster.
    _onAddToGroupBatch: function (map) {
        var layersArray = this.getLayers();

        this._map = map;
        this._parentGroup.addLayers(layersArray);
    },

    _onRemoveFromGroupBatch: function () {
        var layersArray = this.getLayers();

        this._parentGroup.removeLayers(layersArray);
        this._map = null;
    },


    // For other parent layer groups.
    _onAddToGroup: function (map) {
        var parentGroup = this._parentGroup;

        this._map = map;
        this.eachLayer(parentGroup.addLayer, parentGroup);
    },

    _onRemoveFromGroup: function () {
        var parentGroup = this._parentGroup;

        this.eachLayer(parentGroup.removeLayer, parentGroup);
        this._map = null;
    },


    // Defaults to standard FeatureGroup behaviour when parent group is not
    // specified or is not a type of LayerGroup.
    _onAddToMap: L.FeatureGroup.prototype.onAdd,
    _onRemoveFromMap: L.FeatureGroup.prototype.onRemove,


    _addLayerToGroup: function (layer) {
        if (this.hasLayer(layer)) {
            return this;
        }

        layer.addEventParent(this);

        var id = this.getLayerId(layer);

        this._layers[id] = layer;

        if (this._map) {
            // Add to parent group instead of directly to map.
            this._parentGroup.addLayer(layer);
        }

        return this.fire("layeradd", {layer: layer});
    },

    _removeLayerFromGroup: function (layer) {
        // If unknown layer, skip.
        if (!this.hasLayer(layer)) {
            return this;
        }

        // Retrieve the layer id.
        var id = layer in this._layers ? layer : this.getLayerId(layer);

        // Retrieve the layer from this._layer.
        layer = this._layers[id];

        // Unregister from events parent.
        layer.removeEventParent(this);

        if (this._map && layer) {
            // Remove from parent group instead of directly from map.
            this._parentGroup.removeLayer(layer);
        }

        delete this._layers[id];

        return this.fire("layerremove", {layer: layer});
    },

    // Defaults to standard FeatureGroup behaviour when parent group is not
    // specified or is not a type of LayerGroup.
    _addLayerToMap: L.FeatureGroup.prototype.addLayer,
    _removeLayerFromMap: L.FeatureGroup.prototype.removeLayer

});



// Supply with a factory for consistency with Leaflet.
L.featureGroup.subGroup = function (parentGroup, options) {
    return new L.FeatureGroup.SubGroup(parentGroup, options);
};

///////////////////////////////////////////////////////////////////////////
// END OF PLUGIN SRC CODE
///////////////////////////////////////////////////////////////////////////

// We could also export the created class and factory:
export const SubGroup = L.FeatureGroup.SubGroup;
export const subGroup = L.featureGroup.subGroup;