tag:blogger.com,1999:blog-65069986269894465942024-03-12T04:53:46.325+00:00This, that and the other (ramblings of Dominic Myers)Dominic Myers writes about all sorts of stuff to do with HTML, CSS, JavaScript and a fair chunk of self-indulgent stuff. Thoughts and opinions are all his own, and nothing to do with any employer.DominicMyershttp://www.blogger.com/profile/15530669398436940737noreply@blogger.comBlogger545125tag:blogger.com,1999:blog-6506998626989446594.post-83667419221837345742023-07-15T06:09:00.003+01:002023-07-15T06:09:37.505+01:00<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsCkSaGygFjwaLmathn5MLix4j401CjAVLJ1N34zwkBTZV1e_3DKRuMPLtOMH2yP0fBonFl1X5YDn-qS40Zn048XDRqXOaMRMfGSZ8Pab9uz_BEWaibrExRWLFyfW95ZEJVQ3LADF5luK7TeKfa0VdRAJ5gkhN-p2v1R9VxeSTYTOUScAPuFn2ZmpkA0mY/s5184/topless_man_standing_near_wall-scopio-772b7187-cc22-41df-a8ed-e6407dd8968e.jpg" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="400" data-original-height="3456" data-original-width="5184" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsCkSaGygFjwaLmathn5MLix4j401CjAVLJ1N34zwkBTZV1e_3DKRuMPLtOMH2yP0fBonFl1X5YDn-qS40Zn048XDRqXOaMRMfGSZ8Pab9uz_BEWaibrExRWLFyfW95ZEJVQ3LADF5luK7TeKfa0VdRAJ5gkhN-p2v1R9VxeSTYTOUScAPuFn2ZmpkA0mY/s400/topless_man_standing_near_wall-scopio-772b7187-cc22-41df-a8ed-e6407dd8968e.jpg"/></a></div>
<label style="display:flex; justify-content: start; align-items: center; font-family: Barlow">
<a style="display:flex; align-items: center" href="https://scop.io">
<img height="20x" src="//cdn.shopify.com/s/files/1/2395/7099/files/Scopio_logo_Color_dark_140x.png?v=1604343350" style="margin: 0px 10px 0px 0px">
</a>
By
<a style="text-decoration: none; margin: 0px 5px;" href="https://artist.scop.io/luis-berra-8ce0799b">Luis Berra</a>
</label>
<p>I’ve recently been updating a website and trying to implement a data of birth field; what do you think is the best input type for such a field?</p>
<span style='color:#a65700; '><</span><span style='color:#800000; font-weight:bold; '>input</span><span style='color:#274796; '> </span><span style='color:#074726; '>type</span><span style='color:#808030; '>=</span><span style='color:#0000e6; '>"date"</span><span style='color:#274796; '> </span><span style='color:#074726; '>id</span><span style='color:#808030; '>=</span><span style='color:#0000e6; '>"dob"</span><span style='color:#274796; '> </span><span style='color:#074726; '>name</span><span style='color:#808030; '>=</span><span style='color:#0000e6; '>"dob"</span><span style='color:#274796; '> </span><span style='color:#a65700; '>/></span>
<p>I thought a date type input would be best, but then I tried entering the date of birth of a lady joining the club on my phone, and I gave up! I asked her to email it to me as it was getting embarrassing scrolling through all the months to the 1970s – see, she wasn’t even as old as me, and I thought about how annoying it is to have to scroll to enter my date of birth!</p>
<p>At least on Android, you must swipe through each month in each year, going back in time to that halcyon time when you were first spawned. 50 years of 12 months are 600 swipes through your history, and let me tell you, that gets depressing fast!</p>
<p>Anyway, I thought about how it’s managed elsewhere and found that the UK Government’s implementation (also used by the NHS) and the GOV.UK Design System has a lovely mechanism for date inputs with three separate fields (one for the day, one for the month and one for the year). It’s located <a href="https://design-system.service.gov.uk/components/date-input/" target="_blank">here</a>, but the page tends to break. The <a href="https://service-manual.nhs.uk/design-system/components/date-input" target="_blank">NHSs version</a> doesn’t break, though – and they acknowledge its ancestry.</p>
<p>As a fan of web components, I thought I’d implement the same thing, add it to our website, and allow others to take advantage of it as well. I built-in date validation using the native date object rather than <a href="https://momentjs.com" target="_blank">Moment.js</a> or <a href="https://date-fns.org" target="_blank">date-fns</a>, as I’ve played before with using dropdown fields to enter the values in a Vue component in the dim and distant past – that was fun though as the dropdown values would only allow valid options to be selected. In that component, you could only choose leap years if you had selected the 29th of February, for instance.</p>
<p>What I was particularly pleased about was the ability to add native form validation, which is something I’ve never tried before but was quite easy to implement. I’ve utilised significant manual testing and asked a mate to do some Selenium testing – but unit testing within web components seems to be something of a dark art, especially if not using a framework to create the component – and why would you use a framework if you’re avoiding frameworks and writing native web components?</p>
<p>There’s a <a href="https://codepen.io/annoyingmouse/pen/BaGzPdv" target="_blank">CODEPEN</a> to play with here, and it’s on <a href="https://www.npmjs.com/package/@annoyingmouse/wc-date-input" target="_blank">npm</a> so that you can play with it too – if you spot anything, <a href="https://github.com/annoyingmouse/wc-date-input/issues" target="_blank">please let me know</a>; hey, tell me your thoughts anyway! I’ve used it within a React application, and it also seems to work well there.</p>
DominicMyershttp://www.blogger.com/profile/15530669398436940737noreply@blogger.com0tag:blogger.com,1999:blog-6506998626989446594.post-71158694703740233582023-02-11T11:08:00.002+00:002023-02-11T11:08:17.494+00:00GitHub Contributions since 2011<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUeYqwOkEZKYCP8Uu2-LQJ26-ZB2olP8n-sD_0gRMDB5D-b8YD0ScDFMA7KlsBTqcQ8wlDo7F501TPP97nISWtars8BNDyBXsfjM99nBoiHC4v3DqED91Sl2F_BC6LyANYwQPtzDGocMveMx1QZZ3X4JH96EhLV7XIPETiYfjmsAeHbDOen3zMsL94yA/s896/GitHub_Contributions.gif" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="400" data-original-height="176" data-original-width="896" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUeYqwOkEZKYCP8Uu2-LQJ26-ZB2olP8n-sD_0gRMDB5D-b8YD0ScDFMA7KlsBTqcQ8wlDo7F501TPP97nISWtars8BNDyBXsfjM99nBoiHC4v3DqED91Sl2F_BC6LyANYwQPtzDGocMveMx1QZZ3X4JH96EhLV7XIPETiYfjmsAeHbDOen3zMsL94yA/s400/GitHub_Contributions.gif"/></a></div>DominicMyershttp://www.blogger.com/profile/15530669398436940737noreply@blogger.com0tag:blogger.com,1999:blog-6506998626989446594.post-26892390807337991222023-01-27T14:13:00.001+00:002023-01-27T14:13:18.962+00:00Smart meter? Snitch meter!<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpMSqKNBQuWJ6mVdQ7PHxLb9VgXe_HlYDDL7mhzNohAGun9HXXKNukJpVoWPHT3c-FeuKI9lTLsCfQKMXN0xFfv_2lYhxHCnJJdoneTNq2mEPbPi4w1ztLMEFARrgFct5pLSixvMC9nBtyMzKW3xRyVpENw8atSlw-0EtGU9zzQXWJpPmwo-3veWr3QQ/s2736/woman_in_orange_tank_top_sitting_on_orange_chair-scopio-f16c73b2-bd3f-4b5d-bb38-c3659382ef8a.jpg" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="400" data-original-height="1824" data-original-width="2736" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpMSqKNBQuWJ6mVdQ7PHxLb9VgXe_HlYDDL7mhzNohAGun9HXXKNukJpVoWPHT3c-FeuKI9lTLsCfQKMXN0xFfv_2lYhxHCnJJdoneTNq2mEPbPi4w1ztLMEFARrgFct5pLSixvMC9nBtyMzKW3xRyVpENw8atSlw-0EtGU9zzQXWJpPmwo-3veWr3QQ/s400/woman_in_orange_tank_top_sitting_on_orange_chair-scopio-f16c73b2-bd3f-4b5d-bb38-c3659382ef8a.jpg"/></a></div>
<label style="display:flex; justify-content: start; align-items: center; font-family: Barlow">
<a style="display:flex; align-items: center" href="https://scop.io">
<img height="20x" src="//cdn.shopify.com/s/files/1/2395/7099/files/Scopio_logo_Color_dark_140x.png?v=1604343350" style="margin: 0px 10px 0px 0px">
</a>
By
<a style="text-decoration: none; margin: 0px 5px;" href="https://scop.io/collections/vendors?q=Jorge%20Antonio%20Flores%20Delgado">Jorge Antonio Flores Delgado</a>
</label>
<p>Last night I was woken by a thought - well, that's not correct; I was mainly woken by pins and needles caused by the dog sleeping on my feet! As I wriggled my toes and tried to get the blood flowing again (while ignoring the growls from the dog), I was struck by the thought of energy prices and how they were likely to fall. Wholesale energy prices are falling - some would say plummetting - so I'm guessing that <abbr title="Office of Gas and Electricity Markets">OFGEM</abbr> will lower the cap sooner rather than later.</p>
<p>Alongside the appreciation that the currently dire situation is likely to change, I remembered something mentioned when I was studying. An old professor asked us to consider how much of our utility bill comprised the cost of the mechanisms employed by calculating our bill. He mentioned that once telephone lines are installed, the outgoings for telephony companies are maintenance and installation of new lines and staff. As such, everything but a small portion of our bills was free and clear profit after paying off the initial investment in infrastructure. He suggested that roughly half of the phone bill was to cover the generation of the bills themselves: the recording of call duration and destination and the postage of those bills to us. Of course, I'm guessing that's changed in these times of online accounts, with that portion of the bill significantly reduced. Have these efficiencies made their way to us as decreasing bills?</p>
<p>I'm reminded of the boon that social media is to the intelligence services - instead of dedicating personnel to track our movements; we do it ourselves.</p>
<p>This reduction was probably the same for the other utilities, such as gas or electricity (let's pop them under the umbrella of energy utilities). I am trying to remember the last time we had any of our meters read - but it was certainly a fair few years ago - thus, the staffing costs have been reduced. This reduction in the number of meter readers has been thanks to smart meters and consumers providing their own readings.</p>
<p>But that's odd, isn't it? Instead of someone coming each quarter to check how much energy has been used in a property and a bill generated from that figure, we now provide that data monthly - or more frequently when we have a smart meter. Now we can tell how much energy we've used and be charged the going rate for that energy at that particular time. December is cold, and the energy price rises; we'll pay more. January is even colder, but energy prices have dropped - do we pay less...? The delay in OFGEM dropping their cap means that we don't - though the utility companies are paying less for the energy they provide.</p>
<p>So what to do? I'm pondering how well I should report my energy consumption. If the cap is high - is it better to report reduced usage as a consumer that provides their readings...? When the cap is lower, I can give increased figures to get me back up to the actual amount. Presumably, that would be far better than relying on the estimated figures used by energy companies - at least for me as a consumer. It does smack of being a gamble, though; who is to say when prices will fall?</p>
DominicMyershttp://www.blogger.com/profile/15530669398436940737noreply@blogger.com0tag:blogger.com,1999:blog-6506998626989446594.post-39356124097931146672023-01-13T09:23:00.004+00:002023-01-25T13:26:56.742+00:00TopTracker total hours snippet<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyauDpQqjwyZgfJQCN0d3txi4ZK3DJfFaVkSPnfDOdpa_w6QuADoNj3I8a38M6ZY8ClivE1ynb4hmdbQK0qYQ6Usl0vL07vMRuNrkmz-ATr0lDZUUKx4qt2ueT5DlXPzr8L9lQ3UWlBZOACwbazW_IIEg1ruGOyH5alMjRjRAUfpvQO9d4f0N8__088w/s5760/brown_wooden_round_analog_clock-scopio-2ab14475-7f69-4adf-b40f-ac0414f3ef29.jpg" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="400" data-original-height="3840" data-original-width="5760" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyauDpQqjwyZgfJQCN0d3txi4ZK3DJfFaVkSPnfDOdpa_w6QuADoNj3I8a38M6ZY8ClivE1ynb4hmdbQK0qYQ6Usl0vL07vMRuNrkmz-ATr0lDZUUKx4qt2ueT5DlXPzr8L9lQ3UWlBZOACwbazW_IIEg1ruGOyH5alMjRjRAUfpvQO9d4f0N8__088w/s400/brown_wooden_round_analog_clock-scopio-2ab14475-7f69-4adf-b40f-ac0414f3ef29.jpg"/></a></div>
<label style="display:flex; justify-content: start; align-items: center; font-family: Barlow">
<a style="display:flex; align-items: center" href="https://scop.io">
<img height="20x" src="//cdn.shopify.com/s/files/1/2395/7099/files/Scopio_logo_Color_dark_140x.png?v=1604343350" style="margin: 0px 10px 0px 0px">
</a>
By
<a style="text-decoration: none; margin: 0px 5px;" href="https://scop.io/collections/vendors?q=Maksim%20Chernyshev">Maksim Chernyshev</a>
</label>
<p>I've been using TopTracker for years to keep track of my hours worked. I've recently clocked that I end up firing up a calculator to check how many hours I've worked for a given week; this seemed a little bit silly, TBH, so this morning I created a quick <a href="https://developer.chrome.com/docs/devtools/javascript/snippets/">snippet</a>. 5 minutes work now, to save lots of work later seems like a fair trade:</p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1yEIvkv6u3LqHybHAGpmSt04RC3j8QHX8Lu74iqvZjkK2v6c2kkcnPQflcGVGSXiEL85E52w21ivC7lQ-rUtDsN-uC4dhCShD4IFgNrMce-GUbIxifhvpb0CfYBb91SmqXv4lDKGwBba7vu98PKNWfwFiqm-S9z4SM-IQpfWSAQPJ3XAMrtcjdB5PcA/s980/screenshot.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="400" data-original-height="304" data-original-width="980" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1yEIvkv6u3LqHybHAGpmSt04RC3j8QHX8Lu74iqvZjkK2v6c2kkcnPQflcGVGSXiEL85E52w21ivC7lQ-rUtDsN-uC4dhCShD4IFgNrMce-GUbIxifhvpb0CfYBb91SmqXv4lDKGwBba7vu98PKNWfwFiqm-S9z4SM-IQpfWSAQPJ3XAMrtcjdB5PcA/s400/screenshot.png"/></a></div>DominicMyershttp://www.blogger.com/profile/15530669398436940737noreply@blogger.com0tag:blogger.com,1999:blog-6506998626989446594.post-20842477430670650682022-12-01T07:28:00.038+00:002022-12-24T09:18:54.614+00:00Scrimba's JavaScriptmas and Advent of Code 2022<h2>Day 1</h2>
<h3>JavaScriptmas</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">const</span> panic <span style="color: #333333">=</span> str <span style="color: #333333">=></span> <span style="color: #FF0000; background-color: #FFAAAA">`</span>${str.toUpperCase().split(<span style="background-color: #fff0f0">' '</span>).join(<span style="background-color: #fff0f0">' 😱 '</span>)}<span style="color: #333333">!</span><span style="color: #FF0000; background-color: #FFAAAA">`</span>
console.log(panic(<span style="background-color: #fff0f0">"I'm almost out of coffee"</span>))
console.log(panic(<span style="background-color: #fff0f0">"winter is coming"</span>))
</pre></div>
<h3>Advent of Code</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">const</span> elves <span style="color: #333333">=</span> input.split(<span style="background-color: #fff0f0">'\n\n'</span>).map(e <span style="color: #333333">=></span> <span style="color: #007020">Number</span>(e.split(<span style="background-color: #fff0f0">'\n'</span>).reduce((a, c) <span style="color: #333333">=></span> <span style="color: #007020">Number</span>(a) <span style="color: #333333">+</span> <span style="color: #007020">Number</span>(c))))
console.log(<span style="color: #007020">Math</span>.max(...elves))
elves.sort((a, b) <span style="color: #333333">=></span> b <span style="color: #333333">-</span> a)
console.log(elves.slice(<span style="color: #0000DD; font-weight: bold">0</span>, <span style="color: #0000DD; font-weight: bold">3</span>).reduce((a, c) <span style="color: #333333">=></span> a <span style="color: #333333">+</span> c))
</pre></div>
<h2>Day 2</h2>
<h3>JavaScriptmas</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">const</span> transformData <span style="color: #333333">=</span> d <span style="color: #333333">=></span> d.map(e <span style="color: #333333">=></span> ({
fullName<span style="color: #333333">:</span> <span style="color: #FF0000; background-color: #FFAAAA">`</span>${e.name.first} ${e.name.last}<span style="color: #FF0000; background-color: #FFAAAA">`</span>,
birthday<span style="color: #333333">:</span> <span style="color: #008800; font-weight: bold">new</span> <span style="color: #007020">Date</span>(e.dob.date).toDateString()
}))
</pre></div>
<h3>Advent of Code</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #888888">/**</span>
<span style="color: #888888"> * Rock: A, X. Worth: 1. Beats: Scissors</span>
<span style="color: #888888"> * Paper: B, Y. Worth: 2. Beats: Rock</span>
<span style="color: #888888"> * Scissors: C, Z. Worth: 3. Beats: Paper</span>
<span style="color: #888888"> * 0 if you lost,</span>
<span style="color: #888888"> * 3 if the round was a draw</span>
<span style="color: #888888"> * and 6 if you won</span>
<span style="color: #888888"> */</span>
console.log(input.split(<span style="background-color: #fff0f0">'\n'</span>).reduce((a, c) <span style="color: #333333">=></span> {
<span style="color: #008800; font-weight: bold">const</span> [them, me] <span style="color: #333333">=</span> c.split(<span style="background-color: #fff0f0">' '</span>)
<span style="color: #008800; font-weight: bold">if</span>(them <span style="color: #333333">===</span> <span style="background-color: #fff0f0">'A'</span>){
<span style="color: #008800; font-weight: bold">if</span>(me <span style="color: #333333">===</span> <span style="background-color: #fff0f0">'X'</span>){
a <span style="color: #333333">+=</span> <span style="color: #0000DD; font-weight: bold">3</span> <span style="color: #333333">+</span> <span style="color: #0000DD; font-weight: bold">1</span>
}
<span style="color: #008800; font-weight: bold">if</span>(me <span style="color: #333333">===</span> <span style="background-color: #fff0f0">'Y'</span>){
a <span style="color: #333333">+=</span> <span style="color: #0000DD; font-weight: bold">6</span> <span style="color: #333333">+</span> <span style="color: #0000DD; font-weight: bold">2</span>
}
<span style="color: #008800; font-weight: bold">if</span>(me <span style="color: #333333">===</span> <span style="background-color: #fff0f0">'Z'</span>){
a <span style="color: #333333">+=</span> <span style="color: #0000DD; font-weight: bold">0</span> <span style="color: #333333">+</span> <span style="color: #0000DD; font-weight: bold">3</span>
}
}
<span style="color: #008800; font-weight: bold">if</span>(them <span style="color: #333333">===</span> <span style="background-color: #fff0f0">'B'</span>){
<span style="color: #008800; font-weight: bold">if</span>(me <span style="color: #333333">===</span> <span style="background-color: #fff0f0">'X'</span>){
a <span style="color: #333333">+=</span> <span style="color: #0000DD; font-weight: bold">0</span> <span style="color: #333333">+</span> <span style="color: #0000DD; font-weight: bold">1</span>
}
<span style="color: #008800; font-weight: bold">if</span>(me <span style="color: #333333">===</span> <span style="background-color: #fff0f0">'Y'</span>){
a <span style="color: #333333">+=</span> <span style="color: #0000DD; font-weight: bold">3</span> <span style="color: #333333">+</span> <span style="color: #0000DD; font-weight: bold">2</span>
}
<span style="color: #008800; font-weight: bold">if</span>(me <span style="color: #333333">===</span> <span style="background-color: #fff0f0">'Z'</span>){
a <span style="color: #333333">+=</span> <span style="color: #0000DD; font-weight: bold">6</span> <span style="color: #333333">+</span> <span style="color: #0000DD; font-weight: bold">3</span>
}
}
<span style="color: #008800; font-weight: bold">if</span>(them <span style="color: #333333">===</span> <span style="background-color: #fff0f0">'C'</span>){
<span style="color: #008800; font-weight: bold">if</span>(me <span style="color: #333333">===</span> <span style="background-color: #fff0f0">'X'</span>){
a <span style="color: #333333">+=</span> <span style="color: #0000DD; font-weight: bold">6</span> <span style="color: #333333">+</span> <span style="color: #0000DD; font-weight: bold">1</span>
}
<span style="color: #008800; font-weight: bold">if</span>(me <span style="color: #333333">===</span> <span style="background-color: #fff0f0">'Y'</span>){
a <span style="color: #333333">+=</span> <span style="color: #0000DD; font-weight: bold">0</span> <span style="color: #333333">+</span> <span style="color: #0000DD; font-weight: bold">2</span>
}
<span style="color: #008800; font-weight: bold">if</span>(me <span style="color: #333333">===</span> <span style="background-color: #fff0f0">'Z'</span>){
a <span style="color: #333333">+=</span> <span style="color: #0000DD; font-weight: bold">3</span> <span style="color: #333333">+</span> <span style="color: #0000DD; font-weight: bold">3</span>
}
}
<span style="color: #008800; font-weight: bold">return</span> a
}, <span style="color: #0000DD; font-weight: bold">0</span>))
<span style="color: #888888">/**</span>
<span style="color: #888888"> * Rock: A, X. Worth: 1. Beats: Scissors</span>
<span style="color: #888888"> * Paper: B, Y. Worth: 2. Beats: Rock</span>
<span style="color: #888888"> * Scissors: C, Z. Worth: 3. Beats: Paper</span>
<span style="color: #888888"> * 0 if you lost,</span>
<span style="color: #888888"> * 3 if the round was a draw</span>
<span style="color: #888888"> * and 6 if you won</span>
<span style="color: #888888"> * X: Lose</span>
<span style="color: #888888"> * Y: Draw</span>
<span style="color: #888888"> * Z: Win</span>
<span style="color: #888888"> */</span>
console.log(input.split(<span style="background-color: #fff0f0">'\n'</span>).reduce((a, c) <span style="color: #333333">=></span> {
<span style="color: #008800; font-weight: bold">const</span> [them, me] <span style="color: #333333">=</span> c.split(<span style="background-color: #fff0f0">' '</span>)
<span style="color: #008800; font-weight: bold">if</span>(them <span style="color: #333333">===</span> <span style="background-color: #fff0f0">'A'</span>){ <span style="color: #888888">// They've played Rock</span>
<span style="color: #008800; font-weight: bold">if</span>(me <span style="color: #333333">===</span> <span style="background-color: #fff0f0">'X'</span>){ <span style="color: #888888">// I need to lose</span>
a <span style="color: #333333">+=</span> <span style="color: #0000DD; font-weight: bold">0</span> <span style="color: #333333">+</span> <span style="color: #0000DD; font-weight: bold">3</span> <span style="color: #888888">// I play Scissors</span>
}
<span style="color: #008800; font-weight: bold">if</span>(me <span style="color: #333333">===</span> <span style="background-color: #fff0f0">'Y'</span>){ <span style="color: #888888">// I need to draw</span>
a <span style="color: #333333">+=</span> <span style="color: #0000DD; font-weight: bold">3</span> <span style="color: #333333">+</span> <span style="color: #0000DD; font-weight: bold">1</span> <span style="color: #888888">// I play Rock</span>
}
<span style="color: #008800; font-weight: bold">if</span>(me <span style="color: #333333">===</span> <span style="background-color: #fff0f0">'Z'</span>){ <span style="color: #888888">// I need to win</span>
a <span style="color: #333333">+=</span> <span style="color: #0000DD; font-weight: bold">6</span> <span style="color: #333333">+</span> <span style="color: #0000DD; font-weight: bold">2</span> <span style="color: #888888">// I play Paper</span>
}
}
<span style="color: #008800; font-weight: bold">if</span>(them <span style="color: #333333">===</span> <span style="background-color: #fff0f0">'B'</span>){ <span style="color: #888888">// They've played Paper</span>
<span style="color: #008800; font-weight: bold">if</span>(me <span style="color: #333333">===</span> <span style="background-color: #fff0f0">'X'</span>){ <span style="color: #888888">// I need to lose</span>
a <span style="color: #333333">+=</span> <span style="color: #0000DD; font-weight: bold">0</span> <span style="color: #333333">+</span> <span style="color: #0000DD; font-weight: bold">1</span> <span style="color: #888888">// I play Rock</span>
}
<span style="color: #008800; font-weight: bold">if</span>(me <span style="color: #333333">===</span> <span style="background-color: #fff0f0">'Y'</span>){ <span style="color: #888888">// I need to draw</span>
a <span style="color: #333333">+=</span> <span style="color: #0000DD; font-weight: bold">3</span> <span style="color: #333333">+</span> <span style="color: #0000DD; font-weight: bold">2</span> <span style="color: #888888">// I play Paper</span>
}
<span style="color: #008800; font-weight: bold">if</span>(me <span style="color: #333333">===</span> <span style="background-color: #fff0f0">'Z'</span>){ <span style="color: #888888">// I need to win</span>
a <span style="color: #333333">+=</span> <span style="color: #0000DD; font-weight: bold">6</span> <span style="color: #333333">+</span> <span style="color: #0000DD; font-weight: bold">3</span> <span style="color: #888888">// I play Scissors</span>
}
}
<span style="color: #008800; font-weight: bold">if</span>(them <span style="color: #333333">===</span> <span style="background-color: #fff0f0">'C'</span>){ <span style="color: #888888">// They've played Scissors</span>
<span style="color: #008800; font-weight: bold">if</span>(me <span style="color: #333333">===</span> <span style="background-color: #fff0f0">'X'</span>){ <span style="color: #888888">// I need to lose</span>
a <span style="color: #333333">+=</span> <span style="color: #0000DD; font-weight: bold">0</span> <span style="color: #333333">+</span> <span style="color: #0000DD; font-weight: bold">2</span> <span style="color: #888888">// I play Paper </span>
}
<span style="color: #008800; font-weight: bold">if</span>(me <span style="color: #333333">===</span> <span style="background-color: #fff0f0">'Y'</span>){ <span style="color: #888888">// I need to draw</span>
a <span style="color: #333333">+=</span> <span style="color: #0000DD; font-weight: bold">3</span> <span style="color: #333333">+</span> <span style="color: #0000DD; font-weight: bold">3</span> <span style="color: #888888">// I play Scissors </span>
}
<span style="color: #008800; font-weight: bold">if</span>(me <span style="color: #333333">===</span> <span style="background-color: #fff0f0">'Z'</span>){ <span style="color: #888888">// I need to win</span>
a <span style="color: #333333">+=</span> <span style="color: #0000DD; font-weight: bold">6</span> <span style="color: #333333">+</span> <span style="color: #0000DD; font-weight: bold">1</span> <span style="color: #888888">// I play Rock </span>
}
}
<span style="color: #008800; font-weight: bold">return</span> a
}, <span style="color: #0000DD; font-weight: bold">0</span>))
</pre></div>
<h2>Day 3</h2>
<h3>JavaScriptmas</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">const</span> faveFoods <span style="color: #333333">=</span> {
breakfast<span style="color: #333333">:</span> <span style="background-color: #fff0f0">'croissants'</span>,
lunch<span style="color: #333333">:</span> <span style="background-color: #fff0f0">'pasta'</span>,
supper<span style="color: #333333">:</span> <span style="background-color: #fff0f0">'pizza'</span>
}
<span style="color: #008800; font-weight: bold">const</span> {breakfast, lunch, supper} <span style="color: #333333">=</span> faveFoods
<span style="color: #007020">document</span>.getElementById(<span style="background-color: #fff0f0">'meals'</span>).innerHTML <span style="color: #333333">=</span> <span style="color: #FF0000; background-color: #FFAAAA">`</span>
For breakfast, I only like ${breakfast}. For lunch, I love ${lunch}, and <span style="color: #008800; font-weight: bold">for</span> supper I want usually want ${supper}.<span style="color: #FF0000; background-color: #FFAAAA">`</span>
</pre></div>
<h3>Advent of Code</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #888888">// drop 96 for lowercase</span>
<span style="color: #888888">// drop 38 for uppercase</span>
<span style="color: #008800; font-weight: bold">const</span> getCodeValue <span style="color: #333333">=</span> letter <span style="color: #333333">=></span> letter <span style="color: #333333">===</span> letter.toLowerCase()
<span style="color: #333333">?</span> letter.charCodeAt(<span style="color: #0000DD; font-weight: bold">0</span>) <span style="color: #333333">-</span> <span style="color: #0000DD; font-weight: bold">96</span>
<span style="color: #333333">:</span> letter.charCodeAt(<span style="color: #0000DD; font-weight: bold">0</span>) <span style="color: #333333">-</span> <span style="color: #0000DD; font-weight: bold">38</span>
<span style="color: #008800; font-weight: bold">const</span> getIntersection <span style="color: #333333">=</span> (a, b) <span style="color: #333333">=></span> {
<span style="color: #008800; font-weight: bold">for</span>(<span style="color: #008800; font-weight: bold">let</span> i <span style="color: #008800; font-weight: bold">in</span> a){
<span style="color: #008800; font-weight: bold">if</span>(b.includes(a[i])){
<span style="color: #008800; font-weight: bold">return</span> a[i]
}
}
}
<span style="color: #008800; font-weight: bold">const</span> getIntersectionThree <span style="color: #333333">=</span> (a, b, c) <span style="color: #333333">=></span> {
<span style="color: #008800; font-weight: bold">for</span>(<span style="color: #008800; font-weight: bold">let</span> i <span style="color: #008800; font-weight: bold">in</span> a){
<span style="color: #008800; font-weight: bold">if</span>(b.includes(a[i]) <span style="color: #333333">&&</span> c.includes(a[i])){
<span style="color: #008800; font-weight: bold">return</span> a[i]
}
}
}
console.log(input.split(<span style="background-color: #fff0f0">'\n'</span>).reduce((a, c) <span style="color: #333333">=></span> a <span style="color: #333333">+</span> getCodeValue(getIntersection(...[c.slice(<span style="color: #0000DD; font-weight: bold">0</span>, <span style="color: #007020">Math</span>.ceil(c.length <span style="color: #333333">/</span> <span style="color: #0000DD; font-weight: bold">2</span>)).split(<span style="background-color: #fff0f0">''</span>), c.slice(<span style="color: #007020">Math</span>.ceil(c.length <span style="color: #333333">/</span> <span style="color: #0000DD; font-weight: bold">2</span>)).split(<span style="background-color: #fff0f0">''</span>)]))
, <span style="color: #0000DD; font-weight: bold">0</span>))
<span style="color: #008800; font-weight: bold">let</span> total <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">0</span>
<span style="color: #008800; font-weight: bold">const</span> lines <span style="color: #333333">=</span> input.split(<span style="background-color: #fff0f0">'\n'</span>)
<span style="color: #008800; font-weight: bold">for</span> (<span style="color: #008800; font-weight: bold">let</span> i <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">0</span>; i <span style="color: #333333"><</span> lines.length; i <span style="color: #333333">+=</span> <span style="color: #0000DD; font-weight: bold">3</span>) {
<span style="color: #008800; font-weight: bold">const</span> chunk <span style="color: #333333">=</span> lines.slice(i, i <span style="color: #333333">+</span> <span style="color: #0000DD; font-weight: bold">3</span>);
total <span style="color: #333333">+=</span> getCodeValue(getIntersectionThree(...chunk))
}
console.log(total)
console.log(input.split(<span style="background-color: #fff0f0">'\n'</span>).reduce((p, _, i, a) <span style="color: #333333">=></span> <span style="color: #333333">!</span>(i<span style="color: #333333">%</span><span style="color: #0000DD; font-weight: bold">3</span>)
<span style="color: #333333">?</span> p <span style="color: #333333">+</span> getCodeValue(getIntersectionThree(...a.slice(i, i <span style="color: #333333">+</span> <span style="color: #0000DD; font-weight: bold">3</span>)))
<span style="color: #333333">:</span> p, <span style="color: #0000DD; font-weight: bold">0</span>))
</pre></div>
<h2>Day 4</h2>
<h3>JavaScriptmas</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">const</span> whisper <span style="color: #333333">=</span> s <span style="color: #333333">=></span> <span style="color: #FF0000; background-color: #FFAAAA">`</span>shh... ${s.endsWith(<span style="background-color: #fff0f0">'!'</span>)
<span style="color: #333333">?</span> s.toLowerCase().slice(<span style="color: #0000DD; font-weight: bold">0</span>, <span style="color: #333333">-</span><span style="color: #0000DD; font-weight: bold">1</span>)
<span style="color: #333333">:</span> s.toLowerCase()}<span style="color: #FF0000; background-color: #FFAAAA">`</span>
</pre></div>
<h3>Advent of Code</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">const</span> range <span style="color: #333333">=</span> (start, stop) <span style="color: #333333">=></span> <span style="color: #007020">Array</span>.from({ length<span style="color: #333333">:</span> stop <span style="color: #333333">-</span> start <span style="color: #333333">+</span> <span style="color: #0000DD; font-weight: bold">1</span> }, (_, i) <span style="color: #333333">=></span> start <span style="color: #333333">+</span> i)
<span style="color: #008800; font-weight: bold">const</span> contains <span style="color: #333333">=</span> (a, b) <span style="color: #333333">=></span> a.every(e <span style="color: #333333">=></span> b.includes(e)) <span style="color: #333333">||</span> b.every(e <span style="color: #333333">=></span> a.includes(e))
<span style="color: #008800; font-weight: bold">const</span> overlaps <span style="color: #333333">=</span> (a, b) <span style="color: #333333">=></span> a.some(e <span style="color: #333333">=></span> b.includes(e))
console.log(input.split(<span style="background-color: #fff0f0">'\n'</span>).reduce((a, line) <span style="color: #333333">=></span> {
<span style="color: #008800; font-weight: bold">const</span> [firstArea, secondArea] <span style="color: #333333">=</span> line.split(<span style="background-color: #fff0f0">','</span>).map(elf <span style="color: #333333">=></span> range(...elf.split(<span style="background-color: #fff0f0">'-'</span>).map(e <span style="color: #333333">=></span> <span style="color: #007020">Number</span>(e))))
a.contains <span style="color: #333333">+=</span> contains(firstArea, secondArea) <span style="color: #333333">?</span> <span style="color: #0000DD; font-weight: bold">1</span> <span style="color: #333333">:</span> <span style="color: #0000DD; font-weight: bold">0</span>
a.overlaps <span style="color: #333333">+=</span> overlaps(firstArea, secondArea) <span style="color: #333333">?</span> <span style="color: #0000DD; font-weight: bold">1</span> <span style="color: #333333">:</span> <span style="color: #0000DD; font-weight: bold">0</span>
<span style="color: #008800; font-weight: bold">return</span> a
}, {
contains<span style="color: #333333">:</span> <span style="color: #0000DD; font-weight: bold">0</span>,
overlaps<span style="color: #333333">:</span> <span style="color: #0000DD; font-weight: bold">0</span>
}))
<span style="color: #888888">// let containedWithin = 0</span>
<span style="color: #888888">// let overlaps = 0</span>
<span style="color: #888888">// input.split('\n').forEach(line => {</span>
<span style="color: #888888">// const [firstArea, secondArea] = line.split(',').map(elf => range(...elf.split('-').map(e => Number(e))))</span>
<span style="color: #888888">// if(secondArea.every(e => firstArea.includes(e)) || firstArea.every(e => secondArea.includes(e))){</span>
<span style="color: #888888">// containedWithin += 1</span>
<span style="color: #888888">// }</span>
<span style="color: #888888">// if(secondArea.some(e => firstArea.includes(e))){</span>
<span style="color: #888888">// overlaps += 1</span>
<span style="color: #888888">// }</span>
<span style="color: #888888">// })</span>
<span style="color: #888888">// console.log(containedWithin, overlaps)</span>
</pre></div>
<h2>Day 5</h2>
<h3>JavaScriptmas</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">const</span> getSaleItems <span style="color: #333333">=</span> d <span style="color: #333333">=></span> d.filter(e <span style="color: #333333">=></span> e.type <span style="color: #333333">===</span> <span style="background-color: #fff0f0">"sweet"</span>).map(e <span style="color: #333333">=></span> ({item<span style="color: #333333">:</span> e.item, price<span style="color: #333333">:</span> e.price}))
</pre></div>
<h3>Advent of Code</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">const</span> chunk <span style="color: #333333">=</span> (str, size) <span style="color: #333333">=></span> {
<span style="color: #008800; font-weight: bold">const</span> numChunks <span style="color: #333333">=</span> <span style="color: #007020">Math</span>.ceil(str.length <span style="color: #333333">/</span> size)
<span style="color: #008800; font-weight: bold">const</span> chunks <span style="color: #333333">=</span> <span style="color: #008800; font-weight: bold">new</span> <span style="color: #007020">Array</span>(numChunks)
<span style="color: #008800; font-weight: bold">for</span> (<span style="color: #008800; font-weight: bold">let</span> i <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">0</span>, o <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">0</span>; i <span style="color: #333333"><</span> numChunks; <span style="color: #333333">++</span>i, o <span style="color: #333333">+=</span> size) {
chunks[i] <span style="color: #333333">=</span> str.substr(o, size)
}
<span style="color: #008800; font-weight: bold">return</span> chunks
}
<span style="color: #008800; font-weight: bold">const</span> [initialState, instructions] <span style="color: #333333">=</span> input.split(<span style="background-color: #fff0f0">'\n\n'</span>)
<span style="color: #008800; font-weight: bold">const</span> initialStateLines <span style="color: #333333">=</span> initialState.split(<span style="background-color: #fff0f0">'\n'</span>).reverse()
<span style="color: #008800; font-weight: bold">const</span> positions <span style="color: #333333">=</span> chunk(initialStateLines.shift(), <span style="color: #0000DD; font-weight: bold">4</span>).reduce((a, c) <span style="color: #333333">=></span> {
a[<span style="color: #007020">Number</span>(c.trim())] <span style="color: #333333">=</span> []
<span style="color: #008800; font-weight: bold">return</span> a
}, {})
initialStateLines.forEach(line <span style="color: #333333">=></span> {
chunk(line, <span style="color: #0000DD; font-weight: bold">4</span>).forEach((position, index) <span style="color: #333333">=></span> {
<span style="color: #008800; font-weight: bold">if</span> (position.trim().length) {
<span style="color: #008800; font-weight: bold">const</span> { groups<span style="color: #333333">:</span> { letter } } <span style="color: #333333">=</span> <span style="color: #000000; background-color: #fff0ff">/\s*\[(?<letter>[A-Z])\]\s*/</span>.exec(position)
positions[<span style="color: #007020">Object</span>.keys(positions)[index]].push(letter)
}
})
})
<span style="color: #888888">/**</span>
<span style="color: #888888"> * Part 1</span>
<span style="color: #888888"> */</span>
<span style="color: #888888">// instructions.split('\n').forEach(instruction => {</span>
<span style="color: #888888">// const {groups: {num, from, to}} = /move (?<num>[0-9]+) from (?<from>[0-9]+) to (?<to>[0-9]+)/.exec(instruction)</span>
<span style="color: #888888">// for(let i = 0; i < Number(num); i++){</span>
<span style="color: #888888">// positions[Number(to)].push(positions[Number(from)].pop())</span>
<span style="color: #888888">// }</span>
<span style="color: #888888">// })</span>
<span style="color: #888888">/**</span>
<span style="color: #888888"> * Part 2</span>
<span style="color: #888888"> */</span>
instructions.split(<span style="background-color: #fff0f0">'\n'</span>).forEach(instruction <span style="color: #333333">=></span> {
<span style="color: #008800; font-weight: bold">const</span> { groups<span style="color: #333333">:</span> { num, from, to } } <span style="color: #333333">=</span> <span style="color: #000000; background-color: #fff0ff">/move (?<num>[0-9]+) from (?<from>[0-9]+) to (?<to>[0-9]+)/</span>.exec(instruction)
positions[<span style="color: #007020">Number</span>(to)].push(...positions[<span style="color: #007020">Number</span>(from)].slice(<span style="color: #333333">-</span><span style="color: #007020">Math</span>.abs(<span style="color: #007020">Number</span>(num))))
positions[<span style="color: #007020">Number</span>(from)].splice(positions[<span style="color: #007020">Number</span>(from)].length <span style="color: #333333">-</span> <span style="color: #007020">Number</span>(num), <span style="color: #007020">Number</span>(num) )
})
console.log(<span style="color: #007020">Object</span>.keys(positions).reduce((a, c, i) <span style="color: #333333">=></span> {
<span style="color: #008800; font-weight: bold">return</span> a <span style="color: #333333">+</span> positions[c].at(<span style="color: #333333">-</span><span style="color: #0000DD; font-weight: bold">1</span>)
}, <span style="background-color: #fff0f0">''</span>))
</pre></div>
<h2>Day 6</h2>
<h3>JavaScriptmas</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">const</span> getRandomNumberOfTacos <span style="color: #333333">=</span> () <span style="color: #333333">=></span> <span style="color: #008800; font-weight: bold">new</span> <span style="color: #007020">Array</span>(<span style="color: #007020">Math</span>.floor(<span style="color: #007020">Math</span>.random() <span style="color: #333333">*</span> (<span style="color: #0000DD; font-weight: bold">10</span> <span style="color: #333333">-</span> <span style="color: #0000DD; font-weight: bold">1</span>) <span style="color: #333333">+</span> <span style="color: #0000DD; font-weight: bold">1</span>)).fill(<span style="background-color: #fff0f0">'🌮'</span>)
</pre></div>
<h3>Advent of Code</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">const</span> test_input_1 <span style="color: #333333">=</span> <span style="color: #FF0000; background-color: #FFAAAA">`</span>mjqjpqmgbljsphdztnvjfqwrcgsmlb<span style="color: #FF0000; background-color: #FFAAAA">`</span>
<span style="color: #008800; font-weight: bold">const</span> test_input_2 <span style="color: #333333">=</span> <span style="color: #FF0000; background-color: #FFAAAA">`</span>bvwbjplbgvbhsrlpgdmjqwftvncz<span style="color: #FF0000; background-color: #FFAAAA">`</span>
<span style="color: #008800; font-weight: bold">const</span> test_input_3 <span style="color: #333333">=</span> <span style="color: #FF0000; background-color: #FFAAAA">`</span>nppdvjthqldpwncqszvftbrmjlhg<span style="color: #FF0000; background-color: #FFAAAA">`</span>
<span style="color: #008800; font-weight: bold">const</span> test_input_4 <span style="color: #333333">=</span> <span style="color: #FF0000; background-color: #FFAAAA">`</span>nznrnfrfntjfmvfwmzdfjlvtqnbhcprsg<span style="color: #FF0000; background-color: #FFAAAA">`</span>
<span style="color: #008800; font-weight: bold">const</span> test_input_5 <span style="color: #333333">=</span> <span style="color: #FF0000; background-color: #FFAAAA">`</span>zcfzfwzzqfrljwzlrfnpqdbhtmscgvjw<span style="color: #FF0000; background-color: #FFAAAA">`</span>
<span style="color: #008800; font-weight: bold">const</span> findPacket <span style="color: #333333">=</span> stream <span style="color: #333333">=></span> {
<span style="color: #008800; font-weight: bold">for</span>(<span style="color: #008800; font-weight: bold">let</span> i <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">3</span>; i <span style="color: #333333"><=</span> stream.length; i<span style="color: #333333">++</span>){
<span style="color: #008800; font-weight: bold">if</span>(<span style="color: #008800; font-weight: bold">new</span> Set(<span style="color: #007020">Array</span>.from({length<span style="color: #333333">:</span> <span style="color: #0000DD; font-weight: bold">4</span>}, (_, a) <span style="color: #333333">=></span> stream.charAt(i <span style="color: #333333">-</span> a))).size <span style="color: #333333">===</span> <span style="color: #0000DD; font-weight: bold">4</span>){
<span style="color: #008800; font-weight: bold">return</span> i <span style="color: #333333">+</span> <span style="color: #0000DD; font-weight: bold">1</span>
}
}
}
<span style="color: #008800; font-weight: bold">const</span> findMessage <span style="color: #333333">=</span> stream <span style="color: #333333">=></span> {
<span style="color: #008800; font-weight: bold">for</span>(<span style="color: #008800; font-weight: bold">let</span> i <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">13</span>; i <span style="color: #333333"><=</span> stream.length; i<span style="color: #333333">++</span>){
<span style="color: #008800; font-weight: bold">if</span>(<span style="color: #008800; font-weight: bold">new</span> Set(<span style="color: #007020">Array</span>.from({length<span style="color: #333333">:</span> <span style="color: #0000DD; font-weight: bold">14</span>}, (_, a) <span style="color: #333333">=></span> stream.charAt(i <span style="color: #333333">-</span> a))).size <span style="color: #333333">===</span> <span style="color: #0000DD; font-weight: bold">14</span>){
<span style="color: #008800; font-weight: bold">return</span> i <span style="color: #333333">+</span> <span style="color: #0000DD; font-weight: bold">1</span>
}
}
}
console.log(findPacket(test_input_1))
console.log(findPacket(test_input_2))
console.log(findPacket(test_input_3))
console.log(findPacket(test_input_4))
console.log(findPacket(test_input_5))
console.log(findPacket(input))
console.log(findMessage(test_input_1))
console.log(findMessage(test_input_2))
console.log(findMessage(test_input_3))
console.log(findMessage(test_input_4))
console.log(findMessage(test_input_5))
console.log(findMessage(input))
</pre></div>
<h2>Day 7</h2>
<h3>JavaScriptmas</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">const</span> altCaps <span style="color: #333333">=</span> str <span style="color: #333333">=></span> str.split(<span style="background-color: #fff0f0">''</span>).map((c, i) <span style="color: #333333">=></span> i <span style="color: #333333">%</span> <span style="color: #0000DD; font-weight: bold">2</span> <span style="color: #333333">?</span> c <span style="color: #333333">:</span> str.charCodeAt(i) <span style="color: #333333">></span> <span style="color: #0000DD; font-weight: bold">96</span> <span style="color: #333333">||</span> str.charCodeAt(i) <span style="color: #333333"><</span> <span style="color: #0000DD; font-weight: bold">123</span> <span style="color: #333333">?</span> c.toUpperCase() <span style="color: #333333">:</span> c).join(<span style="background-color: #fff0f0">''</span>)
</pre></div>
<h3>Advent of Code</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #888888">// import { Tree } from './Tree.js'</span>
<span style="color: #888888">// import { TreeNode } from './TreeNode.js'</span>
<span style="color: #008800; font-weight: bold">class</span> TreeNode {
constructor(key, value <span style="color: #333333">=</span> key, parent <span style="color: #333333">=</span> <span style="color: #008800; font-weight: bold">null</span>) {
<span style="color: #008800; font-weight: bold">this</span>.key <span style="color: #333333">=</span> key;
<span style="color: #008800; font-weight: bold">this</span>.value <span style="color: #333333">=</span> value;
<span style="color: #008800; font-weight: bold">this</span>.parent <span style="color: #333333">=</span> parent;
<span style="color: #008800; font-weight: bold">this</span>.children <span style="color: #333333">=</span> [];
}
get isLeaf() {
<span style="color: #008800; font-weight: bold">return</span> <span style="color: #008800; font-weight: bold">this</span>.children.length <span style="color: #333333">===</span> <span style="color: #0000DD; font-weight: bold">0</span>;
}
get hasChildren() {
<span style="color: #008800; font-weight: bold">return</span> <span style="color: #333333">!</span><span style="color: #008800; font-weight: bold">this</span>.isLeaf;
}
}
<span style="color: #008800; font-weight: bold">class</span> Tree {
constructor(key, value <span style="color: #333333">=</span> key) {
<span style="color: #008800; font-weight: bold">this</span>.root <span style="color: #333333">=</span> <span style="color: #008800; font-weight: bold">new</span> TreeNode(key, value);
}
<span style="color: #333333">*</span>preOrderTraversal(node <span style="color: #333333">=</span> <span style="color: #008800; font-weight: bold">this</span>.root) {
yield node;
<span style="color: #008800; font-weight: bold">if</span> (node.children.length) {
<span style="color: #008800; font-weight: bold">for</span> (<span style="color: #008800; font-weight: bold">let</span> child of node.children) {
yield<span style="color: #333333">*</span> <span style="color: #008800; font-weight: bold">this</span>.preOrderTraversal(child);
}
}
}
<span style="color: #333333">*</span>postOrderTraversal(node <span style="color: #333333">=</span> <span style="color: #008800; font-weight: bold">this</span>.root) {
<span style="color: #008800; font-weight: bold">if</span> (node.children.length) {
<span style="color: #008800; font-weight: bold">for</span> (<span style="color: #008800; font-weight: bold">let</span> child of node.children) {
yield<span style="color: #333333">*</span> <span style="color: #008800; font-weight: bold">this</span>.postOrderTraversal(child);
}
}
yield node;
}
insert(parentNodeKey, key, value <span style="color: #333333">=</span> key) {
<span style="color: #008800; font-weight: bold">for</span> (<span style="color: #008800; font-weight: bold">let</span> node of <span style="color: #008800; font-weight: bold">this</span>.preOrderTraversal()) {
<span style="color: #008800; font-weight: bold">if</span> (node.key <span style="color: #333333">===</span> parentNodeKey) {
node.children.push(<span style="color: #008800; font-weight: bold">new</span> TreeNode(key, value, node));
<span style="color: #008800; font-weight: bold">return</span> <span style="color: #008800; font-weight: bold">true</span>;
}
}
<span style="color: #008800; font-weight: bold">return</span> <span style="color: #008800; font-weight: bold">false</span>;
}
remove(key) {
<span style="color: #008800; font-weight: bold">for</span> (<span style="color: #008800; font-weight: bold">let</span> node of <span style="color: #008800; font-weight: bold">this</span>.preOrderTraversal()) {
<span style="color: #008800; font-weight: bold">const</span> filtered <span style="color: #333333">=</span> node.children.filter(c <span style="color: #333333">=></span> c.key <span style="color: #333333">!==</span> key);
<span style="color: #008800; font-weight: bold">if</span> (filtered.length <span style="color: #333333">!==</span> node.children.length) {
node.children <span style="color: #333333">=</span> filtered;
<span style="color: #008800; font-weight: bold">return</span> <span style="color: #008800; font-weight: bold">true</span>;
}
}
<span style="color: #008800; font-weight: bold">return</span> <span style="color: #008800; font-weight: bold">false</span>;
}
find(key) {
<span style="color: #008800; font-weight: bold">for</span> (<span style="color: #008800; font-weight: bold">let</span> node of <span style="color: #008800; font-weight: bold">this</span>.preOrderTraversal()) {
<span style="color: #008800; font-weight: bold">if</span> (node.key <span style="color: #333333">===</span> key) <span style="color: #008800; font-weight: bold">return</span> node;
}
<span style="color: #008800; font-weight: bold">return</span> <span style="color: #008800; font-weight: bold">undefined</span>;
}
}
<span style="color: #888888">/*</span>
<span style="color: #888888"> * https://www.30secondsofcode.org/articles/s/js-data-structures-tree</span>
<span style="color: #888888"> */</span>
addEventListener(<span style="background-color: #fff0f0">'DOMContentLoaded'</span>, async () <span style="color: #333333">=></span> {
<span style="color: #888888">//const res = await fetch("./test.txt")</span>
<span style="color: #008800; font-weight: bold">const</span> res <span style="color: #333333">=</span> await fetch(<span style="background-color: #fff0f0">"./input.txt"</span>)
<span style="color: #008800; font-weight: bold">const</span> text <span style="color: #333333">=</span> await res.text()
<span style="color: #008800; font-weight: bold">const</span> input <span style="color: #333333">=</span> text.split(<span style="background-color: #fff0f0">'\n'</span>)
<span style="color: #008800; font-weight: bold">let</span> target <span style="color: #333333">=</span> <span style="color: #008800; font-weight: bold">null</span>
<span style="color: #008800; font-weight: bold">let</span> tree <span style="color: #333333">=</span> <span style="color: #008800; font-weight: bold">null</span>
<span style="color: #008800; font-weight: bold">let</span> lineParts
input.forEach((line, index) <span style="color: #333333">=></span> {
<span style="color: #008800; font-weight: bold">if</span> (<span style="color: #333333">!</span>index) {
tree <span style="color: #333333">=</span> <span style="color: #008800; font-weight: bold">new</span> Tree(<span style="background-color: #fff0f0">'/'</span>, <span style="color: #0000DD; font-weight: bold">0</span>)
target <span style="color: #333333">=</span> tree.root
} <span style="color: #008800; font-weight: bold">else</span> {
<span style="color: #008800; font-weight: bold">if</span> (line.charAt(<span style="color: #0000DD; font-weight: bold">0</span>) <span style="color: #333333">===</span> <span style="background-color: #fff0f0">'$'</span>) {
lineParts <span style="color: #333333">=</span> line.split(<span style="background-color: #fff0f0">' '</span>)
<span style="color: #008800; font-weight: bold">if</span> (lineParts.length <span style="color: #333333">===</span> <span style="color: #0000DD; font-weight: bold">3</span>) {
<span style="color: #008800; font-weight: bold">if</span> (lineParts[<span style="color: #0000DD; font-weight: bold">2</span>] <span style="color: #333333">===</span> <span style="background-color: #fff0f0">'..'</span>) {
target <span style="color: #333333">=</span> target.parent
} <span style="color: #008800; font-weight: bold">else</span> <span style="color: #008800; font-weight: bold">if</span> (lineParts[<span style="color: #0000DD; font-weight: bold">2</span>] <span style="color: #333333">===</span> <span style="background-color: #fff0f0">'/'</span>) {
target <span style="color: #333333">=</span> tree.root
} <span style="color: #008800; font-weight: bold">else</span> {
target <span style="color: #333333">=</span> target.children.find(ch <span style="color: #333333">=></span> ch.key <span style="color: #333333">===</span> lineParts[<span style="color: #0000DD; font-weight: bold">2</span>])
}
}
} <span style="color: #008800; font-weight: bold">else</span> {
lineParts <span style="color: #333333">=</span> line.split(<span style="background-color: #fff0f0">' '</span>)
<span style="color: #008800; font-weight: bold">if</span> (lineParts[<span style="color: #0000DD; font-weight: bold">0</span>] <span style="color: #333333">===</span> <span style="background-color: #fff0f0">'dir'</span>) {
target.children.push(<span style="color: #008800; font-weight: bold">new</span> TreeNode(lineParts[<span style="color: #0000DD; font-weight: bold">1</span>], <span style="color: #0000DD; font-weight: bold">0</span>, target))
} <span style="color: #008800; font-weight: bold">else</span> {
<span style="color: #008800; font-weight: bold">const</span> value <span style="color: #333333">=</span> <span style="color: #007020">Number</span>(lineParts[<span style="color: #0000DD; font-weight: bold">0</span>])
target.children.push(<span style="color: #008800; font-weight: bold">new</span> TreeNode(lineParts[<span style="color: #0000DD; font-weight: bold">1</span>], value, target))
target.value <span style="color: #333333">+=</span> value
<span style="color: #008800; font-weight: bold">let</span> parent <span style="color: #333333">=</span> target.parent
<span style="color: #008800; font-weight: bold">while</span> (parent) {
parent.value <span style="color: #333333">+=</span> value
parent <span style="color: #333333">=</span> parent.parent
}
}
}
}
})
<span style="color: #008800; font-weight: bold">const</span> dirs <span style="color: #333333">=</span> [...tree.postOrderTraversal()].filter(x <span style="color: #333333">=></span> x.hasChildren)
console.log(<span style="background-color: #fff0f0">'Part 1:'</span>, dirs.reduce((a, c) <span style="color: #333333">=></span> {
<span style="color: #008800; font-weight: bold">if</span> (c.value <span style="color: #333333"><=</span> <span style="color: #0000DD; font-weight: bold">100000</span>) {
a <span style="color: #333333">+=</span> c.value
}
<span style="color: #008800; font-weight: bold">return</span> a
}, <span style="color: #0000DD; font-weight: bold">0</span>))
<span style="color: #008800; font-weight: bold">const</span> spaceRequired <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">30000000</span> <span style="color: #333333">-</span> (<span style="color: #0000DD; font-weight: bold">70000000</span> <span style="color: #333333">-</span> tree.root.value)
console.log(<span style="background-color: #fff0f0">'Space required: '</span>, spaceRequired)
console.log(<span style="background-color: #fff0f0">'Part 2:'</span>, dirs.filter(dir <span style="color: #333333">=></span> {
<span style="color: #008800; font-weight: bold">if</span> (dir.value <span style="color: #333333">>=</span> spaceRequired) {
console.log(dir.key, dir.value)
<span style="color: #008800; font-weight: bold">return</span> <span style="color: #008800; font-weight: bold">true</span>
}
<span style="color: #008800; font-weight: bold">return</span> <span style="color: #008800; font-weight: bold">false</span>
}).sort((a, b) <span style="color: #333333">=></span> a.value <span style="color: #333333">-</span> b.value)[<span style="color: #0000DD; font-weight: bold">0</span>].value)
})
</pre></div>
<h2>Day 8</h2>
<h3>JavaScriptmas</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">const</span> validTime <span style="color: #333333">=</span> str <span style="color: #333333">=></span> {
<span style="color: #008800; font-weight: bold">const</span> [hours, minutes] <span style="color: #333333">=</span> str.split(<span style="background-color: #fff0f0">':'</span>).map(n <span style="color: #333333">=></span> <span style="color: #007020">Number</span>(n))
<span style="color: #008800; font-weight: bold">return</span> hours <span style="color: #333333">>=</span> <span style="color: #0000DD; font-weight: bold">1</span> <span style="color: #333333">&&</span> hours <span style="color: #333333"><=</span> <span style="color: #0000DD; font-weight: bold">24</span> <span style="color: #333333">&&</span> minutes <span style="color: #333333">>=</span> <span style="color: #0000DD; font-weight: bold">0</span> <span style="color: #333333">&&</span> minutes <span style="color: #333333"><</span> <span style="color: #0000DD; font-weight: bold">60</span>
}
</pre></div>
<h2>Day 9</h2>
<h3>JavaScriptmas</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">const</span> capitalizeWord <span style="color: #333333">=</span> w <span style="color: #333333">=></span> <span style="color: #FF0000; background-color: #FFAAAA">`</span>${w.charAt(<span style="color: #0000DD; font-weight: bold">0</span>).toUpperCase()}${w.slice(<span style="color: #0000DD; font-weight: bold">1</span>, w.length)}<span style="color: #FF0000; background-color: #FFAAAA">`</span>
<span style="color: #008800; font-weight: bold">const</span> toTitleCase <span style="color: #333333">=</span> s <span style="color: #333333">=></span> s.split(<span style="background-color: #fff0f0">' '</span>).map(w <span style="color: #333333">=></span> capitalizeWord(w)).join(<span style="background-color: #fff0f0">' '</span>)
</pre></div>
<h2>Day 10</h2>
<h3>JavaScriptmas</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">const</span> sortByLength <span style="color: #333333">=</span> s <span style="color: #333333">=></span> s.sort((a, b) <span style="color: #333333">=></span> a.length <span style="color: #333333">-</span> b.length)
</pre></div>
<h2>Day 11</h2>
<h3>JavaScriptmas</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">const</span> reverseString <span style="color: #333333">=</span> arr <span style="color: #333333">=></span> arr.split(<span style="background-color: #fff0f0">''</span>).reverse().join(<span style="background-color: #fff0f0">''</span>)
<span style="color: #008800; font-weight: bold">const</span> reverseStringsInArray <span style="color: #333333">=</span> arr <span style="color: #333333">=></span> arr.map(a <span style="color: #333333">=></span> reverseString(a))
</pre></div>
<h2>Day 12</h2>
<h3>JavaScriptmas</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">class</span> MenuItem <span style="color: #008800; font-weight: bold">extends</span> HTMLElement{
<span style="color: #008800; font-weight: bold">static</span> get observedAttributes() {
<span style="color: #008800; font-weight: bold">return</span> [
<span style="background-color: #fff0f0">'food'</span>
]
}
constructor() {
<span style="color: #008800; font-weight: bold">super</span>()
}
render() {
<span style="color: #008800; font-weight: bold">this</span>.innerHTML <span style="color: #333333">=</span> <span style="color: #008800; font-weight: bold">this</span>.html
}
get html() {
<span style="color: #008800; font-weight: bold">return</span> <span style="color: #FF0000; background-color: #FFAAAA">`</span><span style="color: #333333"><</span>div <span style="color: #008800; font-weight: bold">class</span><span style="color: #333333">=</span><span style="background-color: #fff0f0">"food"</span><span style="color: #333333">></span>${<span style="color: #008800; font-weight: bold">this</span>.food}<span style="color: #333333"><</span><span style="color: #FF0000; background-color: #FFAAAA">/div>`</span>
}
attributeChangedCallback(name, oldValue, newValue) {
<span style="color: #008800; font-weight: bold">if</span> (oldValue <span style="color: #333333">!==</span> newValue) {
<span style="color: #008800; font-weight: bold">this</span>.render()
}
}
set food(v){
<span style="color: #008800; font-weight: bold">this</span>.setAttribute(<span style="background-color: #fff0f0">'food'</span>, v)
}
get food() {
<span style="color: #008800; font-weight: bold">return</span> <span style="color: #008800; font-weight: bold">this</span>.getAttribute(<span style="background-color: #fff0f0">'food'</span>)
}
}
<span style="color: #007020">window</span>.customElements.define(<span style="background-color: #fff0f0">'menu-item'</span>, MenuItem)
<span style="color: #008800; font-weight: bold">const</span> menu <span style="color: #333333">=</span> <span style="color: #007020">document</span>.getElementById(<span style="background-color: #fff0f0">'menu'</span>)
<span style="color: #008800; font-weight: bold">const</span> dinnerFoods <span style="color: #333333">=</span> [<span style="background-color: #fff0f0">'🍝'</span>,<span style="background-color: #fff0f0">'🍔'</span>,<span style="background-color: #fff0f0">'🌮'</span>]
menu.innerHTML <span style="color: #333333">=</span> dinnerFoods.map(food <span style="color: #333333">=></span> <span style="color: #FF0000; background-color: #FFAAAA">`</span><span style="color: #333333"><</span>menu<span style="color: #333333">-</span>item food<span style="color: #333333">=</span><span style="background-color: #fff0f0">"${food}"</span><span style="color: #333333">/><</span><span style="color: #FF0000; background-color: #FFAAAA">/menu-item>`).join('')</span>
</pre></div>
<h2>Day 13</h2>
<h3>JavaScriptmas</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">const emojifyWord <span style="color: #333333">=</span> w <span style="color: #333333">=></span> w.charAt(<span style="color: #0000DD; font-weight: bold">0</span>) <span style="color: #333333">===</span> <span style="background-color: #fff0f0">':'</span> <span style="color: #333333">&&</span> w.charAt(w.<span style="color: #008800; font-weight: bold">length</span> <span style="color: #333333">-</span> <span style="color: #0000DD; font-weight: bold">1</span>) <span style="color: #333333">===</span> <span style="background-color: #fff0f0">':'</span> <span style="color: #333333">?</span> emojis[w.slice(<span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #333333">-</span><span style="color: #0000DD; font-weight: bold">1</span>)] <span style="color: #333333">?</span> emojis[w.slice(<span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #333333">-</span><span style="color: #0000DD; font-weight: bold">1</span>)] : w.slice(<span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #333333">-</span><span style="color: #0000DD; font-weight: bold">1</span>) : w
const emojifyPhrase <span style="color: #333333">=</span> phrase <span style="color: #333333">=></span> phrase.split(<span style="background-color: #fff0f0">' '</span>).<span style="color: #008800; font-weight: bold">map</span>(word <span style="color: #333333">=></span> emojifyWord(word)).<span style="color: #008800; font-weight: bold">join</span>(<span style="background-color: #fff0f0">' '</span>)
</pre></div>
<h2>Day 14</h2>
<h3>JavaScriptmas</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">const</span> countVowelConsonant <span style="color: #333333">=</span> str <span style="color: #333333">=></span> str.split(<span style="background-color: #fff0f0">''</span>).reduce((a, c) <span style="color: #333333">=></span> a <span style="color: #333333">+=</span> [<span style="background-color: #fff0f0">'a'</span>,<span style="background-color: #fff0f0">'e'</span>,<span style="background-color: #fff0f0">'i'</span>,<span style="background-color: #fff0f0">'o'</span>,<span style="background-color: #fff0f0">'u'</span>].includes(c) <span style="color: #333333">?</span> <span style="color: #0000DD; font-weight: bold">1</span> <span style="color: #333333">:</span> <span style="color: #0000DD; font-weight: bold">2</span>, <span style="color: #0000DD; font-weight: bold">0</span>)
</pre></div>
<h2>Day 15</h2>
<h3>JavaScriptmas</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">const</span> isPalindrome <span style="color: #333333">=</span> str <span style="color: #333333">=></span> str <span style="color: #333333">===</span> str.split(<span style="background-color: #fff0f0">''</span>).reverse().join(<span style="background-color: #fff0f0">''</span>)
</pre></div>
<h2>Day 16</h2>
<h3>JavaScriptmas</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">const insertDashes <span style="color: #333333">=</span> arr <span style="color: #333333">=></span> arr.split(<span style="background-color: #fff0f0">' '</span>).<span style="color: #008800; font-weight: bold">map</span>(w <span style="color: #333333">=></span> w.split(<span style="background-color: #fff0f0">''</span>).<span style="color: #008800; font-weight: bold">join</span>(<span style="background-color: #fff0f0">'-'</span>)).<span style="color: #008800; font-weight: bold">join</span>(<span style="background-color: #fff0f0">' '</span>)
</pre></div>
<h2>Day 17</h2>
<h3>JavaScriptmas</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">const flatten <span style="color: #333333">=</span> arr <span style="color: #333333">=></span> arr.flat()
const flatten <span style="color: #333333">=</span> arr <span style="color: #333333">=></span> <span style="color: #007020">Array</span>.prototype.concat.apply([], arr)
const flatten <span style="color: #333333">=</span> arr <span style="color: #333333">=></span> arr.toString().split(<span style="background-color: #fff0f0">','</span>)
</pre></div>
<h2>Day 18</h2>
<h3>JavaScriptmas</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">const</span> candies <span style="color: #333333">=</span> (ch, ca) <span style="color: #333333">=></span> <span style="color: #007020">Math</span>.floor(ca<span style="color: #333333">/</span>ch) <span style="color: #333333">*</span> ch
</pre></div>
<h2>Day 19</h2>
<h3>JavaScriptmas</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">const</span> centuryFromYear <span style="color: #333333">=</span> num <span style="color: #333333">=></span> num <span style="color: #333333">%</span> <span style="color: #0000DD; font-weight: bold">100</span> <span style="color: #333333">===</span> <span style="color: #0000DD; font-weight: bold">0</span> <span style="color: #333333">?</span> num <span style="color: #333333">/</span> <span style="color: #0000DD; font-weight: bold">100</span> <span style="color: #333333">:</span> <span style="color: #007020">Math</span>.floor(num <span style="color: #333333">/</span> <span style="color: #0000DD; font-weight: bold">100</span>) <span style="color: #333333">+</span> <span style="color: #0000DD; font-weight: bold">1</span>
</pre></div>
<h2>Day 20</h2>
<h3>JavaScriptmas</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">const</span> getFreePodcasts <span style="color: #333333">=</span> data <span style="color: #333333">=></span> podcasts.filter(p <span style="color: #333333">=></span> <span style="color: #333333">!</span>p.paid).map(({title, rating, paid}) <span style="color: #333333">=></span> ({title, rating, paid}))
</pre></div>
<h2>Day 21</h2>
<h3>JavaScriptmas</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">const</span> awardBonuses <span style="color: #333333">=</span> num <span style="color: #333333">=></span> <span style="color: #007020">Array</span>.from({length<span style="color: #333333">:</span> num}, (_, i) <span style="color: #333333">=></span> i <span style="color: #333333">+</span> <span style="color: #0000DD; font-weight: bold">1</span>).forEach(i <span style="color: #333333">=></span> console.log(<span style="color: #FF0000; background-color: #FFAAAA">`</span>${i} <span style="color: #333333">-</span> ${<span style="color: #333333">!</span>(i<span style="color: #333333">%</span><span style="color: #0000DD; font-weight: bold">3</span>) <span style="color: #333333">&&</span> <span style="color: #333333">!</span>(i<span style="color: #333333">%</span><span style="color: #0000DD; font-weight: bold">5</span>) <span style="color: #333333">?</span> <span style="background-color: #fff0f0">'JACKPOT! 1 Million and a Yacht!'</span> <span style="color: #333333">:</span> <span style="color: #333333">!</span>(i<span style="color: #333333">%</span><span style="color: #0000DD; font-weight: bold">3</span>) <span style="color: #333333">?</span> <span style="background-color: #fff0f0">'Vacation!'</span> <span style="color: #333333">:</span> <span style="color: #333333">!</span>(i<span style="color: #333333">%</span><span style="color: #0000DD; font-weight: bold">5</span>) <span style="color: #333333">?</span> <span style="background-color: #fff0f0">'$100,000 bonus!'</span> <span style="color: #333333">:</span> <span style="background-color: #fff0f0">':('</span>}<span style="color: #FF0000; background-color: #FFAAAA">`</span>))
awardBonuses(<span style="color: #0000DD; font-weight: bold">100</span>)
</pre></div>
<h2>Day 22</h2>
<h3>JavaScriptmas</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">function</span> getReadyTables() {
<span style="color: #008800; font-weight: bold">const</span> readyTables <span style="color: #333333">=</span> []
<span style="color: #008800; font-weight: bold">for</span> (<span style="color: #008800; font-weight: bold">let</span> i <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">0</span>; i <span style="color: #333333"><</span> <span style="color: #0000DD; font-weight: bold">2</span>; i<span style="color: #333333">++</span>) {
readyTables.push(<span style="color: #007020">Math</span>.round(<span style="color: #007020">Math</span>.random()<span style="color: #333333">*</span><span style="color: #0000DD; font-weight: bold">20</span>) <span style="color: #333333">+</span> <span style="color: #0000DD; font-weight: bold">1</span>)
}
<span style="color: #008800; font-weight: bold">return</span> readyTables
}
<span style="color: #008800; font-weight: bold">const</span> displayTables <span style="color: #333333">=</span> () <span style="color: #333333">=></span> getReadyTables().map(el <span style="color: #333333">=></span> {
<span style="color: #008800; font-weight: bold">const</span> table <span style="color: #333333">=</span> <span style="color: #007020">document</span>.createElement(<span style="background-color: #fff0f0">'div'</span>)
table.classList.add(<span style="background-color: #fff0f0">'table'</span>)
table.innerText <span style="color: #333333">=</span> el
<span style="color: #008800; font-weight: bold">return</span> table
})
<span style="color: #007020">document</span>.getElementById(<span style="background-color: #fff0f0">'tables'</span>).append(...displayTables())
</pre></div>
<h2>Day 23</h2>
<h3>JavaScriptmas</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">const</span> sortProducts <span style="color: #333333">=</span> data <span style="color: #333333">=></span> data.sort((a, b) <span style="color: #333333">=></span> a.price <span style="color: #333333">-</span> b.price)
</pre></div>
<h2>Day 24</h2>
<h3>JavaScriptmas</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">const</span> player <span style="color: #333333">=</span> <span style="color: #007020">document</span>.getElementById(<span style="background-color: #fff0f0">"player"</span>)
<span style="color: #008800; font-weight: bold">const</span> playSong <span style="color: #333333">=</span> id <span style="color: #333333">=></span> player.src <span style="color: #333333">=</span> <span style="color: #FF0000; background-color: #FFAAAA">`</span>https<span style="color: #333333">:</span><span style="color: #888888">//www.youtube.com/embed/${id}?autoplay=1`</span>
</pre></div>
DominicMyershttp://www.blogger.com/profile/15530669398436940737noreply@blogger.com0tag:blogger.com,1999:blog-6506998626989446594.post-88723565487989409872022-11-15T08:41:00.000+00:002022-11-15T08:41:14.528+00:00Create dot notation array of strings from an Object<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-QBQhtenwbRL048k1x_r9Jm5mf622EnjMZ1nB3Ij6aVoo_i3rRB8l4OPIhm4vaTgsn-mdgtk6x8SmGR9zWHz9nN7OXdiiogVGwuOvdGs4z7EY09RWdxtxfaSRmJRhY8B9pqH-gTrNbguOMg_L-vZggAL_Gjf4XHU5fYmgQAlusyeDZMY_sqoHIiXddA/s5957/brown_wooden_bridge_over_snow_covered_ground-scopio-31c270a4-e4e3-4055-b148-7dad078d06e6.jpg" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="400" data-original-height="3972" data-original-width="5957" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-QBQhtenwbRL048k1x_r9Jm5mf622EnjMZ1nB3Ij6aVoo_i3rRB8l4OPIhm4vaTgsn-mdgtk6x8SmGR9zWHz9nN7OXdiiogVGwuOvdGs4z7EY09RWdxtxfaSRmJRhY8B9pqH-gTrNbguOMg_L-vZggAL_Gjf4XHU5fYmgQAlusyeDZMY_sqoHIiXddA/s400/brown_wooden_bridge_over_snow_covered_ground-scopio-31c270a4-e4e3-4055-b148-7dad078d06e6.jpg"/></a></div>
<label style="display:flex; justify-content: start; align-items: center; font-family: Barlow">
<a style="display:flex; align-items: center" href="https://scop.io">
<img height="20x" src="//cdn.shopify.com/s/files/1/2395/7099/files/Scopio_logo_Color_dark_140x.png?v=1604343350" style="margin: 0px 10px 0px 0px">
</a>
By
<a style="text-decoration: none; margin: 0px 5px;" href="https://scop.io/collections/vendors?q=Maxim%20Polak">Maxim Polak</a>
</label>
<p>Last night, <a href="https://drmsite.blogspot.com/2022/11/create-object-from-dot-notation.html">I created an object from an array of strings with dot notation</a>; I needed to do that because I had previously flattened an object into those strings. I did this long and laboriously, but I asked a colleague to see if he could figure out how to do it using recursion. He did, and I'd like to share it here.</p>
<p>If we have this object:</p>
<pre style='color:#000000;background:#ffffff;'><span style='color:#800080; '>{</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>thingOne</span><span style='color:#800000; '>"</span><span style='color:#800080; '>:</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>thingTwo</span><span style='color:#800000; '>"</span><span style='color:#800080; '>:</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>thingThree</span><span style='color:#800000; '>"</span><span style='color:#800080; '>:</span> <span style='color:#0f4d75; '>true</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>thingFour</span><span style='color:#800000; '>"</span><span style='color:#800080; '>:</span> <span style='color:#0f4d75; '>true</span>
<span style='color:#800080; '>}</span>
<span style='color:#800080; '>}</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>thingyOne</span><span style='color:#800000; '>"</span><span style='color:#800080; '>:</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>thingyTwo</span><span style='color:#800000; '>"</span><span style='color:#800080; '>:</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>thingyThree</span><span style='color:#800000; '>"</span><span style='color:#800080; '>:</span> <span style='color:#0f4d75; '>true</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>thingyFour</span><span style='color:#800000; '>"</span><span style='color:#800080; '>:</span> <span style='color:#0f4d75; '>true</span>
<span style='color:#800080; '>}</span>
<span style='color:#800080; '>}</span>
<span style='color:#800080; '>}</span>
</pre>
<p>Then this code:</p>
<pre style='color:#000000;background:#ffffff;'><span style='color:#808030; '>(</span><span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#808030; '>=</span><span style='color:#808030; '>></span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>const</span> obj <span style='color:#808030; '>=</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>thingOne</span><span style='color:#800000; '>"</span><span style='color:#800080; '>:</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>thingTwo</span><span style='color:#800000; '>"</span><span style='color:#800080; '>:</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>thingThree</span><span style='color:#800000; '>"</span><span style='color:#800080; '>:</span> <span style='color:#0f4d75; '>true</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>thingFour</span><span style='color:#800000; '>"</span><span style='color:#800080; '>:</span> <span style='color:#0f4d75; '>true</span>
<span style='color:#800080; '>}</span>
<span style='color:#800080; '>}</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>thingyOne</span><span style='color:#800000; '>"</span><span style='color:#800080; '>:</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>thingyTwo</span><span style='color:#800000; '>"</span><span style='color:#800080; '>:</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>thingyThree</span><span style='color:#800000; '>"</span><span style='color:#800080; '>:</span> <span style='color:#0f4d75; '>true</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>thingyFour</span><span style='color:#800000; '>"</span><span style='color:#800080; '>:</span> <span style='color:#0f4d75; '>true</span>
<span style='color:#800080; '>}</span>
<span style='color:#800080; '>}</span>
<span style='color:#800080; '>}</span>
<span style='color:#800000; font-weight:bold; '>const</span> getObjStringsArr <span style='color:#808030; '>=</span> <span style='color:#808030; '>(</span>o <span style='color:#808030; '>=</span> <span style='color:#800080; '>{</span><span style='color:#800080; '>}</span><span style='color:#808030; '>,</span> arr <span style='color:#808030; '>=</span> <span style='color:#808030; '>[</span><span style='color:#808030; '>]</span><span style='color:#808030; '>,</span> name <span style='color:#808030; '>=</span> <span style='color:#800000; '>'</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span> <span style='color:#808030; '>=</span><span style='color:#808030; '>></span> <span style='color:#800080; '>{</span>
<span style='color:#797997; '>Object</span><span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>keys</span><span style='color:#808030; '>(</span>o<span style='color:#808030; '>)</span><span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>forEach</span><span style='color:#808030; '>(</span>key <span style='color:#808030; '>=</span><span style='color:#808030; '>></span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>if</span> <span style='color:#808030; '>(</span>o<span style='color:#808030; '>[</span>key<span style='color:#808030; '>]</span> <span style='color:#808030; '>===</span> <span style='color:#0f4d75; '>true</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
arr<span style='color:#808030; '>.</span>push<span style='color:#808030; '>(</span><span style='color:#800000; '>`</span><span style='color:#800000; '>${</span><span style='color:#797997; '>name</span><span style='color:#800000; '>}</span><span style='color:#800000; '>${</span><span style='color:#797997; '>key</span><span style='color:#800000; '>}</span><span style='color:#800000; '>`</span><span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span> <span style='color:#800000; font-weight:bold; '>else</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>const</span> nested <span style='color:#808030; '>=</span> getObjStringsArr<span style='color:#808030; '>(</span>o<span style='color:#808030; '>[</span>key<span style='color:#808030; '>]</span><span style='color:#808030; '>,</span> arr<span style='color:#808030; '>,</span> <span style='color:#800000; '>`</span><span style='color:#800000; '>${</span><span style='color:#797997; '>name</span><span style='color:#800000; '>}</span><span style='color:#800000; '>${</span><span style='color:#797997; '>key</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>.</span><span style='color:#800000; '>`</span><span style='color:#808030; '>)</span>
arr<span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>concat</span><span style='color:#808030; '>(</span>nested<span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span>
<span style='color:#800080; '>}</span><span style='color:#808030; '>)</span><span style='color:#800080; '>;</span>
<span style='color:#800000; font-weight:bold; '>return</span> arr
<span style='color:#800080; '>}</span>
console<span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>log</span><span style='color:#808030; '>(</span>getObjStringsArr<span style='color:#808030; '>(</span>obj<span style='color:#808030; '>)</span><span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span><span style='color:#808030; '>)</span><span style='color:#808030; '>(</span><span style='color:#808030; '>)</span>
</pre>
<p>It's brilliant having colleagues; it's even better having colleagues with huge brains! Thanks, Hamish!</p>
<p>It's <a href="https://jsben.ch/ZvBb3">not necessarily faster than my cludge</a>, but it is far more elegant!</p>
DominicMyershttp://www.blogger.com/profile/15530669398436940737noreply@blogger.com0tag:blogger.com,1999:blog-6506998626989446594.post-15215073797198359732022-11-14T20:29:00.001+00:002022-11-15T08:41:27.304+00:00Create an Object from dot notation<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3d6ySOsuTKolxA4GfF7ZjGH6ozm6Vx22QsQkDYU-jA-1Ta8pN5IUs-rBG52RqI40q1KTWg9Vcr4rmWxM3BixclKHW2fELiZdOU93ODdaI-NhitACdu5uY4YOd8Zd-X_rTosb7SkqY5cy0r8UogowWC_54OYpcknvm5V5lBuMW0a3rjwCBjNBGYxlA9g/s3284/brown_and_black_dragonfly_on_brown_stick-scopio-f03ed555-eaee-4bc8-a1d3-5a3e4697643e.jpg" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="400" data-original-height="2181" data-original-width="3284" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3d6ySOsuTKolxA4GfF7ZjGH6ozm6Vx22QsQkDYU-jA-1Ta8pN5IUs-rBG52RqI40q1KTWg9Vcr4rmWxM3BixclKHW2fELiZdOU93ODdaI-NhitACdu5uY4YOd8Zd-X_rTosb7SkqY5cy0r8UogowWC_54OYpcknvm5V5lBuMW0a3rjwCBjNBGYxlA9g/s400/brown_and_black_dragonfly_on_brown_stick-scopio-f03ed555-eaee-4bc8-a1d3-5a3e4697643e.jpg"/></a></div>
<label style="display:flex; justify-content: start; align-items: center; font-family: Barlow">
<a style="display:flex; align-items: center" href="https://scop.io">
<img height="20x" src="//cdn.shopify.com/s/files/1/2395/7099/files/Scopio_logo_Color_dark_140x.png?v=1604343350" style="margin: 0px 10px 0px 0px">
</a>
By
<a style="text-decoration: none; margin: 0px 5px;" href="https://scop.io/collections/vendors?q=Oleksandr%20Klymovych">Oleksandr Klymovych</a>
</label>
<p>This was puzzling me all afternoon, and I came up with a bloody terrible work-around using <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval"><code>eval</code></a>, this evening I decided to do a little more research and found <a href="https://stackoverflow.com/questions/31464393/javascript-how-to-create-an-object-from-a-dot-separated-string#31464652">this answer</a> on StackOverflow.</p>
<p>I've adapted it and it seems to work a treat:</p>
<pre style='color:#000000;background:#ffffff;overflow-x:auto;'><span style='color:#808030; '>(</span><span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#808030; '>=</span><span style='color:#808030; '>></span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>const</span> obj <span style='color:#808030; '>=</span> <span style='color:#800080; '>{</span><span style='color:#800080; '>}</span>
<span style='color:#800000; font-weight:bold; '>const</span> expand <span style='color:#808030; '>=</span> <span style='color:#808030; '>(</span>output<span style='color:#808030; '>,</span> mystr<span style='color:#808030; '>,</span> value<span style='color:#808030; '>)</span> <span style='color:#808030; '>=</span><span style='color:#808030; '>></span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>const</span> items <span style='color:#808030; '>=</span> mystr<span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>split</span><span style='color:#808030; '>(</span><span style='color:#800000; '>"</span><span style='color:#0000e6; '>.</span><span style='color:#800000; '>"</span><span style='color:#808030; '>)</span> <span style='color:#696969; '>// split on dot notation</span>
<span style='color:#800000; font-weight:bold; '>let</span> ref <span style='color:#808030; '>=</span> output <span style='color:#696969; '>// keep a reference of the new object</span>
<span style='color:#696969; '>// loop through all nodes, except the last one</span>
<span style='color:#800000; font-weight:bold; '>for</span> <span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>let</span> i <span style='color:#808030; '>=</span> <span style='color:#008c00; '>0</span><span style='color:#800080; '>;</span> i <span style='color:#808030; '><</span> items<span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>length</span> <span style='color:#808030; '>-</span> <span style='color:#008c00; '>1</span><span style='color:#800080; '>;</span> i<span style='color:#808030; '>++</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>if</span> <span style='color:#808030; '>(</span><span style='color:#808030; '>!</span>ref<span style='color:#808030; '>[</span>items<span style='color:#808030; '>[</span>i<span style='color:#808030; '>]</span><span style='color:#808030; '>]</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#696969; '>// create a new element inside the reference</span>
ref<span style='color:#808030; '>[</span>items<span style='color:#808030; '>[</span>i<span style='color:#808030; '>]</span><span style='color:#808030; '>]</span> <span style='color:#808030; '>=</span> <span style='color:#800080; '>{</span><span style='color:#800080; '>}</span>
<span style='color:#800080; '>}</span>
ref <span style='color:#808030; '>=</span> ref<span style='color:#808030; '>[</span>items<span style='color:#808030; '>[</span>i<span style='color:#808030; '>]</span><span style='color:#808030; '>]</span> <span style='color:#696969; '>// shift the reference to the newly created object </span>
<span style='color:#800080; '>}</span>
ref<span style='color:#808030; '>[</span>items<span style='color:#808030; '>[</span>items<span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>length</span> <span style='color:#808030; '>-</span> <span style='color:#008c00; '>1</span><span style='color:#808030; '>]</span><span style='color:#808030; '>]</span> <span style='color:#808030; '>=</span> value <span style='color:#696969; '>// apply the final value</span>
<span style='color:#800000; font-weight:bold; '>return</span> output <span style='color:#696969; '>// return the full object</span>
<span style='color:#800080; '>}</span>
<span style='color:#800000; font-weight:bold; '>const</span> arr <span style='color:#808030; '>=</span> <span style='color:#808030; '>[</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>thingOne.thingTwo.thingThree</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>thingOne.thingTwo.thingFour</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>thingyOne.thingyTwo.thingyThree</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>thingyOne.thingyTwo.thingyFour</span><span style='color:#800000; '>"</span>
<span style='color:#808030; '>]</span>
arr<span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>forEach</span><span style='color:#808030; '>(</span>a <span style='color:#808030; '>=</span><span style='color:#808030; '>></span> <span style='color:#800080; '>{</span>
expand<span style='color:#808030; '>(</span>obj<span style='color:#808030; '>,</span> a<span style='color:#808030; '>,</span> <span style='color:#0f4d75; '>true</span><span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span><span style='color:#808030; '>)</span>
console<span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>log</span><span style='color:#808030; '>(</span>obj<span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span><span style='color:#808030; '>)</span><span style='color:#808030; '>(</span><span style='color:#808030; '>)</span>
</pre>
<p>I was nearly there on my tod TBH, but wussed out at the end, thisis lovely though! It produces this lovely object:</p>
<pre style='color:#000000;background:#ffffff;'><span style='color:#696969; '>{</span>
<span style='color:#696969; '>  "thingOne": {</span>
<span style='color:#696969; '>    "thingTwo": {</span>
<span style='color:#696969; '>      "thingThree": true,</span>
<span style='color:#696969; '>      "thingFour": true</span>
<span style='color:#696969; '>    }</span>
}<span style='color:#808030; '>,</span>
"thingyOne"<span style='color:#808030; '>:</span> <span style='color:#696969; '>{</span>
<span style='color:#696969; '>    "thingyTwo": {</span>
<span style='color:#696969; '>      "thingyThree": true,</span>
<span style='color:#696969; '>      "thingyFour": true</span>
<span style='color:#696969; '>    }</span>
}
}
</pre>DominicMyershttp://www.blogger.com/profile/15530669398436940737noreply@blogger.com0tag:blogger.com,1999:blog-6506998626989446594.post-7255014923024758482022-10-06T08:38:00.001+01:002022-10-06T08:45:45.488+01:00Democide<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKPWPPMMbwR0hQ78BLXYO-jZI5PHfPelBd-JbPQxufEsDuceCQ04UDEeqEXRXx431nmGFBN1hAwMkOEweX7w8_TWvkUC2DZLVjsQKg-FkAFqK81yKqoKhWDtXmctFDbpSnKwvhbeCMU9pY50WAgj82R4g-F3-7GuZX2WB7HohgGbVENoVpBXuc6EoFNw/s742/Deaths%20vs%20Regime.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="400" data-original-height="458" data-original-width="742" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKPWPPMMbwR0hQ78BLXYO-jZI5PHfPelBd-JbPQxufEsDuceCQ04UDEeqEXRXx431nmGFBN1hAwMkOEweX7w8_TWvkUC2DZLVjsQKg-FkAFqK81yKqoKhWDtXmctFDbpSnKwvhbeCMU9pY50WAgj82R4g-F3-7GuZX2WB7HohgGbVENoVpBXuc6EoFNw/s400/Deaths%20vs%20Regime.png"/></a></div>
<p>As reported in The Guardian in 2019, the Institute of Public Policy Research (IPPR) said more than <a href="https://www.theguardian.com/politics/2019/jun/01/perfect-storm-austerity-behind-130000-deaths-uk-ippr-report" target="_blank">"130,000 deaths in the UK since 2012 could have been prevented if improvements in public health policy had not stalled as a direct result of austerity cuts"</a>. More conservatively, the British Medical Journal (BMJ) said that in 2017, austerity was linked to 120,000 extra deaths in England (just in England, not Scotland, Wales or Northern Ireland). In 2018, the Office for National Statistics (ONS) showed a fall in life expectancy for poorer socioeconomic groups and those living in more impoverished areas.</p>
<p>So, it's not like we've not known the Tories have had an appalling impact on our population, but, on top of these utterly shocking figures, we're now presented with yet more. The Independent reported today (05/10/2022), <a href="https://www.independent.co.uk/news/uk/politics/uk-covid-economic-policy-deaths-b2195813.html" target="_blank">"The UK government's economic policies are 'likely' to have caused a 'great many more deaths' than the Covid Pandemic, an academic has claimed"</a>. The Independent used an article from the Journal of Epidemiology and Community Health (JECH) titled <a href="https://jech.bmj.com/content/early/2022/09/26/jech-2022-219645?rss=1" target="_blank">"Bearing the burden of austerity: how do changing mortality rates in the UK compare between men and women?"</a> by Walsh, Dundas, McCartney, Gibson and Seaman. Walsh et al. looked at previous statistics, compared actual figures with predicted figures, and came up with the eye-watering figure of 335,000 deaths between 2012 and 2019. Hang about, though; those figures don't include those deaths from the COVID-19 epidemic.</p>
<p>According to the Government's own <a href="https://coronavirus.data.gov.uk/details/deaths" target="_blank">website today</a> (05/10/2022), there have been 177,977 "deaths within 28 days of being identified as a COVID-19 case by a positive test, reported up to Friday, 20 May 2022". Is anyone else confused by that date? 20 May 2022? Maybe I'm being paranoid; maybe it's not been updated in a while. Perhaps we don't know how many actual deaths from COVID-19 there have been since the start of the Pandemic.</p>
<p>There can be little doubt that the Tories cost lives during the Pandemic. <a href="https://committees.parliament.uk/committee/81/health-and-social-care-committee/news/157991/coronavirus-lessons-learned-to-date-report-published/" target="_blank">A joint report by the House of Commons Science and Technology Committee and the Health and Social Care Committee</a> condemned severe errors, including delayed lockdowns and how a test, trace and isolate system was set up. It did praise the vaccination programme, though. Funnily enough, the Government took credit for the vaccination programme while crediting the NHS with their disastrous Test and Trace program.</p>
<p>I'm not sure what proportion of that 177,977 needs to be added to the 335,000 death toll of the Tories; whatever figure we'll end up with, it's fair to say that the Tories are guilty of <a href="https://hawaii.edu/powerkills/DBG.CHAP2.HTM" target="_blank">Democide</a>.</p>
<p>If we look at the percentages, the Tories have done a grand job of killing half a per cent of the population; <a href="https://www.theguardian.com/politics/2021/apr/26/pressure-mounts-on-boris-johnson-over-alleged-let-the-bodies-pile-high-remarks" target="_blank">"let the bodies pile high in their thousands"</a>, indeed!</p>
<p>The chart at the top, it must be noted, uses a logarithmic scale. So, while the Tories aren't guilty of Mega-murder, nor Deka-mega-murder, they are guilty of Hecto-kilo-murder - and that's us they've been killing (Thank you, <a href="https://en.wikipedia.org/wiki/Deca-" target="_blank">Wikipedia</a>, for the pre-fixes)!</p>
DominicMyershttp://www.blogger.com/profile/15530669398436940737noreply@blogger.com0tag:blogger.com,1999:blog-6506998626989446594.post-88781869302094471912022-09-30T09:26:00.000+01:002022-09-30T09:26:00.700+01:00wc-slider (An alternative to the range input)<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimlVaQFhzxQDg3BonYWPcSTQwxRF3Vrlz_079FdVHuGIovppQLz4l1zTFsvEjv0MvMENTHFkrMIVjuNKUqJKi_ycVJin4u3RlL7BzjVnyLJHTclRJOPKjzNfQa6V7rYZOmS5a6tZlg-LfElpL32ByE-K8sXWLITAJn8WT72GxzrinCi2qyvgSQsv4Izw/s5760/woman_in_white_sports_bra_and_pink_panty_standing_on_black_round_plastic_slide-scopio-6aeaea03-eb12-4a6b-ae58-35c3afb24e39.jpg" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="400" data-original-height="3840" data-original-width="5760" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimlVaQFhzxQDg3BonYWPcSTQwxRF3Vrlz_079FdVHuGIovppQLz4l1zTFsvEjv0MvMENTHFkrMIVjuNKUqJKi_ycVJin4u3RlL7BzjVnyLJHTclRJOPKjzNfQa6V7rYZOmS5a6tZlg-LfElpL32ByE-K8sXWLITAJn8WT72GxzrinCi2qyvgSQsv4Izw/s400/woman_in_white_sports_bra_and_pink_panty_standing_on_black_round_plastic_slide-scopio-6aeaea03-eb12-4a6b-ae58-35c3afb24e39.jpg"/></a></div>
<label style="display:flex; justify-content: start; align-items: center; font-family: Barlow">
<a style="display:flex; align-items: center" href="https://scop.io">
<img height="20x" src="//cdn.shopify.com/s/files/1/2395/7099/files/Scopio_logo_Color_dark_140x.png?v=1604343350" style="margin: 0px 10px 0px 0px">
</a>
By
<a style="text-decoration: none; margin: 0px 5px;" href="https://scop.io/collections/vendors?q=Maksim%20Chernyshev">Maksim Chernyshev</a>
</label>
<p>HTML is brilliant; it's an ever-growing standard; CSS is also pretty amazing! I say this because I was bored over the evenings this week and brushed off an old thing I started years ago to help me with the inability to style range inputs. You can do some cool styling on range inputs now, but when I created my initial component, it wasn't easy and involved many vendor prefixes, with some target browsers unable to handle even those. So I decided to write a <a href="https://jsfiddle.net/annoyingmouse/gy9ctzfm/10/">component</a> to get our designer's desired effect.</p>
<p>But I was bored this week, so I decided to revisit it; you can see the result on <a href="https://jsfiddle.net/annoyingmouse/ozt3hx1g/">JSFiddle</a>.</p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgS9Ph0nIx7Pc7jVVlmhlI4sZXr9cVFSBhbsRp3rrjNvH31yaWMHKlYr0o7Uh4PEhvhI9vqVHQ7wtmbrZI0jY3BX-a0WFkKJ-DMHB0vXbF6jCwn7SbYq1WVo9q3gXl5N1ztmwBjN3OK53E8_tLSQDMiF3X_UJn6DHrE9oSOp_-Iw8hj-cnse2bIKSaUtw/s689/Screenshot%202022-09-30%20091610.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="400" data-original-height="115" data-original-width="689" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgS9Ph0nIx7Pc7jVVlmhlI4sZXr9cVFSBhbsRp3rrjNvH31yaWMHKlYr0o7Uh4PEhvhI9vqVHQ7wtmbrZI0jY3BX-a0WFkKJ-DMHB0vXbF6jCwn7SbYq1WVo9q3gXl5N1ztmwBjN3OK53E8_tLSQDMiF3X_UJn6DHrE9oSOp_-Iw8hj-cnse2bIKSaUtw/s400/Screenshot%202022-09-30%20091610.png"/></a></div>
<p>It was a lot of fun doing this, I'm not sure if I'll ever need it again, but it was a valuable learning experience. Asking for help from a mate meant that she could echo back something I've said to her many times before: "Have you tried flex?", so embarrassing, but it just goes to show! One issue was that I was sticking to the original CSS too much and didn't have to cope with variable-sized wc-sliders. You see, the little arrows behind the slider element moved depending on the number of elements in the slider.</p>
<p>The Drag-and-Drop mechanism took the most time and - as a result of checking my workings - I clocked I was using the getters for <code>range</code>, <code>colourRange</code> and <code>deselectedRange</code> far too much. I moved these to <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields">Private class features</a> and only calculate them on <code>render()</code>. Thanks to the dictates of working with a designer, I also spent a fair bit of effort working with colours and gradients - a bit of a ballache, TBH, but I've got the functions now so that I can use them again in the future!</p>
<p>I do like the <code>invertColor(hex, bw)</code> though. That's tremendous fun and might be useful should you check what colour you need to set text atop different coloured backgrounds. Looking at it again now, though, I think the none <code>bw</code> might be a little borked; I'll fix it as and when I've time.</p>
<p>It's a bit CSS-heavy, but no worse for that, TBH; if you can do something with CSS, then it's better than firing up JS - let the browser do the work!</p>
<p>From the README:</p>
<ul>
<li>Dragging the slider element will alter the value surfaced by the component from its <code>value</code> attribute (should the number in which the drop ends be greater than or equal to the <code>constrain-min</code> or less than or equal to the <code>constrain-max</code>)</li>
<li>Clicking on the numbers shown at the top of each step will alter the value surfaced by the component from its <code>value</code> attribute (should the number be greater than or equal to the <code>constrain-min</code> or less than or equal to the <code>constrain-max</code>).</li>
<li>Clicking on the triangles on either side of the slider will alter the value surfaced by the component from its <code>value</code> attribute by +/- 1 (should the number resulting from the click be greater than or equal to the <code>constrain-min</code> or less than or equal to the <code>constrain-max</code>).</li>
</ul>
<p>As you can doubtless see, there are three ways of changing the value and - given the work I put into checking the bugger, no way for an invalid <code>value</code> to be produced - though you might not like the <code>value</code>. Having said that, if you manage to break it, <a href="https://github.com/annoyingmouse/wc-slider/issues">please let me know</a>, so I can fix it!</p>
<p>It has some default attributes so that you can test it for your use case.</p>
<p>Again, from the README:</p>
<ul>
<li>The range of numbers, inclusive of min and max, should not be too large - tests have found that the ranges should not have more than 15 numbers, but <abbr title="Your Mileage May Vary">YMMV</abbr>.</li>
</ul>
<p>One thing to consider in the future is whether or not to allow for a comma-separated list of hex values so that designers can adequately define what colours should appear on the <a href="https://www.npmjs.com/package/@annoyingmouse/wc-slider">wc-slider</a>.</p>DominicMyershttp://www.blogger.com/profile/15530669398436940737noreply@blogger.com0tag:blogger.com,1999:blog-6506998626989446594.post-40221995972545823072022-09-21T15:34:00.001+01:002022-09-21T15:34:49.740+01:00Fixing the Donut<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgv0o0C5R78CUk1w2UyMPE8AtFHoc0UG_KJrygNDQMW6U8F8MUzrE87u0-WeUurOB-su9bBSosTDlZ3TZg-Gsr8xf4KE4lxc2nD1FlHd0o_UBpFcI3gA-A-h8MlHRLjY8OYiLAtSHW6jGK4fuO-2xMRgcArB7jpYeys5ZYCP_UmXX4BfY4UD8xWeJPY9A/s5077/woman_in_pink_inflatable_donut_on_beach-scopio-8f8d1ec8-3f76-4c7c-8f60-ed9b16e7746e.jpg" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="400" data-original-height="4062" data-original-width="5077" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgv0o0C5R78CUk1w2UyMPE8AtFHoc0UG_KJrygNDQMW6U8F8MUzrE87u0-WeUurOB-su9bBSosTDlZ3TZg-Gsr8xf4KE4lxc2nD1FlHd0o_UBpFcI3gA-A-h8MlHRLjY8OYiLAtSHW6jGK4fuO-2xMRgcArB7jpYeys5ZYCP_UmXX4BfY4UD8xWeJPY9A/s400/woman_in_pink_inflatable_donut_on_beach-scopio-8f8d1ec8-3f76-4c7c-8f60-ed9b16e7746e.jpg"/></a></div>
<label style="display:flex; justify-content: start; align-items: center; font-family: Barlow">
<a style="display:flex; align-items: center" href="https://scop.io">
<img height="20x" src="//cdn.shopify.com/s/files/1/2395/7099/files/Scopio_logo_Color_dark_140x.png?v=1604343350" style="margin: 0px 10px 0px 0px">
</a>
By
<a style="text-decoration: none; margin: 0px 5px;" href="https://scop.io/collections/vendors?q=Jessica%20May">Jessica May</a>
</label>
<p>I've been playing with a <a href="https://drmsite.blogspot.com/2022/06/doughnut-donut-chart-web-component.html">pie-chart web component</a> for a little while now, and I was thrilled with the result... until I started to use it in anger, that is.</p>
<p>The thing was, angles over 180 messed something up - I decided to revisit it this week after reading this <a href="https://www.freecodecamp.org/news/css-only-pie-chart/">article</a> by Temani Afif, and I'm once again thrilled to see it working - and working correctly (at least in Chrome and Edge):</p>
<pre style='color:#000000;background:#ffffff;overflow-x:auto;'><span style='color:#800000; font-weight:bold; '>class</span> DMPieChart <span style='color:#800000; font-weight:bold; '>extends</span> HTMLElement <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>static</span> get observedAttributes<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>return</span> <span style='color:#808030; '>[</span>
<span style='color:#800000; '>'</span><span style='color:#0000e6; '>width</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span> <span style='color:#696969; '>// width of the chart</span>
<span style='color:#800000; '>'</span><span style='color:#0000e6; '>duration</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span> <span style='color:#696969; '>// duration of the animation</span>
<span style='color:#800000; '>'</span><span style='color:#0000e6; '>delay</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span> <span style='color:#696969; '>// delay before the animation</span>
<span style='color:#800000; '>'</span><span style='color:#0000e6; '>thickness</span><span style='color:#800000; '>'</span> <span style='color:#696969; '>// thickness of the slices</span>
<span style='color:#808030; '>]</span><span style='color:#800080; '>;</span>
<span style='color:#800080; '>}</span>
get style<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>return</span><span style='color:#800000; '> `</span><span style='color:#0000e6; '></span>
<span style='color:#0000e6; '>      <style></span>
<span style='color:#0000e6; '>        * {</span>
<span style='color:#0000e6; '>          box-sizing: border-box;</span>
<span style='color:#0000e6; '>        }</span>
<span style='color:#0000e6; '>        div {</span>
<span style='color:#0000e6; '>          width: </span><span style='color:#800000; '>${</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span><span style='color:#797997; '>width</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>px;</span>
<span style='color:#0000e6; '>          height: </span><span style='color:#800000; '>${</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span><span style='color:#797997; '>width</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>px;</span>
<span style='color:#0000e6; '>          position: relative;</span>
<span style='color:#0000e6; '>        }</span>
<span style='color:#0000e6; '>      </style></span>
<span style='color:#0000e6; '>    </span><span style='color:#800000; '>`</span>
<span style='color:#800080; '>}</span>
<span style='color:#797997; '>constructor</span><span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>super</span><span style='color:#808030; '>(</span><span style='color:#808030; '>)</span>
<span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>shadow <span style='color:#808030; '>=</span> <span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>attachShadow<span style='color:#808030; '>(</span><span style='color:#800080; '>{</span>
mode<span style='color:#800080; '>:</span> <span style='color:#800000; '>'</span><span style='color:#0000e6; '>closed</span><span style='color:#800000; '>'</span>
<span style='color:#800080; '>}</span><span style='color:#808030; '>)</span>
<span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>shadow<span style='color:#808030; '>.</span>innerHTML <span style='color:#808030; '>=</span> <span style='color:#800000; '>`</span><span style='color:#0000e6; '></span>
<span style='color:#0000e6; '>      </span><span style='color:#800000; '>${</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span><span style='color:#797997; '>style</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '></span>
<span style='color:#0000e6; '>      <div></span>
<span style='color:#0000e6; '>        <slot name='pie-slices'></slot></span>
<span style='color:#0000e6; '>      </div></span>
<span style='color:#0000e6; '>    </span><span style='color:#800000; '>`</span>
<span style='color:#800000; font-weight:bold; '>try</span> <span style='color:#800080; '>{</span>
window<span style='color:#808030; '>.</span>CSS<span style='color:#808030; '>.</span>registerProperty<span style='color:#808030; '>(</span><span style='color:#800080; '>{</span>
name<span style='color:#800080; '>:</span> <span style='color:#800000; '>'</span><span style='color:#0000e6; '>--p</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span>
syntax<span style='color:#800080; '>:</span> <span style='color:#800000; '>'</span><span style='color:#0000e6; '><number></span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span>
inherits<span style='color:#800080; '>:</span> <span style='color:#0f4d75; '>true</span><span style='color:#808030; '>,</span>
initialValue<span style='color:#800080; '>:</span> <span style='color:#008c00; '>0</span><span style='color:#808030; '>,</span>
<span style='color:#800080; '>}</span><span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span><span style='color:#800000; font-weight:bold; '>catch</span> <span style='color:#808030; '>(</span>e<span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
console<span style='color:#808030; '>.</span>warn<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>Browser does not support animated conical gradients</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span>
<span style='color:#800080; '>}</span>
connectedCallback<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>const</span> segments <span style='color:#808030; '>=</span> <span style='color:#808030; '>[</span><span style='color:#808030; '>.</span><span style='color:#808030; '>.</span><span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>querySelectorAll<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>dm-pie-slice</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span><span style='color:#808030; '>]</span>
<span style='color:#800000; font-weight:bold; '>const</span> total <span style='color:#808030; '>=</span> segments<span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>reduce</span><span style='color:#808030; '>(</span><span style='color:#808030; '>(</span>p<span style='color:#808030; '>,</span> c<span style='color:#808030; '>)</span> <span style='color:#808030; '>=</span><span style='color:#808030; '>></span> p <span style='color:#808030; '>+</span> <span style='color:#797997; '>Number</span><span style='color:#808030; '>(</span>c<span style='color:#808030; '>.</span>getAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>value</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span><span style='color:#808030; '>)</span><span style='color:#808030; '>,</span> <span style='color:#008c00; '>0</span><span style='color:#808030; '>)</span>
<span style='color:#800000; font-weight:bold; '>let</span> durationTotal <span style='color:#808030; '>=</span> <span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>delay<span style='color:#800080; '>;</span>
<span style='color:#800000; font-weight:bold; '>let</span> rotationTotal <span style='color:#808030; '>=</span> <span style='color:#008c00; '>0</span>
<span style='color:#800000; font-weight:bold; '>const</span> totalDegree <span style='color:#808030; '>=</span> <span style='color:#008c00; '>360</span><span style='color:#808030; '>/</span>total
segments<span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>forEach</span><span style='color:#808030; '>(</span>segment <span style='color:#808030; '>=</span><span style='color:#808030; '>></span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>const</span> value <span style='color:#808030; '>=</span> <span style='color:#797997; '>Number</span><span style='color:#808030; '>(</span>segment<span style='color:#808030; '>.</span>getAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>value</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span><span style='color:#808030; '>)</span>
<span style='color:#800000; font-weight:bold; '>const</span> currentRotation <span style='color:#808030; '>=</span> totalDegree <span style='color:#808030; '>*</span> value
<span style='color:#800000; font-weight:bold; '>const</span> animationDuration <span style='color:#808030; '>=</span> currentRotation <span style='color:#808030; '>/</span> <span style='color:#808030; '>(</span><span style='color:#008c00; '>360</span><span style='color:#808030; '>/</span><span style='color:#797997; '>Number</span><span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>duration<span style='color:#808030; '>)</span><span style='color:#808030; '>)</span>
segment<span style='color:#808030; '>.</span>setAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>thickness</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span> <span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>thickness <span style='color:#808030; '>*</span> <span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>width<span style='color:#808030; '>)</span>
segment<span style='color:#808030; '>.</span>setAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>end</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span> <span style='color:#808030; '>(</span>value <span style='color:#808030; '>/</span> total<span style='color:#808030; '>)</span> <span style='color:#808030; '>*</span> <span style='color:#008c00; '>100</span><span style='color:#808030; '>)</span>
segment<span style='color:#808030; '>.</span>setAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>rotate</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span> rotationTotal<span style='color:#808030; '>)</span>
segment<span style='color:#808030; '>.</span>setAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>delay</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span> durationTotal<span style='color:#808030; '>)</span>
segment<span style='color:#808030; '>.</span>setAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>duration</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span> animationDuration<span style='color:#808030; '>)</span>
segment<span style='color:#808030; '>.</span>setAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>width</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span> <span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>width<span style='color:#808030; '>)</span>
rotationTotal <span style='color:#808030; '>+=</span> currentRotation
durationTotal <span style='color:#808030; '>+=</span> animationDuration
<span style='color:#800080; '>}</span><span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span>
get width<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>return</span> <span style='color:#797997; '>Number</span><span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>getAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>width</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span><span style='color:#808030; '>)</span> <span style='color:#808030; '>||</span> <span style='color:#008c00; '>150</span> <span style='color:#696969; '>// 150px by default</span>
<span style='color:#800080; '>}</span>
get duration<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>return</span> <span style='color:#797997; '>Number</span><span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>getAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>duration</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span><span style='color:#808030; '>)</span> <span style='color:#808030; '>||</span> <span style='color:#008c00; '>5000</span> <span style='color:#696969; '>// 5 seconds by default</span>
<span style='color:#800080; '>}</span>
get delay<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>return</span> <span style='color:#797997; '>Number</span><span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>getAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>delay</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span><span style='color:#808030; '>)</span> <span style='color:#808030; '>||</span> <span style='color:#008c00; '>500</span> <span style='color:#696969; '>// half a second by default</span>
<span style='color:#800080; '>}</span>
get thickness<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>return</span> <span style='color:#797997; '>Number</span><span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>getAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>thickness</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span><span style='color:#808030; '>)</span> <span style='color:#808030; '>||</span> <span style='color:#008000; '>0.2</span> <span style='color:#696969; '>// 60% of width by default</span>
<span style='color:#800080; '>}</span>
<span style='color:#800080; '>}</span>
<span style='color:#800000; font-weight:bold; '>class</span> DMPieSlice <span style='color:#800000; font-weight:bold; '>extends</span> HTMLElement<span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>static</span> get observedAttributes<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>return</span> <span style='color:#808030; '>[</span>
<span style='color:#800000; '>'</span><span style='color:#0000e6; '>width</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span> <span style='color:#696969; '>// width of the chart</span>
<span style='color:#800000; '>'</span><span style='color:#0000e6; '>duration</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span> <span style='color:#696969; '>// duration of the animation</span>
<span style='color:#800000; '>'</span><span style='color:#0000e6; '>delay</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span> <span style='color:#696969; '>// delay before the animation</span>
<span style='color:#800000; '>'</span><span style='color:#0000e6; '>color</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span> <span style='color:#696969; '>// color of the arc</span>
<span style='color:#800000; '>'</span><span style='color:#0000e6; '>thickness</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span> <span style='color:#696969; '>// thickness of the arc</span>
<span style='color:#800000; '>'</span><span style='color:#0000e6; '>rotate</span><span style='color:#800000; '>'</span> <span style='color:#696969; '>// how far to rotate the arc</span>
<span style='color:#808030; '>]</span><span style='color:#800080; '>;</span>
<span style='color:#800080; '>}</span>
get style<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>return</span><span style='color:#800000; '> `</span><span style='color:#0000e6; '></span>
<span style='color:#0000e6; '>      <style></span>
<span style='color:#0000e6; '>        * {</span>
<span style='color:#0000e6; '>          box-sizing: border-box;</span>
<span style='color:#0000e6; '>        }</span>
<span style='color:#0000e6; '>        div {</span>
<span style='color:#0000e6; '>          --p: </span><span style='color:#800000; '>${</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span><span style='color:#797997; '>end</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>;</span>
<span style='color:#0000e6; '>          width: </span><span style='color:#800000; '>${</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span><span style='color:#797997; '>width</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>px;</span>
<span style='color:#0000e6; '>          aspect-ratio: 1;</span>
<span style='color:#0000e6; '>          margin: 0;</span>
<span style='color:#0000e6; '>          position: absolute;</span>
<span style='color:#0000e6; '>          left: 50%;</span>
<span style='color:#0000e6; '>          top: 50%;</span>
<span style='color:#0000e6; '>          animation-name: p;</span>
<span style='color:#0000e6; '>          animation-fill-mode: both;</span>
<span style='color:#0000e6; '>          animation-timing-function: ease-in-out;</span>
<span style='color:#0000e6; '>          transform: translate(-50%, -50%);</span>
<span style='color:#0000e6; '>          animation-duration: </span><span style='color:#800000; '>${</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span><span style='color:#797997; '>duration</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>ms;</span>
<span style='color:#0000e6; '>          animation-delay: </span><span style='color:#800000; '>${</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span><span style='color:#797997; '>delay</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>ms;</span>
<span style='color:#0000e6; '>        }</span>
<span style='color:#0000e6; '>        div:before {</span>
<span style='color:#0000e6; '>          content: "";</span>
<span style='color:#0000e6; '>          position: absolute;</span>
<span style='color:#0000e6; '>          border-radius: 50%;</span>
<span style='color:#0000e6; '>          inset: 0;</span>
<span style='color:#0000e6; '>          background: conic-gradient(from </span><span style='color:#800000; '>${</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span><span style='color:#797997; '>rotate</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>deg, </span><span style='color:#800000; '>${</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span><span style='color:#797997; '>color</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '> calc(var(--p)*1%), transparent 0);</span>
<span style='color:#0000e6; '>          -webkit-mask: radial-gradient(farthest-side, transparent calc(99% - </span><span style='color:#800000; '>${</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span><span style='color:#797997; '>thickness</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>px), #000 calc(100% - </span><span style='color:#800000; '>${</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span><span style='color:#797997; '>thickness</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>px));</span>
<span style='color:#0000e6; '>          mask: radial-gradient(farthest-side,#0000 calc(99% - </span><span style='color:#800000; '>${</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span><span style='color:#797997; '>thickness</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>px), #000 calc(100% - </span><span style='color:#800000; '>${</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span><span style='color:#797997; '>thickness</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>px));</span>
<span style='color:#0000e6; '>        }</span>
<span style='color:#0000e6; '>        @keyframes p {</span>
<span style='color:#0000e6; '>          from {</span>
<span style='color:#0000e6; '>            --p: 0</span>
<span style='color:#0000e6; '>          }</span>
<span style='color:#0000e6; '>        }</span>
<span style='color:#0000e6; '>      </style></span>
<span style='color:#0000e6; '>    </span><span style='color:#800000; '>`</span>
<span style='color:#800080; '>}</span>
<span style='color:#797997; '>constructor</span><span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>super</span><span style='color:#808030; '>(</span><span style='color:#808030; '>)</span><span style='color:#800080; '>;</span>
<span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>shadow <span style='color:#808030; '>=</span> <span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>attachShadow<span style='color:#808030; '>(</span><span style='color:#800080; '>{</span>
mode<span style='color:#800080; '>:</span> <span style='color:#800000; '>'</span><span style='color:#0000e6; '>closed</span><span style='color:#800000; '>'</span>
<span style='color:#800080; '>}</span><span style='color:#808030; '>)</span>
<span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>shadow<span style='color:#808030; '>.</span>innerHTML <span style='color:#808030; '>=</span> <span style='color:#800000; '>`</span><span style='color:#800000; '>${</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span><span style='color:#797997; '>style</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '><div/></span><span style='color:#800000; '>`</span>
<span style='color:#800080; '>}</span>
get width<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>return</span> <span style='color:#797997; '>Number</span><span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>getAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>width</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span><span style='color:#808030; '>)</span> <span style='color:#808030; '>||</span> <span style='color:#008c00; '>150</span> <span style='color:#696969; '>// 150px by default</span>
<span style='color:#800080; '>}</span>
get duration<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>return</span> <span style='color:#797997; '>Number</span><span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>getAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>duration</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span><span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span>
get delay<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>return</span> <span style='color:#797997; '>Number</span><span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>getAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>delay</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span><span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span>
get color<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>return</span> <span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>getAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>color</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span> <span style='color:#808030; '>||</span> <span style='color:#800000; '>'</span><span style='color:#0000e6; '>#000000</span><span style='color:#800000; '>'</span> <span style='color:#696969; '>// black by default</span>
<span style='color:#800080; '>}</span>
get thickness<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>return</span> <span style='color:#797997; '>Number</span><span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>getAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>thickness</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span><span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span>
get rotate<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>return</span> <span style='color:#797997; '>Number</span><span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>getAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>rotate</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span><span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span>
get end<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>return</span> <span style='color:#797997; '>Number</span><span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>getAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>end</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span><span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span>
<span style='color:#800080; '>}</span>
window<span style='color:#808030; '>.</span>customElements<span style='color:#808030; '>.</span>define<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>dm-pie-chart</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span> DMPieChart<span style='color:#808030; '>)</span>
window<span style='color:#808030; '>.</span>customElements<span style='color:#808030; '>.</span>define<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>dm-pie-slice</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span> DMPieSlice<span style='color:#808030; '>)</span>
</pre>
<p>It is significantly cleaner but only animates within Chrome and Edge (everywhere else, it should just appear without animation, which is a shame).</p>
<p>I've also moved away from using the <a href="https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet">CSSStyleSheet</a> interface as Safari throws a wobble when it's used without a <a href="https://www.npmjs.com/package/construct-style-sheets-polyfill">polyfill</a>, which is a shame as constructible/adoptable style sheets rock!</p>
<p>The animation is thanks to <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@property">@property</a> CSS at-rule. It is utterly brilliant, especially once I understood you could inject it via JS, as injecting it into the component's CSS didn't work at all - either via the static CSS or the constructible/adoptable CSS.</p>
<p>Bundling it into one file should also ease its adoption.</p>
DominicMyershttp://www.blogger.com/profile/15530669398436940737noreply@blogger.com0tag:blogger.com,1999:blog-6506998626989446594.post-56354593687453034572022-09-19T10:46:00.003+01:002022-09-19T10:48:24.950+01:00Sierpiński triangle<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiOjYxDd40hKfsSssc9q3w9H7x07IiirGzKjyBeZe7wPv_g1WoIFOwpKJFszmF-QDz-oT-qoKMkLgZ35lH-ux_GgKOr840sEalB9km2Z8D2Jo8c689jvvAn7usXyisvYX8grERuCXhBfeQ8Eo753uPgF-hMVmeKwN1T_TAoLybd_YTKUPOjZhPCYMUEQ/s1200/download.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="400" data-original-height="1200" data-original-width="1200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiOjYxDd40hKfsSssc9q3w9H7x07IiirGzKjyBeZe7wPv_g1WoIFOwpKJFszmF-QDz-oT-qoKMkLgZ35lH-ux_GgKOr840sEalB9km2Z8D2Jo8c689jvvAn7usXyisvYX8grERuCXhBfeQ8Eo753uPgF-hMVmeKwN1T_TAoLybd_YTKUPOjZhPCYMUEQ/s400/download.png"/></a></div>
<p>I was scrolling through TikTok a couple of evenings ago (I know, I'm probably far too old to do so, but now and again, there's gold!) and I came across the <a href="https://vm.tiktok.com/ZMFJCm8Rh/" target="_blank">following video</a>:</p>
<blockquote class="tiktok-embed" cite="https://www.tiktok.com/@flipperzer0/video/7144396286114958638" data-video-id="7144396286114958638" style="max-width: 605px;min-width: 325px;" > <section> <a target="_blank" title="@flipperzer0" href="https://www.tiktok.com/@flipperzer0?refer=embed">@flipperzer0</a> <p></p> <a target="_blank" title="♬ Levels - Live Session - Sarah Coponat" href="https://www.tiktok.com/music/Levels-Live-Session-7052173894207145986?refer=embed">♬ Levels - Live Session - Sarah Coponat</a> </section> </blockquote> <script async src="https://www.tiktok.com/embed.js"></script>
<p>Anyway, inspired to give it a go, I worked up a p5 test, and it works!</p>
<pre style='color:#000000;background:#ffffff;'><span style='color:#800000; font-weight:bold; '>const</span> points <span style='color:#808030; '>=</span> <span style='color:#808030; '>[</span>
<span style='color:#808030; '>[</span><span style='color:#808030; '>-</span><span style='color:#008c00; '>75</span><span style='color:#808030; '>,</span> <span style='color:#008c00; '>130</span><span style='color:#808030; '>]</span><span style='color:#808030; '>,</span>
<span style='color:#808030; '>[</span><span style='color:#808030; '>-</span><span style='color:#008c00; '>150</span><span style='color:#808030; '>,</span> <span style='color:#008c00; '>0</span><span style='color:#808030; '>]</span><span style='color:#808030; '>,</span>
<span style='color:#808030; '>[</span><span style='color:#808030; '>-</span><span style='color:#008c00; '>75</span><span style='color:#808030; '>,</span> <span style='color:#808030; '>-</span><span style='color:#008c00; '>130</span><span style='color:#808030; '>]</span><span style='color:#808030; '>,</span>
<span style='color:#808030; '>[</span><span style='color:#008c00; '>75</span><span style='color:#808030; '>,</span> <span style='color:#808030; '>-</span><span style='color:#008c00; '>130</span><span style='color:#808030; '>]</span><span style='color:#808030; '>,</span>
<span style='color:#808030; '>[</span><span style='color:#008c00; '>150</span><span style='color:#808030; '>,</span> <span style='color:#008c00; '>0</span><span style='color:#808030; '>]</span><span style='color:#808030; '>,</span>
<span style='color:#808030; '>[</span><span style='color:#008c00; '>75</span><span style='color:#808030; '>,</span> <span style='color:#008c00; '>130</span><span style='color:#808030; '>]</span><span style='color:#808030; '>,</span>
<span style='color:#808030; '>]</span>
<span style='color:#800000; font-weight:bold; '>const</span> rand <span style='color:#808030; '>=</span> <span style='color:#808030; '>(</span>int<span style='color:#808030; '>)</span> <span style='color:#808030; '>=</span><span style='color:#808030; '>></span> <span style='color:#797997; '>Math</span><span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>round</span><span style='color:#808030; '>(</span><span style='color:#797997; '>Math</span><span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>random</span><span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#808030; '>*</span> int<span style='color:#808030; '>)</span>
<span style='color:#800000; font-weight:bold; '>const</span> width <span style='color:#808030; '>=</span> <span style='color:#008c00; '>600</span>
<span style='color:#800000; font-weight:bold; '>const</span> height <span style='color:#808030; '>=</span> <span style='color:#008c00; '>600</span>
<span style='color:#800000; font-weight:bold; '>function</span> setup<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
createCanvas<span style='color:#808030; '>(</span>width<span style='color:#808030; '>,</span> height<span style='color:#808030; '>)</span>
noStroke<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span>
<span style='color:#800000; font-weight:bold; '>function</span> draw<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
background<span style='color:#808030; '>(</span><span style='color:#008c00; '>0</span><span style='color:#808030; '>)</span>
fill<span style='color:#808030; '>(</span><span style='color:#008c00; '>255</span><span style='color:#808030; '>,</span> <span style='color:#008c00; '>255</span><span style='color:#808030; '>,</span> <span style='color:#008c00; '>255</span><span style='color:#808030; '>)</span>
text<span style='color:#808030; '>(</span>points<span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>length</span><span style='color:#808030; '>,</span> <span style='color:#008c00; '>50</span><span style='color:#808030; '>,</span> <span style='color:#008c00; '>50</span><span style='color:#808030; '>)</span>
points<span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>forEach</span><span style='color:#808030; '>(</span>point <span style='color:#808030; '>=</span><span style='color:#808030; '>></span> <span style='color:#800080; '>{</span>
circle<span style='color:#808030; '>(</span>point<span style='color:#808030; '>[</span><span style='color:#008c00; '>0</span><span style='color:#808030; '>]</span> <span style='color:#808030; '>+</span> <span style='color:#808030; '>(</span>width <span style='color:#808030; '>/</span><span style='color:#008c00; '>2</span><span style='color:#808030; '>)</span><span style='color:#808030; '>,</span> point<span style='color:#808030; '>[</span><span style='color:#008c00; '>1</span><span style='color:#808030; '>]</span> <span style='color:#808030; '>+</span> <span style='color:#808030; '>(</span>height <span style='color:#808030; '>/</span><span style='color:#008c00; '>2</span><span style='color:#808030; '>)</span><span style='color:#808030; '>,</span> <span style='color:#008c00; '>1</span><span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span><span style='color:#808030; '>)</span>
<span style='color:#800000; font-weight:bold; '>if</span><span style='color:#808030; '>(</span>points<span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>length</span> <span style='color:#808030; '>===</span> <span style='color:#008c00; '>6</span><span style='color:#808030; '>)</span><span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>const</span> target <span style='color:#808030; '>=</span> points<span style='color:#808030; '>[</span>rand<span style='color:#808030; '>(</span><span style='color:#008c00; '>6</span><span style='color:#808030; '>)</span><span style='color:#808030; '>]</span>
<span style='color:#800000; font-weight:bold; '>const</span> <span style='color:#797997; '>source</span> <span style='color:#808030; '>=</span> points<span style='color:#808030; '>[</span><span style='color:#008c00; '>0</span><span style='color:#808030; '>]</span>
points<span style='color:#808030; '>.</span>push<span style='color:#808030; '>(</span><span style='color:#808030; '>[</span>
<span style='color:#808030; '>(</span><span style='color:#797997; '>source</span><span style='color:#808030; '>[</span><span style='color:#008c00; '>0</span><span style='color:#808030; '>]</span> <span style='color:#808030; '>+</span> <span style='color:#808030; '>(</span><span style='color:#008c00; '>2</span><span style='color:#808030; '>/</span><span style='color:#008c00; '>3</span> <span style='color:#808030; '>*</span> <span style='color:#808030; '>(</span>target<span style='color:#808030; '>[</span><span style='color:#008c00; '>0</span><span style='color:#808030; '>]</span> <span style='color:#808030; '>-</span> <span style='color:#797997; '>source</span><span style='color:#808030; '>[</span><span style='color:#008c00; '>0</span><span style='color:#808030; '>]</span><span style='color:#808030; '>)</span><span style='color:#808030; '>)</span><span style='color:#808030; '>)</span><span style='color:#808030; '>,</span>
<span style='color:#808030; '>(</span><span style='color:#797997; '>source</span><span style='color:#808030; '>[</span><span style='color:#008c00; '>1</span><span style='color:#808030; '>]</span> <span style='color:#808030; '>+</span> <span style='color:#808030; '>(</span><span style='color:#008c00; '>2</span><span style='color:#808030; '>/</span><span style='color:#008c00; '>3</span> <span style='color:#808030; '>*</span> <span style='color:#808030; '>(</span>target<span style='color:#808030; '>[</span><span style='color:#008c00; '>1</span><span style='color:#808030; '>]</span> <span style='color:#808030; '>-</span> <span style='color:#797997; '>source</span><span style='color:#808030; '>[</span><span style='color:#008c00; '>1</span><span style='color:#808030; '>]</span><span style='color:#808030; '>)</span><span style='color:#808030; '>)</span><span style='color:#808030; '>)</span>
<span style='color:#808030; '>]</span><span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span><span style='color:#800000; font-weight:bold; '>else</span><span style='color:#800080; '>{</span>
populateArray<span style='color:#808030; '>(</span><span style='color:#008c00; '>1000</span><span style='color:#808030; '>,</span> points<span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span>
<span style='color:#800080; '>}</span>
<span style='color:#800000; font-weight:bold; '>const</span> populateArray <span style='color:#808030; '>=</span> <span style='color:#808030; '>(</span>count<span style='color:#808030; '>,</span> arr<span style='color:#808030; '>)</span> <span style='color:#808030; '>=</span><span style='color:#808030; '>></span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>for</span><span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>let</span> i <span style='color:#808030; '>=</span> <span style='color:#008c00; '>0</span><span style='color:#800080; '>;</span> i <span style='color:#808030; '><</span> count<span style='color:#800080; '>;</span> i<span style='color:#808030; '>++</span><span style='color:#808030; '>)</span><span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>const</span> target <span style='color:#808030; '>=</span> points<span style='color:#808030; '>[</span>rand<span style='color:#808030; '>(</span><span style='color:#008c00; '>6</span><span style='color:#808030; '>)</span><span style='color:#808030; '>]</span>
<span style='color:#800000; font-weight:bold; '>const</span> <span style='color:#797997; '>source</span> <span style='color:#808030; '>=</span> points<span style='color:#808030; '>[</span>points<span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>length</span> <span style='color:#808030; '>-</span> <span style='color:#008c00; '>1</span><span style='color:#808030; '>]</span>
points<span style='color:#808030; '>.</span>push<span style='color:#808030; '>(</span><span style='color:#808030; '>[</span>
<span style='color:#808030; '>(</span><span style='color:#797997; '>source</span><span style='color:#808030; '>[</span><span style='color:#008c00; '>0</span><span style='color:#808030; '>]</span> <span style='color:#808030; '>+</span> <span style='color:#808030; '>(</span><span style='color:#008c00; '>2</span><span style='color:#808030; '>/</span><span style='color:#008c00; '>3</span><span style='color:#808030; '>)</span> <span style='color:#808030; '>*</span> <span style='color:#808030; '>(</span>target<span style='color:#808030; '>[</span><span style='color:#008c00; '>0</span><span style='color:#808030; '>]</span> <span style='color:#808030; '>-</span> <span style='color:#797997; '>source</span><span style='color:#808030; '>[</span><span style='color:#008c00; '>0</span><span style='color:#808030; '>]</span><span style='color:#808030; '>)</span><span style='color:#808030; '>)</span><span style='color:#808030; '>,</span>
<span style='color:#808030; '>(</span><span style='color:#797997; '>source</span><span style='color:#808030; '>[</span><span style='color:#008c00; '>1</span><span style='color:#808030; '>]</span> <span style='color:#808030; '>+</span> <span style='color:#808030; '>(</span><span style='color:#008c00; '>2</span><span style='color:#808030; '>/</span><span style='color:#008c00; '>3</span><span style='color:#808030; '>)</span> <span style='color:#808030; '>*</span> <span style='color:#808030; '>(</span>target<span style='color:#808030; '>[</span><span style='color:#008c00; '>1</span><span style='color:#808030; '>]</span> <span style='color:#808030; '>-</span> <span style='color:#797997; '>source</span><span style='color:#808030; '>[</span><span style='color:#008c00; '>1</span><span style='color:#808030; '>]</span><span style='color:#808030; '>)</span><span style='color:#808030; '>)</span>
<span style='color:#808030; '>]</span><span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span>
<span style='color:#800080; '>}</span>
</pre>
<p>for some unknown reason, and only every so often, the pattern goes wrong; does anyone have any idea why or how to fix it?</p>
DominicMyershttp://www.blogger.com/profile/15530669398436940737noreply@blogger.com0tag:blogger.com,1999:blog-6506998626989446594.post-73217117379719854822022-09-12T09:49:00.000+01:002022-09-12T09:49:01.429+01:00Sorting colours is a pain!<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZk3BP5utZe-OCGjrv8lJa4OMqYH75A9fPhPiWTEBehXYfSHVjuVcV4Mv6VAvfHmH-vZ6X5pV10i_gEOyLD_TaAq-H8nyezsas4kgi7gJ2pm8UlBoYyLOEKtDxoQjlJyYS18WRQ9XnUUXeyqNTzNkudmXSP8xOcGga51FlNj1ksKVmHBgEb4L9Utwoow/s7138/multicolored_houses_in_valley_of_colors_la_trinidad_philippines-scopio-e2af8b9b-8b79-4324-993a-f3d6fd3352e9.jpg" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="400" data-original-height="4150" data-original-width="7138" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZk3BP5utZe-OCGjrv8lJa4OMqYH75A9fPhPiWTEBehXYfSHVjuVcV4Mv6VAvfHmH-vZ6X5pV10i_gEOyLD_TaAq-H8nyezsas4kgi7gJ2pm8UlBoYyLOEKtDxoQjlJyYS18WRQ9XnUUXeyqNTzNkudmXSP8xOcGga51FlNj1ksKVmHBgEb4L9Utwoow/s400/multicolored_houses_in_valley_of_colors_la_trinidad_philippines-scopio-e2af8b9b-8b79-4324-993a-f3d6fd3352e9.jpg"/></a></div>
<label style="display:flex; justify-content: start; align-items: center; font-family: Barlow">
<a style="display:flex; align-items: center" href="https://scop.io">
<img height="20x" src="//cdn.shopify.com/s/files/1/2395/7099/files/Scopio_logo_Color_dark_140x.png?v=1604343350" style="margin: 0px 10px 0px 0px">
</a>
By
<a style="text-decoration: none; margin: 0px 5px;" href="https://scop.io/collections/vendors?q=Garrick%20Ang">Garrick Ang</a>
</label>
<p>I've written before about <a href="https://drmsite.blogspot.com/2021/02/polital-spectrum.html">sorting colours</a>, and this got me thinking about some work I'm doing in terms of converting some CSS to SCSS (with the proper use of CSS variables, I must add).</p>
<p>As such, I've been wading through some CSS, extracting colours, and then popping them into a <code><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/:root">:root</a></code> CSS pseudo-class. I do this by looking for `#` and popping the colour into the function as and when I find them. The resulting text is well messy! I thought it couldn't be that hard to sort them similarly as employed in Google Sheets; so I came up with <a href="https://csscoloursorter.annoyingmouse.repl.co">CSSColourSorter</a>, which you're more than welcome to use or steal/borrow as you see fit.</p>
<p>It works by pasting in your whole <code>:root</code> directive - you'll then need to copy and paste the resulting test into your CSS/SCSS as noted before, though, <a href="https://www.alanzucconi.com/2015/09/30/colour-sorting/">sorting colours is a pain</a>!</p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuSA44fwDmlqztiz4gg2kQ8fY6_Knussww3Fs_e4gMjlFpL-pcUiue90M0aRyr8_Y2Kn7N028guR5hJcYLy5k6CZwQ5YPD1DXu3XQ_SuoRjDnICTo_8_iEjl1tYfwo7aI2izZc_MIKQRxfSXyO5oVDfmr-83LX-w3Ng1WJOMf2DwtyLRvlOpW1p19xag/s871/swatch.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="400" data-original-height="20" data-original-width="871" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuSA44fwDmlqztiz4gg2kQ8fY6_Knussww3Fs_e4gMjlFpL-pcUiue90M0aRyr8_Y2Kn7N028guR5hJcYLy5k6CZwQ5YPD1DXu3XQ_SuoRjDnICTo_8_iEjl1tYfwo7aI2izZc_MIKQRxfSXyO5oVDfmr-83LX-w3Ng1WJOMf2DwtyLRvlOpW1p19xag/s400/swatch.png"/></a></div>
<p>I've added a swatch beneath the <code>textarea</code>s so you can see the new spectrum - mainly to check that I was doing things right!</p>DominicMyershttp://www.blogger.com/profile/15530669398436940737noreply@blogger.com0tag:blogger.com,1999:blog-6506998626989446594.post-47903928037347954702022-07-14T15:11:00.003+01:002023-08-06T11:21:56.425+01:00Merging two SQLite DBs<p>We've got an <a href="https://www.elancity.co.uk/evolis-radar-speed-sign/">MVAS</a> (well, we've got two, but only one team to manage the one) in Witchford, and I'm part of the team that manages it.</p>
<div class="tenor-gif-embed" data-postid="13992342" data-share-method="host" data-aspect-ratio="1.77778" data-width="100%"><a href="https://tenor.com/view/last-of-the-summer-wine-britbox-bbc-classic-haha-gif-13992342">Last Of The Summer Wine Britbox GIF</a>from <a href="https://tenor.com/search/last+of+the+summer+wine-gifs">Last Of The Summer Wine GIFs</a></div> <script type="text/javascript" async src="https://tenor.com/embed.js"></script>
<p>I hold ladders and carry batteries, and it's not all that hard a task, quite good fun. One chap downloads the data and lets me cast my eye over it (it's stored as in SQLite database). He went on holiday a little while back, so I had to collect the data. That meant there was an issue with the data integrity between his copy of the DB and mine. Thus, I was left with a need to merge two SQLite DBs; with the help of SQLiteStudio, it was pretty easy to resolve. Each DB has three tables: <code>campaign</code>, <code>campaign_details</code> and <code>measure</code>.</p>
<p>Thinking about it, after going through this process, I realised I just needed to copy over the entirety of my DB to him; it had the same data apart from the latest readings... but hindsight is a beautiful thing.</p>
<p>Anyway, there was an extra row in <code>campaign</code> - so that was easy to copy using some SQL; there were an additional 13 rows in <code>campaign_details</code> - again, dead easy to copy over using a bit of SQL. But, there were an extra 17K+ rows in <code>measure</code>...</p>
<p>I got in touch with my mate Oliwia to see if she could help, but she was busy, so I had to cobble together my SQL; this is what I came up with:</p>
<pre style='color:#000000;background:#ffffff;'><span style='color:#800000; font-weight:bold; '>INSERT</span> <span style='color:#800000; font-weight:bold; '>INTO</span>
original<span style='color:#808030; '>.</span>measure
<span style='color:#800000; font-weight:bold; '>SELECT</span>
<span style='color:#808030; '>*</span>
<span style='color:#800000; font-weight:bold; '>FROM</span>
new<span style='color:#808030; '>.</span>measure a
<span style='color:#800000; font-weight:bold; '>WHERE</span>
a<span style='color:#808030; '>.</span>meas_id
<span style='color:#808030; '>NOT</span> <span style='color:#800000; font-weight:bold; '>IN</span> <span style='color:#808030; '>(</span>
<span style='color:#800000; font-weight:bold; '>SELECT</span>
meas_id
<span style='color:#800000; font-weight:bold; '>FROM</span>
original<span style='color:#808030; '>.</span>measure b
<span style='color:#808030; '>)</span>
</pre>
<p>Not pretty, but it worked! I blame the heat for not realising sooner.</p>
<p><strong>EDIT</strong></p>
<p>So, this happened again so I thought I'd better take some notes and use some proper SQL:</p>
<pre style='color:#000000;background:#ffffff;'><span style='color:#800000; font-weight:bold; '>INSERT</span> <span style='color:#800000; font-weight:bold; '>INTO</span>
`TARGET_TABLE`<span style='color:#808030; '>.</span>campaign <span style='color:#808030; '>(</span>
product_prod_id<span style='color:#808030; '>,</span>
camp_date_begin<span style='color:#808030; '>,</span>
camp_date_end<span style='color:#808030; '>,</span>
date_created<span style='color:#808030; '>,</span>
camp_store_mode<span style='color:#808030; '>,</span>
camp_title<span style='color:#808030; '>,</span>
camp_comment
<span style='color:#808030; '>)</span>
<span style='color:#800000; font-weight:bold; '>SELECT</span>
product_prod_id<span style='color:#808030; '>,</span>
camp_date_begin<span style='color:#808030; '>,</span>
camp_date_end<span style='color:#808030; '>,</span>
date_created<span style='color:#808030; '>,</span>
camp_store_mode<span style='color:#808030; '>,</span>
camp_title<span style='color:#808030; '>,</span>
camp_comment
<span style='color:#800000; font-weight:bold; '>FROM</span>
`SOURCE_TABLE`<span style='color:#808030; '>.</span>campaign <span style='color:#800000; font-weight:bold; '>a</span>
<span style='color:#800000; font-weight:bold; '>WHERE</span>
<span style='color:#800000; font-weight:bold; '>a</span><span style='color:#808030; '>.</span>camp_date_begin
<span style='color:#800000; font-weight:bold; '>NOT</span> <span style='color:#800000; font-weight:bold; '>IN</span> <span style='color:#808030; '>(</span>
<span style='color:#800000; font-weight:bold; '>SELECT</span>
camp_date_begin
<span style='color:#800000; font-weight:bold; '>FROM</span>
`TARGET_TABLE`<span style='color:#808030; '>.</span>campaign b
<span style='color:#808030; '>)</span><span style='color:#808030; '>;</span>
<span style='color:#800000; font-weight:bold; '>INSERT</span> <span style='color:#800000; font-weight:bold; '>INTO</span>
`TARGET_TABLE`<span style='color:#808030; '>.</span>campaign_details <span style='color:#808030; '>(</span>
product_prod_id<span style='color:#808030; '>,</span>
cpd_date<span style='color:#808030; '>,</span>
campaign_camp_id<span style='color:#808030; '>,</span>
cpd_status<span style='color:#808030; '>,</span>
cpd_attempt<span style='color:#808030; '>,</span>
last_updated<span style='color:#808030; '>,</span>
cpd_max_time
<span style='color:#808030; '>)</span>
<span style='color:#800000; font-weight:bold; '>SELECT</span>
product_prod_id<span style='color:#808030; '>,</span>
cpd_date<span style='color:#808030; '>,</span>
<span style='color:#008c00; '>51</span><span style='color:#808030; '>,</span>
cpd_status<span style='color:#808030; '>,</span>
cpd_attempt<span style='color:#808030; '>,</span>
last_updated<span style='color:#808030; '>,</span>
cpd_max_time
<span style='color:#800000; font-weight:bold; '>FROM</span>
`SOURCE_TABLE`<span style='color:#808030; '>.</span>campaign_details <span style='color:#800000; font-weight:bold; '>a</span>
<span style='color:#800000; font-weight:bold; '>WHERE</span>
<span style='color:#800000; font-weight:bold; '>a</span><span style='color:#808030; '>.</span>cpd_date
<span style='color:#800000; font-weight:bold; '>NOT</span> <span style='color:#800000; font-weight:bold; '>IN</span> <span style='color:#808030; '>(</span>
<span style='color:#800000; font-weight:bold; '>SELECT</span>
cpd_date
<span style='color:#800000; font-weight:bold; '>FROM</span>
`TARGET_TABLE`<span style='color:#808030; '>.</span>campaign_details b
<span style='color:#808030; '>)</span><span style='color:#808030; '>;</span>
<span style='color:#800000; font-weight:bold; '>INSERT</span> <span style='color:#800000; font-weight:bold; '>INTO</span>
`TARGET_TABLE`<span style='color:#808030; '>.</span>measure <span style='color:#808030; '>(</span>
meas_date<span style='color:#808030; '>,</span>
meas_speed<span style='color:#808030; '>,</span>
meas_direction
<span style='color:#808030; '>)</span>
<span style='color:#800000; font-weight:bold; '>SELECT</span>
meas_date<span style='color:#808030; '>,</span>
meas_speed<span style='color:#808030; '>,</span>
meas_direction
<span style='color:#800000; font-weight:bold; '>FROM</span>
`SOURCE_TABLE`<span style='color:#808030; '>.</span>measure <span style='color:#800000; font-weight:bold; '>a</span>
<span style='color:#800000; font-weight:bold; '>WHERE</span>
<span style='color:#800000; font-weight:bold; '>a</span><span style='color:#808030; '>.</span>meas_date
<span style='color:#800000; font-weight:bold; '>NOT</span> <span style='color:#800000; font-weight:bold; '>IN</span> <span style='color:#808030; '>(</span>
<span style='color:#800000; font-weight:bold; '>SELECT</span>
meas_date
<span style='color:#800000; font-weight:bold; '>FROM</span>
`TARGET_TABLE`<span style='color:#808030; '>.</span>measure b
<span style='color:#808030; '>)</span><span style='color:#808030; '>;</span>
</pre>
<p><strong>Please note</strong> the <code>51</code> is hardcoded and the result of the previous query inserting another row in the <code>campaign</code> table.</p>
DominicMyershttp://www.blogger.com/profile/15530669398436940737noreply@blogger.com0tag:blogger.com,1999:blog-6506998626989446594.post-87906026551268015702022-07-05T08:31:00.003+01:002022-07-05T08:31:34.157+01:00Donut bugs<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgctd4h08e4bgNA_j2OfUW12mDkLPLIRtftdxt-2AkB_UZ3WtCxRAKHlVa0sikhAVxjwHYGxfl0A5B2cNgHUfpmACPbv3xSa1fbsa5VzwMGOVH5xC4-2qLkBMXucxTofrigVRFfsx1YSc7b67Q-uAgiaHyyir5G03-Mj82JoQ8Ly1H_Xa-gqYSJ0MeyPg/s4912/brown_and_white_pie_on_brown_wooden_table-scopio-4159b201-576e-4ea9-b5cc-4527b704fa5a.jpg" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="400" data-original-height="4912" data-original-width="4912" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgctd4h08e4bgNA_j2OfUW12mDkLPLIRtftdxt-2AkB_UZ3WtCxRAKHlVa0sikhAVxjwHYGxfl0A5B2cNgHUfpmACPbv3xSa1fbsa5VzwMGOVH5xC4-2qLkBMXucxTofrigVRFfsx1YSc7b67Q-uAgiaHyyir5G03-Mj82JoQ8Ly1H_Xa-gqYSJ0MeyPg/s400/brown_and_white_pie_on_brown_wooden_table-scopio-4159b201-576e-4ea9-b5cc-4527b704fa5a.jpg"/></a></div>
<label style="display:flex; justify-content: start; align-items: center; font-family: Barlow">
<a style="display:flex; align-items: center" href="https://scop.io">
<img height="20x" src="//cdn.shopify.com/s/files/1/2395/7099/files/Scopio_logo_Color_dark_140x.png?v=1604343350" style="margin: 0px 10px 0px 0px">
</a>
By
<a style="text-decoration: none; margin: 0px 5px;" href="https://scop.io/collections/vendors?q=Ivan%20Naunov">Ivan Naunov</a>
</label>
<p>I <a href="https://drmsite.blogspot.com/2022/07/comparing-json-gzipped-or-not-in.html">noted before</a> that my <a href="https://drmsite.blogspot.com/2022/06/doughnut-donut-chart-web-component.html">Donut Component</a> has a bug in it when it comes to drawing segments with a value over 50% of the total - such a pain!</p>
<p>I was hoping to avoid using SVGs for this component, but I think that is what I'll have to do - not such a bad thing, TBH, but still annoying!</p>DominicMyershttp://www.blogger.com/profile/15530669398436940737noreply@blogger.com0tag:blogger.com,1999:blog-6506998626989446594.post-86115682669643183432022-07-05T08:22:00.001+01:002022-07-05T08:22:28.485+01:00Comparing JSON (gzipped or not) in localStorage with IndexedDB (using PouchDB)<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifXmjXklbShGsKXIcjI600Oj-0DZlw3W9DABCsjGZE_1vuBQhiTVvzYzVs-hYTL5Yn9TPvCDmmDuRpkxAm9enFPIYTNFhpfxzqeUPUi-eJNj0MzNygcRZiOUIxJo6jB7mAzwq515x0T40dIYi7fITuHm9yf31wToezEDat1CStYf8BcQvfpY74osXyKQ/s4256/shadow_of_runners_during_race-scopio-d2cf9c42-eca2-4bc3-a575-198f8ca7d13d.jpg" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="400" data-original-height="2832" data-original-width="4256" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifXmjXklbShGsKXIcjI600Oj-0DZlw3W9DABCsjGZE_1vuBQhiTVvzYzVs-hYTL5Yn9TPvCDmmDuRpkxAm9enFPIYTNFhpfxzqeUPUi-eJNj0MzNygcRZiOUIxJo6jB7mAzwq515x0T40dIYi7fITuHm9yf31wToezEDat1CStYf8BcQvfpY74osXyKQ/s400/shadow_of_runners_during_race-scopio-d2cf9c42-eca2-4bc3-a575-198f8ca7d13d.jpg"/></a></div>
<label style="display:flex; justify-content: start; align-items: center; font-family: Barlow">
<a style="display:flex; align-items: center" href="https://scop.io">
<img height="20x" src="//cdn.shopify.com/s/files/1/2395/7099/files/Scopio_logo_Color_dark_140x.png?v=1604343350" style="margin: 0px 10px 0px 0px">
</a>
By
<a style="text-decoration: none; margin: 0px 5px;" href="https://scop.io/collections/vendors?q=Israel%20Mart%C3%ADnez%20Vald%C3%A9s">Israel Martínez Valdés</a>
</label>
<p>I wrote last week about <a href="https://drmsite.blogspot.com/2022/06/gzipping-json-for-localstorage.html">GZipping JSON for localStorage</a> and, over the weekend, I decided to do some checks on the efficacy of this approach. I noted that the larger the payload, the more significant the space saving; smaller payloads often negated any saving, with the gzipped file being significantly larger than the original JSON for smaller JSON payloads.<p>
<p>I didn't only compare the original JSON and the gzipped JSON though, I decided to take a wee look into <a href="https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API">IndexedDB</a>, with the help of <a href="https://pouchdb.com">PouchDB</a>.</p>
<p>I worked with three JSON files:</p>
<ol>
<li><code><a href="https://github.com/annoyingmouse/pako-test/blob/main/bodies.json">bodies.json</a></code> (330 KB)</li>
<li><code><a href="https://github.com/annoyingmouse/pako-test/blob/main/employees.json">employees.json</a></code> (2284 KB)</li>
<li><code><a href="https://github.com/annoyingmouse/pako-test/blob/main/family.json">family.json</a></code> (2 KB)</li>
</ol>
<p>As you'll be able to see from the <a href="https://github.com/annoyingmouse/pako-test/blob/main/index.js">code</a>, I do a fair bit of computation using both <a href="https://developer.mozilla.org/en-US/docs/Web/API/console/time"><code>console.time()</code></a> and <a href="https://developer.mozilla.org/en-US/docs/Web/API/Performance/now"><code>performance.now()</code></a>.</p>
<p>The results are output to the developer console (I did try using a <a href="http://drmsite.blogspot.com/2022/06/doughnut-donut-chart-web-component.html">Donut Chart</a> - but I discovered a bug in my Component - I'll fix it this week, hopefully!).</p>
<p>The following are my results for saving on Firefox:</p>
<ol>
<li>
<ol>
<li>Time taken to save bodies using localStorage: 0ms</li>
<li>Time taken to save bodies with Pako: 20ms</li>
<li>Time taken to save bodies with PouchDB: 34ms</li>
</ol>
</li>
<li>
<ol>
<li>Time taken to save employees using localStorage: 0.002ms</li>
<li>Time taken to save employees with Pako: 69ms</li>
<li>Time taken to save employees with PouchDB: 149ms</li>
</ol>
</li>
<li>
<ol>
<li>Time taken to save family using localStorage: 0ms</li>
<li>Time taken to save family with Pako: 2ms</li>
<li>Time taken to save family with PouchDB: 157ms</li>
</ol>
</li>
</ol>
<p>And these are my results for retrieving the data on Firefox:</p>
<ol>
<li>
<ol>
<li>Time taken to get bodies using localStorage: 2ms</li>
<li>Time taken to get bodies with Pako: 10ms</li>
<li>Time taken to get bodies with PouchDB: 45ms</li>
</ol>
</li>
<li>
<ol>
<li>Time taken to get employees using localStorage: 12ms</li>
<li>Time taken to get employees with Pako: 25ms</li>
<li>Time taken to get employees with PouchDB: 22ms</li>
</ol>
</li>
<li>
<ol>
<li>Time taken to get family using localStorage: 1ms</li>
<li>Time taken to get family with Pako: 1ms</li>
<li>Time taken to get family with PouchDB: 43ms</li>
</ol>
</li>
</ol>
<p>The following are my results for saving on Chrome:</p>
<ol>
<li>
<ol>
<li>Time taken to save bodies using localStorage: 0ms</li>
<li>Time taken to save bodies with Pako: 6.5ms</li>
<li>Time taken to save bodies with PouchDB: 185.1ms</li>
</ol>
</li>
<li>
<ol>
<li>Time taken to save employees using localStorage: 0ms</li>
<li>Time taken to save employees with Pako: 54ms</li>
<li>Time taken to save employees with PouchDB: 143.89ms</li>
</ol>
</li>
<li>
<ol>
<li>Time taken to save family using localStorage: 0ms</li>
<li>Time taken to save family with Pako: 0.4ms</li>
<li>Time taken to save family with PouchDB: 178.5ms</li>
</ol>
</li>
</ol>
<p>And these are my results for retrieving the data on Chrome:</p>
<ol>
<li>
<ol>
<li>Time taken to get bodies using localStorage: 0.9ms</li>
<li>Time taken to get bodies with Pako: 4.29ms</li>
<li>Time taken to get bodies with PouchDB: 39.6ms</li>
</ol>
</li>
<li>
<ol>
<li>Time taken to get employees using localStorage: 5.19ms</li>
<li>Time taken to get employees with Pako: 27.9ms</li>
<li>Time taken to get employees with PouchDB: 19.2ms</li>
</ol>
</li>
<li>
<ol>
<li>Time taken to get family using localStorage: 0ms</li>
<li>Time taken to get family with Pako: 0.19ms</li>
<li>Time taken to get family with PouchDB: 34.69ms</li>
</ol>
</li>
</ol>
<p>The results (in chart form) are here:</p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvcg7qTnQuxoUEA0G-Gad9UBVk96Jd6xCUy_-oUyKYtgQ81WN9iyl9yhjlwatkTufW_SMwf6nyjOjfYEwTMrtVvPupSHvhAIi7CoTCrbg0supk3RjZe4XhS9uqV67b6GmYsOS8wYH9HU-UIr9O0T7vv6uS79b6JrglnBwo9eD1KA7Ugo9J_zk-QymB-Q/s1158/chart.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="400" data-original-height="716" data-original-width="1158" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvcg7qTnQuxoUEA0G-Gad9UBVk96Jd6xCUy_-oUyKYtgQ81WN9iyl9yhjlwatkTufW_SMwf6nyjOjfYEwTMrtVvPupSHvhAIi7CoTCrbg0supk3RjZe4XhS9uqV67b6GmYsOS8wYH9HU-UIr9O0T7vv6uS79b6JrglnBwo9eD1KA7Ugo9J_zk-QymB-Q/s400/chart.png"/></a></div>
<p>I think we can probably all tell that localStorage wins, and wins handsomely. Though the limitations of space in localStorage means that IndexedDB still has a place; perhaps not for smaller data sets though.</p>
<p>I'm happy that I've taken the time to find this out; it certainly means that I have evidence for future decisions - I'd be interested in analysing it further, though, especially as there are discrepancies between the different browsers. Saving to IndexedDB on Firefox seems much faster than on Chrome, though the situation is reversed when retrieving data from IndexedDB.<p>DominicMyershttp://www.blogger.com/profile/15530669398436940737noreply@blogger.com0tag:blogger.com,1999:blog-6506998626989446594.post-52883245566639619102022-06-28T16:13:00.002+01:002022-06-28T16:13:18.989+01:00Cross the floor, please!<p>Quite frankly, we're in a pretty terrible situation in this country, and I've been trying to think of how we could get out of it. Last week I got to thinking about how to remove our MP (<a href="https://en.wikipedia.org/wiki/Lucy_Frazer">Lucy Frazer</a>); I've written to her a couple of times in the past and always received a reply - she even sent a follow up when it came to Ukraine, so I sort of have semi-positive vibes about her (despite her political party). After <a href="https://en.wikipedia.org/wiki/Recall_of_MPs_Act_2015">reading up</a> though, it seems as though there's no way I, as a constituent, can remove her, despite being the one to pay her wages; the <abbr title="Prime Minister">PM</abbr> can, but not I as someone who she's is supposed to represent. The salient parts of the Recall of MPs Act 2015:</p>
<blockquote>
<p>...the Speaker of the House of Commons would trigger the recall process, namely:</p>
<ul>
<li>A custodial prison sentence (including a suspended sentence)
<ul>
<li>Note that MPs imprisoned with sentences greater than one year are automatically removed due to the Representation of the People Act 1981</li>
</ul>
</li>
<li>Suspension from the House of at least 10 sitting days or 14 calendar days, following a report by the Committee on Standards;</li>
<li>A conviction for providing false or misleading expenses claims.</li>
</ul>
</blockquote>
<p>As I noted, though, I don't hate her, I wouldn't say I like her policies and her support for our disaster of a PM, but she always struck me as being reasonable; misguided perhaps, but generally pretty decent. But things are getting serious now.</p>
<p>So, we can't remove her unless she seriously messes up according to the Recall of MPs Act 2015, but what else would trigger a by-election?</p>
<p>According to <a href="https://www.parliament.uk/about/how/elections-and-voting/by-elections/">parliment</a>:</p>
<blockquote>
<p>A by-election is held when a seat becomes vacant. This can happen when an MP:</p>
<ul>
<li>resigns or dies</li>
<li>is declared bankrupt</li>
<li>takes a seat in the House of Lords</li>
<li>is convicted of a serious criminal offence.</li>
</ul>
<p>A by-election does not have to take place if an MP changes political party.</p>
</blockquote>
<p>Let's take those one-by-one - I don't want her dead, and I can't see her resigning soon. I can't see her being short of a few bob. I can't see her moving into the Lords or being convicted of a serious criminal offence. It's that there last sentence, though. I'm pretty sure the Liberal Democrats would welcome her - and in light of the probably local voting pattern in any future election - it's likely to be the only way she can retain her seat in the Commons. And what's more, no by-election would be triggered either.</p>
<p>Now, who's shell-like should I whisper this to?</p>
<p>Why leave it at that - the current <a href="https://members.parliament.uk/parties/Commons">working majority is 75</a> - we'd only need a few Conservatives to either see the writing on the wall - or grow a conscience - before we could oust our PM. Christian Wakeford <a href="https://www.theguardian.com/politics/2022/apr/02/tory-defector-christian-wakeford-crossing-floor-dont-throw-up">did it</a> and <a href="https://www.theguardian.com/politics/live/2022/jun/06/boris-johnson-confidence-vote-graham-brady-tory-mps-live">148 have no confidence in Johnson</a>, if only a third of those voted with their feet and joined another party, then we might be on the start of recovering.</p>
<p>Might it be time for our MPs to stand up for their constituents rather than bolstering the reign of <a href="https://www.independent.co.uk/news/uk/politics/rory-stewart-boris-johnson-partygate-b1997813.html">lying Johnson</a> (I do like Rory Stewart - the Tories messed up by not electing him!)?</p>DominicMyershttp://www.blogger.com/profile/15530669398436940737noreply@blogger.com0tag:blogger.com,1999:blog-6506998626989446594.post-1562689606155771072022-06-24T17:09:00.003+01:002022-06-24T17:09:53.446+01:00GZipping JSON for localStorage<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhapqRVR65AKx3pfyB6YYOmSW5NDuYFXZdkVW_S1fudasc6UpEopfEnS4xgi_v_MowY7uZTKJTEv5cLSRmdLsZDoVc-4wIK1rAkolskAZw-pLnuznldrFH6LGs1oHplsvHCcpFv0sac0sQiKhXoE-bR8pL26NZZX3y7LQuQurUmmhGcUchsSDD9zlzJRw/s4000/black_and_gray_metal_pipe-scopio-dbb81530-60b0-4b48-94f6-7419a9715ef5.jpg" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="400" data-original-height="3000" data-original-width="4000" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhapqRVR65AKx3pfyB6YYOmSW5NDuYFXZdkVW_S1fudasc6UpEopfEnS4xgi_v_MowY7uZTKJTEv5cLSRmdLsZDoVc-4wIK1rAkolskAZw-pLnuznldrFH6LGs1oHplsvHCcpFv0sac0sQiKhXoE-bR8pL26NZZX3y7LQuQurUmmhGcUchsSDD9zlzJRw/s400/black_and_gray_metal_pipe-scopio-dbb81530-60b0-4b48-94f6-7419a9715ef5.jpg"/></a></div>
<label style="display:flex; justify-content: start; align-items: center; font-family: Barlow">
<a style="display:flex; align-items: center" href="https://scop.io">
<img height="20x" src="//cdn.shopify.com/s/files/1/2395/7099/files/Scopio_logo_Color_dark_140x.png?v=1604343350" style="margin: 0px 10px 0px 0px">
</a>
By
<a style="text-decoration: none; margin: 0px 5px;" href="https://scop.io/collections/vendors?q=Suparerg%20Suksai">Suparerg Suksai</a>
</label>
<p>I've written before about <a href="https://drmsite.blogspot.com/2022/01/jsondbish.html">trimming JSON before</a> but I've recently been thinking about how we can trim it even further.</p>
<p>I came across the fantastic <a href="https://github.com/nodeca/pako">pako</a> earlier in the week and decided to <a href="https://github.com/annoyingmouse/pako-test">try it out</a> with some data. You'll see from the repo that we're testing two different JSON files, <a href="https://github.com/annoyingmouse/pako-test/blob/main/family.json">one</a> was quite small (and was, indeed, the example I used <a href="https://drmsite.blogspot.com/2022/01/jsondbish.html">earlier</a>), the <a href="https://github.com/annoyingmouse/pako-test/blob/main/bodies.json">other</a> is significantly larger.<p>
<p>If you download and run the repo, you'll see I've added a check to see if the data retrieved from localStorage is the same as the data retrieved from the file system - it is!</p>
<p>You'll also notice something interesting in the developer console: the smaller JSON ends up being larger (119.93%) when gzipped compared to the stringified JSON; the larger JSON file was 37.49% the size of the stringified JSON.</p>
<p>That sort of makes sense, though, doesn't it? Gzipping a file adds some overhead (hash table), and that overhead might end up making the final gzipped file larger. Not that I know a great deal about the process: I'm cribbing this from an answer on <a href="https://www.quora.com/Can-gzip-file-compression-increase-the-file-size">Quora</a>.</p>
<p>The <code>compressAndStore</code> process is quite interesting, with these steps:</p>
<ol>
<li>The JSON is fetched form a <code>.json</code> file as a string</li>
<li>The fetched string is ocnverted into a JSON object</li>
<li>The JSON is stringified (IKR - we've only just converted into an object)</li>
<li>The stringified JSON is defalted with pako</li>
<li>The resulting Uint8Array is converted into a regular array</li>
<li>The array is saved to localStorage, along with the original stringified JSON</li>
</ol>
<pre style='color:#000000;background:#ffffff;overflow-x:auto;'>async <span style='color:#800000; font-weight:bold; '>function</span> compressAndStore<span style='color:#808030; '>(</span>file<span style='color:#808030; '>,</span> name<span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#696969; '>// Get our data</span>
<span style='color:#800000; font-weight:bold; '>const</span> response <span style='color:#808030; '>=</span> await fetch<span style='color:#808030; '>(</span>file<span style='color:#808030; '>)</span>
<span style='color:#800000; font-weight:bold; '>const</span> fetchedJSON <span style='color:#808030; '>=</span> await response<span style='color:#808030; '>.</span>json<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span>
<span style='color:#696969; '>// Convert our JSON to a string</span>
<span style='color:#800000; font-weight:bold; '>const</span> stingifiedJSON <span style='color:#808030; '>=</span> <span style='color:#797997; '>JSON</span><span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>stringify</span><span style='color:#808030; '>(</span>fetchedJSON<span style='color:#808030; '>)</span>
<span style='color:#696969; '>// Deflate our data with Pako</span>
<span style='color:#800000; font-weight:bold; '>const</span> deflatedStringifiedJSON <span style='color:#808030; '>=</span> pako<span style='color:#808030; '>.</span>deflate<span style='color:#808030; '>(</span>stingifiedJSON<span style='color:#808030; '>)</span>
<span style='color:#696969; '>// Convert the resulting Uint8Array into a regular array</span>
<span style='color:#800000; font-weight:bold; '>const</span> regularArray <span style='color:#808030; '>=</span> <span style='color:#797997; '>Array</span><span style='color:#808030; '>.</span>from<span style='color:#808030; '>(</span>deflatedStringifiedJSON<span style='color:#808030; '>)</span>
<span style='color:#696969; '>// Store our data (both deflated and the original)</span>
localStorage<span style='color:#808030; '>.</span>setItem<span style='color:#808030; '>(</span><span style='color:#800000; '>`</span><span style='color:#800000; '>${</span><span style='color:#797997; '>name</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>Array</span><span style='color:#800000; '>`</span><span style='color:#808030; '>,</span> <span style='color:#797997; '>JSON</span><span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>stringify</span><span style='color:#808030; '>(</span>regularArray<span style='color:#808030; '>)</span><span style='color:#808030; '>)</span>
localStorage<span style='color:#808030; '>.</span>setItem<span style='color:#808030; '>(</span><span style='color:#800000; '>`</span><span style='color:#800000; '>${</span><span style='color:#797997; '>name</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>JSON</span><span style='color:#800000; '>`</span><span style='color:#808030; '>,</span> stingifiedJSON<span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span>
</pre>
<p>The <code>retrieveAndDecompress</code> process is almost a direct reverse:</p>
<ol>
<li>The array is retrieved from localStorage as a string</li>
<li>That string is converted back into an array</li>
<li>The array is converted into a Uint8Array array</li>
<li>The Uint8Array is inflated with pako</li>
<li>The inflated Uint8Array is decoded and then converted back into a JSON object.</li>
<li>The original file is compared with the retrieved and decompressed file</li>
</ol>
<pre style='color:#000000;background:#ffffff;overflow-x:auto;'>async <span style='color:#800000; font-weight:bold; '>function</span> retrieveAndDecompress<span style='color:#808030; '>(</span>file<span style='color:#808030; '>,</span> name<span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#696969; '>// Get our data for later testing</span>
<span style='color:#800000; font-weight:bold; '>const</span> response <span style='color:#808030; '>=</span> await fetch<span style='color:#808030; '>(</span>file<span style='color:#808030; '>)</span>
<span style='color:#800000; font-weight:bold; '>const</span> fetchedJSON <span style='color:#808030; '>=</span> await response<span style='color:#808030; '>.</span>json<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span>
<span style='color:#696969; '>// Get our data from localStorage</span>
<span style='color:#800000; font-weight:bold; '>const</span> retrievedData <span style='color:#808030; '>=</span> localStorage<span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>getItem</span><span style='color:#808030; '>(</span><span style='color:#800000; '>`</span><span style='color:#800000; '>${</span><span style='color:#797997; '>name</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>Array</span><span style='color:#800000; '>`</span><span style='color:#808030; '>)</span>
<span style='color:#696969; '>// Convert it into an array again using JSON.parse()</span>
<span style='color:#800000; font-weight:bold; '>const</span> retrievedArray <span style='color:#808030; '>=</span> <span style='color:#797997; '>JSON</span><span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>parse</span><span style='color:#808030; '>(</span>retrievedData<span style='color:#808030; '>)</span><span style='color:#800080; '>;</span>
<span style='color:#696969; '>// Convert the array back into a Uint8Array array</span>
<span style='color:#800000; font-weight:bold; '>const</span> retrievedTypedArray <span style='color:#808030; '>=</span> <span style='color:#800000; font-weight:bold; '>new</span> Uint8Array<span style='color:#808030; '>(</span>retrievedArray<span style='color:#808030; '>)</span><span style='color:#800080; '>;</span>
<span style='color:#696969; '>// inflate the Uint8Array array using Pako</span>
<span style='color:#800000; font-weight:bold; '>const</span> deflatedTypedArray <span style='color:#808030; '>=</span> pako<span style='color:#808030; '>.</span>inflate<span style='color:#808030; '>(</span>retrievedTypedArray<span style='color:#808030; '>)</span>
<span style='color:#696969; '>// convert it back into the original data</span>
<span style='color:#800000; font-weight:bold; '>const</span> json <span style='color:#808030; '>=</span> <span style='color:#797997; '>JSON</span><span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>parse</span><span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>new</span> TextDecoder<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span><span style='color:#808030; '>.</span>decode<span style='color:#808030; '>(</span>deflatedTypedArray<span style='color:#808030; '>)</span><span style='color:#808030; '>)</span>
console<span style='color:#808030; '>.</span>info<span style='color:#808030; '>(</span><span style='color:#800000; '>`</span><span style='color:#0000e6; '>Is the fetched </span><span style='color:#800000; '>${</span><span style='color:#797997; '>file</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '> the same as the retrieve and decompressed </span><span style='color:#800000; '>${</span><span style='color:#797997; '>name</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>Array: </span><span style='color:#800000; '>${</span><span style='color:#797997; '>JSON</span><span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>stringify</span><span style='color:#808030; '>(</span><span style='color:#797997; '>fetchedJSON</span><span style='color:#808030; '>)</span><span style='color:#797997; '> </span><span style='color:#808030; '>===</span><span style='color:#797997; '> </span><span style='color:#797997; '>JSON</span><span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>stringify</span><span style='color:#808030; '>(</span><span style='color:#797997; '>json</span><span style='color:#808030; '>)</span><span style='color:#800000; '>}</span><span style='color:#800000; '>`</span><span style='color:#808030; '>)</span>
<span style='color:#800000; font-weight:bold; '>const</span> regularArraySize <span style='color:#808030; '>=</span> <span style='color:#808030; '>(</span>localStorage<span style='color:#808030; '>[</span><span style='color:#800000; '>`</span><span style='color:#800000; '>${</span><span style='color:#797997; '>name</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>Array</span><span style='color:#800000; '>`</span><span style='color:#808030; '>]</span><span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>length</span> <span style='color:#808030; '>*</span> <span style='color:#008c00; '>2</span><span style='color:#808030; '>)</span> <span style='color:#808030; '>/</span> <span style='color:#008c00; '>1024</span>
<span style='color:#800000; font-weight:bold; '>const</span> stingifiedJSONSize <span style='color:#808030; '>=</span> <span style='color:#808030; '>(</span>localStorage<span style='color:#808030; '>[</span><span style='color:#800000; '>`</span><span style='color:#800000; '>${</span><span style='color:#797997; '>name</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>JSON</span><span style='color:#800000; '>`</span><span style='color:#808030; '>]</span><span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>length</span> <span style='color:#808030; '>*</span> <span style='color:#008c00; '>2</span><span style='color:#808030; '>)</span> <span style='color:#808030; '>/</span> <span style='color:#008c00; '>1024</span>
console<span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>log</span><span style='color:#808030; '>(</span><span style='color:#800000; '>`</span><span style='color:#800000; '>${</span><span style='color:#797997; '>name</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>Array (</span><span style='color:#800000; '>${</span><span style='color:#797997; '>regularArraySize</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>) is </span><span style='color:#800000; '>${</span><span style='color:#808030; '>(</span><span style='color:#808030; '>(</span><span style='color:#797997; '>regularArraySize </span><span style='color:#808030; '>/</span><span style='color:#797997; '> stingifiedJSONSize</span><span style='color:#808030; '>)</span><span style='color:#797997; '> </span><span style='color:#808030; '>*</span><span style='color:#797997; '> </span><span style='color:#008c00; '>100</span><span style='color:#808030; '>)</span><span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>toFixed</span><span style='color:#808030; '>(</span><span style='color:#008c00; '>2</span><span style='color:#808030; '>)</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>% of the size of </span><span style='color:#800000; '>${</span><span style='color:#797997; '>name</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>JSON </span><span style='color:#800000; '>${</span><span style='color:#797997; '>stingifiedJSONSize</span><span style='color:#800000; '>}</span><span style='color:#800000; '>`</span><span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span>
</pre>DominicMyershttp://www.blogger.com/profile/15530669398436940737noreply@blogger.com0tag:blogger.com,1999:blog-6506998626989446594.post-12290861133757708372022-06-20T08:19:00.004+01:002022-06-20T08:21:07.321+01:00(Doughnut) Donut Chart Web Component<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKTKpAI6Gy0AIlwPXe2j9QbFeutdQOE4q29KNrl9pA9WviAbJbqrWKFjsdm5HNubogmc9C3yNUDRGWCrHNAuuucGKNouEPbohC1d9Kj9tdBbnrWt8T7KV--3p8jzg49_FGE2xkvwUhhmWf7E8RzrkFv_12S47wun9ruJoCwCd6jck8q2_8ZMbxPLiBKg/s6016/brown_doughnut_with_black_background-scopio-cbea0577-28cd-4475-be63-12f228bcb5bc.jpg" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" height="600" data-original-height="6016" data-original-width="4016" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKTKpAI6Gy0AIlwPXe2j9QbFeutdQOE4q29KNrl9pA9WviAbJbqrWKFjsdm5HNubogmc9C3yNUDRGWCrHNAuuucGKNouEPbohC1d9Kj9tdBbnrWt8T7KV--3p8jzg49_FGE2xkvwUhhmWf7E8RzrkFv_12S47wun9ruJoCwCd6jck8q2_8ZMbxPLiBKg/s600/brown_doughnut_with_black_background-scopio-cbea0577-28cd-4475-be63-12f228bcb5bc.jpg"/></a></div>
<label style="display:flex; justify-content: start; align-items: center; font-family: Barlow">
<a style="display:flex; align-items: center" href="https://scop.io">
<img height="20x" src="//cdn.shopify.com/s/files/1/2395/7099/files/Scopio_logo_Color_dark_140x.png?v=1604343350" style="margin: 0px 10px 0px 0px">
</a>
By
<a style="text-decoration: none; margin: 0px 5px;" href="https://scop.io/collections/vendors?q=Diego%20Tovar">Diego Tovar</a>
</label>
<p>About three months back I saw a <a href="https://codepen.io/hilar47/pen/RprXev">CodePen</a> by <a href="https://codepen.io/hilar47">Hilario Goes</a> and I was inspired to convert it into a Web Component. That I did but it ended up being really messy:</p>
<pre style='color:#000000;background:#ffffff;overflow-x:auto;'><span style='color:#808030; '><</span>wc<span style='color:#808030; '>-</span>donut<span style='color:#808030; '>-</span>chart id<span style='color:#808030; '>=</span><span style='color:#800000; '>"</span><span style='color:#0000e6; '>test</span><span style='color:#800000; '>"</span>
part<span style='color:#808030; '>-</span><span style='color:#008c00; '>1</span><span style='color:#808030; '>-</span>value<span style='color:#808030; '>=</span><span style='color:#800000; '>"</span><span style='color:#0000e6; '>5</span><span style='color:#800000; '>"</span>
part<span style='color:#808030; '>-</span><span style='color:#008c00; '>1</span><span style='color:#808030; '>-</span>name<span style='color:#808030; '>=</span><span style='color:#800000; '>"</span><span style='color:#0000e6; '>Part 1</span><span style='color:#800000; '>"</span>
part<span style='color:#808030; '>-</span><span style='color:#008c00; '>1</span><span style='color:#808030; '>-</span>color<span style='color:#808030; '>=</span><span style='color:#800000; '>"</span><span style='color:#0000e6; '>#E64C65</span><span style='color:#800000; '>"</span>
part<span style='color:#808030; '>-</span><span style='color:#008c00; '>2</span><span style='color:#808030; '>-</span>value<span style='color:#808030; '>=</span><span style='color:#800000; '>"</span><span style='color:#0000e6; '>5</span><span style='color:#800000; '>"</span>
part<span style='color:#808030; '>-</span><span style='color:#008c00; '>2</span><span style='color:#808030; '>-</span>name<span style='color:#808030; '>=</span><span style='color:#800000; '>"</span><span style='color:#0000e6; '>Part 2</span><span style='color:#800000; '>"</span>
part<span style='color:#808030; '>-</span><span style='color:#008c00; '>2</span><span style='color:#808030; '>-</span>color<span style='color:#808030; '>=</span><span style='color:#800000; '>"</span><span style='color:#0000e6; '>#11A8AB</span><span style='color:#800000; '>"</span>
part<span style='color:#808030; '>-</span><span style='color:#008c00; '>3</span><span style='color:#808030; '>-</span>value<span style='color:#808030; '>=</span><span style='color:#800000; '>"</span><span style='color:#0000e6; '>5</span><span style='color:#800000; '>"</span>
part<span style='color:#808030; '>-</span><span style='color:#008c00; '>3</span><span style='color:#808030; '>-</span>name<span style='color:#808030; '>=</span><span style='color:#800000; '>"</span><span style='color:#0000e6; '>Part 3</span><span style='color:#800000; '>"</span>
part<span style='color:#808030; '>-</span><span style='color:#008c00; '>3</span><span style='color:#808030; '>-</span>color<span style='color:#808030; '>=</span><span style='color:#800000; '>"</span><span style='color:#0000e6; '>#4FC4F6</span><span style='color:#800000; '>"</span>
animation<span style='color:#808030; '>-</span>duration<span style='color:#808030; '>=</span><span style='color:#800000; '>"</span><span style='color:#0000e6; '>3</span><span style='color:#800000; '>"</span>
hole<span style='color:#808030; '>-</span>color<span style='color:#808030; '>=</span><span style='color:#800000; '>"</span><span style='color:#0000e6; '>#394264</span><span style='color:#800000; '>"</span><span style='color:#808030; '>></span><span style='color:#808030; '><</span><span style='color:#808030; '>/</span>wc<span style='color:#808030; '>-</span>donut<span style='color:#808030; '>-</span>chart<span style='color:#808030; '>></span>
</pre>
<p>(you can see it in action if you download the repo and run <code><a href="https://github.com/annoyingmouse/DonutComponent/blob/main/index.html">index.html</a></code>.)</p>
<p>It worked, but it relied upon a mechanism I developed a little while back for injecting <a href="https://github.com/annoyingmouse/DonutComponent/blob/main/Components/wc-donut-chart/wc-donut-chart.css">CSS</a> into components, and the <a href="https://github.com/annoyingmouse/DonutComponent/blob/main/Components/wc-donut-chart/wc-donut-chart.js">code</a> was all over the place. It also went against a best practice I read a little while back regarding components doing too much.</p>
<p>The segments of the doughnut chart didn't need to be created by the doughnut but could - instead - be their own concern - so I made the <code><a href="https://github.com/annoyingmouse/DonutComponent/blob/main/Components/dm-donut/dm-donut-part.js">dm-donut-part</a></code> Component:</p>
<pre style='color:#000000;background:#ffffff;overflow-x:auto;'><span style='color:#808030; '>(</span><span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#808030; '>=</span><span style='color:#808030; '>></span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>const</span> mainSheet <span style='color:#808030; '>=</span> <span style='color:#800000; font-weight:bold; '>new</span> CSSStyleSheet<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span>
mainSheet<span style='color:#808030; '>.</span>replaceSync<span style='color:#808030; '>(</span><span style='color:#800000; '>`</span><span style='color:#0000e6; '></span>
<span style='color:#0000e6; '>    :host { </span>
<span style='color:#0000e6; '>      --end: 20deg;</span>
<span style='color:#0000e6; '>    }</span>
<span style='color:#0000e6; '>    * {</span>
<span style='color:#0000e6; '>      box-sizing: border-box;</span>
<span style='color:#0000e6; '>    }</span>
<span style='color:#0000e6; '>    .segment-holder {</span>
<span style='color:#0000e6; '>      border-radius: 50%;</span>
<span style='color:#0000e6; '>      clip: rect(0, var(--dimension), var(--dimension), calc(var(--dimension) * 0.5));</span>
<span style='color:#0000e6; '>      height: 100%;</span>
<span style='color:#0000e6; '>      position: absolute;</span>
<span style='color:#0000e6; '>      width: 100%;</span>
<span style='color:#0000e6; '>    }</span>
<span style='color:#0000e6; '>    .segment {</span>
<span style='color:#0000e6; '>      border-radius: 50%;</span>
<span style='color:#0000e6; '>      clip: rect(0, calc(var(--dimension) * .5), var(--dimension), 0);</span>
<span style='color:#0000e6; '>      height: 100%;</span>
<span style='color:#0000e6; '>      position: absolute;</span>
<span style='color:#0000e6; '>      width: 100%;</span>
<span style='color:#0000e6; '>      font-size: 1.5rem;</span>
<span style='color:#0000e6; '>      animation-fill-mode: forwards;</span>
<span style='color:#0000e6; '>      animation-iteration-count: 1;</span>
<span style='color:#0000e6; '>      animation-timing-function: ease;</span>
<span style='color:#0000e6; '>      animation-name: rotate;</span>
<span style='color:#0000e6; '>    }</span>
<span style='color:#0000e6; '>    @keyframes rotate {</span>
<span style='color:#0000e6; '>      from {</span>
<span style='color:#0000e6; '>        transform: rotate(0deg);</span>
<span style='color:#0000e6; '>      }</span>
<span style='color:#0000e6; '>      to {</span>
<span style='color:#0000e6; '>        transform: rotate(var(--end));</span>
<span style='color:#0000e6; '>      }</span>
<span style='color:#0000e6; '>    }</span>
<span style='color:#0000e6; '>  </span><span style='color:#800000; '>`</span><span style='color:#808030; '>)</span>
<span style='color:#800000; font-weight:bold; '>class</span> DonutPart <span style='color:#800000; font-weight:bold; '>extends</span> HTMLElement <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>static</span> get observedAttributes<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>return</span> <span style='color:#808030; '>[</span>
<span style='color:#800000; '>'</span><span style='color:#0000e6; '>name</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>'</span><span style='color:#0000e6; '>color</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>'</span><span style='color:#0000e6; '>rotate</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>'</span><span style='color:#0000e6; '>duration</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>'</span><span style='color:#0000e6; '>start</span><span style='color:#800000; '>'</span>
<span style='color:#808030; '>]</span><span style='color:#800080; '>;</span>
<span style='color:#800080; '>}</span>
<span style='color:#797997; '>constructor</span><span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>super</span><span style='color:#808030; '>(</span><span style='color:#808030; '>)</span>
<span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>shadow <span style='color:#808030; '>=</span> <span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>attachShadow<span style='color:#808030; '>(</span><span style='color:#800080; '>{</span>
mode<span style='color:#800080; '>:</span> <span style='color:#800000; '>'</span><span style='color:#0000e6; '>open</span><span style='color:#800000; '>'</span>
<span style='color:#800080; '>}</span><span style='color:#808030; '>)</span>
<span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>shadow<span style='color:#808030; '>.</span>adoptedStyleSheets <span style='color:#808030; '>=</span> <span style='color:#808030; '>[</span>mainSheet<span style='color:#808030; '>]</span><span style='color:#800080; '>;</span>
<span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>shadow<span style='color:#808030; '>.</span>innerHTML <span style='color:#808030; '>=</span> <span style='color:#800000; '>`</span><span style='color:#0000e6; '></span>
<span style='color:#0000e6; '>        <div class="segment-holder"></span>
<span style='color:#0000e6; '>          <div class="segment"></div></span>
<span style='color:#0000e6; '>        </div></span>
<span style='color:#0000e6; '>      </span><span style='color:#800000; '>`</span>
<span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>render<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span>
render<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>const</span> sheet <span style='color:#808030; '>=</span> <span style='color:#800000; font-weight:bold; '>new</span> CSSStyleSheet<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span>
sheet<span style='color:#808030; '>.</span>replaceSync<span style='color:#808030; '>(</span> <span style='color:#800000; '>`</span><span style='color:#0000e6; '></span>
<span style='color:#0000e6; '>        :host { </span>
<span style='color:#0000e6; '>          --end: </span><span style='color:#800000; '>${</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span><span style='color:#797997; '>end</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>;</span>
<span style='color:#0000e6; '>        }</span>
<span style='color:#0000e6; '>        .segment-holder {</span>
<span style='color:#0000e6; '>          transform: rotate(</span><span style='color:#800000; '>${</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span><span style='color:#797997; '>rotate</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>);</span>
<span style='color:#0000e6; '>        }</span>
<span style='color:#0000e6; '>        .segment {</span>
<span style='color:#0000e6; '>          background-color: </span><span style='color:#800000; '>${</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span><span style='color:#797997; '>color</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>;</span>
<span style='color:#0000e6; '>          animation-delay: </span><span style='color:#800000; '>${</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span><span style='color:#797997; '>delay</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>;</span>
<span style='color:#0000e6; '>          animation-duration: </span><span style='color:#800000; '>${</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span><span style='color:#797997; '>duration</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>;</span>
<span style='color:#0000e6; '>        }</span>
<span style='color:#0000e6; '>      </span><span style='color:#800000; '>`</span><span style='color:#808030; '>)</span>
<span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>shadowRoot<span style='color:#808030; '>.</span>adoptedStyleSheets <span style='color:#808030; '>=</span> <span style='color:#808030; '>[</span>mainSheet<span style='color:#808030; '>,</span> sheet<span style='color:#808030; '>]</span>
<span style='color:#800080; '>}</span>
get end<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>return</span> <span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>getAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>end</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span> <span style='color:#808030; '>||</span> <span style='color:#800000; '>'</span><span style='color:#0000e6; '>120deg</span><span style='color:#800000; '>'</span>
<span style='color:#800080; '>}</span>
get color<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>return</span> <span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>getAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>color</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span> <span style='color:#808030; '>||</span> <span style='color:#800000; '>'</span><span style='color:#0000e6; '>#000000</span><span style='color:#800000; '>'</span>
<span style='color:#800080; '>}</span>
get delay<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>return</span> <span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>getAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>delay</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span> <span style='color:#808030; '>||</span> <span style='color:#800000; '>'</span><span style='color:#0000e6; '>0s</span><span style='color:#800000; '>'</span>
<span style='color:#800080; '>}</span>
get duration<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>return</span> <span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>getAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>duration</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span> <span style='color:#808030; '>||</span> <span style='color:#800000; '>'</span><span style='color:#0000e6; '>0s</span><span style='color:#800000; '>'</span>
<span style='color:#800080; '>}</span>
get rotate<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>return</span> <span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>getAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>rotate</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span> <span style='color:#808030; '>||</span> <span style='color:#800000; '>'</span><span style='color:#0000e6; '>0deg</span><span style='color:#800000; '>'</span>
<span style='color:#800080; '>}</span>
get title<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>return</span> <span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>getAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>title</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span> <span style='color:#808030; '>||</span> <span style='color:#0f4d75; '>null</span>
<span style='color:#800080; '>}</span>
attributeChangedCallback<span style='color:#808030; '>(</span>name<span style='color:#808030; '>,</span> oldValue<span style='color:#808030; '>,</span> newValue<span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>if</span><span style='color:#808030; '>(</span><span style='color:#808030; '>(</span>oldValue <span style='color:#808030; '>!==</span> newValue<span style='color:#808030; '>)</span><span style='color:#808030; '>)</span><span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>render<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span>
<span style='color:#800080; '>}</span>
<span style='color:#800080; '>}</span>
window<span style='color:#808030; '>.</span>customElements<span style='color:#808030; '>.</span>define<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>dm-donut-part</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span> DonutPart<span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span><span style='color:#808030; '>)</span><span style='color:#808030; '>(</span><span style='color:#808030; '>)</span>
</pre>
<p>These parts are injected into the parent <code><a href="https://github.com/annoyingmouse/DonutComponent/blob/main/Components/dm-donut/dm-donut-chart.js">dm-donut-chart</a></code> in a slot and the parent <code>dm-donut-chart</code> interogates them in order to populate their attributes.</p>
<pre style='color:#000000;background:#ffffff;overflow-x:auto;'><span style='color:#808030; '>(</span><span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#808030; '>=</span><span style='color:#808030; '>></span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>const</span> mainSheet <span style='color:#808030; '>=</span> <span style='color:#800000; font-weight:bold; '>new</span> CSSStyleSheet<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span>
mainSheet<span style='color:#808030; '>.</span>replaceSync<span style='color:#808030; '>(</span><span style='color:#800000; '>`</span><span style='color:#0000e6; '></span>
<span style='color:#0000e6; '>    :host {</span>
<span style='color:#0000e6; '>      --dimension: 200px;</span>
<span style='color:#0000e6; '>    }</span>
<span style='color:#0000e6; '>    * {</span>
<span style='color:#0000e6; '>      box-sizing: border-box;</span>
<span style='color:#0000e6; '>    }</span>
<span style='color:#0000e6; '>    .donut-chart {</span>
<span style='color:#0000e6; '>      position: relative;</span>
<span style='color:#0000e6; '>      width: var(--dimension);</span>
<span style='color:#0000e6; '>      height: var(--dimension);</span>
<span style='color:#0000e6; '>      margin: 0 auto;</span>
<span style='color:#0000e6; '>      border-radius: 100%</span>
<span style='color:#0000e6; '>    }</span>
<span style='color:#0000e6; '>    .center {</span>
<span style='color:#0000e6; '>      position: absolute;</span>
<span style='color:#0000e6; '>      top:0;</span>
<span style='color:#0000e6; '>      left:0;</span>
<span style='color:#0000e6; '>      bottom:0;</span>
<span style='color:#0000e6; '>      right:0;</span>
<span style='color:#0000e6; '>      width: calc(var(--dimension) * .65);</span>
<span style='color:#0000e6; '>      height: calc(var(--dimension) * .65);</span>
<span style='color:#0000e6; '>      margin: auto;</span>
<span style='color:#0000e6; '>      border-radius: 50%;</span>
<span style='color:#0000e6; '>    }</span>
<span style='color:#0000e6; '>  </span><span style='color:#800000; '>`</span><span style='color:#808030; '>)</span>
<span style='color:#800000; font-weight:bold; '>class</span> DonutChart <span style='color:#800000; font-weight:bold; '>extends</span> HTMLElement <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>static</span> get observedAttributes<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>return</span> <span style='color:#808030; '>[</span>
<span style='color:#800000; '>'</span><span style='color:#0000e6; '>duration</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>'</span><span style='color:#0000e6; '>color</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>'</span><span style='color:#0000e6; '>delay</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>'</span><span style='color:#0000e6; '>diameter</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>'</span><span style='color:#0000e6; '>dimension</span><span style='color:#800000; '>'</span>
<span style='color:#808030; '>]</span><span style='color:#800080; '>;</span>
<span style='color:#800080; '>}</span>
<span style='color:#797997; '>constructor</span><span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>super</span><span style='color:#808030; '>(</span><span style='color:#808030; '>)</span>
<span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>shadow <span style='color:#808030; '>=</span> <span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>attachShadow<span style='color:#808030; '>(</span><span style='color:#800080; '>{</span>
mode<span style='color:#800080; '>:</span> <span style='color:#800000; '>'</span><span style='color:#0000e6; '>open</span><span style='color:#800000; '>'</span>
<span style='color:#800080; '>}</span><span style='color:#808030; '>)</span>
<span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>shadow<span style='color:#808030; '>.</span>adoptedStyleSheets <span style='color:#808030; '>=</span> <span style='color:#808030; '>[</span>mainSheet<span style='color:#808030; '>]</span><span style='color:#800080; '>;</span>
<span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>shadow<span style='color:#808030; '>.</span>innerHTML <span style='color:#808030; '>=</span> <span style='color:#800000; '>`</span><span style='color:#0000e6; '></span>
<span style='color:#0000e6; '>        <div class="donut-chart"></span>
<span style='color:#0000e6; '>          <slot name='segments'></slot></span>
<span style='color:#0000e6; '>          <div class="center"></div></span>
<span style='color:#0000e6; '>        </div></span>
<span style='color:#0000e6; '>      </span><span style='color:#800000; '>`</span>
<span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>render<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span>
render<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>const</span> segments <span style='color:#808030; '>=</span> <span style='color:#808030; '>[</span><span style='color:#808030; '>.</span><span style='color:#808030; '>.</span><span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>querySelectorAll<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>dm-donut-part</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span><span style='color:#808030; '>]</span>
<span style='color:#800000; font-weight:bold; '>const</span> total <span style='color:#808030; '>=</span> segments<span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>reduce</span><span style='color:#808030; '>(</span><span style='color:#808030; '>(</span>p<span style='color:#808030; '>,</span> c<span style='color:#808030; '>)</span> <span style='color:#808030; '>=</span><span style='color:#808030; '>></span> p <span style='color:#808030; '>+</span> <span style='color:#797997; '>Number</span><span style='color:#808030; '>(</span>c<span style='color:#808030; '>.</span>getAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>value</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span><span style='color:#808030; '>)</span><span style='color:#808030; '>,</span> <span style='color:#008c00; '>0</span><span style='color:#808030; '>)</span>
<span style='color:#800000; font-weight:bold; '>let</span> durationTotal <span style='color:#808030; '>=</span> <span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>delay<span style='color:#800080; '>;</span>
<span style='color:#800000; font-weight:bold; '>let</span> rotationTotal <span style='color:#808030; '>=</span> <span style='color:#008c00; '>0</span>
<span style='color:#800000; font-weight:bold; '>const</span> totalDegree <span style='color:#808030; '>=</span> <span style='color:#008c00; '>360</span><span style='color:#808030; '>/</span>total
segments<span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>forEach</span><span style='color:#808030; '>(</span>segment <span style='color:#808030; '>=</span><span style='color:#808030; '>></span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>const</span> currentRotation <span style='color:#808030; '>=</span> totalDegree <span style='color:#808030; '>*</span> <span style='color:#797997; '>Number</span><span style='color:#808030; '>(</span>segment<span style='color:#808030; '>.</span>getAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>value</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span><span style='color:#808030; '>)</span>
<span style='color:#800000; font-weight:bold; '>const</span> animationDuration <span style='color:#808030; '>=</span> currentRotation <span style='color:#808030; '>/</span> <span style='color:#808030; '>(</span><span style='color:#008c00; '>360</span><span style='color:#808030; '>/</span><span style='color:#797997; '>Number</span><span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>duration<span style='color:#808030; '>)</span><span style='color:#808030; '>)</span>
segment<span style='color:#808030; '>.</span>setAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>end</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span> <span style='color:#800000; '>`</span><span style='color:#800000; '>${</span><span style='color:#797997; '>currentRotation</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>deg</span><span style='color:#800000; '>`</span><span style='color:#808030; '>)</span>
segment<span style='color:#808030; '>.</span>setAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>rotate</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span> <span style='color:#800000; '>`</span><span style='color:#800000; '>${</span><span style='color:#797997; '>rotationTotal</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>deg</span><span style='color:#800000; '>`</span><span style='color:#808030; '>)</span>
segment<span style='color:#808030; '>.</span>setAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>delay</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span> <span style='color:#800000; '>`</span><span style='color:#800000; '>${</span><span style='color:#797997; '>durationTotal</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>s</span><span style='color:#800000; '>`</span><span style='color:#808030; '>)</span>
segment<span style='color:#808030; '>.</span>setAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>duration</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span> <span style='color:#800000; '>`</span><span style='color:#800000; '>${</span><span style='color:#797997; '>animationDuration</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>s</span><span style='color:#800000; '>`</span><span style='color:#808030; '>)</span>
rotationTotal <span style='color:#808030; '>+=</span> currentRotation
durationTotal <span style='color:#808030; '>+=</span> animationDuration
<span style='color:#800080; '>}</span><span style='color:#808030; '>)</span>
<span style='color:#800000; font-weight:bold; '>const</span> sheet <span style='color:#808030; '>=</span> <span style='color:#800000; font-weight:bold; '>new</span> CSSStyleSheet<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span>
sheet<span style='color:#808030; '>.</span>replaceSync<span style='color:#808030; '>(</span> <span style='color:#800000; '>`</span><span style='color:#0000e6; '></span>
<span style='color:#0000e6; '>        :host {</span>
<span style='color:#0000e6; '>          --dimension: </span><span style='color:#800000; '>${</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span><span style='color:#797997; '>dimension</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>px;</span>
<span style='color:#0000e6; '>        }</span>
<span style='color:#0000e6; '>        .center {</span>
<span style='color:#0000e6; '>          background-color: </span><span style='color:#800000; '>${</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span><span style='color:#797997; '>color</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>;</span>
<span style='color:#0000e6; '>          width: calc(var(--dimension) * </span><span style='color:#800000; '>${</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span><span style='color:#797997; '>diameter</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>);</span>
<span style='color:#0000e6; '>          height: calc(var(--dimension) * </span><span style='color:#800000; '>${</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span><span style='color:#797997; '>diameter</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>);</span>
<span style='color:#0000e6; '>        }</span>
<span style='color:#0000e6; '>      </span><span style='color:#800000; '>`</span><span style='color:#808030; '>)</span>
<span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>shadowRoot<span style='color:#808030; '>.</span>adoptedStyleSheets <span style='color:#808030; '>=</span> <span style='color:#808030; '>[</span>mainSheet<span style='color:#808030; '>,</span> sheet<span style='color:#808030; '>]</span>
<span style='color:#800080; '>}</span>
get color<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>return</span> <span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>getAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>color</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span> <span style='color:#808030; '>||</span> <span style='color:#800000; '>'</span><span style='color:#0000e6; '>#000000</span><span style='color:#800000; '>'</span>
<span style='color:#800080; '>}</span>
get duration<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>return</span> <span style='color:#797997; '>Number</span><span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>getAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>duration</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span><span style='color:#808030; '>)</span> <span style='color:#808030; '>||</span> <span style='color:#008000; '>4.5</span>
<span style='color:#800080; '>}</span>
get delay<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>return</span> <span style='color:#797997; '>Number</span><span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>getAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>delay</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span><span style='color:#808030; '>)</span> <span style='color:#808030; '>||</span> <span style='color:#008c00; '>0</span>
<span style='color:#800080; '>}</span>
get diameter<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>return</span> <span style='color:#797997; '>Number</span><span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>getAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>diameter</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span><span style='color:#808030; '>)</span> <span style='color:#808030; '>||</span> <span style='color:#008000; '>.65</span>
<span style='color:#800080; '>}</span>
get dimension<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>return</span> <span style='color:#797997; '>Number</span><span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>getAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>dimension</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span><span style='color:#808030; '>)</span> <span style='color:#808030; '>||</span> <span style='color:#008c00; '>200</span>
<span style='color:#800080; '>}</span>
<span style='color:#800080; '>}</span>
window<span style='color:#808030; '>.</span>customElements<span style='color:#808030; '>.</span>define<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>dm-donut-chart</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span> DonutChart<span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span><span style='color:#808030; '>)</span><span style='color:#808030; '>(</span><span style='color:#808030; '>)</span>
</pre>
<p>A much cleaner approach, and it allowed me to slim down the code and remove the need for the <code><a href="https://github.com/annoyingmouse/DonutComponent/blob/main/Components/wc-dom-helpers.js">DomHelpers</a></code> (though I do love them).</p>
<p>I also got a chance to play with <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/replaceSync">replaceSync</a></code>, which is brilliant and even works on Safari with a <a href="https://github.com/calebdwilliams/construct-style-sheets">suitable polyfill</a>.</p>
<p>This is how <code><a href="https://github.com/annoyingmouse/DonutComponent/blob/main/components.html">I invoke the doughnut</a></code>:</p>
<pre style='color:#000000;background:#ffffff;overflow-x:auto;'><span style='color:#a65700; '><</span><span style='color:#5f5035; '>dm-donut-chart</span><span style='color:#274796; '> </span><span style='color:#074726; '>color</span><span style='color:#808030; '>=</span><span style='color:#0000e6; '>"#394264"</span><span style='color:#274796; '></span>
<span style='color:#274796; '>                duration</span><span style='color:#808030; '>=</span><span style='color:#0000e6; '>"4.5"</span><span style='color:#274796; '></span>
<span style='color:#274796; '>                delay</span><span style='color:#808030; '>=</span><span style='color:#0000e6; '>"2"</span><span style='color:#274796; '></span>
<span style='color:#274796; '>                diameter</span><span style='color:#808030; '>=</span><span style='color:#0000e6; '>".6"</span><span style='color:#274796; '></span>
<span style='color:#274796; '>                dimension</span><span style='color:#808030; '>=</span><span style='color:#0000e6; '>"200"</span><span style='color:#a65700; '>></span>
<span style='color:#a65700; '><</span><span style='color:#800000; font-weight:bold; '>div</span><span style='color:#274796; '> slot</span><span style='color:#808030; '>=</span><span style='color:#0000e6; '>"segments"</span><span style='color:#a65700; '>></span>
<span style='color:#a65700; '><</span><span style='color:#5f5035; '>dm-donut-part</span><span style='color:#274796; '> </span><span style='color:#074726; '>color</span><span style='color:#808030; '>=</span><span style='color:#0000e6; '>"#E64C65"</span><span style='color:#274796; '></span>
<span style='color:#274796; '>                   </span><span style='color:#074726; '>value</span><span style='color:#808030; '>=</span><span style='color:#0000e6; '>"5"</span><span style='color:#a65700; '>></span><span style='color:#a65700; '></</span><span style='color:#5f5035; '>dm-donut-part</span><span style='color:#a65700; '>></span>
<span style='color:#a65700; '><</span><span style='color:#5f5035; '>dm-donut-part</span><span style='color:#274796; '> </span><span style='color:#074726; '>color</span><span style='color:#808030; '>=</span><span style='color:#0000e6; '>"#11A8AB"</span><span style='color:#274796; '></span>
<span style='color:#274796; '>                   </span><span style='color:#074726; '>value</span><span style='color:#808030; '>=</span><span style='color:#0000e6; '>"5"</span><span style='color:#a65700; '>></span><span style='color:#a65700; '></</span><span style='color:#5f5035; '>dm-donut-part</span><span style='color:#a65700; '>></span>
<span style='color:#a65700; '><</span><span style='color:#5f5035; '>dm-donut-part</span><span style='color:#274796; '> </span><span style='color:#074726; '>color</span><span style='color:#808030; '>=</span><span style='color:#0000e6; '>"#4FC4F6"</span><span style='color:#274796; '></span>
<span style='color:#274796; '>                   </span><span style='color:#074726; '>value</span><span style='color:#808030; '>=</span><span style='color:#0000e6; '>"5"</span><span style='color:#a65700; '>></span><span style='color:#a65700; '></</span><span style='color:#5f5035; '>dm-donut-part</span><span style='color:#a65700; '>></span>
<span style='color:#a65700; '></</span><span style='color:#800000; font-weight:bold; '>div</span><span style='color:#a65700; '>></span>
<span style='color:#a65700; '></</span><span style='color:#5f5035; '>dm-donut-chart</span><span style='color:#a65700; '>></span>
</pre>
<p>I'm still not overly happy with having to have a <em>hole</em> within the doughnut - I'll do some more work and see if I can use arcs instead of squares - but I guess, without the <em>hole</em>, the doughnut chart acts like a regular pie chart.</p>
DominicMyershttp://www.blogger.com/profile/15530669398436940737noreply@blogger.com0tag:blogger.com,1999:blog-6506998626989446594.post-33785540591423076602022-05-12T11:57:00.001+01:002022-05-16T14:45:03.464+01:00Clearing local storage with a BookMarklet<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi425YlvShUtNB4khoN5ZvrWDQfj_O_IZq8uFKN7qaCWksE3iWsr2uFuIf6fAsJlDanAfXi60PhL0oHvNuEe0NVBtHWqLSa_QWS26qLUefH6FSgMQUa78iw7eP-FPdPFlsVL3C5IGyH1glh-w6S93G5B-LBxj-is6rXF5MUoWRGIsK7ALH_9Qf5zT6nHA/s4608/broken_hand_holding_a_bookmark_on_opened_books-scopio-73d84ccc-311f-41b6-86de-73aadeab6d86.jpg" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="400" data-original-height="3456" data-original-width="4608" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi425YlvShUtNB4khoN5ZvrWDQfj_O_IZq8uFKN7qaCWksE3iWsr2uFuIf6fAsJlDanAfXi60PhL0oHvNuEe0NVBtHWqLSa_QWS26qLUefH6FSgMQUa78iw7eP-FPdPFlsVL3C5IGyH1glh-w6S93G5B-LBxj-is6rXF5MUoWRGIsK7ALH_9Qf5zT6nHA/s400/broken_hand_holding_a_bookmark_on_opened_books-scopio-73d84ccc-311f-41b6-86de-73aadeab6d86.jpg"/></a></div>
<label style="display:flex; justify-content: start; align-items: center; font-family: Barlow">
<a style="display:flex; align-items: center" href="https://scop.io">
<img height="20x" src="//cdn.shopify.com/s/files/1/2395/7099/files/Scopio_logo_Color_dark_140x.png?v=1604343350" style="margin: 0px 10px 0px 0px">
</a>
By
<a style="text-decoration: none; margin: 0px 5px;" href="https://scop.io/collections/vendors?q=Inzamam%20Talukder">Inzamam Talukder</a>
</label>
<p>I'm doing a fair bit with <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage"><code>localStorage</code></a> at the minute; and I need to clear it out regularly. Opening the <code>chrome://settings</code> can get boring real quick, so I spent a happy 5 minutes researching the subject and clocked that a <a href="https://dev.to/siddharthshyniben/on-bookmarklets-and-how-to-make-them-45cd">Bookmarklet</a> would work a treat; here it is <a href="javascript:(() => {localStorage.clear(); location.reload(); console.info('Local Storage Cleared')})();">Clear Local Storage</a>, feel free to use it. Here's the JS should you need to adapt it for your purposes:</p>
<pre style='color:#000000;background:#ffffff;'>javascript<span style='color:#800080; '>:</span><span style='color:#808030; '>(</span><span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#808030; '>=</span><span style='color:#808030; '>></span> <span style='color:#800080; '>{</span>
localStorage<span style='color:#808030; '>.</span>clear<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span><span style='color:#800080; '>;</span>
location<span style='color:#808030; '>.</span>reload<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span><span style='color:#800080; '>;</span>
console<span style='color:#808030; '>.</span>info<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>Local Storage Cleared</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span><span style='color:#800080; '>;</span>
<span style='color:#800080; '>}</span><span style='color:#808030; '>)</span><span style='color:#808030; '>(</span><span style='color:#808030; '>)</span><span style='color:#800080; '>;</span>
</pre>
<h2>Edit</h2>
<p>I realised that I needed to refresh the page for the cleared cache to be evident, I've added a <code>location.reload()</code> to do just that.</p>DominicMyershttp://www.blogger.com/profile/15530669398436940737noreply@blogger.com0tag:blogger.com,1999:blog-6506998626989446594.post-63179718467990308402022-04-28T09:53:00.000+01:002022-04-28T09:53:17.468+01:00Unconscious Bias<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNCBDswaQQe4iawqnzB6vvJ80BvibISkzjYLDhmmBe5uszfAhqp5PumGDHVFY0tzA7RhpETVHb_z4cec_2yL5Q-AD4g5QOvkr0lwEEy_2FB0bC0gJpwO1lYq8jAG5Cw18XTLhSka4tySOBKkJpFlomWj3kK1GI8xD7q4gttanm_ALv7LCqLR1LbZl9Zw/s5760/man_in_black_crew_neck_shirt_under_blue_and_white_sunny_cloudy_sky-scopio-5e8fadbe-b159-43ac-9d89-9d14b899d04e.jpg" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="400" data-original-height="3840" data-original-width="5760" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNCBDswaQQe4iawqnzB6vvJ80BvibISkzjYLDhmmBe5uszfAhqp5PumGDHVFY0tzA7RhpETVHb_z4cec_2yL5Q-AD4g5QOvkr0lwEEy_2FB0bC0gJpwO1lYq8jAG5Cw18XTLhSka4tySOBKkJpFlomWj3kK1GI8xD7q4gttanm_ALv7LCqLR1LbZl9Zw/s400/man_in_black_crew_neck_shirt_under_blue_and_white_sunny_cloudy_sky-scopio-5e8fadbe-b159-43ac-9d89-9d14b899d04e.jpg"/></a></div>
<label style="display:flex; justify-content: start; align-items: center; font-family: Barlow">
<a style="display:flex; align-items: center" href="https://scop.io">
<img height="20x" src="//cdn.shopify.com/s/files/1/2395/7099/files/Scopio_logo_Color_dark_140x.png?v=1604343350" style="margin: 0px 10px 0px 0px">
</a>
By
<a style="text-decoration: none; margin: 0px 5px;" href="https://scop.io/collections/vendors?q=Maksim%20Chernyshev">Maksim Chernyshev</a>
</label>
<p>We just had a work based session on unconscious bias, and while I didn't contribute, I got to thinking about my own unconscious bias. I believe my unconscious bias has been mostly burnt out; let me explain: The good and bad thing about being from Yorkshire (and being raised by my Ma) is that I grew up hating everyone! It wasn't a race, religion, ability or gender thing; it was everyone: people from other countries, counties, towns or villages; even people who lived on different streets or who lived on our street in a different house, sometimes even people in our home, and quite possibly, ourselves.</p>
<p>It was only once I left Yorkshire (and grew up some more) that I clocked that, on the whole, I like everyone. This realisation was firmed up by my early career and the odd personality test, which indicated I was more gregarious than curmudgeonly.</p>DominicMyershttp://www.blogger.com/profile/15530669398436940737noreply@blogger.com0tag:blogger.com,1999:blog-6506998626989446594.post-45750643563160315992022-04-25T08:22:00.001+01:002022-04-25T08:22:58.382+01:00Form data to table<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOta5i7ynHdRscRQgX7WUJEZeRmWFcwPuy_59VgIZe9niXKDeRmSLiouMJWEYeTk20RxKIgj8IinKCK80LrcPq-rgsACxBUQjy8j1oyCG37M6iUooCPV42q06fyaJQrPUBZkJK_XA2HLE5O6QGYSXXfDRlc0IT_zGco-68BfgmbLufW_aXvtVPA2NO9g/s2048/brown_wooden_table-scopio-2bebdb49-a2cd-4eab-bdf5-88bae349ac3c.jpg" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="400" data-original-height="2048" data-original-width="2048" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOta5i7ynHdRscRQgX7WUJEZeRmWFcwPuy_59VgIZe9niXKDeRmSLiouMJWEYeTk20RxKIgj8IinKCK80LrcPq-rgsACxBUQjy8j1oyCG37M6iUooCPV42q06fyaJQrPUBZkJK_XA2HLE5O6QGYSXXfDRlc0IT_zGco-68BfgmbLufW_aXvtVPA2NO9g/s400/brown_wooden_table-scopio-2bebdb49-a2cd-4eab-bdf5-88bae349ac3c.jpg"/></a></div>
<label style="display:flex; justify-content: start; align-items: center; font-family: Barlow">
<a style="display:flex; align-items: center" href="https://scop.io">
<img height="20x" src="//cdn.shopify.com/s/files/1/2395/7099/files/Scopio_logo_Color_dark_140x.png?v=1604343350" style="margin: 0px 10px 0px 0px">
</a>
By
<a style="text-decoration: none; margin: 0px 5px;" href="https://scop.io/collections/vendors?q=Dona%20Faye%20Saulog">Dona Faye Saulog</a>
</label>
<p>I've been doing a fair bit with jQuery's <a href="https://api.jquery.com/serialize/#serialize"><code>serialize()</code></a> recently but found myself looking for a way to display the values before submitting them via an <a href="https://api.jquery.com/jquery.ajax/#jQuery-ajax-url-settings"><code>ajax()</code></a> request. A friendly and straightforward method is to take advantage of <a href="https://developer.mozilla.org/en-US/docs/Web/API/console/table"><code>console.table()</code></a> to do the heavy lifting:</p>
<pre style='color:#000000;background:#ffffff;overflow-x:auto;'>console<span style='color:#808030; '>.</span>table<span style='color:#808030; '>(</span><span style='color:#797997; '>Object</span><span style='color:#808030; '>.</span>fromEntries<span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>new</span> URLSearchParams<span style='color:#808030; '>(</span>$form<span style='color:#808030; '>.</span>serialize<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span><span style='color:#808030; '>)</span><span style='color:#808030; '>)</span><span style='color:#808030; '>)</span>
</pre>DominicMyershttp://www.blogger.com/profile/15530669398436940737noreply@blogger.com0tag:blogger.com,1999:blog-6506998626989446594.post-40365117691335231552022-03-25T16:26:00.006+00:002022-04-12T07:31:13.003+01:00FizzBuzz, my arse<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijAhi64ctnte_DoHNvweEV9Tml3DgNdiBnpJPX7Rj_PJDitwDJUBD8CKBbOEBraQG-Ibrw85zqwcNL5dIA7sTvv6iDdDxWRgjuN8gywEjCCH8nKx05lrZhuPdjFxbjYUP_estKaoFLi_TKHI6EKRHQV78XtwoN4f26QZvl9iW_j4OdtxjFuyh9Jjy6Lg/s980/screenshot%20%282%29.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="320" data-original-height="285" data-original-width="980" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijAhi64ctnte_DoHNvweEV9Tml3DgNdiBnpJPX7Rj_PJDitwDJUBD8CKBbOEBraQG-Ibrw85zqwcNL5dIA7sTvv6iDdDxWRgjuN8gywEjCCH8nKx05lrZhuPdjFxbjYUP_estKaoFLi_TKHI6EKRHQV78XtwoN4f26QZvl9iW_j4OdtxjFuyh9Jjy6Lg/s320/screenshot%20%282%29.png"/></a></div>
<p>If you ever look me up on Goodreads, you'll find that I took an age to read <a href="https://www.goodreads.com/book/show/53776568-the-fizz-buzz-fix">The Fizz Buzz Fix: Secrets to Thinking Like an Experienced Software Developer.</a>. I was primarily interested in reading about the FizzBuzz problem and found the rest exhausting (I wonder if they do it as an audio version?). Anyway, I found myself pondering it again recently and came across this version by <a href="https://codeburst.io/javascript-breaking-down-the-shortest-possible-fizzbuzz-answer-94a0ad9d128a">Brandon Morelli</a>:</p>
<pre style='color:#000000;background:#ffffff;overflow-x:auto;'><span style='color:#800000; font-weight:bold; '>for</span><span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>let</span> i<span style='color:#808030; '>=</span><span style='color:#008c00; '>0</span><span style='color:#800080; '>;</span>i<span style='color:#808030; '><</span><span style='color:#008c00; '>100</span><span style='color:#800080; '>;</span><span style='color:#808030; '>)</span>console<span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>log</span><span style='color:#808030; '>(</span><span style='color:#808030; '>(</span><span style='color:#808030; '>++</span>i<span style='color:#808030; '>%</span><span style='color:#008c00; '>3</span><span style='color:#800080; '>?</span><span style='color:#800000; '>'</span><span style='color:#800000; '>'</span><span style='color:#800080; '>:</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>fizz</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span><span style='color:#808030; '>+</span><span style='color:#808030; '>(</span>i<span style='color:#808030; '>%</span><span style='color:#008c00; '>5</span><span style='color:#800080; '>?</span><span style='color:#800000; '>'</span><span style='color:#800000; '>'</span><span style='color:#800080; '>:</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>buzz</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span><span style='color:#808030; '>||</span>i<span style='color:#808030; '>)</span>
</pre>
<p>Aye, it's brilliant, but all approaches seem to end up using a <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for">For</a> loop, and I got to thinking about alternatives. Thanks to messing about with other coding challenges, I clocked the way of generating an array, then thought about using that generated array with a <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach">forEach</a>:</p>
<pre style='color:#000000;background:#ffffff;overflow-x:auto;'><span style='color:#797997; '>Array</span><span style='color:#808030; '>.</span>from<span style='color:#808030; '>(</span><span style='color:#800080; '>{</span><span style='color:#800000; font-weight:bold; '>length</span><span style='color:#800080; '>:</span> <span style='color:#008c00; '>100</span><span style='color:#800080; '>}</span><span style='color:#808030; '>,</span> <span style='color:#808030; '>(</span>_<span style='color:#808030; '>,</span> i<span style='color:#808030; '>)</span> <span style='color:#808030; '>=</span><span style='color:#808030; '>></span> i <span style='color:#808030; '>+</span> <span style='color:#008c00; '>1</span><span style='color:#808030; '>)</span><span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>forEach</span><span style='color:#808030; '>(</span>i <span style='color:#808030; '>=</span><span style='color:#808030; '>></span> <span style='color:#800080; '>{</span>
console<span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>log</span><span style='color:#808030; '>(</span><span style='color:#808030; '>(</span>i<span style='color:#808030; '>%</span><span style='color:#008c00; '>3</span> <span style='color:#808030; '>&&</span> i<span style='color:#808030; '>%</span><span style='color:#008c00; '>5</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>?</span> <span style='color:#800000; '>`</span><span style='color:#800000; '>${</span><span style='color:#797997; '>i</span><span style='color:#800000; '>}</span><span style='color:#800000; '>`</span> <span style='color:#800080; '>:</span> <span style='color:#800000; '>`</span><span style='color:#800000; '>${</span><span style='color:#797997; '>i</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '> </span><span style='color:#800000; '>${</span><span style='color:#808030; '>(</span><span style='color:#797997; '>i</span><span style='color:#808030; '>%</span><span style='color:#008c00; '>3</span><span style='color:#797997; '> </span><span style='color:#800080; '>?</span><span style='color:#797997; '> </span><span style='color:#800000; '>'</span><span style='color:#800000; '>'</span><span style='color:#797997; '> </span><span style='color:#800080; '>:</span><span style='color:#797997; '> </span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>Fizz</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span><span style='color:#797997; '> </span><span style='color:#808030; '>+</span><span style='color:#797997; '> </span><span style='color:#808030; '>(</span><span style='color:#797997; '>i</span><span style='color:#808030; '>%</span><span style='color:#008c00; '>5</span><span style='color:#797997; '> </span><span style='color:#800080; '>?</span><span style='color:#797997; '> </span><span style='color:#800000; '>'</span><span style='color:#800000; '>'</span><span style='color:#797997; '> </span><span style='color:#800080; '>:</span><span style='color:#797997; '> </span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>Buzz</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span><span style='color:#800000; '>}</span><span style='color:#800000; '>`</span><span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span><span style='color:#808030; '>)</span>
</pre>
<p>This method has the benefit of not adding an extra space after the number for those numbers that aren't divisible by three or five. The forEach seems as fast for numbers up to 100 during testing and <a href="https://jsbench.me/3kl16iuse3/">faster for numbers up to 1000</a>.</p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIA2f6rd3niI9qqJ7g-bYL_TthkMjWeqiY3ZOxotnDM_dLYnapL-VMm7p_5KvsV41HqHaMtJLVL92G5Nymz9MWdf_n_5WJ92rBvnNIB20Ag8QJOvbp5g_AR46scpoZex4Uz9ZRgBctIs94CeBVzpVLCcZWFyqmAH-sZP-lY-Sb-A5Hf962cQGlAwk2qQ/s980/screenshot%20%283%29.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="320" data-original-height="250" data-original-width="980" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIA2f6rd3niI9qqJ7g-bYL_TthkMjWeqiY3ZOxotnDM_dLYnapL-VMm7p_5KvsV41HqHaMtJLVL92G5Nymz9MWdf_n_5WJ92rBvnNIB20Ag8QJOvbp5g_AR46scpoZex4Uz9ZRgBctIs94CeBVzpVLCcZWFyqmAH-sZP-lY-Sb-A5Hf962cQGlAwk2qQ/s320/screenshot%20%283%29.png"/></a></div>
<p>The images of code are from <a href="https://chalk.ist">https://chalk.ist</a>, bloody brilliant aren't they?</p>
DominicMyershttp://www.blogger.com/profile/15530669398436940737noreply@blogger.com0tag:blogger.com,1999:blog-6506998626989446594.post-36560415460830209322022-01-02T11:26:00.003+00:002022-04-12T07:33:26.182+01:00JSONDB(ish)<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEiTPMafPP_iqW8lzU6ruXe5O3KgGO7m_Y-Ue0mbuenYfikyu1zdjHne_zKWs17n4uCvqBasLum4b2BNC7uqFCAutWW1aXmS_bGhTxOYZ-zerxgSqlqHfZN8QGNre2C9TMDJnFp7gudmez5Y69ThQY0vsl_MrPwxOKUe-jsjqpT--Q5_ZIMxD7hOKE8afg=s3872" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" height="400" data-original-height="3872" data-original-width="2581" src="https://blogger.googleusercontent.com/img/a/AVvXsEiTPMafPP_iqW8lzU6ruXe5O3KgGO7m_Y-Ue0mbuenYfikyu1zdjHne_zKWs17n4uCvqBasLum4b2BNC7uqFCAutWW1aXmS_bGhTxOYZ-zerxgSqlqHfZN8QGNre2C9TMDJnFp7gudmez5Y69ThQY0vsl_MrPwxOKUe-jsjqpT--Q5_ZIMxD7hOKE8afg=s400"/></a></div>
<label style="display:flex; justify-content: start; align-items: center; font-family: Barlow">
<a style="display:flex; align-items: center" href="https://scop.io">
<img height="20x" src="//cdn.shopify.com/s/files/1/2395/7099/files/Scopio_logo_Color_dark_140x.png?v=1604343350" style="margin: 0px 10px 0px 0px">
</a>
By
<a style="text-decoration: none; margin: 0px 5px;" href="https://scop.io/collections/vendors?q=Danielle+Kilgore">Danielle Kilgore</a>
</label>
<p>It's that time of year when I have a little time to piddle about, so I decided to do a little research, prompted by reading <a href="https://calendar.perfplanet.com/2021/beyond-json-performance/" target="_blank">this post</a> from Andrea Giammarchi. I've written loads about DataTables over the years, so think about grabbing data from APIs probably far too much for someone to be sane. I'm also old enough to remember that AJAX was initially designed to get XML from data sources rather than the JSON we currently, mainly, acquire and process. There's a section in <a href="https://shop.bcs.org/store/221/detail/WorkGroupByIsbn/9781780174761" target="_blank">my book</a> (pp. 143-147) about the costs and benefits of both data formats.</p>
<p>Andrea prompted my examination of <a href="https://github.com/WebReflection/JSONH" target="_blank">JSONH</a>, which - in turn - pointed me to <a href="http://michaux.ca/articles/json-db-a-compressed-json-format" target="_blank">JSONDB</a>, and then I found <a href="https://gist.github.com/devongovett/1039559" target="_blank">Devon Govett's implementation</a>. I got to thinking about making JSON even smaller!</p>
<p>In an early draft, I compared the relative sizes of both the XML and JSON used as an example; I thought it'd be interesting to fiddle with the family's data I use to get to grips with the adapted CoffeeScript implementation of JSONDB. I also tweaked it to consider nested arrays of objects because why wouldn't you? Anyway, this is the data I'll be comparing:</p>
<pre style='color:#000000;background:#ffffff;'><span style='color:#800000; font-weight:bold; '>const</span> familyJSON <span style='color:#808030; '>=</span> <span style='color:#800080; '>{</span>
family<span style='color:#800080; '>:</span> <span style='color:#808030; '>[</span>
<span style='color:#800080; '>{</span>
title<span style='color:#800080; '>:</span> <span style='color:#800000; '>"</span><span style='color:#0000e6; '>Dr</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
forename<span style='color:#800080; '>:</span> <span style='color:#800000; '>"</span><span style='color:#0000e6; '>08</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
surname<span style='color:#800080; '>:</span> <span style='color:#800000; '>"</span><span style='color:#0000e6; '>08</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
dateOfBirth<span style='color:#800080; '>:</span> <span style='color:#800000; '>"</span><span style='color:#0000e6; '>08/08/0808</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
hairColour<span style='color:#800080; '>:</span> <span style='color:#800000; '>"</span><span style='color:#0000e6; '>brown</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
eyeColour<span style='color:#800080; '>:</span> <span style='color:#800000; '>"</span><span style='color:#0000e6; '>brown</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
handedness<span style='color:#800080; '>:</span> <span style='color:#800000; '>"</span><span style='color:#0000e6; '>left</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
something<span style='color:#800080; '>:</span> <span style='color:#808030; '>[</span>
<span style='color:#800080; '>{</span>
one<span style='color:#800080; '>:</span> <span style='color:#008c00; '>1</span><span style='color:#808030; '>,</span>
two<span style='color:#800080; '>:</span> <span style='color:#008c00; '>2</span><span style='color:#808030; '>,</span>
three<span style='color:#800080; '>:</span> <span style='color:#808030; '>[</span><span style='color:#008c00; '>1</span><span style='color:#808030; '>,</span> <span style='color:#008c00; '>2</span><span style='color:#808030; '>]</span>
<span style='color:#800080; '>}</span><span style='color:#808030; '>,</span>
<span style='color:#800080; '>{</span>
one<span style='color:#800080; '>:</span> <span style='color:#008c00; '>2</span><span style='color:#808030; '>,</span>
two<span style='color:#800080; '>:</span> <span style='color:#008c00; '>4</span><span style='color:#808030; '>,</span>
three<span style='color:#800080; '>:</span> <span style='color:#808030; '>[</span><span style='color:#008c00; '>2</span><span style='color:#808030; '>,</span> <span style='color:#008c00; '>4</span><span style='color:#808030; '>]</span>
<span style='color:#800080; '>}</span>
<span style='color:#808030; '>]</span>
<span style='color:#800080; '>}</span><span style='color:#808030; '>,</span>
<span style='color:#800080; '>{</span>
title<span style='color:#800080; '>:</span> <span style='color:#800000; '>"</span><span style='color:#0000e6; '>Dr</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
forename<span style='color:#800080; '>:</span> <span style='color:#800000; '>"</span><span style='color:#0000e6; '>09</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
surname<span style='color:#800080; '>:</span> <span style='color:#800000; '>"</span><span style='color:#0000e6; '>09</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
dateOfBirth<span style='color:#800080; '>:</span> <span style='color:#800000; '>"</span><span style='color:#0000e6; '>09/09/0909</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
hairColour<span style='color:#800080; '>:</span> <span style='color:#800000; '>"</span><span style='color:#0000e6; '>white</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
eyeColour<span style='color:#800080; '>:</span> <span style='color:#800000; '>"</span><span style='color:#0000e6; '>silver</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
handedness<span style='color:#800080; '>:</span> <span style='color:#800000; '>"</span><span style='color:#0000e6; '>ambidextrous</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
something<span style='color:#800080; '>:</span> <span style='color:#808030; '>[</span>
<span style='color:#800080; '>{</span>
one<span style='color:#800080; '>:</span> <span style='color:#008c00; '>3</span><span style='color:#808030; '>,</span>
two<span style='color:#800080; '>:</span> <span style='color:#008c00; '>4</span><span style='color:#808030; '>,</span>
three<span style='color:#800080; '>:</span> <span style='color:#808030; '>[</span><span style='color:#008c00; '>3</span><span style='color:#808030; '>,</span> <span style='color:#008c00; '>4</span><span style='color:#808030; '>]</span>
<span style='color:#800080; '>}</span><span style='color:#808030; '>,</span>
<span style='color:#800080; '>{</span>
one<span style='color:#800080; '>:</span> <span style='color:#008c00; '>6</span><span style='color:#808030; '>,</span>
two<span style='color:#800080; '>:</span> <span style='color:#008c00; '>8</span><span style='color:#808030; '>,</span>
three<span style='color:#800080; '>:</span> <span style='color:#808030; '>[</span><span style='color:#008c00; '>6</span><span style='color:#808030; '>,</span> <span style='color:#008c00; '>8</span><span style='color:#808030; '>]</span>
<span style='color:#800080; '>}</span>
<span style='color:#808030; '>]</span>
<span style='color:#800080; '>}</span><span style='color:#808030; '>,</span>
<span style='color:#800080; '>{</span>
title<span style='color:#800080; '>:</span> <span style='color:#800000; '>"</span><span style='color:#0000e6; '>Dr</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
forename<span style='color:#800080; '>:</span> <span style='color:#800000; '>"</span><span style='color:#0000e6; '>10</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
surname<span style='color:#800080; '>:</span> <span style='color:#800000; '>"</span><span style='color:#0000e6; '>10</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
dateOfBirth<span style='color:#800080; '>:</span> <span style='color:#800000; '>"</span><span style='color:#0000e6; '>10/10/1010</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
hairColour<span style='color:#800080; '>:</span> <span style='color:#0f4d75; '>null</span><span style='color:#808030; '>,</span>
eyeColour<span style='color:#800080; '>:</span> <span style='color:#0f4d75; '>null</span><span style='color:#808030; '>,</span>
handedness<span style='color:#800080; '>:</span> <span style='color:#800000; '>"</span><span style='color:#0000e6; '>ambilevous</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
something<span style='color:#800080; '>:</span> <span style='color:#808030; '>[</span>
<span style='color:#800080; '>{</span>
one<span style='color:#800080; '>:</span> <span style='color:#008c00; '>5</span><span style='color:#808030; '>,</span>
two<span style='color:#800080; '>:</span> <span style='color:#008c00; '>6</span><span style='color:#808030; '>,</span>
three<span style='color:#800080; '>:</span> <span style='color:#808030; '>[</span><span style='color:#008c00; '>5</span><span style='color:#808030; '>,</span> <span style='color:#008c00; '>6</span><span style='color:#808030; '>]</span>
<span style='color:#800080; '>}</span><span style='color:#808030; '>,</span>
<span style='color:#800080; '>{</span>
one<span style='color:#800080; '>:</span> <span style='color:#008c00; '>10</span><span style='color:#808030; '>,</span>
two<span style='color:#800080; '>:</span> <span style='color:#008c00; '>12</span><span style='color:#808030; '>,</span>
three<span style='color:#800080; '>:</span> <span style='color:#808030; '>[</span><span style='color:#008c00; '>10</span><span style='color:#808030; '>,</span> <span style='color:#008c00; '>12</span><span style='color:#808030; '>]</span>
<span style='color:#800080; '>}</span>
<span style='color:#808030; '>]</span>
<span style='color:#800080; '>}</span><span style='color:#808030; '>,</span>
<span style='color:#800080; '>{</span>
title<span style='color:#800080; '>:</span> <span style='color:#800000; '>"</span><span style='color:#0000e6; '>Dr</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
forename<span style='color:#800080; '>:</span> <span style='color:#800000; '>"</span><span style='color:#0000e6; '>11</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
surname<span style='color:#800080; '>:</span> <span style='color:#800000; '>"</span><span style='color:#0000e6; '>11</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
dateOfBirth<span style='color:#800080; '>:</span> <span style='color:#800000; '>"</span><span style='color:#0000e6; '>11/11/1111</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
hairColour<span style='color:#800080; '>:</span> <span style='color:#800000; '>"</span><span style='color:#0000e6; '>brown</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
eyeColour<span style='color:#800080; '>:</span> <span style='color:#800000; '>"</span><span style='color:#0000e6; '>brown</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
handedness<span style='color:#800080; '>:</span> <span style='color:#800000; '>"</span><span style='color:#0000e6; '>right</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
something<span style='color:#800080; '>:</span> <span style='color:#808030; '>[</span>
<span style='color:#800080; '>{</span>
one<span style='color:#800080; '>:</span> <span style='color:#008c00; '>7</span><span style='color:#808030; '>,</span>
two<span style='color:#800080; '>:</span> <span style='color:#008c00; '>8</span><span style='color:#808030; '>,</span>
three<span style='color:#800080; '>:</span> <span style='color:#808030; '>[</span><span style='color:#008c00; '>7</span><span style='color:#808030; '>,</span> <span style='color:#008c00; '>8</span><span style='color:#808030; '>]</span>
<span style='color:#800080; '>}</span><span style='color:#808030; '>,</span>
<span style='color:#800080; '>{</span>
one<span style='color:#800080; '>:</span> <span style='color:#008c00; '>14</span><span style='color:#808030; '>,</span>
two<span style='color:#800080; '>:</span> <span style='color:#008c00; '>16</span><span style='color:#808030; '>,</span>
three<span style='color:#800080; '>:</span> <span style='color:#808030; '>[</span><span style='color:#008c00; '>14</span><span style='color:#808030; '>,</span> <span style='color:#008c00; '>16</span><span style='color:#808030; '>]</span>
<span style='color:#800080; '>}</span>
<span style='color:#808030; '>]</span>
<span style='color:#800080; '>}</span>
<span style='color:#808030; '>]</span>
<span style='color:#800080; '>}</span>
</pre>
<p>And this is the helper class I created:</p>
<pre style='color:#000000;background:#ffffff;'><span style='color:#800000; font-weight:bold; '>class</span> JSONDB <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>static</span> isObject <span style='color:#808030; '>=</span> o <span style='color:#808030; '>=</span><span style='color:#808030; '>></span> o <span style='color:#800000; font-weight:bold; '>instanceof</span> <span style='color:#797997; '>Object</span> <span style='color:#808030; '>&&</span> o<span style='color:#808030; '>.</span><span style='color:#797997; '>constructor</span> <span style='color:#808030; '>===</span> <span style='color:#797997; '>Object</span>
<span style='color:#800000; font-weight:bold; '>static</span> pack <span style='color:#808030; '>=</span> records <span style='color:#808030; '>=</span><span style='color:#808030; '>></span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>const</span> <span style='color:#800000; font-weight:bold; '>keys</span> <span style='color:#808030; '>=</span> <span style='color:#797997; '>Object</span><span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>keys</span><span style='color:#808030; '>(</span>records<span style='color:#808030; '>[</span><span style='color:#008c00; '>0</span><span style='color:#808030; '>]</span><span style='color:#808030; '>)</span><span style='color:#800080; '>;</span>
<span style='color:#800000; font-weight:bold; '>const</span> ret <span style='color:#808030; '>=</span> <span style='color:#808030; '>[</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>JSONDB</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span> <span style='color:#800000; font-weight:bold; '>keys</span><span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>length</span><span style='color:#808030; '>,</span> <span style='color:#808030; '>.</span><span style='color:#808030; '>.</span><span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>keys</span><span style='color:#808030; '>]</span>
<span style='color:#800000; font-weight:bold; '>for</span> <span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>let</span> i <span style='color:#808030; '>=</span> <span style='color:#008c00; '>0</span><span style='color:#800080; '>;</span> i <span style='color:#808030; '><</span> records<span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>length</span><span style='color:#800080; '>;</span> i<span style='color:#808030; '>++</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>for</span> <span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>const</span> key <span style='color:#800000; font-weight:bold; '>in</span> records<span style='color:#808030; '>[</span>i<span style='color:#808030; '>]</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>const</span> record <span style='color:#808030; '>=</span> records<span style='color:#808030; '>[</span>i<span style='color:#808030; '>]</span><span style='color:#808030; '>[</span>key<span style='color:#808030; '>]</span>
ret<span style='color:#808030; '>.</span>push<span style='color:#808030; '>(</span><span style='color:#797997; '>Array</span><span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>isArray</span><span style='color:#808030; '>(</span>record<span style='color:#808030; '>)</span> <span style='color:#808030; '>&&</span> record<span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>every</span><span style='color:#808030; '>(</span>el <span style='color:#808030; '>=</span><span style='color:#808030; '>></span>
<span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>isObject<span style='color:#808030; '>(</span>el<span style='color:#808030; '>)</span><span style='color:#808030; '>)</span>
<span style='color:#800080; '>?</span> <span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>pack<span style='color:#808030; '>(</span>record<span style='color:#808030; '>)</span>
<span style='color:#800080; '>:</span> record<span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span>
<span style='color:#800080; '>}</span>
<span style='color:#800000; font-weight:bold; '>return</span> ret<span style='color:#800080; '>;</span>
<span style='color:#800080; '>}</span><span style='color:#800080; '>;</span>
<span style='color:#800000; font-weight:bold; '>static</span> unpack <span style='color:#808030; '>=</span> array <span style='color:#808030; '>=</span><span style='color:#808030; '>></span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>if</span> <span style='color:#808030; '>(</span>array<span style='color:#808030; '>[</span><span style='color:#008c00; '>0</span><span style='color:#808030; '>]</span> <span style='color:#808030; '>!==</span> <span style='color:#800000; '>'</span><span style='color:#0000e6; '>JSONDB</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>return</span> array<span style='color:#800080; '>;</span>
<span style='color:#800080; '>}</span>
<span style='color:#800000; font-weight:bold; '>const</span> numKeys <span style='color:#808030; '>=</span> array<span style='color:#808030; '>[</span><span style='color:#008c00; '>1</span><span style='color:#808030; '>]</span><span style='color:#800080; '>;</span>
<span style='color:#800000; font-weight:bold; '>const</span> pos <span style='color:#808030; '>=</span> numKeys <span style='color:#808030; '>+</span> <span style='color:#008c00; '>2</span><span style='color:#800080; '>;</span>
<span style='color:#800000; font-weight:bold; '>const</span> <span style='color:#800000; font-weight:bold; '>keys</span> <span style='color:#808030; '>=</span> array<span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>slice</span><span style='color:#808030; '>(</span><span style='color:#008c00; '>2</span><span style='color:#808030; '>,</span> pos<span style='color:#808030; '>)</span><span style='color:#800080; '>;</span>
<span style='color:#800000; font-weight:bold; '>const</span> ret <span style='color:#808030; '>=</span> <span style='color:#808030; '>[</span><span style='color:#808030; '>]</span><span style='color:#800080; '>;</span>
<span style='color:#800000; font-weight:bold; '>let</span> cur <span style='color:#808030; '>=</span> <span style='color:#800080; '>{</span><span style='color:#800080; '>}</span><span style='color:#800080; '>;</span>
<span style='color:#800000; font-weight:bold; '>const</span> iterable <span style='color:#808030; '>=</span> array<span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>slice</span><span style='color:#808030; '>(</span>pos<span style='color:#808030; '>)</span><span style='color:#800080; '>;</span>
<span style='color:#800000; font-weight:bold; '>for</span> <span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>let</span> i <span style='color:#808030; '>=</span> <span style='color:#008c00; '>0</span><span style='color:#800080; '>;</span> i <span style='color:#808030; '><</span> iterable<span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>length</span><span style='color:#800080; '>;</span> i<span style='color:#808030; '>++</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>let</span> val <span style='color:#808030; '>=</span> iterable<span style='color:#808030; '>[</span>i<span style='color:#808030; '>]</span><span style='color:#800080; '>;</span>
<span style='color:#800000; font-weight:bold; '>if</span><span style='color:#808030; '>(</span><span style='color:#797997; '>Array</span><span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>isArray</span><span style='color:#808030; '>(</span>val<span style='color:#808030; '>)</span><span style='color:#808030; '>)</span><span style='color:#800080; '>{</span>
val <span style='color:#808030; '>=</span> <span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>.</span>unpack<span style='color:#808030; '>(</span>val<span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span>
<span style='color:#800000; font-weight:bold; '>if</span> <span style='color:#808030; '>(</span><span style='color:#808030; '>(</span>i <span style='color:#808030; '>></span> <span style='color:#008c00; '>0</span><span style='color:#808030; '>)</span> <span style='color:#808030; '>&&</span> <span style='color:#808030; '>(</span><span style='color:#808030; '>(</span>i <span style='color:#808030; '>%</span> numKeys<span style='color:#808030; '>)</span> <span style='color:#808030; '>===</span> <span style='color:#008c00; '>0</span><span style='color:#808030; '>)</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
ret<span style='color:#808030; '>.</span>push<span style='color:#808030; '>(</span>cur<span style='color:#808030; '>)</span><span style='color:#800080; '>;</span>
cur <span style='color:#808030; '>=</span> <span style='color:#800080; '>{</span><span style='color:#800080; '>}</span><span style='color:#800080; '>;</span>
<span style='color:#800080; '>}</span>
<span style='color:#800000; font-weight:bold; '>const</span> key <span style='color:#808030; '>=</span> <span style='color:#800000; font-weight:bold; '>keys</span><span style='color:#808030; '>[</span>i <span style='color:#808030; '>%</span> numKeys<span style='color:#808030; '>]</span><span style='color:#800080; '>;</span>
cur<span style='color:#808030; '>[</span>key<span style='color:#808030; '>]</span> <span style='color:#808030; '>=</span> val<span style='color:#800080; '>;</span>
<span style='color:#800080; '>}</span>
ret<span style='color:#808030; '>.</span>push<span style='color:#808030; '>(</span>cur<span style='color:#808030; '>)</span><span style='color:#800080; '>;</span>
<span style='color:#800000; font-weight:bold; '>return</span> ret<span style='color:#800080; '>;</span>
<span style='color:#800080; '>}</span>
<span style='color:#800080; '>}</span>
</pre>
<p><a href="https://replit.com/@annoyingmouse/JSONH#script.js" target="_blank">This example</a> shows the saving of 339 characters.</p>
<p>This is the compressed data:</p>
<pre style='color:#000000;background:#ffffff;'><span style='color:#808030; '>[</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>JSONDB</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#008c00; '>8</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>title</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>forename</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>surname</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>dateOfBirth</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>hairColour</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>eyeColour</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>handedness</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>something</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>Dr</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>08</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>08</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>08/08/0808</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>brown</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>brown</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>left</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#808030; '>[</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>JSONDB</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#008c00; '>3</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>one</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>two</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>three</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#008c00; '>1</span><span style='color:#808030; '>,</span>
<span style='color:#008c00; '>2</span><span style='color:#808030; '>,</span>
<span style='color:#808030; '>[</span>
<span style='color:#008c00; '>1</span><span style='color:#808030; '>,</span>
<span style='color:#008c00; '>2</span>
<span style='color:#808030; '>]</span><span style='color:#808030; '>,</span>
<span style='color:#008c00; '>2</span><span style='color:#808030; '>,</span>
<span style='color:#008c00; '>4</span><span style='color:#808030; '>,</span>
<span style='color:#808030; '>[</span>
<span style='color:#008c00; '>2</span><span style='color:#808030; '>,</span>
<span style='color:#008c00; '>4</span>
<span style='color:#808030; '>]</span>
<span style='color:#808030; '>]</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>Dr</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>09</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>09</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>09/09/0909</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>white</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>silver</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>ambidextrous</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#808030; '>[</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>JSONDB</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#008c00; '>3</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>one</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>two</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>three</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#008c00; '>3</span><span style='color:#808030; '>,</span>
<span style='color:#008c00; '>4</span><span style='color:#808030; '>,</span>
<span style='color:#808030; '>[</span>
<span style='color:#008c00; '>3</span><span style='color:#808030; '>,</span>
<span style='color:#008c00; '>4</span>
<span style='color:#808030; '>]</span><span style='color:#808030; '>,</span>
<span style='color:#008c00; '>6</span><span style='color:#808030; '>,</span>
<span style='color:#008c00; '>8</span><span style='color:#808030; '>,</span>
<span style='color:#808030; '>[</span>
<span style='color:#008c00; '>6</span><span style='color:#808030; '>,</span>
<span style='color:#008c00; '>8</span>
<span style='color:#808030; '>]</span>
<span style='color:#808030; '>]</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>Dr</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>10</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>10</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>10/10/1010</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#0f4d75; '>null</span><span style='color:#808030; '>,</span>
<span style='color:#0f4d75; '>null</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>ambilevous</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#808030; '>[</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>JSONDB</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#008c00; '>3</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>one</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>two</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>three</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#008c00; '>5</span><span style='color:#808030; '>,</span>
<span style='color:#008c00; '>6</span><span style='color:#808030; '>,</span>
<span style='color:#808030; '>[</span>
<span style='color:#008c00; '>5</span><span style='color:#808030; '>,</span>
<span style='color:#008c00; '>6</span>
<span style='color:#808030; '>]</span><span style='color:#808030; '>,</span>
<span style='color:#008c00; '>10</span><span style='color:#808030; '>,</span>
<span style='color:#008c00; '>12</span><span style='color:#808030; '>,</span>
<span style='color:#808030; '>[</span>
<span style='color:#008c00; '>10</span><span style='color:#808030; '>,</span>
<span style='color:#008c00; '>12</span>
<span style='color:#808030; '>]</span>
<span style='color:#808030; '>]</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>Dr</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>11</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>11</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>11/11/1111</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>brown</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>brown</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>right</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#808030; '>[</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>JSONDB</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#008c00; '>3</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>one</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>two</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#800000; '>"</span><span style='color:#0000e6; '>three</span><span style='color:#800000; '>"</span><span style='color:#808030; '>,</span>
<span style='color:#008c00; '>7</span><span style='color:#808030; '>,</span>
<span style='color:#008c00; '>8</span><span style='color:#808030; '>,</span>
<span style='color:#808030; '>[</span>
<span style='color:#008c00; '>7</span><span style='color:#808030; '>,</span>
<span style='color:#008c00; '>8</span>
<span style='color:#808030; '>]</span><span style='color:#808030; '>,</span>
<span style='color:#008c00; '>14</span><span style='color:#808030; '>,</span>
<span style='color:#008c00; '>16</span><span style='color:#808030; '>,</span>
<span style='color:#808030; '>[</span>
<span style='color:#008c00; '>14</span><span style='color:#808030; '>,</span>
<span style='color:#008c00; '>16</span>
<span style='color:#808030; '>]</span>
<span style='color:#808030; '>]</span>
<span style='color:#808030; '>]</span>
</pre>
<p>I'm wondering where I can implement this approach now; it would seem to offer significant savings in terms of the size of the payload while still returning something that will be relatively quick to convert back into JSON.</p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcJccmY021YnA77ov2FeXpg-9-Hz93D4GnFUXyrvxqzlImwlUL5m40ttE1TXuQws_Y_TeO6sVrpDt91Z2sPL4dhlBxA7XrqW8WxEagR1vW3x9g85zTBpe5KgiZoElWw5OrNEyvlMRPCyYl9Lc9v2PbkuBPDgXI2tcKZJGU846W7dFO4YkUNnZ8OyAc8Q/s1086/screenshot%20%284%29.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" height="400" data-original-height="1086" data-original-width="980" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcJccmY021YnA77ov2FeXpg-9-Hz93D4GnFUXyrvxqzlImwlUL5m40ttE1TXuQws_Y_TeO6sVrpDt91Z2sPL4dhlBxA7XrqW8WxEagR1vW3x9g85zTBpe5KgiZoElWw5OrNEyvlMRPCyYl9Lc9v2PbkuBPDgXI2tcKZJGU846W7dFO4YkUNnZ8OyAc8Q/s400/screenshot%20%284%29.png"/></a></div>
DominicMyershttp://www.blogger.com/profile/15530669398436940737noreply@blogger.com0tag:blogger.com,1999:blog-6506998626989446594.post-31839236926489216792021-07-23T11:28:00.006+01:002022-01-02T11:34:16.448+00:00Email: border-radius and box-shadow<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzwc9td62QKKisXP0l92HqDItkUzrtton2mXa8ko1GdQxroBV6djPhTtgwycU1SjSAsojYhO1Bs3AocvSVzCNCgdwJY9IQP29BQj0qprY0HeRT34HBg44vRKcNrNB_N_NeWEv334buR4OR/s2048/black_and_white_plastic_container-scopio-72e10570-343e-45d2-9736-10124dbbd23c.jpg" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="400" data-original-height="1363" data-original-width="2048" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzwc9td62QKKisXP0l92HqDItkUzrtton2mXa8ko1GdQxroBV6djPhTtgwycU1SjSAsojYhO1Bs3AocvSVzCNCgdwJY9IQP29BQj0qprY0HeRT34HBg44vRKcNrNB_N_NeWEv334buR4OR/s400/black_and_white_plastic_container-scopio-72e10570-343e-45d2-9736-10124dbbd23c.jpg"/></a></div>
<label style="display:flex; justify-content: start; align-items: center; font-family: Barlow">
<a style="display:flex; align-items: center" href="https://scop.io">
<img height="20x" src="//cdn.shopify.com/s/files/1/2395/7099/files/Scopio_logo_Color_dark_140x.png?v=1604343350" style="margin: 0px 10px 0px 0px">
</a>
By
<a style="text-decoration: none; margin: 0px 5px;" href="https://scop.io/collections/vendors?q=Andreas+Steidlinger">Andreas Steidlinger</a>
</label>
<p>I love working with designers; they constantly challenge me to develop new designs to implement. They have their lovely pixel-based programs and design beautiful things, which I then convert into different formats. This conversion is often relatively easy, but recently I had to create an email with the content within a rounded container, a rounded container with a drop shadow.</p>
<p>Let me tell you, that was a pain! I did a fair bit of research and found excellent ways of generating rounded corners (not least <a href="https://drmsite.blogspot.com/2005/12/rounded-corners-with-tables.html">my own from back in the day</a>). <a href="https://agencyentourage.com">AE Writer</a> has an article on <a href="https://agencyentourage.com/blog/drop-shadows-for-html-email/">drop shadow for HTML email</a>, which sort of confirmed my thoughts on needing to use tables. <a href="https://medium.com/@alexvargash">Alejandro Vargas</a> has an article up on Medium about <a href="https://medium.com/@alexvargash/html-email-rounded-corners-2d58c42e491c">HTML email rounded corners</a>. I spent a fair few hours over last weekend taking a screengrab of a container into The Gimp and playing with contrast to generate the appropriate data format for a chunk of JS to generate the appropriate nested divs within a table.</p>
<p>Given this table row:</p>
<pre style='color:#000000;background:#ffffff;overflow-x:auto;'><span style='color:#a65700; '><</span><span style='color:#800000; font-weight:bold; '>tr</span><span style='color:#274796; '> </span><span style='color:#074726; '>data</span><span style='color:#274796; '>-row</span><span style='color:#808030; '>=</span><span style='color:#0000e6; '>"5"</span><span style='color:#274796; '></span>
<span style='color:#274796; '>    </span><span style='color:#074726; '>data</span><span style='color:#274796; '>-description</span><span style='color:#808030; '>=</span><span style='color:#0000e6; '>"6->3-fe->2-fd->2-fc->1-fb->1-fd->ff"</span><span style='color:#a65700; '>></span>
</pre>
<p>This code:</p>
<pre style='color:#000000;background:#ffffff;overflow-x:auto;'><span style='color:#808030; '>(</span><span style='color:#808030; '>(</span><span style='color:#808030; '>)</span><span style='color:#808030; '>=</span><span style='color:#808030; '>></span><span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>const</span> setStyles <span style='color:#808030; '>=</span> <span style='color:#808030; '>(</span>element<span style='color:#808030; '>,</span> declarations<span style='color:#808030; '>)</span> <span style='color:#808030; '>=</span><span style='color:#808030; '>></span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>for</span> <span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>const</span> prop <span style='color:#800000; font-weight:bold; '>in</span> declarations<span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>if</span><span style='color:#808030; '>(</span>declarations<span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>hasOwnProperty</span><span style='color:#808030; '>(</span>prop<span style='color:#808030; '>)</span><span style='color:#808030; '>)</span><span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>const</span> property <span style='color:#808030; '>=</span> prop<span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>split</span><span style='color:#808030; '>(</span><span style='color:#800000; '>/</span><span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>?=</span><span style='color:#808030; '>[</span><span style='color:#0000e6; '>A</span><span style='color:#808030; '>-</span><span style='color:#0000e6; '>Z</span><span style='color:#808030; '>]</span><span style='color:#808030; '>)</span><span style='color:#800000; '>/</span><span style='color:#808030; '>)</span><span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>join</span><span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>-</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span><span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>toLowerCase</span><span style='color:#808030; '>(</span><span style='color:#808030; '>)</span>
element<span style='color:#808030; '>.</span>style<span style='color:#808030; '>[</span>property<span style='color:#808030; '>]</span> <span style='color:#808030; '>=</span> declarations<span style='color:#808030; '>[</span>prop<span style='color:#808030; '>]</span>
<span style='color:#800080; '>}</span>
<span style='color:#800080; '>}</span>
<span style='color:#800080; '>}</span>
document<span style='color:#808030; '>.</span>querySelectorAll<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>tr</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span><span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>forEach</span><span style='color:#808030; '>(</span>tr <span style='color:#808030; '>=</span><span style='color:#808030; '>></span> <span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>if</span><span style='color:#808030; '>(</span>tr<span style='color:#808030; '>.</span>dataset<span style='color:#808030; '>.</span>description<span style='color:#808030; '>)</span><span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>const</span> description <span style='color:#808030; '>=</span> tr<span style='color:#808030; '>.</span>dataset<span style='color:#808030; '>.</span>description<span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>split</span><span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>-></span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span>
<span style='color:#800000; font-weight:bold; '>let</span> target <span style='color:#808030; '>=</span> tr
<span style='color:#800000; font-weight:bold; '>const</span> td <span style='color:#808030; '>=</span> document<span style='color:#808030; '>.</span>createElement<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>td</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span>
td<span style='color:#808030; '>.</span>setAttribute<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>align</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span> <span style='color:#800000; '>'</span><span style='color:#0000e6; '>center</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span>
setStyles<span style='color:#808030; '>(</span>td<span style='color:#808030; '>,</span> <span style='color:#800080; '>{</span>
paddingLeft<span style='color:#800080; '>:</span> <span style='color:#800000; '>`</span><span style='color:#800000; '>${</span><span style='color:#797997; '>description</span><span style='color:#808030; '>[</span><span style='color:#008c00; '>0</span><span style='color:#808030; '>]</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>px</span><span style='color:#800000; '>`</span><span style='color:#808030; '>,</span>
paddingRight<span style='color:#800080; '>:</span><span style='color:#800000; '>`</span><span style='color:#800000; '>${</span><span style='color:#797997; '>description</span><span style='color:#808030; '>[</span><span style='color:#008c00; '>0</span><span style='color:#808030; '>]</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>px</span><span style='color:#800000; '>`</span><span style='color:#808030; '>,</span>
<span style='color:#800080; '>}</span><span style='color:#808030; '>)</span>
<span style='color:#800000; font-weight:bold; '>if</span><span style='color:#808030; '>(</span><span style='color:#808030; '>!</span>tr<span style='color:#808030; '>.</span>dataset<span style='color:#808030; '>.</span>main<span style='color:#808030; '>)</span><span style='color:#800080; '>{</span>
setStyles<span style='color:#808030; '>(</span>td<span style='color:#808030; '>,</span> <span style='color:#800080; '>{</span>
height<span style='color:#800080; '>:</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>1px</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span>
lineHeight<span style='color:#800080; '>:</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>1px</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span>
fontSize<span style='color:#800080; '>:</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>1px</span><span style='color:#800000; '>'</span>
<span style='color:#800080; '>}</span><span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span>
target<span style='color:#808030; '>.</span>appendChild<span style='color:#808030; '>(</span>td<span style='color:#808030; '>)</span>
target <span style='color:#808030; '>=</span> td
description<span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>shift</span><span style='color:#808030; '>(</span><span style='color:#808030; '>)</span>
<span style='color:#800000; font-weight:bold; '>for</span><span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>let</span> i <span style='color:#808030; '>=</span> <span style='color:#008c00; '>0</span><span style='color:#800080; '>;</span> i <span style='color:#808030; '><</span> description<span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>length</span><span style='color:#800080; '>;</span> i<span style='color:#808030; '>++</span><span style='color:#808030; '>)</span><span style='color:#800080; '>{</span>
<span style='color:#800000; font-weight:bold; '>const</span> parts <span style='color:#808030; '>=</span> description<span style='color:#808030; '>[</span>i<span style='color:#808030; '>]</span><span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>split</span><span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>-</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span>
<span style='color:#800000; font-weight:bold; '>const</span> div <span style='color:#808030; '>=</span> document<span style='color:#808030; '>.</span>createElement<span style='color:#808030; '>(</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>div</span><span style='color:#800000; '>'</span><span style='color:#808030; '>)</span>
setStyles<span style='color:#808030; '>(</span>div<span style='color:#808030; '>,</span> <span style='color:#800080; '>{</span>
display<span style='color:#800080; '>:</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>block</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span>
paddingLeft<span style='color:#800080; '>:</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>0px</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span>
paddingRight<span style='color:#800080; '>:</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>0px</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span>
backgroundColor<span style='color:#800080; '>:</span><span style='color:#800000; '>`</span><span style='color:#0000e6; '>#</span><span style='color:#800000; '>${</span><span style='color:#797997; '>parts</span><span style='color:#808030; '>[</span><span style='color:#008c00; '>0</span><span style='color:#808030; '>]</span><span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>repeat</span><span style='color:#808030; '>(</span><span style='color:#008c00; '>3</span><span style='color:#808030; '>)</span><span style='color:#800000; '>}</span><span style='color:#800000; '>`</span><span style='color:#808030; '>,</span>
width<span style='color:#800080; '>:</span> <span style='color:#800000; '>'</span><span style='color:#0000e6; '>100% !important</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span>
minWidth<span style='color:#800080; '>:</span> <span style='color:#800000; '>'</span><span style='color:#0000e6; '>initial !important</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span>
<span style='color:#800080; '>}</span><span style='color:#808030; '>)</span>
<span style='color:#800000; font-weight:bold; '>if</span><span style='color:#808030; '>(</span>parts<span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>length</span> <span style='color:#808030; '>!==</span> <span style='color:#008c00; '>1</span><span style='color:#808030; '>)</span><span style='color:#800080; '>{</span>
setStyles<span style='color:#808030; '>(</span>div<span style='color:#808030; '>,</span> <span style='color:#800080; '>{</span>
paddingLeft<span style='color:#800080; '>:</span> <span style='color:#800000; '>`</span><span style='color:#800000; '>${</span><span style='color:#797997; '>parts</span><span style='color:#808030; '>[</span><span style='color:#008c00; '>0</span><span style='color:#808030; '>]</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>px</span><span style='color:#800000; '>`</span><span style='color:#808030; '>,</span>
paddingRight<span style='color:#800080; '>:</span><span style='color:#800000; '>`</span><span style='color:#800000; '>${</span><span style='color:#797997; '>parts</span><span style='color:#808030; '>[</span><span style='color:#008c00; '>0</span><span style='color:#808030; '>]</span><span style='color:#800000; '>}</span><span style='color:#0000e6; '>px</span><span style='color:#800000; '>`</span><span style='color:#808030; '>,</span>
backgroundColor<span style='color:#800080; '>:</span><span style='color:#800000; '>`</span><span style='color:#0000e6; '>#</span><span style='color:#800000; '>${</span><span style='color:#797997; '>parts</span><span style='color:#808030; '>[</span><span style='color:#008c00; '>1</span><span style='color:#808030; '>]</span><span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>repeat</span><span style='color:#808030; '>(</span><span style='color:#008c00; '>3</span><span style='color:#808030; '>)</span><span style='color:#800000; '>}</span><span style='color:#800000; '>`</span><span style='color:#808030; '>,</span>
<span style='color:#800080; '>}</span><span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span><span style='color:#800000; font-weight:bold; '>else</span><span style='color:#800080; '>{</span>
setStyles<span style='color:#808030; '>(</span>div<span style='color:#808030; '>,</span> <span style='color:#800080; '>{</span>
backgroundColor<span style='color:#800080; '>:</span><span style='color:#800000; '>`</span><span style='color:#0000e6; '>#</span><span style='color:#800000; '>${</span><span style='color:#797997; '>parts</span><span style='color:#808030; '>[</span><span style='color:#008c00; '>0</span><span style='color:#808030; '>]</span><span style='color:#808030; '>.</span><span style='color:#800000; font-weight:bold; '>repeat</span><span style='color:#808030; '>(</span><span style='color:#008c00; '>3</span><span style='color:#808030; '>)</span><span style='color:#800000; '>}</span><span style='color:#800000; '>`</span><span style='color:#808030; '>,</span>
<span style='color:#800080; '>}</span><span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span>
<span style='color:#800000; font-weight:bold; '>if</span><span style='color:#808030; '>(</span><span style='color:#808030; '>!</span>tr<span style='color:#808030; '>.</span>dataset<span style='color:#808030; '>.</span>main<span style='color:#808030; '>)</span><span style='color:#800080; '>{</span>
setStyles<span style='color:#808030; '>(</span>div<span style='color:#808030; '>,</span> <span style='color:#800080; '>{</span>
height<span style='color:#800080; '>:</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>1px</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span>
lineHeight<span style='color:#800080; '>:</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>1px</span><span style='color:#800000; '>'</span><span style='color:#808030; '>,</span>
fontSize<span style='color:#800080; '>:</span><span style='color:#800000; '>'</span><span style='color:#0000e6; '>1px</span><span style='color:#800000; '>'</span>
<span style='color:#800080; '>}</span><span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span>
target<span style='color:#808030; '>.</span>appendChild<span style='color:#808030; '>(</span>div<span style='color:#808030; '>)</span>
target <span style='color:#808030; '>=</span> div
<span style='color:#800080; '>}</span>
<span style='color:#800080; '>}</span>
<span style='color:#800080; '>}</span><span style='color:#808030; '>)</span>
<span style='color:#800080; '>}</span><span style='color:#808030; '>)</span><span style='color:#808030; '>(</span><span style='color:#808030; '>)</span>
</pre>
<p>Would generate this markup:</p>
<pre style='color:#000000;background:#ffffff;overflow-x:auto;'><span style='color:#a65700; '><</span><span style='color:#800000; font-weight:bold; '>tr</span><span style='color:#274796; '> </span><span style='color:#074726; '>data</span><span style='color:#274796; '>-row</span><span style='color:#808030; '>=</span><span style='color:#0000e6; '>"5"</span><span style='color:#274796; '></span>
<span style='color:#274796; '>    </span><span style='color:#074726; '>data</span><span style='color:#274796; '>-description</span><span style='color:#808030; '>=</span><span style='color:#0000e6; '>"6->3-fe->2-fd->2-fc->1-fb->1-fd->ff"</span><span style='color:#a65700; '>></span>
<span style='color:#a65700; '><</span><span style='color:#800000; font-weight:bold; '>td</span><span style='color:#274796; '> </span><span style='color:#074726; '>align</span><span style='color:#808030; '>=</span><span style='color:#0000e6; '>"center"</span><span style='color:#274796; '></span>
<span style='color:#274796; '>      </span><span style='color:#074726; '>style</span><span style='color:#808030; '>=</span><span style='color:#0000e6; '>"</span><span style='color:#bb7977; font-weight:bold; '>padding-left</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>6</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>padding-right</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>6</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>height</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>1</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>line-height</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>1</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>font-size</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>1</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#0000e6; '>"</span><span style='color:#a65700; '>></span>
<span style='color:#a65700; '><</span><span style='color:#800000; font-weight:bold; '>div</span><span style='color:#274796; '> </span><span style='color:#074726; '>style</span><span style='color:#808030; '>=</span><span style='color:#0000e6; '>"</span><span style='color:#bb7977; font-weight:bold; '>display</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#074726; '>block</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>padding-left</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>3</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>padding-right</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>3</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>background-color</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#400000; '>rgb</span><span style='color:#808030; '>(</span><span style='color:#008c00; '>254</span><span style='color:#808030; '>,</span><span style='color:#274796; '> </span><span style='color:#008c00; '>254</span><span style='color:#808030; '>,</span><span style='color:#274796; '> </span><span style='color:#008c00; '>254</span><span style='color:#808030; '>)</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>height</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>1</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>line-height</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>1</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>font-size</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>1</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#0000e6; '>"</span><span style='color:#a65700; '>></span>
<span style='color:#a65700; '><</span><span style='color:#800000; font-weight:bold; '>div</span><span style='color:#274796; '> </span><span style='color:#074726; '>style</span><span style='color:#808030; '>=</span><span style='color:#0000e6; '>"</span><span style='color:#bb7977; font-weight:bold; '>display</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#074726; '>block</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>padding-left</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>2</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>padding-right</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>2</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>background-color</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#400000; '>rgb</span><span style='color:#808030; '>(</span><span style='color:#008c00; '>253</span><span style='color:#808030; '>,</span><span style='color:#274796; '> </span><span style='color:#008c00; '>253</span><span style='color:#808030; '>,</span><span style='color:#274796; '> </span><span style='color:#008c00; '>253</span><span style='color:#808030; '>)</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>height</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>1</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>line-height</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>1</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>font-size</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>1</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#0000e6; '>"</span><span style='color:#a65700; '>></span>
<span style='color:#a65700; '><</span><span style='color:#800000; font-weight:bold; '>div</span><span style='color:#274796; '> </span><span style='color:#074726; '>style</span><span style='color:#808030; '>=</span><span style='color:#0000e6; '>"</span><span style='color:#bb7977; font-weight:bold; '>display</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#074726; '>block</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>padding-left</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>2</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>padding-right</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>2</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>background-color</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#400000; '>rgb</span><span style='color:#808030; '>(</span><span style='color:#008c00; '>252</span><span style='color:#808030; '>,</span><span style='color:#274796; '> </span><span style='color:#008c00; '>252</span><span style='color:#808030; '>,</span><span style='color:#274796; '> </span><span style='color:#008c00; '>252</span><span style='color:#808030; '>)</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>height</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>1</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>line-height</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>1</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>font-size</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>1</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#0000e6; '>"</span><span style='color:#a65700; '>></span>
<span style='color:#a65700; '><</span><span style='color:#800000; font-weight:bold; '>div</span><span style='color:#274796; '> </span><span style='color:#074726; '>style</span><span style='color:#808030; '>=</span><span style='color:#0000e6; '>"</span><span style='color:#bb7977; font-weight:bold; '>display</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#074726; '>block</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>padding-left</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>1</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>padding-right</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>1</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>background-color</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#400000; '>rgb</span><span style='color:#808030; '>(</span><span style='color:#008c00; '>251</span><span style='color:#808030; '>,</span><span style='color:#274796; '> </span><span style='color:#008c00; '>251</span><span style='color:#808030; '>,</span><span style='color:#274796; '> </span><span style='color:#008c00; '>251</span><span style='color:#808030; '>)</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>height</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>1</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>line-height</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>1</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>font-size</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>1</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#0000e6; '>"</span><span style='color:#a65700; '>></span>
<span style='color:#a65700; '><</span><span style='color:#800000; font-weight:bold; '>div</span><span style='color:#274796; '> </span><span style='color:#074726; '>style</span><span style='color:#808030; '>=</span><span style='color:#0000e6; '>"</span><span style='color:#bb7977; font-weight:bold; '>display</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#074726; '>block</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>padding-left</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>1</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>padding-right</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>1</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>background-color</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#400000; '>rgb</span><span style='color:#808030; '>(</span><span style='color:#008c00; '>253</span><span style='color:#808030; '>,</span><span style='color:#274796; '> </span><span style='color:#008c00; '>253</span><span style='color:#808030; '>,</span><span style='color:#274796; '> </span><span style='color:#008c00; '>253</span><span style='color:#808030; '>)</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>height</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>1</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>line-height</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>1</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>font-size</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>1</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#0000e6; '>"</span><span style='color:#a65700; '>></span>
<span style='color:#a65700; '><</span><span style='color:#800000; font-weight:bold; '>div</span><span style='color:#274796; '> </span><span style='color:#074726; '>style</span><span style='color:#808030; '>=</span><span style='color:#0000e6; '>"</span><span style='color:#bb7977; font-weight:bold; '>display</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#074726; '>block</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>padding-left</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>0</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>padding-right</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>0</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>background-color</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#400000; '>rgb</span><span style='color:#808030; '>(</span><span style='color:#008c00; '>255</span><span style='color:#808030; '>,</span><span style='color:#274796; '> </span><span style='color:#008c00; '>255</span><span style='color:#808030; '>,</span><span style='color:#274796; '> </span><span style='color:#008c00; '>255</span><span style='color:#808030; '>)</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>height</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>1</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>line-height</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>1</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#274796; '> </span><span style='color:#bb7977; font-weight:bold; '>font-size</span><span style='color:#808030; '>:</span><span style='color:#274796; '> </span><span style='color:#008c00; '>1</span><span style='color:#006600; '>px</span><span style='color:#800080; '>;</span><span style='color:#0000e6; '>"</span><span style='color:#a65700; '>></span>
<span style='color:#a65700; '></</span><span style='color:#800000; font-weight:bold; '>div</span><span style='color:#a65700; '>></span>
<span style='color:#a65700; '></</span><span style='color:#800000; font-weight:bold; '>div</span><span style='color:#a65700; '>></span>
<span style='color:#a65700; '></</span><span style='color:#800000; font-weight:bold; '>div</span><span style='color:#a65700; '>></span>
<span style='color:#a65700; '></</span><span style='color:#800000; font-weight:bold; '>div</span><span style='color:#a65700; '>></span>
<span style='color:#a65700; '></</span><span style='color:#800000; font-weight:bold; '>div</span><span style='color:#a65700; '>></span>
<span style='color:#a65700; '></</span><span style='color:#800000; font-weight:bold; '>div</span><span style='color:#a65700; '>></span>
<span style='color:#a65700; '></</span><span style='color:#800000; font-weight:bold; '>td</span><span style='color:#a65700; '>></span>
<span style='color:#a65700; '></</span><span style='color:#800000; font-weight:bold; '>tr</span><span style='color:#a65700; '>></span>
</pre>
<p>That whole manual process was boring, though, so I decided to automate the process. Especially as, knowing designers, I just knew that the box-shadow or border-radius would need to change in the future.</p>
<p>I knew that libraries for generating images from DOM elements were available, so I tried a couple. <a href="https://html2canvas.hertzen.com/">html2canvas</a> wasn't quite what I was looking for, but <a href="https://github.com/tsayen/dom-to-image">dom-to-image</a> worked a treat!</p>
<p>I decided to take an incremental approach and started by copying the dom to a png image format and placing that png within a canvas element of the same size as the element. This process is the code within the Immediately Invoked Function Expression (IIFE) at the bottom of the <a href="https://github.com/annoyingmouse/dropShadowForEmail/blob/main/script.js">file</a>. One thing to take note of is the <code>onload</code> function. I ran into all sorts of issues with the subsequent scripts failing until I clocked that the img wasn't loaded when I tried to manipulate it. Once we've set drawn the image atop the canvas, we add some data attributes using the <code>getDimension</code> function - I wouldn't've bothered with this except WebStorm kept complaining about the amount of repeated code I had.</p>
<p><code>trim</code>, invoked at the end of the IIFE, strips out the remaining white space around the image, leaving us with an image that has only grey-scale colours surrounding it (except at the corners). It trims the rows and columns which contain only white colour values by referencing the values from <code>getDimension</code>. <code>getDimension</code> was clever and checked the values from iterating over the data from <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/getImageData">getImageData</a></code>, if any value was not 255 then we had something what was not pure white. The <a href="https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-getimagedata-dev">array</a> from <code>getImageData</code> should be chunked into sub-arrays of four as each lump of four values represent the RGBA value from a single pixel.</p>
<p>Once we have a trimmed image, we can build the values that equate with the data attribute we had in the original implementation. I created a simple class for this as a simple array wouldn't work here as I needed more than just the array of values; I needed to know which was the repeating row, so we had a placeholder for the actual content.</p>
<p>We chunk the data into sub-arrays of four and grab the hex colour value from each chunk. If the preceding HEX value is identical, the preceding classes incidence count is incremented; if not, it's added to the <code>row</code> array. If the <code>row</code> is not identical to the preceding <code>row</code>, then it's added to the <code>rows</code> as a <code>Row</code> object; if it is identical then the preceding <code>Row</code> has it's <code>main</code> value changed to <code>true</code> - this will be our placeholder.</p>
<p>We then build our table using the array of <code>Row</code> objects (<code>rows</code>) using code that is very similar to the one above but that is ever so slightly more nuanced and places a placeholder table within the <code>main</code> row. Nice eh? I'm quite pleased with it.</p>
<ul>
<li><a href="https://github.com/annoyingmouse/dropShadowForEmail">GitHub Repo</a></li>
<li><a href="https://replit.com/@annoyingmouse/DropShadowEmailGenerator-V1#index.html">Repl</li>
<li><a href="https://replit.com/@annoyingmouse/DropShadowEmailGenerator-V2#script.js">Enhanced Repl</li>
</ul> DominicMyershttp://www.blogger.com/profile/15530669398436940737noreply@blogger.com0tag:blogger.com,1999:blog-6506998626989446594.post-11223252688905400302021-07-13T10:55:00.008+01:002022-01-02T11:35:17.563+00:00Rhino SFRA<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiozBPoPfoccjZWZy6xl_U-YS_NtM_2YnSReoQfI_yjUBdQ0253-dxjVTFw1J85xIXrgIV_W6IGXd7FP7TimcA8MP6emu3JCVqS4Z3x1s2jILs-IbGeNBgbIjj8oLxdRxKhq3I59l7IOUIQ/s2048/brown_rhinoceros_on_green_grass_field-scopio-a92e1d2f-82a4-46ee-b669-93d82ab9b2e8.jpg" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="400" data-original-height="2048" data-original-width="2048" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiozBPoPfoccjZWZy6xl_U-YS_NtM_2YnSReoQfI_yjUBdQ0253-dxjVTFw1J85xIXrgIV_W6IGXd7FP7TimcA8MP6emu3JCVqS4Z3x1s2jILs-IbGeNBgbIjj8oLxdRxKhq3I59l7IOUIQ/s400/brown_rhinoceros_on_green_grass_field-scopio-a92e1d2f-82a4-46ee-b669-93d82ab9b2e8.jpg"/></a></div>
<label style="display:flex; justify-content: start; align-items: center; font-family: Barlow">
<a style="display:flex; align-items: center" href="https://scop.io">
<img height="20x" src="//cdn.shopify.com/s/files/1/2395/7099/files/Scopio_logo_Color_dark_140x.png?v=1604343350" style="margin: 0px 10px 0px 0px">
</a>
By
<a style="text-decoration: none; margin: 0px 5px;" href="https://scop.io/collections/vendors?q=Silvia+Ribeiro">Silvia Ribeiro</a>
</label>
<p>Being a fan of JavaScript and now working with SFRA, colleagues told me that we're using Rhino under the hood rather than NodeJS (as I'd assumed from looking at the controllers). Further, from doing a little <a href="https://stackoverflow.com/questions/54423572/what-version-of-rhino-javascript-does-salesforce-commerce-cloud-use#54429841">research</a>, I found out that we're using <a href="https://en.wikipedia.org/wiki/Rhino_(JavaScript_engine)">Rhino 1.7R5</a>. As such, we're a little limited in terms of the JS we can use; <a href="https://mozilla.github.io/rhino/compat/engines.html">proper ES5</a>.</p>DominicMyershttp://www.blogger.com/profile/15530669398436940737noreply@blogger.com0