diff --git a/.gitignore b/.gitignore index 6e985a867..17bb232ea 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,7 @@ habitat/VERSION habitat/results /.ruby-gemset /.ruby-version + +www/source/index.html.slim + +www/source/index.html.slim diff --git a/www/source/community.html.slim b/www/source/community.html.slim index 8d7d553ff..0f5bd8b06 100644 --- a/www/source/community.html.slim +++ b/www/source/community.html.slim @@ -3,40 +3,59 @@ title: InSpec - Community description: This is where you interact with the InSpec open source community - contribute to the project, provide feedback and ask questions of other community members. --- -.row - .columns.large-10.large-offset-1 - img.hero--img src="/images/community/community-icon.png" - h1.hero--heading InSpec Community - h2.hero--subhead.text-center - | Let's build together -.icon-blocks.row - .columns.medium-4.center - img.icon-block--img src="/images/community/contribute-icon.png" - h3.icon-block--heading Contribute to InSpec - .columns.medium-4.center - img.icon-block--img src="/images/community/get-icon.png" - h3.icon-block--heading Get Answers Quickly - .columns.medium-4.center - img.icon-block--img src="/images/community/report-icon.png" - h3.icon-block--heading Report Bugs and Request Features -.icon-blocks.row - .columns.medium-4 - p.icon-block--text +.row.margin-both-offset + .columns.large-6.medium-6 + h2#icon-trigger data-enllax-direction="horizontal" data-enllax-ratio=".1" data-enllax-type="foreground" + | Inspec is better with friends. + br/ + | Let’s build together. + hr.text-left/ + h3.margin-top + | Join us on Slack and get answers fast + P + | Is something unclear or are you just feeling stuck? We're here to help keep you moving. Chat with us on Slack, so we can help you keep moving. + p.margin-both-xs + | Sign in to slack or request an invite below: + input + .columns.large-6.medium-6.relative + img.grid.strict-right src="/images/community/blue-web.svg" / + img.ball src="/images/community/glow-ball.png" / + img.ball.bright-animate src="/images/community/glow-ball.png" / + img.ball src="/images/community/glow-ball.png" / + +.row.strict-center.margin-top + .large-6.medium-6.columns.strict-center + img.icon-art src="/images/community/contribute.svg" / + h3 Contribute to InSpec + p | InSpec is an open source project created and supported by active and passionate users. If you would like to contribute, we would love to have you. - .columns.medium-4 - p.icon-block--text - | Is something unclear or are you just feeling stuck? We're here to - help keep you moving. Chat with us on Slack, so we can help you keep - moving. - .columns.medium-4 - p.icon-block--text - | We rely on your feedback to improve InSpec. Whether you found a bug + .large-6.medium-6.columns.strict-center + img.icon-art src="/images/community/bugs.svg" / + h3 Report Bugs and Request Features + p + | We rely on your feedback to improve InSpec.
Whether you found a bug or have a great idea for an improvement, join us on GitHub. -.icon-blocks.row - .columns.medium-4 - a.button.primary.block href="https://github.com/chef/inspec" Start Contributing - .columns.medium-4 - a.button.primary.block href="https://community-slack.chef.io" Get Help - .columns.medium-4 - a.button.primary.block href="https://github.com/chef/inspec/issues" Give Feedback +.row.margin-under + .columns.medium-6.strict-center + p + a.btn href="https://github.com/chef/inspec" Start Contributing + .columns.medium-6.strict-center + p + a.btn href="https://github.com/chef/inspec/issues" Give Feedback + + +/.row + .icon.shadow + img src="/images/circ-arrow.svg" / +/.block-angl.blue-gradient +/ .section.purp-shade +/ .row.triangle-shade +/ .large-7.medium-7.columns.margin-top-xl.margin-under-xs data-enllax-ratio=".1" data-enllax-type="foreground" +/ small.t-dk Inspec on Twitter +/ h2.t-white +/ | Latest from #inspec +/ .row +/ .large-12.medium-12.columns.margin-under +/ .shadow +/ Inspec diff --git a/www/source/images/circ-arrow.svg b/www/source/images/circ-arrow.svg new file mode 100644 index 000000000..5e2a6ba79 --- /dev/null +++ b/www/source/images/circ-arrow.svg @@ -0,0 +1 @@ +circ-arrow_1 \ No newline at end of file diff --git a/www/source/images/community/Contrinue.svg b/www/source/images/community/Contrinue.svg new file mode 100644 index 000000000..4ee6ff33c --- /dev/null +++ b/www/source/images/community/Contrinue.svg @@ -0,0 +1 @@ +Contrinue \ No newline at end of file diff --git a/www/source/images/community/blue-web.svg b/www/source/images/community/blue-web.svg new file mode 100644 index 000000000..86246683b --- /dev/null +++ b/www/source/images/community/blue-web.svg @@ -0,0 +1 @@ +blue-web \ No newline at end of file diff --git a/www/source/images/community/bugs.svg b/www/source/images/community/bugs.svg new file mode 100644 index 000000000..10916d83b --- /dev/null +++ b/www/source/images/community/bugs.svg @@ -0,0 +1 @@ +bugs \ No newline at end of file diff --git a/www/source/images/community/contribute.svg b/www/source/images/community/contribute.svg new file mode 100644 index 000000000..1ef3d751f --- /dev/null +++ b/www/source/images/community/contribute.svg @@ -0,0 +1 @@ +contribute \ No newline at end of file diff --git a/www/source/images/community/glow-ball.png b/www/source/images/community/glow-ball.png new file mode 100644 index 000000000..b7291de66 Binary files /dev/null and b/www/source/images/community/glow-ball.png differ diff --git a/www/source/images/hexagon.svg b/www/source/images/hexagon.svg new file mode 100644 index 000000000..712a87cd1 --- /dev/null +++ b/www/source/images/hexagon.svg @@ -0,0 +1 @@ +Asset 1 \ No newline at end of file diff --git a/www/source/index.html.slim b/www/source/index.html.slim index ec8060d9a..bacc67eb4 100644 --- a/www/source/index.html.slim +++ b/www/source/index.html.slim @@ -1,36 +1,30 @@ --- title: InSpec - Audit and Test Framework --- - /! animated banner -header +header.blue-gradient .h-top.strict-center.purp-shade h1.center.t-white.strict-center data-enllax-ratio=".1" data-enllax-type="foreground" InSpec is compliance as code img.grid-animate.strict-center src="/images/home/web.svg" / /! diamond image img.strict-center.bright-animate.3d-animate data-enllax-ratio=".3" data-enllax-type="foreground" src="/images/home/diamond.png" / /! Blue gradient and canvas elements - #container.blue-gradient - canvas#pixie /! style for callout icons + #particles-js + canvas.particles-js-canvas-el / .row .icon.shadow - img src="/images/home/circ-arrow.svg" / + img src="/images/circ-arrow.svg" / /! Second Content .row.margin-both .large-8.columns data-enllax-direction="horizontal" data-enllax-ratio=".1" data-enllax-type="foreground" - h4 + h4#icon-trigger | InSpec is an open-source testing framework for infrastructure with a human-readable language for specifying compliance, security and other policy requirements. Easily integrate automated tests that check for adherence to policy into any stage of your deployment pipeline. - p - small - | Crafted with - span.t-blue ❤ - | by humans, for humans /! Third Content -#icon-trigger.row.strict-center.margin-under-xs +.row.strict-center.margin-under-xs .large-12.columns hr/ - small Cool facts about inspec + small FEATURES OF INSPEC h2 InSpec is compliance by design hr/ /! images with text - grid of 4 @@ -40,7 +34,7 @@ header h3 Platform Agnostic p | InSpec supports all major operating systems and many applications out of the box. - .large-3.medium-3.columns.strict-center data-enllax-ratio=".1" data-enllax-type="foreground" + .large-3.medium-3.columns.strict-center img.icon-art src="/images/home/free.svg" / h3 Free to run anywhere p @@ -50,124 +44,131 @@ header h3 Test locally or remotely p | InSpec provides a local agent, as well as full remote testing support. - .large-3.medium-3.columns.strict-center data-enllax-ratio=".1" data-enllax-type="foreground" + .large-3.medium-3.columns.strict-center img.icon-art src="/images/home/language.svg" / - h3 Fully extensible language + h3 Extensible language p | Easily extend the InSpec language to cover new operating systems, devices, or applications. /! Fourth Content /! style for callout icons .row .icon.shadow - img src="/images/home/circ-lock.svg" / -.block-angl.blue-gradient.margin-under - .row.triangle-shade - .large-7.medium-7.columns.margin-top-xl.margin-under-xs data-enllax-ratio=".1" data-enllax-type="foreground" - small.t-dk Inspec for compliance - h2.t-white - | Transform your compliance and security requirements - | into simple code - .row - .large-5.medium-5.columns.margin-under - h3.t-white Codify agreements - p.t-white - | Combine profiles and customize them with overlays. Pick - | controls and define exceptions as code. - h3.t-white Add context to your tests - p.t-white - | Supports many fields like descriptions, tags, and - | impact. - h3.t-white Apply to all systems - p.t-white - | Combine profiles and customize them with overlays. Pick - | controls and define exceptions as code. - /! code - .large-6.medium-6.columns.code-example.shadow - code.code-demo - span.code-attribute> control - | 'sshd-21' - br/ - span.code-token title - | 'Set SSH Protocol to 2' - br/ - span.code-token desc - | 'A detailed description about why we - | want this...' - br/ - span.code-token impact 1.0 - | \#this is critical - br/ - span.code-token ref - | 'Our little compliance guide, section - | 2.1' - br/ - span.code-attribute describe - | sshd_config - span.code-attribute do - br/ - span.code-attribute its - | ('Protocol') { should cmp 2 } - br/ - span.code-attribute end - br/ - span.code-attribute end - a.btn.strict-right Try the Demo - /! Next row - .row - .large-6.medium-6.columns.margin-under-xs data-enllax-ratio=".1" data-enllax-type="foreground" - small.t-dk Inspec for infrastructure - h2.t-white - | Solve your infrastructure testing needs simply and - | efficiently - .row - .large-5.medium-5.columns.margin-under-xl - h3.t-white Test the desired state - p.t-white Match your infrastructure to your expectations. - h3.t-white Add context to your tests - p.t-white - | Supports many fields like descriptions, tags, and - | impact. - h3.t-white Apply to all systems - p.t-white - | Combine profiles and customize them with overlays. Pick - | controls and define exceptions as code. - /! code - .large-6.medium-6.columns.code-example.shadow - code.code-demo - span.code-attribute control - | 'sshd-21' - br/ - span.code-token title - | 'Set SSH Protocol to 2' - br/ - span.code-token desc - | 'A detailed description about why we - | want this...' - br/ - span.code-token impact 1.0 - | \#this is critical - br/ - span.code-token ref - | 'Our little compliance guide, section - | 2.1' - br/ - span.code-attribute describe - | sshd_config - span.code-attribute do - br/ - span.code-attribute its - | ('Protocol') { should cmp 2 } - br/ - span.code-attribute end - br/ - span.code-attribute end - a.btn.strict-right Try the Demo -/! Fifth Content -.row.strict-center.margin-under-xs - .large-12.columns data-enllax-ratio=".2" data-enllax-type="foreground" - hr/ - small Inspec and friends - h2 Inspec plays nicely with others - hr/ -h4.strict-center.large-8 - | Use Inspec for DevOps with other technologies for a unified workflow, end-to-end visibility, and automated compliance. + img src="/images/circ-arrow.svg" / +.block-angl.blue-gradient + .section.purp-shade + .row.triangle-shade + .large-7.medium-7.columns.margin-top-xl.margin-under-xs data-enllax-ratio=".1" data-enllax-type="foreground" + small.t-dk Inspec for compliance + h2.t-white + | Transform your compliance and security requirements into simple code + #particles-second + canvas.particles-js-canvas-el + .row + .large-5.medium-5.columns.margin-under + h3.t-white + i.fa.fa-angle-right.t-dk + | Codify agreements + p.t-white + | Combine profiles and customize them with overlays. Pick controls and define exceptions as code. + h3.t-white + i.fa.fa-angle-right.t-dk + | Add context to your tests + p.t-white + | Supports many fields like descriptions, tags, and impact. + h3.t-white + i.fa.fa-angle-right.t-dk + | Apply to all systems + p.t-white + | Combine profiles and customize them with overlays. Pick controls and define exceptions as code. + /! code + .large-6.medium-6.columns.code-example.shadow + code.code-demo + span.code-attribute control + | 'sshd-21' + br/ + span.code-token.indent title + | 'Set SSH Protocol to 2' + br/ + span.code-token.indent desc + | 'A detailed description' + br/ + span.code-token.indent impact + | 1.0 #this is critical + br/ + span.code-token.indent ref + | 'compliance guide, section 2.1' + br/ + br/ + span.code-attribute.indent describe + | sshd_config + span.code-attribute do + br/ + span.code-attribute.indent its + | ('Protocol') {should cmp 2} + br/ + span.code-attribute.indent end + br/ + span.code-attribute end + a.btn.strict-right.t-white Try the Demo + /! Next row + .row + .large-6.medium-6.columns.margin-under-xs data-enllax-ratio=".1" data-enllax-type="foreground" + small.t-dk Inspec for infrastructure + h2.t-white + | Solve your infrastructure testing needs simply and efficiently + .row + .large-5.medium-5.columns.margin-under-xl + h3.t-white + i.fa.fa-angle-right.t-dk + | Test the desired state + p.t-white Match your infrastructure to your expectations. + h3.t-white + i.fa.fa-angle-right.t-dk + | Use simple and expressive code + p.t-white + | These tests are easy to understand by anyone, reducing friction. + h3.t-white + i.fa.fa-angle-right.t-dk + | Test any system anywhere + p.t-white + | Runs locally and remotely. Supports all major operating systems and configurations. + h3.t-white + i.fa.fa-angle-right.t-dk + | Extensible + p.t-white + | Easily create custom resources and share them. + /! code + .large-6.medium-6.columns.code-example.shadow + code.code-demo + span.code-attribute describe + | file('/etc/myap.conf') + span.code-attribute do + br/ + span.code-attribute.indent it + | {should exist} + br/ + span.code-attribute.indent its + | ('mode') {should cmp '0644'} + br/ + span.code-attribute end + br/ + br/ + span.code-attribute describe + | myapp.conf + span.code-attribute do + br/ + span.code-attribute.indent its + | ('port') {should cmp 8080} + br/ + span.code-attribute end + br/ + br/ + span.code-attribute describe + | port(8080) + span.code-attribute do + br/ + span.code-attribute.indent it + | {should be_listening} + br/ + span.code-attribute end + a.btn.strict-right.t-white Try the Demo diff --git a/www/source/javascripts/all.js b/www/source/javascripts/all.js index bfdf70b81..5057a87f9 100644 --- a/www/source/javascripts/all.js +++ b/www/source/javascripts/all.js @@ -1,5 +1,6 @@ //= require vendor/jquery.min //= require vendor/foundation.min //= require nav -//= require stars //= require jquery.enllax.min +//= require particles +//= require app diff --git a/www/source/javascripts/app.js b/www/source/javascripts/app.js new file mode 100755 index 000000000..d1184f966 --- /dev/null +++ b/www/source/javascripts/app.js @@ -0,0 +1,254 @@ +/* ----------------------------------------------- +/* How to use? : Check the GitHub README +/* ----------------------------------------------- */ + +/* To load a config file (particles.json) you need to host this demo (MAMP/WAMP/local)... */ + +particlesJS.load('particles-js', 'particles-second' , 'particles.json', function() { + console.log('particles.js loaded - callback'); +}); + + +/* Otherwise just put the config content (json): */ + +particlesJS('particles-second', + +{ + "particles": { + "number": { + "value": 15, + "density": { + "enable": true, + "value_area": 500 + } + }, + "color": { + "value": "#ffffff" + }, + "shape": { + "type": "circle", + "stroke": { + "width": 0, + "color": "#000000" + }, + "polygon": { + "nb_sides": 3 + }, + "image": { + "src": "img/github.svg", + "width": 100, + "height": 100 + } + }, + "opacity": { + "value": 0.5, + "random": false, + "anim": { + "enable": false, + "speed": 4, + "opacity_min": 0.1, + "sync": false + } + }, + "size": { + "value": 3, + "random": true, + "anim": { + "enable": false, + "speed": 40, + "size_min": 0.1, + "sync": false + } + }, + "line_linked": { + "enable": true, + "distance": 150, + "color": "#ffffff", + "opacity": 0.5, + "width": 1 + }, + "move": { + "enable": true, + "speed": 4, + "direction": "none", + "random": true, + "straight": false, + "out_mode": "out", + "attract": { + "enable": false, + "rotateX": 600, + "rotateY": 1200 + } + } + }, + "interactivity": { + "detect_on": "canvas", + "events": { + "onhover": { + "enable": false, + "mode": "repulse" + }, + "onclick": { + "enable": false, + "mode": "repulse" + }, + "resize": true + }, + "modes": { + "grab": { + "distance": 400, + "line_linked": { + "opacity": 1 + } + }, + "bubble": { + "distance": 400, + "size": 10, + "duration": 2, + "opacity": 8, + "speed": 3 + }, + "repulse": { + "distance": 300 + }, + "push": { + "particles_nb": 4 + }, + "remove": { + "particles_nb": 2 + } + } + }, + "retina_detect": true, + "config_demo": { + "hide_card": false, + "background_color": "#b61924", + "background_image": "", + "background_position": "50% 50%", + "background_repeat": "no-repeat", + "background_size": "cover" + } +} + +); + +particlesJS('particles-js', + + { + "particles": { + "number": { + "value": 30, + "density": { + "enable": true, + "value_area": 500 + } + }, + "color": { + "value": "#ffffff" + }, + "shape": { + "type": "circle", + "stroke": { + "width": 0, + "color": "#000000" + }, + "polygon": { + "nb_sides": 3 + }, + "image": { + "src": "img/github.svg", + "width": 100, + "height": 100 + } + }, + "opacity": { + "value": 0.5, + "random": false, + "anim": { + "enable": false, + "speed": 4, + "opacity_min": 0.1, + "sync": false + } + }, + "size": { + "value": 3, + "random": true, + "anim": { + "enable": false, + "speed": 40, + "size_min": 0.1, + "sync": false + } + }, + "line_linked": { + "enable": false, + "distance": 150, + "color": "#ffffff", + "opacity": 0.4, + "width": 1 + }, + "move": { + "enable": true, + "speed": 4, + "direction": "none", + "random": true, + "straight": false, + "out_mode": "out", + "attract": { + "enable": false, + "rotateX": 600, + "rotateY": 1200 + } + } + }, + "interactivity": { + "detect_on": "canvas", + "events": { + "onhover": { + "enable": true, + "mode": "repulse" + }, + "onclick": { + "enable": true, + "mode": "repulse" + }, + "resize": true + }, + "modes": { + "grab": { + "distance": 400, + "line_linked": { + "opacity": 1 + } + }, + "bubble": { + "distance": 400, + "size": 10, + "duration": 2, + "opacity": 8, + "speed": 3 + }, + "repulse": { + "distance": 150 + }, + "push": { + "particles_nb": 4 + }, + "remove": { + "particles_nb": 2 + } + } + }, + "retina_detect": true, + "config_demo": { + "hide_card": false, + "background_color": "#b61924", + "background_image": "", + "background_position": "50% 50%", + "background_repeat": "no-repeat", + "background_size": "cover" + } + } + +); diff --git a/www/source/javascripts/particles.js b/www/source/javascripts/particles.js new file mode 100755 index 000000000..68c22d305 --- /dev/null +++ b/www/source/javascripts/particles.js @@ -0,0 +1,1541 @@ +/* ----------------------------------------------- +/* Author : Vincent Garreau - vincentgarreau.com +/* MIT license: http://opensource.org/licenses/MIT +/* Demo / Generator : vincentgarreau.com/particles.js +/* GitHub : github.com/VincentGarreau/particles.js +/* How to use? : Check the GitHub README +/* v2.0.0 +/* ----------------------------------------------- */ + + var pJS = function(tag_id, params){ + + var canvas_el = document.querySelector('#'+tag_id+' > .particles-js-canvas-el'); + + /* particles.js variables with default values */ + this.pJS = { + canvas: { + el: canvas_el, + w: canvas_el.offsetWidth, + h: canvas_el.offsetHeight + }, + particles: { + number: { + value: 400, + density: { + enable: true, + value_area: 800 + } + }, + color: { + value: '#fff' + }, + shape: { + type: 'circle', + stroke: { + width: 0, + color: '#ff0000' + }, + polygon: { + nb_sides: 5 + }, + image: { + src: '', + width: 100, + height: 100 + } + }, + opacity: { + value: 1, + random: false, + anim: { + enable: false, + speed: 2, + opacity_min: 0, + sync: false + } + }, + size: { + value: 20, + random: false, + anim: { + enable: false, + speed: 20, + size_min: 0, + sync: false + } + }, + line_linked: { + enable: true, + distance: 100, + color: '#fff', + opacity: 1, + width: 1 + }, + move: { + enable: true, + speed: 2, + direction: 'none', + random: false, + straight: false, + out_mode: 'out', + bounce: false, + attract: { + enable: false, + rotateX: 3000, + rotateY: 3000 + } + }, + array: [] + }, + interactivity: { + detect_on: 'canvas', + events: { + onhover: { + enable: true, + mode: 'grab' + }, + onclick: { + enable: true, + mode: 'push' + }, + resize: true + }, + modes: { + grab:{ + distance: 100, + line_linked:{ + opacity: 1 + } + }, + bubble:{ + distance: 200, + size: 80, + duration: 0.4 + }, + repulse:{ + distance: 200, + duration: 0.4 + }, + push:{ + particles_nb: 4 + }, + remove:{ + particles_nb: 2 + } + }, + mouse:{} + }, + retina_detect: false, + fn: { + interact: {}, + modes: {}, + vendors:{} + }, + tmp: {} + }; + + var pJS = this.pJS; + + /* params settings */ + if(params){ + Object.deepExtend(pJS, params); + } + + pJS.tmp.obj = { + size_value: pJS.particles.size.value, + size_anim_speed: pJS.particles.size.anim.speed, + move_speed: pJS.particles.move.speed, + line_linked_distance: pJS.particles.line_linked.distance, + line_linked_width: pJS.particles.line_linked.width, + mode_grab_distance: pJS.interactivity.modes.grab.distance, + mode_bubble_distance: pJS.interactivity.modes.bubble.distance, + mode_bubble_size: pJS.interactivity.modes.bubble.size, + mode_repulse_distance: pJS.interactivity.modes.repulse.distance + }; + + + pJS.fn.retinaInit = function(){ + + if(pJS.retina_detect && window.devicePixelRatio > 1){ + pJS.canvas.pxratio = window.devicePixelRatio; + pJS.tmp.retina = true; + } + else{ + pJS.canvas.pxratio = 1; + pJS.tmp.retina = false; + } + + pJS.canvas.w = pJS.canvas.el.offsetWidth * pJS.canvas.pxratio; + pJS.canvas.h = pJS.canvas.el.offsetHeight * pJS.canvas.pxratio; + + pJS.particles.size.value = pJS.tmp.obj.size_value * pJS.canvas.pxratio; + pJS.particles.size.anim.speed = pJS.tmp.obj.size_anim_speed * pJS.canvas.pxratio; + pJS.particles.move.speed = pJS.tmp.obj.move_speed * pJS.canvas.pxratio; + pJS.particles.line_linked.distance = pJS.tmp.obj.line_linked_distance * pJS.canvas.pxratio; + pJS.interactivity.modes.grab.distance = pJS.tmp.obj.mode_grab_distance * pJS.canvas.pxratio; + pJS.interactivity.modes.bubble.distance = pJS.tmp.obj.mode_bubble_distance * pJS.canvas.pxratio; + pJS.particles.line_linked.width = pJS.tmp.obj.line_linked_width * pJS.canvas.pxratio; + pJS.interactivity.modes.bubble.size = pJS.tmp.obj.mode_bubble_size * pJS.canvas.pxratio; + pJS.interactivity.modes.repulse.distance = pJS.tmp.obj.mode_repulse_distance * pJS.canvas.pxratio; + + }; + + + + /* ---------- pJS functions - canvas ------------ */ + + pJS.fn.canvasInit = function(){ + pJS.canvas.ctx = pJS.canvas.el.getContext('2d'); + }; + + pJS.fn.canvasSize = function(){ + + pJS.canvas.el.width = pJS.canvas.w; + pJS.canvas.el.height = pJS.canvas.h; + + if(pJS && pJS.interactivity.events.resize){ + + window.addEventListener('resize', function(){ + + pJS.canvas.w = pJS.canvas.el.offsetWidth; + pJS.canvas.h = pJS.canvas.el.offsetHeight; + + /* resize canvas */ + if(pJS.tmp.retina){ + pJS.canvas.w *= pJS.canvas.pxratio; + pJS.canvas.h *= pJS.canvas.pxratio; + } + + pJS.canvas.el.width = pJS.canvas.w; + pJS.canvas.el.height = pJS.canvas.h; + + /* repaint canvas on anim disabled */ + if(!pJS.particles.move.enable){ + pJS.fn.particlesEmpty(); + pJS.fn.particlesCreate(); + pJS.fn.particlesDraw(); + pJS.fn.vendors.densityAutoParticles(); + } + + /* density particles enabled */ + pJS.fn.vendors.densityAutoParticles(); + + }); + + } + + }; + + + pJS.fn.canvasPaint = function(){ + pJS.canvas.ctx.fillRect(0, 0, pJS.canvas.w, pJS.canvas.h); + }; + + pJS.fn.canvasClear = function(){ + pJS.canvas.ctx.clearRect(0, 0, pJS.canvas.w, pJS.canvas.h); + }; + + + /* --------- pJS functions - particles ----------- */ + + pJS.fn.particle = function(color, opacity, position){ + + /* size */ + this.radius = (pJS.particles.size.random ? Math.random() : 1) * pJS.particles.size.value; + if(pJS.particles.size.anim.enable){ + this.size_status = false; + this.vs = pJS.particles.size.anim.speed / 100; + if(!pJS.particles.size.anim.sync){ + this.vs = this.vs * Math.random(); + } + } + + /* position */ + this.x = position ? position.x : Math.random() * pJS.canvas.w; + this.y = position ? position.y : Math.random() * pJS.canvas.h; + + /* check position - into the canvas */ + if(this.x > pJS.canvas.w - this.radius*2) this.x = this.x - this.radius; + else if(this.x < this.radius*2) this.x = this.x + this.radius; + if(this.y > pJS.canvas.h - this.radius*2) this.y = this.y - this.radius; + else if(this.y < this.radius*2) this.y = this.y + this.radius; + + /* check position - avoid overlap */ + if(pJS.particles.move.bounce){ + pJS.fn.vendors.checkOverlap(this, position); + } + + /* color */ + this.color = {}; + if(typeof(color.value) == 'object'){ + + if(color.value instanceof Array){ + var color_selected = color.value[Math.floor(Math.random() * pJS.particles.color.value.length)]; + this.color.rgb = hexToRgb(color_selected); + }else{ + if(color.value.r != undefined && color.value.g != undefined && color.value.b != undefined){ + this.color.rgb = { + r: color.value.r, + g: color.value.g, + b: color.value.b + } + } + if(color.value.h != undefined && color.value.s != undefined && color.value.l != undefined){ + this.color.hsl = { + h: color.value.h, + s: color.value.s, + l: color.value.l + } + } + } + + } + else if(color.value == 'random'){ + this.color.rgb = { + r: (Math.floor(Math.random() * (255 - 0 + 1)) + 0), + g: (Math.floor(Math.random() * (255 - 0 + 1)) + 0), + b: (Math.floor(Math.random() * (255 - 0 + 1)) + 0) + } + } + else if(typeof(color.value) == 'string'){ + this.color = color; + this.color.rgb = hexToRgb(this.color.value); + } + + /* opacity */ + this.opacity = (pJS.particles.opacity.random ? Math.random() : 1) * pJS.particles.opacity.value; + if(pJS.particles.opacity.anim.enable){ + this.opacity_status = false; + this.vo = pJS.particles.opacity.anim.speed / 100; + if(!pJS.particles.opacity.anim.sync){ + this.vo = this.vo * Math.random(); + } + } + + /* animation - velocity for speed */ + var velbase = {} + switch(pJS.particles.move.direction){ + case 'top': + velbase = { x:0, y:-1 }; + break; + case 'top-right': + velbase = { x:0.5, y:-0.5 }; + break; + case 'right': + velbase = { x:1, y:-0 }; + break; + case 'bottom-right': + velbase = { x:0.5, y:0.5 }; + break; + case 'bottom': + velbase = { x:0, y:1 }; + break; + case 'bottom-left': + velbase = { x:-0.5, y:1 }; + break; + case 'left': + velbase = { x:-1, y:0 }; + break; + case 'top-left': + velbase = { x:-0.5, y:-0.5 }; + break; + default: + velbase = { x:0, y:0 }; + break; + } + + if(pJS.particles.move.straight){ + this.vx = velbase.x; + this.vy = velbase.y; + if(pJS.particles.move.random){ + this.vx = this.vx * (Math.random()); + this.vy = this.vy * (Math.random()); + } + }else{ + this.vx = velbase.x + Math.random()-0.5; + this.vy = velbase.y + Math.random()-0.5; + } + + // var theta = 2.0 * Math.PI * Math.random(); + // this.vx = Math.cos(theta); + // this.vy = Math.sin(theta); + + this.vx_i = this.vx; + this.vy_i = this.vy; + + + + /* if shape is image */ + + var shape_type = pJS.particles.shape.type; + if(typeof(shape_type) == 'object'){ + if(shape_type instanceof Array){ + var shape_selected = shape_type[Math.floor(Math.random() * shape_type.length)]; + this.shape = shape_selected; + } + }else{ + this.shape = shape_type; + } + + if(this.shape == 'image'){ + var sh = pJS.particles.shape; + this.img = { + src: sh.image.src, + ratio: sh.image.width / sh.image.height + } + if(!this.img.ratio) this.img.ratio = 1; + if(pJS.tmp.img_type == 'svg' && pJS.tmp.source_svg != undefined){ + pJS.fn.vendors.createSvgImg(this); + if(pJS.tmp.pushing){ + this.img.loaded = false; + } + } + } + + + + }; + + + pJS.fn.particle.prototype.draw = function() { + + var p = this; + + if(p.radius_bubble != undefined){ + var radius = p.radius_bubble; + }else{ + var radius = p.radius; + } + + if(p.opacity_bubble != undefined){ + var opacity = p.opacity_bubble; + }else{ + var opacity = p.opacity; + } + + if(p.color.rgb){ + var color_value = 'rgba('+p.color.rgb.r+','+p.color.rgb.g+','+p.color.rgb.b+','+opacity+')'; + }else{ + var color_value = 'hsla('+p.color.hsl.h+','+p.color.hsl.s+'%,'+p.color.hsl.l+'%,'+opacity+')'; + } + + pJS.canvas.ctx.fillStyle = color_value; + pJS.canvas.ctx.beginPath(); + + switch(p.shape){ + + case 'circle': + pJS.canvas.ctx.arc(p.x, p.y, radius, 0, Math.PI * 2, false); + break; + + case 'edge': + pJS.canvas.ctx.rect(p.x-radius, p.y-radius, radius*2, radius*2); + break; + + case 'triangle': + pJS.fn.vendors.drawShape(pJS.canvas.ctx, p.x-radius, p.y+radius / 1.66, radius*2, 3, 2); + break; + + case 'polygon': + pJS.fn.vendors.drawShape( + pJS.canvas.ctx, + p.x - radius / (pJS.particles.shape.polygon.nb_sides/3.5), // startX + p.y - radius / (2.66/3.5), // startY + radius*2.66 / (pJS.particles.shape.polygon.nb_sides/3), // sideLength + pJS.particles.shape.polygon.nb_sides, // sideCountNumerator + 1 // sideCountDenominator + ); + break; + + case 'star': + pJS.fn.vendors.drawShape( + pJS.canvas.ctx, + p.x - radius*2 / (pJS.particles.shape.polygon.nb_sides/4), // startX + p.y - radius / (2*2.66/3.5), // startY + radius*2*2.66 / (pJS.particles.shape.polygon.nb_sides/3), // sideLength + pJS.particles.shape.polygon.nb_sides, // sideCountNumerator + 2 // sideCountDenominator + ); + break; + + case 'image': + + function draw(){ + pJS.canvas.ctx.drawImage( + img_obj, + p.x-radius, + p.y-radius, + radius*2, + radius*2 / p.img.ratio + ); + } + + if(pJS.tmp.img_type == 'svg'){ + var img_obj = p.img.obj; + }else{ + var img_obj = pJS.tmp.img_obj; + } + + if(img_obj){ + draw(); + } + + break; + + } + + pJS.canvas.ctx.closePath(); + + if(pJS.particles.shape.stroke.width > 0){ + pJS.canvas.ctx.strokeStyle = pJS.particles.shape.stroke.color; + pJS.canvas.ctx.lineWidth = pJS.particles.shape.stroke.width; + pJS.canvas.ctx.stroke(); + } + + pJS.canvas.ctx.fill(); + + }; + + + pJS.fn.particlesCreate = function(){ + for(var i = 0; i < pJS.particles.number.value; i++) { + pJS.particles.array.push(new pJS.fn.particle(pJS.particles.color, pJS.particles.opacity.value)); + } + }; + + pJS.fn.particlesUpdate = function(){ + + for(var i = 0; i < pJS.particles.array.length; i++){ + + /* the particle */ + var p = pJS.particles.array[i]; + + // var d = ( dx = pJS.interactivity.mouse.click_pos_x - p.x ) * dx + ( dy = pJS.interactivity.mouse.click_pos_y - p.y ) * dy; + // var f = -BANG_SIZE / d; + // if ( d < BANG_SIZE ) { + // var t = Math.atan2( dy, dx ); + // p.vx = f * Math.cos(t); + // p.vy = f * Math.sin(t); + // } + + /* move the particle */ + if(pJS.particles.move.enable){ + var ms = pJS.particles.move.speed/2; + p.x += p.vx * ms; + p.y += p.vy * ms; + } + + /* change opacity status */ + if(pJS.particles.opacity.anim.enable) { + if(p.opacity_status == true) { + if(p.opacity >= pJS.particles.opacity.value) p.opacity_status = false; + p.opacity += p.vo; + }else { + if(p.opacity <= pJS.particles.opacity.anim.opacity_min) p.opacity_status = true; + p.opacity -= p.vo; + } + if(p.opacity < 0) p.opacity = 0; + } + + /* change size */ + if(pJS.particles.size.anim.enable){ + if(p.size_status == true){ + if(p.radius >= pJS.particles.size.value) p.size_status = false; + p.radius += p.vs; + }else{ + if(p.radius <= pJS.particles.size.anim.size_min) p.size_status = true; + p.radius -= p.vs; + } + if(p.radius < 0) p.radius = 0; + } + + /* change particle position if it is out of canvas */ + if(pJS.particles.move.out_mode == 'bounce'){ + var new_pos = { + x_left: p.radius, + x_right: pJS.canvas.w, + y_top: p.radius, + y_bottom: pJS.canvas.h + } + }else{ + var new_pos = { + x_left: -p.radius, + x_right: pJS.canvas.w + p.radius, + y_top: -p.radius, + y_bottom: pJS.canvas.h + p.radius + } + } + + if(p.x - p.radius > pJS.canvas.w){ + p.x = new_pos.x_left; + p.y = Math.random() * pJS.canvas.h; + } + else if(p.x + p.radius < 0){ + p.x = new_pos.x_right; + p.y = Math.random() * pJS.canvas.h; + } + if(p.y - p.radius > pJS.canvas.h){ + p.y = new_pos.y_top; + p.x = Math.random() * pJS.canvas.w; + } + else if(p.y + p.radius < 0){ + p.y = new_pos.y_bottom; + p.x = Math.random() * pJS.canvas.w; + } + + /* out of canvas modes */ + switch(pJS.particles.move.out_mode){ + case 'bounce': + if (p.x + p.radius > pJS.canvas.w) p.vx = -p.vx; + else if (p.x - p.radius < 0) p.vx = -p.vx; + if (p.y + p.radius > pJS.canvas.h) p.vy = -p.vy; + else if (p.y - p.radius < 0) p.vy = -p.vy; + break; + } + + /* events */ + if(isInArray('grab', pJS.interactivity.events.onhover.mode)){ + pJS.fn.modes.grabParticle(p); + } + + if(isInArray('bubble', pJS.interactivity.events.onhover.mode) || isInArray('bubble', pJS.interactivity.events.onclick.mode)){ + pJS.fn.modes.bubbleParticle(p); + } + + if(isInArray('repulse', pJS.interactivity.events.onhover.mode) || isInArray('repulse', pJS.interactivity.events.onclick.mode)){ + pJS.fn.modes.repulseParticle(p); + } + + /* interaction auto between particles */ + if(pJS.particles.line_linked.enable || pJS.particles.move.attract.enable){ + for(var j = i + 1; j < pJS.particles.array.length; j++){ + var p2 = pJS.particles.array[j]; + + /* link particles */ + if(pJS.particles.line_linked.enable){ + pJS.fn.interact.linkParticles(p,p2); + } + + /* attract particles */ + if(pJS.particles.move.attract.enable){ + pJS.fn.interact.attractParticles(p,p2); + } + + /* bounce particles */ + if(pJS.particles.move.bounce){ + pJS.fn.interact.bounceParticles(p,p2); + } + + } + } + + + } + + }; + + pJS.fn.particlesDraw = function(){ + + /* clear canvas */ + pJS.canvas.ctx.clearRect(0, 0, pJS.canvas.w, pJS.canvas.h); + + /* update each particles param */ + pJS.fn.particlesUpdate(); + + /* draw each particle */ + for(var i = 0; i < pJS.particles.array.length; i++){ + var p = pJS.particles.array[i]; + p.draw(); + } + + }; + + pJS.fn.particlesEmpty = function(){ + pJS.particles.array = []; + }; + + pJS.fn.particlesRefresh = function(){ + + /* init all */ + cancelRequestAnimFrame(pJS.fn.checkAnimFrame); + cancelRequestAnimFrame(pJS.fn.drawAnimFrame); + pJS.tmp.source_svg = undefined; + pJS.tmp.img_obj = undefined; + pJS.tmp.count_svg = 0; + pJS.fn.particlesEmpty(); + pJS.fn.canvasClear(); + + /* restart */ + pJS.fn.vendors.start(); + + }; + + + /* ---------- pJS functions - particles interaction ------------ */ + + pJS.fn.interact.linkParticles = function(p1, p2){ + + var dx = p1.x - p2.x, + dy = p1.y - p2.y, + dist = Math.sqrt(dx*dx + dy*dy); + + /* draw a line between p1 and p2 if the distance between them is under the config distance */ + if(dist <= pJS.particles.line_linked.distance){ + + var opacity_line = pJS.particles.line_linked.opacity - (dist / (1/pJS.particles.line_linked.opacity)) / pJS.particles.line_linked.distance; + + if(opacity_line > 0){ + + /* style */ + var color_line = pJS.particles.line_linked.color_rgb_line; + pJS.canvas.ctx.strokeStyle = 'rgba('+color_line.r+','+color_line.g+','+color_line.b+','+opacity_line+')'; + pJS.canvas.ctx.lineWidth = pJS.particles.line_linked.width; + //pJS.canvas.ctx.lineCap = 'round'; /* performance issue */ + + /* path */ + pJS.canvas.ctx.beginPath(); + pJS.canvas.ctx.moveTo(p1.x, p1.y); + pJS.canvas.ctx.lineTo(p2.x, p2.y); + pJS.canvas.ctx.stroke(); + pJS.canvas.ctx.closePath(); + + } + + } + + }; + + + pJS.fn.interact.attractParticles = function(p1, p2){ + + /* condensed particles */ + var dx = p1.x - p2.x, + dy = p1.y - p2.y, + dist = Math.sqrt(dx*dx + dy*dy); + + if(dist <= pJS.particles.line_linked.distance){ + + var ax = dx/(pJS.particles.move.attract.rotateX*1000), + ay = dy/(pJS.particles.move.attract.rotateY*1000); + + p1.vx -= ax; + p1.vy -= ay; + + p2.vx += ax; + p2.vy += ay; + + } + + + } + + + pJS.fn.interact.bounceParticles = function(p1, p2){ + + var dx = p1.x - p2.x, + dy = p1.y - p2.y, + dist = Math.sqrt(dx*dx + dy*dy), + dist_p = p1.radius+p2.radius; + + if(dist <= dist_p){ + p1.vx = -p1.vx; + p1.vy = -p1.vy; + + p2.vx = -p2.vx; + p2.vy = -p2.vy; + } + + } + + + /* ---------- pJS functions - modes events ------------ */ + + pJS.fn.modes.pushParticles = function(nb, pos){ + + pJS.tmp.pushing = true; + + for(var i = 0; i < nb; i++){ + pJS.particles.array.push( + new pJS.fn.particle( + pJS.particles.color, + pJS.particles.opacity.value, + { + 'x': pos ? pos.pos_x : Math.random() * pJS.canvas.w, + 'y': pos ? pos.pos_y : Math.random() * pJS.canvas.h + } + ) + ) + if(i == nb-1){ + if(!pJS.particles.move.enable){ + pJS.fn.particlesDraw(); + } + pJS.tmp.pushing = false; + } + } + + }; + + + pJS.fn.modes.removeParticles = function(nb){ + + pJS.particles.array.splice(0, nb); + if(!pJS.particles.move.enable){ + pJS.fn.particlesDraw(); + } + + }; + + + pJS.fn.modes.bubbleParticle = function(p){ + + /* on hover event */ + if(pJS.interactivity.events.onhover.enable && isInArray('bubble', pJS.interactivity.events.onhover.mode)){ + + var dx_mouse = p.x - pJS.interactivity.mouse.pos_x, + dy_mouse = p.y - pJS.interactivity.mouse.pos_y, + dist_mouse = Math.sqrt(dx_mouse*dx_mouse + dy_mouse*dy_mouse), + ratio = 1 - dist_mouse / pJS.interactivity.modes.bubble.distance; + + function init(){ + p.opacity_bubble = p.opacity; + p.radius_bubble = p.radius; + } + + /* mousemove - check ratio */ + if(dist_mouse <= pJS.interactivity.modes.bubble.distance){ + + if(ratio >= 0 && pJS.interactivity.status == 'mousemove'){ + + /* size */ + if(pJS.interactivity.modes.bubble.size != pJS.particles.size.value){ + + if(pJS.interactivity.modes.bubble.size > pJS.particles.size.value){ + var size = p.radius + (pJS.interactivity.modes.bubble.size*ratio); + if(size >= 0){ + p.radius_bubble = size; + } + }else{ + var dif = p.radius - pJS.interactivity.modes.bubble.size, + size = p.radius - (dif*ratio); + if(size > 0){ + p.radius_bubble = size; + }else{ + p.radius_bubble = 0; + } + } + + } + + /* opacity */ + if(pJS.interactivity.modes.bubble.opacity != pJS.particles.opacity.value){ + + if(pJS.interactivity.modes.bubble.opacity > pJS.particles.opacity.value){ + var opacity = pJS.interactivity.modes.bubble.opacity*ratio; + if(opacity > p.opacity && opacity <= pJS.interactivity.modes.bubble.opacity){ + p.opacity_bubble = opacity; + } + }else{ + var opacity = p.opacity - (pJS.particles.opacity.value-pJS.interactivity.modes.bubble.opacity)*ratio; + if(opacity < p.opacity && opacity >= pJS.interactivity.modes.bubble.opacity){ + p.opacity_bubble = opacity; + } + } + + } + + } + + }else{ + init(); + } + + + /* mouseleave */ + if(pJS.interactivity.status == 'mouseleave'){ + init(); + } + + } + + /* on click event */ + else if(pJS.interactivity.events.onclick.enable && isInArray('bubble', pJS.interactivity.events.onclick.mode)){ + + + if(pJS.tmp.bubble_clicking){ + var dx_mouse = p.x - pJS.interactivity.mouse.click_pos_x, + dy_mouse = p.y - pJS.interactivity.mouse.click_pos_y, + dist_mouse = Math.sqrt(dx_mouse*dx_mouse + dy_mouse*dy_mouse), + time_spent = (new Date().getTime() - pJS.interactivity.mouse.click_time)/1000; + + if(time_spent > pJS.interactivity.modes.bubble.duration){ + pJS.tmp.bubble_duration_end = true; + } + + if(time_spent > pJS.interactivity.modes.bubble.duration*2){ + pJS.tmp.bubble_clicking = false; + pJS.tmp.bubble_duration_end = false; + } + } + + + function process(bubble_param, particles_param, p_obj_bubble, p_obj, id){ + + if(bubble_param != particles_param){ + + if(!pJS.tmp.bubble_duration_end){ + if(dist_mouse <= pJS.interactivity.modes.bubble.distance){ + if(p_obj_bubble != undefined) var obj = p_obj_bubble; + else var obj = p_obj; + if(obj != bubble_param){ + var value = p_obj - (time_spent * (p_obj - bubble_param) / pJS.interactivity.modes.bubble.duration); + if(id == 'size') p.radius_bubble = value; + if(id == 'opacity') p.opacity_bubble = value; + } + }else{ + if(id == 'size') p.radius_bubble = undefined; + if(id == 'opacity') p.opacity_bubble = undefined; + } + }else{ + if(p_obj_bubble != undefined){ + var value_tmp = p_obj - (time_spent * (p_obj - bubble_param) / pJS.interactivity.modes.bubble.duration), + dif = bubble_param - value_tmp; + value = bubble_param + dif; + if(id == 'size') p.radius_bubble = value; + if(id == 'opacity') p.opacity_bubble = value; + } + } + + } + + } + + if(pJS.tmp.bubble_clicking){ + /* size */ + process(pJS.interactivity.modes.bubble.size, pJS.particles.size.value, p.radius_bubble, p.radius, 'size'); + /* opacity */ + process(pJS.interactivity.modes.bubble.opacity, pJS.particles.opacity.value, p.opacity_bubble, p.opacity, 'opacity'); + } + + } + + }; + + + pJS.fn.modes.repulseParticle = function(p){ + + if(pJS.interactivity.events.onhover.enable && isInArray('repulse', pJS.interactivity.events.onhover.mode) && pJS.interactivity.status == 'mousemove') { + + var dx_mouse = p.x - pJS.interactivity.mouse.pos_x, + dy_mouse = p.y - pJS.interactivity.mouse.pos_y, + dist_mouse = Math.sqrt(dx_mouse*dx_mouse + dy_mouse*dy_mouse); + + var normVec = {x: dx_mouse/dist_mouse, y: dy_mouse/dist_mouse}, + repulseRadius = pJS.interactivity.modes.repulse.distance, + velocity = 100, + repulseFactor = clamp((1/repulseRadius)*(-1*Math.pow(dist_mouse/repulseRadius,2)+1)*repulseRadius*velocity, 0, 50); + + var pos = { + x: p.x + normVec.x * repulseFactor, + y: p.y + normVec.y * repulseFactor + } + + if(pJS.particles.move.out_mode == 'bounce'){ + if(pos.x - p.radius > 0 && pos.x + p.radius < pJS.canvas.w) p.x = pos.x; + if(pos.y - p.radius > 0 && pos.y + p.radius < pJS.canvas.h) p.y = pos.y; + }else{ + p.x = pos.x; + p.y = pos.y; + } + + } + + + else if(pJS.interactivity.events.onclick.enable && isInArray('repulse', pJS.interactivity.events.onclick.mode)) { + + if(!pJS.tmp.repulse_finish){ + pJS.tmp.repulse_count++; + if(pJS.tmp.repulse_count == pJS.particles.array.length){ + pJS.tmp.repulse_finish = true; + } + } + + if(pJS.tmp.repulse_clicking){ + + var repulseRadius = Math.pow(pJS.interactivity.modes.repulse.distance/6, 3); + + var dx = pJS.interactivity.mouse.click_pos_x - p.x, + dy = pJS.interactivity.mouse.click_pos_y - p.y, + d = dx*dx + dy*dy; + + var force = -repulseRadius / d * 1; + + function process(){ + + var f = Math.atan2(dy,dx); + p.vx = force * Math.cos(f); + p.vy = force * Math.sin(f); + + if(pJS.particles.move.out_mode == 'bounce'){ + var pos = { + x: p.x + p.vx, + y: p.y + p.vy + } + if (pos.x + p.radius > pJS.canvas.w) p.vx = -p.vx; + else if (pos.x - p.radius < 0) p.vx = -p.vx; + if (pos.y + p.radius > pJS.canvas.h) p.vy = -p.vy; + else if (pos.y - p.radius < 0) p.vy = -p.vy; + } + + } + + // default + if(d <= repulseRadius){ + process(); + } + + // bang - slow motion mode + // if(!pJS.tmp.repulse_finish){ + // if(d <= repulseRadius){ + // process(); + // } + // }else{ + // process(); + // } + + + }else{ + + if(pJS.tmp.repulse_clicking == false){ + + p.vx = p.vx_i; + p.vy = p.vy_i; + + } + + } + + } + + } + + + pJS.fn.modes.grabParticle = function(p){ + + if(pJS.interactivity.events.onhover.enable && pJS.interactivity.status == 'mousemove'){ + + var dx_mouse = p.x - pJS.interactivity.mouse.pos_x, + dy_mouse = p.y - pJS.interactivity.mouse.pos_y, + dist_mouse = Math.sqrt(dx_mouse*dx_mouse + dy_mouse*dy_mouse); + + /* draw a line between the cursor and the particle if the distance between them is under the config distance */ + if(dist_mouse <= pJS.interactivity.modes.grab.distance){ + + var opacity_line = pJS.interactivity.modes.grab.line_linked.opacity - (dist_mouse / (1/pJS.interactivity.modes.grab.line_linked.opacity)) / pJS.interactivity.modes.grab.distance; + + if(opacity_line > 0){ + + /* style */ + var color_line = pJS.particles.line_linked.color_rgb_line; + pJS.canvas.ctx.strokeStyle = 'rgba('+color_line.r+','+color_line.g+','+color_line.b+','+opacity_line+')'; + pJS.canvas.ctx.lineWidth = pJS.particles.line_linked.width; + //pJS.canvas.ctx.lineCap = 'round'; /* performance issue */ + + /* path */ + pJS.canvas.ctx.beginPath(); + pJS.canvas.ctx.moveTo(p.x, p.y); + pJS.canvas.ctx.lineTo(pJS.interactivity.mouse.pos_x, pJS.interactivity.mouse.pos_y); + pJS.canvas.ctx.stroke(); + pJS.canvas.ctx.closePath(); + + } + + } + + } + + }; + + + + /* ---------- pJS functions - vendors ------------ */ + + pJS.fn.vendors.eventsListeners = function(){ + + /* events target element */ + if(pJS.interactivity.detect_on == 'window'){ + pJS.interactivity.el = window; + }else{ + pJS.interactivity.el = pJS.canvas.el; + } + + + /* detect mouse pos - on hover / click event */ + if(pJS.interactivity.events.onhover.enable || pJS.interactivity.events.onclick.enable){ + + /* el on mousemove */ + pJS.interactivity.el.addEventListener('mousemove', function(e){ + + if(pJS.interactivity.el == window){ + var pos_x = e.clientX, + pos_y = e.clientY; + } + else{ + var pos_x = e.offsetX || e.clientX, + pos_y = e.offsetY || e.clientY; + } + + pJS.interactivity.mouse.pos_x = pos_x; + pJS.interactivity.mouse.pos_y = pos_y; + + if(pJS.tmp.retina){ + pJS.interactivity.mouse.pos_x *= pJS.canvas.pxratio; + pJS.interactivity.mouse.pos_y *= pJS.canvas.pxratio; + } + + pJS.interactivity.status = 'mousemove'; + + }); + + /* el on onmouseleave */ + pJS.interactivity.el.addEventListener('mouseleave', function(e){ + + pJS.interactivity.mouse.pos_x = null; + pJS.interactivity.mouse.pos_y = null; + pJS.interactivity.status = 'mouseleave'; + + }); + + } + + /* on click event */ + if(pJS.interactivity.events.onclick.enable){ + + pJS.interactivity.el.addEventListener('click', function(){ + + pJS.interactivity.mouse.click_pos_x = pJS.interactivity.mouse.pos_x; + pJS.interactivity.mouse.click_pos_y = pJS.interactivity.mouse.pos_y; + pJS.interactivity.mouse.click_time = new Date().getTime(); + + if(pJS.interactivity.events.onclick.enable){ + + switch(pJS.interactivity.events.onclick.mode){ + + case 'push': + if(pJS.particles.move.enable){ + pJS.fn.modes.pushParticles(pJS.interactivity.modes.push.particles_nb, pJS.interactivity.mouse); + }else{ + if(pJS.interactivity.modes.push.particles_nb == 1){ + pJS.fn.modes.pushParticles(pJS.interactivity.modes.push.particles_nb, pJS.interactivity.mouse); + } + else if(pJS.interactivity.modes.push.particles_nb > 1){ + pJS.fn.modes.pushParticles(pJS.interactivity.modes.push.particles_nb); + } + } + break; + + case 'remove': + pJS.fn.modes.removeParticles(pJS.interactivity.modes.remove.particles_nb); + break; + + case 'bubble': + pJS.tmp.bubble_clicking = true; + break; + + case 'repulse': + pJS.tmp.repulse_clicking = true; + pJS.tmp.repulse_count = 0; + pJS.tmp.repulse_finish = false; + setTimeout(function(){ + pJS.tmp.repulse_clicking = false; + }, pJS.interactivity.modes.repulse.duration*1000) + break; + + } + + } + + }); + + } + + + }; + + pJS.fn.vendors.densityAutoParticles = function(){ + + if(pJS.particles.number.density.enable){ + + /* calc area */ + var area = pJS.canvas.el.width * pJS.canvas.el.height / 1000; + if(pJS.tmp.retina){ + area = area/(pJS.canvas.pxratio*2); + } + + /* calc number of particles based on density area */ + var nb_particles = area * pJS.particles.number.value / pJS.particles.number.density.value_area; + + /* add or remove X particles */ + var missing_particles = pJS.particles.array.length - nb_particles; + if(missing_particles < 0) pJS.fn.modes.pushParticles(Math.abs(missing_particles)); + else pJS.fn.modes.removeParticles(missing_particles); + + } + + }; + + + pJS.fn.vendors.checkOverlap = function(p1, position){ + for(var i = 0; i < pJS.particles.array.length; i++){ + var p2 = pJS.particles.array[i]; + + var dx = p1.x - p2.x, + dy = p1.y - p2.y, + dist = Math.sqrt(dx*dx + dy*dy); + + if(dist <= p1.radius + p2.radius){ + p1.x = position ? position.x : Math.random() * pJS.canvas.w; + p1.y = position ? position.y : Math.random() * pJS.canvas.h; + pJS.fn.vendors.checkOverlap(p1); + } + } + }; + + + pJS.fn.vendors.createSvgImg = function(p){ + + /* set color to svg element */ + var svgXml = pJS.tmp.source_svg, + rgbHex = /#([0-9A-F]{3,6})/gi, + coloredSvgXml = svgXml.replace(rgbHex, function (m, r, g, b) { + if(p.color.rgb){ + var color_value = 'rgba('+p.color.rgb.r+','+p.color.rgb.g+','+p.color.rgb.b+','+p.opacity+')'; + }else{ + var color_value = 'hsla('+p.color.hsl.h+','+p.color.hsl.s+'%,'+p.color.hsl.l+'%,'+p.opacity+')'; + } + return color_value; + }); + + /* prepare to create img with colored svg */ + var svg = new Blob([coloredSvgXml], {type: 'image/svg+xml;charset=utf-8'}), + DOMURL = window.URL || window.webkitURL || window, + url = DOMURL.createObjectURL(svg); + + /* create particle img obj */ + var img = new Image(); + img.addEventListener('load', function(){ + p.img.obj = img; + p.img.loaded = true; + DOMURL.revokeObjectURL(url); + pJS.tmp.count_svg++; + }); + img.src = url; + + }; + + + pJS.fn.vendors.destroypJS = function(){ + cancelAnimationFrame(pJS.fn.drawAnimFrame); + canvas_el.remove(); + pJSDom = null; + }; + + + pJS.fn.vendors.drawShape = function(c, startX, startY, sideLength, sideCountNumerator, sideCountDenominator){ + + // By Programming Thomas - https://programmingthomas.wordpress.com/2013/04/03/n-sided-shapes/ + var sideCount = sideCountNumerator * sideCountDenominator; + var decimalSides = sideCountNumerator / sideCountDenominator; + var interiorAngleDegrees = (180 * (decimalSides - 2)) / decimalSides; + var interiorAngle = Math.PI - Math.PI * interiorAngleDegrees / 180; // convert to radians + c.save(); + c.beginPath(); + c.translate(startX, startY); + c.moveTo(0,0); + for (var i = 0; i < sideCount; i++) { + c.lineTo(sideLength,0); + c.translate(sideLength,0); + c.rotate(interiorAngle); + } + //c.stroke(); + c.fill(); + c.restore(); + + }; + + pJS.fn.vendors.exportImg = function(){ + window.open(pJS.canvas.el.toDataURL('image/png'), '_blank'); + }; + + + pJS.fn.vendors.loadImg = function(type){ + + pJS.tmp.img_error = undefined; + + if(pJS.particles.shape.image.src != ''){ + + if(type == 'svg'){ + + var xhr = new XMLHttpRequest(); + xhr.open('GET', pJS.particles.shape.image.src); + xhr.onreadystatechange = function (data) { + if(xhr.readyState == 4){ + if(xhr.status == 200){ + pJS.tmp.source_svg = data.currentTarget.response; + pJS.fn.vendors.checkBeforeDraw(); + }else{ + console.log('Error pJS - Image not found'); + pJS.tmp.img_error = true; + } + } + } + xhr.send(); + + }else{ + + var img = new Image(); + img.addEventListener('load', function(){ + pJS.tmp.img_obj = img; + pJS.fn.vendors.checkBeforeDraw(); + }); + img.src = pJS.particles.shape.image.src; + + } + + }else{ + console.log('Error pJS - No image.src'); + pJS.tmp.img_error = true; + } + + }; + + + pJS.fn.vendors.draw = function(){ + + if(pJS.particles.shape.type == 'image'){ + + if(pJS.tmp.img_type == 'svg'){ + + if(pJS.tmp.count_svg >= pJS.particles.number.value){ + pJS.fn.particlesDraw(); + if(!pJS.particles.move.enable) cancelRequestAnimFrame(pJS.fn.drawAnimFrame); + else pJS.fn.drawAnimFrame = requestAnimFrame(pJS.fn.vendors.draw); + }else{ + //console.log('still loading...'); + if(!pJS.tmp.img_error) pJS.fn.drawAnimFrame = requestAnimFrame(pJS.fn.vendors.draw); + } + + }else{ + + if(pJS.tmp.img_obj != undefined){ + pJS.fn.particlesDraw(); + if(!pJS.particles.move.enable) cancelRequestAnimFrame(pJS.fn.drawAnimFrame); + else pJS.fn.drawAnimFrame = requestAnimFrame(pJS.fn.vendors.draw); + }else{ + if(!pJS.tmp.img_error) pJS.fn.drawAnimFrame = requestAnimFrame(pJS.fn.vendors.draw); + } + + } + + }else{ + pJS.fn.particlesDraw(); + if(!pJS.particles.move.enable) cancelRequestAnimFrame(pJS.fn.drawAnimFrame); + else pJS.fn.drawAnimFrame = requestAnimFrame(pJS.fn.vendors.draw); + } + + }; + + + pJS.fn.vendors.checkBeforeDraw = function(){ + + // if shape is image + if(pJS.particles.shape.type == 'image'){ + + if(pJS.tmp.img_type == 'svg' && pJS.tmp.source_svg == undefined){ + pJS.tmp.checkAnimFrame = requestAnimFrame(check); + }else{ + //console.log('images loaded! cancel check'); + cancelRequestAnimFrame(pJS.tmp.checkAnimFrame); + if(!pJS.tmp.img_error){ + pJS.fn.vendors.init(); + pJS.fn.vendors.draw(); + } + + } + + }else{ + pJS.fn.vendors.init(); + pJS.fn.vendors.draw(); + } + + }; + + + pJS.fn.vendors.init = function(){ + + /* init canvas + particles */ + pJS.fn.retinaInit(); + pJS.fn.canvasInit(); + pJS.fn.canvasSize(); + pJS.fn.canvasPaint(); + pJS.fn.particlesCreate(); + pJS.fn.vendors.densityAutoParticles(); + + /* particles.line_linked - convert hex colors to rgb */ + pJS.particles.line_linked.color_rgb_line = hexToRgb(pJS.particles.line_linked.color); + + }; + + + pJS.fn.vendors.start = function(){ + + if(isInArray('image', pJS.particles.shape.type)){ + pJS.tmp.img_type = pJS.particles.shape.image.src.substr(pJS.particles.shape.image.src.length - 3); + pJS.fn.vendors.loadImg(pJS.tmp.img_type); + }else{ + pJS.fn.vendors.checkBeforeDraw(); + } + + }; + + + + + /* ---------- pJS - start ------------ */ + + + pJS.fn.vendors.eventsListeners(); + + pJS.fn.vendors.start(); + + + +}; + +/* ---------- global functions - vendors ------------ */ + +Object.deepExtend = function(destination, source) { + for (var property in source) { + if (source[property] && source[property].constructor && + source[property].constructor === Object) { + destination[property] = destination[property] || {}; + arguments.callee(destination[property], source[property]); + } else { + destination[property] = source[property]; + } + } + return destination; +}; + +window.requestAnimFrame = (function(){ + return window.requestAnimationFrame || + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.oRequestAnimationFrame || + window.msRequestAnimationFrame || + function(callback){ + window.setTimeout(callback, 1000 / 60); + }; +})(); + +window.cancelRequestAnimFrame = ( function() { + return window.cancelAnimationFrame || + window.webkitCancelRequestAnimationFrame || + window.mozCancelRequestAnimationFrame || + window.oCancelRequestAnimationFrame || + window.msCancelRequestAnimationFrame || + clearTimeout +} )(); + +function hexToRgb(hex){ + // By Tim Down - http://stackoverflow.com/a/5624139/3493650 + // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF") + var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; + hex = hex.replace(shorthandRegex, function(m, r, g, b) { + return r + r + g + g + b + b; + }); + var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); + return result ? { + r: parseInt(result[1], 16), + g: parseInt(result[2], 16), + b: parseInt(result[3], 16) + } : null; +}; + +function clamp(number, min, max) { + return Math.min(Math.max(number, min), max); +}; + +function isInArray(value, array) { + return array.indexOf(value) > -1; +} + + +/* ---------- particles.js functions - start ------------ */ + +window.pJSDom = []; + +window.particlesJS = function(tag_id, params){ + + //console.log(params); + + /* no string id? so it's object params, and set the id with default id */ + if(typeof(tag_id) != 'string'){ + params = tag_id; + tag_id = 'particles-js'; + } + + /* no id? set the id to default id */ + if(!tag_id){ + tag_id = 'particles-js'; + } + + /* pJS elements */ + var pJS_tag = document.getElementById(tag_id), + pJS_canvas_class = 'particles-js-canvas-el', + exist_canvas = pJS_tag.getElementsByClassName(pJS_canvas_class); + + /* remove canvas if exists into the pJS target tag */ + if(exist_canvas.length){ + while(exist_canvas.length > 0){ + pJS_tag.removeChild(exist_canvas[0]); + } + } + + /* create canvas element */ + var canvas_el = document.createElement('canvas'); + canvas_el.className = pJS_canvas_class; + + /* set size canvas */ + canvas_el.style.width = "100%"; + canvas_el.style.height = "100%"; + + /* append canvas */ + var canvas = document.getElementById(tag_id).appendChild(canvas_el); + + /* launch particle.js */ + if(canvas != null){ + pJSDom.push(new pJS(tag_id, params)); + } + +}; + +window.particlesJS.load = function(tag_id, path_config_json, callback){ + + /* load json config */ + var xhr = new XMLHttpRequest(); + xhr.open('GET', path_config_json); + xhr.onreadystatechange = function (data) { + if(xhr.readyState == 4){ + if(xhr.status == 200){ + var params = JSON.parse(data.currentTarget.response); + window.particlesJS(tag_id, params); + if(callback) callback(); + }else{ + console.log('Error pJS - XMLHttpRequest status: '+xhr.status); + console.log('Error pJS - File config not found'); + } + } + }; + xhr.send(); + +}; diff --git a/www/source/layouts/_footer.slim b/www/source/layouts/_footer.slim index 1d64b5aa7..9052730d0 100644 --- a/www/source/layouts/_footer.slim +++ b/www/source/layouts/_footer.slim @@ -1,22 +1,28 @@ -footer#main-footer - .container - .row - .columns.large-3.medium-4 - .footer--logos - a.footer--logo.chef href="http://www.chef.io" - img src="/images/chef-logo.png" - a.footer--logo.inspec href="/" - img src="/images/inspec-by-chef-logo.png" - .columns.large-9.medium-8.medium-text-right.text-center - ul.footer--links - li - a.footer--link href="/legal/licensing" Licensing - li - a.footer--link href="/legal/terms-and-conditions" Terms & Conditions - ul.footer--links - li - a.footer--link href="/legal/trademark-policy" Trademark Policy - li - a.footer--link href="/legal/privacy-policy" Privacy Policy - p - small © Chef Software 2016 \ No newline at end of file +footer#main-footer.dark-bg + #dlmsg.strict-center + img#hex src="/images/hexagon.svg" / + h3.t-white.margin-top-xs See how it works in less than 10 minutes! + .row.margin-top-xs + a.btn.t-white.try-demo href="#" Try the Demo + a.btn.t-white href="https://downloads.chef.io/inspec" + i.fa.fa-cloud-download + span Download + .row + .footer--logos + a.footer--logo.inspec href="/" + img src="/images/inspec-by-chef-logo.png" + a.footer--logo.chef href="http://www.chef.io" + img src="/images/chef-logo.png" + + ul.footer--links + li + a.footer--link href="/legal/licensing" Licensing + li + a.footer--link href="/legal/terms-and-conditions" Terms & Conditions + li + a.footer--link href="/legal/trademark-policy" Trademark Policy + li + a.footer--link href="/legal/privacy-policy" Privacy Policy + + p.strict-center + small © Chef Software 2016 diff --git a/www/source/layouts/_nav.slim b/www/source/layouts/_nav.slim index 8da700a09..7b06db7f9 100644 --- a/www/source/layouts/_nav.slim +++ b/www/source/layouts/_nav.slim @@ -1,46 +1,46 @@ nav#main-nav class="sidebar-layout-#{locals[:sidebar_layout]}" - a.main-nav--logo href="/" - img src="/images/inspec-by-chef-logo.svg" onerror="this.src='/images/inspec-by-chef-logo.png'" = partial "layouts/svg/nav-icon.svg" ul.main-nav--links li.main-nav--link-ctas - a.button.transparent.try-demo href="#" Try the Demo - a.button.secondary href="https://downloads.chef.io/inspec" Download + a.button href="/" + span.main-nav--link-text Overview + a href="/tutorials" + span.main-nav--link-text Tutorials + a href="/docs" + span.main-nav--link-text Docs + a href="/community" + span.main-nav--link-text Community + a href="https://downloads.chef.io/inspec" + span.main-nav--link-text Downloads + a href="https://github.com/chef/inspec" + i.main-nav--link-icon.fa.fa-github + span.main-nav--link-text Github Project + a href="https://github.com/chef/inspec/blob/master/CONTRIBUTING.md" + i.main-nav--link-icon.fa.fa-code-fork + span.main-nav--link-text Contribute + a.btn.try-demo href="#" Try the Demo + a.btn href="https://downloads.chef.io/inspec" Download + - if locals[:sidebar_layout] == 'docs' li.main-nav--sidebar = partial "layouts/sidebar" - else - li.main-nav--link - a href="/" - i.main-nav--link-icon.fa.fa-home - span.main-nav--link-text Overview - li.main-nav--link - a href="/tutorials" - i.main-nav--link-icon.fa.fa-flask - span.main-nav--link-text Tutorials - li.main-nav--link - a href="/docs" - i.main-nav--link-icon.fa.fa-file-text-o - span.main-nav--link-text Docs - li.main-nav--link - a href="/community" - i.main-nav--link-icon.fa.fa-group - span.main-nav--link-text Community - li.main-nav--link - a href="https://downloads.chef.io/inspec" - i.main-nav--link-icon.fa.fa-download - span.main-nav--link-text Downloads - li.main-nav--link - a href="https://github.com/chef/inspec" - i.main-nav--link-icon.fa.fa-github - span.main-nav--link-text Github Project - li.main-nav--link - a href="https://github.com/chef/inspec/blob/master/CONTRIBUTING.md" - i.main-nav--link-icon.fa.fa-code-fork - span.main-nav--link-text Contribute nav#main-nav-ctas - a.button.transparent.try-demo href="#" Try the Demo - a.button.secondary href="https://downloads.chef.io/inspec" Download + a.main-nav--logo href="/" + img src="/images/inspec-by-chef-logo.svg" onerror="this.src='/images/inspec-by-chef-logo.png'" + a href="/tutorials" + span.main-nav--link-text Tutorials + a href="/docs" + span.main-nav--link-text Docs + a href="/community" + span.main-nav--link-text Community + a href="https://github.com/chef/inspec" + i.fa.fa-github-alt + span.main-nav--link-text Github + a.btn.try-demo href="#" Try the Demo + a.btn href="https://downloads.chef.io/inspec" + i.fa.fa-cloud-download + span.main-nav--link-text Download diff --git a/www/source/layouts/layout.slim b/www/source/layouts/layout.slim index 10e07a9b9..ae1374a49 100644 --- a/www/source/layouts/layout.slim +++ b/www/source/layouts/layout.slim @@ -10,7 +10,7 @@ html title = current_page.data.title || "InSpec" - link href='//allfont.net/allfont.css?fonts=open-sans-light' rel='stylesheet' type='text/css' + link href='//fonts.googleapis.com/css?family=Roboto:300,400' rel='stylesheet' type='text/css' link href='//allfont.net/allfont.css?fonts=source-sans-pro' rel='stylesheet' type='text/css' link rel='stylesheet' type='text/css' href='css/inspec_tutorial.css' @@ -38,6 +38,16 @@ html javascript: $(window).enllax(); + javascript: + $(window).scroll(function() { + var scroll = $(window).scrollTop(); + var objectSelect = $('#icon-trigger'); + var objectPosition = objectSelect.offset().top; + if (scroll > objectPosition) { + $('hr').addClass('stretch') + } + }); + javascript: $(document).foundation(); $('.try-demo').click(function(event){ @@ -50,6 +60,7 @@ html }) }); + javascript: !function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","page","once","off","on"];analytics.factory=function(t){return function(){var e=Array.prototype.slice.call(arguments);e.unshift(t);analytics.push(e);return analytics}};for(var t=0;tGrant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + li + p Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. - li - p Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + li + p Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. - li - p Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + li + p Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: - ol.lower-alpha - li You must give any other recipients of the Work or Derivative Works a copy of this License; and - li You must cause any modified files to carry prominent notices stating that You changed the files; and - li You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and - li If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + ol.lower-alpha + li You must give any other recipients of the Work or Derivative Works a copy of this License; and + li You must cause any modified files to carry prominent notices stating that You changed the files; and + li You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and + li If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. - p You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. - 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + p You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. - li - p Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + li + p Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. - li - p Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + li + p Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. - li - p Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + li + p Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. - li - p Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + li + p Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. -p END OF TERMS AND CONDITIONS + p END OF TERMS AND CONDITIONS diff --git a/www/source/legal/privacy-policy.html.slim b/www/source/legal/privacy-policy.html.slim index 10aa2c7da..d0fc99243 100644 --- a/www/source/legal/privacy-policy.html.slim +++ b/www/source/legal/privacy-policy.html.slim @@ -2,9 +2,9 @@ title: InSpec - Privacy Policy --- -.row +.row.margin-both-offset .columns.medium-12 - h1.no-margin Chef Privacy Policy + h2.no-margin Chef Privacy Policy p This privacy policy ("Policy") explains how Personal Information is collected, used, and disclosed by Chef Software, Inc. ("Chef, "we" or "us") with respect to your use of the Web sites operated by Chef that link to this Policy, including without limitation www.Chef.io (collectively the "Sites") and any services provided to you by Chef (the "Services"). We reserve the right to change the provisions of this Policy at any time. We will alert you that changes have been made by indicating on the Policy the date it was last updated. We encourage you to review this Policy from time to time to make sure that you understand how any Personal Information you provide will be used. p Please read this policy carefully to understand our policies and practices regarding your information and how we will treat it. If you do not agree with our policies and practices, your choice is not to use our Sites or Services. By accessing or using the Sites or Services, you agree to this privacy policy. Your continued use of the Sites or Services after we make changes is deemed to be acceptance of those changes, so please check the policy periodically for updates. h4 WHAT IS PERSONAL INFORMATION? diff --git a/www/source/legal/terms-and-conditions.html.slim b/www/source/legal/terms-and-conditions.html.slim index 8b3e6c9e6..74d894fd8 100644 --- a/www/source/legal/terms-and-conditions.html.slim +++ b/www/source/legal/terms-and-conditions.html.slim @@ -2,9 +2,9 @@ title: Terms and Conditions of Use --- -.row +.row.margin-both-offset .columns.medium-12 - h1.no-margin Terms and Conditions of Use + h2.no-margin Terms and Conditions of Use p strong diff --git a/www/source/legal/trademark-policy.html.slim b/www/source/legal/trademark-policy.html.slim index 09c1e9f37..37d527a1e 100644 --- a/www/source/legal/trademark-policy.html.slim +++ b/www/source/legal/trademark-policy.html.slim @@ -1,84 +1,85 @@ --- title: Inspec - Trademark Policy --- +.row.margin-both-offset -h1 Chef Trademark Policy -p - small June 16, 2016 + h2 Chef Trademark Policy + p + small June 16, 2016 -h4 - u INTRODUCTION -p This document outlines the policy of Chef Software Inc. ("Chef") regarding the use of Chef trademarks and/or logos, including without limitation Chef's Open Source Projects, such as for example, Habitat, InSpec and Server ("Chef Marks"). Any use of any Chef Mark must be in accordance with this policy or a separate license agreement. Any use that does not comply with this policy or does not have written authorization from Chef is not authorized. Any goodwill generated by the use of any Chef Marks will be for the benefit of Chef. This Trademark Policy ("Policy") attempts to balance two competing interests: Chef's need to ensure that the Chef Marks remain reliable indicators of quality, source, and security; and Chef's desire to permit community members, contributors, software users and distributors, and others to discuss the Chef products and to accurately describe their affiliation with Chef. Striking a proper balance is a complex situation that many organizations - in particular those whose products are distributed electronically - wrestle with every day and Chef has attempted to balance it here. Chef protects its Chef Marks on behalf and for the benefit of the entire community. The law obligates trademark owners to police their marks and prevent the use of confusingly similar names by third parties. If you have questions about this Policy, please contact the Chef marketing team at marketing@chef.io.
 -p Underlying this Policy is the general law of trademarks. Trademarks exist to help consumers identify, and organizations publicize, the source of products. Someone's trust in the Chef name and products is crucial to us. Particularly in connection with intangible products like software, trust is all consumers have to decide on which product to choose. Chef also caretakes and curates the trust of the Chef community. This Policy seeks to protect both the public's and the Chef community's trust in the Chef Marks.
 -p In addition, Chef may receive reports about websites or companies using the Chef Marks to promote other products and services, or using modified versions of the Chef Marks. The problem with these activities is that they may be deceptive, harm users, cause consumer confusion, or jeopardize the identity and meaning of the Chef Marks. Such cases range from good intentions but improper use of the trademarks, to people intentionally trading on the Chef brand for their own benefit and/or to distribute modified versions of the product, to a clear intent to deceive, manipulate and steal from users in a highly organized and syndicated fashion. When Chef receives reports of such activities, or identifies problematic activities, Chef analyzes the reports and treats each case individually based on the intent and severity of the matter.
 In creating this Policy, Chef seeks to clarify legitimate uses of the Chef Marks. Although this Policy is composed of a number of specific examples, most reflect the fundamental requirement that your use of the Chef Marks be non-confusing and non-disparaging. "Non-confusing" means people should always know with whom they are dealing and where the software originates. Websites, software and other services that are not officially maintained or supported by Chef should not imply, either directly or by omission, that they are. These basic requirements can serve as a guide as you work your way through the Policy.
 -p This Policy, prepared by Chef, sets out rules for proper use of the Chef Marks. Some, but not all, Chef Marks include the following: -ul - li Chef and Chef Logo - li Inspec and Inspec Logo - li Compliance at Velocity - li CODE CAN - li RULE THE CLOUD - li POWERED BY CHEF -p Chef may update its Chef Marks from time to time and without prior notice. If you ever have any questions about a Chef Mark, please contact Chef at marketing@chef.io.
 Approved Chef logos can be downloaded here: http://style.chef.io/branding/ -p This Policy applies to all uses of the Chef Marks, in text and logo form, whether or not identified above. -h4 - u OBJECTIVE AND SCOPE OF THE CHEF TRADEMARK POLICY -p The objective of this Policy is to ensure that the Chef Marks remain reliable indicators of source and quality and that they are protected from inappropriate and unauthorized use. This Policy explains when and how you may use the Chef Marks without written authorization and, conversely, when written permission from Chef is required. Chef reserves the right to review all usage of the Chef Marks and to terminate use of the Chef Marks by any party for non-compliance with this Policy or written authorization. Chef may change this Policy at its sole discretion at any time effective immediately upon being published at https://www.chef.io/trademark-policy/ . -h4 - u AUTHORIZED USE OF CHEF MARKS -ul - li - u SUMMARY - ul - li AS A GENERAL RULE, THE CHEF MARKS MAY NOT BE USED IN ANY MANNER OTHER THAN EXPRESSLY AUTHORIZED IN A WRITTEN AGREEMENT SIGNED BY A DULY AUTHORIZED CHEF REPRESENTATIVE OR AS EXPRESSLY PERMITTED BY THIS POLICY.
 - li You must use a Chef Mark in accordance with this Policy. To the extent any part of this Policy conflicts or is inconsistent with any part of a written agreement between you and Chef, the written agreement shall control. No other rights of any kind are granted hereunder by implication or otherwise.

You must obtain written permission from Chef to use the Chef Marks for any use, including but not limited to; (i) merchandising purposes (e.g. T-shirts, mugs); (ii) on or in relation to a software product that includes or is built on top of any Chef product, including Chef's open source projects; or (iii) in an attention-getting or branding manner. Without the express prior written consent of Chef, no Chef Marks may be used in a manner that implies an affiliation with, approval by, endorsement of or sponsorship by Chef. - li - u GENERAL GUIDELINES - ul - li You may use of the Chef Marks, without a license, provided such use complies with the following requirements: (i) the Chef Mark is used only to refer to the Chef project and/or technology; (ii) the Chef Mark is not used as part of your product, brand, domain, URL, or service name; (iii) the Chef Mark appears less prominent than your company or product name; (iv) the reference to Chef does not create a sense of endorsement, sponsorship, or ownership by Chef; and/or (v) Your use of the Chef Mark is necessary to fully describe your services or products and is limited to as much of the Chef Mark as is necessary for such identification ("Nominative Use"). ALL OTHER USES OF THE CHEF MARK, INCLUDING LOGOS, REQUIRE A WRITTEN LICENSE AGREEMENT. - li - u SPECIFIC USE CASES - ul - li USE WITH OPEN SOURCE SOFTWARE: We release open source code under the Apache 2.0 license, which permits third parties to copy and redistribute the underlying software under the terms of the license. However, the Apache 2.0 license does not provide any license or right to use any of the Chef Marks. You may redistribute the applicable Chef open source software under the terms of the Apache 2.0 license, but You may not use the Chef Marks in doing so without express written permission from Chef or as expressly permitted in this Policy. - li PUBLICATIONS AND PRESENTATIONS: Third parties may use the Chef Marks in publications, such as books or magazines, or in connection with the presentations and publications that are displayed to the public (collectively, "Publications"), provided that: (i) such use is referential only: You are simply referring to Chef and its products; (ii) Your name or mark and logo shall appear in a prominent location on the cover or the title page of the Publication and shall be featured with greater prominence than the Chef Mark; (iii) You do not apply to register or register any term comprised or consisting of in whole or in part the Chef Mark, or any confusingly similar mark as trademarks, service marks, corporate names, trade names or domain names, Internet keywords, metatags, or trigger words to lead to a website or other Internet destination; (iv) You do not alter or change any Chef Mark or logo; (v) You comply with this Policy and usage guidelines; (vi) You attribute the Chef Marks with the proper symbol and footnote it on all Publications, webpages, announcements, or anywhere you might use the term. - li TRADEMARK NOTICE SYMBOL: When using the Chef Marks, you must use the appropriate trademark symbol (either ™ or ®) as a notice to third parties of our rights to the Chef Mark. A trademark notice symbol must be used in connection with the first and most prominent usage of a mark (e.g. "Chef™"). A Chef Logo must always appear with the TM notice in every use. - li ATTRIBUTION STATEMENT: You must acknowledge the rights of Chef in the Chef Marks and agree not to register or seek to register any Chef Marks in any country. All uses of Chef Marks must identify the Marks as being trademarks of Chef with our standard trademark attribution statement. The following statement must be used in all materials using the Chef Marks, including but not limited to websites, publications, splash screens, screenshots or in documentation or source code: "The Chef™ Mark and Chef Logo are either registered trademarks/service marks or trademarks/ service marks of Chef, in the United States and other countries and are used with Chef Software Inc.'s permission. We are not affiliated with, endorsed or sponsored by Chef Software Inc." While you may scale the size to suit your needs, you may not modify any of the Chef logos in any other way (such as by changing the design or color or the relative proportions of the elements which comprise the logo). When using Chef Marks, you will never vary the spelling, hyphenation or spacing of the any portion of the marks. You will never use a Chef Mark as a verb or noun or in possessive or plural form. (This is just good form.) - li DOMAIN NAMES AND URLs: You may not use Chef Marks in your own domain names or URLs in a way that would likely to confuse a relevant consumer about the source of software or services provided through your website without written approval from Chef. - li PRODUCTS AND SERVICES RELATED TO CHEF SOFTWARE: If you offer products or services related to Chef Marks, you may use the Chef Marks in describing and advertising your product so long as you don't mislead customers into thinking that either your website, service, or product is a Chef website, service, or product, or that Chef has any direct relationship with your organization. For example: "FooCo Management Dashboard for Chef Inspec" is okay. "FooCo Chef" is not okay, nor is "FooCo Chef Automate Dashboard". In addition, your website may not copy the look and feel of any Chef website. Again, Chef does not want the visitor to your website to be confused with whom she/he is dealing. When in doubt, err on the side of providing more, rather than less, explanation and information. - li MARKS AND MERCHANDISE: You must obtain prior written approval from Chef to use the Chef Marks in any merchandise. In general, permission to use a Chef Mark may be granted for those wishing to create merchandise that promotes Chef and the Chef community. Permission will typically be denied to merchandise that would detract, disparage, or insult Chef or the Chef community. (We hope this comes as no surprise.) - li MODIFICATIONS: There is one additional broad category of things you can't do with the Chef Marks - produce modified versions of them. A modified mark also would raise the possibility of consumer confusion, thus violating Chef trademark rights (remember the overarching requirement that any use of a Chef Mark be non-confusing?). -h4 - u UNAUTHORIZED USE OF THE CHEF MARKS -p Unauthorized use of the Chef Marks or marks that are confusingly similar may constitute an infringement of Chef trademark rights and are strictly prohibited. The following are examples of unauthorized uses of the Chef Marks or company name "Chef Software":
 -ul - li - u Use of Chef Marks in connection with third party marks: - | Use of the Chef Marks in connection with or as part of company names, trademarks or logos is not allowed. Do not hyphenate Chef with your product name to create a new product name. You may not use or register, in whole or in part, Chef, Chef logos or any other Chef trademarks, including Chef -owned graphic symbols, icons or any alteration thereof, as part of your trademark, service mark, company name, trade name, product name or service name. You may not incorporate the Chef Marks into the name or logo of your website, domain name, Internet keywords, metatags, or trigger words to lead to a website or other Internet destination, product, business or service. - li - u Incorporation of all or a portion of a Chef Mark into a domain name: - | You may not register a domain name or use a registered domain name that includes a Chef, or any marks that are phonetically equivalent to or confusingly similar to the Chef Marks.
 - li - u Damaging Use: - | Use of the Chef Marks or any other Chef-owned graphic, symbol or logo in a manner that disparages Chef, the Chef project and community or its technology or damages the brand integrity, including use of the Chef Marks in a manner that is, in the opinion of Chef, offensive, defamatory, illegal or unethical. - li - u Confusingly similar marks: - | You may not use trademarks, logos or other content that is confusingly similar to the Chef Marks, Chef-owned graphics, symbols or any logos ("Chef Brand Assets"). - li - u Variations or abbreviations or combinations with any other marks: - | You may not use variations, foreign language equivalent or abbreviation of the Chef Marks for any purpose. - li - u Endorsement or Sponsorship: - | You may not use Chef Marks to imply approval, sponsorship, endorsement or affiliation of your company, website, products or services by Chef or the Chef project. -p Please note that the preceding examples are illustrative rather than an exhaustive list of types of unauthorized uses of the Chef Marks. All rights not explicitly granted in this Policy are expressly reserved by Chef. -h4 - u QUESTIONS AND REPORTING MISUSE OF THE CHEF MARKS -p If You wish to obtain Chef permission for any uses above or for any other use which is not specifically addressed in this Policy or You became aware of unauthorized use of the Chef Marks, please contact marketing@chef.io. Please note that permission will only be granted under certain conditions and/or subject to You entering into an agreement with Chef to maintain the quality of the products and or services You offer.
 -p Chef reserves the right to revoke the authorization at any time in its sole discretion. If Chef determines that Your use of a Chef Mark does not truthfully and accurately identify the inclusion of the applicable Chef technology or Your use is otherwise unacceptable or detrimental to Chef or outside the scope of this Policy or an applicable license, Chef will revoke the authorization. Upon revocation of the authorization You agree that You will immediately cease all use of the applicable Chef Mark. -h4 - u ACKNOWLEDGEMENT -p - strong Nothing in this Trademark Policy shall be interpreted to allow any third party to claim any association with Chef or to imply any approval or support by Chef for any third party products or services.
 -p - strong You acknowledge and agree that Chef is the sole and exclusive owner of the Chef Marks and agree that You will do nothing inconsistent with such ownership either during the term of such use or afterwards. You agree that you will not acquire any rights in the Chef Marks and that any goodwill generated by your use of the Chef Marks inures solely to the benefit of Chef. You also agree that "Chef" is not descriptive or generic and you agree not to challenge Chef's rights in the Chef Marks, including but not limited to its trademark applications and registrations, on any grounds. You also ensure that Your use of the Chef Marks does not create any confusion as to the source of Your products, services and activities and those of the Chef community or Chef. You agree not to challenge Chef's rights in the Chef Marks, including but not limited to its trademark applications and registrations, on any grounds. -p - strong Thank you for caring about the Chef brand! + h4 + u INTRODUCTION + p This document outlines the policy of Chef Software Inc. ("Chef") regarding the use of Chef trademarks and/or logos, including without limitation Chef's Open Source Projects, such as for example, Habitat, InSpec and Server ("Chef Marks"). Any use of any Chef Mark must be in accordance with this policy or a separate license agreement. Any use that does not comply with this policy or does not have written authorization from Chef is not authorized. Any goodwill generated by the use of any Chef Marks will be for the benefit of Chef. This Trademark Policy ("Policy") attempts to balance two competing interests: Chef's need to ensure that the Chef Marks remain reliable indicators of quality, source, and security; and Chef's desire to permit community members, contributors, software users and distributors, and others to discuss the Chef products and to accurately describe their affiliation with Chef. Striking a proper balance is a complex situation that many organizations - in particular those whose products are distributed electronically - wrestle with every day and Chef has attempted to balance it here. Chef protects its Chef Marks on behalf and for the benefit of the entire community. The law obligates trademark owners to police their marks and prevent the use of confusingly similar names by third parties. If you have questions about this Policy, please contact the Chef marketing team at marketing@chef.io.
 + p Underlying this Policy is the general law of trademarks. Trademarks exist to help consumers identify, and organizations publicize, the source of products. Someone's trust in the Chef name and products is crucial to us. Particularly in connection with intangible products like software, trust is all consumers have to decide on which product to choose. Chef also caretakes and curates the trust of the Chef community. This Policy seeks to protect both the public's and the Chef community's trust in the Chef Marks.
 + p In addition, Chef may receive reports about websites or companies using the Chef Marks to promote other products and services, or using modified versions of the Chef Marks. The problem with these activities is that they may be deceptive, harm users, cause consumer confusion, or jeopardize the identity and meaning of the Chef Marks. Such cases range from good intentions but improper use of the trademarks, to people intentionally trading on the Chef brand for their own benefit and/or to distribute modified versions of the product, to a clear intent to deceive, manipulate and steal from users in a highly organized and syndicated fashion. When Chef receives reports of such activities, or identifies problematic activities, Chef analyzes the reports and treats each case individually based on the intent and severity of the matter.
 In creating this Policy, Chef seeks to clarify legitimate uses of the Chef Marks. Although this Policy is composed of a number of specific examples, most reflect the fundamental requirement that your use of the Chef Marks be non-confusing and non-disparaging. "Non-confusing" means people should always know with whom they are dealing and where the software originates. Websites, software and other services that are not officially maintained or supported by Chef should not imply, either directly or by omission, that they are. These basic requirements can serve as a guide as you work your way through the Policy.
 + p This Policy, prepared by Chef, sets out rules for proper use of the Chef Marks. Some, but not all, Chef Marks include the following: + ul + li Chef and Chef Logo + li Inspec and Inspec Logo + li Compliance at Velocity + li CODE CAN + li RULE THE CLOUD + li POWERED BY CHEF + p Chef may update its Chef Marks from time to time and without prior notice. If you ever have any questions about a Chef Mark, please contact Chef at marketing@chef.io.
 Approved Chef logos can be downloaded here: http://style.chef.io/branding/ + p This Policy applies to all uses of the Chef Marks, in text and logo form, whether or not identified above. + h4 + u OBJECTIVE AND SCOPE OF THE CHEF TRADEMARK POLICY + p The objective of this Policy is to ensure that the Chef Marks remain reliable indicators of source and quality and that they are protected from inappropriate and unauthorized use. This Policy explains when and how you may use the Chef Marks without written authorization and, conversely, when written permission from Chef is required. Chef reserves the right to review all usage of the Chef Marks and to terminate use of the Chef Marks by any party for non-compliance with this Policy or written authorization. Chef may change this Policy at its sole discretion at any time effective immediately upon being published at https://www.chef.io/trademark-policy/ . + h4 + u AUTHORIZED USE OF CHEF MARKS + ul + li + u SUMMARY + ul + li AS A GENERAL RULE, THE CHEF MARKS MAY NOT BE USED IN ANY MANNER OTHER THAN EXPRESSLY AUTHORIZED IN A WRITTEN AGREEMENT SIGNED BY A DULY AUTHORIZED CHEF REPRESENTATIVE OR AS EXPRESSLY PERMITTED BY THIS POLICY.
 + li You must use a Chef Mark in accordance with this Policy. To the extent any part of this Policy conflicts or is inconsistent with any part of a written agreement between you and Chef, the written agreement shall control. No other rights of any kind are granted hereunder by implication or otherwise.

You must obtain written permission from Chef to use the Chef Marks for any use, including but not limited to; (i) merchandising purposes (e.g. T-shirts, mugs); (ii) on or in relation to a software product that includes or is built on top of any Chef product, including Chef's open source projects; or (iii) in an attention-getting or branding manner. Without the express prior written consent of Chef, no Chef Marks may be used in a manner that implies an affiliation with, approval by, endorsement of or sponsorship by Chef. + li + u GENERAL GUIDELINES + ul + li You may use of the Chef Marks, without a license, provided such use complies with the following requirements: (i) the Chef Mark is used only to refer to the Chef project and/or technology; (ii) the Chef Mark is not used as part of your product, brand, domain, URL, or service name; (iii) the Chef Mark appears less prominent than your company or product name; (iv) the reference to Chef does not create a sense of endorsement, sponsorship, or ownership by Chef; and/or (v) Your use of the Chef Mark is necessary to fully describe your services or products and is limited to as much of the Chef Mark as is necessary for such identification ("Nominative Use"). ALL OTHER USES OF THE CHEF MARK, INCLUDING LOGOS, REQUIRE A WRITTEN LICENSE AGREEMENT. + li + u SPECIFIC USE CASES + ul + li USE WITH OPEN SOURCE SOFTWARE: We release open source code under the Apache 2.0 license, which permits third parties to copy and redistribute the underlying software under the terms of the license. However, the Apache 2.0 license does not provide any license or right to use any of the Chef Marks. You may redistribute the applicable Chef open source software under the terms of the Apache 2.0 license, but You may not use the Chef Marks in doing so without express written permission from Chef or as expressly permitted in this Policy. + li PUBLICATIONS AND PRESENTATIONS: Third parties may use the Chef Marks in publications, such as books or magazines, or in connection with the presentations and publications that are displayed to the public (collectively, "Publications"), provided that: (i) such use is referential only: You are simply referring to Chef and its products; (ii) Your name or mark and logo shall appear in a prominent location on the cover or the title page of the Publication and shall be featured with greater prominence than the Chef Mark; (iii) You do not apply to register or register any term comprised or consisting of in whole or in part the Chef Mark, or any confusingly similar mark as trademarks, service marks, corporate names, trade names or domain names, Internet keywords, metatags, or trigger words to lead to a website or other Internet destination; (iv) You do not alter or change any Chef Mark or logo; (v) You comply with this Policy and usage guidelines; (vi) You attribute the Chef Marks with the proper symbol and footnote it on all Publications, webpages, announcements, or anywhere you might use the term. + li TRADEMARK NOTICE SYMBOL: When using the Chef Marks, you must use the appropriate trademark symbol (either ™ or ®) as a notice to third parties of our rights to the Chef Mark. A trademark notice symbol must be used in connection with the first and most prominent usage of a mark (e.g. "Chef™"). A Chef Logo must always appear with the TM notice in every use. + li ATTRIBUTION STATEMENT: You must acknowledge the rights of Chef in the Chef Marks and agree not to register or seek to register any Chef Marks in any country. All uses of Chef Marks must identify the Marks as being trademarks of Chef with our standard trademark attribution statement. The following statement must be used in all materials using the Chef Marks, including but not limited to websites, publications, splash screens, screenshots or in documentation or source code: "The Chef™ Mark and Chef Logo are either registered trademarks/service marks or trademarks/ service marks of Chef, in the United States and other countries and are used with Chef Software Inc.'s permission. We are not affiliated with, endorsed or sponsored by Chef Software Inc." While you may scale the size to suit your needs, you may not modify any of the Chef logos in any other way (such as by changing the design or color or the relative proportions of the elements which comprise the logo). When using Chef Marks, you will never vary the spelling, hyphenation or spacing of the any portion of the marks. You will never use a Chef Mark as a verb or noun or in possessive or plural form. (This is just good form.) + li DOMAIN NAMES AND URLs: You may not use Chef Marks in your own domain names or URLs in a way that would likely to confuse a relevant consumer about the source of software or services provided through your website without written approval from Chef. + li PRODUCTS AND SERVICES RELATED TO CHEF SOFTWARE: If you offer products or services related to Chef Marks, you may use the Chef Marks in describing and advertising your product so long as you don't mislead customers into thinking that either your website, service, or product is a Chef website, service, or product, or that Chef has any direct relationship with your organization. For example: "FooCo Management Dashboard for Chef Inspec" is okay. "FooCo Chef" is not okay, nor is "FooCo Chef Automate Dashboard". In addition, your website may not copy the look and feel of any Chef website. Again, Chef does not want the visitor to your website to be confused with whom she/he is dealing. When in doubt, err on the side of providing more, rather than less, explanation and information. + li MARKS AND MERCHANDISE: You must obtain prior written approval from Chef to use the Chef Marks in any merchandise. In general, permission to use a Chef Mark may be granted for those wishing to create merchandise that promotes Chef and the Chef community. Permission will typically be denied to merchandise that would detract, disparage, or insult Chef or the Chef community. (We hope this comes as no surprise.) + li MODIFICATIONS: There is one additional broad category of things you can't do with the Chef Marks - produce modified versions of them. A modified mark also would raise the possibility of consumer confusion, thus violating Chef trademark rights (remember the overarching requirement that any use of a Chef Mark be non-confusing?). + h4 + u UNAUTHORIZED USE OF THE CHEF MARKS + p Unauthorized use of the Chef Marks or marks that are confusingly similar may constitute an infringement of Chef trademark rights and are strictly prohibited. The following are examples of unauthorized uses of the Chef Marks or company name "Chef Software":
 + ul + li + u Use of Chef Marks in connection with third party marks: + | Use of the Chef Marks in connection with or as part of company names, trademarks or logos is not allowed. Do not hyphenate Chef with your product name to create a new product name. You may not use or register, in whole or in part, Chef, Chef logos or any other Chef trademarks, including Chef -owned graphic symbols, icons or any alteration thereof, as part of your trademark, service mark, company name, trade name, product name or service name. You may not incorporate the Chef Marks into the name or logo of your website, domain name, Internet keywords, metatags, or trigger words to lead to a website or other Internet destination, product, business or service. + li + u Incorporation of all or a portion of a Chef Mark into a domain name: + | You may not register a domain name or use a registered domain name that includes a Chef, or any marks that are phonetically equivalent to or confusingly similar to the Chef Marks.
 + li + u Damaging Use: + | Use of the Chef Marks or any other Chef-owned graphic, symbol or logo in a manner that disparages Chef, the Chef project and community or its technology or damages the brand integrity, including use of the Chef Marks in a manner that is, in the opinion of Chef, offensive, defamatory, illegal or unethical. + li + u Confusingly similar marks: + | You may not use trademarks, logos or other content that is confusingly similar to the Chef Marks, Chef-owned graphics, symbols or any logos ("Chef Brand Assets"). + li + u Variations or abbreviations or combinations with any other marks: + | You may not use variations, foreign language equivalent or abbreviation of the Chef Marks for any purpose. + li + u Endorsement or Sponsorship: + | You may not use Chef Marks to imply approval, sponsorship, endorsement or affiliation of your company, website, products or services by Chef or the Chef project. + p Please note that the preceding examples are illustrative rather than an exhaustive list of types of unauthorized uses of the Chef Marks. All rights not explicitly granted in this Policy are expressly reserved by Chef. + h4 + u QUESTIONS AND REPORTING MISUSE OF THE CHEF MARKS + p If You wish to obtain Chef permission for any uses above or for any other use which is not specifically addressed in this Policy or You became aware of unauthorized use of the Chef Marks, please contact marketing@chef.io. Please note that permission will only be granted under certain conditions and/or subject to You entering into an agreement with Chef to maintain the quality of the products and or services You offer.
 + p Chef reserves the right to revoke the authorization at any time in its sole discretion. If Chef determines that Your use of a Chef Mark does not truthfully and accurately identify the inclusion of the applicable Chef technology or Your use is otherwise unacceptable or detrimental to Chef or outside the scope of this Policy or an applicable license, Chef will revoke the authorization. Upon revocation of the authorization You agree that You will immediately cease all use of the applicable Chef Mark. + h4 + u ACKNOWLEDGEMENT + p + strong Nothing in this Trademark Policy shall be interpreted to allow any third party to claim any association with Chef or to imply any approval or support by Chef for any third party products or services.
 + p + strong You acknowledge and agree that Chef is the sole and exclusive owner of the Chef Marks and agree that You will do nothing inconsistent with such ownership either during the term of such use or afterwards. You agree that you will not acquire any rights in the Chef Marks and that any goodwill generated by your use of the Chef Marks inures solely to the benefit of Chef. You also agree that "Chef" is not descriptive or generic and you agree not to challenge Chef's rights in the Chef Marks, including but not limited to its trademark applications and registrations, on any grounds. You also ensure that Your use of the Chef Marks does not create any confusion as to the source of Your products, services and activities and those of the Chef community or Chef. You agree not to challenge Chef's rights in the Chef Marks, including but not limited to its trademark applications and registrations, on any grounds. + p + strong Thank you for caring about the Chef brand! diff --git a/www/source/stylesheets/_buttons.scss b/www/source/stylesheets/_buttons.scss index 892c2acd4..4af177bc9 100644 --- a/www/source/stylesheets/_buttons.scss +++ b/www/source/stylesheets/_buttons.scss @@ -1,5 +1,5 @@ a { - font-family: $main-font; + font-family: $heading-font; color: $color_link; @extend %transition; } @@ -7,8 +7,8 @@ a { .btn { background: transparent; border: 1px solid transparent; - border-radius: 7px; - color: $color_white; + border-radius: 4px; + color: $color_purple; padding: 0.6rem 1.25rem; border-left: 1px solid $color_purple; border-right: 1px solid $color_link; @@ -20,8 +20,10 @@ a { &:hover { background-color: $color_purple; color: $color_white; + border-color: $color_purple; + background-image: initial; } - &.inverse { + &.btn-inverse { color: $color_purple; &:hover { background-color: $color_purple; diff --git a/www/source/stylesheets/_code.scss b/www/source/stylesheets/_code.scss index 7a6025b5a..42589364f 100644 --- a/www/source/stylesheets/_code.scss +++ b/www/source/stylesheets/_code.scss @@ -21,3 +21,7 @@ .code-comment { opacity: 0.6; } +.indent { + padding-left: 1em; + word-wrap: normal; +} diff --git a/www/source/stylesheets/_footer.scss b/www/source/stylesheets/_footer.scss index 3a37e6e49..e5c2ae22f 100644 --- a/www/source/stylesheets/_footer.scss +++ b/www/source/stylesheets/_footer.scss @@ -1,78 +1,83 @@ //Not Styled Yet #main-footer { - padding: 30px 0; - margin-top: 40px; background: $color_heading; + padding-left: 40px; + padding-right: 40px; } -.footer--logos { - @include nav-small { - max-width: 230px; - width: 100%; - margin: 0 auto; - text-align: center; - } +#main-footer > .row { + max-width: 100%; + vertical-align: middle; + display: flex; + align-items: center; } +footer > #dlmsg { + padding-top: $percent_md; + padding-bottom: $percent_md; +} + +footer a.btn:last-child { + margin-left: 1.6em; +} + +footer span { + margin-left: 6px; +} + + + .footer--logo { display: inline-block; vertical-align: middle; - padding-top: 10px; - padding-bottom: 10px; + filter: brightness(0) invert(1); - &.chef { - width: 27%; - padding-right: 5%; - border-right: 1px solid $color_gray; + &.chef { + width: 80px; + border-left: 1px solid $color_white; + padding-left:1.6em; } &.inspec { - width: 46%; - padding-left: 5%; + width: 130px; + padding-right:1.6em; } } .footer--links { + margin-left: auto; + display: inline-flex; @extend .no-bullet; - margin: 25px 0 0; - font-size: 14px; - line-height: 1.1; - - & > li { - margin-bottom: 25px; - } - - @media (min-width: 640px) { - margin: 10px 0 5px; - - & > li { - display: inline-block; - margin: 0 25px 0 0; - - &:last-child { - margin-right: 0; - } - } - } - - @media (min-width: 880px) { - display: inline-block; - - &:first-child { - margin-right: 25px; - } - } } .footer--link { + margin-left: 1.6em; color: $color_gray; - text-transform: uppercase; font-family: $heading-font; - &:hover, &:focus, &:active { - color: darken($color_gray, 15%); + color: $color_purple; } } +//Hex Animation +img#hex { + width: 25px; + -webkit-animation: spin 2s linear infinite both; + animation: spin 2s linear infinite both; + -moz-animation: spin 2s linear infinite both; +} + +@-moz-keyframes spin { + from { -moz-transform: rotate(0deg); } + to { -moz-transform: rotate(360deg); } +} +@-webkit-keyframes spin { + from { -webkit-transform: rotate(0deg); } + to { -webkit-transform: rotate(360deg); } +} +@keyframes spin { + from {transform:rotate(0deg);} + to {transform:rotate(360deg);} +} diff --git a/www/source/stylesheets/_homepage.scss b/www/source/stylesheets/_homepage.scss index 29b78864c..652a5a6af 100644 --- a/www/source/stylesheets/_homepage.scss +++ b/www/source/stylesheets/_homepage.scss @@ -4,33 +4,101 @@ header { height: 500px; } -#container { +#particles-js { + width: 100%; height: 500px; overflow: hidden; - position: relative; -} -.h-top { position: absolute; - z-index: 1; + background-color: transparent; + margin-top: -500px; + z-index: 20; +} + +#particles-second{ + width: 100%; + overflow: hidden; + position: absolute; + background-color: transparent; + height:100%; + z-index: -1; +} + + +.h-top { + height: 500px; img { &:first-of-type { - height: 500px; - position: relative; + height: 420px; + position: absolute; + top:90px; + z-index: 10; } &:nth-child(3) { - position: absolute; height: 250px; - top: 120px; - z-index: -1; + margin-top: 115px; } } h1 { - position: absolute; z-index: 10; - top: 75%; + position: absolute; + margin-top: 400px; } } +//Hero Community + +img.grid { + margin-top: -80px; + z-index: -1; +} + +img.ball { + position: absolute; + width: 35px; + margin-left: 240px; + margin-top: 20px; + -webkit-animation: spin 2s linear infinite both; + animation: spin 2s linear infinite both; + -moz-animation: spin 2s linear infinite both; +} + +img.ball:nth-child(2){ +width: 55px; +margin-left: 150px; +margin-top: 110px; +} + +img.ball:nth-child(3){ + width: 75px; + margin-left: 290px; + margin-top: 130px; +} + +//Tutorials + +.tutorials { + height: 200px; + margin-top: 25px; + align-items: center; +} + +.tutorials .purp-shade { + line-height: 200px; + height: 200px; +} + +.tutorials h2 { + padding-top: 60px; +} + +.tutorials #particles-second { + width: 100%; + overflow: hidden; + position: absolute; + background-color: transparent; + max-height: 200px; + z-index: initial; + } // Animation for Home Page //Reflecting Diamond @@ -96,3 +164,22 @@ header { transform: rotateZ(10deg) scale3d(0.7, 1.2, 0.5); } } + + //Warping Grid Animation// + + .stretch{ + -webkit-animation: grow 1.2s linear 1 both; + animation: grow 1.2s linear 1 both; + -moz-animation: grow 1.2s linear 1 both; + } + @-webkit-keyframes grow { + from { width:0px;} + to {width:150px;} + } + + @keyframes grow { + from { width:0px;} + + to {width:150px;} + + } diff --git a/www/source/stylesheets/_layout.scss b/www/source/stylesheets/_layout.scss index 8f20172e5..56ac73e93 100644 --- a/www/source/stylesheets/_layout.scss +++ b/www/source/stylesheets/_layout.scss @@ -11,6 +11,15 @@ float: right; text-align: right; } + +.strict-left { + text-align: left; + float: left; +} + +.relative { + position: relative; +} //margins .margin-both-xl { @@ -27,12 +36,28 @@ margin-top: $percent_md; margin-bottom: $percent_md; } + +.pad-both { + padding-top: $percent_md; + padding-bottom: $percent_md; +} +.margin-both-offset { + margin-top: 140px; + margin-bottom: $percent_md; +} .margin-top { margin-top: $percent_md; } .margin-under { margin-bottom: $percent_md; } +.margin-both-xs { + margin-top: $percent_sm; + margin-bottom: $percent_sm; +} +.margin-top-xs { + margin-top: $percent_sm; +} .margin-under-xs { margin-bottom: $percent_sm; } @@ -67,18 +92,16 @@ background: $color_triangle_block; clip-path: polygon(0 0, 100% 10%, 100% 100%, 0 100%); } -.triangle-shade { - background-image: url('/images/home/triangle-motif.png'); - background-repeat: no-repeat; - background-attachment: fixed; - background-position: 85% 0; -} + .purp-shade { background: -moz-radial-gradient(center, ellipse cover, rgba(151,110,229,0.4) 0%, rgba(151,110,229,0.2) 50%, rgba(151,110,229,0) 100%); background: -webkit-radial-gradient(center, ellipse cover, rgba(151,110,229,0.4) 0%,rgba(151,110,229,0.2) 50%,rgba(151,110,229,0) 100%); background: radial-gradient(ellipse at center, rgba(151,110,229,0.4) 0%,rgba(151,110,229,0.2) 50%,rgba(151,110,229,0) 100%); filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#66976ee5', endColorstr='#00976ee5',GradientType=1 ); } +.dark-bg { + background-color: $color_heading; +} .blue-gradient { background: -moz-linear-gradient(100% -14.24% -80deg,rgba(99, 206, 153, 1) 0%,rgba(91, 201, 163, 1) 8.33%,rgba(67, 185, 194, 1) 36.64%,rgba(58, 179, 206, 1) 52.48%,rgba(58, 175, 206, 1) 67.93%,rgba(58, 162, 206, 1) 83.94%,rgba(58, 142, 206, 1) 100%); background: -webkit-linear-gradient(-80deg, rgba(99, 206, 153, 1) 0%, rgba(91, 201, 163, 1) 8.33%, rgba(67, 185, 194, 1) 36.64%, rgba(58, 179, 206, 1) 52.48%, rgba(58, 175, 206, 1) 67.93%, rgba(58, 162, 206, 1) 83.94%, rgba(58, 142, 206, 1) 100%); diff --git a/www/source/stylesheets/_nav.scss b/www/source/stylesheets/_nav.scss index 5744f2bf5..b73865ac2 100644 --- a/www/source/stylesheets/_nav.scss +++ b/www/source/stylesheets/_nav.scss @@ -7,6 +7,11 @@ $side-nav-padding-small: 30px; $nav-breakpoint: 730px; +nav { + z-index: 200; + box-shadow: 0 0 4px rgba(151, 110, 229, 0.1); +} + @mixin nav-large { @media (min-width: #{$nav-breakpoint}) { @content; @@ -90,17 +95,9 @@ $nav-breakpoint: 730px; } .main-nav--logo { - display: block; - - @include nav-small { - max-width: 130px; - margin: 15px 0 15px $side-nav-padding-small; - } - - @include nav-large { - padding: 0 $side-nav-padding-large; - margin: 30px 0; - } + display: inline-block; + width: 130px; + float: left; } .main-nav--links { @@ -162,6 +159,29 @@ $nav-breakpoint: 730px; #main-nav-ctas { transition: top 0.3s ease; background: $color_white; + padding-left: 40px; + padding-right: 40px; + + .main-nav--link-text { + margin-left: 6px; + } + + a { + margin-left: 1.6em; + color: $color_gray; + } + + a#main-nav--logo { + margin-left: initial!important; + } + + a:hover, a.btn, a:active { + color: $color_purple; + } + + a.btn:hover { + color: white; + } @include nav-small { display: none; @@ -172,8 +192,7 @@ $nav-breakpoint: 730px; z-index: 90; top: 0; width: 100%; - max-width: 1200px; - padding: 30px 10px 30px 0; + line-height: 80px; text-align: right; & > .button { @@ -181,3 +200,10 @@ $nav-breakpoint: 730px; } } } + +a.main-nav--logo { + display: inline-block; + width: 130px; + float: left; + margin-left: initial!important; +} diff --git a/www/source/stylesheets/_settings.scss b/www/source/stylesheets/_settings.scss index f73def728..720c54cb5 100644 --- a/www/source/stylesheets/_settings.scss +++ b/www/source/stylesheets/_settings.scss @@ -1,10 +1,10 @@ //colors $color_heading: #2c2e30; -$color_paragraph: #647b82; +$color_paragraph: #69787f; $color_gray: #b0bebf; $color_white: white; $color_link: #3ab3ce; -$color_purple: #955af2; +$color_purple: #8d66d8; $color_code_token: #3bc5cc; $color_hr: rgba(99,206,153,1); $color_shadow: rgba(151,110,229,0.2); @@ -15,14 +15,14 @@ $color_blue_shade_2: rgba(58, 142, 206, 1); //Font -$heading-font: 'open sans light', Helvetica, Arial, sans-serif; +$heading-font:'Roboto', sans-serif; $main-font: 'source sans pro light', Helvetica, Arial, sans-serif; //Margin Sizes $percent_lg: 12%; -$percent_md: 8%; -$percent_sm: 3%; +$percent_md: 100px; +$percent_sm: 40px; //Shared Styles diff --git a/www/source/stylesheets/_typography.scss b/www/source/stylesheets/_typography.scss index 465eae26c..ebcdf748f 100644 --- a/www/source/stylesheets/_typography.scss +++ b/www/source/stylesheets/_typography.scss @@ -2,23 +2,28 @@ h1 { font-family: $heading-font; font-size: 36px; color: $color_heading; + font-weight: 300; } h2 { font-family: $heading-font; font-size: 30px; color: $color_heading; + font-weight: 300; } h3 { font-family: $heading-font; font-size: 20px; color: $color_heading; + font-weight: 300; } h4 { font-family: $heading-font; font-size: 20px; color: $color_paragraph; + line-height: 1.4em; + font-weight: 300; } -p { +p, ol, ul, li { font-family: $main-font; color: $color_paragraph; font-weight: 300; @@ -31,9 +36,10 @@ small { } hr { + margin: 0; + width: 0px; border: 0; height: 1px; - width: 20%; background-color: $color_hr; background: linear-gradient(to right, $color_hr 0, $color_link 100%); filter: progid:dximagetransform.microsoft.gradient(startcolorstr='$color_hr', endcolorstr='$color_link', gradienttype=1 ); diff --git a/www/source/tutorials.html.slim b/www/source/tutorials.html.slim index aee9fad20..4b4cd71de 100644 --- a/www/source/tutorials.html.slim +++ b/www/source/tutorials.html.slim @@ -2,17 +2,23 @@ title: InSpec - Tutorials --- -.row - .columns.large-10.large-offset-1 - img.hero--img src="/images/tutorials/tutorial-icon.png" - h1.hero--heading InSpec Tutorials - h2.hero--subhead.text-center - | Clear, step-by-step instructions for getting started and building - your InSpec skills. -.row +/! animated banner +.tutorials.blue-gradient + #particles-second + canvas.particles-js-canvas-el / + .purp-shade + .row + .columns.large-8.medium-8 + h2.t-white#icon-trigger data-enllax-direction="horizontal" data-enllax-ratio=".1" data-enllax-type="foreground" + | Clear, step-by-step instructions for getting started and building your InSpec skills + + + +.row.margin-top .columns.medium-12 - h3.tutorials--subhead Tutorials - p Huge thanks to Annie Hedgpeth for creating all of these fantastic tutorials. + h3 Tutorials + hr.strict-left + p Huge thanks to Annie Hedgpeth for creating all of these fantastic tutorials. ul.tutorials--links.no-bullet li a.tutorials--link href="http://www.anniehedgie.com/inspec-basics-1"