<script type='text/javascript'>
  /* global google */
/* global MarkerClusterer */
// eslint-disable-next-line no-unused-vars
var jekyllMaps = (function() {
  'use strict'
  var clusterSettings = {}
  var clusterReady = false
  var mapReady = false
  var options = {}
  var data = []
  var maps = []

  return {
    initializeMap: initializeMap,
    initializeCluster: initializeCluster,
    register: register
  }

  /**
   * Setup Google Maps options and call renderer.
   */
  function initializeMap() {
    options = {
      mapTypeId: google.maps.MapTypeId.ROADMAP,
      center: new google.maps.LatLng(0, 0),
      styles: []
    }
    mapReady = true
    render()
  }

  /**
   * Register map data to be rendered once Google Maps API is loaded.
   *
   * @param string id
   * @param Array locations
   * @param Object settings
   */
  function register(id, locations, options) {
    data.push({ id: id, locations: locations, options: options })
    render()
  }

  /**
   * Render maps data if Google Maps API is loaded.
   */
  function render() {
    if (!mapReady) return

    while (data.length > 0) {
      var item = data.pop()
      var bounds = new google.maps.LatLngBounds()
      var mapOptions = Object.assign({}, options, item.options)
      var map = new google.maps.Map(
        document.getElementById(item.id),
        mapOptions
      )
      var infoWindow = new google.maps.InfoWindow()
      var markers = item.locations.map(createMarker)

      map.fitBounds(bounds)
      google.maps.event.addListenerOnce(map, 'idle', function() {
        if (this.customZoom) this.setZoom(this.customZoom)
      })
      if (mapOptions.useCluster) {
        maps.push({ map: map, markers: markers })
        processCluster()
      }
    }

    function createMarker(location) {
      var position = new google.maps.LatLng(
        location.latitude,
        location.longitude
      )
      bounds.extend(position)
      if (!mapOptions.showMarker) return false

      var marker = new google.maps.Marker({
        position: position,
        title: location.title,
        image: location.image,
        popup_html: location.popup_html,
        icon: location.icon || mapOptions.markerIcon,
        url: markerUrl(mapOptions.baseUrl, location.url),
        url_text: location.url_text,
        map: map
      })
      if (mapOptions.showMarkerPopup) marker.addListener('click', markerPopup)

      return marker
    }

    function markerUrl(baseUrl, url) {
      if (/^(https?|\/\/)/.test(url)) return url

      return url.length > 0 ? baseUrl + url : ''
    }

    function markerPopup() {
      var content = '<div class="map-info-window"><h5>' + this.title + '</h5>'
      if (this.popup_html.length > 0) {
        content += this.popup_html
      }
      else {
        var imageTag =
          this.image.length > 0 &&
          '<img src="' + this.image + '" alt="' + this.title + '"/>'
        if (this.url.length > 0) {
          var linkContent = imageTag || this.url_text || 'View'
          content += '<a href="' + this.url + '">' + linkContent + '</a>'
        } else if (imageTag) {
          content += imageTag
        }
      }
      content += '</div>'
      infoWindow.setContent(content)
      infoWindow.open(map, this)
    }
  }

  function initializeCluster(settings) {
    clusterReady = true
    clusterSettings = settings || {}
    processCluster()
  }

  function processCluster() {
    if (!clusterReady) return

    while (maps.length > 0) {
      var obj = maps.pop()
      // eslint-disable-next-line no-new
      new MarkerClusterer(obj.map, obj.markers, {
        gridSize: clusterSettings.grid_size || 25,
        imagePath:
          'https://cdn.rawgit.com/googlemaps/js-marker-clusterer/gh-pages/images/m'
      })
    }
  }
})()
/* Object.assign polyfill */
if (typeof Object.assign !== 'function') {
  Object.assign = function(target) {
    'use strict'
    if (target == null) {
      throw new TypeError('Cannot convert undefined or null to object')
    }

    target = Object(target)
    for (var index = 1; index < arguments.length; index++) {
      var source = arguments[index]
      if (source != null) {
        for (var key in source) {
          if (Object.prototype.hasOwnProperty.call(source, key)) {
            target[key] = source[key]
          }
        }
      }
    }
    return target
  }
}

</script>
<script type='text/javascript'>
  /* global google */
/* global MarkerClusterer */
// eslint-disable-next-line no-unused-vars
var jekyllMaps = (function() {
  'use strict'
  var clusterSettings = {}
  var clusterReady = false
  var mapReady = false
  var options = {}
  var data = []
  var maps = []

  return {
    initializeMap: initializeMap,
    initializeCluster: initializeCluster,
    register: register
  }

  /**
   * Setup Google Maps options and call renderer.
   */
  function initializeMap() {
    options = {
      mapTypeId: google.maps.MapTypeId.ROADMAP,
      center: new google.maps.LatLng(0, 0),
      styles: []
    }
    mapReady = true
    render()
  }

  /**
   * Register map data to be rendered once Google Maps API is loaded.
   *
   * @param string id
   * @param Array locations
   * @param Object settings
   */
  function register(id, locations, options) {
    data.push({ id: id, locations: locations, options: options })
    render()
  }

  /**
   * Render maps data if Google Maps API is loaded.
   */
  function render() {
    if (!mapReady) return

    while (data.length > 0) {
      var item = data.pop()
      var bounds = new google.maps.LatLngBounds()
      var mapOptions = Object.assign({}, options, item.options)
      var map = new google.maps.Map(
        document.getElementById(item.id),
        mapOptions
      )
      var infoWindow = new google.maps.InfoWindow()
      var markers = item.locations.map(createMarker)

      map.fitBounds(bounds)
      google.maps.event.addListenerOnce(map, 'idle', function() {
        if (this.customZoom) this.setZoom(this.customZoom)
      })
      if (mapOptions.useCluster) {
        maps.push({ map: map, markers: markers })
        processCluster()
      }
    }

    function createMarker(location) {
      var position = new google.maps.LatLng(
        location.latitude,
        location.longitude
      )
      bounds.extend(position)
      if (!mapOptions.showMarker) return false

      var marker = new google.maps.Marker({
        position: position,
        title: location.title,
        image: location.image,
        popup_html: location.popup_html,
        icon: location.icon || mapOptions.markerIcon,
        url: markerUrl(mapOptions.baseUrl, location.url),
        url_text: location.url_text,
        map: map
      })
      if (mapOptions.showMarkerPopup) marker.addListener('click', markerPopup)

      return marker
    }

    function markerUrl(baseUrl, url) {
      if (/^(https?|\/\/)/.test(url)) return url

      return url.length > 0 ? baseUrl + url : ''
    }

    function markerPopup() {
      var content = '<div class="map-info-window"><h5>' + this.title + '</h5>'
      if (this.popup_html.length > 0) {
        content += this.popup_html
      }
      else {
        var imageTag =
          this.image.length > 0 &&
          '<img src="' + this.image + '" alt="' + this.title + '"/>'
        if (this.url.length > 0) {
          var linkContent = imageTag || this.url_text || 'View'
          content += '<a href="' + this.url + '">' + linkContent + '</a>'
        } else if (imageTag) {
          content += imageTag
        }
      }
      content += '</div>'
      infoWindow.setContent(content)
      infoWindow.open(map, this)
    }
  }

  function initializeCluster(settings) {
    clusterReady = true
    clusterSettings = settings || {}
    processCluster()
  }

  function processCluster() {
    if (!clusterReady) return

    while (maps.length > 0) {
      var obj = maps.pop()
      // eslint-disable-next-line no-new
      new MarkerClusterer(obj.map, obj.markers, {
        gridSize: clusterSettings.grid_size || 25,
        imagePath:
          'https://cdn.rawgit.com/googlemaps/js-marker-clusterer/gh-pages/images/m'
      })
    }
  }
})()
/* Object.assign polyfill */
if (typeof Object.assign !== 'function') {
  Object.assign = function(target) {
    'use strict'
    if (target == null) {
      throw new TypeError('Cannot convert undefined or null to object')
    }

    target = Object(target)
    for (var index = 1; index < arguments.length; index++) {
      var source = arguments[index]
      if (source != null) {
        for (var key in source) {
          if (Object.prototype.hasOwnProperty.call(source, key)) {
            target[key] = source[key]
          }
        }
      }
    }
    return target
  }
}

</script>
<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.3.4">Jekyll</generator><link href="https://fabricationfest.org/feed.xml" rel="self" type="application/atom+xml" /><link href="https://fabricationfest.org/" rel="alternate" type="text/html" /><updated>2025-08-03T01:40:12+00:00</updated><id>https://fabricationfest.org/feed.xml</id><title type="html">Fabrication Fest</title><subtitle>A celebration of design and fabrication.</subtitle><author><name>{&quot;name&quot;=&gt;&quot;&quot;, &quot;email&quot;=&gt;&quot;&quot;}</name><email></email></author><entry><title type="html">Announcing the 2023 Fabrication Fest in Providence, RI</title><link href="https://fabricationfest.org/announcements/2023/07/27/announcing-2023-fabrication-fest.html" rel="alternate" type="text/html" title="Announcing the 2023 Fabrication Fest in Providence, RI" /><published>2023-07-27T16:00:00+00:00</published><updated>2023-07-27T16:00:00+00:00</updated><id>https://fabricationfest.org/announcements/2023/07/27/announcing-2023-fabrication-fest</id><content type="html" xml:base="https://fabricationfest.org/announcements/2023/07/27/announcing-2023-fabrication-fest.html"><![CDATA[<p><img src="/assets/posts/diorama_18.jpg" alt="Family fun" /></p>

<p><a href="https://www.ricomputermuseum.org/">Rhode Island Computer Museum</a>, in cooperation with <a href="https://www.designxri.com/events-calendar/design-week-ri/">DESIGN WEEK RI</a> and the <a href="https://www.195districtpark.com/">195 District Park</a>, is excited to announce a celebration of design and fabrication on November 4, 2023. The focus of the event is on those places where design and fabrication meet. Everything from traditional methods of making things to digital fabrication with machines will be showcased at this show-and-tell event.</p>

<p>Fabrication Fest takes place outdoors at the 195 District Park, and will be free and open to the public. Our call for exhibitors is open until October 21: if you have a project, product, or experience that would be of interest to the design community, please <a href="/call">submit a proposal</a>.  There is no cost to exhibit.</p>

<p><a href="/call" class="button_centered">Sign Up to Exhibit</a></p>

<div id="57b7acde-a0f9-41e7-a5d6-0f025742aa24" style="width:100%;height:400px;" class=" jekyll-map"></div>
<script type="text/javascript">
  jekyllMaps.register(
    '57b7acde-a0f9-41e7-a5d6-0f025742aa24',
    [{"latitude":41.82050627001376,"longitude":-71.40743034722179,"title":"Announcing the 2023 Fabrication Fest in Providence, RI","icon":null,"url":"/announcements/2023/07/27/announcing-2023-fabrication-fest.html","url_text":null,"image":"/assets/posts/diorama_18.jpg","popup_html":""}],
    {"baseUrl":"","useCluster":true,"showMarker":true,"showMarkerPopup":true,"markerIcon":null,"styles":"[]","customZoom":17}
  );
</script>]]></content><author><name>{&quot;name&quot;=&gt;&quot;&quot;, &quot;email&quot;=&gt;&quot;&quot;}</name></author><category term="announcements" /><category term="announcement" /><summary type="html"><![CDATA[Please join us for a celebration of design and fabrication. November 4, 2023]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://fabricationfest.org/assets/posts/diorama_18.jpg" /><media:content medium="image" url="https://fabricationfest.org/assets/posts/diorama_18.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>