From 95c2cd91b28bedd3a2ef15afd5c8523f21a23162 Mon Sep 17 00:00:00 2001 From: daniel Date: Sat, 22 Dec 2018 11:17:52 +0100 Subject: [PATCH] Bumped version. --- README.md | 2 +- dist/jdenticon.js | 6 +++--- dist/jdenticon.min.js | 4 ++-- dist/jdenticon.min.js.map | 2 +- package.json | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 51f985c..0d0fa9d 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ use it right off [jsDelivr](https://www.jsdelivr.com). ```HTML - + diff --git a/dist/jdenticon.js b/dist/jdenticon.js index 24d3a2a..67668c6 100644 --- a/dist/jdenticon.js +++ b/dist/jdenticon.js @@ -1,8 +1,8 @@ /** - * Jdenticon 2.1.0 + * Jdenticon 2.1.1 * http://jdenticon.com * - * Built: 2018-04-15T17:32:59.846Z + * Built: 2018-12-22T10:15:41.611Z * * Copyright (c) 2014-2018 Daniel Mester Pirttijärvi * @@ -1323,7 +1323,7 @@ function jdenticonStartup() { jdenticon["drawIcon"] = drawIcon; jdenticon["toSvg"] = toSvg; jdenticon["update"] = update; -jdenticon["version"] = "2.1.0"; +jdenticon["version"] = "2.1.1"; // Basic jQuery plugin if (jQuery) { diff --git a/dist/jdenticon.min.js b/dist/jdenticon.min.js index f719182..20c0545 100644 --- a/dist/jdenticon.min.js +++ b/dist/jdenticon.min.js @@ -1,4 +1,4 @@ -// Jdenticon 2.1.0 | jdenticon.com | MIT licensed | (c) 2014-2018 Daniel Mester Pirttijärvi +// Jdenticon 2.1.1 | jdenticon.com | MIT licensed | (c) 2014-2018 Daniel Mester Pirttijärvi (function(q,y,z){var t=z(q,q.jQuery);"undefined"!==typeof module&&"exports"in module?module.exports=t:"function"===typeof define&&define.amd?define([],function(){return t}):q[y]=t})(this,"jdenticon",function(q,y){function z(a,b,c){for(var d=document.createElementNS("http://www.w3.org/2000/svg",b),f=2;f+1>>e&15).toString(16));return b.join("")}(function(a){for(var b= 1732584193,d=4023233417,f=2562383102,e=271733878,h=3285377520,k=[b,d,f,e,h],g=0;gl;l++){var A=u[l-3]^u[l-8]^u[l-14]^u[l-16];u[l]=A<<1|A>>>31}for(l=0;80>l;l++)A=(b<<5|b>>>27)+(20>l?(d&f^~d&e)+1518500249:40>l?(d^f^e)+1859775393:60>l?(d&f^d&e^f&e)+2400959708:(d^f^e)+3395469782)+h+u[l],h=e,e=f,f=d<<30|d>>>2,d=b,b=A|0;k[0]=b=k[0]+b|0;k[1]=d=k[1]+d|0;k[2]=f=k[2]+f|0;k[3]=e=k[3]+e|0;k[4]=h=k[4]+h|0}return k}(function(a){function b(a,b){for(var c=[],d=-1,e=0;e';\r\n}\r\nSvgWriter.prototype = {\r\n /**\r\n * Fills the background with the specified color.\r\n * @param {string} fillColor Fill color on the format #rrggbb.\r\n * @param {number} opacity Opacity in the range [0.0, 1.0].\r\n */\r\n setBackground: function (fillColor, opacity) {\r\n if (opacity) {\r\n this._s += '';\r\n }\r\n },\r\n /**\r\n * Writes a path to the SVG string.\r\n * @param {string} color Fill color on format #rrggbb.\r\n * @param {string} dataString The SVG path data string.\r\n */\r\n append: function (color, dataString) {\r\n this._s += \r\n '';\r\n },\r\n /**\r\n * Gets the rendered image as an SVG string.\r\n */\r\n toString: function () {\r\n return this._s + \"\";\r\n }\r\n};\r\n\r\n\r\n\r\nvar dom = {\r\n /** @const */\r\n ICON_TYPE_SVG: 1,\r\n\r\n /** @const */\r\n ICON_TYPE_CANVAS: 2,\r\n \r\n /** @const */\r\n HASH_ATTRIBUTE: \"data-jdenticon-hash\",\r\n \r\n /** @const */\r\n VALUE_ATTRIBUTE: \"data-jdenticon-value\",\r\n\r\n supportsQuerySelectorAll: typeof document !== \"undefined\" && \"querySelectorAll\" in document,\r\n\r\n getIdenticonType: dom_getIdenticonType\r\n};\r\n\r\n/** @const */\r\ndom.ICON_SELECTOR = \"[\" + dom.HASH_ATTRIBUTE +\"],[\" + dom.VALUE_ATTRIBUTE +\"]\";\r\n\r\nfunction dom_getIdenticonType(el) {\r\n if (el) {\r\n var tagName = el[\"tagName\"];\r\n\r\n if (/svg/i.test(tagName)) {\r\n return dom.ICON_TYPE_SVG;\r\n }\r\n\r\n if (/canvas/i.test(tagName) && \"getContext\" in el) {\r\n return dom.ICON_TYPE_CANVAS;\r\n }\r\n }\r\n}\r\n\r\n\r\n\r\n\r\n/**\r\n * Computes a SHA1 hash for any value and returns it as a hexadecimal string.\r\n * @param {string} message \r\n */\r\nfunction sha1(message) {\r\n /**\r\n * Converts an array of 32-bit unsigned numbers to a hexadecimal string in big endian format.\r\n * @param {Array} words\r\n */\r\n function wordsToHexString(words) {\r\n var hashOctets = [];\r\n for (var i = 0; i < words.length; i++) {\r\n var val = words[i];\r\n \r\n for (var shift = 28; shift >= 0; shift -= 4) {\r\n var octet = (val >>> shift) & 0xf;\r\n hashOctets.push(octet.toString(16));\r\n }\r\n }\r\n\r\n return hashOctets.join(\"\");\r\n }\r\n \r\n /**\r\n * Converts the specified message to a sequence of UTF8 encoded and padded 64 byte blocks.\r\n * @param {string} message Any value that will be padded to 64 byte blocks.\r\n */\r\n function getBlocks(message) {\r\n var percentEncoded = encodeURI(message),\r\n binaryMessage = [],\r\n binaryMessageLength = 0,\r\n i, b,\r\n\r\n blocks = [],\r\n\r\n BLOCK_SIZE_BYTES = 64,\r\n BLOCK_SIZE_WORDS = BLOCK_SIZE_BYTES >>> 2,\r\n MESSAGE_LENGTH_SIZE_BYTES = 8;\r\n\r\n // UTF8 encode message\r\n for (i = 0; i < percentEncoded.length; i++) {\r\n if (percentEncoded[i] == \"%\") {\r\n b = parseHex(percentEncoded, i + 1, 2);\r\n i += 2;\r\n }\r\n else {\r\n b = percentEncoded.charCodeAt(i);\r\n }\r\n binaryMessage[binaryMessageLength++] = b;\r\n }\r\n\r\n // Trailing '1' bit\r\n binaryMessage[binaryMessageLength++] = 0x80;\r\n \r\n function getWordBlock(startIndex, byteCount) {\r\n var words = [];\r\n var wordIndex = -1;\r\n \r\n for (var i = 0; i < byteCount; i++) {\r\n wordIndex = (i / 4) | 0;\r\n words[wordIndex] = (words[wordIndex] || 0) +\r\n (binaryMessage[startIndex + i] << ((3 - (i & 3)) * 8));\r\n }\r\n \r\n while (++wordIndex < BLOCK_SIZE_WORDS) {\r\n words[wordIndex] = 0;\r\n }\r\n\r\n return words;\r\n }\r\n\r\n // Full blocks\r\n for (i = 0; i + BLOCK_SIZE_BYTES <= binaryMessageLength; i+= BLOCK_SIZE_BYTES) {\r\n blocks.push(getWordBlock(i, BLOCK_SIZE_BYTES));\r\n }\r\n\r\n // Final block(s)\r\n // Rest of message\r\n var lastBlockDataLength = binaryMessageLength - i;\r\n \r\n var block = getWordBlock(i, lastBlockDataLength);\r\n \r\n // If there is no room for the message size in this block, \r\n // return the block and put the size in the following block.\r\n if (lastBlockDataLength + MESSAGE_LENGTH_SIZE_BYTES > BLOCK_SIZE_BYTES) {\r\n // Message size goes in next block\r\n blocks.push(block);\r\n block = getWordBlock(0, 0);\r\n }\r\n\r\n var messageSizeBits = binaryMessageLength * 8 - 8;\r\n block[BLOCK_SIZE_WORDS - 1] = messageSizeBits;\r\n blocks.push(block);\r\n\r\n return blocks;\r\n }\r\n\r\n /**\r\n * Rotates the value a specified number of bits to the left.\r\n * @param {number} value Value to rotate\r\n * @param {number} shift Bit count to shift.\r\n */\r\n function rotl(value, shift) {\r\n return (value << shift) | (value >>> (32 - shift));\r\n }\r\n \r\n /**\r\n * Computes a SHA1 hash for the specified array of 64 byte blocks.\r\n * @param {Array>} blocks \r\n */\r\n function computeHash(blocks) {\r\n var a = 0x67452301,\r\n b = 0xefcdab89,\r\n c = 0x98badcfe,\r\n d = 0x10325476,\r\n e = 0xc3d2e1f0,\r\n hash = [a, b, c, d, e];\r\n\r\n for (var i = 0; i < blocks.length; i++) {\r\n var w = blocks[i];\r\n\r\n for (var t = 16; t < 80; t++) {\r\n w[t] = rotl(w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16], 1);\r\n }\r\n\r\n for (var t = 0; t < 80; t++) {\r\n var f =\r\n // Ch\r\n t < 20 ? ((b & c) ^ ((~b) & d)) + 0x5a827999 :\r\n \r\n // Parity\r\n t < 40 ? (b ^ c ^ d) + 0x6ed9eba1 :\r\n \r\n // Maj\r\n t < 60 ? ((b & c) ^ (b & d) ^ (c & d)) + 0x8f1bbcdc :\r\n \r\n // Parity\r\n (b ^ c ^ d) + 0xca62c1d6;\r\n\r\n var T = rotl(a, 5) + f + e + w[t];\r\n\r\n e = d;\r\n d = c;\r\n c = rotl(b, 30);\r\n b = a;\r\n a = T | 0;\r\n }\r\n\r\n hash[0] = a = ((hash[0] + a) | 0);\r\n hash[1] = b = ((hash[1] + b) | 0);\r\n hash[2] = c = ((hash[2] + c) | 0);\r\n hash[3] = d = ((hash[3] + d) | 0);\r\n hash[4] = e = ((hash[4] + e) | 0);\r\n }\r\n\r\n return hash;\r\n }\r\n\r\n return wordsToHexString(computeHash(getBlocks(message)));\r\n}\r\n\r\n\r\n\r\n\r\n/**\r\n * Renderer redirecting drawing commands to a canvas context.\r\n * @param {number=} size\r\n * @private\r\n * @constructor\r\n */\r\nfunction CanvasRenderer(ctx, size) {\r\n var width = ctx.canvas.width,\r\n height = ctx.canvas.height;\r\n \r\n ctx.save();\r\n \r\n this._ctx = ctx;\r\n \r\n if (size) {\r\n this.size = size;\r\n }\r\n else {\r\n this.size = Math.min(width, height);\r\n \r\n ctx.translate(\r\n ((width - this.size) / 2) | 0,\r\n ((height - this.size) / 2) | 0);\r\n }\r\n \r\n ctx.clearRect(0, 0, this.size, this.size);\r\n}\r\nCanvasRenderer.prototype = {\r\n /**\r\n * Fills the background with the specified color.\r\n * @param {string} fillColor Fill color on the format #rrggbb[aa].\r\n */\r\n setBackground: function (fillColor) {\r\n var ctx = this._ctx,\r\n size = this.size;\r\n \r\n ctx.fillStyle = color.toCss3(fillColor);\r\n ctx.fillRect(0, 0, size, size);\r\n },\r\n /**\r\n * Marks the beginning of a new shape of the specified color. Should be ended with a call to endShape.\r\n * @param {string} fillColor Fill color on format #rrggbb[aa].\r\n */\r\n beginShape: function (fillColor) {\r\n this._ctx.fillStyle = color.toCss3(fillColor);\r\n this._ctx.beginPath();\r\n },\r\n /**\r\n * Marks the end of the currently drawn shape. This causes the queued paths to be rendered on the canvas.\r\n */\r\n endShape: function () {\r\n this._ctx.fill();\r\n },\r\n /**\r\n * Adds a polygon to the rendering queue.\r\n * @param points An array of Point objects.\r\n */\r\n addPolygon: function (points) {\r\n var ctx = this._ctx, i;\r\n ctx.moveTo(points[0].x, points[0].y);\r\n for (i = 1; i < points.length; i++) {\r\n ctx.lineTo(points[i].x, points[i].y);\r\n }\r\n ctx.closePath();\r\n },\r\n /**\r\n * Adds a circle to the rendering queue.\r\n * @param {Point} point The upper left corner of the circle bounding box.\r\n * @param {number} diameter The diameter of the circle.\r\n * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path).\r\n */\r\n addCircle: function (point, diameter, counterClockwise) {\r\n var ctx = this._ctx,\r\n radius = diameter / 2;\r\n ctx.moveTo(point.x + radius, point.y + radius);\r\n ctx.arc(point.x + radius, point.y + radius, radius, 0, Math.PI * 2, counterClockwise);\r\n ctx.closePath();\r\n },\r\n /**\r\n * Called when the icon has been completely drawn.\r\n */\r\n finish: function () {\r\n this._ctx.restore();\r\n }\r\n};\r\n\r\n\r\n\r\n\r\nfunction decToHex(v) {\r\n v |= 0; // Ensure integer value\r\n return v < 0 ? \"00\" :\r\n v < 16 ? \"0\" + v.toString(16) :\r\n v < 256 ? v.toString(16) :\r\n \"ff\";\r\n}\r\n\r\nfunction hueToRgb(m1, m2, h) {\r\n h = h < 0 ? h + 6 : h > 6 ? h - 6 : h;\r\n return decToHex(255 * (\r\n h < 1 ? m1 + (m2 - m1) * h :\r\n h < 3 ? m2 :\r\n h < 4 ? m1 + (m2 - m1) * (4 - h) :\r\n m1));\r\n}\r\n \r\n/**\r\n * Functions for converting colors to hex-rgb representations.\r\n * @private\r\n */\r\nvar color = {\r\n /**\r\n * @param {number} r Red channel [0, 255]\r\n * @param {number} g Green channel [0, 255]\r\n * @param {number} b Blue channel [0, 255]\r\n */\r\n rgb: function (r, g, b) {\r\n return \"#\" + decToHex(r) + decToHex(g) + decToHex(b);\r\n },\r\n /**\r\n * @param {string} color Color value to parse. Curently hexadecimal strings on the format #rgb[a] and #rrggbb[aa] are supported.\r\n */\r\n parse: function (color) {\r\n if (/^#[0-9a-f]{3,8}$/i.test(color)) {\r\n if (color.length < 6) {\r\n var r = color[1],\r\n g = color[2],\r\n b = color[3],\r\n a = color[4] || \"\";\r\n return \"#\" + r + r + g + g + b + b + a + a;\r\n }\r\n if (color.length == 7 || color.length > 8) {\r\n return color;\r\n }\r\n }\r\n },\r\n /**\r\n * @param {string} hexColor Color on the format \"#RRGGBB\" or \"#RRGGBBAA\"\r\n */\r\n toCss3: function (hexColor) {\r\n var a = parseHex(hexColor, 7, 2);\r\n if (isNaN(a)) {\r\n return hexColor;\r\n }\r\n var r = parseHex(hexColor, 1, 2),\r\n g = parseHex(hexColor, 3, 2),\r\n b = parseHex(hexColor, 5, 2);\r\n return \"rgba(\" + r + \",\" + g + \",\" + b + \",\" + (a / 255).toFixed(2) + \")\";\r\n },\r\n /**\r\n * @param h Hue [0, 1]\r\n * @param s Saturation [0, 1]\r\n * @param l Lightness [0, 1]\r\n */\r\n hsl: function (h, s, l) {\r\n // Based on http://www.w3.org/TR/2011/REC-css3-color-20110607/#hsl-color\r\n if (s == 0) {\r\n var partialHex = decToHex(l * 255);\r\n return \"#\" + partialHex + partialHex + partialHex;\r\n }\r\n else {\r\n var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s,\r\n m1 = l * 2 - m2;\r\n return \"#\" +\r\n hueToRgb(m1, m2, h * 6 + 2) +\r\n hueToRgb(m1, m2, h * 6) +\r\n hueToRgb(m1, m2, h * 6 - 2);\r\n }\r\n },\r\n // This function will correct the lightness for the \"dark\" hues\r\n correctedHsl: function (h, s, l) {\r\n // The corrector specifies the perceived middle lightnesses for each hue\r\n var correctors = [ 0.55, 0.5, 0.5, 0.46, 0.6, 0.55, 0.55 ],\r\n corrector = correctors[(h * 6 + 0.5) | 0];\r\n \r\n // Adjust the input lightness relative to the corrector\r\n l = l < 0.5 ? l * corrector * 2 : corrector + (l - 0.5) * (1 - corrector) * 2;\r\n \r\n return color.hsl(h, s, l);\r\n }\r\n};\r\n\r\n\r\n\r\n\r\nfunction observer(updateCallback) {\r\n if (typeof MutationObserver != \"undefined\") {\r\n var mutationObserver = new MutationObserver(function onmutation(mutations) {\r\n for (var mutationIndex = 0; mutationIndex < mutations.length; mutationIndex++) {\r\n var mutation = mutations[mutationIndex];\r\n var addedNodes = mutation.addedNodes;\r\n \r\n for (var addedNodeIndex = 0; addedNodes && addedNodeIndex < addedNodes.length; addedNodeIndex++) {\r\n var addedNode = addedNodes[addedNodeIndex];\r\n \r\n // Skip other types of nodes than element nodes, since they might not support\r\n // the querySelectorAll method => runtime error.\r\n if (addedNode.nodeType == Node.ELEMENT_NODE) {\r\n if (dom.getIdenticonType(addedNode)) {\r\n updateCallback(addedNode);\r\n }\r\n else {\r\n var icons = addedNode.querySelectorAll(dom.ICON_SELECTOR);\r\n for (var iconIndex = 0; iconIndex < icons.length; iconIndex++) {\r\n updateCallback(icons[iconIndex]);\r\n }\r\n }\r\n }\r\n }\r\n \r\n if (mutation.type == \"attributes\" && dom.getIdenticonType(mutation.target)) {\r\n updateCallback(mutation.target);\r\n }\r\n }\r\n });\r\n\r\n mutationObserver.observe(document.body, { \r\n \"childList\": true, \r\n \"attributes\": true, \r\n \"attributeFilter\": [dom.VALUE_ATTRIBUTE, dom.HASH_ATTRIBUTE, \"width\", \"height\"], \r\n \"subtree\": true \r\n });\r\n }\r\n}\r\n\r\n\r\n\r\nvar shapes = {\r\n center: [\r\n /** @param {Graphics} g */\r\n function (g, cell, index) {\r\n var k = cell * 0.42;\r\n g.addPolygon([\r\n 0, 0,\r\n cell, 0,\r\n cell, cell - k * 2,\r\n cell - k, cell,\r\n 0, cell\r\n ]);\r\n },\r\n /** @param {Graphics} g */\r\n function (g, cell, index) {\r\n var w = 0 | (cell * 0.5), \r\n h = 0 | (cell * 0.8);\r\n g.addTriangle(cell - w, 0, w, h, 2);\r\n },\r\n /** @param {Graphics} g */\r\n function (g, cell, index) { \r\n var s = 0 | (cell / 3);\r\n g.addRectangle(s, s, cell - s, cell - s);\r\n },\r\n /** @param {Graphics} g */\r\n function (g, cell, index) { \r\n var inner = cell * 0.1,\r\n // Use fixed outer border widths in small icons to ensure the border is drawn\r\n outer = \r\n cell < 6 ? 1 :\r\n cell < 8 ? 2 :\r\n (0 | (cell * 0.25));\r\n \r\n inner = \r\n inner > 1 ? (0 | inner) : // large icon => truncate decimals\r\n inner > 0.5 ? 1 : // medium size icon => fixed width\r\n inner; // small icon => anti-aliased border\r\n\r\n g.addRectangle(outer, outer, cell - inner - outer, cell - inner - outer);\r\n },\r\n /** @param {Graphics} g */\r\n function (g, cell, index) { \r\n var m = 0 | (cell * 0.15),\r\n s = 0 | (cell * 0.5);\r\n g.addCircle(cell - s - m, cell - s - m, s);\r\n },\r\n /** @param {Graphics} g */\r\n function (g, cell, index) {\r\n var inner = cell * 0.1,\r\n outer = inner * 4;\r\n\r\n // Align edge to nearest pixel in large icons\r\n if (outer > 3) {\r\n outer = 0 | outer;\r\n }\r\n\r\n g.addRectangle(0, 0, cell, cell);\r\n g.addPolygon([\r\n outer, outer,\r\n cell - inner, outer,\r\n outer + (cell - outer - inner) / 2, cell - inner\r\n ], true);\r\n },\r\n /** @param {Graphics} g */\r\n function (g, cell, index) {\r\n g.addPolygon([\r\n 0, 0,\r\n cell, 0,\r\n cell, cell * 0.7,\r\n cell * 0.4, cell * 0.4,\r\n cell * 0.7, cell,\r\n 0, cell\r\n ]);\r\n },\r\n /** @param {Graphics} g */\r\n function (g, cell, index) {\r\n g.addTriangle(cell / 2, cell / 2, cell / 2, cell / 2, 3);\r\n },\r\n /** @param {Graphics} g */\r\n function (g, cell, index) {\r\n g.addRectangle(0, 0, cell, cell / 2);\r\n g.addRectangle(0, cell / 2, cell / 2, cell / 2);\r\n g.addTriangle(cell / 2, cell / 2, cell / 2, cell / 2, 1);\r\n },\r\n /** @param {Graphics} g */\r\n function (g, cell, index) {\r\n var inner = cell * 0.14,\r\n // Use fixed outer border widths in small icons to ensure the border is drawn\r\n outer = \r\n cell < 4 ? 1 :\r\n cell < 6 ? 2 :\r\n (0 | (cell * 0.35));\r\n\r\n inner = \r\n cell < 8 ? inner : // small icon => anti-aliased border\r\n (0 | inner); // large icon => truncate decimals\r\n\r\n g.addRectangle(0, 0, cell, cell);\r\n g.addRectangle(outer, outer, cell - outer - inner, cell - outer - inner, true);\r\n },\r\n /** @param {Graphics} g */\r\n function (g, cell, index) {\r\n var inner = cell * 0.12,\r\n outer = inner * 3;\r\n\r\n g.addRectangle(0, 0, cell, cell);\r\n g.addCircle(outer, outer, cell - inner - outer, true);\r\n },\r\n /** @param {Graphics} g */\r\n function (g, cell, index) {\r\n g.addTriangle(cell / 2, cell / 2, cell / 2, cell / 2, 3);\r\n },\r\n /** @param {Graphics} g */\r\n function (g, cell, index) {\r\n var m = cell * 0.25;\r\n g.addRectangle(0, 0, cell, cell);\r\n g.addRhombus(m, m, cell - m, cell - m, true);\r\n },\r\n /** @param {Graphics} g */\r\n function (g, cell, index) {\r\n var m = cell * 0.4, s = cell * 1.2;\r\n if (!index) {\r\n g.addCircle(m, m, s);\r\n }\r\n }\r\n ],\r\n \r\n outer: [\r\n /** @param {Graphics} g */\r\n function (g, cell, index) {\r\n g.addTriangle(0, 0, cell, cell, 0);\r\n },\r\n /** @param {Graphics} g */\r\n function (g, cell, index) {\r\n g.addTriangle(0, cell / 2, cell, cell / 2, 0);\r\n },\r\n /** @param {Graphics} g */\r\n function (g, cell, index) {\r\n g.addRhombus(0, 0, cell, cell);\r\n },\r\n /** @param {Graphics} g */\r\n function (g, cell, index) {\r\n var m = cell / 6;\r\n g.addCircle(m, m, cell - 2 * m);\r\n }\r\n ]\r\n};\r\n\r\n\r\n\r\n/**\r\n * Parses a substring of the hash as a number.\r\n * @param {number} startPosition \r\n * @param {number=} octets \r\n * @noinline\r\n */\r\nfunction parseHex(hash, startPosition, octets) {\r\n return parseInt(hash.substr(startPosition, octets), 16);\r\n}\r\n\r\n\r\n\r\n/**\r\n * Prepares a measure to be used as a measure in an SVG path, by\r\n * rounding the measure to a single decimal. This reduces the file\r\n * size of the generated SVG with more than 50% in some cases.\r\n */\r\nfunction svgValue(value) {\r\n return ((value * 10 + 0.5) | 0) / 10;\r\n}\r\n\r\n/**\r\n * Represents an SVG path element.\r\n * @private\r\n * @constructor\r\n */\r\nfunction SvgPath() {\r\n /**\r\n * This property holds the data string (path.d) of the SVG path.\r\n */\r\n this.dataString = \"\";\r\n}\r\nSvgPath.prototype = {\r\n /**\r\n * Adds a polygon with the current fill color to the SVG path.\r\n * @param points An array of Point objects.\r\n */\r\n addPolygon: function (points) {\r\n var dataString = \"M\" + svgValue(points[0].x) + \" \" + svgValue(points[0].y);\r\n for (var i = 1; i < points.length; i++) {\r\n dataString += \"L\" + svgValue(points[i].x) + \" \" + svgValue(points[i].y);\r\n }\r\n this.dataString += dataString + \"Z\";\r\n },\r\n /**\r\n * Adds a circle with the current fill color to the SVG path.\r\n * @param {Point} point The upper left corner of the circle bounding box.\r\n * @param {number} diameter The diameter of the circle.\r\n * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path).\r\n */\r\n addCircle: function (point, diameter, counterClockwise) {\r\n var sweepFlag = counterClockwise ? 0 : 1,\r\n svgRadius = svgValue(diameter / 2),\r\n svgDiameter = svgValue(diameter);\r\n \r\n this.dataString += \r\n \"M\" + svgValue(point.x) + \" \" + svgValue(point.y + diameter / 2) +\r\n \"a\" + svgRadius + \",\" + svgRadius + \" 0 1,\" + sweepFlag + \" \" + svgDiameter + \",0\" + \r\n \"a\" + svgRadius + \",\" + svgRadius + \" 0 1,\" + sweepFlag + \" \" + (-svgDiameter) + \",0\";\r\n }\r\n};\r\n\r\n\r\n\r\n\r\n/**\r\n * Renderer producing SVG output.\r\n * @private\r\n * @constructor\r\n * @param {SvgElement|SvgWriter} target \r\n */\r\nfunction SvgRenderer(target) {\r\n this._pathsByColor = { };\r\n this._target = target;\r\n this.size = target.size;\r\n}\r\nSvgRenderer.prototype = {\r\n /**\r\n * Fills the background with the specified color.\r\n * @param {string} fillColor Fill color on the format #rrggbb[aa].\r\n */\r\n setBackground: function (fillColor) {\r\n var match = /^(#......)(..)?/.exec(fillColor),\r\n opacity = match[2] ? parseHex(match[2], 0) / 255 : 1;\r\n this._target.setBackground(match[1], opacity);\r\n },\r\n /**\r\n * Marks the beginning of a new shape of the specified color. Should be ended with a call to endShape.\r\n * @param {string} color Fill color on format #xxxxxx.\r\n */\r\n beginShape: function (color) {\r\n this._path = this._pathsByColor[color] || (this._pathsByColor[color] = new SvgPath());\r\n },\r\n /**\r\n * Marks the end of the currently drawn shape.\r\n */\r\n endShape: function () { },\r\n /**\r\n * Adds a polygon with the current fill color to the SVG.\r\n * @param points An array of Point objects.\r\n */\r\n addPolygon: function (points) {\r\n this._path.addPolygon(points);\r\n },\r\n /**\r\n * Adds a circle with the current fill color to the SVG.\r\n * @param {Point} point The upper left corner of the circle bounding box.\r\n * @param {number} diameter The diameter of the circle.\r\n * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path).\r\n */\r\n addCircle: function (point, diameter, counterClockwise) {\r\n this._path.addCircle(point, diameter, counterClockwise);\r\n },\r\n /**\r\n * Called when the icon has been completely drawn.\r\n */\r\n finish: function () { \r\n for (var color in this._pathsByColor) {\r\n this._target.append(color, this._pathsByColor[color].dataString);\r\n }\r\n }\r\n};\r\n\r\n\r\n\r\n\r\n/**\r\n * Provides helper functions for rendering common basic shapes.\r\n * @private\r\n * @constructor\r\n */\r\nfunction Graphics(renderer) {\r\n this._renderer = renderer;\r\n this._transform = Transform.noTransform;\r\n}\r\nGraphics.prototype = {\r\n /**\r\n * Adds a polygon to the underlying renderer.\r\n * @param {Array} points The points of the polygon clockwise on the format [ x0, y0, x1, y1, ..., xn, yn ]\r\n * @param {boolean=} invert Specifies if the polygon will be inverted.\r\n */\r\n addPolygon: function (points, invert) {\r\n var di = invert ? -2 : 2, \r\n transform = this._transform,\r\n transformedPoints = [],\r\n i;\r\n \r\n for (i = invert ? points.length - 2 : 0; i < points.length && i >= 0; i += di) {\r\n transformedPoints.push(transform.transformPoint(points[i], points[i + 1]));\r\n }\r\n \r\n this._renderer.addPolygon(transformedPoints);\r\n },\r\n \r\n /**\r\n * Adds a polygon to the underlying renderer.\r\n * Source: http://stackoverflow.com/a/2173084\r\n * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the entire ellipse.\r\n * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the entire ellipse.\r\n * @param {number} size The size of the ellipse.\r\n * @param {boolean=} invert Specifies if the ellipse will be inverted.\r\n */\r\n addCircle: function (x, y, size, invert) {\r\n var p = this._transform.transformPoint(x, y, size, size);\r\n this._renderer.addCircle(p, size, invert);\r\n },\r\n\r\n /**\r\n * Adds a rectangle to the underlying renderer.\r\n * @param {number} x The x-coordinate of the upper left corner of the rectangle.\r\n * @param {number} y The y-coordinate of the upper left corner of the rectangle.\r\n * @param {number} w The width of the rectangle.\r\n * @param {number} h The height of the rectangle.\r\n * @param {boolean=} invert Specifies if the rectangle will be inverted.\r\n */\r\n addRectangle: function (x, y, w, h, invert) {\r\n this.addPolygon([\r\n x, y, \r\n x + w, y,\r\n x + w, y + h,\r\n x, y + h\r\n ], invert);\r\n },\r\n\r\n /**\r\n * Adds a right triangle to the underlying renderer.\r\n * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the triangle.\r\n * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the triangle.\r\n * @param {number} w The width of the triangle.\r\n * @param {number} h The height of the triangle.\r\n * @param {number} r The rotation of the triangle (clockwise). 0 = right corner of the triangle in the lower left corner of the bounding rectangle.\r\n * @param {boolean=} invert Specifies if the triangle will be inverted.\r\n */\r\n addTriangle: function (x, y, w, h, r, invert) {\r\n var points = [\r\n x + w, y, \r\n x + w, y + h, \r\n x, y + h,\r\n x, y\r\n ];\r\n points.splice(((r || 0) % 4) * 2, 2);\r\n this.addPolygon(points, invert);\r\n },\r\n\r\n /**\r\n * Adds a rhombus to the underlying renderer.\r\n * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the rhombus.\r\n * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the rhombus.\r\n * @param {number} w The width of the rhombus.\r\n * @param {number} h The height of the rhombus.\r\n * @param {boolean=} invert Specifies if the rhombus will be inverted.\r\n */\r\n addRhombus: function (x, y, w, h, invert) {\r\n this.addPolygon([\r\n x + w / 2, y,\r\n x + w, y + h / 2,\r\n x + w / 2, y + h,\r\n x, y + h / 2\r\n ], invert);\r\n }\r\n};\r\n\r\n\r\n\r\n\r\n/**\r\n * Gets a set of identicon color candidates for a specified hue and config.\r\n */\r\nfunction colorTheme(hue, config) {\r\n hue = config.hue(hue);\r\n return [\r\n // Dark gray\r\n color.correctedHsl(hue, config.grayscaleSaturation, config.grayscaleLightness(0)),\r\n // Mid color\r\n color.correctedHsl(hue, config.colorSaturation, config.colorLightness(0.5)),\r\n // Light gray\r\n color.correctedHsl(hue, config.grayscaleSaturation, config.grayscaleLightness(1)),\r\n // Light color\r\n color.correctedHsl(hue, config.colorSaturation, config.colorLightness(1)),\r\n // Dark color\r\n color.correctedHsl(hue, config.colorSaturation, config.colorLightness(0))\r\n ];\r\n}\r\n\r\n\r\n\r\n/**\r\n * Represents a point.\r\n * @private\r\n * @constructor\r\n */\r\nfunction Point(x, y) {\r\n this.x = x;\r\n this.y = y;\r\n};\r\n\r\n\r\n\r\n\r\n/**\r\n * Translates and rotates a point before being passed on to the canvas context. This was previously done by the canvas context itself, \r\n * but this caused a rendering issue in Chrome on sizes > 256 where the rotation transformation of inverted paths was not done properly.\r\n * @param {number} x The x-coordinate of the upper left corner of the transformed rectangle.\r\n * @param {number} y The y-coordinate of the upper left corner of the transformed rectangle.\r\n * @param {number} size The size of the transformed rectangle.\r\n * @param {number} rotation Rotation specified as 0 = 0 rad, 1 = 0.5π rad, 2 = π rad, 3 = 1.5π rad\r\n * @private\r\n * @constructor\r\n */\r\nfunction Transform(x, y, size, rotation) {\r\n this._x = x;\r\n this._y = y;\r\n this._size = size;\r\n this._rotation = rotation;\r\n}\r\nTransform.prototype = {\r\n /**\r\n * Transforms the specified point based on the translation and rotation specification for this Transform.\r\n * @param {number} x x-coordinate\r\n * @param {number} y y-coordinate\r\n * @param {number=} w The width of the transformed rectangle. If greater than 0, this will ensure the returned point is of the upper left corner of the transformed rectangle.\r\n * @param {number=} h The height of the transformed rectangle. If greater than 0, this will ensure the returned point is of the upper left corner of the transformed rectangle.\r\n */\r\n transformPoint: function (x, y, w, h) {\r\n var right = this._x + this._size,\r\n bottom = this._y + this._size;\r\n return this._rotation === 1 ? new Point(right - y - (h || 0), this._y + x) :\r\n this._rotation === 2 ? new Point(right - x - (w || 0), bottom - y - (h || 0)) :\r\n this._rotation === 3 ? new Point(this._x + y, bottom - x - (w || 0)) :\r\n new Point(this._x + x, this._y + y);\r\n }\r\n};\r\nTransform.noTransform = new Transform(0, 0, 0, 0);\r\n\r\n\r\n\r\n \r\n/**\r\n * Draws an identicon to a specified renderer.\r\n */\r\nfunction iconGenerator(renderer, hash, x, y, size, padding, config) {\r\n var undefined;\r\n \r\n // Set background color\r\n if (config.backColor) {\r\n renderer.setBackground(config.backColor);\r\n }\r\n \r\n // Calculate padding and round to nearest integer\r\n padding = (0.5 + size * (padding === undefined ? 0.08 : padding)) | 0;\r\n size -= padding * 2;\r\n \r\n var graphics = new Graphics(renderer);\r\n \r\n // Calculate cell size and ensure it is an integer\r\n var cell = 0 | (size / 4);\r\n \r\n // Since the cell size is integer based, the actual icon will be slightly smaller than specified => center icon\r\n x += 0 | (padding + size / 2 - cell * 2);\r\n y += 0 | (padding + size / 2 - cell * 2);\r\n\r\n function renderShape(colorIndex, shapes, index, rotationIndex, positions) {\r\n var r = rotationIndex ? parseHex(hash, rotationIndex, 1) : 0,\r\n shape = shapes[parseHex(hash, index, 1) % shapes.length],\r\n i;\r\n \r\n renderer.beginShape(availableColors[selectedColorIndexes[colorIndex]]);\r\n \r\n for (i = 0; i < positions.length; i++) {\r\n graphics._transform = new Transform(x + positions[i][0] * cell, y + positions[i][1] * cell, cell, r++ % 4);\r\n shape(graphics, cell, i);\r\n }\r\n \r\n renderer.endShape();\r\n }\r\n\r\n // AVAILABLE COLORS\r\n var hue = parseHex(hash, -7) / 0xfffffff,\r\n \r\n // Available colors for this icon\r\n availableColors = colorTheme(hue, config),\r\n\r\n // The index of the selected colors\r\n selectedColorIndexes = [],\r\n index;\r\n\r\n function isDuplicate(values) {\r\n if (values.indexOf(index) >= 0) {\r\n for (var i = 0; i < values.length; i++) {\r\n if (selectedColorIndexes.indexOf(values[i]) >= 0) {\r\n return true;\r\n }\r\n }\r\n }\r\n }\r\n\r\n for (var i = 0; i < 3; i++) {\r\n index = parseHex(hash, 8 + i, 1) % availableColors.length;\r\n if (isDuplicate([0, 4]) || // Disallow dark gray and dark color combo\r\n isDuplicate([2, 3])) { // Disallow light gray and light color combo\r\n index = 1;\r\n }\r\n selectedColorIndexes.push(index);\r\n }\r\n\r\n // ACTUAL RENDERING\r\n // Sides\r\n renderShape(0, shapes.outer, 2, 3, [[1, 0], [2, 0], [2, 3], [1, 3], [0, 1], [3, 1], [3, 2], [0, 2]]);\r\n // Corners\r\n renderShape(1, shapes.outer, 4, 5, [[0, 0], [3, 0], [3, 3], [0, 3]]);\r\n // Center\r\n renderShape(2, shapes.center, 1, null, [[1, 1], [2, 1], [2, 2], [1, 2]]);\r\n \r\n renderer.finish();\r\n};\r\n\r\n\r\n\r\n \r\n\r\n\r\n/**\r\n * Gets the normalized current Jdenticon color configuration. Missing fields have default values.\r\n */\r\nfunction getCurrentConfig() {\r\n var configObject = jdenticon[\"config\"] || global[\"jdenticon_config\"] || { },\r\n lightnessConfig = configObject[\"lightness\"] || { },\r\n \r\n // In versions < 2.1.0 there was no grayscale saturation -\r\n // saturation was the color saturation.\r\n saturation = configObject[\"saturation\"] || { },\r\n colorSaturation = \"color\" in saturation ? saturation[\"color\"] : saturation,\r\n grayscaleSaturation = saturation[\"grayscale\"],\r\n\r\n backColor = configObject[\"backColor\"];\r\n \r\n /**\r\n * Creates a lightness range.\r\n */\r\n function lightness(configName, defaultRange) {\r\n var range = lightnessConfig[configName];\r\n \r\n // Check if the lightness range is an array-like object. This way we ensure the\r\n // array contain two values at the same time.\r\n if (!(range && range.length > 1)) {\r\n range = defaultRange;\r\n }\r\n\r\n /**\r\n * Gets a lightness relative the specified value in the specified lightness range.\r\n */\r\n return function (value) {\r\n value = range[0] + value * (range[1] - range[0]);\r\n return value < 0 ? 0 : value > 1 ? 1 : value;\r\n };\r\n }\r\n\r\n /**\r\n * Gets a hue allowed by the configured hue restriction,\r\n * provided the originally computed hue.\r\n */\r\n function hueFunction(originalHue) {\r\n var hueConfig = configObject[\"hues\"], hue;\r\n \r\n // Check if 'hues' is an array-like object. This way we also ensure that\r\n // the array is not empty, which would mean no hue restriction.\r\n if (hueConfig && hueConfig.length > 0) {\r\n // originalHue is in the range [0, 1]\r\n // Multiply with 0.999 to change the range to [0, 1) and then truncate the index.\r\n hue = hueConfig[0 | (0.999 * originalHue * hueConfig.length)];\r\n }\r\n\r\n return typeof hue == \"number\" ?\r\n \r\n // A hue was specified. We need to convert the hue from\r\n // degrees on any turn - e.g. 746° is a perfectly valid hue -\r\n // to turns in the range [0, 1).\r\n ((((hue / 360) % 1) + 1) % 1) :\r\n\r\n // No hue configured => use original hue\r\n originalHue;\r\n }\r\n \r\n return {\r\n hue: hueFunction,\r\n colorSaturation: typeof colorSaturation == \"number\" ? colorSaturation : 0.5,\r\n grayscaleSaturation: typeof grayscaleSaturation == \"number\" ? grayscaleSaturation : 0,\r\n colorLightness: lightness(\"color\", [0.4, 0.8]),\r\n grayscaleLightness: lightness(\"grayscale\", [0.3, 0.9]),\r\n backColor: color.parse(backColor)\r\n }\r\n}\r\n\r\n/**\r\n * Inputs a value that might be a valid hash string for Jdenticon and returns it \r\n * if it is determined valid, otherwise a falsy value is returned.\r\n */\r\nfunction getValidHash(hashCandidate) {\r\n return /^[0-9a-f]{11,}$/i.test(hashCandidate) && hashCandidate;\r\n}\r\n\r\n/**\r\n * Computes a hash for the specified value. Currnently SHA1 is used. This function\r\n * always returns a valid hash.\r\n */\r\nfunction computeHash(value) {\r\n return sha1(value == null ? \"\" : \"\" + value);\r\n}\r\n\r\n/**\r\n * Updates the identicon in the specified canvas or svg elements.\r\n * @param {(string|Element)} el - Specifies the container in which the icon is rendered. Can be a CSS selector or a DOM element of the type SVG or CANVAS.\r\n * @param {string=} hash - Optional hash to be rendered. If not specified, the hash specified by the data-jdenticon-hash is used.\r\n * @param {number=} padding - Optional padding in percents. Extra padding might be added to center the rendered identicon.\r\n */\r\nfunction update(el, hash, padding) {\r\n if (typeof(el) === \"string\") {\r\n if (dom.supportsQuerySelectorAll) {\r\n var elements = document.querySelectorAll(el);\r\n for (var i = 0; i < elements.length; i++) {\r\n update(elements[i], hash, padding);\r\n }\r\n }\r\n return;\r\n }\r\n\r\n var iconType = dom.getIdenticonType(el);\r\n if (!iconType) {\r\n return;\r\n }\r\n \r\n // Hash selection. The result from getValidHash or computeHash is \r\n // accepted as a valid hash.\r\n hash = \r\n // 1. Explicit valid hash\r\n getValidHash(hash) ||\r\n \r\n // 2. Explicit value (`!= null` catches both null and undefined)\r\n hash != null && computeHash(hash) ||\r\n \r\n // 3. `data-jdenticon-hash` attribute\r\n getValidHash(el.getAttribute(dom.HASH_ATTRIBUTE)) ||\r\n \r\n // 4. `data-jdenticon-value` attribute. \r\n // We want to treat an empty attribute as an empty value. \r\n // Some browsers return empty string even if the attribute \r\n // is not specified, so use hasAttribute to determine if \r\n // the attribute is specified.\r\n el.hasAttribute(dom.VALUE_ATTRIBUTE) && computeHash(el.getAttribute(dom.VALUE_ATTRIBUTE));\r\n \r\n if (!hash) {\r\n // No hash specified. Don't render an icon.\r\n return;\r\n }\r\n \r\n var renderer = iconType == dom.ICON_TYPE_SVG ? \r\n new SvgRenderer(new SvgElement(el)) : \r\n new CanvasRenderer(el.getContext(\"2d\"));\r\n \r\n // Draw icon\r\n iconGenerator(renderer, hash, 0, 0, renderer.size, padding, getCurrentConfig());\r\n}\r\n\r\n/**\r\n * Draws an identicon to a context.\r\n * @param {CanvasRenderingContext2D} ctx - Canvas context on which the icon will be drawn at location (0, 0).\r\n * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon.\r\n * @param {number} size - Icon size in pixels.\r\n */\r\nfunction drawIcon(ctx, hashOrValue, size, padding) {\r\n if (!ctx) {\r\n throw new Error(\"No canvas specified.\");\r\n }\r\n \r\n var renderer = new CanvasRenderer(ctx, size);\r\n iconGenerator(renderer, \r\n getValidHash(hashOrValue) || computeHash(hashOrValue), \r\n 0, 0, size, padding || 0, getCurrentConfig());\r\n}\r\n\r\n/**\r\n * Draws an identicon as an SVG string.\r\n * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon.\r\n * @param {number} size - Icon size in pixels.\r\n * @param {number=} padding - Optional padding in percents. Extra padding might be added to center the rendered identicon.\r\n * @returns {string} SVG string\r\n */\r\nfunction toSvg(hashOrValue, size, padding) {\r\n var writer = new SvgWriter(size);\r\n var renderer = new SvgRenderer(writer);\r\n iconGenerator(renderer, \r\n getValidHash(hashOrValue) || computeHash(hashOrValue),\r\n 0, 0, size, padding, getCurrentConfig());\r\n return writer.toString();\r\n}\r\n\r\n/**\r\n * Updates all canvas elements with the data-jdenticon-hash attribute.\r\n */\r\nfunction jdenticon() {\r\n if (dom.supportsQuerySelectorAll) {\r\n update(dom.ICON_SELECTOR);\r\n }\r\n}\r\n\r\n/**\r\n * This function is called once upon page load.\r\n */\r\nfunction jdenticonStartup() {\r\n var replaceMode = (jdenticon[\"config\"] || global[\"jdenticon_config\"] || { })[\"replaceMode\"];\r\n if (replaceMode != \"never\") {\r\n jdenticon();\r\n \r\n if (replaceMode == \"observe\") {\r\n observer(update);\r\n }\r\n }\r\n}\r\n\r\n// Public API\r\njdenticon[\"drawIcon\"] = drawIcon;\r\njdenticon[\"toSvg\"] = toSvg;\r\njdenticon[\"update\"] = update;\r\njdenticon[\"version\"] = \"2.1.0\";\r\n\r\n// Basic jQuery plugin\r\nif (jQuery) {\r\n jQuery[\"fn\"][\"jdenticon\"] = function (hashOrValue, padding) {\r\n this[\"each\"](function (index, el) {\r\n update(el, hashOrValue, padding);\r\n });\r\n return this;\r\n };\r\n}\r\n\r\n// Schedule to render all identicons on the page once it has been loaded.\r\nif (typeof setTimeout === \"function\") {\r\n setTimeout(jdenticonStartup, 0);\r\n}\r\n\r\n\r\n\r\n\r\n return jdenticon;\r\n});"]} \ No newline at end of file +{"version":3,"file":"jdenticon.min.js","lineCount":19,"mappings":"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","sources":["jdenticon.js"],"names":["global","name","factory","jdenticon","jQuery","module","define","SvgElement_append","parentNode","keyValuePairs","el","document","createElementNS","i","arguments","length","setAttribute","appendChild","SvgElement","element","size","Math","min","Number","getAttribute","_el","firstChild","removeChild","SvgWriter","_s","sha1","message","wordsToHexString","words","hashOctets","val","shift","push","toString","join","computeHash","blocks","a","b","c","d","e","hash","w","t","value","T","f","getBlocks","getWordBlock","startIndex","byteCount","wordIndex","binaryMessage","BLOCK_SIZE_WORDS","percentEncoded","encodeURI","binaryMessageLength","parseHex","charCodeAt","BLOCK_SIZE_BYTES","lastBlockDataLength","block","MESSAGE_LENGTH_SIZE_BYTES","CanvasRenderer","ctx","width","canvas","height","save","_ctx","translate","clearRect","decToHex","v","hueToRgb","m1","m2","h","observer","updateCallback","MutationObserver","observe","mutationObserver","onmutation","mutations","mutationIndex","mutation","addedNodes","addedNodeIndex","addedNode","nodeType","dom","getIdenticonType","icons","querySelectorAll","ICON_SELECTOR","iconIndex","type","target","body","VALUE_ATTRIBUTE","HASH_ATTRIBUTE","startPosition","octets","parseInt","substr","svgValue","SvgPath","dataString","SvgRenderer","_pathsByColor","_target","Graphics","renderer","_renderer","_transform","Transform","noTransform","colorTheme","hue","config","color","correctedHsl","grayscaleSaturation","grayscaleLightness","colorSaturation","colorLightness","Point","x","y","rotation","_x","_y","_size","_rotation","iconGenerator","padding","renderShape","colorIndex","shapes","index","rotationIndex","positions","r","shape","beginShape","availableColors","selectedColorIndexes","graphics","cell","endShape","isDuplicate","values","indexOf","backColor","setBackground","undefined","outer","center","finish","getCurrentConfig","lightness","configName","defaultRange","range","lightnessConfig","configObject","saturation","hueFunction","originalHue","hueConfig","parse","getValidHash","hashCandidate","test","update","supportsQuerySelectorAll","elements","iconType","hasAttribute","ICON_TYPE_SVG","getContext","jdenticonStartup","replaceMode","prototype","fillColor","opacity","append","toFixed","ICON_TYPE_CANVAS","dom_getIdenticonType","tagName","fillStyle","toCss3","fillRect","beginPath","fill","addPolygon","points","moveTo","lineTo","closePath","addCircle","point","diameter","counterClockwise","radius","arc","PI","restore","rgb","g","hexColor","isNaN","hsl","s","l","partialHex","corrector","correctors","k","addTriangle","addRectangle","inner","m","addRhombus","sweepFlag","svgRadius","svgDiameter","match","exec","_path","invert","di","transform","transformedPoints","transformPoint","p","splice","right","bottom","drawIcon","hashOrValue","Error","toSvg","writer","setTimeout"],"sourcesContent":["/**\r\n * Jdenticon 2.1.1\r\n * http://jdenticon.com\r\n * \r\n * Built: 2018-12-22T10:15:41.611Z\r\n *\r\n * Copyright (c) 2014-2018 Daniel Mester Pirttijärvi\r\n *\r\n * Permission is hereby granted, free of charge, to any person obtaining \r\n * a copy of this software and associated documentation files (the \r\n * \"Software\"), to deal in the Software without restriction, including \r\n * without limitation the rights to use, copy, modify, merge, publish, \r\n * distribute, sublicense, and/or sell copies of the Software, and to \r\n * permit persons to whom the Software is furnished to do so, subject to \r\n * the following conditions:\r\n * \r\n * The above copyright notice and this permission notice shall be \r\n * included in all copies or substantial portions of the Software.\r\n * \r\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, \r\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF \r\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. \r\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY \r\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, \r\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE \r\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n */\r\n\r\n/*jslint bitwise: true */\r\n\r\n(function (global, name, factory) {\r\n var jQuery = global[\"jQuery\"],\r\n jdenticon = factory(global, jQuery);\r\n\r\n // Node.js\r\n if (typeof module !== \"undefined\" && \"exports\" in module) {\r\n module[\"exports\"] = jdenticon;\r\n }\r\n // RequireJS\r\n else if (typeof define === \"function\" && define[\"amd\"]) {\r\n define([], function () { return jdenticon; });\r\n }\r\n // No module loader\r\n else {\r\n global[name] = jdenticon;\r\n }\r\n})(this, \"jdenticon\", function (global, jQuery) {\r\n \"use strict\";\r\n\r\n/**\r\n * Creates a new element and adds it to the specified parent.\r\n * @param {Element} parentNode\r\n * @param {string} name\r\n * @param {...*} keyValuePairs\r\n */\r\nfunction SvgElement_append(parentNode, name, keyValuePairs) {\r\n var el = document.createElementNS(\"http://www.w3.org/2000/svg\", name);\r\n \r\n for (var i = 2; i + 1 < arguments.length; i += 2) {\r\n el.setAttribute(arguments[i], arguments[i + 1]);\r\n }\r\n\r\n parentNode.appendChild(el);\r\n}\r\n\r\n/**\r\n * Renderer producing SVG output.\r\n * @private\r\n * @constructor\r\n */\r\nfunction SvgElement(element) {\r\n // Don't use the clientWidth and clientHeight properties on SVG elements\r\n // since Firefox won't serve a proper value of these properties on SVG\r\n // elements (https://bugzilla.mozilla.org/show_bug.cgi?id=874811)\r\n // Instead use 100px as a hardcoded size (the svg viewBox will rescale \r\n // the icon to the correct dimensions)\r\n this.size = Math.min(\r\n (Number(element.getAttribute(\"width\")) || 100),\r\n (Number(element.getAttribute(\"height\")) || 100)\r\n );\r\n this._el = element;\r\n \r\n // Clear current SVG child elements\r\n while (element.firstChild) {\r\n element.removeChild(element.firstChild);\r\n }\r\n \r\n // Set viewBox attribute to ensure the svg scales nicely.\r\n element.setAttribute(\"viewBox\", \"0 0 \" + this.size + \" \" + this.size);\r\n element.setAttribute(\"preserveAspectRatio\", \"xMidYMid meet\");\r\n}\r\nSvgElement.prototype = {\r\n /**\r\n * Fills the background with the specified color.\r\n * @param {string} fillColor Fill color on the format #rrggbb.\r\n * @param {number} opacity Opacity in the range [0.0, 1.0].\r\n */\r\n setBackground: function (fillColor, opacity) {\r\n if (opacity) {\r\n SvgElement_append(this._el, \"rect\",\r\n \"width\", \"100%\",\r\n \"height\", \"100%\",\r\n \"fill\", fillColor,\r\n \"opacity\", opacity);\r\n }\r\n },\r\n /**\r\n * Appends a path to the SVG element.\r\n * @param {string} color Fill color on format #xxxxxx.\r\n * @param {string} dataString The SVG path data string.\r\n */\r\n append: function (color, dataString) {\r\n SvgElement_append(this._el, \"path\",\r\n \"fill\", color,\r\n \"d\", dataString);\r\n }\r\n};\r\n\r\n\r\n\r\n/**\r\n * Renderer producing SVG output.\r\n * @private\r\n * @constructor\r\n */\r\nfunction SvgWriter(size) {\r\n this.size = size;\r\n this._s =\r\n '';\r\n}\r\nSvgWriter.prototype = {\r\n /**\r\n * Fills the background with the specified color.\r\n * @param {string} fillColor Fill color on the format #rrggbb.\r\n * @param {number} opacity Opacity in the range [0.0, 1.0].\r\n */\r\n setBackground: function (fillColor, opacity) {\r\n if (opacity) {\r\n this._s += '';\r\n }\r\n },\r\n /**\r\n * Writes a path to the SVG string.\r\n * @param {string} color Fill color on format #rrggbb.\r\n * @param {string} dataString The SVG path data string.\r\n */\r\n append: function (color, dataString) {\r\n this._s += \r\n '';\r\n },\r\n /**\r\n * Gets the rendered image as an SVG string.\r\n */\r\n toString: function () {\r\n return this._s + \"\";\r\n }\r\n};\r\n\r\n\r\n\r\nvar dom = {\r\n /** @const */\r\n ICON_TYPE_SVG: 1,\r\n\r\n /** @const */\r\n ICON_TYPE_CANVAS: 2,\r\n \r\n /** @const */\r\n HASH_ATTRIBUTE: \"data-jdenticon-hash\",\r\n \r\n /** @const */\r\n VALUE_ATTRIBUTE: \"data-jdenticon-value\",\r\n\r\n supportsQuerySelectorAll: typeof document !== \"undefined\" && \"querySelectorAll\" in document,\r\n\r\n getIdenticonType: dom_getIdenticonType\r\n};\r\n\r\n/** @const */\r\ndom.ICON_SELECTOR = \"[\" + dom.HASH_ATTRIBUTE +\"],[\" + dom.VALUE_ATTRIBUTE +\"]\";\r\n\r\nfunction dom_getIdenticonType(el) {\r\n if (el) {\r\n var tagName = el[\"tagName\"];\r\n\r\n if (/svg/i.test(tagName)) {\r\n return dom.ICON_TYPE_SVG;\r\n }\r\n\r\n if (/canvas/i.test(tagName) && \"getContext\" in el) {\r\n return dom.ICON_TYPE_CANVAS;\r\n }\r\n }\r\n}\r\n\r\n\r\n\r\n\r\n/**\r\n * Computes a SHA1 hash for any value and returns it as a hexadecimal string.\r\n * @param {string} message \r\n */\r\nfunction sha1(message) {\r\n /**\r\n * Converts an array of 32-bit unsigned numbers to a hexadecimal string in big endian format.\r\n * @param {Array} words\r\n */\r\n function wordsToHexString(words) {\r\n var hashOctets = [];\r\n for (var i = 0; i < words.length; i++) {\r\n var val = words[i];\r\n \r\n for (var shift = 28; shift >= 0; shift -= 4) {\r\n var octet = (val >>> shift) & 0xf;\r\n hashOctets.push(octet.toString(16));\r\n }\r\n }\r\n\r\n return hashOctets.join(\"\");\r\n }\r\n \r\n /**\r\n * Converts the specified message to a sequence of UTF8 encoded and padded 64 byte blocks.\r\n * @param {string} message Any value that will be padded to 64 byte blocks.\r\n */\r\n function getBlocks(message) {\r\n var percentEncoded = encodeURI(message),\r\n binaryMessage = [],\r\n binaryMessageLength = 0,\r\n i, b,\r\n\r\n blocks = [],\r\n\r\n BLOCK_SIZE_BYTES = 64,\r\n BLOCK_SIZE_WORDS = BLOCK_SIZE_BYTES >>> 2,\r\n MESSAGE_LENGTH_SIZE_BYTES = 8;\r\n\r\n // UTF8 encode message\r\n for (i = 0; i < percentEncoded.length; i++) {\r\n if (percentEncoded[i] == \"%\") {\r\n b = parseHex(percentEncoded, i + 1, 2);\r\n i += 2;\r\n }\r\n else {\r\n b = percentEncoded.charCodeAt(i);\r\n }\r\n binaryMessage[binaryMessageLength++] = b;\r\n }\r\n\r\n // Trailing '1' bit\r\n binaryMessage[binaryMessageLength++] = 0x80;\r\n \r\n function getWordBlock(startIndex, byteCount) {\r\n var words = [];\r\n var wordIndex = -1;\r\n \r\n for (var i = 0; i < byteCount; i++) {\r\n wordIndex = (i / 4) | 0;\r\n words[wordIndex] = (words[wordIndex] || 0) +\r\n (binaryMessage[startIndex + i] << ((3 - (i & 3)) * 8));\r\n }\r\n \r\n while (++wordIndex < BLOCK_SIZE_WORDS) {\r\n words[wordIndex] = 0;\r\n }\r\n\r\n return words;\r\n }\r\n\r\n // Full blocks\r\n for (i = 0; i + BLOCK_SIZE_BYTES <= binaryMessageLength; i+= BLOCK_SIZE_BYTES) {\r\n blocks.push(getWordBlock(i, BLOCK_SIZE_BYTES));\r\n }\r\n\r\n // Final block(s)\r\n // Rest of message\r\n var lastBlockDataLength = binaryMessageLength - i;\r\n \r\n var block = getWordBlock(i, lastBlockDataLength);\r\n \r\n // If there is no room for the message size in this block, \r\n // return the block and put the size in the following block.\r\n if (lastBlockDataLength + MESSAGE_LENGTH_SIZE_BYTES > BLOCK_SIZE_BYTES) {\r\n // Message size goes in next block\r\n blocks.push(block);\r\n block = getWordBlock(0, 0);\r\n }\r\n\r\n var messageSizeBits = binaryMessageLength * 8 - 8;\r\n block[BLOCK_SIZE_WORDS - 1] = messageSizeBits;\r\n blocks.push(block);\r\n\r\n return blocks;\r\n }\r\n\r\n /**\r\n * Rotates the value a specified number of bits to the left.\r\n * @param {number} value Value to rotate\r\n * @param {number} shift Bit count to shift.\r\n */\r\n function rotl(value, shift) {\r\n return (value << shift) | (value >>> (32 - shift));\r\n }\r\n \r\n /**\r\n * Computes a SHA1 hash for the specified array of 64 byte blocks.\r\n * @param {Array>} blocks \r\n */\r\n function computeHash(blocks) {\r\n var a = 0x67452301,\r\n b = 0xefcdab89,\r\n c = 0x98badcfe,\r\n d = 0x10325476,\r\n e = 0xc3d2e1f0,\r\n hash = [a, b, c, d, e];\r\n\r\n for (var i = 0; i < blocks.length; i++) {\r\n var w = blocks[i];\r\n\r\n for (var t = 16; t < 80; t++) {\r\n w[t] = rotl(w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16], 1);\r\n }\r\n\r\n for (var t = 0; t < 80; t++) {\r\n var f =\r\n // Ch\r\n t < 20 ? ((b & c) ^ ((~b) & d)) + 0x5a827999 :\r\n \r\n // Parity\r\n t < 40 ? (b ^ c ^ d) + 0x6ed9eba1 :\r\n \r\n // Maj\r\n t < 60 ? ((b & c) ^ (b & d) ^ (c & d)) + 0x8f1bbcdc :\r\n \r\n // Parity\r\n (b ^ c ^ d) + 0xca62c1d6;\r\n\r\n var T = rotl(a, 5) + f + e + w[t];\r\n\r\n e = d;\r\n d = c;\r\n c = rotl(b, 30);\r\n b = a;\r\n a = T | 0;\r\n }\r\n\r\n hash[0] = a = ((hash[0] + a) | 0);\r\n hash[1] = b = ((hash[1] + b) | 0);\r\n hash[2] = c = ((hash[2] + c) | 0);\r\n hash[3] = d = ((hash[3] + d) | 0);\r\n hash[4] = e = ((hash[4] + e) | 0);\r\n }\r\n\r\n return hash;\r\n }\r\n\r\n return wordsToHexString(computeHash(getBlocks(message)));\r\n}\r\n\r\n\r\n\r\n\r\n/**\r\n * Renderer redirecting drawing commands to a canvas context.\r\n * @param {number=} size\r\n * @private\r\n * @constructor\r\n */\r\nfunction CanvasRenderer(ctx, size) {\r\n var width = ctx.canvas.width,\r\n height = ctx.canvas.height;\r\n \r\n ctx.save();\r\n \r\n this._ctx = ctx;\r\n \r\n if (size) {\r\n this.size = size;\r\n }\r\n else {\r\n this.size = Math.min(width, height);\r\n \r\n ctx.translate(\r\n ((width - this.size) / 2) | 0,\r\n ((height - this.size) / 2) | 0);\r\n }\r\n \r\n ctx.clearRect(0, 0, this.size, this.size);\r\n}\r\nCanvasRenderer.prototype = {\r\n /**\r\n * Fills the background with the specified color.\r\n * @param {string} fillColor Fill color on the format #rrggbb[aa].\r\n */\r\n setBackground: function (fillColor) {\r\n var ctx = this._ctx,\r\n size = this.size;\r\n \r\n ctx.fillStyle = color.toCss3(fillColor);\r\n ctx.fillRect(0, 0, size, size);\r\n },\r\n /**\r\n * Marks the beginning of a new shape of the specified color. Should be ended with a call to endShape.\r\n * @param {string} fillColor Fill color on format #rrggbb[aa].\r\n */\r\n beginShape: function (fillColor) {\r\n this._ctx.fillStyle = color.toCss3(fillColor);\r\n this._ctx.beginPath();\r\n },\r\n /**\r\n * Marks the end of the currently drawn shape. This causes the queued paths to be rendered on the canvas.\r\n */\r\n endShape: function () {\r\n this._ctx.fill();\r\n },\r\n /**\r\n * Adds a polygon to the rendering queue.\r\n * @param points An array of Point objects.\r\n */\r\n addPolygon: function (points) {\r\n var ctx = this._ctx, i;\r\n ctx.moveTo(points[0].x, points[0].y);\r\n for (i = 1; i < points.length; i++) {\r\n ctx.lineTo(points[i].x, points[i].y);\r\n }\r\n ctx.closePath();\r\n },\r\n /**\r\n * Adds a circle to the rendering queue.\r\n * @param {Point} point The upper left corner of the circle bounding box.\r\n * @param {number} diameter The diameter of the circle.\r\n * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path).\r\n */\r\n addCircle: function (point, diameter, counterClockwise) {\r\n var ctx = this._ctx,\r\n radius = diameter / 2;\r\n ctx.moveTo(point.x + radius, point.y + radius);\r\n ctx.arc(point.x + radius, point.y + radius, radius, 0, Math.PI * 2, counterClockwise);\r\n ctx.closePath();\r\n },\r\n /**\r\n * Called when the icon has been completely drawn.\r\n */\r\n finish: function () {\r\n this._ctx.restore();\r\n }\r\n};\r\n\r\n\r\n\r\n\r\nfunction decToHex(v) {\r\n v |= 0; // Ensure integer value\r\n return v < 0 ? \"00\" :\r\n v < 16 ? \"0\" + v.toString(16) :\r\n v < 256 ? v.toString(16) :\r\n \"ff\";\r\n}\r\n\r\nfunction hueToRgb(m1, m2, h) {\r\n h = h < 0 ? h + 6 : h > 6 ? h - 6 : h;\r\n return decToHex(255 * (\r\n h < 1 ? m1 + (m2 - m1) * h :\r\n h < 3 ? m2 :\r\n h < 4 ? m1 + (m2 - m1) * (4 - h) :\r\n m1));\r\n}\r\n \r\n/**\r\n * Functions for converting colors to hex-rgb representations.\r\n * @private\r\n */\r\nvar color = {\r\n /**\r\n * @param {number} r Red channel [0, 255]\r\n * @param {number} g Green channel [0, 255]\r\n * @param {number} b Blue channel [0, 255]\r\n */\r\n rgb: function (r, g, b) {\r\n return \"#\" + decToHex(r) + decToHex(g) + decToHex(b);\r\n },\r\n /**\r\n * @param {string} color Color value to parse. Curently hexadecimal strings on the format #rgb[a] and #rrggbb[aa] are supported.\r\n */\r\n parse: function (color) {\r\n if (/^#[0-9a-f]{3,8}$/i.test(color)) {\r\n if (color.length < 6) {\r\n var r = color[1],\r\n g = color[2],\r\n b = color[3],\r\n a = color[4] || \"\";\r\n return \"#\" + r + r + g + g + b + b + a + a;\r\n }\r\n if (color.length == 7 || color.length > 8) {\r\n return color;\r\n }\r\n }\r\n },\r\n /**\r\n * @param {string} hexColor Color on the format \"#RRGGBB\" or \"#RRGGBBAA\"\r\n */\r\n toCss3: function (hexColor) {\r\n var a = parseHex(hexColor, 7, 2);\r\n if (isNaN(a)) {\r\n return hexColor;\r\n }\r\n var r = parseHex(hexColor, 1, 2),\r\n g = parseHex(hexColor, 3, 2),\r\n b = parseHex(hexColor, 5, 2);\r\n return \"rgba(\" + r + \",\" + g + \",\" + b + \",\" + (a / 255).toFixed(2) + \")\";\r\n },\r\n /**\r\n * @param h Hue [0, 1]\r\n * @param s Saturation [0, 1]\r\n * @param l Lightness [0, 1]\r\n */\r\n hsl: function (h, s, l) {\r\n // Based on http://www.w3.org/TR/2011/REC-css3-color-20110607/#hsl-color\r\n if (s == 0) {\r\n var partialHex = decToHex(l * 255);\r\n return \"#\" + partialHex + partialHex + partialHex;\r\n }\r\n else {\r\n var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s,\r\n m1 = l * 2 - m2;\r\n return \"#\" +\r\n hueToRgb(m1, m2, h * 6 + 2) +\r\n hueToRgb(m1, m2, h * 6) +\r\n hueToRgb(m1, m2, h * 6 - 2);\r\n }\r\n },\r\n // This function will correct the lightness for the \"dark\" hues\r\n correctedHsl: function (h, s, l) {\r\n // The corrector specifies the perceived middle lightnesses for each hue\r\n var correctors = [ 0.55, 0.5, 0.5, 0.46, 0.6, 0.55, 0.55 ],\r\n corrector = correctors[(h * 6 + 0.5) | 0];\r\n \r\n // Adjust the input lightness relative to the corrector\r\n l = l < 0.5 ? l * corrector * 2 : corrector + (l - 0.5) * (1 - corrector) * 2;\r\n \r\n return color.hsl(h, s, l);\r\n }\r\n};\r\n\r\n\r\n\r\n\r\nfunction observer(updateCallback) {\r\n if (typeof MutationObserver != \"undefined\") {\r\n var mutationObserver = new MutationObserver(function onmutation(mutations) {\r\n for (var mutationIndex = 0; mutationIndex < mutations.length; mutationIndex++) {\r\n var mutation = mutations[mutationIndex];\r\n var addedNodes = mutation.addedNodes;\r\n \r\n for (var addedNodeIndex = 0; addedNodes && addedNodeIndex < addedNodes.length; addedNodeIndex++) {\r\n var addedNode = addedNodes[addedNodeIndex];\r\n \r\n // Skip other types of nodes than element nodes, since they might not support\r\n // the querySelectorAll method => runtime error.\r\n if (addedNode.nodeType == Node.ELEMENT_NODE) {\r\n if (dom.getIdenticonType(addedNode)) {\r\n updateCallback(addedNode);\r\n }\r\n else {\r\n var icons = addedNode.querySelectorAll(dom.ICON_SELECTOR);\r\n for (var iconIndex = 0; iconIndex < icons.length; iconIndex++) {\r\n updateCallback(icons[iconIndex]);\r\n }\r\n }\r\n }\r\n }\r\n \r\n if (mutation.type == \"attributes\" && dom.getIdenticonType(mutation.target)) {\r\n updateCallback(mutation.target);\r\n }\r\n }\r\n });\r\n\r\n mutationObserver.observe(document.body, { \r\n \"childList\": true, \r\n \"attributes\": true, \r\n \"attributeFilter\": [dom.VALUE_ATTRIBUTE, dom.HASH_ATTRIBUTE, \"width\", \"height\"], \r\n \"subtree\": true \r\n });\r\n }\r\n}\r\n\r\n\r\n\r\nvar shapes = {\r\n center: [\r\n /** @param {Graphics} g */\r\n function (g, cell, index) {\r\n var k = cell * 0.42;\r\n g.addPolygon([\r\n 0, 0,\r\n cell, 0,\r\n cell, cell - k * 2,\r\n cell - k, cell,\r\n 0, cell\r\n ]);\r\n },\r\n /** @param {Graphics} g */\r\n function (g, cell, index) {\r\n var w = 0 | (cell * 0.5), \r\n h = 0 | (cell * 0.8);\r\n g.addTriangle(cell - w, 0, w, h, 2);\r\n },\r\n /** @param {Graphics} g */\r\n function (g, cell, index) { \r\n var s = 0 | (cell / 3);\r\n g.addRectangle(s, s, cell - s, cell - s);\r\n },\r\n /** @param {Graphics} g */\r\n function (g, cell, index) { \r\n var inner = cell * 0.1,\r\n // Use fixed outer border widths in small icons to ensure the border is drawn\r\n outer = \r\n cell < 6 ? 1 :\r\n cell < 8 ? 2 :\r\n (0 | (cell * 0.25));\r\n \r\n inner = \r\n inner > 1 ? (0 | inner) : // large icon => truncate decimals\r\n inner > 0.5 ? 1 : // medium size icon => fixed width\r\n inner; // small icon => anti-aliased border\r\n\r\n g.addRectangle(outer, outer, cell - inner - outer, cell - inner - outer);\r\n },\r\n /** @param {Graphics} g */\r\n function (g, cell, index) { \r\n var m = 0 | (cell * 0.15),\r\n s = 0 | (cell * 0.5);\r\n g.addCircle(cell - s - m, cell - s - m, s);\r\n },\r\n /** @param {Graphics} g */\r\n function (g, cell, index) {\r\n var inner = cell * 0.1,\r\n outer = inner * 4;\r\n\r\n // Align edge to nearest pixel in large icons\r\n if (outer > 3) {\r\n outer = 0 | outer;\r\n }\r\n\r\n g.addRectangle(0, 0, cell, cell);\r\n g.addPolygon([\r\n outer, outer,\r\n cell - inner, outer,\r\n outer + (cell - outer - inner) / 2, cell - inner\r\n ], true);\r\n },\r\n /** @param {Graphics} g */\r\n function (g, cell, index) {\r\n g.addPolygon([\r\n 0, 0,\r\n cell, 0,\r\n cell, cell * 0.7,\r\n cell * 0.4, cell * 0.4,\r\n cell * 0.7, cell,\r\n 0, cell\r\n ]);\r\n },\r\n /** @param {Graphics} g */\r\n function (g, cell, index) {\r\n g.addTriangle(cell / 2, cell / 2, cell / 2, cell / 2, 3);\r\n },\r\n /** @param {Graphics} g */\r\n function (g, cell, index) {\r\n g.addRectangle(0, 0, cell, cell / 2);\r\n g.addRectangle(0, cell / 2, cell / 2, cell / 2);\r\n g.addTriangle(cell / 2, cell / 2, cell / 2, cell / 2, 1);\r\n },\r\n /** @param {Graphics} g */\r\n function (g, cell, index) {\r\n var inner = cell * 0.14,\r\n // Use fixed outer border widths in small icons to ensure the border is drawn\r\n outer = \r\n cell < 4 ? 1 :\r\n cell < 6 ? 2 :\r\n (0 | (cell * 0.35));\r\n\r\n inner = \r\n cell < 8 ? inner : // small icon => anti-aliased border\r\n (0 | inner); // large icon => truncate decimals\r\n\r\n g.addRectangle(0, 0, cell, cell);\r\n g.addRectangle(outer, outer, cell - outer - inner, cell - outer - inner, true);\r\n },\r\n /** @param {Graphics} g */\r\n function (g, cell, index) {\r\n var inner = cell * 0.12,\r\n outer = inner * 3;\r\n\r\n g.addRectangle(0, 0, cell, cell);\r\n g.addCircle(outer, outer, cell - inner - outer, true);\r\n },\r\n /** @param {Graphics} g */\r\n function (g, cell, index) {\r\n g.addTriangle(cell / 2, cell / 2, cell / 2, cell / 2, 3);\r\n },\r\n /** @param {Graphics} g */\r\n function (g, cell, index) {\r\n var m = cell * 0.25;\r\n g.addRectangle(0, 0, cell, cell);\r\n g.addRhombus(m, m, cell - m, cell - m, true);\r\n },\r\n /** @param {Graphics} g */\r\n function (g, cell, index) {\r\n var m = cell * 0.4, s = cell * 1.2;\r\n if (!index) {\r\n g.addCircle(m, m, s);\r\n }\r\n }\r\n ],\r\n \r\n outer: [\r\n /** @param {Graphics} g */\r\n function (g, cell, index) {\r\n g.addTriangle(0, 0, cell, cell, 0);\r\n },\r\n /** @param {Graphics} g */\r\n function (g, cell, index) {\r\n g.addTriangle(0, cell / 2, cell, cell / 2, 0);\r\n },\r\n /** @param {Graphics} g */\r\n function (g, cell, index) {\r\n g.addRhombus(0, 0, cell, cell);\r\n },\r\n /** @param {Graphics} g */\r\n function (g, cell, index) {\r\n var m = cell / 6;\r\n g.addCircle(m, m, cell - 2 * m);\r\n }\r\n ]\r\n};\r\n\r\n\r\n\r\n/**\r\n * Parses a substring of the hash as a number.\r\n * @param {number} startPosition \r\n * @param {number=} octets \r\n * @noinline\r\n */\r\nfunction parseHex(hash, startPosition, octets) {\r\n return parseInt(hash.substr(startPosition, octets), 16);\r\n}\r\n\r\n\r\n\r\n/**\r\n * Prepares a measure to be used as a measure in an SVG path, by\r\n * rounding the measure to a single decimal. This reduces the file\r\n * size of the generated SVG with more than 50% in some cases.\r\n */\r\nfunction svgValue(value) {\r\n return ((value * 10 + 0.5) | 0) / 10;\r\n}\r\n\r\n/**\r\n * Represents an SVG path element.\r\n * @private\r\n * @constructor\r\n */\r\nfunction SvgPath() {\r\n /**\r\n * This property holds the data string (path.d) of the SVG path.\r\n */\r\n this.dataString = \"\";\r\n}\r\nSvgPath.prototype = {\r\n /**\r\n * Adds a polygon with the current fill color to the SVG path.\r\n * @param points An array of Point objects.\r\n */\r\n addPolygon: function (points) {\r\n var dataString = \"M\" + svgValue(points[0].x) + \" \" + svgValue(points[0].y);\r\n for (var i = 1; i < points.length; i++) {\r\n dataString += \"L\" + svgValue(points[i].x) + \" \" + svgValue(points[i].y);\r\n }\r\n this.dataString += dataString + \"Z\";\r\n },\r\n /**\r\n * Adds a circle with the current fill color to the SVG path.\r\n * @param {Point} point The upper left corner of the circle bounding box.\r\n * @param {number} diameter The diameter of the circle.\r\n * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path).\r\n */\r\n addCircle: function (point, diameter, counterClockwise) {\r\n var sweepFlag = counterClockwise ? 0 : 1,\r\n svgRadius = svgValue(diameter / 2),\r\n svgDiameter = svgValue(diameter);\r\n \r\n this.dataString += \r\n \"M\" + svgValue(point.x) + \" \" + svgValue(point.y + diameter / 2) +\r\n \"a\" + svgRadius + \",\" + svgRadius + \" 0 1,\" + sweepFlag + \" \" + svgDiameter + \",0\" + \r\n \"a\" + svgRadius + \",\" + svgRadius + \" 0 1,\" + sweepFlag + \" \" + (-svgDiameter) + \",0\";\r\n }\r\n};\r\n\r\n\r\n\r\n\r\n/**\r\n * Renderer producing SVG output.\r\n * @private\r\n * @constructor\r\n * @param {SvgElement|SvgWriter} target \r\n */\r\nfunction SvgRenderer(target) {\r\n this._pathsByColor = { };\r\n this._target = target;\r\n this.size = target.size;\r\n}\r\nSvgRenderer.prototype = {\r\n /**\r\n * Fills the background with the specified color.\r\n * @param {string} fillColor Fill color on the format #rrggbb[aa].\r\n */\r\n setBackground: function (fillColor) {\r\n var match = /^(#......)(..)?/.exec(fillColor),\r\n opacity = match[2] ? parseHex(match[2], 0) / 255 : 1;\r\n this._target.setBackground(match[1], opacity);\r\n },\r\n /**\r\n * Marks the beginning of a new shape of the specified color. Should be ended with a call to endShape.\r\n * @param {string} color Fill color on format #xxxxxx.\r\n */\r\n beginShape: function (color) {\r\n this._path = this._pathsByColor[color] || (this._pathsByColor[color] = new SvgPath());\r\n },\r\n /**\r\n * Marks the end of the currently drawn shape.\r\n */\r\n endShape: function () { },\r\n /**\r\n * Adds a polygon with the current fill color to the SVG.\r\n * @param points An array of Point objects.\r\n */\r\n addPolygon: function (points) {\r\n this._path.addPolygon(points);\r\n },\r\n /**\r\n * Adds a circle with the current fill color to the SVG.\r\n * @param {Point} point The upper left corner of the circle bounding box.\r\n * @param {number} diameter The diameter of the circle.\r\n * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path).\r\n */\r\n addCircle: function (point, diameter, counterClockwise) {\r\n this._path.addCircle(point, diameter, counterClockwise);\r\n },\r\n /**\r\n * Called when the icon has been completely drawn.\r\n */\r\n finish: function () { \r\n for (var color in this._pathsByColor) {\r\n this._target.append(color, this._pathsByColor[color].dataString);\r\n }\r\n }\r\n};\r\n\r\n\r\n\r\n\r\n/**\r\n * Provides helper functions for rendering common basic shapes.\r\n * @private\r\n * @constructor\r\n */\r\nfunction Graphics(renderer) {\r\n this._renderer = renderer;\r\n this._transform = Transform.noTransform;\r\n}\r\nGraphics.prototype = {\r\n /**\r\n * Adds a polygon to the underlying renderer.\r\n * @param {Array} points The points of the polygon clockwise on the format [ x0, y0, x1, y1, ..., xn, yn ]\r\n * @param {boolean=} invert Specifies if the polygon will be inverted.\r\n */\r\n addPolygon: function (points, invert) {\r\n var di = invert ? -2 : 2, \r\n transform = this._transform,\r\n transformedPoints = [],\r\n i;\r\n \r\n for (i = invert ? points.length - 2 : 0; i < points.length && i >= 0; i += di) {\r\n transformedPoints.push(transform.transformPoint(points[i], points[i + 1]));\r\n }\r\n \r\n this._renderer.addPolygon(transformedPoints);\r\n },\r\n \r\n /**\r\n * Adds a polygon to the underlying renderer.\r\n * Source: http://stackoverflow.com/a/2173084\r\n * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the entire ellipse.\r\n * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the entire ellipse.\r\n * @param {number} size The size of the ellipse.\r\n * @param {boolean=} invert Specifies if the ellipse will be inverted.\r\n */\r\n addCircle: function (x, y, size, invert) {\r\n var p = this._transform.transformPoint(x, y, size, size);\r\n this._renderer.addCircle(p, size, invert);\r\n },\r\n\r\n /**\r\n * Adds a rectangle to the underlying renderer.\r\n * @param {number} x The x-coordinate of the upper left corner of the rectangle.\r\n * @param {number} y The y-coordinate of the upper left corner of the rectangle.\r\n * @param {number} w The width of the rectangle.\r\n * @param {number} h The height of the rectangle.\r\n * @param {boolean=} invert Specifies if the rectangle will be inverted.\r\n */\r\n addRectangle: function (x, y, w, h, invert) {\r\n this.addPolygon([\r\n x, y, \r\n x + w, y,\r\n x + w, y + h,\r\n x, y + h\r\n ], invert);\r\n },\r\n\r\n /**\r\n * Adds a right triangle to the underlying renderer.\r\n * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the triangle.\r\n * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the triangle.\r\n * @param {number} w The width of the triangle.\r\n * @param {number} h The height of the triangle.\r\n * @param {number} r The rotation of the triangle (clockwise). 0 = right corner of the triangle in the lower left corner of the bounding rectangle.\r\n * @param {boolean=} invert Specifies if the triangle will be inverted.\r\n */\r\n addTriangle: function (x, y, w, h, r, invert) {\r\n var points = [\r\n x + w, y, \r\n x + w, y + h, \r\n x, y + h,\r\n x, y\r\n ];\r\n points.splice(((r || 0) % 4) * 2, 2);\r\n this.addPolygon(points, invert);\r\n },\r\n\r\n /**\r\n * Adds a rhombus to the underlying renderer.\r\n * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the rhombus.\r\n * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the rhombus.\r\n * @param {number} w The width of the rhombus.\r\n * @param {number} h The height of the rhombus.\r\n * @param {boolean=} invert Specifies if the rhombus will be inverted.\r\n */\r\n addRhombus: function (x, y, w, h, invert) {\r\n this.addPolygon([\r\n x + w / 2, y,\r\n x + w, y + h / 2,\r\n x + w / 2, y + h,\r\n x, y + h / 2\r\n ], invert);\r\n }\r\n};\r\n\r\n\r\n\r\n\r\n/**\r\n * Gets a set of identicon color candidates for a specified hue and config.\r\n */\r\nfunction colorTheme(hue, config) {\r\n hue = config.hue(hue);\r\n return [\r\n // Dark gray\r\n color.correctedHsl(hue, config.grayscaleSaturation, config.grayscaleLightness(0)),\r\n // Mid color\r\n color.correctedHsl(hue, config.colorSaturation, config.colorLightness(0.5)),\r\n // Light gray\r\n color.correctedHsl(hue, config.grayscaleSaturation, config.grayscaleLightness(1)),\r\n // Light color\r\n color.correctedHsl(hue, config.colorSaturation, config.colorLightness(1)),\r\n // Dark color\r\n color.correctedHsl(hue, config.colorSaturation, config.colorLightness(0))\r\n ];\r\n}\r\n\r\n\r\n\r\n/**\r\n * Represents a point.\r\n * @private\r\n * @constructor\r\n */\r\nfunction Point(x, y) {\r\n this.x = x;\r\n this.y = y;\r\n};\r\n\r\n\r\n\r\n\r\n/**\r\n * Translates and rotates a point before being passed on to the canvas context. This was previously done by the canvas context itself, \r\n * but this caused a rendering issue in Chrome on sizes > 256 where the rotation transformation of inverted paths was not done properly.\r\n * @param {number} x The x-coordinate of the upper left corner of the transformed rectangle.\r\n * @param {number} y The y-coordinate of the upper left corner of the transformed rectangle.\r\n * @param {number} size The size of the transformed rectangle.\r\n * @param {number} rotation Rotation specified as 0 = 0 rad, 1 = 0.5π rad, 2 = π rad, 3 = 1.5π rad\r\n * @private\r\n * @constructor\r\n */\r\nfunction Transform(x, y, size, rotation) {\r\n this._x = x;\r\n this._y = y;\r\n this._size = size;\r\n this._rotation = rotation;\r\n}\r\nTransform.prototype = {\r\n /**\r\n * Transforms the specified point based on the translation and rotation specification for this Transform.\r\n * @param {number} x x-coordinate\r\n * @param {number} y y-coordinate\r\n * @param {number=} w The width of the transformed rectangle. If greater than 0, this will ensure the returned point is of the upper left corner of the transformed rectangle.\r\n * @param {number=} h The height of the transformed rectangle. If greater than 0, this will ensure the returned point is of the upper left corner of the transformed rectangle.\r\n */\r\n transformPoint: function (x, y, w, h) {\r\n var right = this._x + this._size,\r\n bottom = this._y + this._size;\r\n return this._rotation === 1 ? new Point(right - y - (h || 0), this._y + x) :\r\n this._rotation === 2 ? new Point(right - x - (w || 0), bottom - y - (h || 0)) :\r\n this._rotation === 3 ? new Point(this._x + y, bottom - x - (w || 0)) :\r\n new Point(this._x + x, this._y + y);\r\n }\r\n};\r\nTransform.noTransform = new Transform(0, 0, 0, 0);\r\n\r\n\r\n\r\n \r\n/**\r\n * Draws an identicon to a specified renderer.\r\n */\r\nfunction iconGenerator(renderer, hash, x, y, size, padding, config) {\r\n var undefined;\r\n \r\n // Set background color\r\n if (config.backColor) {\r\n renderer.setBackground(config.backColor);\r\n }\r\n \r\n // Calculate padding and round to nearest integer\r\n padding = (0.5 + size * (padding === undefined ? 0.08 : padding)) | 0;\r\n size -= padding * 2;\r\n \r\n var graphics = new Graphics(renderer);\r\n \r\n // Calculate cell size and ensure it is an integer\r\n var cell = 0 | (size / 4);\r\n \r\n // Since the cell size is integer based, the actual icon will be slightly smaller than specified => center icon\r\n x += 0 | (padding + size / 2 - cell * 2);\r\n y += 0 | (padding + size / 2 - cell * 2);\r\n\r\n function renderShape(colorIndex, shapes, index, rotationIndex, positions) {\r\n var r = rotationIndex ? parseHex(hash, rotationIndex, 1) : 0,\r\n shape = shapes[parseHex(hash, index, 1) % shapes.length],\r\n i;\r\n \r\n renderer.beginShape(availableColors[selectedColorIndexes[colorIndex]]);\r\n \r\n for (i = 0; i < positions.length; i++) {\r\n graphics._transform = new Transform(x + positions[i][0] * cell, y + positions[i][1] * cell, cell, r++ % 4);\r\n shape(graphics, cell, i);\r\n }\r\n \r\n renderer.endShape();\r\n }\r\n\r\n // AVAILABLE COLORS\r\n var hue = parseHex(hash, -7) / 0xfffffff,\r\n \r\n // Available colors for this icon\r\n availableColors = colorTheme(hue, config),\r\n\r\n // The index of the selected colors\r\n selectedColorIndexes = [],\r\n index;\r\n\r\n function isDuplicate(values) {\r\n if (values.indexOf(index) >= 0) {\r\n for (var i = 0; i < values.length; i++) {\r\n if (selectedColorIndexes.indexOf(values[i]) >= 0) {\r\n return true;\r\n }\r\n }\r\n }\r\n }\r\n\r\n for (var i = 0; i < 3; i++) {\r\n index = parseHex(hash, 8 + i, 1) % availableColors.length;\r\n if (isDuplicate([0, 4]) || // Disallow dark gray and dark color combo\r\n isDuplicate([2, 3])) { // Disallow light gray and light color combo\r\n index = 1;\r\n }\r\n selectedColorIndexes.push(index);\r\n }\r\n\r\n // ACTUAL RENDERING\r\n // Sides\r\n renderShape(0, shapes.outer, 2, 3, [[1, 0], [2, 0], [2, 3], [1, 3], [0, 1], [3, 1], [3, 2], [0, 2]]);\r\n // Corners\r\n renderShape(1, shapes.outer, 4, 5, [[0, 0], [3, 0], [3, 3], [0, 3]]);\r\n // Center\r\n renderShape(2, shapes.center, 1, null, [[1, 1], [2, 1], [2, 2], [1, 2]]);\r\n \r\n renderer.finish();\r\n};\r\n\r\n\r\n\r\n \r\n\r\n\r\n/**\r\n * Gets the normalized current Jdenticon color configuration. Missing fields have default values.\r\n */\r\nfunction getCurrentConfig() {\r\n var configObject = jdenticon[\"config\"] || global[\"jdenticon_config\"] || { },\r\n lightnessConfig = configObject[\"lightness\"] || { },\r\n \r\n // In versions < 2.1.0 there was no grayscale saturation -\r\n // saturation was the color saturation.\r\n saturation = configObject[\"saturation\"] || { },\r\n colorSaturation = \"color\" in saturation ? saturation[\"color\"] : saturation,\r\n grayscaleSaturation = saturation[\"grayscale\"],\r\n\r\n backColor = configObject[\"backColor\"];\r\n \r\n /**\r\n * Creates a lightness range.\r\n */\r\n function lightness(configName, defaultRange) {\r\n var range = lightnessConfig[configName];\r\n \r\n // Check if the lightness range is an array-like object. This way we ensure the\r\n // array contain two values at the same time.\r\n if (!(range && range.length > 1)) {\r\n range = defaultRange;\r\n }\r\n\r\n /**\r\n * Gets a lightness relative the specified value in the specified lightness range.\r\n */\r\n return function (value) {\r\n value = range[0] + value * (range[1] - range[0]);\r\n return value < 0 ? 0 : value > 1 ? 1 : value;\r\n };\r\n }\r\n\r\n /**\r\n * Gets a hue allowed by the configured hue restriction,\r\n * provided the originally computed hue.\r\n */\r\n function hueFunction(originalHue) {\r\n var hueConfig = configObject[\"hues\"], hue;\r\n \r\n // Check if 'hues' is an array-like object. This way we also ensure that\r\n // the array is not empty, which would mean no hue restriction.\r\n if (hueConfig && hueConfig.length > 0) {\r\n // originalHue is in the range [0, 1]\r\n // Multiply with 0.999 to change the range to [0, 1) and then truncate the index.\r\n hue = hueConfig[0 | (0.999 * originalHue * hueConfig.length)];\r\n }\r\n\r\n return typeof hue == \"number\" ?\r\n \r\n // A hue was specified. We need to convert the hue from\r\n // degrees on any turn - e.g. 746° is a perfectly valid hue -\r\n // to turns in the range [0, 1).\r\n ((((hue / 360) % 1) + 1) % 1) :\r\n\r\n // No hue configured => use original hue\r\n originalHue;\r\n }\r\n \r\n return {\r\n hue: hueFunction,\r\n colorSaturation: typeof colorSaturation == \"number\" ? colorSaturation : 0.5,\r\n grayscaleSaturation: typeof grayscaleSaturation == \"number\" ? grayscaleSaturation : 0,\r\n colorLightness: lightness(\"color\", [0.4, 0.8]),\r\n grayscaleLightness: lightness(\"grayscale\", [0.3, 0.9]),\r\n backColor: color.parse(backColor)\r\n }\r\n}\r\n\r\n/**\r\n * Inputs a value that might be a valid hash string for Jdenticon and returns it \r\n * if it is determined valid, otherwise a falsy value is returned.\r\n */\r\nfunction getValidHash(hashCandidate) {\r\n return /^[0-9a-f]{11,}$/i.test(hashCandidate) && hashCandidate;\r\n}\r\n\r\n/**\r\n * Computes a hash for the specified value. Currnently SHA1 is used. This function\r\n * always returns a valid hash.\r\n */\r\nfunction computeHash(value) {\r\n return sha1(value == null ? \"\" : \"\" + value);\r\n}\r\n\r\n/**\r\n * Updates the identicon in the specified canvas or svg elements.\r\n * @param {(string|Element)} el - Specifies the container in which the icon is rendered. Can be a CSS selector or a DOM element of the type SVG or CANVAS.\r\n * @param {string=} hash - Optional hash to be rendered. If not specified, the hash specified by the data-jdenticon-hash is used.\r\n * @param {number=} padding - Optional padding in percents. Extra padding might be added to center the rendered identicon.\r\n */\r\nfunction update(el, hash, padding) {\r\n if (typeof(el) === \"string\") {\r\n if (dom.supportsQuerySelectorAll) {\r\n var elements = document.querySelectorAll(el);\r\n for (var i = 0; i < elements.length; i++) {\r\n update(elements[i], hash, padding);\r\n }\r\n }\r\n return;\r\n }\r\n\r\n var iconType = dom.getIdenticonType(el);\r\n if (!iconType) {\r\n return;\r\n }\r\n \r\n // Hash selection. The result from getValidHash or computeHash is \r\n // accepted as a valid hash.\r\n hash = \r\n // 1. Explicit valid hash\r\n getValidHash(hash) ||\r\n \r\n // 2. Explicit value (`!= null` catches both null and undefined)\r\n hash != null && computeHash(hash) ||\r\n \r\n // 3. `data-jdenticon-hash` attribute\r\n getValidHash(el.getAttribute(dom.HASH_ATTRIBUTE)) ||\r\n \r\n // 4. `data-jdenticon-value` attribute. \r\n // We want to treat an empty attribute as an empty value. \r\n // Some browsers return empty string even if the attribute \r\n // is not specified, so use hasAttribute to determine if \r\n // the attribute is specified.\r\n el.hasAttribute(dom.VALUE_ATTRIBUTE) && computeHash(el.getAttribute(dom.VALUE_ATTRIBUTE));\r\n \r\n if (!hash) {\r\n // No hash specified. Don't render an icon.\r\n return;\r\n }\r\n \r\n var renderer = iconType == dom.ICON_TYPE_SVG ? \r\n new SvgRenderer(new SvgElement(el)) : \r\n new CanvasRenderer(el.getContext(\"2d\"));\r\n \r\n // Draw icon\r\n iconGenerator(renderer, hash, 0, 0, renderer.size, padding, getCurrentConfig());\r\n}\r\n\r\n/**\r\n * Draws an identicon to a context.\r\n * @param {CanvasRenderingContext2D} ctx - Canvas context on which the icon will be drawn at location (0, 0).\r\n * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon.\r\n * @param {number} size - Icon size in pixels.\r\n */\r\nfunction drawIcon(ctx, hashOrValue, size, padding) {\r\n if (!ctx) {\r\n throw new Error(\"No canvas specified.\");\r\n }\r\n \r\n var renderer = new CanvasRenderer(ctx, size);\r\n iconGenerator(renderer, \r\n getValidHash(hashOrValue) || computeHash(hashOrValue), \r\n 0, 0, size, padding || 0, getCurrentConfig());\r\n}\r\n\r\n/**\r\n * Draws an identicon as an SVG string.\r\n * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon.\r\n * @param {number} size - Icon size in pixels.\r\n * @param {number=} padding - Optional padding in percents. Extra padding might be added to center the rendered identicon.\r\n * @returns {string} SVG string\r\n */\r\nfunction toSvg(hashOrValue, size, padding) {\r\n var writer = new SvgWriter(size);\r\n var renderer = new SvgRenderer(writer);\r\n iconGenerator(renderer, \r\n getValidHash(hashOrValue) || computeHash(hashOrValue),\r\n 0, 0, size, padding, getCurrentConfig());\r\n return writer.toString();\r\n}\r\n\r\n/**\r\n * Updates all canvas elements with the data-jdenticon-hash attribute.\r\n */\r\nfunction jdenticon() {\r\n if (dom.supportsQuerySelectorAll) {\r\n update(dom.ICON_SELECTOR);\r\n }\r\n}\r\n\r\n/**\r\n * This function is called once upon page load.\r\n */\r\nfunction jdenticonStartup() {\r\n var replaceMode = (jdenticon[\"config\"] || global[\"jdenticon_config\"] || { })[\"replaceMode\"];\r\n if (replaceMode != \"never\") {\r\n jdenticon();\r\n \r\n if (replaceMode == \"observe\") {\r\n observer(update);\r\n }\r\n }\r\n}\r\n\r\n// Public API\r\njdenticon[\"drawIcon\"] = drawIcon;\r\njdenticon[\"toSvg\"] = toSvg;\r\njdenticon[\"update\"] = update;\r\njdenticon[\"version\"] = \"2.1.1\";\r\n\r\n// Basic jQuery plugin\r\nif (jQuery) {\r\n jQuery[\"fn\"][\"jdenticon\"] = function (hashOrValue, padding) {\r\n this[\"each\"](function (index, el) {\r\n update(el, hashOrValue, padding);\r\n });\r\n return this;\r\n };\r\n}\r\n\r\n// Schedule to render all identicons on the page once it has been loaded.\r\nif (typeof setTimeout === \"function\") {\r\n setTimeout(jdenticonStartup, 0);\r\n}\r\n\r\n\r\n\r\n\r\n return jdenticon;\r\n});"]} \ No newline at end of file diff --git a/package.json b/package.json index a542410..1838102 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jdenticon", - "version": "2.1.0", + "version": "2.1.1", "description": "Javascript identicon generator", "main": "index.js", "browser": "dist/jdenticon.min.js",