   'uproxy-lib/loggingprovider'
   'uproxy-lib/churn-pipe'
   'uproxy-lib/cloud/social'
+]
+
+getWithBasePath = (files, base = '') ->
+  for file in files
+    if file[0] == '!'
+      '!' + path.join(base, file[1..])
+    else
+      path.join(base, file)
+
+uiDistFiles = [
+  'generic_ui/*.html'
+  'generic_ui/style/*.css'
+  'generic_ui/polymer/vulcanized*.{html,js}'
+  'generic_ui/fonts/*'
+  'generic_ui/icons/*'
+]
+
+coreDistFiles = [
+  'fonts/*'
+  '*.html' # technically does not exist in Firefox
+
+  'freedomjs-anonymized-metrics/anonmetrics.json'
+  'freedomjs-anonymized-metrics/metric.js'
+  'freedom-social-github/social.github.json'
+  'freedom-social-github/github-social-provider.js'
+  'freedom-social-firebase/social.firebase-facebook.json'
+  'freedom-social-firebase/social.firebase-google.json'
+  'freedom-social-firebase/firebase-shims.js'
+  'freedom-social-firebase/firebase.js'
+  'freedom-social-firebase/firebase-social-provider.js'
+  'freedom-social-firebase/facebook-social-provider.js'
+  'freedom-social-firebase/google-social-provider.js'
+  'freedom-social-firebase/google-auth.js'
+  'freedom-port-control/port-control.js'
+  'freedom-port-control/port-control.json'
+  'freedom-pgp-e2e/end-to-end.compiled.js'
+  'freedom-pgp-e2e/googstorage.js'
+  'freedom-pgp-e2e/e2e.js'
+  'freedom-pgp-e2e/pgpapi.json'
+
+  '**/freedom-module.json'
+  '**/*.static.js'
+]
+
+# this should always be added to the array last
+universalDistFiles = [
+  'icons/*'
+  'bower/webcomponentsjs/webcomponents.min.js'
+  'bower/polymer/polymer.js'
+
+  '!generic_core/freedom-module.json' # not actually needed for the UI builds
+  '!generic_ui/polymer/vulcanized*inline.html'
+  '!generic_ui/polymer/vulcanized.js' # vulcanized.html uses vulcanized.static.js
+  '!**/*spec*'
 ]
 
 gruntConfig = {

          cwd: chromeExtDevPath
          src: [
            'manifest.json'

            'bower/webcomponentsjs/webcomponents.min.js'
            'bower/polymer/polymer.js'

            'generic_ui/*.html'
            'generic_ui/polymer/vulcanized*.{html,js}'
            '!generic_ui/polymer/vulcanized*inline.html'
            '!generic_ui/polymer/vulcanized.js' # vulcanized.html uses vulcanized.static.js

            'generic_ui/scripts/copypaste.js'
            'generic_ui/scripts/get_logs.js'
            'scripts/context.static.js'
            'scripts/background.static.js'
            '!**/*spec*'

            'generic_ui/style/*.css'

            # extra components we use
            'generic_ui/fonts/*'
            'generic_ui/icons/*'
            'icons/*'
            '_locales/**'
          ]
          dest: 'build/dist/chrome/extension'
        }
        { # Chrome app

          src: [
            'manifest.json'
            'config.xml'

            # This is not browserified so we use .js instead of .static.js
            'polymer/vulcanized.{html,js}'

            'generic_ui/scripts/copypaste.js'
            'generic_ui/scripts/get_logs.js'

            # TODO move to universalDistFiles once supported on other platforms
            'freedom-social-quiver/socketio.quiver.json'
            'freedom-social-quiver/socketio.quiver.js'

            'freedom-for-chrome/freedom-for-chrome.js'
          ].concat uiDistFiles
            .concat coreDistFiles
            .concat universalDistFiles
          dest: ccaDistPath
        }
        { # CCA dist freedom-module.json
