diff --git a/app/js/murmurhash3_gc.js b/app/js/murmurhash3_gc.js
new file mode 100644
index 00000000..57e0dfb6
--- /dev/null
+++ b/app/js/murmurhash3_gc.js
@@ -0,0 +1,89 @@
+/**
+ * JS Implementation of MurmurHash3 (r136) (as of May 20, 2011)
+ *
+ * Copyright (c) 2011 Gary Court
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * @author Gary Court
+ * @see http://github.com/garycourt/murmurhash-js
+ * @author Austin Appleby
+ * @see http://sites.google.com/site/murmurhash/
+ *
+ * @param {string} key ASCII only
+ * @param {number} seed Positive integer only
+ * @return {number} 32-bit positive integer hash
+ */
+
+function murmurhash3_32_gc(key, seed) {
+ var remainder, bytes, h1, h1b, c1, c1b, c2, c2b, k1, i;
+
+ remainder = key.length & 3; // key.length % 4
+ bytes = key.length - remainder;
+ h1 = seed;
+ c1 = 0xcc9e2d51;
+ c2 = 0x1b873593;
+ i = 0;
+
+ while (i < bytes) {
+ k1 =
+ ((key.charCodeAt(i) & 0xff)) |
+ ((key.charCodeAt(++i) & 0xff) << 8) |
+ ((key.charCodeAt(++i) & 0xff) << 16) |
+ ((key.charCodeAt(++i) & 0xff) << 24);
+ ++i;
+
+ k1 = ((((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16))) & 0xffffffff;
+ k1 = (k1 << 15) | (k1 >>> 17);
+ k1 = ((((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16))) & 0xffffffff;
+
+ h1 ^= k1;
+ h1 = (h1 << 13) | (h1 >>> 19);
+ h1b = ((((h1 & 0xffff) * 5) + ((((h1 >>> 16) * 5) & 0xffff) << 16))) & 0xffffffff;
+ h1 = (((h1b & 0xffff) + 0x6b64) + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16));
+ }
+
+ k1 = 0;
+
+ switch (remainder) {
+ case 3: k1 ^= (key.charCodeAt(i + 2) & 0xff) << 16;
+ case 2: k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8;
+ case 1: k1 ^= (key.charCodeAt(i) & 0xff);
+
+ k1 = (((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;
+ k1 = (k1 << 15) | (k1 >>> 17);
+ k1 = (((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;
+ h1 ^= k1;
+ }
+
+ h1 ^= key.length;
+
+ h1 ^= h1 >>> 16;
+ h1 = (((h1 & 0xffff) * 0x85ebca6b) + ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) & 0xffffffff;
+ h1 ^= h1 >>> 13;
+ h1 = ((((h1 & 0xffff) * 0xc2b2ae35) + ((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16))) & 0xffffffff;
+ h1 ^= h1 >>> 16;
+
+ return h1 >>> 0;
+}
+
+
diff --git a/app/modules/components/project-logo-src/project-logo-src.directive.coffee b/app/modules/components/project-logo-src/project-logo-src.directive.coffee
new file mode 100644
index 00000000..2b7b8804
--- /dev/null
+++ b/app/modules/components/project-logo-src/project-logo-src.directive.coffee
@@ -0,0 +1,77 @@
+###
+# Copyright (C) 2014-2016 Taiga Agile LLC
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+# File: project-logo.directive.coffee
+###
+
+
+IMAGES = [
+ "/#{window._version}/images/project-logos/project-logo-01.png"
+ "/#{window._version}/images/project-logos/project-logo-02.png"
+ "/#{window._version}/images/project-logos/project-logo-03.png"
+ "/#{window._version}/images/project-logos/project-logo-04.png"
+ "/#{window._version}/images/project-logos/project-logo-05.png"
+]
+
+COLORS = [
+ "rgba( 153, 214, 220, 1 )"
+ "rgba( 213, 156, 156, 1 )"
+ "rgba( 214, 161, 212, 1 )"
+ "rgba( 164, 162, 219, 1 )"
+ "rgba( 152, 224, 168, 1 )"
+]
+
+LOGOS = _.cartesianProduct(IMAGES, COLORS)
+
+
+ProjectLogoSrcDirective = ($parse) ->
+ _getDefaultProjectLogo = (project) ->
+ key = "#{project.get("slug")}-#{project.get("id")}"
+ idx = murmurhash3_32_gc(key, 42) %% LOGOS.length
+ logo = LOGOS[idx]
+
+ return { src: logo[0], color: logo[1] }
+
+ link = (scope, el, attrs) ->
+ scope.$watch "project", (project) ->
+ project = Immutable.fromJS(project) # Necesary for old code
+
+ return if not project
+
+ projectLogo = project.get('logo_small_url')
+
+ if projectLogo
+ el.attr("src", projectLogo)
+ el.css('background', "")
+ else
+ logo = _getDefaultProjectLogo(project)
+ el.attr("src", logo.src)
+ el.css('background', logo.color)
+
+ scope.$on "$destroy", -> el.off()
+
+ return {
+ link: link
+ scope: {
+ project: "=tgProjectLogoSrc"
+ }
+ }
+
+ProjectLogoSrcDirective.$inject = [
+ "$parse"
+]
+
+angular.module("taigaComponents").directive("tgProjectLogoSrc", ProjectLogoSrcDirective)
diff --git a/gulpfile.js b/gulpfile.js
index 61db5d31..bb3d9a71 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -173,7 +173,8 @@ paths.libs = [
paths.app + "js/jquery-ui.drag-multiple-custom.js",
paths.app + "js/jquery.ui.touch-punch.min.js",
paths.app + "js/tg-repeat.js",
- paths.app + "js/sha1-custom.js"
+ paths.app + "js/sha1-custom.js",
+ paths.app + "js/murmurhash3_gc.js"
];
var isDeploy = argv["_"].indexOf("deploy") !== -1;