the PATCHES

So far we have 45 parks designed and each patch was designed to capture the each park's unique personality. Every patch is 100% embroidered, which means you will be receiving the highest quality stitch count available. The dimensions vary, but most are around 3.5" - which makes these iron-on patches amazing for display on backpacks and jackets.

 
<div class="map-canvas"></div>
<script>
// Global variables
const _classPrefix = 'si-';
const _root2 = 1.41421356237;
const _inverseRoot2 = 0.7071067811865474;
const _eventPrefix = 'snazzy-info-window-';
const _defaultShadow = {
    h: '0px',
    v: '3px',
    blur: '6px',
    spread: '0px',
    color: '#000'
};
const _defaultOptions = {
    placement: 'top',
    pointer: true,
    openOnMarkerClick: true,
    closeOnMapClick: true,
    closeWhenOthersOpen: false,
    showCloseButton: true,
    panOnOpen: true,
    edgeOffset: {
        top: 20,
        right: 20,
        bottom: 20,
        left: 20
    }
};

// Copy keys from the source into the target
function copyKeys(target, source) {
    if (target && source) {
        Object.keys(source).forEach((key) => {
            target[key] = source[key];
        });
    }
}

// We need to safely merge options from the defaults. This will make
// sure settings like edgeOffset are properly assigned.
function mergeDefaultOptions(opts) {
    const copy = {};
    copyKeys(copy, _defaultOptions);
    copyKeys(copy, opts);
    Object.keys(_defaultOptions).forEach((key) => {
        const obj = _defaultOptions[key];
        if (typeof obj === 'object') {
            const objCopy = {};
            copyKeys(objCopy, obj);
            copyKeys(objCopy, copy[key]);
            copy[key] = objCopy;
        }
    });
    return copy;
}

// Parse a css attribute into the numeric portion and the units
function parseAttribute(attribute, defaultValue) {
    // 1em, 1.0em, 0.1em, .1em, 1.    em
    const re = /^(-{0,1}\.{0,1}\d+(\.\d+)?)[\s|\.]*(\w*)$/;
    if (attribute && re.test(attribute)) {
        const match = re.exec(attribute);
        const number = match[1];
        const units = match[3] || 'px';
        return { value: number * 1, units, original: attribute };
    }
    if (defaultValue) {
        return parseAttribute(defaultValue);
    }
    return { original: defaultValue };
}

// Set the html of a container. Should support both raw text and a single
// DOM Element.
function setHTML(container, content) {
    if (container) {
        // Clear out everything in the container
        while (container.firstChild) {
            container.removeChild(container.firstChild);
        }
        if (content) {
            if (typeof content === 'string') {
                container.innerHTML = content;
            } else {
                container.appendChild(content);
            }
        }
    }
}

// Get the opposite of a given placement
function oppositePlacement(p) {
    if (p === 'top') {
        return 'bottom';
    } else if (p === 'bottom') {
        return 'top';
    } else if (p === 'left') {
        return 'right';
    } else if (p === 'right') {
        return 'left';
    }
    return p;
}

// Return the placement with the first letter capitalized
function capitalizePlacement(p) {
    return p.charAt(0).toUpperCase() + p.slice(1);
}

// Convert the value into a Google Map LatLng
function toLatLng(v) {
    if (v !== undefined && v !== null && google) {
        if (v instanceof google.maps.LatLng) {
            return v;
        } else if (v.lat !== undefined && v.lng !== undefined) {
            return new google.maps.LatLng(v);
        }
    }
    return null;
}

class SnazzyInfoWindow extends google.maps.OverlayView {

    constructor(opts) {
        super(opts);
        // Private properties
        this._html = null;
        this._opts = mergeDefaultOptions(opts);
        this._callbacks = this._opts.callbacks || {};
        this._marker = this._opts.marker;
        this._map = this._opts.map;
        this._position = toLatLng(this._opts.position);
        this._isOpen = false;
        this._listeners = [];

        // This listener remains active when the info window is closed.
        if (google && this._marker && this._opts.openOnMarkerClick) {
            this.trackListener(google.maps.event.addListener(this._marker, 'click', () => {
                if (!this.getMap()) {
                    this.open();
                }
            }), true);
        }

        // When using a position the default option for the offset is 0
        if (this._position && !this._opts.offset) {
            this._opts.offset = {
                top: '0px',
                left: '0px'
            };
        }

        // Validate the placement option
        let p = opts.placement || this._opts.position;
        // The position variable was renamed to placement so we must type check
        if (typeof p === 'string' || p instanceof String) {
            p = p.toLowerCase();
        }
        if (p !== 'top' && p !== 'bottom' &&
            p !== 'left' && p !== 'right') {
            this._opts.placement = _defaultOptions.placement;
        } else {
            this._opts.placement = p;
        }

        // Validate the position option
        p = this._opts.position;
        if (p !== undefined && p !== null &&
            typeof p !== 'string' && !(p instanceof String)) {
            this._opts.position = p;
        }

        // Validate the other options
        if (this._opts.border === undefined || this._opts.border === true) {
            this._opts.border = {};
        }
        if (this._opts.pointer === undefined) {
            this._opts.pointer = _defaultOptions.pointer;
        }
        if (this._opts.shadow === undefined || this._opts.shadow === true) {
            this._opts.shadow = {};
        }
    }

    // Activate the specified callback and return the result
    activateCallback(callback) {
        const lambda = this._callbacks[callback];
        return lambda ? lambda.apply(this) : undefined;
    }

    // Track the provided listener. A persistent listener means it remains
    // tracked even if the info window is closed.
    trackListener(listener, persistent) {
        this._listeners.push({ listener, persistent });
    }

    // Will clear all listeners that are used during the open state.
    clearListeners(clearPersistent) {
        if (google) {
            if (this._listeners) {
                this._listeners.forEach((e) => {
                    if (clearPersistent || !e.persistent) {
                        google.maps.event.removeListener(e.listener);
                        e.listener = null;
                    }
                });
                this._listeners = this._listeners.filter((e) => {
                    return e.listener != null;
                });
            }
        }
    }

    isOpen() {
        return this._isOpen;
    }

    // Open the info window after attaching to a specific marker.
    open() {
        const result = this.activateCallback('beforeOpen');
        if (result !== undefined && !result) {
            return;
        }
        if (this._marker) {
            this.setMap(this._marker.getMap());
        } else if (this._map && this._position) {
            this.setMap(this._map);
        }
    }

    // Close the info window.
    close() {
        const result = this.activateCallback('beforeClose');
        if (result !== undefined && !result) {
            return;
        }
        this.clearListeners();
        this.setMap(null);
    }

    // Force close the map and remove any event listeners attached to google
    destroy() {
        if (this.getMap()) {
            this.setMap(null);
        }
        // Make sure to clear all persistent listeners
        this.clearListeners(true);
    }

    setContent(content) {
        this._opts.content = content;
        if (this._html && this._html.content) {
            setHTML(this._html.content, content);
        }
    }

    setPosition(latLng) {
        this._position = toLatLng(latLng);
        if (this._isOpen && this._position) {
            this.draw();
            this.resize();
            this.reposition();
        }
    }

    getWrapper() {
        if (this._html) {
            return this._html.wrapper;
        }
        return null;
    }

    // Implementation of OverlayView draw method.
    draw() {
        if (!this.getMap() || !this._html) {
            return;
        }
        if (!this._marker && !this._position) {
            return;
        }

        // 1. Assign offset
        const offset = this._opts.offset;
        if (offset) {
            if (offset.left) {
                this._html.wrapper.style.marginLeft = offset.left;
            }
            if (offset.top) {
                this._html.wrapper.style.marginTop = offset.top;
            }
        }
        // 2. Set the background color
        const bg = this._opts.backgroundColor;
        if (bg) {
            this._html.contentWrapper.style.backgroundColor = bg;
            if (this._opts.pointer) {
                this._html.pointerBg.style[`border${capitalizePlacement(this._opts.placement)}Color`] = bg;
            }
        }
        // 3. Padding
        if (this._opts.padding) {
            this._html.contentWrapper.style.padding = this._opts.padding;
            if (this._opts.shadow) {
                this._html.shadowFrame.style.padding = this._opts.padding;
            }
        }
        // 4. Border radius
        if (this._opts.borderRadius) {
            this._html.contentWrapper.style.borderRadius = this._opts.borderRadius;
            if (this._opts.shadow) {
                this._html.shadowFrame.style.borderRadius = this._opts.borderRadius;
            }
        }
        // 5. Font Size
        if (this._opts.fontSize) {
            this._html.wrapper.style.fontSize = this._opts.fontSize;
        }
        // 6. Font Color
        if (this._opts.fontColor) {
            this._html.contentWrapper.style.color = this._opts.fontColor;
        }
        // 7. Pointer
        // Check if the pointer is enabled. Also make sure the value isn't just the boolean true.
        if (this._opts.pointer && this._opts.pointer !== true) {
            if (this._opts.shadow) {
                this._html.shadowPointer.style.width = this._opts.pointer;
                this._html.shadowPointer.style.height = this._opts.pointer;
            }
            if (this._html.pointerBorder) {
                this._html.pointerBorder.style.borderWidth = this._opts.pointer;
            }
            this._html.pointerBg.style.borderWidth = this._opts.pointer;
        }

        // 8. Border
        if (this._opts.border) {
            // Calculate the border width
            let bWidth = 0;
            if (this._opts.border.width !== undefined) {
                bWidth = parseAttribute(this._opts.border.width, '0px');
                this._html.contentWrapper.style.borderWidth = bWidth.value + bWidth.units;
            }
            bWidth = Math.round((this._html.contentWrapper.offsetWidth -
                     this._html.contentWrapper.clientWidth) / 2.0);
            bWidth = parseAttribute(`${bWidth}px`, '0px');

            if (this._opts.pointer) {
                // Calculate the pointer length
                let pLength = Math.min(this._html.pointerBorder.offsetHeight,
                                       this._html.pointerBorder.offsetWidth);
                pLength = parseAttribute(`${pLength}px`, '0px');

                let triangleDiff = Math.round(bWidth.value * (_root2 - 1));
                triangleDiff = Math.min(triangleDiff, pLength.value);

                this._html.pointerBg.style.borderWidth =
                    (pLength.value - triangleDiff) + pLength.units;

                const reverseP = capitalizePlacement(oppositePlacement(this._opts.placement));
                this._html.pointerBg.style[`margin${reverseP}`] =
                    triangleDiff + bWidth.units;
                this._html.pointerBg.style[this._opts.placement] =
                    -bWidth.value + bWidth.units;
            }
            const color = this._opts.border.color;
            if (color) {
                this._html.contentWrapper.style.borderColor = color;
                if (this._html.pointerBorder) {
                    this._html.pointerBorder.style[`border${capitalizePlacement(this._opts.placement)}Color`] = color;
                }
            }
        }
        // 9. Shadow
        if (this._opts.shadow) {
            // Check if any of the shadow settings have actually been set
            const shadow = this._opts.shadow;
            const isSet = (attribute) => {
                const v = shadow[attribute];
                return v !== undefined && v != null;
            };

            if (isSet('h') || isSet('v') || isSet('blur') || isSet('spread') || isSet('color')) {
                const hOffset = parseAttribute(shadow.h, _defaultShadow.h);
                const vOffset = parseAttribute(shadow.v, _defaultShadow.v);
                const blur = parseAttribute(shadow.blur, _defaultShadow.blur);
                const spread = parseAttribute(shadow.spread, _defaultShadow.spread);
                const color = shadow.color || _defaultShadow.color;
                const formatBoxShadow = (h, v) => {
                    return `${h} ${v} ${blur.original} ${spread.original} ${color}`;
                };

                this._html.shadowFrame.style.boxShadow =
                    formatBoxShadow(hOffset.original, vOffset.original);

                // Correctly rotate the shadows before the css transform
                const hRotated = (_inverseRoot2 * (hOffset.value - vOffset.value)) + hOffset.units;
                const vRotated = (_inverseRoot2 * (hOffset.value + vOffset.value)) + vOffset.units;
                this._html.shadowPointerInner.style.boxShadow = formatBoxShadow(hRotated, vRotated);
            }
            if (this._opts.shadow.opacity) {
                this._html.shadowWrapper.style.opacity = this._opts.shadow.opacity;
            }
        }

        const divPixel = this.getProjection()
            .fromLatLngToDivPixel(this._position || this._marker.position);
        if (divPixel) {
            this._html.floatWrapper.style.top = `${Math.floor(divPixel.y)}px`;
            this._html.floatWrapper.style.left = `${Math.floor(divPixel.x)}px`;
        }
        if (!this._isOpen) {
            this._isOpen = true;
            this.resize();
            this.reposition();
            this.activateCallback('afterOpen');
            if (google) {
                google.maps.event.trigger(this.getMap(), `${_eventPrefix}opened`, this);
            }
        }
    }

    // Implementation of OverlayView onAdd method.
    onAdd() {
        if (this._html) {
            return;
        }
        // Used for creating new elements
        const applyCss = (element, args) => {
            if (element && args) {
                for (let i = 0; i < args.length; i++) {
                    const className = args[i];
                    if (className) {
                        if (element.className) {
                            element.className += ' ';
                        }
                        element.className += _classPrefix + className;
                    }
                }
            }
        };
        const newElement = (...args) => {
            const element = document.createElement('div');
            applyCss(element, args);
            return element;
        };

        this._html = {};

        // 1. Create the wrapper
        this._html.wrapper = newElement(
            `wrapper-${this._opts.placement}`
        );
        if (this._opts.wrapperClass) {
            this._html.wrapper.className += ` ${this._opts.wrapperClass}`;
        }
        if (this._opts.border) {
            applyCss(this._html.wrapper, ['has-border']);
        }

        // 2. Create the shadow
        if (this._opts.shadow) {
            this._html.shadowWrapper = newElement(
                `shadow-wrapper-${this._opts.placement}`
            );
            this._html.shadowFrame = newElement(
                'frame',
                'shadow-frame'
            );
            this._html.shadowWrapper.appendChild(this._html.shadowFrame);

            if (this._opts.pointer) {
                this._html.shadowPointer = newElement(
                    `shadow-pointer-${this._opts.placement}`
                );
                this._html.shadowPointerInner = newElement(
                    `shadow-inner-pointer-${this._opts.placement}`
                );
                this._html.shadowPointer.appendChild(this._html.shadowPointerInner);
                this._html.shadowWrapper.appendChild(this._html.shadowPointer);
            }

            this._html.wrapper.appendChild(this._html.shadowWrapper);
        }

        // 3. Create the content
        this._html.contentWrapper = newElement(
            'frame',
            'content-wrapper'
        );
        this._html.content = newElement(
            'content'
        );
        if (this._opts.content) {
            setHTML(this._html.content, this._opts.content);
        }

        // 4. Create the close button
        if (this._opts.showCloseButton) {
            if (this._opts.closeButtonMarkup) {
                const d = document.createElement('div');
                setHTML(d, this._opts.closeButtonMarkup);
                this._html.closeButton = d.firstChild;
            } else {
                this._html.closeButton = document.createElement('button');
                this._html.closeButton.setAttribute('type', 'button');
                this._html.closeButton.innerHTML = '&#215;';
                applyCss(this._html.closeButton, ['close-button']);
            }
            this._html.contentWrapper.appendChild(this._html.closeButton);
        }
        this._html.contentWrapper.appendChild(this._html.content);
        this._html.wrapper.appendChild(this._html.contentWrapper);

        // 5. Create the pointer
        if (this._opts.pointer) {
            if (this._opts.border) {
                this._html.pointerBorder = newElement(
                    `pointer-${this._opts.placement}`,
                    `pointer-border-${this._opts.placement}`
                );
                this._html.wrapper.appendChild(this._html.pointerBorder);
            }
            this._html.pointerBg = newElement(
                `pointer-${this._opts.placement}`,
                `pointer-bg-${this._opts.placement}`
            );
            this._html.wrapper.appendChild(this._html.pointerBg);
        }

        // Create an outer wrapper
        this._html.floatWrapper = newElement(
            'float-wrapper'
        );
        this._html.floatWrapper.appendChild(this._html.wrapper);

        // Add the wrapper to the Google Maps float pane
        this.getPanes().floatPane.appendChild(this._html.floatWrapper);

        // Now add all the event listeners
        const map = this.getMap();
        this.clearListeners();
        if (this._opts.closeOnMapClick) {
            this.trackListener(google.maps.event.addListener(map, 'click', () => {
                this.close();
            }));
        }
        if (this._opts.closeWhenOthersOpen) {
            this.trackListener(google.maps.event.addListener(map, `${_eventPrefix}opened`, (other) => {
                if (this !== other) {
                    this.close();
                }
            }));
        }
        if (google) {
            // Clear out the previous map bounds
            this._previousWidth = null;
            this._previousHeight = null;
            this.trackListener(google.maps.event.addListener(map, 'bounds_changed', () => {
                const d = map.getDiv();
                const ow = d.offsetWidth;
                const oh = d.offsetHeight;
                const pw = this._previousWidth;
                const ph = this._previousHeight;
                if (pw === null || ph === null || pw !== ow || ph !== oh) {
                    this._previousWidth = ow;
                    this._previousHeight = oh;
                    this.resize();
                }
            }));

            // Marker moves
            if (this._marker) {
                this.trackListener(google.maps.event.addListener(this._marker,
                    'position_changed', () => {
                        this.draw();
                    }));
            }

            // Close button
            if (this._opts.showCloseButton && !this._opts.closeButtonMarkup) {
                this.trackListener(google.maps.event.addDomListener(this._html.closeButton,
                    'click', (e) => {
                        e.cancelBubble = true;
                        if (e.stopPropagation) {
                            e.stopPropagation();
                        }
                        this.close();
                    }));
            }

            // Stop the mouse event propagation
            const mouseEvents = ['click', 'dblclick', 'rightclick', 'contextmenu',
                'drag', 'dragend', 'dragstart',
                'mousedown', 'mouseout', 'mouseover', 'mouseup',
                'touchstart', 'touchend', 'touchmove',
                'wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'];
            mouseEvents.forEach((event) => {
                this.trackListener(google.maps.event.addDomListener(this._html.wrapper,
                    event, (e) => {
                        e.cancelBubble = true;
                        if (e.stopPropagation) {
                            e.stopPropagation();
                        }
                    }));
            });
        }


        this.activateCallback('open');
    }

    // Implementation of OverlayView onRemove method
    onRemove() {
        this.activateCallback('close');
        if (this._html) {
            const parent = this._html.floatWrapper.parentElement;
            if (parent) {
                parent.removeChild(this._html.floatWrapper);
            }
            this._html = null;
        }
        this._isOpen = false;
        this.activateCallback('afterClose');
    }

    // The map inner bounds used for panning and resizing
    getMapInnerBounds() {
        const mb = this.getMap().getDiv().getBoundingClientRect();
        const mib = {
            top: mb.top + this._opts.edgeOffset.top,
            right: mb.right - this._opts.edgeOffset.right,
            bottom: mb.bottom - this._opts.edgeOffset.bottom,
            left: mb.left + this._opts.edgeOffset.left
        };
        mib.width = mib.right - mib.left;
        mib.height = mib.bottom - mib.top;
        return mib;
    }

    // Pan the Google Map such that the info window is visible
    reposition() {
        if (!this._opts.panOnOpen || !this._html) {
            return;
        }
        const mib = this.getMapInnerBounds();
        const wb = this._html.wrapper.getBoundingClientRect();
        let dx = 0;
        let dy = 0;
        if (mib.left >= wb.left) {
            dx = wb.left - mib.left;
        } else if (mib.right <= wb.right) {
            dx = wb.left - (mib.right - wb.width);
        }
        if (mib.top >= wb.top) {
            dy = wb.top - mib.top;
        } else if (mib.bottom <= wb.bottom) {
            dy = wb.top - (mib.bottom - wb.height);
        }
        if (dx !== 0 || dy !== 0) {
            this.getMap().panBy(dx, dy);
        }
    }

    // Resize the info window to fit within the map bounds and edge offset
    resize() {
        if (!this._html) {
            return;
        }
        const mib = this.getMapInnerBounds();
        // Handle the max width
        let maxWidth = mib.width;
        if (this._opts.maxWidth !== undefined) {
            maxWidth = Math.min(maxWidth, this._opts.maxWidth);
        }
        maxWidth -= (this._html.wrapper.offsetWidth - this._html.content.offsetWidth);
        this._html.content.style.maxWidth = `${maxWidth}px`;

        // Handle the max height
        let maxHeight = mib.height;
        if (this._opts.maxHeight !== undefined) {
            maxHeight = Math.min(maxHeight, this._opts.maxHeight);
        }
        maxHeight -= (this._html.wrapper.offsetHeight - this._html.content.offsetHeight);
        this._html.content.style.maxHeight = `${maxHeight}px`;
    }
}
</script>
<script>

    // Snazzy Map Style - https://snazzymaps.com/style/8097/wy
    var mapStyle = [{
        'featureType': 'all',
        'elementType': 'geometry.fill',
        'stylers': [{
            'weight': '2.00'
        }]
    }, {
        'featureType': 'all',
        'elementType': 'geometry.stroke',
        'stylers': [{
            'color': '#9c9c9c'
        }]
    }, {
        'featureType': 'all',
        'elementType': 'labels.text',
        'stylers': [{
            'visibility': 'on'
        }]
    }, {
        'featureType': 'landscape',
        'elementType': 'all',
        'stylers': [{
            'color': '#f2f2f2'
        }]
    }, {
        'featureType': 'landscape',
        'elementType': 'geometry.fill',
        'stylers': [{
            'color': '#ffffff'
        }]
    }, {
        'featureType': 'landscape.man_made',
        'elementType': 'geometry.fill',
        'stylers': [{
            'color': '#ffffff'
        }]
    }, {
        'featureType': 'poi',
        'elementType': 'all',
        'stylers': [{
            'visibility': 'off'
        }]
    }, {
        'featureType': 'road',
        'elementType': 'all',
        'stylers': [{
            'saturation': -100
        }, {
            'lightness': 45
        }]
    }, {
        'featureType': 'road',
        'elementType': 'geometry.fill',
        'stylers': [{
            'color': '#eeeeee'
        }]
    }, {
        'featureType': 'road',
        'elementType': 'labels.text.fill',
        'stylers': [{
            'color': '#7b7b7b'
        }]
    }, {
        'featureType': 'road',
        'elementType': 'labels.text.stroke',
        'stylers': [{
            'color': '#ffffff'
        }]
    }, {
        'featureType': 'road.highway',
        'elementType': 'all',
        'stylers': [{
            'visibility': 'simplified'
        }]
    }, {
        'featureType': 'road.arterial',
        'elementType': 'labels.icon',
        'stylers': [{
            'visibility': 'off'
        }]
    }, {
        'featureType': 'transit',
        'elementType': 'all',
        'stylers': [{
            'visibility': 'off'
        }]
    }, {
        'featureType': 'water',
        'elementType': 'all',
        'stylers': [{
            'color': '#46bcec'
        }, {
            'visibility': 'on'
        }]
    }, {
        'featureType': 'water',
        'elementType': 'geometry.fill',
        'stylers': [{
            'color': '#c8d7d4'
        }]
    }, {
        'featureType': 'water',
        'elementType': 'labels.text.fill',
        'stylers': [{
            'color': '#070707'
        }]
    }, {
        "featureType": "poi.park",
        "elementType": "geometry.fill",
        "stylers": [
            {
                "visibility": "on"
            },
            {
                "color": "#e55c3b"
            },
            {
              "gamma" : "3"
            }
        ]
    },
     {
        'featureType': 'water',
        'elementType': 'labels.text.stroke',
        'stylers': [{
            'color': '#ffffff'
        }]
    }];

    // Create the map
    var map = new google.maps.Map($('.map-canvas')[0], {
        zoom: 8,
        styles: mapStyle,
        center: new google.maps.LatLng(41.2033216, -77.1945247),
      scrollwheel:  false
    });

    // Add a custom marker
    var markerIcon = {
        path: 'M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z',
        fillColor: '#e25a00',
        fillOpacity: 0.95,
        scale: 2,
        strokeColor: '#fff',
        strokeWeight: 3,
        anchor: new google.maps.Point(12, 24)
    };
    // Set up handle bars
    var template = Handlebars.compile($('#marker-content-template').html());
    // Set up a close delay for CSS animations
    var info = null;
    var closeDelayed = false;
    var closeDelayHandler = function() {
        $(info.getWrapper()).removeClass('active');
        setTimeout(function() {
            closeDelayed = true;
            info.close();
        }, 300);
    };

    var locations = [
        ['Ohiopyle State Park', 39.868022, -79.4942011],
        ['Cherry Springs State Park', 41.6656062, -77.8280371, 'https://static1.squarespace.com/static/582a26f2e58c628c3cb33891/t/582a5bb659cc68c3cd3b154a/1479171008165/5Patches.jpg',  "Cherry Springs State Park is a 82-acre state park in Potter County. It is popular with astronomers and stargazers for having \"some of the darkest night skies on the east coast\" of the United States, and was chosen by the Pennsylvania Department of Conservation and Natural Resources (DCNR) and its Bureau of Parks as one of \"25 Must-See Pennsylvania State Parks\"", 'linktovalue.com'],
        ['Cook Forest State Park', 41.332574, -79.207968],
        ['Little Buffalo State Park', 40.452341, -77.185578, 'https://static1.squarespace.com/static/582a26f2e58c628c3cb33891/t/582a5b3103596eb5cddaad27/1479170873437/LittleBuffalo.jpg'],
        ['Keystone State Park', 40.371807, -79.388788],
        ['Laurel Mountain State Park', 40.163849, -79.163319],
        ['Kinzua Bridge State Park', 41.758029, -78.587438],
        ['Lehigh GorgeState Park', 40.966677, -75.755088],
        ['Laurel Ridge State Park', 39.946825, -79.363452],
        ['Rickets Glenn State Park', 41.340684, -76.259489],
        ['Big Pocono State Park', 41.041825, -75.34996],
        ['Promised Land State Park', 41.299112, -75.214004],
        ['Worlds End State Park',41.466699, -76.575368, 'https://static1.squarespace.com/static/582a26f2e58c628c3cb33891/t/582a5b4659cc68c3cd3b0f6f/1479170896195/WorldsEnd.jpg'],
        ['Warriors Path State Park',40.340443, -78.167844, 'https://static1.squarespace.com/static/582a26f2e58c628c3cb33891/t/582a5b5f59cc68c3cd3b10e5/1479170923787/WarriorsPath.jpg']
    ];
    var markers;
    for (i = 0; i < locations.length; i++) {
        marker = new google.maps.Marker({
            map: map,
            icon: markerIcon,
            position: new google.maps.LatLng(locations[i][1], locations[i][2])
        });
        // Add a Snazzy Info Window to the marker
        info = new SnazzyInfoWindow({
            marker: marker,
            wrapperClass: 'custom-window',
            offset: {
                top: '-72px'
            },
            edgeOffset: {
                top: 50,
                right: 60,
                bottom: 50
            },
            border: false,
            
            content: template({
                title: locations[i][0],
                subtitle: 'For Snazzy Info Windows',
                bgImg: locations[i][3],
                body: locations[i][4],
                bd: locations[i][4],
                link: locations[i][5]
            }),
            callbacks: {
                open: function() {
                    $(this.getWrapper()).addClass('open');
                },
                afterOpen: function() {
                    var wrapper = $(this.getWrapper());
                    wrapper.addClass('active');
                    wrapper.find('.custom-close').on('click', closeDelayHandler);
                },
                beforeClose: function() {

                },
                afterClose: function() {
                    var wrapper = $(this.getWrapper());
                    wrapper.find('.custom-close').off();
                    wrapper.removeClass('open');
                    closeDelayed = false;
                }
            }
        });






    }







</script>