<commit_before>/*global dojo */
/** @license
 | Version 10.2
 | Copyright 2012 Esri
 |
 | Licensed under the Apache License, Version 2.0 (the "License");
 | you may not use this file except in compliance with the License.
 | You may obtain a copy of the License at
 |
 |    http://www.apache.org/licenses/LICENSE-2.0
 |
 | Unless required by applicable law or agreed to in writing, software
 | distributed under the License is distributed on an "AS IS" BASIS,
 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | See the License for the specific language governing permissions and
 | limitations under the License.
 */
dojo.provide("js.Config");
dojo.declare("js.Config", null, {

    // This file contains various configuration settings for "HTML5" template
    //
    // Use this file to perform the following:
    //
    // 1.  Specify application title                  - [ Tag(s) to look for: ApplicationName ]
    // 2.  Set path for application icon              - [ Tag(s) to look for: ApplicationIcon ]
    // 3.  Set splash screen message                  - [ Tag(s) to look for: SplashScreenMessage ]
    // 4.  Set URL for help page                      - [ Tag(s) to look for: HelpURL ]
    //
    // 5.  Specify URLs for base maps                  - [ Tag(s) to look for: BaseMapLayers ]
    // 6.  Set initial map extent                     - [ Tag(s) to look for: DefaultExtent ]
    //
    // 7.  Or for using map services:
    // 7a. Customize info-Window settings             - [ Tag(s) to look for: InfoWindowHeader, InfoPopupFieldsCollection ]
    // 7b. Customize info-Popup size                  - [ Tag(s) to look for: InfoPopupHeight, InfoPopupWidth ]
    // 7c. Customize data formatting                  - [ Tag(s) to look for: ShowNullValueAs]
    //
    // 8. Customize address search settings           - [ Tag(s) to look for: LocatorURL, LocatorFields, DefaultValue, LocatorMarkupSymbolPath, LocatorRippleSize ]
    //
    // 9. Set URL for geometry service               - [ Tag(s) to look for: GeometryService ]
    //
    // 10. Customize routing settings for directions  - [ Tag(s) to look for: RouteServiceURL, RouteColor, RouteWidth, SearchforDirections]
    //
    // 11. Configure data to be displayed on the bottom panel, ReferenceOverlayLayer
    //                                                - [ Tag(s) to look for: InfoBoxWidth, Services, ReferenceOverlayLayer]
    //
    // 12. Customize the Zoom level, CallOutAddress, Render color, ripple size
    //                                                - [ Tag(s) to look for: Zoom level, CallOutAddress, RendererColor, RippleSize]
    //
    // 13. Specify URLs for map sharing               - [ Tag(s) to look for: MapSharingOptions (set TinyURLServiceURL, TinyURLResponseAttribute) ]
    // 13a.In case of changing the TinyURL service
    //     Specify URL for the new service            - [ Tag(s) to look for: FacebookShareURL, TwitterShareURL, ShareByMailLink ]
    //
    //

    // ------------------------------------------------------------------------------------------------------------------------
    // GENERAL SETTINGS
    // ------------------------------------------------------------------------------------------------------------------------
    // Set application title.
    ApplicationName: "My Hazard Information",

    // Set application icon path.
    ApplicationIcon: "images/MyHazardInfoappIcon.png",

    // Set splash window content - Message that appears when the application starts.
    SplashScreenMessage: "My Hazard Information

The My Hazard Information application helps residents discover hazards that exist in their community and obtain information about evacuation routes and shelters provided by a government agency.

To locate an area of interest, simply enter an address in the search box, or use your current location. Your location will then be highlighted on the map and relevant evacuation and facility information will be presented to the user.

",

    // Set URL of help page/portal.
    HelpURL: "helpMyHazard.htm",

    // ------------------------------------------------------------------------------------------------------------------------
    // BASEMAP SETTINGS
    // ------------------------------------------------------------------------------------------------------------------------
    // Set baseMap layers.
    // Please note: All base maps need to use the same spatial reference. By default, on application start the first base map will be loaded
    BaseMapLayers: [{
        Key: "parcelMap",
        ThumbnailSource: "images/parcelMap.png",
        Name: "Streets",
        MapURL: "http://tryitlive.arcgis.com/arcgis/rest/services/GeneralPurpose/MapServer"
    }, {
        Key: "hybridMap",
        ThumbnailSource: "images/imageryHybrid.png",
        Name: "Imagery",
        MapURL: "http://tryitlive.arcgis.com/arcgis/rest/services/ImageryHybrid/MapServer"
    }],

    // Initial map extent. Use comma (,) to separate values and don t delete the last comma.
    DefaultExtent: "-9816010,5123000,-9809970,5129500",

    // ------------------------------------------------------------------------------------------------------------------------
    // INFO-POPUP SETTINGS
    // ------------------------------------------------------------------------------------------------------------------------
    // Info-popup is a popup dialog that gets displayed on selecting a feature

    //Field for Displaying the features as info window header.
    InfoWindowHeader: "NAME",

    // Set the content to be displayed on the info-Popup. Define labels, field values, field types and field formats.
    InfoPopupFieldsCollection: [{
        DisplayText: "Name:",
        FieldName: "NAME"
    }, {
        DisplayText: "Address:",
        FieldName: "FULLADDR"
    }, {
        DisplayText: "Contact:",
        FieldName: "CONTACT"
    }, {
        DisplayText: "Phone:",
        FieldName: "PHONE"
    }, {
        DisplayText: "Email:",
        FieldName: "EMAIL"
    }, {
        DisplayText: "Days Open:",
        FieldName: "OPERDAYS"
    }, {
        DisplayText: "Hours of Operation:",
        FieldName: "OPERHOURS"
    }],

    // Set size of the info-Popup - select maximum height and width in pixels.
    //minimum height should be 200 for the info-popup in pixels
    InfoPopupHeight: 200,

    //minimum width should be 300 for the info-popup in pixels
    InfoPopupWidth: 300,

    // Set string value to be shown for null or blank values.
    ShowNullValueAs: "N/A",

    // ------------------------------------------------------------------------------------------------------------------------
    // ADDRESS SEARCH SETTINGS
    // ------------------------------------------------------------------------------------------------------------------------
    // Set Locator service URL.

    LocatorSettings: {
        LocatorMarkupSymbolPath: "images/RedPushpin.png", // Set pushpin image path.
        MarkupSymbolSize: {
            width: 25,
            height: 25
        },
        Locators: [{
            DisplayText: "Search Address", //Set placeholder text
            DefaultValue: "7S610 Carriage Way Ct Naperville IL", // Set default address to search.
            LocatorParameters: ["SingleLine"], // Set Locator fields (fields to be used for searching).
            LocatorURL: "http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer",
            CandidateFields: "Loc_name, Score, Match_addr", //Set which fields are returned in results
            DisplayField: "${Match_addr}", //Set which field from results is displayed
            AddressMatchScore: 80, //Set minimum score to be considered a match
            LocatorFieldName: 'Loc_name', //The returned field which specifies match type (specific locator within composite)
            LocatorFieldValues: ["USA.StreetName", "USA.PointAddress", "USA.StreetAddress"] //List of acceptable individual locators (within composite)
        }]
    },

    // ------------------------------------------------------------------------------------------------------------------------
    // GEOMETRY SERVICE SETTINGS
    // ------------------------------------------------------------------------------------------------------------------------
    // Set geometry service URL.
    GeometryService: "http://tasks.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer",

    // ------------------------------------------------------------------------------------------------------------------------
    // DRIVING DIRECTIONS SETTINGS
    // ------------------------------------------------------------------------------------------------------------------------
    // Set URL for routing service (network analyst).
    RouteServiceURL: "http://tasks.arcgisonline.com/ArcGIS/rest/services/NetworkAnalysis/ESRI_Route_NA/NAServer/Route",

    // Set color for the route symbol.
    RouteColor: "#CC6633",

    // Set width of the route.
    RouteWidth: 4,

    // Set this to true to show directions on map
    SearchforDirections: false,

    // ------------------------------------------------------------------------------------------------------------------------
    // SETTINGS FOR INFO-PODS ON THE BOTTOM PANEL
    // ------------------------------------------------------------------------------------------------------------------------
    // Set width of the boxes in the bottom panel.
    InfoBoxWidth: 417,

    //Operational layer collection.
    Services: {
        EvacArea: {
            Name: "Evacuation Areas",
            Image: "images/EvacArea.png",
            HasRendererImage: false,
            ServiceUrl: "http://tryitlive.arcgis.com/arcgis/rest/services/HazardServices/MapServer/6",
            FieldNames: [{
                Field: "Evacuation Areas: ${DESCRIPTION}"
            }, {
                Links: [{
                    DisplayText: "Website",
                    FieldName: "EVACURL",
                    type: "web"
                }]
            }],
            Color: "#FCD208",
            isRendererColor: true,
            LayerVisibility: true
        },
        FloodHazards: {
            Name: "Flood Hazards",
            Image: "images/Flood.png",
            HasRendererImage: false,
            ServiceUrl: "http://tryitlive.arcgis.com/arcgis/rest/services/HazardServices/MapServer/7",
            FieldNames: [{
                Field: "Flood Zone: ${FLOODZONE}"
            }],
            Color: "#FCD208",
            isRendererColor: true,
            LayerVisibility: true
        },
        Hazards: {
            Name: "Hazardous Facilities",
            Image: "images/HazardFacilities.png",
            HasRendererImage: false,
            ServiceUrl: "http://tryitlive.arcgis.com/arcgis/rest/services/HazardServices/MapServer/0",
            distance: 4,
            FieldNames: [{
                FieldName: "NAME"
            }, {
                FieldName: "FULLADDR"
            }, {
                FieldName: "PHONE"
            }],
            LayerVisibility: true,
            ShowBeyondBuffer: true
        },
        Hospitals: {
            Name: "Hospitals",
            Image: "images/hospital.png",
            HasRendererImage: false,
            ServiceUrl: "http://tryitlive.arcgis.com/arcgis/rest/services/HazardServices/MapServer/1",
            distance: 4,
            FieldNames: [{
                FieldName: "NAME"
            }, {
                FieldName: "FULLADDR"
            }, {
                FieldName: "PHONE"
            }],
            LayerVisibility: true,
            ShowBeyondBuffer: true
        },
        PoliceStations: {
            Name: "Police Stations",
            Image: "images/policeStations.png",
            HasRendererImage: false,
            ServiceUrl: "http://tryitlive.arcgis.com/arcgis/rest/services/HazardServices/MapServer/2",
            distance: 4,
            FieldNames: [{
                FieldName: "NAME"
            }, {
                FieldName: "FULLADDR"
            }, {
                FieldName: "PHONE"
            }],
            LayerVisibility: true,
            ShowBeyondBuffer: true
        },
        FireStations: {
            Name: "Fire Stations",
            Image: "images/fireStations.png",
            HasRendererImage: false,
            ServiceUrl: "http://tryitlive.arcgis.com/arcgis/rest/services/HazardServices/MapServer/3",
            distance: 4,
            FieldNames: [{
                FieldName: "NAME"
            }, {
                FieldName: "FULLADDR"
            }, {
                FieldName: "PHONE"
            }],
            LayerVisibility: true,
            ShowBeyondBuffer: true
        },
        CoolCenter: {
            Name: "Cooling Center",
            Image: "images/CoolCenter.png",
            HasRendererImage: false,
            ServiceUrl: "http://tryitlive.arcgis.com/arcgis/rest/services/HazardServices/MapServer/4",
            distance: 4,
            FieldNames: [{
                FieldName: "FACNAME"
            }, {
                FieldName: "HOURSOPER"
            }, {
                FieldName: "CAPACITY"
            }],
            LayerVisibility: true,
            ShowBeyondBuffer: true
        },
        WarmCenter: {
            Name: "Warming Center",
            Image: "images/WarmCenter.png",
            HasRendererImage: false,
            ServiceUrl: "http://tryitlive.arcgis.com/arcgis/rest/services/HazardServices/MapServer/5",
            distance: 4,
            FieldNames: [{
                FieldName: "FACNAME"
            }, {
                FieldName: "HOURSOPER"
            }, {
                FieldName: "CAPACITY"
            }],
            LayerVisibility: true,
            ShowBeyondBuffer: true
        }
    },

    // ServiceUrl is the REST end point for the reference overlay layer
    // DisplayOnLoad setting this will show the reference overlay layer on load
    ReferenceOverlayLayer: {
        ServiceUrl: "http://tryitlive.arcgis.com/arcgis/rest/services/HazardReference/MapServer",
        DisplayOnLoad: true
    },

    //Set required zoom level.
    ZoomLevel: 6,

    //Set Address to be displayed on mobile callout.
    CallOutAddress: "Street: ${Address}",

    //Set Renderer color for selected feature.
    RendererColor: "#CC6633",

    //Set size of the ripple.
    RippleSize: 25,

    // ------------------------------------------------------------------------------------------------------------------------
    // SETTINGS FOR MAP SHARING
    // ------------------------------------------------------------------------------------------------------------------------
    // Set URL for TinyURL service, and URLs for social media.
    MapSharingOptions: {
        TinyURLServiceURL: "http://api.bit.ly/v3/shorten?login=esri&apiKey=R_65fd9891cd882e2a96b99d4bda1be00e&uri=${0}&format=json",
        TinyURLResponseAttribute: "data.url",
        FacebookShareURL: "http://www.facebook.com/sharer.php?u=${0}&t=My%20Government%20Services",
        TwitterShareURL: "http://mobile.twitter.com/compose/tweet?status=My%20Government%20Services ${0}",
        ShareByMailLink: "mailto:%20?subject=Check%20out%20this%20map!&body=${0}"
    }
});
<commit_msg>updated the routing service<commit_after>/*global dojo */
/** @license
 | Version 10.2
 | Copyright 2012 Esri
 |
 | Licensed under the Apache License, Version 2.0 (the "License");
 | you may not use this file except in compliance with the License.
 | You may obtain a copy of the License at
 |
 |    http://www.apache.org/licenses/LICENSE-2.0
 |
 | Unless required by applicable law or agreed to in writing, software
 | distributed under the License is distributed on an "AS IS" BASIS,
 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | See the License for the specific language governing permissions and
 | limitations under the License.
 */
dojo.provide("js.Config");
dojo.declare("js.Config", null, {

    // This file contains various configuration settings for "HTML5" template
    //
    // Use this file to perform the following:
    //
    // 1.  Specify application title                  - [ Tag(s) to look for: ApplicationName ]
    // 2.  Set path for application icon              - [ Tag(s) to look for: ApplicationIcon ]
    // 3.  Set splash screen message                  - [ Tag(s) to look for: SplashScreenMessage ]
    // 4.  Set URL for help page                      - [ Tag(s) to look for: HelpURL ]
    //
    // 5.  Specify URLs for base maps                  - [ Tag(s) to look for: BaseMapLayers ]
    // 6.  Set initial map extent                     - [ Tag(s) to look for: DefaultExtent ]
    //
    // 7.  Or for using map services:
    // 7a. Customize info-Window settings             - [ Tag(s) to look for: InfoWindowHeader, InfoPopupFieldsCollection ]
    // 7b. Customize info-Popup size                  - [ Tag(s) to look for: InfoPopupHeight, InfoPopupWidth ]
    // 7c. Customize data formatting                  - [ Tag(s) to look for: ShowNullValueAs]
    //
    // 8. Customize address search settings           - [ Tag(s) to look for: LocatorURL, LocatorFields, DefaultValue, LocatorMarkupSymbolPath, LocatorRippleSize ]
    //
    // 9. Set URL for geometry service               - [ Tag(s) to look for: GeometryService ]
    //
    // 10. Customize routing settings for directions  - [ Tag(s) to look for: RouteServiceURL, RouteColor, RouteWidth, SearchforDirections]
    //
    // 11. Configure data to be displayed on the bottom panel, ReferenceOverlayLayer
    //                                                - [ Tag(s) to look for: InfoBoxWidth, Services, ReferenceOverlayLayer]
    //
    // 12. Customize the Zoom level, CallOutAddress, Render color, ripple size
    //                                                - [ Tag(s) to look for: Zoom level, CallOutAddress, RendererColor, RippleSize]
    //
    // 13. Specify URLs for map sharing               - [ Tag(s) to look for: MapSharingOptions (set TinyURLServiceURL, TinyURLResponseAttribute) ]
    // 13a.In case of changing the TinyURL service
    //     Specify URL for the new service            - [ Tag(s) to look for: FacebookShareURL, TwitterShareURL, ShareByMailLink ]
    //
    //

    // ------------------------------------------------------------------------------------------------------------------------
    // GENERAL SETTINGS
    // ------------------------------------------------------------------------------------------------------------------------
    // Set application title.
    ApplicationName: "My Hazard Information",

    // Set application icon path.
    ApplicationIcon: "images/MyHazardInfoappIcon.png",

    // Set splash window content - Message that appears when the application starts.
    SplashScreenMessage: "My Hazard Information

The My Hazard Information application helps residents discover hazards that exist in their community and obtain information about evacuation routes and shelters provided by a government agency.

To locate an area of interest, simply enter an address in the search box, or use your current location. Your location will then be highlighted on the map and relevant evacuation and facility information will be presented to the user.

",

    // Set URL of help page/portal.
    HelpURL: "helpMyHazard.htm",

    // ------------------------------------------------------------------------------------------------------------------------
    // BASEMAP SETTINGS
    // ------------------------------------------------------------------------------------------------------------------------
    // Set baseMap layers.
    // Please note: All base maps need to use the same spatial reference. By default, on application start the first base map will be loaded
    BaseMapLayers: [{
        Key: "parcelMap",
        ThumbnailSource: "images/parcelMap.png",
        Name: "Streets",
        MapURL: "http://tryitlive.arcgis.com/arcgis/rest/services/GeneralPurpose/MapServer"
    }, {
        Key: "hybridMap",
        ThumbnailSource: "images/imageryHybrid.png",
        Name: "Imagery",
        MapURL: "http://tryitlive.arcgis.com/arcgis/rest/services/ImageryHybrid/MapServer"
    }],

    // Initial map extent. Use comma (,) to separate values and don t delete the last comma.
    DefaultExtent: "-9816010,5123000,-9809970,5129500",

    // ------------------------------------------------------------------------------------------------------------------------
    // INFO-POPUP SETTINGS
    // ------------------------------------------------------------------------------------------------------------------------
    // Info-popup is a popup dialog that gets displayed on selecting a feature

    //Field for Displaying the features as info window header.
    InfoWindowHeader: "NAME",

    // Set the content to be displayed on the info-Popup. Define labels, field values, field types and field formats.
    InfoPopupFieldsCollection: [{
        DisplayText: "Name:",
        FieldName: "NAME"
    }, {
        DisplayText: "Address:",
        FieldName: "FULLADDR"
    }, {
        DisplayText: "Contact:",
        FieldName: "CONTACT"
    }, {
        DisplayText: "Phone:",
        FieldName: "PHONE"
    }, {
        DisplayText: "Email:",
        FieldName: "EMAIL"
    }, {
        DisplayText: "Days Open:",
        FieldName: "OPERDAYS"
    }, {
        DisplayText: "Hours of Operation:",
        FieldName: "OPERHOURS"
    }],

    // Set size of the info-Popup - select maximum height and width in pixels.
    //minimum height should be 200 for the info-popup in pixels
    InfoPopupHeight: 200,

    //minimum width should be 300 for the info-popup in pixels
    InfoPopupWidth: 300,

    // Set string value to be shown for null or blank values.
    ShowNullValueAs: "N/A",

    // ------------------------------------------------------------------------------------------------------------------------
    // ADDRESS SEARCH SETTINGS
    // ------------------------------------------------------------------------------------------------------------------------
    // Set Locator service URL.

    LocatorSettings: {
        LocatorMarkupSymbolPath: "images/RedPushpin.png", // Set pushpin image path.
        MarkupSymbolSize: {
            width: 25,
            height: 25
        },
        Locators: [{
            DisplayText: "Search Address", //Set placeholder text
            DefaultValue: "7S610 Carriage Way Ct Naperville IL", // Set default address to search.
            LocatorParameters: ["SingleLine"], // Set Locator fields (fields to be used for searching).
            LocatorURL: "http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer",
            CandidateFields: "Loc_name, Score, Match_addr", //Set which fields are returned in results
            DisplayField: "${Match_addr}", //Set which field from results is displayed
            AddressMatchScore: 80, //Set minimum score to be considered a match
            LocatorFieldName: 'Loc_name', //The returned field which specifies match type (specific locator within composite)
            LocatorFieldValues: ["USA.StreetName", "USA.PointAddress", "USA.StreetAddress"] //List of acceptable individual locators (within composite)
        }]
    },

    // ------------------------------------------------------------------------------------------------------------------------
    // GEOMETRY SERVICE SETTINGS
    // ------------------------------------------------------------------------------------------------------------------------
    // Set geometry service URL.
    GeometryService: "http://tasks.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer",

    // ------------------------------------------------------------------------------------------------------------------------
    // DRIVING DIRECTIONS SETTINGS
    // ------------------------------------------------------------------------------------------------------------------------
    // Set URL for routing service (network analyst).
    RouteServiceURL: "http://route.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World",

    // Set color for the route symbol.
    RouteColor: "#CC6633",

    // Set width of the route.
    RouteWidth: 4,

    // Set this to true to show directions on map
    SearchforDirections: false,

    // ------------------------------------------------------------------------------------------------------------------------
    // SETTINGS FOR INFO-PODS ON THE BOTTOM PANEL
    // ------------------------------------------------------------------------------------------------------------------------
    // Set width of the boxes in the bottom panel.
    InfoBoxWidth: 417,

    //Operational layer collection.
    Services: {
        EvacArea: {
            Name: "Evacuation Areas",
            Image: "images/EvacArea.png",
            HasRendererImage: false,
            ServiceUrl: "http://tryitlive.arcgis.com/arcgis/rest/services/HazardServices/MapServer/6",
            FieldNames: [{
                Field: "Evacuation Areas: ${DESCRIPTION}"
            }, {
                Links: [{
                    DisplayText: "Website",
                    FieldName: "EVACURL",
                    type: "web"
                }]
            }],
            Color: "#FCD208",
            isRendererColor: true,
            LayerVisibility: true
        },
        FloodHazards: {
            Name: "Flood Hazards",
            Image: "images/Flood.png",
            HasRendererImage: false,
            ServiceUrl: "http://tryitlive.arcgis.com/arcgis/rest/services/HazardServices/MapServer/7",
            FieldNames: [{
                Field: "Flood Zone: ${FLOODZONE}"
            }],
            Color: "#FCD208",
            isRendererColor: true,
            LayerVisibility: true
        },
        Hazards: {
            Name: "Hazardous Facilities",
            Image: "images/HazardFacilities.png",
            HasRendererImage: false,
            ServiceUrl: "http://tryitlive.arcgis.com/arcgis/rest/services/HazardServices/MapServer/0",
            distance: 4,
            FieldNames: [{
                FieldName: "NAME"
            }, {
                FieldName: "FULLADDR"
            }, {
                FieldName: "PHONE"
            }],
            LayerVisibility: true,
            ShowBeyondBuffer: true
        },
        Hospitals: {
            Name: "Hospitals",
            Image: "images/hospital.png",
            HasRendererImage: false,
            ServiceUrl: "http://tryitlive.arcgis.com/arcgis/rest/services/HazardServices/MapServer/1",
            distance: 4,
            FieldNames: [{
                FieldName: "NAME"
            }, {
                FieldName: "FULLADDR"
            }, {
                FieldName: "PHONE"
            }],
            LayerVisibility: true,
            ShowBeyondBuffer: true
        },
        PoliceStations: {
            Name: "Police Stations",
            Image: "images/policeStations.png",
            HasRendererImage: false,
            ServiceUrl: "http://tryitlive.arcgis.com/arcgis/rest/services/HazardServices/MapServer/2",
            distance: 4,
            FieldNames: [{
                FieldName: "NAME"
            }, {
                FieldName: "FULLADDR"
            }, {
                FieldName: "PHONE"
            }],
            LayerVisibility: true,
            ShowBeyondBuffer: true
        },
        FireStations: {
            Name: "Fire Stations",
            Image: "images/fireStations.png",
            HasRendererImage: false,
            ServiceUrl: "http://tryitlive.arcgis.com/arcgis/rest/services/HazardServices/MapServer/3",
            distance: 4,
            FieldNames: [{
                FieldName: "NAME"
            }, {
                FieldName: "FULLADDR"
            }, {
                FieldName: "PHONE"
            }],
            LayerVisibility: true,
            ShowBeyondBuffer: true
        },
        CoolCenter: {
            Name: "Cooling Center",
            Image: "images/CoolCenter.png",
            HasRendererImage: false,
            ServiceUrl: "http://tryitlive.arcgis.com/arcgis/rest/services/HazardServices/MapServer/4",
            distance: 4,
            FieldNames: [{
                FieldName: "FACNAME"
            }, {
                FieldName: "HOURSOPER"
            }, {
                FieldName: "CAPACITY"
            }],
            LayerVisibility: true,
            ShowBeyondBuffer: true
        },
        WarmCenter: {
            Name: "Warming Center",
            Image: "images/WarmCenter.png",
            HasRendererImage: false,
            ServiceUrl: "http://tryitlive.arcgis.com/arcgis/rest/services/HazardServices/MapServer/5",
            distance: 4,
            FieldNames: [{
                FieldName: "FACNAME"
            }, {
                FieldName: "HOURSOPER"
            }, {
                FieldName: "CAPACITY"
            }],
            LayerVisibility: true,
            ShowBeyondBuffer: true
        }
    },

    // ServiceUrl is the REST end point for the reference overlay layer
    // DisplayOnLoad setting this will show the reference overlay layer on load
    ReferenceOverlayLayer: {
        ServiceUrl: "http://tryitlive.arcgis.com/arcgis/rest/services/HazardReference/MapServer",
        DisplayOnLoad: true
    },

    //Set required zoom level.
    ZoomLevel: 6,

    //Set Address to be displayed on mobile callout.
    CallOutAddress: "Street: ${Address}",

    //Set Renderer color for selected feature.
    RendererColor: "#CC6633",

    //Set size of the ripple.
    RippleSize: 25,

    // ------------------------------------------------------------------------------------------------------------------------
    // SETTINGS FOR MAP SHARING
    // ------------------------------------------------------------------------------------------------------------------------
    // Set URL for TinyURL service, and URLs for social media.
    MapSharingOptions: {
        TinyURLServiceURL: "http://api.bit.ly/v3/shorten?login=esri&apiKey=R_65fd9891cd882e2a96b99d4bda1be00e&uri=${0}&format=json",
        TinyURLResponseAttribute: "data.url",
        FacebookShareURL: "http://www.facebook.com/sharer.php?u=${0}&t=My%20Government%20Services",
        TwitterShareURL: "http://mobile.twitter.com/compose/tweet?status=My%20Government%20Services ${0}",
        ShareByMailLink: "mailto:%20?subject=Check%20out%20this%20map!&body=${0}"
    }
});
<|endoftext|>


<commit_before>const path = require('path');
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const PostCSSAssetsPlugin = require('postcss-assets-webpack-plugin');
const ManifestPlugin = require('webpack-manifest-plugin');

module.exports = () => {
    const mode = 'production';
    const targetPath = 'public/app/themes/wordpress-boilerplate/assets';

    return {
        mode: mode,
        entry: {
            'main': [
                './assets/webpack-public-path.js',
                './assets/main/index.js',
            ],
        },
        output: {
            path: path.resolve(__dirname, targetPath),
            //publicPath: '/app/themes/wordpress-boilerplate/assets/',
            filename: '[name].[contenthash].js',
            chunkFilename: '[name].[contenthash].js',
        },
        optimization: {
            runtimeChunk: 'single'
        },
        resolve: {
            extensions: ['.js', '.css', '.json']
        },
        module: {
            strictExportPresence: true,
            rules: [
                {
                    test: /\.js$/,
                    use: [
                        {
                            loader: 'babel-loader',
                            options: {
                                cacheDirectory: true,
                                babelrc: false,
                                presets: [
                                    [
                                        '@babel/preset-env',
                                        {
                                            useBuiltIns: 'entry',
                                            modules: false,
                                            debug: true,
                                        }
                                    ]
                                ],
                                plugins: [
                                    '@babel/plugin-syntax-dynamic-import',
                                ]
                            },
                        },
                    ],
                },
                {
                    test: /\.css$/,
                    use: [
                        mode !== 'production' ? 'style-loader' : MiniCssExtractPlugin.loader,
                        {
                            loader: 'css-loader',
                            options: {
                                importLoaders: 1,
                                minimize: false, // Minification done by the PostCSSAssetsPlugin
                            }
                        },
                        {
                            loader: 'postcss-loader',
                            options: {
                                plugins: [
                                    require('postcss-import')(),
                                    require('postcss-cssnext')(),
                                    require('postcss-flexbugs-fixes')()
                                ]
                            }
                        }
                    ],
                },
                {
                    test: /\.(gif|png|jpe?g|svg)$/i,
                    use: [
                        'file-loader',
                        {
                            loader: 'image-webpack-loader',
                            options: {
                                bypassOnDebug: true,
                            },
                        },
                    ],
                },
                {
                    test: /\.(woff|woff2|eot|ttf|otf)$/,
                    use: [
                        'file-loader',
                    ],
                },
            ],
        },
        plugins: [
            new CleanWebpackPlugin([targetPath + '/*']),
            // https://webpack.js.org/guides/caching/#module-identifiers
            new webpack.HashedModuleIdsPlugin(),
            new MiniCssExtractPlugin({
                filename: '[name].[contenthash].css',
                chunkFilename: '[name].[contenthash].css',
            }),
            new PostCSSAssetsPlugin({
                plugins: [
                    require('cssnano')({
                        preset: ['default', {
                            discardComments: {
                                removeAll: true,
                            },
                        }]
                    }),
                ],
            }),
            new ManifestPlugin(),
        ]
    };
};
<commit_msg>Use 'disable' instead of deprecated 'bypassOnDebug' option for image-webpack-loader<commit_after>const path = require('path');
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const PostCSSAssetsPlugin = require('postcss-assets-webpack-plugin');
const ManifestPlugin = require('webpack-manifest-plugin');

module.exports = () => {
    const mode = 'production';
    const targetPath = 'public/app/themes/wordpress-boilerplate/assets';

    return {
        mode: mode,
        entry: {
            'main': [
                './assets/webpack-public-path.js',
                './assets/main/index.js',
            ],
        },
        output: {
            path: path.resolve(__dirname, targetPath),
            //publicPath: '/app/themes/wordpress-boilerplate/assets/',
            filename: '[name].[contenthash].js',
            chunkFilename: '[name].[contenthash].js',
        },
        optimization: {
            runtimeChunk: 'single'
        },
        resolve: {
            extensions: ['.js', '.css', '.json']
        },
        module: {
            strictExportPresence: true,
            rules: [
                {
                    test: /\.js$/,
                    use: [
                        {
                            loader: 'babel-loader',
                            options: {
                                cacheDirectory: true,
                                babelrc: false,
                                presets: [
                                    [
                                        '@babel/preset-env',
                                        {
                                            useBuiltIns: 'entry',
                                            modules: false,
                                            debug: true,
                                        }
                                    ]
                                ],
                                plugins: [
                                    '@babel/plugin-syntax-dynamic-import',
                                ]
                            },
                        },
                    ],
                },
                {
                    test: /\.css$/,
                    use: [
                        mode !== 'production' ? 'style-loader' : MiniCssExtractPlugin.loader,
                        {
                            loader: 'css-loader',
                            options: {
                                importLoaders: 1,
                                minimize: false, // Minification done by the PostCSSAssetsPlugin
                            }
                        },
                        {
                            loader: 'postcss-loader',
                            options: {
                                plugins: [
                                    require('postcss-import')(),
                                    require('postcss-cssnext')(),
                                    require('postcss-flexbugs-fixes')()
                                ]
                            }
                        }
                    ],
                },
                {
                    test: /\.(gif|png|jpe?g|svg)$/i,
                    use: [
                        'file-loader',
                        {
                            loader: 'image-webpack-loader',
                            options: {
                                disable: mode !== 'production',
                            },
                        },
                    ],
                },
                {
                    test: /\.(woff|woff2|eot|ttf|otf)$/,
                    use: [
                        'file-loader',
                    ],
                },
            ],
        },
        plugins: [
            new CleanWebpackPlugin([targetPath + '/*']),
            // https://webpack.js.org/guides/caching/#module-identifiers
            new webpack.HashedModuleIdsPlugin(),
            new MiniCssExtractPlugin({
                filename: '[name].[contenthash].css',
                chunkFilename: '[name].[contenthash].css',
            }),
            new PostCSSAssetsPlugin({
                plugins: [
                    require('cssnano')({
                        preset: ['default', {
                            discardComments: {
                                removeAll: true,
                            },
                        }]
                    }),
                ],
            }),
            new ManifestPlugin(),
        ]
    };
};
<|endoftext|>


<commit_before>import Style from './style.css';
import ChatTemplate from './chat.html';

//Teste
export default class Application {
  constructor() {
    this.APIURL = 'https://api.0mn.io/partners';

    this.IFRAMEURL_HMG = 'https://hmg-blip-sdk.azurewebsites.net/chat';
    this.IFRAMEURL_LOCAL = 'http://localhost:3000/chat';
    this.IFRAMEURL_PRD = 'https://blip-sdk.azurewebsites.net/chat'
    this.IFRAMEURL = this.IFRAMEURL_LOCAL;

    if (process.env.NODE_ENV === 'homolog') {
      this.IFRAMEURL = this.IFRAMEURL_HMG;
    } else if (process.env.NODE_ENV === 'production') {
      this.IFRAMEURL = this.IFRAMEURL_PRD;
    }

  }

  /* Init chat and set values, style and cookies */
  openBlipThread() {
    let params = 'apikey=' + this._apiKey;

    //Chat HTML element
    this.buildChat(params);
  }

  /* Build chat HTML element */
  buildChat(params) {
    let body = document.getElementsByTagName('body')[0];
    //Div element
    let chatDiv = document.createElement('div');

    //Div ID and Class
    chatDiv.id = 'take-chat';
    chatDiv.className = 'blip-hidden-chat';
    chatDiv.innerHTML = ChatTemplate;

    body.appendChild(chatDiv);

    //Chat iframe
    let chatIframe = document.createElement('iframe');
    chatIframe.width = 290;
    chatIframe.height = 400;
    chatIframe.src = this.IFRAMEURL + '?' + params;

    chatDiv.appendChild(chatIframe);

    let closeBtn = document.getElementById('blip-close-btn');
    closeBtn.addEventListener('click', () => {
      if (chatDiv.getAttribute('class') == 'blip-hidden-chat') {
        chatDiv.setAttribute('class', 'blip-show-chat');
      }
      else {
        chatDiv.setAttribute('class', 'blip-hidden-chat');
      }
    });
  }
}
<commit_msg>Remove unnecessary comment<commit_after>import Style from './style.css';
import ChatTemplate from './chat.html';

export default class Application {
  constructor() {
    this.APIURL = 'https://api.0mn.io/partners';

    this.IFRAMEURL_HMG = 'https://hmg-blip-sdk.azurewebsites.net/chat';
    this.IFRAMEURL_LOCAL = 'http://localhost:3000/chat';
    this.IFRAMEURL_PRD = 'https://blip-sdk.azurewebsites.net/chat'
    this.IFRAMEURL = this.IFRAMEURL_LOCAL;

    if (process.env.NODE_ENV === 'homolog') {
      this.IFRAMEURL = this.IFRAMEURL_HMG;
    } else if (process.env.NODE_ENV === 'production') {
      this.IFRAMEURL = this.IFRAMEURL_PRD;
    }

  }

  /* Init chat and set values, style and cookies */
  openBlipThread() {
    let params = 'apikey=' + this._apiKey;

    //Chat HTML element
    this.buildChat(params);
  }

  /* Build chat HTML element */
  buildChat(params) {
    let body = document.getElementsByTagName('body')[0];
    //Div element
    let chatDiv = document.createElement('div');

    //Div ID and Class
    chatDiv.id = 'take-chat';
    chatDiv.className = 'blip-hidden-chat';
    chatDiv.innerHTML = ChatTemplate;

    body.appendChild(chatDiv);

    //Chat iframe
    let chatIframe = document.createElement('iframe');
    chatIframe.width = 290;
    chatIframe.height = 400;
    chatIframe.src = this.IFRAMEURL + '?' + params;

    chatDiv.appendChild(chatIframe);

    let closeBtn = document.getElementById('blip-close-btn');
    closeBtn.addEventListener('click', () => {
      if (chatDiv.getAttribute('class') == 'blip-hidden-chat') {
        chatDiv.setAttribute('class', 'blip-show-chat');
      }
      else {
        chatDiv.setAttribute('class', 'blip-hidden-chat');
      }
    });
  }
}
<|endoftext|>


<commit_before>// Handler when the DOM is fully loaded
document.addEventListener("DOMContentLoaded", function(){
    dataLayer.push({ language: getLanguage().toUpperCase() });
    dataLayer.push({ event: 'page_load' });

    const clients_country = getClientCountry();

    // Handle form submission
    if (window.location.hash === '#done') {
        dataLayer.push({ bom_country_abbrev: clients_country || '' });
        dataLayer.push({ event: 'ico_success' });
        for (let i = 0; i < 2; i++) {
            document.querySelectorAll('.notice-msg')[i].classList.remove('invisible');
            document.getElementsByTagName('form')[i].classList.add('invisible');
        }
        if (window.history.pushState) {
            window.history.pushState('', '/', window.location.pathname)
        } else {
            window.location.hash = '';
        }
        let navbarHeight = checkWidth();
        const to = document.getElementById('coming-soon').offsetTop - navbarHeight;
        scrollTo(to);
    }

    // Set language fields
    const language = getLanguage();
    const el_langs = document.getElementsByClassName('frm-language');
    for (let i = 0; i < el_langs.length; i++) {
        el_langs[i].value = language;
    }

    toggleMobileMenu();

    // Scroll to section
    document.addEventListener('click', function(e) {
        if (e.target.classList.contains('page-scroll')) {
            document.getElementById('home').classList.remove('invisible');
            document.getElementById('faq').classList.add('invisible');
            const target = e.target.getAttribute('href').substr(1);
            const offset = /who-we-are|page-top/.test(target) ? 55 : 0;
            const navbarHeight = checkWidth();
            const to = document.getElementById(target).offsetTop - navbarHeight - offset;
            scrollTo(to);
            e.preventDefault();
        }
    });

    const faqButtons = document.getElementsByClassName('faq-btn');
    for (let i = 0; i < faqButtons.length; i++) {
        faqButtons[i].addEventListener('click', function(e) {
            document.getElementById('faq').classList.remove('invisible');
            scrollTo(0);
            e.stopPropagation();
            document.getElementById('home').classList.add('invisible');
        });
    };

    window.onresize = checkWidth;
    window.onscroll = collapseNavbar;
    document.ready = collapseNavbar;
});

function getClientCountry() {
    let clients_country = sessionStorage.getItem('clients_country');
    let residence_list  = sessionStorage.getItem('residence_list');

    // Try to get residence from client's info if logged-in
    if (!clients_country) {
        const accounts = JSON.parse(localStorage.getItem('client.accounts') || null);
        if (accounts) {
            Object.keys(accounts).some(function (loginid) {
                if (accounts[loginid].residence) {
                    clients_country = accounts[loginid].residence;
                    setSession('clients_country', clients_country);
                    return true;
                }
            });
        }
    }

    // Get required info from WebSocket
    if (!clients_country || !residence_list) {
        const ws = wsConnect();

        function sendRequests() {
            if (!clients_country) wsSend(ws, { website_status: 1 });
            if (!residence_list)  wsSend(ws, { residence_list: 1 });
        }

        if (ws.readyState === 1) {
            sendRequests();
        } else {
            ws.onopen = sendRequests;
        }

        ws.onmessage = function (msg) {
            const response = JSON.parse(msg.data);
            if (response.website_status) {
                clients_country = response.website_status.clients_country;
                setSession('clients_country', clients_country);
            } else if (response.residence_list) {
                setSession('residence_list', JSON.stringify(response.residence_list));
            }
        }
    }

    return clients_country;
}

// Collapse navbar on scroll
function collapseNavbar() {
    const navbarFixedTopEl = document.getElementsByClassName('navbar-fixed-top');
    navbarFixedTopEl[0].classList[window.scrollY > 50 ? 'add' : 'remove']('top-nav-collapse');
}
<commit_msg>Add hash to ico faq<commit_after>// Handler when the DOM is fully loaded
document.addEventListener("DOMContentLoaded", function(){
    dataLayer.push({ language: getLanguage().toUpperCase() });
    dataLayer.push({ event: 'page_load' });

    const clients_country = getClientCountry();

    // Handle form submission
    if (window.location.hash === '#done') {
        dataLayer.push({ bom_country_abbrev: clients_country || '' });
        dataLayer.push({ event: 'ico_success' });
        for (let i = 0; i < 2; i++) {
            document.querySelectorAll('.notice-msg')[i].classList.remove('invisible');
            document.getElementsByTagName('form')[i].classList.add('invisible');
        }
        if (window.history.pushState) {
            window.history.pushState('', '/', window.location.pathname)
        } else {
            window.location.hash = '';
        }
        let navbarHeight = checkWidth();
        const to = document.getElementById('coming-soon').offsetTop - navbarHeight;
        scrollTo(to);
    }

    if (window.location.hash === '#faq') {
        document.getElementById('faq').classList.remove('invisible');
        document.getElementById('home').classList.add('invisible');
    }

    // Set language fields
    const language = getLanguage();
    const el_langs = document.getElementsByClassName('frm-language');
    for (let i = 0; i < el_langs.length; i++) {
        el_langs[i].value = language;
    }

    toggleMobileMenu();

    // Scroll to section
    document.addEventListener('click', function(e) {
        if (e.target.classList.contains('page-scroll')) {
            document.getElementById('home').classList.remove('invisible');
            document.getElementById('faq').classList.add('invisible');
            const target = e.target.getAttribute('href').substr(1);
            const offset = /who-we-are|page-top/.test(target) ? 55 : 0;
            const navbarHeight = checkWidth();
            const to = document.getElementById(target).offsetTop - navbarHeight - offset;
            scrollTo(to);
            e.preventDefault();
        }
    });

    const faqButtons = document.getElementsByClassName('faq-btn');
    for (let i = 0; i < faqButtons.length; i++) {
        faqButtons[i].addEventListener('click', function(e) {
            document.getElementById('faq').classList.remove('invisible');
            scrollTo(0);
            e.stopPropagation();
            document.getElementById('home').classList.add('invisible');
        });
    };

    window.onresize = checkWidth;
    window.onscroll = collapseNavbar;
    document.ready = collapseNavbar;
});

function getClientCountry() {
    let clients_country = sessionStorage.getItem('clients_country');
    let residence_list  = sessionStorage.getItem('residence_list');

    // Try to get residence from client's info if logged-in
    if (!clients_country) {
        const accounts = JSON.parse(localStorage.getItem('client.accounts') || null);
        if (accounts) {
            Object.keys(accounts).some(function (loginid) {
                if (accounts[loginid].residence) {
                    clients_country = accounts[loginid].residence;
                    setSession('clients_country', clients_country);
                    return true;
                }
            });
        }
    }

    // Get required info from WebSocket
    if (!clients_country || !residence_list) {
        const ws = wsConnect();

        function sendRequests() {
            if (!clients_country) wsSend(ws, { website_status: 1 });
            if (!residence_list)  wsSend(ws, { residence_list: 1 });
        }

        if (ws.readyState === 1) {
            sendRequests();
        } else {
            ws.onopen = sendRequests;
        }

        ws.onmessage = function (msg) {
            const response = JSON.parse(msg.data);
            if (response.website_status) {
                clients_country = response.website_status.clients_country;
                setSession('clients_country', clients_country);
            } else if (response.residence_list) {
                setSession('residence_list', JSON.stringify(response.residence_list));
            }
        }
    }

    return clients_country;
}

// Collapse navbar on scroll
function collapseNavbar() {
    const navbarFixedTopEl = document.getElementsByClassName('navbar-fixed-top');
    navbarFixedTopEl[0].classList[window.scrollY > 50 ? 'add' : 'remove']('top-nav-collapse');
}
<|endoftext|>


<commit_before>// View model for the courses page
function pageViewModel(gvm) {
    // Page specific i18n bindings
    gvm.title = ko.computed(function(){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("CoursesTitle");}, gvm);
    gvm.pageHeader = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("CoursesHeader");}, gvm);
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectName");}, gvm);

    gvm.availableLocations = ko.observableArray([]);
    gvm.availableTrainings = ko.observableArray([]);
    gvm.availableCourses = ko.observableArray([]);

    gvm.addAvailableLocations = function(id, name) {
        var selectObject = {id: id, locationName: name};
        gvm.availableLocations.push(selectObject);
    }
    gvm.addAvailableTrainings = function(id, name) {
        var selectObject = {id: id, trainingName: name};
        gvm.availableTrainings.push(selectObject);
    }

    gvm.addAvailableCourses = function(id, name) {
        var selectObject = {id: id, courseName: name};
        gvm.availableCourses.push(selectObject);
    }

    gvm.clearAll = function() {
        gvm.availableLocations.removeAll();
        gvm.availableTrainings.removeAll();
        gvm.availableCourses.removeAll();
    }
}

function loadAllSelects($locationid, $trainingid)
{
    viewModel.clearAll();
    $.getJSON('/api/courses/' + $locationid + '/' +  $trainingid, function(data) {
        $.each(data[1],function(i, item) {
            viewModel.addAvailableLocations(item.id, item.name);
        });
        $.each(data[2], function(i, item) {
            viewModel.addAvailableTrainings(item.id, item.name);
        });
        $.each(data[3], function(i, item) {
            viewModel.addAvailableCourses(item.id, item.name);
        });
    });
    bindEvents();
}

function bindEvents() {
    $("#location").bind("change", function() {
        $("#location").unbind("change").done($("#training").unbind("change").done(loadAllSelects($("#location").val(), $("#training").val())));
    });
    $("#training").bind("change", function() {
        $("#location").unbind("change").done($("#training").unbind("change").done(loadAllSelects($("#location").val(), $("#training").val())));
    });
}

function initPage() {
    loadAllSelects(1,1);
}<commit_msg>courses<commit_after>// View model for the courses page
function pageViewModel(gvm) {
    // Page specific i18n bindings
    gvm.title = ko.computed(function(){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("CoursesTitle");}, gvm);
    gvm.pageHeader = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("CoursesHeader");}, gvm);
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectName");}, gvm);

    gvm.isUpdating = false;

    gvm.availableLocations = ko.observableArray([]);
    gvm.availableTrainings = ko.observableArray([]);
    gvm.availableCourses = ko.observableArray([]);

    gvm.addAvailableLocations = function(id, name) {
        var selectObject = {id: id, locationName: name};
        gvm.availableLocations.push(selectObject);
    }
    gvm.addAvailableTrainings = function(id, name) {
        var selectObject = {id: id, trainingName: name};
        gvm.availableTrainings.push(selectObject);
    }

    gvm.addAvailableCourses = function(id, name) {
        var selectObject = {id: id, courseName: name};
        gvm.availableCourses.push(selectObject);
    }

    gvm.clearAll = function() {
        gvm.availableLocations.removeAll();
        gvm.availableTrainings.removeAll();
        gvm.availableCourses.removeAll();
    }
}

function loadAllSelects($locationid, $trainingid)
{
    viewModel.isUpdating = true;
    viewModel.clearAll();
    $.getJSON('/api/courses/' + $locationid + '/' +  $trainingid, function(data) {
        $.each(data[1],function(i, item) {
            viewModel.addAvailableLocations(item.id, item.name);
        });
        $.each(data[2], function(i, item) {
            viewModel.addAvailableTrainings(item.id, item.name);
        });
        $.each(data[3], function(i, item) {
            viewModel.addAvailableCourses(item.id, item.name);
        });
    });
    viewModel.isUpdating = false;
    bindEvents();
}

function bindEvents() {
    if(!viewModel.isUpdating) {
        $("#location").one("change", function() {
            loadAllSelects($("#location").val(), $("#training").val());
        });
        $("#training").bind("change", function() {
            loadAllSelects($("#location").val(), $("#training").val());
        });
        viewModel.isUpdating = false;
    }
}

function initPage() {
    loadAllSelects(1,1);
}<|endoftext|>


<commit_before>#!/usr/bin/env node

/**
 * Geolistic command line tool
 *
 * Copyright (c) 2017 Gunnar Skeid
 */
'use strict';

var config,
    testMode = (process.env.TEST ? true : false);

try {config = require('./data/cli-config.json')} catch (ex) {config = {}};

var elasticUrl = process.env.ELASTIC_URL || config["elasticUrl"] || "127.0.0.1:9200",
    elasticPath = process.env.ELASTIC_PATH || config["elasticPath"] || "geonames/geoname",
    dataPath = process.env.DATAPATH || config["dataPath"];  // no default for dataPath, as the library handles it with os.tmpdir()

elasticUrl = elasticUrl.replace(/^(https\:\/\/|http\:\/\/)/, "");
elasticUrl = elasticUrl.replace("/", "");

// We only init with dataPath
// elastic is only set later if needed and after we've connected to it
var options = {};
if (dataPath) {
    options.dataPath = dataPath;
}

const elasticsearch = require('elasticsearch'),
    parse = require('csv-parse'),
    fs = require('fs'),
    transform = require('stream-transform'),
    geolistic = require('./lib').init(options);

const NS_PER_SEC = 1e9;

var processTime,
    db = null,
    countryCode = null,
    doHelp = false,
    doAdd = false,
    doDownload = false,
    bufferRecords = null,
    fclasses = null;

function _add(countries) {

    db = testMode ?
        {close: function () {}, ping: function (args, fn) {fn(null);}} :
        new elasticsearch.Client({
            host: elasticUrl,
            log: []
        });

    db.ping({}, function (err) {

        if (err) {
            console.error("Error connecting to elastic, check your config");
            console.error(err);
            db.close();
            return;
        }

        try {

            geolistic.config({
                elasticClient: db,
                elasticPath: elasticPath
            });

        } catch (err) {

            console.error(err);
            db.close();
            return;
        }

        var options = {
            "bufferAdded": function(records) {

                var mem = process.memoryUsage().heapUsed;

                if (mem > 1000000) {
                    mem = parseInt(mem/1000000) + 'm';
                } else if (mem > 1000) {
                    mem = parseInt(mem/1000) + 'k';
                } else {
                    mem = mem + 'b';
                }

                var diffTime = process.hrtime(processTime);

                var recordsPerSec = parseInt(records / (diffTime[0] + (diffTime[1]/NS_PER_SEC)));

                process.stdout.write("\rProcessed " + records + " records (" + mem + " mem, " +
                    diffTime[0] + ":" + parseInt(diffTime[1]/1000000) +" elapsed " +
                    recordsPerSec + " records/sec) ");

            }};

        if (fclasses) {
            options.classFilters = fclasses;
        }
        if (bufferRecords) {
            options.bufferRecords = bufferRecords;
        }

        var allProcessed = 0,
            allAdded = 0;

        (function addCountry(index) {
            index = index || 0;

            if (!countries[index]) {

                console.log("All done with %d processed and %d added records",
                    allProcessed,
                    allAdded);

                if (db) {
                    db.close();
                }
                return;

            }

            processTime = process.hrtime();

            geolistic.addFileToElastic(countries[index], options, function (err, result) {

                if (err) {

                    console.error(err);

                } else {

                    console.log("\n%s finished with %d processed and %d added records",
                        countries[index],
                        result.processed,
                        result.added);

                    allProcessed += result.processed;
                    allAdded += result.added;

                    addCountry(index + 1);
                }

            });

        })();

    });

}

var args = process.argv.slice(2);

for (var i = 0; i < args.length; i += 1) {

    if (args[i] === '-help' || args[i] === '--help') {

        doHelp = true;

    } else if (args[i] === '-addall') {

        doAdd = true;
        fclasses = [];

    } else if (args[i] === '-add') {

        doAdd = true;
        fclasses = [];

        if (args.length < (i + 1)) {
            console.error("Missing argument: countryCode");
            process.exit(0);
        }

        i += 1;

        countryCode = args[i];
        if (countryCode === '00') {
            testMode = true;
        }

    } else if (args[i] === '-downloadall') {

        doDownload = true;

    } else if (args[i] === '-buffer') {

        if (args.length < (i + 1)) {
            console.error("Missing argument: buffer size");
            process.exit(0);
        }

        i += 1;

        bufferRecords = +args[i];

    } else if (args[i] === '-download') {

        doDownload = true;

        if (args.length < (i + 1)) {
            console.error("Missing argument: countryCode");
            process.exit(0);
        }

        i += 1;

        countryCode = args[i];

    } else {

        if (fclasses) {
            fclasses[fclasses.length] = args[i];
            continue;
        } else {

            console.warn("Unknown argument '" + args[i] + "'");

        }

    }

}

if (doHelp || (!doAdd && !doDownload)) {

    console.log("Usage: node geolistic-cli [OPTION]\n" +
        "Download or index geoname files in elastic\n" +
        "\n" +
        "Valid arguments:\n" +
        "  -download <country code>       Download specified country geoname file\n" +
        "  -downloadall                   Download all country geoname files\n" +
        "  -add <country code> [fclasses] Index specified country geoname file\n" +
        "  -addall [fclasses]             Index all country geoname files\n" +
        "  -buffer <records>              Buffer size in records (only for add operations), defaults to 1000\n" +
        "\n" +
        "For valid fclasses see http://www.geonames.org/export/codes.html\n" +
        "  A - country, state, region\n" +
        "  P - city, village\n" +
        "  etc...\n" +
        "\n" +
        "Example: node geolistic-cli -add NO F A"
    );

    return;

}

if (doDownload || doAdd) {

    var getCountries;

    if (countryCode) {
        getCountries = function (fn) {
            fn(null, [countryCode]);
        };
    } else {
        getCountries = function (fn) {
            geolistic.getGeoNameCountries(fn);
        };
    }

    getCountries(function (err, countries) {

        if (err) {

            console.error("Error getting countries: " + err);

        } else {

            if (doDownload) {

                if (testMode) {
                    countries = ['NU'];
                }
                geolistic.downloadGeoNameCountryFiles(countries, {
                    "parallelDownloads": 5,
                    "postDownload": function (files) {

                        for (var i = 0; i < files.length; i += 1) {
                            console.log("Downloaded " + files[i]);
                        }

                    },
                    "extract": true
                }, function (err, filesProcessed) {

                    if (err) {
                        console.error(err);
                    } else {
                        console.log(filesProcessed + " files downloaded and extracted");

                        if (doAdd) {
                            _add(countries);
                        }
                    }

                });

            }

            if (doAdd && !doDownload) {

                if (testMode) {
                    countries = ['00'];
                }
                _add(countries);

            }
        }
    });
}
<commit_msg>Fix fclass filter<commit_after>#!/usr/bin/env node

/**
 * Geolistic command line tool
 *
 * Copyright (c) 2017 Gunnar Skeid
 */
'use strict';

var config,
    testMode = (process.env.TEST ? true : false);

try {config = require('./data/cli-config.json')} catch (ex) {config = {}};

var elasticUrl = process.env.ELASTIC_URL || config["elasticUrl"] || "127.0.0.1:9200",
    elasticPath = process.env.ELASTIC_PATH || config["elasticPath"] || "geonames/geoname",
    dataPath = process.env.DATAPATH || config["dataPath"];  // no default for dataPath, as the library handles it with os.tmpdir()

elasticUrl = elasticUrl.replace(/^(https\:\/\/|http\:\/\/)/, "");
elasticUrl = elasticUrl.replace("/", "");

// We only init with dataPath
// elastic is only set later if needed and after we've connected to it
var options = {};
if (dataPath) {
    options.dataPath = dataPath;
}

const elasticsearch = require('elasticsearch'),
    parse = require('csv-parse'),
    fs = require('fs'),
    transform = require('stream-transform'),
    geolistic = require('./lib').init(options);

const NS_PER_SEC = 1e9;

var processTime,
    db = null,
    countryCode = null,
    doHelp = false,
    doAdd = false,
    doDownload = false,
    bufferRecords = null,
    fclasses = null;

function _add(countries) {

    db = testMode ?
        {close: function () {}, ping: function (args, fn) {fn(null);}} :
        new elasticsearch.Client({
            host: elasticUrl,
            log: []
        });

    db.ping({}, function (err) {

        if (err) {
            console.error("Error connecting to elastic, check your config");
            console.error(err);
            db.close();
            return;
        }

        try {

            geolistic.config({
                elasticClient: db,
                elasticPath: elasticPath
            });

        } catch (err) {

            console.error(err);
            db.close();
            return;
        }

        var options = {
            "bufferAdded": function(records) {

                var mem = process.memoryUsage().heapUsed;

                if (mem > 1000000) {
                    mem = parseInt(mem/1000000) + 'm';
                } else if (mem > 1000) {
                    mem = parseInt(mem/1000) + 'k';
                } else {
                    mem = mem + 'b';
                }

                var diffTime = process.hrtime(processTime);

                var recordsPerSec = parseInt(records / (diffTime[0] + (diffTime[1]/NS_PER_SEC)));

                process.stdout.write("\rProcessed " + records + " records (" + mem + " mem, " +
                    diffTime[0] + ":" + parseInt(diffTime[1]/1000000) +" elapsed " +
                    recordsPerSec + " records/sec) ");

            }};

        if (fclasses) {
            options.classFilters = fclasses;
        }
        if (bufferRecords) {
            options.bufferRecords = bufferRecords;
        }

        var allProcessed = 0,
            allAdded = 0;

        (function addCountry(index) {
            index = index || 0;

            if (!countries[index]) {

                console.log("All done with %d processed and %d added records",
                    allProcessed,
                    allAdded);

                if (db) {
                    db.close();
                }
                return;

            }

            processTime = process.hrtime();

            geolistic.addFileToElastic(countries[index], options, function (err, result) {

                if (err) {

                    console.error(err);

                } else {

                    console.log("\n%s finished with %d processed and %d added records",
                        countries[index],
                        result.processed,
                        result.added);

                    allProcessed += result.processed;
                    allAdded += result.added;

                    addCountry(index + 1);
                }

            });

        })();

    });

}

var args = process.argv.slice(2);

for (var i = 0; i < args.length; i += 1) {

    if (args[i] === '-help' || args[i] === '--help') {

        doHelp = true;

    } else if (args[i] === '-addall') {

        doAdd = true;
        fclasses = [];

    } else if (args[i] === '-add') {

        doAdd = true;
        fclasses = [];

        if (args.length < (i + 1)) {
            console.error("Missing argument: countryCode");
            process.exit(0);
        }

        i += 1;

        countryCode = args[i];
        if (countryCode === '00') {
            testMode = true;
        }

    } else if (args[i] === '-downloadall') {

        doDownload = true;

    } else if (args[i] === '-buffer') {

        if (args.length < (i + 1)) {
            console.error("Missing argument: buffer size");
            process.exit(0);
        }

        i += 1;

        bufferRecords = +args[i];

    } else if (args[i] === '-download') {

        doDownload = true;

        if (args.length < (i + 1)) {
            console.error("Missing argument: countryCode");
            process.exit(0);
        }

        i += 1;

        countryCode = args[i];

    } else {

        if (fclasses) {
            fclasses[fclasses.length] = args[i];
            continue;
        } else {

            console.warn("Unknown argument '" + args[i] + "'");

        }

    }

}

if (doHelp || (!doAdd && !doDownload)) {

    console.log("Usage: node geolistic-cli [OPTION]\n" +
        "Download or index geoname files in elastic\n" +
        "\n" +
        "Valid arguments:\n" +
        "  -download <country code>       Download specified country geoname file\n" +
        "  -downloadall                   Download all country geoname files\n" +
        "  -add <country code> [fclasses] Index specified country geoname file\n" +
        "  -addall [fclasses]             Index all country geoname files\n" +
        "  -buffer <records>              Buffer size in records (only for add operations), defaults to 1000\n" +
        "\n" +
        "For valid fclasses see http://www.geonames.org/export/codes.html\n" +
        "  A - country, state, region\n" +
        "  P - city, village\n" +
        "  etc...\n" +
        "\n" +
        "Example: node geolistic-cli -add NO P A"
    );

    return;

}

if (doDownload || doAdd) {

    var getCountries;

    if (countryCode) {
        getCountries = function (fn) {
            fn(null, [countryCode]);
        };
    } else {
        getCountries = function (fn) {
            geolistic.getGeoNameCountries(fn);
        };
    }

    getCountries(function (err, countries) {

        if (err) {

            console.error("Error getting countries: " + err);

        } else {

            if (doDownload) {

                if (testMode) {
                    countries = ['NU'];
                }
                geolistic.downloadGeoNameCountryFiles(countries, {
                    "parallelDownloads": 5,
                    "postDownload": function (files) {

                        for (var i = 0; i < files.length; i += 1) {
                            console.log("Downloaded " + files[i]);
                        }

                    },
                    "extract": true
                }, function (err, filesProcessed) {

                    if (err) {
                        console.error(err);
                    } else {
                        console.log(filesProcessed + " files downloaded and extracted");

                        if (doAdd) {
                            _add(countries);
                        }
                    }

                });

            }

            if (doAdd && !doDownload) {

                if (testMode) {
                    countries = ['00'];
                }
                _add(countries);

            }
        }
    });
}
<|endoftext|>


<commit_before>const webpack = require('webpack');
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');

module.exports = {
    entry: {
        app: './src/main.js',
    },
    output: {
        path: path.resolve(__dirname, './dist'),
        publicPath: '/dist/',
        filename: 'lesspass.min.js'
    },
    resolve: {
        extensions: ['.json', '.js']
    },
    module: {
        rules: [
            {test: /\.vue$/, loader: 'vue-loader'},
            {test: /\.js$/, include: [path.resolve(__dirname, './src')], loader: 'babel-loader'},
            {test: /\.json/, loader: 'json-loader'},
            {test: /\.(png|jpg|jpeg|gif)$/, loader: 'file-loader?name=[name].[ext]'},
            {test: /\.scss$/, loader: ExtractTextPlugin.extract({fallbackLoader: 'style-loader', loader: 'css-loader!sass-loader', publicPath: ''})},
            {test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=8192&mimetype=application/font-woff'},
            {test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=8192&mimetype=application/font-woff'},
            {test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=8192&mimetype=application/octet-stream'},
            {test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'},
            {test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=8192&mimetype=image/svg+xml'},
        ]
    },
    plugins: [
        new ExtractTextPlugin('lesspass.min.css')
    ]
};

if (process.env.NODE_ENV === 'production') {
    module.exports.devtool = false;
    module.exports.plugins = (module.exports.plugins || []).concat([
        new OptimizeCssAssetsPlugin(),
        new webpack.optimize.UglifyJsPlugin({
            output: {comments: false},
            compress: {warnings: false}
        })
    ]);
}

<commit_msg>replace deprecated options<commit_after>const webpack = require('webpack');
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');

module.exports = {
    entry: {
        app: './src/main.js',
    },
    output: {
        path: path.resolve(__dirname, './dist'),
        publicPath: '/dist/',
        filename: 'lesspass.min.js'
    },
    resolve: {
        extensions: ['.json', '.js']
    },
    module: {
        rules: [
            {test: /\.vue$/, loader: 'vue-loader'},
            {test: /\.js$/, include: [path.resolve(__dirname, './src')], loader: 'babel-loader'},
            {test: /\.json/, loader: 'json-loader'},
            {test: /\.(png|jpg|jpeg|gif)$/, loader: 'file-loader?name=[name].[ext]'},
            {test: /\.scss$/, loader: ExtractTextPlugin.extract({fallback: 'style-loader', use: 'css-loader!sass-loader', publicPath: ''})},
            {test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=8192&mimetype=application/font-woff'},
            {test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=8192&mimetype=application/font-woff'},
            {test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=8192&mimetype=application/octet-stream'},
            {test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'},
            {test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=8192&mimetype=image/svg+xml'},
        ]
    },
    plugins: [
        new ExtractTextPlugin('lesspass.min.css')
    ]
};

if (process.env.NODE_ENV === 'production') {
    module.exports.devtool = false;
    module.exports.plugins = (module.exports.plugins || []).concat([
        new OptimizeCssAssetsPlugin(),
        new webpack.optimize.UglifyJsPlugin({
            output: {comments: false},
            compress: {warnings: false}
        })
    ]);
}

<|endoftext|>


<commit_before>function MemoryContextStore() {
  this.memory = {};
}

MemoryContextStore.prototype.start = function(callback) {
  callback();
}

MemoryContextStore.prototype.get = function(key, callback) {
  callback(this.memory[key]);
}

MemoryContextStore.prototype.set = function(key, value) {
  this.memory[key] = value;
}

module.exports = MemoryContextStore;
<commit_msg>Set key.<commit_after>function MemoryContextStore() {
  this.memory = {};
}

MemoryContextStore.prototype.start = function(callback) {
  callback();
}

MemoryContextStore.prototype.get = function(key, callback) {
  callback(this.memory[key]);
}

MemoryContextStore.prototype.set = function(key, value) {
  console.log("set key");
  this.memory[key] = value;
}

module.exports = MemoryContextStore;
<|endoftext|>


<commit_before>/**
 * Route Mappings
 * (sails.config.routes)
 *
 * Your routes map URLs to views and controllers.
 *
 * If Sails receives a URL that doesn't match any of the routes below,
 * it will check for matching files (images, scripts, stylesheets, etc.)
 * in your assets directory.  e.g. `http://localhost:1337/images/foo.jpg`
 * might match an image file: `/assets/images/foo.jpg`
 *
 * Finally, if those don't match either, the default 404 handler is triggered.
 * See `api/responses/notFound.js` to adjust your app's 404 logic.
 *
 * Note: Sails doesn't ACTUALLY serve stuff from `assets`-- the default Gruntfile in Sails copies
 * flat files from `assets` to `.tmp/public`.  This allows you to do things like compile LESS or
 * CoffeeScript for the front-end.
 *
 * For more information on configuring custom routes, check out:
 * http://sailsjs.org/#!/documentation/concepts/Routes/RouteTargetSyntax.html
 */

module.exports.routes = {

  /***************************************************************************
  *                                                                          *
  * Make the view located at `views/homepage.ejs` (or `views/homepage.jade`, *
  * etc. depending on your default view engine) your home page.              *
  *                                                                          *
  * (Alternatively, remove this and add an `index.html` file in your         *
  * `assets` directory)                                                      *
  *                                                                          *
  ***************************************************************************/

  '/': {
    view: 'homepage'
  },

  /* WISH CONTROLLER ------------------------------------------------------*/
  'put /finishWish' : 'WishController.finishWish',
  'put /acceptWish' : 'WishController.acceptWish',
  'put /makePublic' : 'WishController.makePublic',
  'put /makePrivate' : 'WishController.makePrivate',
  'get /wishes': 'WishController.getAllWishes'

  /***************************************************************************
  *                                                                          *
  * Custom routes here...                                                    *
  *                                                                          *
  * If a request to a URL doesn't match any of the custom routes above, it   *
  * is matched against Sails route blueprints. See `config/blueprints.js`    *
  * for configuration options and examples.                                  *
  *                                                                          *
  ***************************************************************************/

};
<commit_msg>Route cleaning<commit_after>/**
 * Route Mappings
 * (sails.config.routes)
 *
 * Your routes map URLs to views and controllers.
 *
 * If Sails receives a URL that doesn't match any of the routes below,
 * it will check for matching files (images, scripts, stylesheets, etc.)
 * in your assets directory.  e.g. `http://localhost:1337/images/foo.jpg`
 * might match an image file: `/assets/images/foo.jpg`
 *
 * Finally, if those don't match either, the default 404 handler is triggered.
 * See `api/responses/notFound.js` to adjust your app's 404 logic.
 *
 * Note: Sails doesn't ACTUALLY serve stuff from `assets`-- the default Gruntfile in Sails copies
 * flat files from `assets` to `.tmp/public`.  This allows you to do things like compile LESS or
 * CoffeeScript for the front-end.
 *
 * For more information on configuring custom routes, check out:
 * http://sailsjs.org/#!/documentation/concepts/Routes/RouteTargetSyntax.html
 */

module.exports.routes = {

  /***************************************************************************
  *                                                                          *
  * Make the view located at `views/homepage.ejs` (or `views/homepage.jade`, *
  * etc. depending on your default view engine) your home page.              *
  *                                                                          *
  * (Alternatively, remove this and add an `index.html` file in your         *
  * `assets` directory)                                                      *
  *                                                                          *
  ***************************************************************************/

  '/': {
    view: 'homepage'
  },

  /* WISH CONTROLLER ------------------------------------------------------*/
  'put /finishWish' : 'WishController.finishWish',
  'put /acceptWish' : 'WishController.acceptWish',
  'put /makePublic' : 'WishController.makePublic',
  'put /makePrivate' : 'WishController.makePrivate'
  /***************************************************************************
  *                                                                          *
  * Custom routes here...                                                    *
  *                                                                          *
  * If a request to a URL doesn't match any of the custom routes above, it   *
  * is matched against Sails route blueprints. See `config/blueprints.js`    *
  * for configuration options and examples.                                  *
  *                                                                          *
  ***************************************************************************/

};
<|endoftext|>


<commit_before>// functions shared by mainTreeView and recordTreeView
ngapp.service('treeService', function() {
    this.buildFunctions = function(scope, element) {
        scope.getNodeForElement = function(handle) {
            let handles = xelib.GetDuplicateHandles(handle);
            for (let i = 0; i < handles.length; i++) {
                let h = handles[i];
                let newNode = scope.tree.find((node) => { return node.handle == h; });
                if (newNode) return newNode;
            }
        };

        scope.expandNode = function(node) {
            if (!node.can_expand) return;
            let start = Date.now();
            node.expanded = true;
            let children = scope.buildNodes(node);
            let childrenLength = children.length;
            if (childrenLength > 0) {
                children.forEach((child) => child.parent = node);
                let insertionIndex = scope.tree.indexOf(node) + 1;
                scope.tree.splice(insertionIndex, 0, ...children);
                console.log(`Built ${childrenLength} nodes in ${Date.now() - start}ms`);
            } else {
                node.can_expand = false;
                node.expanded = false;
            }
        };

        scope.collapseNode = function(node) {
            if (node.expanded) delete node.expanded;
            let startIndex = scope.tree.indexOf(node) + 1,
                endIndex = startIndex;
            for (; endIndex < scope.tree.length; endIndex++) {
                let child = scope.tree[endIndex];
                if (child.depth <= node.depth) break;
                if (child.selected) scope.selectSingle(child, false);
            }
            let removedNodes = scope.tree.splice(startIndex, endIndex - startIndex);
            removedNodes.forEach((node) => xelib.Release(node.handle));
            if (scope.prevNode && scope.prevNode.parent === node) {
                scope.prevNode = undefined;
            }
        };

        scope.toggleNode = function(e, node) {
            if (node.expanded) {
                scope.collapseNode(node);
            } else {
                scope.expandNode(node);
            }
            e.stopPropagation();
        };

        let scrollbarWidth = 17;
        scope.treeMouseDown = function(e) {
            let t = scope.treeElement;
            if (e.clientX - t.offsetLeft < t.offsetWidth - scrollbarWidth) {
                scope.clearSelection(true);
            }
        };

        scope.toggleSearch = function(visible) {
            scope.showSearch = visible;
            if (!visible) scope.treeElement.focus();
        };

        scope.onKeyDown = function(e) {
            if (e.keyCode == 39) {
                scope.handleRightArrow(e);
            } else if (e.keyCode == 37) {
                scope.handleLeftArrow(e);
            } else if (e.keyCode == 40) {
                scope.handleDownArrow(e)
            } else if (e.keyCode == 38) {
                scope.handleUpArrow(e);
            } else if (e.ctrlKey && !e.shiftKey && e.keyCode == 70) {
                scope.toggleSearch(true);
            } else {
                return;
            }
            e.stopPropagation();
            e.preventDefault();
        };

        scope.resolveTreeElement = function() {
            let tabView = element[0].nextElementSibling;
            let treeNodes = tabView.lastElementChild;
            scope.treeElement = treeNodes.firstElementChild;
        };
    }
});<commit_msg>fixed bug with releasing handles when nodes are collapsed<commit_after>// functions shared by mainTreeView and recordTreeView
ngapp.service('treeService', function() {
    this.buildFunctions = function(scope, element) {
        scope.getNodeForElement = function(handle) {
            let handles = xelib.GetDuplicateHandles(handle);
            for (let i = 0; i < handles.length; i++) {
                let h = handles[i];
                let newNode = scope.tree.find((node) => { return node.handle == h; });
                if (newNode) return newNode;
            }
        };

        scope.expandNode = function(node) {
            if (!node.can_expand) return;
            let start = Date.now();
            node.expanded = true;
            let children = scope.buildNodes(node);
            let childrenLength = children.length;
            if (childrenLength > 0) {
                children.forEach((child) => child.parent = node);
                let insertionIndex = scope.tree.indexOf(node) + 1;
                scope.tree.splice(insertionIndex, 0, ...children);
                console.log(`Built ${childrenLength} nodes in ${Date.now() - start}ms`);
            } else {
                node.can_expand = false;
                node.expanded = false;
            }
        };

        scope.collapseNode = function(node) {
            if (node.expanded) delete node.expanded;
            let startIndex = scope.tree.indexOf(node) + 1,
                endIndex = startIndex;
            for (; endIndex < scope.tree.length; endIndex++) {
                let child = scope.tree[endIndex];
                if (child.depth <= node.depth) break;
                if (child.selected) scope.selectSingle(child, false);
            }
            let removedNodes = scope.tree.splice(startIndex, endIndex - startIndex);
            removedNodes.forEach(function(node) {
                if (node.handle) xelib.Release(node.handle);
                if (node.handles) {
                    node.handles.forEach((handle) => handle && xelib.Release(handle));
                }
            });
            if (scope.prevNode && scope.prevNode.parent === node) {
                scope.prevNode = undefined;
            }
        };

        scope.toggleNode = function(e, node) {
            if (node.expanded) {
                scope.collapseNode(node);
            } else {
                scope.expandNode(node);
            }
            e.stopPropagation();
        };

        let scrollbarWidth = 17;
        scope.treeMouseDown = function(e) {
            let t = scope.treeElement;
            if (e.clientX - t.offsetLeft < t.offsetWidth - scrollbarWidth) {
                scope.clearSelection(true);
            }
        };

        scope.toggleSearch = function(visible) {
            scope.showSearch = visible;
            if (!visible) scope.treeElement.focus();
        };

        scope.onKeyDown = function(e) {
            if (e.keyCode == 39) {
                scope.handleRightArrow(e);
            } else if (e.keyCode == 37) {
                scope.handleLeftArrow(e);
            } else if (e.keyCode == 40) {
                scope.handleDownArrow(e)
            } else if (e.keyCode == 38) {
                scope.handleUpArrow(e);
            } else if (e.ctrlKey && !e.shiftKey && e.keyCode == 70) {
                scope.toggleSearch(true);
            } else {
                return;
            }
            e.stopPropagation();
            e.preventDefault();
        };

        scope.resolveTreeElement = function() {
            let tabView = element[0].nextElementSibling;
            let treeNodes = tabView.lastElementChild;
            scope.treeElement = treeNodes.firstElementChild;
        };
    }
});<|endoftext|>