Reorder chain based on window width

Solved: I received @EdnilsonMaia answer and adapted it http://codepen.io/anon/pen/QNGroX

I have a layout where there is a chain of such users:

Window ------------------- O - O - O - O - O | | | O - O - O - O - O | | | O - O - O | ------------------ O = user - = chain (icon) 

chain diagram

When a user resizes the window, the number of users per line decreases, and the chain needs to be rearranged, increasing the number of lines and reducing the number of users in each line. I found it very similar to sorting algorithms.

Please note that when regrouping, the last user of the first line goes to the last position of the second line and the first user of the second line to the first position of the third line, he must follow the order in which they are connected, changing the position.

I need to be guided by how to code the algorithm in JS. So far, my code changes the position of users, but does not take into account the correct order, as well as chain icons. It also does not work when resizing to its original size.

This is my code, please note that each line is UL split:

 function log(msg, debug) { debug = typeof debug !== 'undefined' ? debug : true; if (debug) { console.log(msg); } } $(document).ready(function() { $(window).on('resize', function() { rearrangeChain(true); }); function rearrangeChain(debug) { debug = typeof debug !== 'undefined' ? debug : false; log('------------------------', debug); var win = $(window); // Percentage // 1170 -------- 100% // size -------- x var totalWindowWidth = 1170; var windowWidth = win.width(); var percentage = (windowWidth * 100) / totalWindowWidth; log('Window:' + percentage + '%', debug); log('Window width:' + win.width() + 'px', debug); var slotSize = 146.25; var imagesPerLine = Math.floor(windowWidth / slotSize); log('Images per line: ' + imagesPerLine, debug); $('ul.users-chain-home').each(function(k) { //var element = $(this); var usersNumber = 1; $(this).find('.user-image').each(function() { var element = $(this).parent(); //console.log('users number', usersNumber, '>', imagesPerLine); if (usersNumber > imagesPerLine) { var nextLine = $('ul.users-chain-home')[k + 1]; console.log('Next line ' + (k + 1), nextLine); if (typeof nextLine != 'undefined') { console.log('Next line append', element[0]); nextLine.appendChild(element[0]); } } usersNumber++; }); log('Users per line chain ' + k + ': ' + usersNumber, debug); }); } rearrangeChain(true); }); 
 div#wrapper { display: inline-block } ul.users-chain-home { list-style-type: none; margin: 0; padding: 0 } ul.users-chain-home li { display: inline; } ul.users-chain-home li div.chain-icon { vertical-align: middle; display: table-cell; width: 40px; height: 96px; text-align: center; } ul.users-chain-home li div.join-chain { vertical-align: middle; display: table-cell; height: 96px; text-align: center; } img.chain-icon-vertical { margin: 5px 42px 5px 0; } img.chain-icon-vertical-left { margin: 5px 0 5px 38px; } 
 <div id="wrapper"> <div> <ul class="users-chain-home"> <li> <img src="img/users/1.jpg" class="user-image"> </li> <li class="chain-icon"> <div class="chain-icon"> <img src="img/assets/chain-icon.gif"> </div> </li> <li> <img src="img/users/2.jpg" class="user-image"> </li> <li class="chain-icon"> <div class="chain-icon"> <img src="img/assets/chain-icon.gif"> </div> </li> <li> <img src="img/users/3.jpg" class="user-image"> </li> <li class="chain-icon"> <div class="chain-icon"> <img src="img/assets/chain-icon.gif"> </div> </li> <li> <img src="img/users/1.jpg" class="user-image"> </li> <li class="chain-icon"> <div class="chain-icon"> <img src="img/assets/chain-icon.gif"> </div> </li> <li> <img src="img/users/2.jpg" class="user-image"> </li> <li class="chain-icon"> <div class="chain-icon"> <img src="img/assets/chain-icon.gif"> </div> </li> <li> <img src="img/users/3.jpg" class="user-image"> </li> <li class="chain-icon"> <div class="chain-icon"> <img src="img/assets/chain-icon.gif"> </div> </li> <li> <img src="img/users/1.jpg" class="user-image"> </li> <li class="chain-icon show-for-large"> <div class="chain-icon"> <img src="img/assets/chain-icon.gif"> </div> </li> <li class="show-for-large"> <img src="img/users/2.jpg" class="user-image"> </li> <li class="chain-icon show-for-large"> <div class="chain-icon"> <img src="img/assets/chain-icon.gif"> </div> </li> <li class="show-for-large"> <img src="img/users/2.jpg" class="user-image"> </li> </ul> </div> <div class="text-right"> <img src="img/assets/chain-icon-vertical.gif" class="chain-icon-vertical"> </div> <div class="text-right"> <ul class="users-chain-home"> <li> <img src="img/users/1.jpg" class="user-image"> </li> <li class="chain-icon"> <div class="chain-icon"> <img src="img/assets/chain-icon.gif"> </div> </li> <li> <img src="img/users/2.jpg" class="user-image"> </li> <li class="chain-icon"> <div class="chain-icon"> <img src="img/assets/chain-icon.gif"> </div> </li> <li> <img src="img/users/3.jpg" class="user-image"> </li> <li class="chain-icon"> <div class="chain-icon"> <img src="img/assets/chain-icon.gif"> </div> </li> <li> <img src="img/users/1.jpg" class="user-image"> </li> <li class="chain-icon"> <div class="chain-icon"> <img src="img/assets/chain-icon.gif"> </div> </li> <li> <img src="img/users/2.jpg" class="user-image"> </li> <li class="chain-icon"> <div class="chain-icon"> <img src="img/assets/chain-icon.gif"> </div> </li> <li> <img src="img/users/3.jpg" class="user-image"> </li> <li class="chain-icon"> <div class="chain-icon"> <img src="img/assets/chain-icon.gif"> </div> </li> <li> <img src="img/users/1.jpg" class="user-image"> </li> <li class="chain-icon"> <div class="chain-icon"> <img src="img/assets/chain-icon.gif"> </div> </li> <li> <img src="img/users/2.jpg" class="user-image"> </li> <li class="chain-icon"> <div class="chain-icon"> <img src="img/assets/chain-icon.gif"> </div> </li> <li> <img src="img/users/3.jpg" class="user-image"> </li> </ul> </div> <div> <img src="img/assets/chain-icon-vertical.gif" class="chain-icon-vertical-left"> </div> <div> <ul class="users-chain-home"> <li> <img src="img/users/1.jpg" class="user-image"> </li> <li class="chain-icon"> <div class="chain-icon"> <img src="img/assets/chain-icon.gif"> </div> </li> <li> <img src="img/users/2.jpg" class="user-image"> </li> <li class="chain-icon"> <div class="chain-icon"> <img src="img/assets/chain-icon.gif"> </div> </li> <li> <img src="img/users/3.jpg" class="user-image"> </li> <li class="chain-icon"> <div class="chain-icon"> <img src="img/assets/chain-icon.gif"> </div> </li> <li> <img src="img/users/1.jpg" class="user-image"> </li> <li class="chain-icon"> <div class="chain-icon"> <img src="img/assets/chain-icon.gif"> </div> </li> <li> <img src="img/users/2.jpg" class="user-image"> </li> <li class="chain-icon"> <div class="chain-icon"> <img src="img/assets/chain-icon.gif"> </div> </li> <li> <img src="img/users/3.jpg" class="user-image"> </li> </ul> </div> </div> 
Run codeHide result
+5
source share
4 answers

Try my solution:

1) PHP / HTML

Creating HTML elements.

 <div id="content"> <ul class="user-chain"> <?php for($i = 1; $i<=50; $i++): ?> <li class="user-item"> <div class="user-container"> <img src="https://cdn1.iconfinder.com/data/icons/user-pictures/100/male3-128.png" class="user-avatar"> </div> </li> <?php endfor; ?> </ul> </div> 

2) CSS

Note. I use FontAwesome to create an icon

  .user-chain { margin: 0; padding: 0 } .user-item { margin: 15px; list-style: none; max-width: 100px; position: absolute; } .user-container { position: relative } .user-avatar { max-width: 100px; max-height: 100px; display: block } .user-container.chain:before { content: "\f0c1"; font-family: FontAwesome; font-style: normal; font-weight: normal; text-decoration: inherit; /*--adjust as necessary--*/ color: #000; font-size: 18px; padding-right: 0.5em; position: absolute; } .user-container.chain-ltr:before { top: 50%; left: -24px; -ms-transform: rotate(-45deg); /* IE 9 */ -webkit-transform: rotate(-45deg); /* Chrome, Safari, Opera */ transform: rotate(-45deg); margin-top: -10px; } .user-container.chain-rtl:before { top: 50%; right: -32px; -ms-transform: rotate(-45deg); /* IE 9 */ -webkit-transform: rotate(-45deg); /* Chrome, Safari, Opera */ transform: rotate(-45deg); margin-top: -10px; } .user-container.chain-ttd:before { top: -20px; right: 50%; -ms-transform: rotate(45deg); /* IE 9 */ -webkit-transform: rotate(45deg); /* Chrome, Safari, Opera */ transform: rotate(45deg); margin-right: -12px; } 

3) jQuery

Get the width of the list container and calculate the maximum values ​​in a row. Define a flag to indicate the direction of the next element in the chain. Use the variable (i) to calculate the fields for each element and the direction of the next element. Calculate the number of rows to determine the top margin.

 $(document).ready(function() { var w_container = $('#content').width(); var elm_h = 100; var elm_w = 100; var elm_m = 15; var maxNodesInLine = Math.floor(w_container / (elm_w + (elm_m *2))); var direction = 'ltr'; var line = 0; var i = 0; function ltr(elm){ console.log('function ltr'); direction = 'ltr'; if(i == 0){ elm.css({"margin-left":0}); } else{ elm.css({"margin-left":(elm_w+(elm_m*2))*i}); } elm.css({"margin-top":(elm_h+(elm_m*2))*line}); i++; } function rtl(elm){ console.log('function rtl'); if(i == (maxNodesInLine)){ elm.css({"margin-left":elm_m*2}); } else{ elm.css({"margin-left":(elm_w+(elm_m*2))*(maxNodesInLine - (i+1))}); } elm.css({"margin-top":(elm_h+(elm_m*2))*line}); i++; } function ttd(elm){ console.log('function ttd'); elm.css({"margin-top":(elm_h+(elm_m*2))*line}); if(direction == 'ltr'){ direction = 'rtl'; elm.css({"margin-left":(elm_w+(elm_m*2))*(i-1)}); } else{ direction = 'ltr'; elm.css({"margin-left":0}); } i=1; } $( ".user-item" ).each(function( index ) { elm = $(this); if(direction == 'ltr' && i < maxNodesInLine) { ltr(elm); $(elm).not(':first-child').children('.user-container').addClass('chain chain-ltr'); } else if(i == (maxNodesInLine)){ line++; ttd(elm); $(elm).children('.user-container').addClass('chain chain-ttd'); } else { rtl(elm); $(elm).children('.user-container').addClass('chain chain-rtl'); } }); $(window).on('resize', function() { console.log('Window re-sized.'); // todo: funtcion to update when resize window... }); }); 

4) Demo https://jsfiddle.net/jftqLf1d/1/

+2
source

Well, you can try the following. First, make your users absolutely positioned:

 div { background: lightgreen; line-height: 30px; position: absolute; text-align: center; width: 30px; } 

Then use the following approach: instead of sorting the HTML elements, it would be easier to simply calculate the location of the element based on simple mathematical calculations. Cm:

 // generate 100 divs document.body.innerHTML = Array.apply(null, new Array(100)).map(function(e, index) { return '<div>' + index + '</div>'; }).join(''); // function which recalculates the positions function render() { var lineLength, margin = 10, height = 30, width = 30; lineLength = Math.floor(document.body.clientWidth / (margin + width)); Array.apply(null, document.querySelectorAll('div')).forEach(function(element, index) { var line = Math.floor(index / lineLength), indexInLine = index - line * lineLength; if (line % 2) indexInLine = lineLength - 1 - indexInLine; element.style.left = indexInLine * (width + margin) + 'px'; element.style.top = line * (height + margin) + 'px'; }); } // initial rendering call render(); // call rendering every time window is resized window.onresize = function() { render(); }; 

See jsfiddle . This is absolutely not the final decision, but the direction. You can improve many things, starting with getting width / height / margin from CSS automatically; getting a parent instead of a body for calculations; and etc.

Adding a chain icon should be very simple: just make it like a pseudo-element ::after in CSS instead of HTML (thereby avoiding a lot of repetition), and for each element at the end of the line just turn it down (by assigning the corresponding class).

+1
source

I have not seen great defendants yet.

Do not be offended, I look forward to hearing :)

So, I go with my CSS idea (bg + flex) and a bit of jQuery to start sorting it, but not using it as it is, it is only for the show, and as it happens, it only cares about the first 4 lines .

 // basic idea , not usable as it is , cares about 4 lines ,it updates CSS flex order. var nbrLi = $('#chain li').size(); var liWidth = $('#chain li').outerWidth(true); var ulWidth = $("#chain").innerWidth(); var perLine = Math.floor(ulWidth / liWidth); // var lastVisualOne= find out left or right line direction then and add margin equals to number of li missing to fill up entire line to avoid justify effect $("#chain li").each(function(i) { this.style.order = i; var nbr = i; if ((i > perLine - 1) && (i < (perLine * 2))) {//* i guess at this point it would be netter to use array() than an each() function */ this.style.order = (perLine * 3) - nbr; this.style.color = "red"; } else if ((i > (perLine * 3) - 1) && (i < (perLine * 4))) {// array() will be more efficient for sure :) this.style.order = (perLine * 7) - nbr; this.style.color = "red"; } else { this.style.order = "i"; } }); 
  ul { padding: 0; margin: 0; display: flex; flex-wrap: wrap; justify-content: space-between; text-align: justify; background: linear-gradient(to top, white, white) no-repeat bottom right, url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCABBAAkDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKACiiigAoqD+1Lb/AJ+IP+/go/tS2/5+IP8Av4KAPzt/be8daxpPxZ8QXCXV1C9rM0FreQzKtzZX+NTktYVGzzNrraWoAWRVwWyknmZT69/4SG+/5+ZPzr5B/be8CaxrHxb8QW62t1K1zK81pZQwhrm+v8anHazKd/mYjW6tdpWNlwGJePy8P9ff8I9ff8+0n5U+gHrlFFFID//Z) repeat-y 30px 60px, url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCABBAAkDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKACiiigAoqD+1Lb/AJ+IP+/go/tS2/5+IP8Av4KAPzt/be8daxpPxZ8QXCXV1C9rM0FreQzKtzZX+NTktYVGzzNrraWoAWRVwWyknmZT69/4SG+/5+ZPzr5B/be8CaxrHxb8QW62t1K1zK81pZQwhrm+v8anHazKd/mYjW6tdpWNlwGJePy8P9ff8I9ff8+0n5U+gHrlFFFID//Z) repeat-y calc(100% - 60px) -40px white; background-size: 100px 100px, 9px 65px, 9px 65px; } li { font-size: 2rem; margin: 0 32px 32px 0; display: inline-block; width: 60px; height: 60px; line-height:60px; text-align:center; font-weight:bold; color:white; text-shadow:0 0 2px black; border: solid gray; border-radius: 50%; position: relative; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFoAAABaCAMAAAAPdrEwAAAAY1BMVEX///8AAACoqKjLy8sWFhZzc3Pu7u6srKwaGhrc3NyFhYXIyMivr68/Pz/8/PzQ0NDj4+NkZGS9vb319fUjIyNSUlK1tbVJSUmbm5sxMTF9fX05OTkICAjW1taVlZWOjo5bW1vxHZ4ZAAABZklEQVRYhe3ZyZKDIBAGYDZRcUFR4xKJef+njI6acZzEC50qp6b/C5y+orBRQEIw/ys2bpjJPgDLoQ1EUNYXcDnL6ZKhgJWLbpVpH6egtO2fNL1LULqhm1hQOt/S5nM0bJGoLa1Bab2RE9hlU3jfNIMtPhJWq9zB1t4Y67WCUpEM4PI4JxFTg69hZyPNNOdca26M1lPXAo28iL0qmVPXS3tXEAVoc0FfpG2cX4D6+gqeohxt+VamtHGj1XuZUqdVKcsjWrnQ0ZFMExc6PqRLlxnxD+kgPDHd+7edKZgHNGp92Q+XD0A03z/NIFJII4000kj/HVq40GYSyvA3zabm6rI1S6fRNen+6yv4dK4Wbiexwka2IGwheb7SREYmhNjFr7T0njRUkEYaaaSRRhpppJE+G738nQngaDOLpVyuc1q4O+x0vnK/EVl/dRyvPH/aXZ1U/riflmrsMEB5jAzl2gH+vYY5dx52WBgiF/12YwAAAABJRU5ErkJggg==) center no-repeat lightgray; ; background-size: contain; counter-increment: nbrli; } li:before { content: url(https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcQ0iwo85deSrLC-3AspbJVxT6NxMlfj5Q3bd3V7vGdwd60mlp0pwA); position: absolute; line-height: 70px; right: 70px } li:after { content: counter(nbrli); } , white, white) no-repeat bottom right, url (data: image / jpeg; base64, / 9j / 4AAQSkZJRgABAQEAYABgAAD / 2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz / 2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz / wAARCABBAAkDASIAAhEBAxEB / 8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL / 8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4 + Tl5ufo6erx8vP09fb3 + Pn6 / 8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL /  ul { padding: 0; margin: 0; display: flex; flex-wrap: wrap; justify-content: space-between; text-align: justify; background: linear-gradient(to top, white, white) no-repeat bottom right, url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCABBAAkDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKACiiigAoqD+1Lb/AJ+IP+/go/tS2/5+IP8Av4KAPzt/be8daxpPxZ8QXCXV1C9rM0FreQzKtzZX+NTktYVGzzNrraWoAWRVwWyknmZT69/4SG+/5+ZPzr5B/be8CaxrHxb8QW62t1K1zK81pZQwhrm+v8anHazKd/mYjW6tdpWNlwGJePy8P9ff8I9ff8+0n5U+gHrlFFFID//Z) repeat-y 30px 60px, url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCABBAAkDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKACiiigAoqD+1Lb/AJ+IP+/go/tS2/5+IP8Av4KAPzt/be8daxpPxZ8QXCXV1C9rM0FreQzKtzZX+NTktYVGzzNrraWoAWRVwWyknmZT69/4SG+/5+ZPzr5B/be8CaxrHxb8QW62t1K1zK81pZQwhrm+v8anHazKd/mYjW6tdpWNlwGJePy8P9ff8I9ff8+0n5U+gHrlFFFID//Z) repeat-y calc(100% - 60px) -40px white; background-size: 100px 100px, 9px 65px, 9px 65px; } li { font-size: 2rem; margin: 0 32px 32px 0; display: inline-block; width: 60px; height: 60px; line-height:60px; text-align:center; font-weight:bold; color:white; text-shadow:0 0 2px black; border: solid gray; border-radius: 50%; position: relative; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFoAAABaCAMAAAAPdrEwAAAAY1BMVEX///8AAACoqKjLy8sWFhZzc3Pu7u6srKwaGhrc3NyFhYXIyMivr68/Pz/8/PzQ0NDj4+NkZGS9vb319fUjIyNSUlK1tbVJSUmbm5sxMTF9fX05OTkICAjW1taVlZWOjo5bW1vxHZ4ZAAABZklEQVRYhe3ZyZKDIBAGYDZRcUFR4xKJef+njI6acZzEC50qp6b/C5y+orBRQEIw/ys2bpjJPgDLoQ1EUNYXcDnL6ZKhgJWLbpVpH6egtO2fNL1LULqhm1hQOt/S5nM0bJGoLa1Bab2RE9hlU3jfNIMtPhJWq9zB1t4Y67WCUpEM4PI4JxFTg69hZyPNNOdca26M1lPXAo28iL0qmVPXS3tXEAVoc0FfpG2cX4D6+gqeohxt+VamtHGj1XuZUqdVKcsjWrnQ0ZFMExc6PqRLlxnxD+kgPDHd+7edKZgHNGp92Q+XD0A03z/NIFJII4000kj/HVq40GYSyvA3zabm6rI1S6fRNen+6yv4dK4Wbiexwka2IGwheb7SREYmhNjFr7T0njRUkEYaaaSRRhpppJE+G738nQngaDOLpVyuc1q4O+x0vnK/EVl/dRyvPH/aXZ1U/riflmrsMEB5jAzl2gH+vYY5dx52WBgiF/12YwAAAABJRU5ErkJggg==) center no-repeat lightgray; ; background-size: contain; counter-increment: nbrli; } li:before { content: url(https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcQ0iwo85deSrLC-3AspbJVxT6NxMlfj5Q3bd3V7vGdwd60mlp0pwA); position: absolute; line-height: 70px; right: 70px } li:after { content: counter(nbrli); } 1Lb / AJ + IP + / go / tS2 /  ul { padding: 0; margin: 0; display: flex; flex-wrap: wrap; justify-content: space-between; text-align: justify; background: linear-gradient(to top, white, white) no-repeat bottom right, url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCABBAAkDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKACiiigAoqD+1Lb/AJ+IP+/go/tS2/5+IP8Av4KAPzt/be8daxpPxZ8QXCXV1C9rM0FreQzKtzZX+NTktYVGzzNrraWoAWRVwWyknmZT69/4SG+/5+ZPzr5B/be8CaxrHxb8QW62t1K1zK81pZQwhrm+v8anHazKd/mYjW6tdpWNlwGJePy8P9ff8I9ff8+0n5U+gHrlFFFID//Z) repeat-y 30px 60px, url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCABBAAkDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKACiiigAoqD+1Lb/AJ+IP+/go/tS2/5+IP8Av4KAPzt/be8daxpPxZ8QXCXV1C9rM0FreQzKtzZX+NTktYVGzzNrraWoAWRVwWyknmZT69/4SG+/5+ZPzr5B/be8CaxrHxb8QW62t1K1zK81pZQwhrm+v8anHazKd/mYjW6tdpWNlwGJePy8P9ff8I9ff8+0n5U+gHrlFFFID//Z) repeat-y calc(100% - 60px) -40px white; background-size: 100px 100px, 9px 65px, 9px 65px; } li { font-size: 2rem; margin: 0 32px 32px 0; display: inline-block; width: 60px; height: 60px; line-height:60px; text-align:center; font-weight:bold; color:white; text-shadow:0 0 2px black; border: solid gray; border-radius: 50%; position: relative; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFoAAABaCAMAAAAPdrEwAAAAY1BMVEX///8AAACoqKjLy8sWFhZzc3Pu7u6srKwaGhrc3NyFhYXIyMivr68/Pz/8/PzQ0NDj4+NkZGS9vb319fUjIyNSUlK1tbVJSUmbm5sxMTF9fX05OTkICAjW1taVlZWOjo5bW1vxHZ4ZAAABZklEQVRYhe3ZyZKDIBAGYDZRcUFR4xKJef+njI6acZzEC50qp6b/C5y+orBRQEIw/ys2bpjJPgDLoQ1EUNYXcDnL6ZKhgJWLbpVpH6egtO2fNL1LULqhm1hQOt/S5nM0bJGoLa1Bab2RE9hlU3jfNIMtPhJWq9zB1t4Y67WCUpEM4PI4JxFTg69hZyPNNOdca26M1lPXAo28iL0qmVPXS3tXEAVoc0FfpG2cX4D6+gqeohxt+VamtHGj1XuZUqdVKcsjWrnQ0ZFMExc6PqRLlxnxD+kgPDHd+7edKZgHNGp92Q+XD0A03z/NIFJII4000kj/HVq40GYSyvA3zabm6rI1S6fRNen+6yv4dK4Wbiexwka2IGwheb7SREYmhNjFr7T0njRUkEYaaaSRRhpppJE+G738nQngaDOLpVyuc1q4O+x0vnK/EVl/dRyvPH/aXZ1U/riflmrsMEB5jAzl2gH+vYY5dx52WBgiF/12YwAAAABJRU5ErkJggg==) center no-repeat lightgray; ; background-size: contain; counter-increment: nbrli; } li:before { content: url(https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcQ0iwo85deSrLC-3AspbJVxT6NxMlfj5Q3bd3V7vGdwd60mlp0pwA); position: absolute; line-height: 70px; right: 70px } li:after { content: counter(nbrli); } + 0n5U + gHrlFFFID // Z) repeat-y 30px 60px, url (data: image / jpeg; base64, / 9j / 4AAQSkZJRgABAQEAYABgAAD / 2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz / 2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz / wAARCABBAAkDASIAAhEBAxEB /  ul { padding: 0; margin: 0; display: flex; flex-wrap: wrap; justify-content: space-between; text-align: justify; background: linear-gradient(to top, white, white) no-repeat bottom right, url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCABBAAkDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKACiiigAoqD+1Lb/AJ+IP+/go/tS2/5+IP8Av4KAPzt/be8daxpPxZ8QXCXV1C9rM0FreQzKtzZX+NTktYVGzzNrraWoAWRVwWyknmZT69/4SG+/5+ZPzr5B/be8CaxrHxb8QW62t1K1zK81pZQwhrm+v8anHazKd/mYjW6tdpWNlwGJePy8P9ff8I9ff8+0n5U+gHrlFFFID//Z) repeat-y 30px 60px, url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCABBAAkDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKACiiigAoqD+1Lb/AJ+IP+/go/tS2/5+IP8Av4KAPzt/be8daxpPxZ8QXCXV1C9rM0FreQzKtzZX+NTktYVGzzNrraWoAWRVwWyknmZT69/4SG+/5+ZPzr5B/be8CaxrHxb8QW62t1K1zK81pZQwhrm+v8anHazKd/mYjW6tdpWNlwGJePy8P9ff8I9ff8+0n5U+gHrlFFFID//Z) repeat-y calc(100% - 60px) -40px white; background-size: 100px 100px, 9px 65px, 9px 65px; } li { font-size: 2rem; margin: 0 32px 32px 0; display: inline-block; width: 60px; height: 60px; line-height:60px; text-align:center; font-weight:bold; color:white; text-shadow:0 0 2px black; border: solid gray; border-radius: 50%; position: relative; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFoAAABaCAMAAAAPdrEwAAAAY1BMVEX///8AAACoqKjLy8sWFhZzc3Pu7u6srKwaGhrc3NyFhYXIyMivr68/Pz/8/PzQ0NDj4+NkZGS9vb319fUjIyNSUlK1tbVJSUmbm5sxMTF9fX05OTkICAjW1taVlZWOjo5bW1vxHZ4ZAAABZklEQVRYhe3ZyZKDIBAGYDZRcUFR4xKJef+njI6acZzEC50qp6b/C5y+orBRQEIw/ys2bpjJPgDLoQ1EUNYXcDnL6ZKhgJWLbpVpH6egtO2fNL1LULqhm1hQOt/S5nM0bJGoLa1Bab2RE9hlU3jfNIMtPhJWq9zB1t4Y67WCUpEM4PI4JxFTg69hZyPNNOdca26M1lPXAo28iL0qmVPXS3tXEAVoc0FfpG2cX4D6+gqeohxt+VamtHGj1XuZUqdVKcsjWrnQ0ZFMExc6PqRLlxnxD+kgPDHd+7edKZgHNGp92Q+XD0A03z/NIFJII4000kj/HVq40GYSyvA3zabm6rI1S6fRNen+6yv4dK4Wbiexwka2IGwheb7SREYmhNjFr7T0njRUkEYaaaSRRhpppJE+G738nQngaDOLpVyuc1q4O+x0vnK/EVl/dRyvPH/aXZ1U/riflmrsMEB5jAzl2gH+vYY5dx52WBgiF/12YwAAAABJRU5ErkJggg==) center no-repeat lightgray; ; background-size: contain; counter-increment: nbrli; } li:before { content: url(https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcQ0iwo85deSrLC-3AspbJVxT6NxMlfj5Q3bd3V7vGdwd60mlp0pwA); position: absolute; line-height: 70px; right: 70px } li:after { content: counter(nbrli); } 8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL / 8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09f  ul { padding: 0; margin: 0; display: flex; flex-wrap: wrap; justify-content: space-between; text-align: justify; background: linear-gradient(to top, white, white) no-repeat bottom right, url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCABBAAkDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKACiiigAoqD+1Lb/AJ+IP+/go/tS2/5+IP8Av4KAPzt/be8daxpPxZ8QXCXV1C9rM0FreQzKtzZX+NTktYVGzzNrraWoAWRVwWyknmZT69/4SG+/5+ZPzr5B/be8CaxrHxb8QW62t1K1zK81pZQwhrm+v8anHazKd/mYjW6tdpWNlwGJePy8P9ff8I9ff8+0n5U+gHrlFFFID//Z) repeat-y 30px 60px, url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCABBAAkDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKACiiigAoqD+1Lb/AJ+IP+/go/tS2/5+IP8Av4KAPzt/be8daxpPxZ8QXCXV1C9rM0FreQzKtzZX+NTktYVGzzNrraWoAWRVwWyknmZT69/4SG+/5+ZPzr5B/be8CaxrHxb8QW62t1K1zK81pZQwhrm+v8anHazKd/mYjW6tdpWNlwGJePy8P9ff8I9ff8+0n5U+gHrlFFFID//Z) repeat-y calc(100% - 60px) -40px white; background-size: 100px 100px, 9px 65px, 9px 65px; } li { font-size: 2rem; margin: 0 32px 32px 0; display: inline-block; width: 60px; height: 60px; line-height:60px; text-align:center; font-weight:bold; color:white; text-shadow:0 0 2px black; border: solid gray; border-radius: 50%; position: relative; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFoAAABaCAMAAAAPdrEwAAAAY1BMVEX///8AAACoqKjLy8sWFhZzc3Pu7u6srKwaGhrc3NyFhYXIyMivr68/Pz/8/PzQ0NDj4+NkZGS9vb319fUjIyNSUlK1tbVJSUmbm5sxMTF9fX05OTkICAjW1taVlZWOjo5bW1vxHZ4ZAAABZklEQVRYhe3ZyZKDIBAGYDZRcUFR4xKJef+njI6acZzEC50qp6b/C5y+orBRQEIw/ys2bpjJPgDLoQ1EUNYXcDnL6ZKhgJWLbpVpH6egtO2fNL1LULqhm1hQOt/S5nM0bJGoLa1Bab2RE9hlU3jfNIMtPhJWq9zB1t4Y67WCUpEM4PI4JxFTg69hZyPNNOdca26M1lPXAo28iL0qmVPXS3tXEAVoc0FfpG2cX4D6+gqeohxt+VamtHGj1XuZUqdVKcsjWrnQ0ZFMExc6PqRLlxnxD+kgPDHd+7edKZgHNGp92Q+XD0A03z/NIFJII4000kj/HVq40GYSyvA3zabm6rI1S6fRNen+6yv4dK4Wbiexwka2IGwheb7SREYmhNjFr7T0njRUkEYaaaSRRhpppJE+G738nQngaDOLpVyuc1q4O+x0vnK/EVl/dRyvPH/aXZ1U/riflmrsMEB5jAzl2gH+vYY5dx52WBgiF/12YwAAAABJRU5ErkJggg==) center no-repeat lightgray; ; background-size: contain; counter-increment: nbrli; } li:before { content: url(https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcQ0iwo85deSrLC-3AspbJVxT6NxMlfj5Q3bd3V7vGdwd60mlp0pwA); position: absolute; line-height: 70px; right: 70px } li:after { content: counter(nbrli); } 1Lb / AJ + IP + / go / tS2 /  ul { padding: 0; margin: 0; display: flex; flex-wrap: wrap; justify-content: space-between; text-align: justify; background: linear-gradient(to top, white, white) no-repeat bottom right, url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCABBAAkDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKACiiigAoqD+1Lb/AJ+IP+/go/tS2/5+IP8Av4KAPzt/be8daxpPxZ8QXCXV1C9rM0FreQzKtzZX+NTktYVGzzNrraWoAWRVwWyknmZT69/4SG+/5+ZPzr5B/be8CaxrHxb8QW62t1K1zK81pZQwhrm+v8anHazKd/mYjW6tdpWNlwGJePy8P9ff8I9ff8+0n5U+gHrlFFFID//Z) repeat-y 30px 60px, url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCABBAAkDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKACiiigAoqD+1Lb/AJ+IP+/go/tS2/5+IP8Av4KAPzt/be8daxpPxZ8QXCXV1C9rM0FreQzKtzZX+NTktYVGzzNrraWoAWRVwWyknmZT69/4SG+/5+ZPzr5B/be8CaxrHxb8QW62t1K1zK81pZQwhrm+v8anHazKd/mYjW6tdpWNlwGJePy8P9ff8I9ff8+0n5U+gHrlFFFID//Z) repeat-y calc(100% - 60px) -40px white; background-size: 100px 100px, 9px 65px, 9px 65px; } li { font-size: 2rem; margin: 0 32px 32px 0; display: inline-block; width: 60px; height: 60px; line-height:60px; text-align:center; font-weight:bold; color:white; text-shadow:0 0 2px black; border: solid gray; border-radius: 50%; position: relative; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFoAAABaCAMAAAAPdrEwAAAAY1BMVEX///8AAACoqKjLy8sWFhZzc3Pu7u6srKwaGhrc3NyFhYXIyMivr68/Pz/8/PzQ0NDj4+NkZGS9vb319fUjIyNSUlK1tbVJSUmbm5sxMTF9fX05OTkICAjW1taVlZWOjo5bW1vxHZ4ZAAABZklEQVRYhe3ZyZKDIBAGYDZRcUFR4xKJef+njI6acZzEC50qp6b/C5y+orBRQEIw/ys2bpjJPgDLoQ1EUNYXcDnL6ZKhgJWLbpVpH6egtO2fNL1LULqhm1hQOt/S5nM0bJGoLa1Bab2RE9hlU3jfNIMtPhJWq9zB1t4Y67WCUpEM4PI4JxFTg69hZyPNNOdca26M1lPXAo28iL0qmVPXS3tXEAVoc0FfpG2cX4D6+gqeohxt+VamtHGj1XuZUqdVKcsjWrnQ0ZFMExc6PqRLlxnxD+kgPDHd+7edKZgHNGp92Q+XD0A03z/NIFJII4000kj/HVq40GYSyvA3zabm6rI1S6fRNen+6yv4dK4Wbiexwka2IGwheb7SREYmhNjFr7T0njRUkEYaaaSRRhpppJE+G738nQngaDOLpVyuc1q4O+x0vnK/EVl/dRyvPH/aXZ1U/riflmrsMEB5jAzl2gH+vYY5dx52WBgiF/12YwAAAABJRU5ErkJggg==) center no-repeat lightgray; ; background-size: contain; counter-increment: nbrli; } li:before { content: url(https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcQ0iwo85deSrLC-3AspbJVxT6NxMlfj5Q3bd3V7vGdwd60mlp0pwA); position: absolute; line-height: 70px; right: 70px } li:after { content: counter(nbrli); } + /  ul { padding: 0; margin: 0; display: flex; flex-wrap: wrap; justify-content: space-between; text-align: justify; background: linear-gradient(to top, white, white) no-repeat bottom right, url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCABBAAkDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKACiiigAoqD+1Lb/AJ+IP+/go/tS2/5+IP8Av4KAPzt/be8daxpPxZ8QXCXV1C9rM0FreQzKtzZX+NTktYVGzzNrraWoAWRVwWyknmZT69/4SG+/5+ZPzr5B/be8CaxrHxb8QW62t1K1zK81pZQwhrm+v8anHazKd/mYjW6tdpWNlwGJePy8P9ff8I9ff8+0n5U+gHrlFFFID//Z) repeat-y 30px 60px, url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCABBAAkDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKACiiigAoqD+1Lb/AJ+IP+/go/tS2/5+IP8Av4KAPzt/be8daxpPxZ8QXCXV1C9rM0FreQzKtzZX+NTktYVGzzNrraWoAWRVwWyknmZT69/4SG+/5+ZPzr5B/be8CaxrHxb8QW62t1K1zK81pZQwhrm+v8anHazKd/mYjW6tdpWNlwGJePy8P9ff8I9ff8+0n5U+gHrlFFFID//Z) repeat-y calc(100% - 60px) -40px white; background-size: 100px 100px, 9px 65px, 9px 65px; } li { font-size: 2rem; margin: 0 32px 32px 0; display: inline-block; width: 60px; height: 60px; line-height:60px; text-align:center; font-weight:bold; color:white; text-shadow:0 0 2px black; border: solid gray; border-radius: 50%; position: relative; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFoAAABaCAMAAAAPdrEwAAAAY1BMVEX///8AAACoqKjLy8sWFhZzc3Pu7u6srKwaGhrc3NyFhYXIyMivr68/Pz/8/PzQ0NDj4+NkZGS9vb319fUjIyNSUlK1tbVJSUmbm5sxMTF9fX05OTkICAjW1taVlZWOjo5bW1vxHZ4ZAAABZklEQVRYhe3ZyZKDIBAGYDZRcUFR4xKJef+njI6acZzEC50qp6b/C5y+orBRQEIw/ys2bpjJPgDLoQ1EUNYXcDnL6ZKhgJWLbpVpH6egtO2fNL1LULqhm1hQOt/S5nM0bJGoLa1Bab2RE9hlU3jfNIMtPhJWq9zB1t4Y67WCUpEM4PI4JxFTg69hZyPNNOdca26M1lPXAo28iL0qmVPXS3tXEAVoc0FfpG2cX4D6+gqeohxt+VamtHGj1XuZUqdVKcsjWrnQ0ZFMExc6PqRLlxnxD+kgPDHd+7edKZgHNGp92Q+XD0A03z/NIFJII4000kj/HVq40GYSyvA3zabm6rI1S6fRNen+6yv4dK4Wbiexwka2IGwheb7SREYmhNjFr7T0njRUkEYaaaSRRhpppJE+G738nQngaDOLpVyuc1q4O+x0vnK/EVl/dRyvPH/aXZ1U/riflmrsMEB5jAzl2gH+vYY5dx52WBgiF/12YwAAAABJRU5ErkJggg==) center no-repeat lightgray; ; background-size: contain; counter-increment: nbrli; } li:before { content: url(https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcQ0iwo85deSrLC-3AspbJVxT6NxMlfj5Q3bd3V7vGdwd60mlp0pwA); position: absolute; line-height: 70px; right: 70px } li:after { content: counter(nbrli); } + 0n5U + gHrlFFFID // Z) repeat-y calc (  ul { padding: 0; margin: 0; display: flex; flex-wrap: wrap; justify-content: space-between; text-align: justify; background: linear-gradient(to top, white, white) no-repeat bottom right, url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCABBAAkDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKACiiigAoqD+1Lb/AJ+IP+/go/tS2/5+IP8Av4KAPzt/be8daxpPxZ8QXCXV1C9rM0FreQzKtzZX+NTktYVGzzNrraWoAWRVwWyknmZT69/4SG+/5+ZPzr5B/be8CaxrHxb8QW62t1K1zK81pZQwhrm+v8anHazKd/mYjW6tdpWNlwGJePy8P9ff8I9ff8+0n5U+gHrlFFFID//Z) repeat-y 30px 60px, url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCABBAAkDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKACiiigAoqD+1Lb/AJ+IP+/go/tS2/5+IP8Av4KAPzt/be8daxpPxZ8QXCXV1C9rM0FreQzKtzZX+NTktYVGzzNrraWoAWRVwWyknmZT69/4SG+/5+ZPzr5B/be8CaxrHxb8QW62t1K1zK81pZQwhrm+v8anHazKd/mYjW6tdpWNlwGJePy8P9ff8I9ff8+0n5U+gHrlFFFID//Z) repeat-y calc(100% - 60px) -40px white; background-size: 100px 100px, 9px 65px, 9px 65px; } li { font-size: 2rem; margin: 0 32px 32px 0; display: inline-block; width: 60px; height: 60px; line-height:60px; text-align:center; font-weight:bold; color:white; text-shadow:0 0 2px black; border: solid gray; border-radius: 50%; position: relative; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFoAAABaCAMAAAAPdrEwAAAAY1BMVEX///8AAACoqKjLy8sWFhZzc3Pu7u6srKwaGhrc3NyFhYXIyMivr68/Pz/8/PzQ0NDj4+NkZGS9vb319fUjIyNSUlK1tbVJSUmbm5sxMTF9fX05OTkICAjW1taVlZWOjo5bW1vxHZ4ZAAABZklEQVRYhe3ZyZKDIBAGYDZRcUFR4xKJef+njI6acZzEC50qp6b/C5y+orBRQEIw/ys2bpjJPgDLoQ1EUNYXcDnL6ZKhgJWLbpVpH6egtO2fNL1LULqhm1hQOt/S5nM0bJGoLa1Bab2RE9hlU3jfNIMtPhJWq9zB1t4Y67WCUpEM4PI4JxFTg69hZyPNNOdca26M1lPXAo28iL0qmVPXS3tXEAVoc0FfpG2cX4D6+gqeohxt+VamtHGj1XuZUqdVKcsjWrnQ0ZFMExc6PqRLlxnxD+kgPDHd+7edKZgHNGp92Q+XD0A03z/NIFJII4000kj/HVq40GYSyvA3zabm6rI1S6fRNen+6yv4dK4Wbiexwka2IGwheb7SREYmhNjFr7T0njRUkEYaaaSRRhpppJE+G738nQngaDOLpVyuc1q4O+x0vnK/EVl/dRyvPH/aXZ1U/riflmrsMEB5jAzl2gH+vYY5dx52WBgiF/12YwAAAABJRU5ErkJggg==) center no-repeat lightgray; ; background-size: contain; counter-increment: nbrli; } li:before { content: url(https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcQ0iwo85deSrLC-3AspbJVxT6NxMlfj5Q3bd3V7vGdwd60mlp0pwA); position: absolute; line-height: 70px; right: 70px } li:after { content: counter(nbrli); } png; base64, iVBORw0KGgoAAAANSUhEUgAAAFoAAABaCAMAAAAPdrEwAAAAY1BMVEX /// 8AAACoqKjLy8sWFhZzc3Pu7u6srKwaGhrc3NyFhYXIyMivr68 / Pz /  ul { padding: 0; margin: 0; display: flex; flex-wrap: wrap; justify-content: space-between; text-align: justify; background: linear-gradient(to top, white, white) no-repeat bottom right, url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCABBAAkDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKACiiigAoqD+1Lb/AJ+IP+/go/tS2/5+IP8Av4KAPzt/be8daxpPxZ8QXCXV1C9rM0FreQzKtzZX+NTktYVGzzNrraWoAWRVwWyknmZT69/4SG+/5+ZPzr5B/be8CaxrHxb8QW62t1K1zK81pZQwhrm+v8anHazKd/mYjW6tdpWNlwGJePy8P9ff8I9ff8+0n5U+gHrlFFFID//Z) repeat-y 30px 60px, url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCABBAAkDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKACiiigAoqD+1Lb/AJ+IP+/go/tS2/5+IP8Av4KAPzt/be8daxpPxZ8QXCXV1C9rM0FreQzKtzZX+NTktYVGzzNrraWoAWRVwWyknmZT69/4SG+/5+ZPzr5B/be8CaxrHxb8QW62t1K1zK81pZQwhrm+v8anHazKd/mYjW6tdpWNlwGJePy8P9ff8I9ff8+0n5U+gHrlFFFID//Z) repeat-y calc(100% - 60px) -40px white; background-size: 100px 100px, 9px 65px, 9px 65px; } li { font-size: 2rem; margin: 0 32px 32px 0; display: inline-block; width: 60px; height: 60px; line-height:60px; text-align:center; font-weight:bold; color:white; text-shadow:0 0 2px black; border: solid gray; border-radius: 50%; position: relative; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFoAAABaCAMAAAAPdrEwAAAAY1BMVEX///8AAACoqKjLy8sWFhZzc3Pu7u6srKwaGhrc3NyFhYXIyMivr68/Pz/8/PzQ0NDj4+NkZGS9vb319fUjIyNSUlK1tbVJSUmbm5sxMTF9fX05OTkICAjW1taVlZWOjo5bW1vxHZ4ZAAABZklEQVRYhe3ZyZKDIBAGYDZRcUFR4xKJef+njI6acZzEC50qp6b/C5y+orBRQEIw/ys2bpjJPgDLoQ1EUNYXcDnL6ZKhgJWLbpVpH6egtO2fNL1LULqhm1hQOt/S5nM0bJGoLa1Bab2RE9hlU3jfNIMtPhJWq9zB1t4Y67WCUpEM4PI4JxFTg69hZyPNNOdca26M1lPXAo28iL0qmVPXS3tXEAVoc0FfpG2cX4D6+gqeohxt+VamtHGj1XuZUqdVKcsjWrnQ0ZFMExc6PqRLlxnxD+kgPDHd+7edKZgHNGp92Q+XD0A03z/NIFJII4000kj/HVq40GYSyvA3zabm6rI1S6fRNen+6yv4dK4Wbiexwka2IGwheb7SREYmhNjFr7T0njRUkEYaaaSRRhpppJE+G738nQngaDOLpVyuc1q4O+x0vnK/EVl/dRyvPH/aXZ1U/riflmrsMEB5jAzl2gH+vYY5dx52WBgiF/12YwAAAABJRU5ErkJggg==) center no-repeat lightgray; ; background-size: contain; counter-increment: nbrli; } li:before { content: url(https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcQ0iwo85deSrLC-3AspbJVxT6NxMlfj5Q3bd3V7vGdwd60mlp0pwA); position: absolute; line-height: 70px; right: 70px } li:after { content: counter(nbrli); } + orBRQEIw / ys2bpjJPgDLoQ1EUNYXcDnL6ZKhgJWLbpVpH6egtO2fNL1LULqhm1hQOt / S5nM0bJGoLa1Bab2RE9hlU3jfNIMtPhJWq9zB1t4Y67WCUpEM4PI4JxFTg69hZyPNNOdca26M1lPXAo28iL0qmVPXS3tXEAVoc0FfpG2cX4D6 + gqeohxt + VamtHGj1XuZUqdVKcsjWrnQ0ZFMExc6PqRLlxnxD + kgPDHd + 7edKZgHNGp92Q + XD0A03z / NIFJII4000kj / HVq40GYSyvA3zabm6rI1S6fRNen +  ul { padding: 0; margin: 0; display: flex; flex-wrap: wrap; justify-content: space-between; text-align: justify; background: linear-gradient(to top, white, white) no-repeat bottom right, url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCABBAAkDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKACiiigAoqD+1Lb/AJ+IP+/go/tS2/5+IP8Av4KAPzt/be8daxpPxZ8QXCXV1C9rM0FreQzKtzZX+NTktYVGzzNrraWoAWRVwWyknmZT69/4SG+/5+ZPzr5B/be8CaxrHxb8QW62t1K1zK81pZQwhrm+v8anHazKd/mYjW6tdpWNlwGJePy8P9ff8I9ff8+0n5U+gHrlFFFID//Z) repeat-y 30px 60px, url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCABBAAkDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKACiiigAoqD+1Lb/AJ+IP+/go/tS2/5+IP8Av4KAPzt/be8daxpPxZ8QXCXV1C9rM0FreQzKtzZX+NTktYVGzzNrraWoAWRVwWyknmZT69/4SG+/5+ZPzr5B/be8CaxrHxb8QW62t1K1zK81pZQwhrm+v8anHazKd/mYjW6tdpWNlwGJePy8P9ff8I9ff8+0n5U+gHrlFFFID//Z) repeat-y calc(100% - 60px) -40px white; background-size: 100px 100px, 9px 65px, 9px 65px; } li { font-size: 2rem; margin: 0 32px 32px 0; display: inline-block; width: 60px; height: 60px; line-height:60px; text-align:center; font-weight:bold; color:white; text-shadow:0 0 2px black; border: solid gray; border-radius: 50%; position: relative; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFoAAABaCAMAAAAPdrEwAAAAY1BMVEX///8AAACoqKjLy8sWFhZzc3Pu7u6srKwaGhrc3NyFhYXIyMivr68/Pz/8/PzQ0NDj4+NkZGS9vb319fUjIyNSUlK1tbVJSUmbm5sxMTF9fX05OTkICAjW1taVlZWOjo5bW1vxHZ4ZAAABZklEQVRYhe3ZyZKDIBAGYDZRcUFR4xKJef+njI6acZzEC50qp6b/C5y+orBRQEIw/ys2bpjJPgDLoQ1EUNYXcDnL6ZKhgJWLbpVpH6egtO2fNL1LULqhm1hQOt/S5nM0bJGoLa1Bab2RE9hlU3jfNIMtPhJWq9zB1t4Y67WCUpEM4PI4JxFTg69hZyPNNOdca26M1lPXAo28iL0qmVPXS3tXEAVoc0FfpG2cX4D6+gqeohxt+VamtHGj1XuZUqdVKcsjWrnQ0ZFMExc6PqRLlxnxD+kgPDHd+7edKZgHNGp92Q+XD0A03z/NIFJII4000kj/HVq40GYSyvA3zabm6rI1S6fRNen+6yv4dK4Wbiexwka2IGwheb7SREYmhNjFr7T0njRUkEYaaaSRRhpppJE+G738nQngaDOLpVyuc1q4O+x0vnK/EVl/dRyvPH/aXZ1U/riflmrsMEB5jAzl2gH+vYY5dx52WBgiF/12YwAAAABJRU5ErkJggg==) center no-repeat lightgray; ; background-size: contain; counter-increment: nbrli; } li:before { content: url(https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcQ0iwo85deSrLC-3AspbJVxT6NxMlfj5Q3bd3V7vGdwd60mlp0pwA); position: absolute; line-height: 70px; right: 70px } li:after { content: counter(nbrli); } dRyvPH / aXZ1U / riflmrsMEB5jAzl2gH + vYY5dx52WBgiF / 12YwAAAABJRU5ErkJggg ==) center no-repeat lightgray;  ul { padding: 0; margin: 0; display: flex; flex-wrap: wrap; justify-content: space-between; text-align: justify; background: linear-gradient(to top, white, white) no-repeat bottom right, url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCABBAAkDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKACiiigAoqD+1Lb/AJ+IP+/go/tS2/5+IP8Av4KAPzt/be8daxpPxZ8QXCXV1C9rM0FreQzKtzZX+NTktYVGzzNrraWoAWRVwWyknmZT69/4SG+/5+ZPzr5B/be8CaxrHxb8QW62t1K1zK81pZQwhrm+v8anHazKd/mYjW6tdpWNlwGJePy8P9ff8I9ff8+0n5U+gHrlFFFID//Z) repeat-y 30px 60px, url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCABBAAkDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKACiiigAoqD+1Lb/AJ+IP+/go/tS2/5+IP8Av4KAPzt/be8daxpPxZ8QXCXV1C9rM0FreQzKtzZX+NTktYVGzzNrraWoAWRVwWyknmZT69/4SG+/5+ZPzr5B/be8CaxrHxb8QW62t1K1zK81pZQwhrm+v8anHazKd/mYjW6tdpWNlwGJePy8P9ff8I9ff8+0n5U+gHrlFFFID//Z) repeat-y calc(100% - 60px) -40px white; background-size: 100px 100px, 9px 65px, 9px 65px; } li { font-size: 2rem; margin: 0 32px 32px 0; display: inline-block; width: 60px; height: 60px; line-height:60px; text-align:center; font-weight:bold; color:white; text-shadow:0 0 2px black; border: solid gray; border-radius: 50%; position: relative; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFoAAABaCAMAAAAPdrEwAAAAY1BMVEX///8AAACoqKjLy8sWFhZzc3Pu7u6srKwaGhrc3NyFhYXIyMivr68/Pz/8/PzQ0NDj4+NkZGS9vb319fUjIyNSUlK1tbVJSUmbm5sxMTF9fX05OTkICAjW1taVlZWOjo5bW1vxHZ4ZAAABZklEQVRYhe3ZyZKDIBAGYDZRcUFR4xKJef+njI6acZzEC50qp6b/C5y+orBRQEIw/ys2bpjJPgDLoQ1EUNYXcDnL6ZKhgJWLbpVpH6egtO2fNL1LULqhm1hQOt/S5nM0bJGoLa1Bab2RE9hlU3jfNIMtPhJWq9zB1t4Y67WCUpEM4PI4JxFTg69hZyPNNOdca26M1lPXAo28iL0qmVPXS3tXEAVoc0FfpG2cX4D6+gqeohxt+VamtHGj1XuZUqdVKcsjWrnQ0ZFMExc6PqRLlxnxD+kgPDHd+7edKZgHNGp92Q+XD0A03z/NIFJII4000kj/HVq40GYSyvA3zabm6rI1S6fRNen+6yv4dK4Wbiexwka2IGwheb7SREYmhNjFr7T0njRUkEYaaaSRRhpppJE+G738nQngaDOLpVyuc1q4O+x0vnK/EVl/dRyvPH/aXZ1U/riflmrsMEB5jAzl2gH+vYY5dx52WBgiF/12YwAAAABJRU5ErkJggg==) center no-repeat lightgray; ; background-size: contain; counter-increment: nbrli; } li:before { content: url(https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcQ0iwo85deSrLC-3AspbJVxT6NxMlfj5Q3bd3V7vGdwd60mlp0pwA); position: absolute; line-height: 70px; right: 70px } li:after { content: counter(nbrli); } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <ul id="chain"> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> 
Run codeHide result
+1
source

Being an intrigued call, I propose the following approach, which works with one or two caveats:

  • All elements that should be "encoded" are present in one parent element, and
  • Link chains are not in HTML.

The following JavaScript code was written using ES2015, without any attempt to circumvent it for browsers that do not implement functions (current, at the time of writing).

However, given the following HTML:

 <ul> <li class="user"></li> <li class="user"></li> <li class="user"></li> <!-- ...as many as you like... --> <li class="user"></li> </ul> 

The following JavaScript seems to work:

 // opts: Object, containing // customisations to alter // the default settings: function chaining(opts) { // chainSelector: String, // the CSS selector passed to // document.querySelectorAll() // to select the relevant // elements. // firstInRowClass: String, // the class-name to add to the // first element in each row to // identify it as such. // lastInRowClose: String, // As above, but to identify the // last element in each row. // rowStartIndex: Number or String, // identifying the starting row- // number. It can be either a // Number or a numeric String // (1, 2, 3... or '1', '2', '3'...) let settings = { 'chainSelector': '.user', 'firstInRowClass': 'first', 'lastInRowClass': 'last', 'rowStartIndex': 0 }; // if we have an opts Object passed we iterate over // the array of keys of that Object, using // Array.prototype.forEach() to update the same // property of the settings Object in order for // user-supplied values to override the defaults: if (opts) { Object.keys(opts).forEach(function(keyname) { settings[keyname] = opts[keyname]; }); } // to save typing we assign the settings Object to // the 's' variable: let s = settings, // here we use Array.from() to convert the collection // returned by document.querySelectorAll(), into an // Array; here document.querySelectorAll() uses the // selector held in the s.chainSelector property to // select the relevant elements: elements = Array.from( document.querySelectorAll( s.chainSelector ) ), // here we initialise the variable to 0, we determine a // new 'row' each time the offsetTop of the found-elements // is greater than the currentOffsetTop (and when it // increases we update the variable to the new value): currentOffsetTop = 0, // here we use parseInt(), along with its radix, to // ensure the starting index is a valid number, if // not we use 0; and we use that to count the rows // starting at the given starting index: rowCount = parseInt( s.rowStartIndex, 10 ) || 0, // we initialise the rowClass to 'odd' in order that // we can select both 'odd' and 'even' rows, should it // be necessary: rowClass = 'odd'; // here we iterate over each of the found-elements, // again using Array.prototype.forEach(), in order // to remove the empty 'padding' elements (inserted // later, under some circumstances): elements.forEach(function(elem){ // if the classList (an Array-like collection of // each of the class-names of an element) contains // the class-name of 'padding': if (elem.classList.contains('padding')) { // we move to the element parentNode and // remove that child: elem.parentNode.removeChild(elem); } }); // again, using Array.prototype.forEach(), along with // an Arrow function syntax; here elem is the current // element of the array over which we're iterating; the // contents of the '{...}' block are a collection of // actions taken to strip out all the class-names that // this function adds to elements in order to identify // them: elements.forEach(elem => { // here we have to use regular expressions in order to // remove the string-literal of 'row' followed by one, // or more, numbers (\d), if the string is surrounded // by word-boundaries (\b); if the string is found we // replace it with an empty, zero-length, String: elem.className = elem.className.replace( /\brow\d+\b/, ''); // in the following lines we remove specific, known (or // identifiable) class-names: elem.classList.remove( s.firstInRowClass ); elem.classList.remove( s.lastInRowClass ); elem.classList.remove( 'odd' ); elem.classList.remove( 'even' ); elem.classList.remove( 'lastRow' ); }); // again, using Array.prototype.forEach(): elements.forEach(function(elem){ // if the currentOffsetTop variable, initialised // to 0, is less than the offsetTop of the current // element: if (currentOffsetTop < elem.offsetTop) { // we update the currentOffsetTop variable to // that of the current element: currentOffsetTop = elem.offsetTop; // and because of the difference between the // currentOffsetTop variable and the offsetTop // of the current element we can surmise we've // started a new row. Therefore we add the // class-name held in the 's.firstInRowClass' // variable: elem.classList.add( s.firstInRowClass ) // if the current element, the first in a new row, // has a previousElementSibling then that previous // sibling must be the last element in its row: if (elem.previousElementSibling) { // therefore we add the class-name to that // element to identify it as such: elem.previousElementSibling.classList.add( s.lastInRowClass ); // we increment the rowCount variable because we're in // a new row: rowCount++; // here we check that the previousElementSibling contains // the class-name of 'odd'; if it does we change the // rowClass (initialised earlier to 'odd') to 'even'. // If it does not contain the class-name of 'odd' we // set the rowClass to be 'odd': rowClass = elem.previousElementSibling.classList.contains( 'odd' ) ? 'even' : 'odd'; } } // here we add the row-number class, 'row0', 'row1', etc... elem.classList.add( 'row' + rowCount ) // here we add the 'odd' or 'even' class-name: elem.classList.add( rowClass ); }); // creating a CSS selector to select those elements in the // last row (from the string '.row' and the current 'rowCount' // variable: let lastRowSelector = '.row' + rowCount, // here we pass that selector to document.querySelectorAll() // to select the elements of the last row, and then use // Array.from() to convert that collection into an Array: lastRow = Array.from( document.querySelectorAll( lastRowSelector ) ); // iterating over the elements of the last-row to add the // 'lastRow' class-name: lastRow.forEach( elem => elem.classList.add('lastRow')); // finding the last element in the last-row: let lastElement = elements[ elements.length - 1 ]; // because there no new row following the last element // the method I used to set the class of the last-in-row // elements doesn't work; so here we explicitly set it: lastElement.classList.add( s.lastInRowClass ); // rowCount is greater than the starting index (so there // is more than one row), and the first-element of the // last-row contains the class of 'even': if ( rowCount > s.rowStartIndex && lastRow[0].classList.contains('even')) { // we get the elements of the penultimate row, by forming a // CSS selector of the string '.row' + rowCount - 1; so if // the last-row has the class of 'row4' (when rowCount = 4), // this would create the selector of '.row3'. // This selector is used by document.querySelectorAll() to // return a collection of elements, which is passed to // Array.from() to create an Array from that collection: let penultimateRow = Array.from( document.querySelectorAll( '.row' + ( rowCount - 1) ) ), // this retrieves the difference in the number of elements // in the penultimate row and the number in the last-row: rowDelta = penultimateRow.length - lastRow.length, // creating a reference to the first element in the last-row: firstInLastRow = lastRow[0], // initialising an empty variable for later use: clone; // while rowDelta is not zero (and then decremented for // the next iteration of the while loop): while (rowDelta--) { // we clone the the firstInLastRow element: clone = firstInLastRow.cloneNode(); // here we make a naive assumption that the only // classes held in the element (before manipulation by // this script) will be those used in the CSS selector // passed to the function (or held in the defaults). // Here we set the class-name property of the // cloned element, to the selector we used to select // the chaining elements after replacing the periods (\.) // in that selector with spaces and trimming trailing and // leading white-space (this part bugs me; I should have // found a better means to set the class-names to their // 'pre-interfered-with state.): clone.className = s.chainSelector.replace(/\./g,' ').trim(); // we add the class-name of 'padding' (which we use at the // beginning of the script to remove the padding elements): clone.classList.add( 'padding' ); // here we move from the firstInLastRow node to its parent, // and then insert the newly-created clone before the // firstInLastRow node (this is to line up the chain // hanging down from the previous row with the top of the // last-element in the last-row): firstInLastRow.parentNode.insertBefore( clone, firstInLastRow ); } } } // calling the function: chaining(); // binding the function to the resize event of the window; allowing the // elements to be 're-chained': window.addEventListener('resize', chaining); 

The following CSS is also used:

 ul, li { /* to remove default list-styling from the <ul> and <li> elements: */ list-style-type: none; } li.user { /* aesthetics, adjust to your own taste: */ width: 3em; height: 3em; line-height: 3em; display: inline-block; margin: 0 0 1em 1em; border: 2px solid #000; box-sizing: border-box; border-radius: 50%; /* to allow the pseudo-elements to be positioned relative to the <li> elements: */ position: relative; } /* this, and the following rule, are both to demonstrate the 'successful' matching; obviously style to your own taste: */ li.first { border-color: red; } li.last { border-color: limegreen; } /* setting the common styles for the pseudo-elements, both the ::before and ::after: */ li::before, li::after { /* Obviously use whatever image you feel appropriate to depict the 'chain' links: */ content: url(https://i.stack.imgur.com/lPrR5.png); position: absolute; width: 24px; height: 24px; /* hiding these pseudo-elements by default: */ display: none; } /* showing the chains 'after' the <li> elements in the '.odd' rows: */ li.odd::after { /* showing the ::after pseudo-elements: */ display: block; /* this is a lot more hit-and-miss than I'd like; fine-tune to your own desires: */ top: calc(50% - 20px); left: 100%; } /* styling the 'drop-down' chain links: */ li.odd.last::after, li.even.first::before { /* rotating the pseudo-element through 90 degrees; to give a vertical chain (the actual rotation depends on the chosen image, though): */ transform: rotate(90deg); /* rotating the pseudo-element through its centre point: */ transform-origin: 50% 50%; top: 100%; left: calc(50% - 10px); } /* on the '.even' rows we use the ::before pseudo-elements: */ li.even::before { display: block; top: calc(50% - 20px); right: 100%; } /* hiding the drop-down chains on the first, and last, elements in the .lastRow (to prevent unnecessary dangling chains): */ li.lastRow.first::before, li.lastRow.last::after { display: none; } /* styling the padding elements; obviously you should probably hide them entirely (using opacity: 0; or visibility: hidden) but they're visible here to show that they exist and the purpose they serve: */ li.user.padding { opacity: 0.2; } 

 function chaining(opts) { let settings = { 'chainSelector': '.user', 'firstInRowClass': 'first', 'lastInRowClass': 'last', 'rowStartIndex': 0 }; if (opts) { Object.keys(opts).forEach(function(keyname) { settings[keyname] = opts[keyname]; }); } let s = settings, elements = Array.from(document.querySelectorAll(s.chainSelector)), currentOffsetTop = 0, rowCount = parseInt(s.rowStartIndex, 10) || 0, rowClass = 'odd'; elements.forEach(function(elem) { if (elem.classList.contains('padding')) { elem.parentNode.removeChild(elem); } }); elements.forEach(elem => { elem.className = elem.className.replace(/\brow\d+\b/, ''); elem.classList.remove(s.firstInRowClass); elem.classList.remove(s.lastInRowClass); elem.classList.remove('odd'); elem.classList.remove('even'); elem.classList.remove('lastRow'); }); elements.forEach(function(elem) { if (currentOffsetTop < elem.offsetTop) { currentOffsetTop = elem.offsetTop; elem.classList.add(s.firstInRowClass) if (elem.previousElementSibling) { elem.previousElementSibling.classList.add(s.lastInRowClass); rowCount++; rowClass = elem.previousElementSibling.classList.contains('odd') ? 'even' : 'odd'; } } elem.classList.add('row' + rowCount) elem.classList.add(rowClass); }); let lastRowSelector = '.row' + rowCount, lastRow = Array.from(document.querySelectorAll(lastRowSelector)); lastRow.forEach(elem => elem.classList.add('lastRow')); let lastElement = elements[elements.length - 1]; lastElement.classList.add(s.lastInRowClass); if (rowCount > s.rowStartIndex && lastRow[0].classList.contains('even')) { let penultimateRow = Array.from(document.querySelectorAll('.row' + (rowCount - 1))), rowDelta = penultimateRow.length - lastRow.length, firstInLastRow = lastRow[0], clone; while (rowDelta--) { clone = firstInLastRow.cloneNode(); clone.className = s.chainSelector.replace(/\./g, ' ').trim(); clone.classList.add('padding'); firstInLastRow.parentNode.insertBefore(clone, firstInLastRow); } } } chaining(); window.addEventListener('resize', chaining); 
 ul, li { list-style-type: none; } li.user { width: 3em; height: 3em; line-height: 3em; position: relative; display: inline-block; margin: 0 0 1em 1em; border: 2px solid #000; box-sizing: border-box; border-radius: 50%; } li.first { border-color: red; } li.last { border-color: limegreen; } li::before, li::after { content: url(https://i.stack.imgur.com/lPrR5.png); position: absolute; width: 24px; height: 24px; display: none; } li.odd::after { display: block; top: calc(50% - 20px); left: 100%; } li.odd.last::after, li.even.first::before { transform: rotate(90deg); transform-origin: 50% 50%; top: 100%; left: calc(50% - 10px); } li.even::before { display: block; top: calc(50% - 20px); right: 100%; } li.lastRow.first::before, li.lastRow.last::after { display: none; } li.user.padding { opacity: 0.2; } 
 <ul> <li class="user"></li> <li class="user"></li> <li class="user"></li> <li class="user"></li> <li class="user"></li> <li class="user"></li> <li class="user"></li> <li class="user"></li> <li class="user"></li> <li class="user"></li> </ul> 
Run codeHide result

JS Fiddle demo .

Edited: to solve a previously identified problem of alignment of elements; since using display: inline-block collapses the white space between the <li> elements into one space, while adding elements to the DOM does not insert any space. This, of course, affects the distance between the elements and the alignment of these elements with previous lines.

So the following line:

 firstInLastRow.parentNode.insertBefore( document.createTextNode(' '), firstInLastRow); 

Fixes the problem by inserting the text of a white space node after each cloned element <li>.

 function chaining(opts) { let settings = { 'chainSelector': '.user', 'firstInRowClass': 'first', 'lastInRowClass': 'last', 'rowStartIndex': 0 }; if (opts) { Object.keys(opts).forEach(function(keyname) { settings[keyname] = opts[keyname]; }); } let s = settings, elements = Array.from(document.querySelectorAll(s.chainSelector)), currentOffsetTop = 0, rowCount = parseInt(s.rowStartIndex, 10) || 0, rowClass = 'odd'; elements.forEach(function(elem) { if (elem.classList.contains('padding')) { elem.parentNode.removeChild(elem); } }); elements.forEach(elem => { elem.className = elem.className.replace(/\brow\d+\b/, ''); elem.classList.remove(s.firstInRowClass); elem.classList.remove(s.lastInRowClass); elem.classList.remove('odd'); elem.classList.remove('even'); elem.classList.remove('lastRow'); }); elements.forEach(function(elem) { if (currentOffsetTop < elem.offsetTop) { currentOffsetTop = elem.offsetTop; elem.classList.add(s.firstInRowClass) if (elem.previousElementSibling) { elem.previousElementSibling.classList.add(s.lastInRowClass); rowCount++; rowClass = elem.previousElementSibling.classList.contains('odd') ? 'even' : 'odd'; } } elem.classList.add('row' + rowCount) elem.classList.add(rowClass); }); let lastRowSelector = '.row' + rowCount, lastRow = Array.from(document.querySelectorAll(lastRowSelector)); lastRow.forEach(elem => elem.classList.add('lastRow')); let lastElement = elements[elements.length - 1]; lastElement.classList.add(s.lastInRowClass); if (rowCount > s.rowStartIndex && lastRow[0].classList.contains('even')) { let penultimateRow = Array.from(document.querySelectorAll('.row' + (rowCount - 1))), rowDelta = penultimateRow.length - lastRow.length, firstInLastRow = lastRow[0], clone; while (rowDelta--) { clone = firstInLastRow.cloneNode(); clone.className = s.chainSelector.replace(/\./g, ' ').trim(); clone.classList.add('padding'); firstInLastRow.parentNode.insertBefore(clone, firstInLastRow); // new line added here to insert the one-space textNode: firstInLastRow.parentNode.insertBefore( document.createTextNode(' '), firstInLastRow); } } } chaining(); window.addEventListener('resize', chaining); 
 ul, li { list-style-type: none; } li.user { width: 3em; height: 3em; line-height: 3em; position: relative; display: inline-block; margin: 0 0 1em 1em; border: 2px solid #000; box-sizing: border-box; border-radius: 50%; } li.first { border-color: red; } li.last { border-color: limegreen; } li::before, li::after { content: url(https://i.stack.imgur.com/lPrR5.png); position: absolute; width: 24px; height: 24px; display: none; } li.odd::after { display: block; top: calc(50% - 20px); left: 100%; } li.odd.last::after, li.even.first::before { transform: rotate(90deg); transform-origin: 50% 50%; top: 100%; left: calc(50% - 10px); } li.even::before { display: block; top: calc(50% - 20px); right: 100%; } li.lastRow.first::before, li.lastRow.last::after { display: none; } li.user.padding { opacity: 0.2; } 
 <ul> <li class="user"></li> <li class="user"></li> <li class="user"></li> <li class="user"></li> <li class="user"></li> <li class="user"></li> <li class="user"></li> <li class="user"></li> <li class="user"></li> <li class="user"></li> </ul> 
Run codeHide result

JS Fiddle demo .

Or we can style elements li.userwith float: leftinstead display: inline-blockto represent them in a string; which ignores white space (but still respects the property of the marginelements.

 function chaining(opts) { let settings = { 'chainSelector': '.user', 'firstInRowClass': 'first', 'lastInRowClass': 'last', 'rowStartIndex': 0 }; if (opts) { Object.keys(opts).forEach(function(keyname) { settings[keyname] = opts[keyname]; }); } let s = settings, elements = Array.from(document.querySelectorAll(s.chainSelector)), currentOffsetTop = 0, rowCount = parseInt(s.rowStartIndex, 10) || 0, rowClass = 'odd'; elements.forEach(function(elem) { if (elem.classList.contains('padding')) { elem.parentNode.removeChild(elem); } }); elements.forEach(elem => { elem.className = elem.className.replace(/\brow\d+\b/, ''); elem.classList.remove(s.firstInRowClass); elem.classList.remove(s.lastInRowClass); elem.classList.remove('odd'); elem.classList.remove('even'); elem.classList.remove('lastRow'); }); elements.forEach(function(elem) { if (currentOffsetTop < elem.offsetTop) { currentOffsetTop = elem.offsetTop; elem.classList.add(s.firstInRowClass) if (elem.previousElementSibling) { elem.previousElementSibling.classList.add(s.lastInRowClass); rowCount++; rowClass = elem.previousElementSibling.classList.contains('odd') ? 'even' : 'odd'; } } elem.classList.add('row' + rowCount) elem.classList.add(rowClass); }); let lastRowSelector = '.row' + rowCount, lastRow = Array.from(document.querySelectorAll(lastRowSelector)); lastRow.forEach(elem => elem.classList.add('lastRow')); let lastElement = elements[elements.length - 1]; lastElement.classList.add(s.lastInRowClass); if (rowCount > s.rowStartIndex && lastRow[0].classList.contains('even')) { let penultimateRow = Array.from(document.querySelectorAll('.row' + (rowCount - 1))), rowDelta = penultimateRow.length - lastRow.length, firstInLastRow = lastRow[0], clone; while (rowDelta--) { clone = firstInLastRow.cloneNode(); clone.className = s.chainSelector.replace(/\./g, ' ').trim(); clone.classList.add('padding'); firstInLastRow.parentNode.insertBefore(clone, firstInLastRow); } } } chaining(); window.addEventListener('resize', chaining); 
 ul, li { list-style-type: none; } li.user { width: 3em; height: 3em; line-height: 3em; position: relative; float: left; margin: 0 0 1em 1em; border: 2px solid #000; box-sizing: border-box; border-radius: 50%; } li.first { border-color: red; } li.last { border-color: limegreen; } li::before, li::after { content: url(https://i.stack.imgur.com/lPrR5.png); position: absolute; width: 24px; height: 24px; display: none; } li.odd::after { display: block; top: calc(50% - 20px); left: 100%; } li.odd.last::after, li.even.first::before { transform: rotate(90deg); transform-origin: 50% 50%; top: 100%; left: calc(50% - 10px); } li.even::before { display: block; top: calc(50% - 20px); right: 100%; } li.lastRow.first::before, li.lastRow.last::after { display: none; } li.user.padding { opacity: 0.2; } 
 <ul> <li class="user"></li> <li class="user"></li> <li class="user"></li> <li class="user"></li> <li class="user"></li> <li class="user"></li> <li class="user"></li> <li class="user"></li> <li class="user"></li> <li class="user"></li> </ul> 
Run codeHide result

JS Fiddle demo .

Literature:

+1
source

Source: https://habr.com/ru/post/1244965/


All Articles