diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..45c1505 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +_site +.sass-cache +.jekyll-metadata diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..294dc40 --- /dev/null +++ b/Gemfile @@ -0,0 +1,13 @@ +source "https://rubygems.org" +ruby RUBY_VERSION + + +#gem "jekyll", "3.2.1" +gem 'github-pages', group: :jekyll_plugins + +#gem "minima" + +# If you have any plugins, put them here! +# group :jekyll_plugins do +# gem "jekyll-github-metadata", "~> 1.0" +# end diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..d2fc238 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,142 @@ +GEM + remote: https://rubygems.org/ + specs: + activesupport (4.2.7) + i18n (~> 0.7) + json (~> 1.7, >= 1.7.7) + minitest (~> 5.1) + thread_safe (~> 0.3, >= 0.3.4) + tzinfo (~> 1.1) + addressable (2.4.0) + coffee-script (2.4.1) + coffee-script-source + execjs + coffee-script-source (1.10.0) + colorator (1.1.0) + ethon (0.9.0) + ffi (>= 1.3.0) + execjs (2.7.0) + faraday (0.9.2) + multipart-post (>= 1.2, < 3) + ffi (1.9.14) + forwardable-extended (2.6.0) + gemoji (2.1.0) + github-pages (96) + activesupport (= 4.2.7) + github-pages-health-check (= 1.2.0) + jekyll (= 3.2.1) + jekyll-coffeescript (= 1.0.1) + jekyll-feed (= 0.5.1) + jekyll-gist (= 1.4.0) + jekyll-github-metadata (= 2.0.2) + jekyll-mentions (= 1.2.0) + jekyll-paginate (= 1.1.0) + jekyll-redirect-from (= 0.11.0) + jekyll-sass-converter (= 1.3.0) + jekyll-seo-tag (= 2.0.0) + jekyll-sitemap (= 0.10.0) + jemoji (= 0.7.0) + kramdown (= 1.11.1) + liquid (= 3.0.6) + listen (= 3.0.6) + mercenary (~> 0.3) + minima (= 1.2.0) + rouge (= 1.11.1) + terminal-table (~> 1.4) + github-pages-health-check (1.2.0) + addressable (~> 2.3) + net-dns (~> 0.8) + octokit (~> 4.0) + public_suffix (~> 1.4) + typhoeus (~> 0.7) + html-pipeline (2.4.2) + activesupport (>= 2) + nokogiri (>= 1.4) + i18n (0.7.0) + jekyll (3.2.1) + colorator (~> 1.0) + jekyll-sass-converter (~> 1.0) + jekyll-watch (~> 1.1) + kramdown (~> 1.3) + liquid (~> 3.0) + mercenary (~> 0.3.3) + pathutil (~> 0.9) + rouge (~> 1.7) + safe_yaml (~> 1.0) + jekyll-coffeescript (1.0.1) + coffee-script (~> 2.2) + jekyll-feed (0.5.1) + jekyll-gist (1.4.0) + octokit (~> 4.2) + jekyll-github-metadata (2.0.2) + jekyll (~> 3.1) + octokit (~> 4.0) + jekyll-mentions (1.2.0) + activesupport (~> 4.0) + html-pipeline (~> 2.3) + jekyll (~> 3.0) + jekyll-paginate (1.1.0) + jekyll-redirect-from (0.11.0) + jekyll (>= 2.0) + jekyll-sass-converter (1.3.0) + sass (~> 3.2) + jekyll-seo-tag (2.0.0) + jekyll (~> 3.1) + jekyll-sitemap (0.10.0) + jekyll-watch (1.5.0) + listen (~> 3.0, < 3.1) + jemoji (0.7.0) + activesupport (~> 4.0) + gemoji (~> 2.0) + html-pipeline (~> 2.2) + jekyll (>= 3.0) + json (1.8.3) + kramdown (1.11.1) + liquid (3.0.6) + listen (3.0.6) + rb-fsevent (>= 0.9.3) + rb-inotify (>= 0.9.7) + mercenary (0.3.6) + mini_portile2 (2.1.0) + minima (1.2.0) + minitest (5.9.0) + multipart-post (2.0.0) + net-dns (0.8.0) + nokogiri (1.6.8) + mini_portile2 (~> 2.1.0) + pkg-config (~> 1.1.7) + octokit (4.3.0) + sawyer (~> 0.7.0, >= 0.5.3) + pathutil (0.14.0) + forwardable-extended (~> 2.6) + pkg-config (1.1.7) + public_suffix (1.5.3) + rb-fsevent (0.9.7) + rb-inotify (0.9.7) + ffi (>= 0.5.0) + rouge (1.11.1) + safe_yaml (1.0.4) + sass (3.4.22) + sawyer (0.7.0) + addressable (>= 2.3.5, < 2.5) + faraday (~> 0.8, < 0.10) + terminal-table (1.7.2) + unicode-display_width (~> 1.1.1) + thread_safe (0.3.5) + typhoeus (0.8.0) + ethon (>= 0.8.0) + tzinfo (1.2.2) + thread_safe (~> 0.1) + unicode-display_width (1.1.1) + +PLATFORMS + ruby + +DEPENDENCIES + github-pages + +RUBY VERSION + ruby 2.3.1p112 + +BUNDLED WITH + 1.12.5 diff --git a/_config.yml b/_config.yml new file mode 100644 index 0000000..2790128 --- /dev/null +++ b/_config.yml @@ -0,0 +1,31 @@ +url: "http://localhost:4000" +baseurl: "" +permalink: "/:year/:month/:day/:title" +title: "Itay as a Service" +description: "Itay Shakury's blog" + +#author profile +author_photo: "/assets/headshot150x150.png" +author_name: "Itay Shakury" +author_bio: "Technology enthusiast, Etrepreneur wannabe, Microsoft employee." +author_twitter: "itayasaservice" +author_linkedin: "itaysk" +author_github: "itaysk" + +# Build settings +markdown: kramdown + +sass: + style: :compressed + + +gems: + - jekyll-gist + - jekyll-feed + +defaults: + - + scope: + path: "_posts" + values: + layout: "post" diff --git a/_includes/disqus_comments.html b/_includes/disqus_comments.html new file mode 100644 index 0000000..642301f --- /dev/null +++ b/_includes/disqus_comments.html @@ -0,0 +1,25 @@ +{% if page.comments != false and jekyll.environment == "production" %} + {% if site.url %} + {% assign disqus_url = page.url | prepend: site.url %} + {% elsif site.github.url %} + {% assign disqus_url = page.url | prepend: site.github.url %} + {% endif %} + +
+ + +{% endif %} diff --git a/_includes/footer.html b/_includes/footer.html new file mode 100644 index 0000000..ef0ccc5 --- /dev/null +++ b/_includes/footer.html @@ -0,0 +1,3 @@ + diff --git a/_includes/google-analytics.html b/_includes/google-analytics.html new file mode 100644 index 0000000..eb2a692 --- /dev/null +++ b/_includes/google-analytics.html @@ -0,0 +1,11 @@ + + diff --git a/_includes/head.html b/_includes/head.html new file mode 100644 index 0000000..1ee04b7 --- /dev/null +++ b/_includes/head.html @@ -0,0 +1,20 @@ + + + + + + {% if page.title %}{{ page.title | escape }}{% else %}{{ site.title | escape }}{% endif %} + + + {% assign custom_url = site.url | append: site.baseurl %} + {% assign full_base_url = custom_url | default: site.github.url %} + + + {% feed_meta %} + + + + {% if jekyll.environment == 'production' and site.google_analytics %} + {% include google-analytics.html %} + {% endif %} + diff --git a/_includes/header.html b/_includes/header.html new file mode 100644 index 0000000..c8172dd --- /dev/null +++ b/_includes/header.html @@ -0,0 +1,15 @@ +
+ {% assign custom_url = site.url | append: site.baseurl %} {% assign full_base_url = site.github.url | default: custom_url %} + + {{ site.title | escape }} + + +
\ No newline at end of file diff --git a/_includes/sidebar.html b/_includes/sidebar.html new file mode 100644 index 0000000..7aa756b --- /dev/null +++ b/_includes/sidebar.html @@ -0,0 +1,32 @@ + \ No newline at end of file diff --git a/_layouts/default.html b/_layouts/default.html new file mode 100644 index 0000000..1f1d49b --- /dev/null +++ b/_layouts/default.html @@ -0,0 +1,24 @@ + + +{% include head.html %} + + + +
+
+
+ {% include sidebar.html %} +
+
+ {{ content }} +
+
+
+ + + + \ No newline at end of file diff --git a/_layouts/page.html b/_layouts/page.html new file mode 100644 index 0000000..01e4b2a --- /dev/null +++ b/_layouts/page.html @@ -0,0 +1,14 @@ +--- +layout: default +--- +
+ +
+

{{ page.title | escape }}

+
+ +
+ {{ content }} +
+ +
diff --git a/_layouts/post.html b/_layouts/post.html new file mode 100644 index 0000000..1d36c28 --- /dev/null +++ b/_layouts/post.html @@ -0,0 +1,18 @@ +--- +layout: default +--- +
+ +
+

{{ page.title | escape }}

+ +
+ +
+ {{ content }} +
+ + {% if site.disqus.shortname %} + {% include disqus_comments.html %} + {% endif %} +
diff --git a/_posts/2012-12-12-is-office365-a-paas-or-a-saas.md b/_posts/2012-12-12-is-office365-a-paas-or-a-saas.md new file mode 100644 index 0000000..5d97a33 --- /dev/null +++ b/_posts/2012-12-12-is-office365-a-paas-or-a-saas.md @@ -0,0 +1,35 @@ +--- +title: Is Office365 a PaaS or a SaaS? +date: 2012-12-12 21:17 +categories: [Thoughts-Opinions] +tags: [Cloud, Office365, SharePoint Online] +--- + +Lately I am more involved in discussions with customers about Office365, and Microsoft's cloud offerings in general. +This kind of discussions always starts with the introduction of cloud hosting concepts such as *Infrastructure as a Service*, *Platform as a Service*, and *Software as a Service*. +You have probably seen this slide before: + +![iaas-paas-saas](/images/2012-12-12-is-office365-a-paas-or-a-saas_1.jpg) + +It very easy to position well known products on this map, for example: +- Amazon's cloud is clearly IaaS. +- Windows Azure is clearly Paas. +- Gmail, SalesForce is clearly Saas. +- What about Office365? + +_(note from the future: re-reading this 4 years later makes the AWS\Azure comparison look naive, but when both platforms were young it made more sense)_ + +Office365 is commonly presented as a SaaS solution by most people, maybe because it is a direct competitor to Google Apps which are all about SaaS, but I think that there's more to that to discuss. + +Here is a typical slide that presents Office 365 as a Saas: + +![office365saas](/images/2012-12-12-is-office365-a-paas-or-a-saas_2.png) + +When talking about Exchange Online and Lync Online – they are most definitely SaaS Products. Is SharePoint Online the same? I think not. +In my opinion, SharePoint online is as much PaaS as it is SaaS. It depends on how you use it, but this question is also relevant for on-premises SharePoint. + +I work with some organizations that see SharePoint as their mainstream development platform. Every new business requirement is developed on SharePoint, and most of the developers there are SharePoint developers. For them, SharePoint is clearly a development platform, regardless on weather it is on the cloud or in their data center. If I had a discussion with them about SharePoint Online, I would probably present SharePoint Online as a PaaS solution, just next to Windows Azure. + +On the other hand, some customers go to SharePoint Online in order to get a quick and easy document collaboration platform, or a social platform. They just want to know what features SharePoint has for them, and use them as is. For them SharePoint online is nothing more that SaaS. They will use it just like Yammer, or Zoho which are obvious SaaS products. + +The bottom line is that SharePoint is an odd beast in the landscape of enterprise software. **It is a product, which is also a platform.** This applies to SharePoint Online as well which is part of Office365. So don't be to rushed to present Office365 as a SaaS solution because then you might put yourself in uncomfortable position when discussions about SharePoint online solutions will come to the table, and they are expected to fall in the "almost no management" bucket, where they clearly don't belong. diff --git a/_posts/2013-03-03-im-speaking-at-sharepoint-extreme-2013.md b/_posts/2013-03-03-im-speaking-at-sharepoint-extreme-2013.md new file mode 100644 index 0000000..66612ce --- /dev/null +++ b/_posts/2013-03-03-im-speaking-at-sharepoint-extreme-2013.md @@ -0,0 +1,16 @@ +--- +title: I'm Speaking at SharePoint Extreme 2013 +date: 2013-03-03 18:00 +categories: [Events] +tags: [Sharepoint; Apps; SharePoint 2013] +--- + +The annual largest Israeli SharePoint conference – SharePoint Extreme will take place next week: 11-13/3/2013. + +This year I am opening the developers track with the oh so popular topic: + +**Introduction to SharePoint 2013 Apps**. The session will take place at 10:15 right after the keynote. + +For details and registration please see the conference's web site: + +[![invitation](/images/im-speaking-at-sharepoint-extreme-2013_1.jpg)](http://sharepoint.jbh.co.il/) diff --git a/_posts/2013-04-22-how-to-use-windows-8-on-tablets.md b/_posts/2013-04-22-how-to-use-windows-8-on-tablets.md new file mode 100644 index 0000000..f01d3ff --- /dev/null +++ b/_posts/2013-04-22-how-to-use-windows-8-on-tablets.md @@ -0,0 +1,13 @@ +--- +title: How to use Windows 8 on Tablets +date: 2013-04-22 13:07 +categories: [Technical-Howto] +tags: [Video, Windows8] +--- + +I have recorded a short video that shows the basics of using Windows 8 on tablet devices. Unfortunately, users don't "just get it" when it comes to Windows 8 UX, especially the swiping gestures, so I have made a short tutorial. + +**The video is in Hebrew**, and is hosted on YouTube: + + + diff --git a/_posts/2013-05-04-lenovo-x1-carbon-touch-review.md b/_posts/2013-05-04-lenovo-x1-carbon-touch-review.md new file mode 100644 index 0000000..13e352a --- /dev/null +++ b/_posts/2013-05-04-lenovo-x1-carbon-touch-review.md @@ -0,0 +1,89 @@ +--- +title: Lenovo X1 Carbon Touch Review +date: 2013-05-04 21:12 +categories: [Technical-Howto] +tags: [Laptop, Review] +--- + +Microsoft has generously allowed all employees to refresh their primary PCs to fresh and modern ones as part of the Windows 8 launch. +We actually got to choose between a handful of very compelling devices. I (as many others) chose the Lenovo X1 Carbon Touch. Here are my thoughts about it. + +![x1carbon](http://www.lenovo.com/shop/americas/content/img_lib/portals/ent/x1carbon-open.jpg) + +## Overall impression +The X1 Carbon is a member of the ThinkPad family, so it carries the same qualities as robustness, comfort, and performance, but it does that with a style. It does a great job representing the ThinkPad family while taking it a step further, adding the cool factor. +The X1 definitely turn heads when you'll take it out of our bag and place it on the table, while still provide everything you'd expect from a ThinkPad. + +## Body +The X1 Carbon is called that way because it is actually constructed of [carbon fiber](http://en.wikipedia.org/wiki/Carbon_(fiber)) - A high quality material that is used in premium products that is very light and tough (and expensive). Carbon fiber was used in other ThinkPads as well, but now it is a major ingredient of the body and shell. The device feels very good, it has a very premium feel to it, so much that it makes other ThinkPads look plasticy and cheap next to it. + +The materials choice adds to the solid quality feel, but also has a side effect. After a decent use, you will notice some smudging marks where your hands touch the laptop, mostly on the touchpad, and the areas where your rest your palms. It's like the surface absorbs the fat from your body and it shows easily on the matt carbon. + +![x1 smudges](/images/2013-05-04-lenovo-x1-carbon-touch-review_1.jpg) + +The body is pretty thin, but not very thin. It is also pretty light but not very light. My point of reference is my old [ThinkPad X220](http://shop.lenovo.com/us/laptops/thinkpad/x-series/x220) (as well as other various X models) and my other [Acer Aspire S3](http://www.engadget.com/2011/09/02/acer-aspire-ultrabook-s3-hands-on) laptop. + +Comparing to the X220 the X1 is pretty thin, but not so lighter. They feel quite the same weight to me. +The Acer Aspire S3 is a MacBook Air competitor (clone) so it's very light and very thin. When held in hand, or placed on lap it feels significantly skinnies and lighter then the X1. + +![x1 vs s3](/images/2013-05-04-lenovo-x1-carbon-touch-review_2.jpg) + +This of course are very unfair comparisons! the X220 is 12" and the Aspire S3 is 13", while the X1 is 14". This means bigger screen but also bigger body which means more material that makes the device heavier. +Comparing to other 14" laptops the X1 is much more attractive, not only in weight and thickness, but also in dimensions - With the X1, Lenovo has managed to cramp a 14" screen in a 13" frame, making it very compact for a 14" device. + +The X1 is the thinnest Thinkpad and lightest 14" ultrabook to date, says Lenovo. I take their word on this and I think that in it's category is a great piece of device. + +## Screen +As mentioned before, the X1 has a 14" screen with 1600x900 max resolution. I have heard people complaining about the max resolution whishing 1080. I personally don't mind this. Actually I think I think this resolution is perfect for this screen size as it's seems like the best compromise between having more screen real-estate, and being actually able to read stuff. I have a 1080 LCD I sometimes use on my workstation and I often find it too small for me to read from (I'm getting old...). +The screen has nice viewing angles and excellent brightness and I like it. + +One thing I absolutely loved about ThinkPads are the matt finish on the screen. Having matt finish disables annoying reflections and distractions and allows me to work longer without straining my eyes. I can work in my car, at customer's offices, on my couch, and where not. I hardly ever sit down at a desk so I need a screen that looks good everywhere, and matt finish is an important feature in a work laptop. +Knowing that the X1 had touch screen, I was afraid it will have a glossy screen. I don't know why, but I never seen a touch screen with a matt finish. Think about it – have you? I was pretty amazed to find out the X1 actually has matt touch screen. It's not as good at canceling refelctions as my older ThinkPads (more on this later), but it's a pretty good deal for having touch. + +Here is how the lamp is reflected on the screen. Not so bad I think: + +![x1 reflection](/images/2013-05-04-lenovo-x1-carbon-touch-review_3.jpg) + +I'm not 100% sure, but I think that the screen here is actually a glossy touch screen like every other touch screen, but to keep ThinkPad's matt tradition, they have added a matt sticker on top of the screen to minimize reflections. +The thing is, this sticker thing is pretty noticeable, and it makes the display a little blurry most times. It's almost as if there is a thin layer of sprayed water on screen you always want to wipe off. It takes a sharp eye to see it, but it's there. Some people mind it, some people don't. I actually mind it, and I have spotted it since first booting the laptop, but I have learned to live with it. + +## Keyboard +The keyboard is excellent – it's just is. It is both beautiful and comfortable. It is not your old ThinkPad keyboard, since the keys are now separated ([chiclet style](http://en.wikipedia.org/wiki/Chiclet_keyboard")) and they feel more solid. It's certainly ThinkPad quality and I like it a lot. In fact, I prefer it over the old unbeatable ThinkPad keyboard. + +I was disappointed to see PgUp\PgDn keys moved next to the arrow keys and the Home\End\Insert\Delete bunch aligned in a raw instead of that good old box. But it's so common nowadays it's almost a requirement from a modern ultra book, and it does clear space for bigger keyboard (which is great BTW, did I mention?). + +Update May 8th 2013: I just noticed that there is no "right click" keyboard button that is usually placed between right Ctrl and Alt. Instead there's a "print screen" button there. Why?? + +## Mouse +The signature [trackpoint](http://en.wikipedia.org/wiki/Pointing_stick) (aka the red nipple) is there and works just great. I use it when my hands are in writing position, and I need to briefly use the mouse. + +The touchpad on the other hand, is another story. +The touchpad is large in dimensions which is a good thing, and is made from a smooth glossy material, which is also a good thing - I hated the small textured touchpads on Thinkpad's W series. So far so good. + +I don't know what is it, but I was (still) having difficulties clicking with it. I am used to just swipe around and touch whenever I want to left click. that touching gesture is sometimes not registered. I couldn't figure out when or why, but it seems like I am having problems adjusting to this touchpad, and you might have as well. I don't know what it is, but it could be better. + +Other then that I love that it supports Windows 8 touch gestures like swiping from the edges, and also two finger scrolling and pinch to zoom. Now, I want to stress this two finger scrolling thing – absolutely amazing. This is one of the things you don't know how you have lived without. I understand Mac users had this forever – I envy you! I am constantly finding myself trying to scroll on other laptops like this and disappointed when it doesn't work. I like it a a lot. + +## Ports +This section is all about compromise, so brace yourselves. + +The X1 has only 2 USB Ports. One is [SS (USB3)](http://en.wikipedia.org/wiki/USB_3.0) and the other is [always on for charging](http://en.wikipedia.org/wiki/USB#Sleep-and-charge_ports). I would have liked to see more USB ports on it. + +There is no [VGA port out](http://en.wikipedia.org/wiki/VGA_connector) – So you can't connect a standard projector or monitor. There is a [Mini Display Port](http://en.wikipedia.org/wiki/Mini_DP), and you can purchase an adapter, as I did. +BTW, forget about using the mini DP the same time as the adjacent USB port, they are too close to one onother. This is a small but noticable fail in human enginerring. + +There is no [RJ45](http://en.wikipedia.org/wiki/RJ45_(computers)#8P8C) LAN port – So you can't connect a to a wired network. You can purchase a USB to LAN adapter, as I did. + +The Power adapter is not the standard yellow circle adapter, but a slimmer rectangle shaped adapter. + +There is no Docking station connections, you can purchase a (rather expensive) USB port replicator that is a decent solution instead. + +## Summary +When I needed to chose my new laptop that will serve me for the next few years, I had the following thoughts in mind: +- 14" screen – I used a 15" beast for a short period (ThinkPad W520) and I really enjoyed the large screen. But the 15" was too big to carry around, and also usually came with monstrous laptops that favored performance over portability. I knew I wanted a 14" sized screen. +- Powerful – One thing I always suffered from was the inability to run virtual machines on my previous laptops. I wanted 16GB of RAM but could settle for 8, not less. Also I have heard about the wonders of SSD and I was looking for this in my next laptop. +- Portable – I am a consultant who travel a lot. I need a light and portable PC that I can carry around in my bag all the time. +- Touch – Windows 8 is all about touch, and so are Microsoft's new approach. I would hate to be left out of the party if I took a non touch laptop. + +Having these requirements in mind, the X1 was a clear winner. I really enjoy having a large 14" device I can comfortably work on long hours, while at the same time is very mobile and pretty handsome. +I definitely recommend this one for anyone who asks me. \ No newline at end of file diff --git a/_posts/2013-11-04-tabs-and-apps-web-apps-evolved.md b/_posts/2013-11-04-tabs-and-apps-web-apps-evolved.md new file mode 100644 index 0000000..d978bed --- /dev/null +++ b/_posts/2013-11-04-tabs-and-apps-web-apps-evolved.md @@ -0,0 +1,72 @@ +--- +title: Tabs and Apps – Web Apps Evolved +date: 2013-11-04 22:08 +categories: [Thoughts-Opinions] +tags: [Apps, Browser, Chrome, Chrome Apps, ChromeOS, Internet Explorer, UX, Web, Windows8] +--- + +Here's something you already know: The web as we know it today, is not how it was originally designed to be. The web was invented as a network of inter-connected articles. This is what HTTP, and HTML were meant to do. This is also what the browser was meant to do. The browser is a tool that allows us to browse through this huge catalog of articles, navigating from one article to another. Today however, the web has evolved into a fully-fledged development platform (perhaps the most popular development platform on earth). Sites like Gmail, Facebook, YouTube, and Dropbox are not "web sites" - They are web applications. +Of course, everybody already knows that, right? So my question is why do we keep using these apps like web sites? In particular – why are we still using "the browser" in order to organize them? + +## Tabs +Here is a common sight that probably everyone can relate to: + +![browser tabs](/images/2013-11-04-tabs-and-apps-web-apps-evolved_1.jpg) + +What's wrong here? All the tabs left to the Google tab, are not *pages* that I'm browsing through, and therefore should not be in my browser. These are *apps* that just happens to be of the web kind, and just because of that they are sentenced to life in a browser tab. Think about the apps that you like to always keep opened, like Gmail to see when you get a new email and respond immediately, or GrooveShark to listen to music, or Twitter to see when you have new tweets in the feeds. These are apps, not pages, and therefore doesn't belong in a browser tab. + +![apps in tabs](/images/2013-11-04-tabs-and-apps-web-apps-evolved_2.png) + +![more apps in tabs](/images/2013-11-04-tabs-and-apps-web-apps-evolved_3.png) + +Having all these apps in the browser tabs bar - This is bad user experience. I want apps to have their own context so I can use them more fluently, and the browser to be free of those apps so I can really use it to browse the web. + +## Taskbar +But we already have an infrastructure to organize running apps – The taskbar. While the browser is not an ideal place to organize running apps, the taskbar is naturally designed for this. + +![taskbar](/images/2013-11-04-tabs-and-apps-web-apps-evolved_4.png) + +**I would really love to see my web apps freed from the browser and live by themselves, on the taskbar.** + +Unfortunately, today's reality is far from that... Remember that screenshot I showed you before? with all the apps opened in chrome? I dropped something from that screenshot. Here is how it really looks like: + +![chrome alone in taskbar](/images/2013-11-04-tabs-and-apps-web-apps-evolved_5.jpg) + +See that tiny miserable taskbar over there? Let me help you: + +![chrome alone in taskbar bigger](/images/2013-11-04-tabs-and-apps-web-apps-evolved_6.png) + +It is the truth - Today's OSs are just big machines used to open browsers, and from then on everything happens in the browser. This really sucks from a User Experience perspective! It just doesn't make sense that the OS provides us this great application management infrastructure (multi tasking in the OS is great), but we don't really use it. Instead, we use it to open another kind of applications management infrastructure, a far inferior one, and use that other one for everything. + +## Solutions + +Recent developments in the Browsers \ OS arena demonstrates the maturity of this idea: +- Chrome apps are really as close as it gets to what I'm talking about. They just lack the website integration and compatibility that I need. +- Chrome OS is an entire Operating system built around this story. It hasn't integrated web apps with the OS, it is just an OS that is built from web apps. +- Windows 8 apps are a great way to solve the usability challenge – you can use Windows 8 apps for all your favorite apps or services and the browser for the rest. +- Internet Explorer 9 introduced Pinned Websites, and notification badges for web pages which in my opinion was a great move, but I can't find it in latest versions anymore... Who knows. + +If I'll have to describe the solution I'm imagining it would be something like this: + +- From your browser, you can always pin sites to the task bar. +- Pinning a site indicates that it's in fact an app and not a web site. +- This app is basically a browser showing only that app. +- When in this app mode, the browser will not show any toolbars, address bar, or navigation controls. Most importantly – No tabs in an app! +- Preferably the browser will pre-download the app's resources locally. +- The host allows app like feature such as notifications. +- All links that are external to the app will open the default browser in another window. Although it's run by the browser, you shouldn't use it to browse. + +If I had something like this, I would have been really happy. I could: + +- See all the open apps at a glance. +- Switch easily between opened apps (Suddenly Alt+Tab is useful!) +- Quickly launch apps that I use frequently. +- Multitask with apps more intuitively. +- See notifications for apps that I care about. + +In addition: + +- I have an authentic browser application that is now clean and simple. With it I surf the web and browse web sites without the mental burden of dozens of apps in tabs. +- And best of all – I have one taskbar for all my apps. + +## What do you think? diff --git a/_posts/2013-11-16-windows-8-share-to-facebook.md b/_posts/2013-11-16-windows-8-share-to-facebook.md new file mode 100644 index 0000000..9900fa7 --- /dev/null +++ b/_posts/2013-11-16-windows-8-share-to-facebook.md @@ -0,0 +1,68 @@ +--- +title: Windows 8 Share to Facebook +date: 2013-11-16 00:23 +categories: [Technical-Howto] +tags: [Facebook, Windows8, Windows8.1] +--- + +My favorite feature in Windows 8 has to be the Share Charm. I really think it's a great and unique idea. +If you don't know what the Share Charm is, do yourself a favor and read about it ASAP here: +[http://windows.microsoft.com/en-us/windows-8/charms-tutorial](http://windows.microsoft.com/en-us/windows-8/charms-tutorial) + +One of the most trivial implementations to sharing is sharing to Facebook. To my big surprise, I found out that Windows 8 has no built in Share to Facebook option. The People app has Sharing capabilities, but it only lets you post to your profile. What about sharing to in a private message? What about posting to a group? In my personal experience these are far more common use cases. + +I've been playing around with the idea of creating this Share to Facebook thing myself, but I always kept hoping that someday they'll just add it. The official Facebook app has a Share target, but it is just as useless as the People app share target. + +So I gave up, I created my own Facebook share target. I'm just putting it here in case anyone else feels the same as I do about the built in Facebook sharing functionality. I'm not going to submit it to the store because I think it's a stupid app. I really hope Microsoft or Facebook will add this soon and this post will be obsolete. + +Here it is in action: +![my FB sharer](/images/2013-11-16-windows-8-share-to-facebook_1.png) + +The code is basically just this: + +```javascript +(function () { + 'use strict'; + + var app = WinJS.Application; + var share; + var fbShareUrlTemplate = 'https://www.facebook.com/sharer/sharer.php?u='; + + app.onready = function (args) { + theWebView.addEventListener(MSWebViewNavigationStarting, navigationStarting); + }; + + app.onactivated = function (args) { + if (args.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.shareTarget) { + share = args.detail.shareOperation; + + if (share.data.contains(Windows.ApplicationModel.DataTransfer.StandardDataFormats.uri)) { + share.data.getUriAsync().then(function (uri) { + if (uri != null) { + var urlToNavigate = fbShareUrlTemplate + uri.absoluteUri; + theWebView.navigate(urlToNavigate); + } + }); + } + } + }; + + function navigationStarting(args) + { + var url = args.uri; + if (url.substr(0, fbShareUrlTemplate.length) !== fbShareUrlTemplate) { // if the url doesn't start with fbShareUrlTemplate + args.preventDefault(); + share.reportCompleted(); + } + } + + app.start(); +})(); +``` + +A couple of things to note: +- It uses Facebook's deprecated sharer.php. +- It can only share urls, like from IE. +- It is poorly written and tested. + +Yes, I am lazy. But it's serves me well, and I'm happy with it. And it just proves how simple it is to implement, so Microsoft \ Facebook – Please do! diff --git a/_posts/2013-11-28-using-browser-profiles-will-save-you-from-multiple-identities-hell.md b/_posts/2013-11-28-using-browser-profiles-will-save-you-from-multiple-identities-hell.md new file mode 100644 index 0000000..369a7b0 --- /dev/null +++ b/_posts/2013-11-28-using-browser-profiles-will-save-you-from-multiple-identities-hell.md @@ -0,0 +1,62 @@ +--- +title: Using Browser Profiles Will Save You From Multiple Identities Hell +date: 2013-11-28 16:12 +categories: [Technical-Howto] +tags: [Chrome, FireFox, Internet Explorer, Office365] +--- + +I have like 10 Office 365 identities: I work for Microsoft, so obviously we use Office 365 internally; I also help some customers maintain their Office 365 tenants; I also have one or two Office 365 account for demos, and for each of those I have several sample user accounts to demonstrate collaboration scenarios. +It's a real pain to work with all these alternating identities in the same browser. And it doesn't stop there, because for each Office 365 account, I also have an associated Yammer account, and for some I also have associated Windows Azure accounts, and you can see where I am going with this. + +First lets agree that signing in and out of services sucks. You really don't want to do this. Other solutions like separating different kinds of use cases into different browser types is lame, and private browsing (incognito) is inconvenient, and not sufficient solution. + +So the requirement is essentially to maintain multiple personas, each with it's own set of credentials an settings. This actually is available today in most browsers but I found that the best implementation of this concept was done in Chrome (not surprisingly). + +## End Result +I have a group in the start screen with shortcuts for each persona. + +![end result](/images/2013-11-28-using-browser-profiles-will-save-you-from-multiple-identities-hell_1.png) + +I can launch multiple browsers with different identities. + +![identity 1](/images/2013-11-28-using-browser-profiles-will-save-you-from-multiple-identities-hell_2.png) + +![identity 2](/images/2013-11-28-using-browser-profiles-will-save-you-from-multiple-identities-hell_3.png) + +For each user I can set different bookmarks (i.e one is admin, other is user). + +I can choose to pin my primary personal user to taskbar, but not test users'. + +![taskbar](/images/2013-11-28-using-browser-profiles-will-save-you-from-multiple-identities-hell_5.png) + +Best of all I don't need to fear from checking "remember my password"! + +## Chrome +Chrome makes it very easy to setup profiles. Just go to the Users section under the Settings screen. There you can add users as you wish. + +![chrome profiles](/images/2013-11-28-using-browser-profiles-will-save-you-from-multiple-identities-hell_6.png) + +The UI let's you create a shortcut for the newly created user instance. You can launch chrome under a specific profile like this: +`chrome.exe --profile-directory="Profile Name"` +I really liked that chrome lets you pick a different icon for each profile so you can tell them apart when you have several opened at the same time. +You can also switch profiles at runtime, a feature that I find useless and confusing actually. + +## Firefox +Firefox has profiles support but it's not as easy as Chrome's. + +first you need to open the separate profiles manager (FF needs to be closed before running this): +`firefox.exe –p` + +![firefox profiles](/images/2013-11-28-using-browser-profiles-will-save-you-from-multiple-identities-hell_7.png) + +You then run different profile instances using +`firefox.exe –no-remote –p profile name` + +I couldn't find a way to set different taskbar icons for each profile, which I this is an important feature when working with multiple identiites at the same time. +There's also no built in profile selector, but there's an extension available, and I don't use this feature anyway. + +## IE +IE doesn't have the concept of profiles. You can use `File->New session` to open a new window that is isolated in terms of authentication, but it will share your bookmarks and other settings. + +## Summary +These days everything is in the cloud, and everything is "as a service". A side effect of this approach is excessive use of identities. This is true for work, home, mobile, everywhere. If there are online services for which you have multiple accounts, you should really check out profiles and sandboxing capabilities of modern browsers, especially Chrome. diff --git a/_posts/2013-12-04-three-stars-why-having-a-windows-phone-app-is-good-for-your-business.md b/_posts/2013-12-04-three-stars-why-having-a-windows-phone-app-is-good-for-your-business.md new file mode 100644 index 0000000..53370cf --- /dev/null +++ b/_posts/2013-12-04-three-stars-why-having-a-windows-phone-app-is-good-for-your-business.md @@ -0,0 +1,39 @@ +--- +title: Three Stars - Why having a Windows Phone app is good for your business +date: 2013-12-04 10:55 +categories: [Thoughts-Opinions] +tags: [Android, iOS, iPhone, Mobile, Windows Phone] +--- + +I often get involved in conversations about wether or not a company or a startup should invest in building a Windows Phone app. There are many considerations for doing this, and it's not my place to convince anyone either way. There is however, one side effect of having cross-platform presence, that in my opinion is alone worth the investment in Windows Phone. +In this post I will try to describe this concept. I call it the three stars, because of how it is usually presented in web landing pages for apps. The theory is that every respectable app should have this trio of icons: + +![3 stars on vine](/images/2013-12-04-three-stars-why-having-a-windows-phone-app-is-good-for-your-business_1.png) + +(an example from vine.co) + +The download icons for your app on different platforms. Some apps have just the iOS (or App store) icon - They have "earned" the bitten apple "achievement". Some also have the Android (Google Play) icon. These have "earned" the green robot "achievement". + +Most apps starts on iOS or Android or both, nothing special there. But if you think about it, only the best apps are available on all three platforms. So when your app is also on Windows Phone, when you "earn" that Windows flag "achievement" to showcase on your landing page - that is when you advance to the big boys league. +It's like you have reached next level in the game. It's like you have earned the three starts achievement. + +![3 stars echievement](/images/2013-12-04-three-stars-why-having-a-windows-phone-app-is-good-for-your-business_2.jpg) + +But this is not just a game. Having three stars, having these three very distinguished icons on your landing page says something about you and your app. It says maturity, it says experience, it says completeness and trust and many other associations that only that combination of three icons can produce. Not iOS alone, not Android alone, not even iOS and Android together can get you there – these are too common. Only when you can proudly display the "tree stars" on your home page, is when you can reach that level of perception. + +![3 stars on waze](/images/2013-12-04-three-stars-why-having-a-windows-phone-app-is-good-for-your-business_3.png) + +(an example from waze.com) + +Imagine we conducted a research where we could measure the (perhaps subconscious) effect of showing that you are there on all major platforms, as opposed to showing that you are on some of them. I'll try to donate at least my thoughts: +- If this app has full platform coverage from day one, they must mean business. +- Most apps don't start on Windows Phone though. So if this app has a WP version, it must mean that their iOS \ Android versions are pretty good. Otherwise they would be still in the stage of perfecting their iOS \ Android app. +- If this app has anything to do with other users (social of any kind), I'd prefer the one that offers also Windows Phone support because I want as many people to be able to interact with me. Maybe even some of my friends have Windows Phones, and I wouldn't want to leave them out if I can choose. +- If I will ever want to switch to WP I will be able to, while maintaining my data \ settings \ connections since this app is cross-platform. +- Since they need support all major platform, they must have robust solution that is thoroughly tested. This means higher quality app. +- This company can afford to build and maintain three apps. It can't be a one man show or a small amateur group. They must be a well established company and idea. +- This company has a great vision of being ubiquitous, and they stand behind it. + +This is just me trying to justify my feelings when I see those three icons together. There's a lot going on inside your head when you see it, but either way the effect is positive. I think having those "three stars" is not just a matter of progress, it's a statement. + +Remember when we said earlier that if we think about it, only the best apps are available on all three platforms? Think about it the other way: If you are available on all three platforms, you will be considered one of the best apps. And to achieve cross platform support your missing piece is probably Windows Phone. diff --git a/_posts/2014-01-04-intuitive-vs-productive-ux.md b/_posts/2014-01-04-intuitive-vs-productive-ux.md new file mode 100644 index 0000000..0da23cb --- /dev/null +++ b/_posts/2014-01-04-intuitive-vs-productive-ux.md @@ -0,0 +1,53 @@ +--- +title: Intuitive vs. Productive UX +date: 2014-01-04 00:29 +categories: [Thoughts] +tags: [UI, UX, Windows8] +--- + +In my opinion intuitivity and productivity are two factors of a successful user experience design that are almost mutually exclusive. +Intuitive means that the users can quickly and easily learn how to work with the software. +Productive means that the user can work as efficiently as possible with the software, getting more done with minimal effort. + +I think of it like a slider, where in one side you have productive design, and on the other side intuitive design. + +![slider](/images/2014-01-04-intuitive-vs-productive-ux_1.png) + +I'm not a UX\UI expert, but I have some experience working with people on product planning, and this point is always surfaced. I don't think I have discovered it, or solved it. I merely recognize and name it. + +For the sake of this post I will use as an example something that is ubiquitous and familiar – navigating backwards within an app. +An intuitive solution might be to have a left facing arrow shaped button that contains the name of the previous screen (This is similar to the iPhone UI). +A Productive solution might be to use a fixed hardware button to go back (This is similar to the Windows Phone UI). +An even more productive UI will be to have the user swipe from left to right in order to navigate back (This is similar to IE on Windows 8). + +![navigate back](/images/2014-01-04-intuitive-vs-productive-ux_2.png) + +The point is that neither of these solutions is both super productive *and* super intuitive at the same time. There has to be some tradeoff, and each is located differently on our Productivity\Intuitivity slider + +![navigating back options on the slider](/images/2014-01-04-intuitive-vs-productive-ux_3.png) + +Let's take just 3 factors and examine each solution by each one of those factors: +1. Screen real estate – How much space the solution takes from the screen. Less is better, and more *productive* because it allows more content in the screen. +2. Learning about the function – How easy it is for a first time user to know that your software has this function, and to learn how to use it. Easier is better, and more *intuitive* because it takes less time for a user to learn how to use your program. +3. Using the function – How fast it is for a user that is already familiar with the feature to invoke it. Faster is better, and more *productive* because users can operate the software efficiently and get more done. + +We will scale each solution for each factor with 1-5 rank where 1 is better according to the description above. + +Parameter | On-Screen | Physical | gesture +--- | --- | --- | --- +Screen space | [4] | [3] Not instead of other UI | [0] No screen space at all! +Learn about | [2] Arrow shape and prev. screen text helps. Good location with other navigation controls | [3] Arrow shape helps. Detached from other navigation controls. Modern idiom. | [5] Impossible to learn without an explicit a hint or training! +Using | [3] Location and appearance might change in apps. Tapping is a basic gesture. | [3] Always there. Outside of comfort zone, hard to reach. Repeatable action, "muscle memory". | [2] Swiping can occur anywhere. Can be done blind fully. Swipping is not a basic gesture. + +I have been clinging on the backward navigation example just to make my point, but this is applied to almost everything. The principle is that you always have to think about where to place the slider between intuitive and productive design. +I was recently involved in a discussion around an app that has a single major use case for the UI which is a map with some controls on it. The controls were grouped into three collapsing menus that always appeared on top of the map and showed icons that represent the action. Some folks suggested that this design was not intuitive enough, and that a user won't know that he needs to expand the menus, and even then that the user won't be able to tell what the icons meant. They wanted a different kind of UI that was easier to understand. The other group tried to keep the UI as minimal as possible to leave as much space for the map itself (which is the major element in this app). This was a classical Intuitive vs. Productive debate. +Of course a first timer will have to stare at the screen for a while before realizing what to do. Also some trial and error learning is expected. On the other hand once the user is accustomed for the app, he probably wants as little distraction as possible, being able to perform tasks faster. + +My suggestion is to start with intuitive and then transition to productive. That can be in the form of having the menus expanded by default, or add tutorial for first time users. Maybe have a setting that allows advanced users get counter productive (but intuitive) stuff out of the UI. + +Another example is the App Bar in Windows Phone 8, that shows only the icons for the most usable actions. When opened it will show their description and other actions. So the first time I get to know an app I will open the app bar and see what every button do. But when I am using the app as a daily tool I just blindly click the icon. +I don't know if it's a design goal, but it fits my purpose here. + +![App Bar in default size](http://i.msdn.microsoft.com/dynimg/IC531095.png) + +Another place where this is extremely recognizable, is with the new UI of Windows 8. I think that the UI of Windows 8 is very productive, but no so intuitive. The main cause is that windows 8 relies too much on gestures. The most fundamental activities in an OS like showing settings, navigating inside an app, switching between apps, and so on – all of this is done by swiping from the edges. This is very productive once you get use to, but you do have to get use to it... diff --git a/_posts/2014-09-07-download-all-repositories-for-a-github-organization.md b/_posts/2014-09-07-download-all-repositories-for-a-github-organization.md new file mode 100644 index 0000000..a36cc8a --- /dev/null +++ b/_posts/2014-09-07-download-all-repositories-for-a-github-organization.md @@ -0,0 +1,12 @@ +--- +title: Download all repositories for a GitHub organization +date: 2014-09-07 22:52 +categories: [Technical-Howto] +tags: [Azure Active Directory, GitHub, PowerShell] +--- + +You might have noticed that Microsoft is now heavily using GitHub for projects, documentations and samples. + +I wanted to learn about Azure Active Directory, and found out they have a bunch of samples on GitHub. I wanted to get them all, and explore them one after the other, so I wrote a little script to get them. I figured it might be useful in other scenarios as well so here it is: + +{% gist itaysk/41bb2cf7cbc8559e0617 %} diff --git a/_posts/2014-10-20-wordpress-vs-umbraco.md b/_posts/2014-10-20-wordpress-vs-umbraco.md new file mode 100644 index 0000000..6f67a4a --- /dev/null +++ b/_posts/2014-10-20-wordpress-vs-umbraco.md @@ -0,0 +1,18 @@ +--- +title: Wordpress vs Umbraco +date: 2014-10-20 14:36 +categories: [Technical-Howto] +tags: [Azure Websites, Umbraco, Wordpress] +--- + +Lately with the rise of Azure Websites and the increased openness of Microsoft, I often find myself talking with customers about open source CMS systems for Azure Websites. +Although there are hundreds of open source CMs systems, usually most of these discussions boils down to the choice between Wordpress and Umbraco. As Microsoft doesn't have anything to compete in this arena, or any other preference it truly is an open discussion. + +I know that Wordpress is way more popular the Umbraco, and that in fact Azure Websites offers a special kind of solution called "Scalable Wordpress" for pain free highly-available Wordpress implementation, so initially it sounded like a Wordpress is the default choice, but I wasn't sure. +Technically I really don't know enough about either of them to compare, and I am not going to become an expert in both just to make a decision, so I turned to Google for the answer. + +![wp vs umbraco in google](/images/2014-10-20-wordpress-vs-umbraco_1.png) + +I searched for "Wordpress vs Umbraco" and followed every single link in the first page of results. I have found a consensus that Wordpress is good mostly for blogs, or small and simple websites, and Umbraco is more versatile and robust. It seems that although Wordpress is more simple to use for the end user, Umbraco offers more. The general vibe that I get reading those article was that of respect towards Umbraco and of hesitation towards Wordpress. Given my natural tendency towards .net as opposed to php, my gut feeling was reassured that Umbraco will be my default choice for the next experiment. + +Note: I don't know or pretend to know anything about Wordpress or Umbraco, this was a vary naïve search and I wanted to share the results. Also, These are the result I got, and [your's might differ](https://en.wikipedia.org/wiki/Filter_bubble). I performed the search in October 20, 2014. diff --git a/_posts/2014-10-30-i-will-be-speaking-at-microsoft-game-changer-event.md b/_posts/2014-10-30-i-will-be-speaking-at-microsoft-game-changer-event.md new file mode 100644 index 0000000..1a035f0 --- /dev/null +++ b/_posts/2014-10-30-i-will-be-speaking-at-microsoft-game-changer-event.md @@ -0,0 +1,14 @@ +--- +layout: post +title: I will be speaking at Microsoft Game Changer event +date: 2014-10-30 21:41 +categories: [Events] +tags: [Universal Apps] +--- + +Microsoft Israel is holding an event called "Game Changer" at November 25, 2014, at Cinema City, Glilot. +I will be speaking about Universal Apps in the DEV oriented track. +Info and registration: +[https://msevents.microsoft.com/cui/EventDetail.aspx?culture=he-IL&EventID=1032599788&](https://msevents.microsoft.com/cui/EventDetail.aspx?culture=he-IL&EventID=1032599788&) + +![invitation](/images/2014-10-30-i-will-be-speaking-at-microsoft-game-changer-event_1.png) diff --git a/_posts/2014-12-27-slides-and-video-from-my-session-about-universal-apps.md b/_posts/2014-12-27-slides-and-video-from-my-session-about-universal-apps.md new file mode 100644 index 0000000..d1d84b3 --- /dev/null +++ b/_posts/2014-12-27-slides-and-video-from-my-session-about-universal-apps.md @@ -0,0 +1,17 @@ +--- +title: Slides and Video From my Session About Universal Apps +date: 2014-12-27 19:47 +categories: [Technical-Howto] +tags: [Universal Apps] +--- + +Recently I had a session at an event called "Game Changer" that Microsoft organized. Here are the slides that I was using, and a video of the session (in Hebrew). + +Slides: +(no longer available) + +Video: [http://youtu.be/osR8847_cK0](http://youtu.be/osR8847_cK0) + + + +Feel free to share and reuse, with attribution please. diff --git a/_posts/2015-01-03-moving-to-a-new-role.md b/_posts/2015-01-03-moving-to-a-new-role.md new file mode 100644 index 0000000..c6a3cfd --- /dev/null +++ b/_posts/2015-01-03-moving-to-a-new-role.md @@ -0,0 +1,16 @@ +--- +title: Moving to a new role +date: 2015-01-03 17:52 +categories: [Events] +--- + +Starting January 1st 2015, I am moving from my current position at Microsoft as a Senior Consultant in MCS to being a Cloud Architect in EPG. If you don't work for (or closely with) Microsoft, this probably doesn't mean much to you, so allow me to explain: + +- I am leaving the Services organization which is a highly technical and specialized group to the EPG (Enterprise and Partners Group) organization which is more business and performance oriented. That being said I am still having a technical role in EPG, and I am still the same geek you knew before :) +- My day to day will be less about long term projects and delivery engagements, and more about Proof Of Concepts, knowledge transfer, architecture, and making sure customers are happy with Azure. +- I am no longer a billable resource which means you don't have to pay for my time. On the other hand, I am no longer in the professional services business so you can't just buy or ask for a bunch of my time. My time will be now dedicated to customers who are strategic to Microsoft and have interesting Azure workloads. +- **My main area of expertise is no longer SharePoint**. From now on my focus is Azure development. I plan to write on this transition in another post. + +So here's to 2015, I wish you all a great year! + +Itay Shakury. diff --git a/_posts/2015-02-09-platform-as-a-service-are-we-there-yet.md b/_posts/2015-02-09-platform-as-a-service-are-we-there-yet.md new file mode 100644 index 0000000..aabdc30 --- /dev/null +++ b/_posts/2015-02-09-platform-as-a-service-are-we-there-yet.md @@ -0,0 +1,29 @@ +--- +title: Platform as a Service – Are we there yet? +date: 2015-02-09 10:04 +categories: [Thoughts-Opinions] +tags: [Azure, Cloud, PaaS] +--- + +The following topic has been occupying my mind ever since the time I was first learning about Azure and Azure Cloud Services (aka Web and Worker Roles). At that time I was only beginning to understand "the cloud" but was already familiar with concepts such as IaaS and PaaS. Particularly, I was very much into the concept of PaaS. +Also at that time Azure was all about Cloud Services. There were no VMs or Websites or any of the other compute solution that are available today. So there I was, all in for the new PaaS stuff, excited to see Microsoft's take on it, and that's when it hit me. + +You see, hearing about PaaS in a theoretical (almost idealistic) manner, I was expecting an amorphic, boundless, elastic cloud, that you can just throw code at, let it do its thing, and you just get the result out. That's it. No infrastructure, no setup, no planning ahead, no fixed costs, and no commitments. I don't want to know the details such as what OS or stack this cloud is running. For all I'm concerned it's using hamsters to turn wheels that power a Turing machine to evaluate my code. As long as I get my response on time – I just don't care. +Imagine then how confused I was when one of the first things I learned about Azure (PaaS) is that you have to choose VM size and number of instances that will run your code. + +![paas scaling](/images/2015-02-09-platform-as-a-service-are-we-there-yet_1.png) + +What I had in mind back then (and what I still wish for today) was a pure PaaS solution. One that I think of like any utility service. From time to time I give talks about the cloud, and I like to use the analogy of electricity and cloud computing. When you consume electricity you don't think about how many generators are operating your neighborhood, or how much electricity each generator produces, you just stick your appliance in the wall and it just works. A true "as a service" experience. Likewise, when I put up a website up in the cloud, I don't want to think about how many servers are operating it, or how powerful each one of them has to be. I just want to give you my code let you run it. Charge me for what I used, just like electricity. + +Since that time where I started to learn about Azure Cloud Services, Azure introduced more PaaS solutions, like Azure Websites. I really like Azure Websites, and I think it's a step towards my ideal PaaS solution. For example, I actually like it that I can't RDP into the machine, and that you don't have to deal with the application stack. But still I have to choose VM sizes and instance count. +Amazon introduced lately AWS Lambda, which in my opinion is another step forward. I like that you are billed by the number of requests you make and the time it took to process them. That's a very "as a service" approach. You do have to choose the size of the compute node that will run you requests, but not the number of instances. + +I really hope to see this trend evolve. I hope that eventually we will get to a point where we can offer a true, pure platform as a service. +I do see the challenge though. Especially if you use current technologies to implement such platform. +There are other PaaS components today that does manage to offer this kind of experience. Storage, Queues and Media services are just some examples for services where this model is successful. The storage service is just that thing you throw files at, and it just works. You never have to think about how many computers operate it or what kind they are. + +What's the difference then? Why can it work for some cases and not the others? What's common to all those true PaaS solutions is that they are all very well defined services, very well scoped, and answer a very specific need. All users of these services use them the exact same way. A push to a queue is a push to a queue, the server side is very predictable. When you have a service like this, you can start standardizing the infrastructure and operations that run it. You can confidently estimate how much resources you require per request, and you can base your billing and SLA models on that instead of raw resources consumption. In the media services example, the algorithm to transcode from A to B is always the same algorithm. The only variable is the length and maybe the resolution of the movie. So you can take those parameters and make them your billing and SLA units. + +That is different from general compute applications. Are all web requests the same? Of course not. A request for a simple marketing campaign website is very different from a request for an image processing service, so it's very hard to fit them both into a unified pay by request model. You could start charging by the time it take to process the request, sounds fair, but what about latency requirements? How fast should your code run, is a question only you can answer, and something that is tightly coupled with your specific code. I can go on with this but I think you get the point – General compute is too general to be easily turned to "as a service". + +There are many issues involved with making my dream Platform as a Service, but I think it may be possible. Specialized services like those that I have mentioned and others are already providing this experience, and people love that. Technology companies (such as Microsoft) are pushing Platform as a Service and are making them the focus of innovation in today's technology, and businesses are seeing the value in it. We are ready for a truly elastic, self-managed PaaS solution, and I hope we will get to see one soon enough. diff --git a/_posts/2015-03-22-ill-be-speaking-at-the-iot-and-cloud-event.md b/_posts/2015-03-22-ill-be-speaking-at-the-iot-and-cloud-event.md new file mode 100644 index 0000000..b934788 --- /dev/null +++ b/_posts/2015-03-22-ill-be-speaking-at-the-iot-and-cloud-event.md @@ -0,0 +1,15 @@ +--- +title: I'll be speaking at the IoT and Cloud event +date: 2015-03-22 18:05 +categories: [ Events] +tags: [Cloud, IoT] +--- + +Talk about a short notice.. :) Tomorrow (23 March 2015) CVCon and CodeValue are hosting a conference at Cinema City Glilot about IoT and the cloud. +That was published a while ago, but just a couple of days ago I was asked to help under a short notice and deliver Microsoft's IoT pitch. + +So I will be delivering the closing session about Microsoft's doings in the IoT space and roadmap. + +Here's the invite: + +[https://www.eventbrite.com/e/cvcon-iot-cloud-registration-15602193581](https://www.eventbrite.com/e/cvcon-iot-cloud-registration-15602193581) diff --git a/_posts/2015-08-03-azure-load-balancer-in-resource-manager-arm.md b/_posts/2015-08-03-azure-load-balancer-in-resource-manager-arm.md new file mode 100644 index 0000000..a565d55 --- /dev/null +++ b/_posts/2015-08-03-azure-load-balancer-in-resource-manager-arm.md @@ -0,0 +1,108 @@ +--- +title: Azure Load Balancer in Resource Manager (ARM) +date: 2015-08-03 16:46 +categories: [Technical-Howto] +tags: [ARM, Azure, Load-Balancer, Network, node.js] +--- + +As part of the new Resource Manager (ARM) stack, and V2 resources, there are some changes to the experience of using load balancer in Azure. With the old stack, the load balancer was an integral part of the cloud service. Each VM had to reside in a cloud service, which came with a VIP that was automatically load balanced. With the new stack this isn't true anymore. Now every resource has to explicitly be created. This includes **Load Balancers**. + +Unfortunately there isn't a GUI for creating load balancer resources in the portal yet, so it has to be done in a template, or via CLI\PowerShell. There's a decent tutorial here: +[https://azure.microsoft.com/en-us/documentation/articles/load-balancer-arm-powershell/](https://azure.microsoft.com/en-us/documentation/articles/load-balancer-arm-powershell/). +It is a good read but it's not the simplest example you could have and also misses on adding load balancer to existing configurations, so I decided to create another walkthrough. + +## Step 1: Setting up the environment + +Log into the portal (portal.azure.com) and create a setup of 2 VMs in an availability set. Should have the following structure: + +- Resource group + - Storage account + - VNET + - 2 VMs (with all network dependency resources) + - Add the 2 VMs to an availability set. + +This is all done via the portal GUI. I am not going to detail the process here because it is straightforward. + +The end result should look like this: + +![resource group before](/images/2015-08-03-azure-load-balancer-in-resource-manager-arm_1.png) + +**In my case**, the names of resources are: + +- Resource group - iron + - Storage account - iron + - VNET - iron + - 2 VMs – iron1, iron3 + - NICs – iron1133, iron3750 + - NSG (one for both VMs) – iron + - PIPs – iron1, iron3 + - Availability set - ironA + +## Step 2: Setting up the load balancer +Here is a PowerShell script that adds a load balancer to the configuration: + +{% gist itaysk/2c717131c4557224bd63 %} + +Since this is an ad hoc activity, I did not take the time to factor the script into a function and input data into variables. **Please change everything in double quotes (") into your own appropriate values.** + +The end result should look like this: + +![resource group after](/images/2015-08-03-azure-load-balancer-in-resource-manager-arm_2.png) + +(BTW, after you create the load balancer you *can* manage it using the portal GUI) + +## Step 3: Testing +To test that it works, I created a simple web application that shows the internal IP address of the server. So if we access each server directly, we should get different results. If we access the load balancer we should get both results, depending on the server we reached. Here is an example: + +Accessing Iron1 always yields 10.2.0.4: + +![accessing Iron1](/images/2015-08-03-azure-load-balancer-in-resource-manager-arm_3.png) + +Accessing Iron3 always yields 10.2.0.6: + +![accessing Iron3](/images/2015-08-03-azure-load-balancer-in-resource-manager-arm_4.png) + +Accessing the load balancer can yield both results: + +![accessing lb 1st try](/images/2015-08-03-azure-load-balancer-in-resource-manager-arm_5.png) + +![accessing lb 2nd try](/images/2015-08-03-azure-load-balancer-in-resource-manager-arm_6.png) + +### The server identification web app +This is a simple node.js app that I have wrote: + +{% gist itaysk/6929551600d96c46d1fb %} + +To deploy it, do the following on both servers: +- RDP into the server +- Install node.js +- Create a folder, and a file called "app.js" in that folder with the code above. +- Open CMD and cd into the folder you created +- Run "node app.js" +- Turn off Windows Firewall + +Also you'll need to add a NSG rule to allow HTTP traffic to the servers (this is done via Azure portal). + +### Bonus: client testing tool +You still have to work hard on refreshing the load balancer page to convince yourself it worked, so I have also created a simple tool to demonstrate that over time, the load balancer actually works. + +The tool just hits the load balancer (http) and counts the number of times each result was received. + +![test1](/images/2015-08-03-azure-load-balancer-in-resource-manager-arm_7.png) + +![test2](/images/2015-08-03-azure-load-balancer-in-resource-manager-arm_8.png) + +`a` is the number of times we got 10.2.0.4, and `b` is the number of times we got 10.2.0.6. As you can see, eventually they even out. + +Here is the code to the test tool: + +{% gist itaysk/11ae6a47d9d159665c05 %} + +**Change the IP addresses to your addresses.** + +To run the test tool: +- Install node.js +- Create a folder, and a file called `app.js` in that folder with the code above. +- Open CMD and cd into the folder you created +- Run `npm install request` +- Run `node app.js` \ No newline at end of file diff --git a/_posts/2015-08-03-new-address.md b/_posts/2015-08-03-new-address.md new file mode 100644 index 0000000..6a47c19 --- /dev/null +++ b/_posts/2015-08-03-new-address.md @@ -0,0 +1,12 @@ +--- +title: New address +date: 2015-08-03 16:41 +categories: [Events] +--- + +Hi, I've changed the primary address of the blog from blog.itayasaservice.com to blog.itaysk.com . + +Why change? cause the old one was too long and when written in lowercase didn't make good initial impression. +Why itaysk? it's a domain I already own and use for other stuff. It's suppoed to stand for **ITAY S**ha**K**ury. + +Also: New Theme! yey diff --git a/_posts/2015-09-04-create-sql-db-from-arm-template-requestedserviceobjectiveid.md b/_posts/2015-09-04-create-sql-db-from-arm-template-requestedserviceobjectiveid.md new file mode 100644 index 0000000..ff2a503 --- /dev/null +++ b/_posts/2015-09-04-create-sql-db-from-arm-template-requestedserviceobjectiveid.md @@ -0,0 +1,15 @@ +--- +title: Create SQL DB from ARM template - requestedServiceObjectiveId +date: 2015-09-04 23:56 +categories: [Technical-Howto] +tags: [ARM, Azure, SQL] +--- + +If you try to create a Azure SQL Database from a ARM template, you probably went through [the docs](https://msdn.microsoft.com/en-us/library/azure/mt163685.aspx),  encountered in the mandatory property called `requestedServiceObjectiveId` which is defined as "The performance level for the database". That's essentially the [pricing tier](http://azure.microsoft.com/en-gb/pricing/details/sql-database/) that you choose for your DB. Now that we understand that, we can set a value for the field, but then we find out that the values for this property are GUIDs that correlate to the available performance levels. [the docs](https://msdn.microsoft.com/en-us/library/azure/mt163685.aspx) shows this example: +`"requestedServiceObjectiveId":"26e021db-f1f9-4c98-84c6-92af8ef433d7"` +Those GUIDs are currently very hard to find. The upcoming Azure PowerShell 0.9.8 [will include](https://github.com/Azure/azure-powershell/pull/792) a cmdlet for that. But even so, why using GUIDs when we can use names... + +## A better solution +There's an undocumented property called `requestedServiceObjectiveName` which allows you to use the pricing tier name like: +`"requestedServiceObjectiveName": "S1"` +As I said it's not documented but confirmed working and makes your template a lot more easy to both write and read. diff --git a/_posts/2015-10-14-ill-be-speaking-at-microsoft-defense-day-tomorrow.md b/_posts/2015-10-14-ill-be-speaking-at-microsoft-defense-day-tomorrow.md new file mode 100644 index 0000000..9ba8d8b --- /dev/null +++ b/_posts/2015-10-14-ill-be-speaking-at-microsoft-defense-day-tomorrow.md @@ -0,0 +1,13 @@ +--- +title: I'll be speaking at Microsoft Defense Day tomorrow +date: 2015-10-14 20:31 +categories: [Events] +--- + +I will be speaking at "Microsoft Defense Day" - an event dedicated to Public Safety & National Security Defense sector in Israel. The event will take place 15 October, 2015, at Casiopea, Herzlya. +[http://www.microsoft.com/israel/promotionalMail/defense/invi/](http://www.microsoft.com/israel/promotionalMail/defense/invi/) + +My session is at 12:25 about Mission Critical Big Data. +The event is "TED style" short sessions - so my session will be more inspirational than informative. + +![invite](/images/2015-10-14-ill-be-speaking-at-microsoft-defense-day-tomorrow_1.png) \ No newline at end of file diff --git a/_posts/2015-11-19-ill-be-speaking-at-azure-tour-tel-aviv.md b/_posts/2015-11-19-ill-be-speaking-at-azure-tour-tel-aviv.md new file mode 100644 index 0000000..8857881 --- /dev/null +++ b/_posts/2015-11-19-ill-be-speaking-at-azure-tour-tel-aviv.md @@ -0,0 +1,14 @@ +--- +title: I'll be speaking at Azure Tour Tel-Aviv +date: 2015-11-19 21:28 +categories: [Events] +tags: [Azure] +--- + +Azure Tour is the biggest Azure focused event of the year. It is running all around the world, and it is coming to Tel-Aviv on December 2, 2015. +See more details and register here: [https://microsoft.eventcore.com/azuretour/telaviv/](https://microsoft.eventcore.com/azuretour/telaviv/) + +We will be running a side track during the event focused on BDMs (Business Decision Makers) - where me and my team will give a session called "Innovation in Azure" that will cover a lot of cool topics and demos. +Registration is open and free (for the general track). Hope to see you there! + +![sign](/images/2015-11-19-ill-be-speaking-at-azure-tour-tel-aviv_1.jpg) \ No newline at end of file diff --git a/_posts/2016-03-29-ill-be-speaking-at-microsoft-cto-breakfast-club.md b/_posts/2016-03-29-ill-be-speaking-at-microsoft-cto-breakfast-club.md new file mode 100644 index 0000000..d5c8c2d --- /dev/null +++ b/_posts/2016-03-29-ill-be-speaking-at-microsoft-cto-breakfast-club.md @@ -0,0 +1,13 @@ +--- +title: I'll be speaking at Microsoft CTO Breakfast Club +date: 2016-03-29 14:46 +categories: [Events] +--- + +The CTO Breakfast Club is a by invitation only gathering of CTOs, Architects, Tech Leads, that meet to share ideas and experiences, and have a quick breakfast together while their at it (If you meet the description and are not in the club - contact me @itayasaservice). + +This meeting is on 31-March-2016 in SOSA Tel Aviv. + +I will be speaking with Gal Klein, CTO from [AudioBurst](http://audioburst.com). Together we will present their architecture, technical decisions and general experience from building their product on Azure. + +![cto breakfast](/images/2016-03-29-ill-be-speaking-at-microsoft-cto-breakfast-club_1.jpg) diff --git a/_posts/2016-05-24-ill-be-speaking-at-open-first-2016.md b/_posts/2016-05-24-ill-be-speaking-at-open-first-2016.md new file mode 100644 index 0000000..969d1a1 --- /dev/null +++ b/_posts/2016-05-24-ill-be-speaking-at-open-first-2016.md @@ -0,0 +1,16 @@ +--- +title: I'll be speaking at Open First 2016 +date: 2016-05-24 13:09 +categories: [Events] +--- + +I'll be speaking at Open First 2016 - Linnovate's annual Open source conference. + +![open first 2016](/images/2016-05-24-ill-be-speaking-at-open-first-2016_1.jpg) + +I will be talking about [Bash on Windows](https://msdn.microsoft.com/en-us/commandline/wsl/about) together with my colleague Yaron Schneider. + +The event will take place 24 May 2016 at Microsoft Offices, Hapnina 2m Rannana, starting at 15:00. + +Registration is free in the following link: +[http://www.linnovate.net/open-first-2016](http://www.linnovate.net/open-first-2016) diff --git a/_posts/2016-06-05-ill-be-speaking-at-microsoft-cto-breakfast-club-2.md b/_posts/2016-06-05-ill-be-speaking-at-microsoft-cto-breakfast-club-2.md new file mode 100644 index 0000000..943c992 --- /dev/null +++ b/_posts/2016-06-05-ill-be-speaking-at-microsoft-cto-breakfast-club-2.md @@ -0,0 +1,19 @@ +--- +title: I'll be speaking at Microsoft CTO Breakfast Club +date: 2016-06-05 13:01 +categories: [Events] +--- + +Following the tradition, We will have another meeting of the Microsoft CTO Breakfast Club, with a customer sharing it's architecture on Azure. +This time we will have a special guest - Scott Guthrie (the man in charge of all Azure)! + +Right after Scott's session, me and my colleague Yaron Schneider will host a "CTO Corner" session, where 2 startups will join us on stage for brainstorming their architecture on Azure. + +The event takes place June 6,2016, starting 09:30 at Talkhouse Tel-Aviv. + +Since this event is by invite only, registration is closed, details can be found here: +[https://www.microsoft.com/israel/promotionalMail/CTO/Breakfast_club/Jun16/index.html](https://www.microsoft.com/israel/promotionalMail/CTO/Breakfast_club/Jun16/index.html) + +If you were not invited and want to, please contact me (Twitter:@itayasaservice \ Linkedin:itaysk) + +![cto breakfast](/images/2016-06-05-ill-be-speaking-at-microsoft-cto-breakfast-club_cto_1.png) diff --git a/_posts/2016-06-14-ill-be-speaking-at-sela-developer-practice-sdp-2016.md b/_posts/2016-06-14-ill-be-speaking-at-sela-developer-practice-sdp-2016.md new file mode 100644 index 0000000..5f4568e --- /dev/null +++ b/_posts/2016-06-14-ill-be-speaking-at-sela-developer-practice-sdp-2016.md @@ -0,0 +1,12 @@ +--- +title: I'll be speaking at Sela Developer Practice (SDP) 2016 +date: 2016-06-14 16:52 +categories: [Events] +--- +I will be speaking at Sela Developer Practice (SDP) 2016 - one of the largest developer conferences in Israel. +The event will take place at 19-23 June 2016 at Cinema City in Rishon Letzion. + +I will be joining my colleagues Assaf Jacoby and Tomer Rosenthal to delivering the second day keynote (21 June, 09:45) . In the keynote, we will discuss and present recent developer innovations from Microsoft including: Bash on Windows, Azure Container Service, Service Fabric, and more... (It's a keynote so no deep dive, just an overview and a short demo) + +Information and registration in the following link: +[http://seladeveloperpractice.com/](http://seladeveloperpractice.com/) \ No newline at end of file diff --git a/_posts/2016-07-07-how-i-interview.md b/_posts/2016-07-07-how-i-interview.md new file mode 100644 index 0000000..9111750 --- /dev/null +++ b/_posts/2016-07-07-how-i-interview.md @@ -0,0 +1,90 @@ +--- +title: How I interview +date: 2016-07-07 23:24 +categories: [Thoughts-Opinions] +--- + +So many times over the past decade I was that guy on the other side of the table, the one obstacle between you and your next job. I never held a management position but was always an appreciated senior technical figure, so I was often trusted with doing the technical interview. I also was present in many interviews as an observer, and saw other people interview, so I think I have a pretty solid perspective on this process. + +Let me start by saying something that sounded obvious to some but at the same time surprised others: **Interviewing is hard!**. Think about it, you have to judge someone's technical skill according to a one-hour chat. That's impossible! Added the stress that usually accompany candidates in interviews, it makes interviewing a hard task. + +So here I'd like to discuss how I interview. I don't know if it's the best advice, or the only one, but I know that I strongly believe following these guidelines makes me a better interviewer. + +## Don'ts +Let's start with the things I won't do in an interview, or I disliked seeing other interviewers do: + +### Give them hell +This is a very common approach for interviewers, that try to pressure and give candidates a hard time with questions. This might come as offensive interrogation style line of questions, or just noticing a doubt or a weak spot with the candidate and grill them on that. + +One time an interviewer told me that first he beats the candidate to the floor by picking on their knowledge gaps, and then let them recover with easier questions. + +Obviously I strongly oppose. My approach is that it is in your (the interviewer's) best interest to bring out the best of the candidate, in order to really see "what they really worth". An interview is stressful enough situation for the candidate which means that for most people they are at their 70% to begin with. Adding more stress and FUD only makes it worse and instead of helping you to see the candidate's true potential, you make them deliver half their potential at best. What you should do instead is support and embrace them from the beginning, and help them build confidence so they're at their 100%. Now you can see who they really are under the FUD mask. + +> "it is in your (the interviewer's) best interest to bring out the best of the candidate" + +### Crazy riddles +You know how many windows there are in New York? Who cares, that's how many. Enough with the stupid riddles, mind games, MBA quizzed and "IQ" tests. Decide what competencies you are looking for in the candidate based on the role and requirements, and look for those. If you are recruiting an analyst it might be relevant to feel their sense of perspective using a question like this, or if the riddle is just an informal way to ask a programming question, so be it. But it feels like people ask this questions to determine if "you are smart", and that's what I am mostly against. + +### Computer Science questions +This is a controversial one. If you are looking for a programmer, front-end, back-end, or whatever, chances are what you are looking for is someone with skills in the technology that your team is invested in, and some solid understanding of programming concepts. Because let's be honest, when is the last time you had to write your own sorting algorithm? + +> Let's be honest, when is the last time you had to write your own sorting algorithm? + +I think we should have different expectations from those who develop products, and those who develop technologies. Those developing a technology should definitely know the theory of their trade, so the one developing the game's engine should know physics, and the one developing the database should know data structures and complexity. But for most developers who don't build technologies, but use them to build products, this is unnecessary. + +Oh, and please leave your fancy university pride out of it. People who went to colleges can be just as good and talented, and people without higher level education as well. I hate it when good people gets screened out by HR based on their education history alone. + +### People are not compilers +No one writes perfect code at first run, and so doesn't you. So don't expect everyone to remember all the quirks and features of a language of the top of their head. That's what compilers are for. Yes – ask about important language features and even ask to demonstrate or use them. No – don't ask the candidate to spot a null reference exception on paper. + +## Do's +Here I'd like to share what I do like doing in an interview: + +### Start with asking about past experience +In my opinion past experience is the most important criteria to determine one's abilities. Never mind what you remember right now, show me what you are capable of. + +> Never mind what you remember right now, show me what you are capable of + +You should also deep dive into a project \ product \ feature they did. + +"Tell me more about XYZ you just mentioned. How was it designed, implemented, why did you choose X over Y, how did you manage this and that" + +This is your place to start and challenge with follow up questions about things they did. This is OK because it's things they did, not a question you made based on your knowledge. + +This is a very important step. You might think this is too easy, asking people about things they already know and had plenty of time to think about, but you will be surprised how many candidates don't invest in fully understanding the domain, the technology and the details of what they did. Some programmers just write code, not develop software. If someone can't convince you of his abilities by talking about stuff they already did (and they chose to discuss) than this is a bad sign. + +### Ask about their strong \ favorite skills +This serves multiple purposes: +- Boosts their confidence that you are on their side and help them be their 100%. +- The topics they pick here can say a lot about their background, breadth of knowledge. +- In my opinion a developer needs to love their job, and should have at least few technologies that makes them feel. +- By picking on those topics you can challenge the candidate even deeper without being a prick, because they stated that they are good at. + +There's one caveat here – you might not know what to ask if it's something you don't know too well. If you are recruiting to a specific role and know what screening process they went through you usually know what to expect here. I did some interviews for architect positions, where people come with various different backgrounds and career paths, and picked topics I knew nothing about. In this case I might ask the candidate to explain or introduce the topic to me (also a good test), and try to ask cross cutting questions that apply to every technology. + +### What you like \ dislike about technology XYZ +This is by far my favorite question to ask. In order to develop love \ hate relationship to something you need to go through some mileage, and by answering this question you can see how much mileage was done there. + +### Define foo +Again, a simple question that reveals a lot. Some things we are so used to, that we forgot to think about what they are good for. "What's the web? What's JavaScript? What's HTTP? What's HTML?" – I know it sounds stupid, but it's so refreshingly fun to talk with a web developer about what these things really are to them. Think for a moment about how you would answer each + +### Hands on tasks – good. Homework – better. Portfolio – best. +There's only so much you can just talk about technology, and remember that at the end of this one hour meeting you have to determine whether or not this candidate will do a good job or not, not weather they are a good interviewees or not. So why not just see how well they are at their job. + +> remember that at the end of this one hour meeting you have to determine whether or not this candidate will do a good job or not, not whether they are a good interviewees or not + +It's a good idea to let them do a hands on tasks, but here are the rules: +- If it's a design question, then white board is your friends, but please - no white board programming. Unless it's pseudo code or just a draft for a solution. +- Let them choose the technology \ programming language \ tools they are comfortable with. +- Allow unlimited use of the internet. Google, Stack Overflow are a developer's best friends. +- Don't lean over their shoulder, leave them be, even leave the room. +- Be clear about the problem, success criteria, and times. + +It is common to see hands on tests during technical interviews. It might be even better to take the test offline, let them complete it at home, before the interview or after. But in my opinion the best thing to is to see something they already did. It's the best representation of what they can really do outside the artificial boundaries of the interview. + +> see something they already did. It's the best representation of what they can really do outside the artificial boundaries of the interview + +A note about cheating: There is no such thing as cheating in software development. Googling the answer, copy-pasting from Stack Overflow, using something from GitHub (unless it's what the task was about), and even calling a friend for advice are all legitimate ways to solve the problem. You know why? Because there are all also available to them in the real world. And besides, Googling is also an important skill for developers to master, and being connected to smart friends who can help will be an asset for your team. If your other developers on the team can do it, so can the candidate during the interview. + +## Summary +As I said, interviewing is hard. I always find it too hard to summarize a person into a few sentences in a textbox, and even harder checking that Hire\No Hire checkbox. So far I don't regret any decision I have made about hiring, and have always managed to value people's qualities, and flaws. I hope this will help you think about how *you* do interviews, and maybe also help interviewees prepare better for the process. diff --git a/_posts/t.md b/_posts/t.md new file mode 100644 index 0000000..e33cd6a --- /dev/null +++ b/_posts/t.md @@ -0,0 +1,8 @@ +--- +layout: post +title: t +date: 2016-10-01 23:24 +categories: [Thoughts-Opinions] +--- + +fff \ No newline at end of file diff --git a/_sass/_bootstrap.scss b/_sass/_bootstrap.scss new file mode 100644 index 0000000..e72d1de --- /dev/null +++ b/_sass/_bootstrap.scss @@ -0,0 +1,56 @@ +/*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ + +// Core variables and mixins +@import "bootstrap/variables"; +@import "bootstrap/mixins"; + +// Reset and dependencies +@import "bootstrap/normalize"; +@import "bootstrap/print"; +@import "bootstrap/glyphicons"; + +// Core CSS +@import "bootstrap/scaffolding"; +@import "bootstrap/type"; +@import "bootstrap/code"; +@import "bootstrap/grid"; +@import "bootstrap/tables"; +@import "bootstrap/forms"; +@import "bootstrap/buttons"; + +// Components +@import "bootstrap/component-animations"; +@import "bootstrap/dropdowns"; +@import "bootstrap/button-groups"; +@import "bootstrap/input-groups"; +@import "bootstrap/navs"; +@import "bootstrap/navbar"; +@import "bootstrap/breadcrumbs"; +@import "bootstrap/pagination"; +@import "bootstrap/pager"; +@import "bootstrap/labels"; +@import "bootstrap/badges"; +@import "bootstrap/jumbotron"; +@import "bootstrap/thumbnails"; +@import "bootstrap/alerts"; +@import "bootstrap/progress-bars"; +@import "bootstrap/media"; +@import "bootstrap/list-group"; +@import "bootstrap/panels"; +@import "bootstrap/responsive-embed"; +@import "bootstrap/wells"; +@import "bootstrap/close"; + +// Components w/ JavaScript +@import "bootstrap/modals"; +@import "bootstrap/tooltip"; +@import "bootstrap/popovers"; +@import "bootstrap/carousel"; + +// Utility classes +@import "bootstrap/utilities"; +@import "bootstrap/responsive-utilities"; diff --git a/_sass/_includes/disqus_comments.html b/_sass/_includes/disqus_comments.html new file mode 100644 index 0000000..642301f --- /dev/null +++ b/_sass/_includes/disqus_comments.html @@ -0,0 +1,25 @@ +{% if page.comments != false and jekyll.environment == "production" %} + {% if site.url %} + {% assign disqus_url = page.url | prepend: site.url %} + {% elsif site.github.url %} + {% assign disqus_url = page.url | prepend: site.github.url %} + {% endif %} + +
+ + +{% endif %} diff --git a/_sass/_includes/footer.html b/_sass/_includes/footer.html new file mode 100644 index 0000000..6ef8e82 --- /dev/null +++ b/_sass/_includes/footer.html @@ -0,0 +1,5 @@ + diff --git a/_sass/_includes/google-analytics.html b/_sass/_includes/google-analytics.html new file mode 100644 index 0000000..eb2a692 --- /dev/null +++ b/_sass/_includes/google-analytics.html @@ -0,0 +1,11 @@ + + diff --git a/_sass/_includes/head.html b/_sass/_includes/head.html new file mode 100644 index 0000000..a606797 --- /dev/null +++ b/_sass/_includes/head.html @@ -0,0 +1,20 @@ + + + + + + {% if page.title %}{{ page.title | escape }}{% else %}{{ site.title | escape }}{% endif %} + + + {% assign custom_url = site.url | append: site.baseurl %} + {% assign full_base_url = custom_url | default: site.github.url %} + + + + + + + {% if jekyll.environment == 'production' and site.google_analytics %} + {% include google-analytics.html %} + {% endif %} + diff --git a/_sass/_includes/header.html b/_sass/_includes/header.html new file mode 100644 index 0000000..56bbea8 --- /dev/null +++ b/_sass/_includes/header.html @@ -0,0 +1,15 @@ +
+ {% assign custom_url = site.url | append: site.baseurl %} {% assign full_base_url = site.github.url | default: custom_url %} + + {{ site.title | escape }} + + +
\ No newline at end of file diff --git a/_sass/_includes/sidebar.html b/_sass/_includes/sidebar.html new file mode 100644 index 0000000..a399e08 --- /dev/null +++ b/_sass/_includes/sidebar.html @@ -0,0 +1,26 @@ + \ No newline at end of file diff --git a/_sass/_layouts/default.html b/_sass/_layouts/default.html new file mode 100644 index 0000000..d3ff96c --- /dev/null +++ b/_sass/_layouts/default.html @@ -0,0 +1,26 @@ + + +{% include head.html %} + + +
+ {% include header.html %} +
+
+
+
+ {% include sidebar.html %} +
+
+ {{ content }} +
+
+
+
+ {% include footer.html %} +
+
+
+ + + \ No newline at end of file diff --git a/_sass/_layouts/page.html b/_sass/_layouts/page.html new file mode 100644 index 0000000..01e4b2a --- /dev/null +++ b/_sass/_layouts/page.html @@ -0,0 +1,14 @@ +--- +layout: default +--- +
+ +
+

{{ page.title | escape }}

+
+ +
+ {{ content }} +
+ +
diff --git a/_sass/_layouts/post.html b/_sass/_layouts/post.html new file mode 100644 index 0000000..1d36c28 --- /dev/null +++ b/_sass/_layouts/post.html @@ -0,0 +1,18 @@ +--- +layout: default +--- +
+ +
+

{{ page.title | escape }}

+ +
+ +
+ {{ content }} +
+ + {% if site.disqus.shortname %} + {% include disqus_comments.html %} + {% endif %} +
diff --git a/_sass/_syntax-highlighting.scss b/_sass/_syntax-highlighting.scss new file mode 100644 index 0000000..5f57ea2 --- /dev/null +++ b/_sass/_syntax-highlighting.scss @@ -0,0 +1,79 @@ +/* from minima.scss */ +$spacing-unit: 30px !default; + +/* from _base.scss */ +%vertical-rhythm { + margin-bottom: $spacing-unit / 2; +} + +/** + * Syntax highlighting styles + */ +.highlight { + background: #fff; + @extend %vertical-rhythm; + + .highlighter-rouge & { + background: #eef; + } + + .c { color: #998; font-style: italic } // Comment + .err { color: #a61717; background-color: #e3d2d2 } // Error + .k { font-weight: bold } // Keyword + .o { font-weight: bold } // Operator + .cm { color: #998; font-style: italic } // Comment.Multiline + .cp { color: #999; font-weight: bold } // Comment.Preproc + .c1 { color: #998; font-style: italic } // Comment.Single + .cs { color: #999; font-weight: bold; font-style: italic } // Comment.Special + .gd { color: #000; background-color: #fdd } // Generic.Deleted + .gd .x { color: #000; background-color: #faa } // Generic.Deleted.Specific + .ge { font-style: italic } // Generic.Emph + .gr { color: #a00 } // Generic.Error + .gh { color: #999 } // Generic.Heading + .gi { color: #000; background-color: #dfd } // Generic.Inserted + .gi .x { color: #000; background-color: #afa } // Generic.Inserted.Specific + .go { color: #888 } // Generic.Output + .gp { color: #555 } // Generic.Prompt + .gs { font-weight: bold } // Generic.Strong + .gu { color: #aaa } // Generic.Subheading + .gt { color: #a00 } // Generic.Traceback + .kc { font-weight: bold } // Keyword.Constant + .kd { font-weight: bold } // Keyword.Declaration + .kp { font-weight: bold } // Keyword.Pseudo + .kr { font-weight: bold } // Keyword.Reserved + .kt { color: #458; font-weight: bold } // Keyword.Type + .m { color: #099 } // Literal.Number + .s { color: #d14 } // Literal.String + .na { color: #008080 } // Name.Attribute + .nb { color: #0086B3 } // Name.Builtin + .nc { color: #458; font-weight: bold } // Name.Class + .no { color: #008080 } // Name.Constant + .ni { color: #800080 } // Name.Entity + .ne { color: #900; font-weight: bold } // Name.Exception + .nf { color: #900; font-weight: bold } // Name.Function + .nn { color: #555 } // Name.Namespace + .nt { color: #000080 } // Name.Tag + .nv { color: #008080 } // Name.Variable + .ow { font-weight: bold } // Operator.Word + .w { color: #bbb } // Text.Whitespace + .mf { color: #099 } // Literal.Number.Float + .mh { color: #099 } // Literal.Number.Hex + .mi { color: #099 } // Literal.Number.Integer + .mo { color: #099 } // Literal.Number.Oct + .sb { color: #d14 } // Literal.String.Backtick + .sc { color: #d14 } // Literal.String.Char + .sd { color: #d14 } // Literal.String.Doc + .s2 { color: #d14 } // Literal.String.Double + .se { color: #d14 } // Literal.String.Escape + .sh { color: #d14 } // Literal.String.Heredoc + .si { color: #d14 } // Literal.String.Interpol + .sx { color: #d14 } // Literal.String.Other + .sr { color: #009926 } // Literal.String.Regex + .s1 { color: #d14 } // Literal.String.Single + .ss { color: #990073 } // Literal.String.Symbol + .bp { color: #999 } // Name.Builtin.Pseudo + .vc { color: #008080 } // Name.Variable.Class + .vg { color: #008080 } // Name.Variable.Global + .vi { color: #008080 } // Name.Variable.Instance + .il { color: #099 } // Literal.Number.Integer.Long +} diff --git a/_sass/bootstrap/_alerts.scss b/_sass/bootstrap/_alerts.scss new file mode 100644 index 0000000..7d1e1fd --- /dev/null +++ b/_sass/bootstrap/_alerts.scss @@ -0,0 +1,73 @@ +// +// Alerts +// -------------------------------------------------- + + +// Base styles +// ------------------------- + +.alert { + padding: $alert-padding; + margin-bottom: $line-height-computed; + border: 1px solid transparent; + border-radius: $alert-border-radius; + + // Headings for larger alerts + h4 { + margin-top: 0; + // Specified for the h4 to prevent conflicts of changing $headings-color + color: inherit; + } + + // Provide class for links that match alerts + .alert-link { + font-weight: $alert-link-font-weight; + } + + // Improve alignment and spacing of inner content + > p, + > ul { + margin-bottom: 0; + } + + > p + p { + margin-top: 5px; + } +} + +// Dismissible alerts +// +// Expand the right padding and account for the close button's positioning. + +.alert-dismissable, // The misspelled .alert-dismissable was deprecated in 3.2.0. +.alert-dismissible { + padding-right: ($alert-padding + 20); + + // Adjust close link position + .close { + position: relative; + top: -2px; + right: -21px; + color: inherit; + } +} + +// Alternate styles +// +// Generate contextual modifier classes for colorizing the alert. + +.alert-success { + @include alert-variant($alert-success-bg, $alert-success-border, $alert-success-text); +} + +.alert-info { + @include alert-variant($alert-info-bg, $alert-info-border, $alert-info-text); +} + +.alert-warning { + @include alert-variant($alert-warning-bg, $alert-warning-border, $alert-warning-text); +} + +.alert-danger { + @include alert-variant($alert-danger-bg, $alert-danger-border, $alert-danger-text); +} diff --git a/_sass/bootstrap/_badges.scss b/_sass/bootstrap/_badges.scss new file mode 100644 index 0000000..70002e0 --- /dev/null +++ b/_sass/bootstrap/_badges.scss @@ -0,0 +1,68 @@ +// +// Badges +// -------------------------------------------------- + + +// Base class +.badge { + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: $font-size-small; + font-weight: $badge-font-weight; + color: $badge-color; + line-height: $badge-line-height; + vertical-align: middle; + white-space: nowrap; + text-align: center; + background-color: $badge-bg; + border-radius: $badge-border-radius; + + // Empty badges collapse automatically (not available in IE8) + &:empty { + display: none; + } + + // Quick fix for badges in buttons + .btn & { + position: relative; + top: -1px; + } + + .btn-xs &, + .btn-group-xs > .btn & { + top: 0; + padding: 1px 5px; + } + + // [converter] extracted a& to a.badge + + // Account for badges in navs + .list-group-item.active > &, + .nav-pills > .active > a > & { + color: $badge-active-color; + background-color: $badge-active-bg; + } + + .list-group-item > & { + float: right; + } + + .list-group-item > & + & { + margin-right: 5px; + } + + .nav-pills > li > a > & { + margin-left: 3px; + } +} + +// Hover state, but only for links +a.badge { + &:hover, + &:focus { + color: $badge-link-hover-color; + text-decoration: none; + cursor: pointer; + } +} diff --git a/_sass/bootstrap/_breadcrumbs.scss b/_sass/bootstrap/_breadcrumbs.scss new file mode 100644 index 0000000..b61f0c7 --- /dev/null +++ b/_sass/bootstrap/_breadcrumbs.scss @@ -0,0 +1,28 @@ +// +// Breadcrumbs +// -------------------------------------------------- + + +.breadcrumb { + padding: $breadcrumb-padding-vertical $breadcrumb-padding-horizontal; + margin-bottom: $line-height-computed; + list-style: none; + background-color: $breadcrumb-bg; + border-radius: $border-radius-base; + + > li { + display: inline-block; + + + li:before { + // [converter] Workaround for https://github.com/sass/libsass/issues/1115 + $nbsp: "\00a0"; + content: "#{$breadcrumb-separator}#{$nbsp}"; // Unicode space added since inline-block means non-collapsing white-space + padding: 0 5px; + color: $breadcrumb-color; + } + } + + > .active { + color: $breadcrumb-active-color; + } +} diff --git a/_sass/bootstrap/_button-groups.scss b/_sass/bootstrap/_button-groups.scss new file mode 100644 index 0000000..4b385f5 --- /dev/null +++ b/_sass/bootstrap/_button-groups.scss @@ -0,0 +1,244 @@ +// +// Button groups +// -------------------------------------------------- + +// Make the div behave like a button +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-block; + vertical-align: middle; // match .btn alignment given font-size hack above + > .btn { + position: relative; + float: left; + // Bring the "active" button to the front + &:hover, + &:focus, + &:active, + &.active { + z-index: 2; + } + } +} + +// Prevent double borders when buttons are next to each other +.btn-group { + .btn + .btn, + .btn + .btn-group, + .btn-group + .btn, + .btn-group + .btn-group { + margin-left: -1px; + } +} + +// Optional: Group multiple button groups together for a toolbar +.btn-toolbar { + margin-left: -5px; // Offset the first child's margin + @include clearfix; + + .btn, + .btn-group, + .input-group { + float: left; + } + > .btn, + > .btn-group, + > .input-group { + margin-left: 5px; + } +} + +.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { + border-radius: 0; +} + +// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match +.btn-group > .btn:first-child { + margin-left: 0; + &:not(:last-child):not(.dropdown-toggle) { + @include border-right-radius(0); + } +} +// Need .dropdown-toggle since :last-child doesn't apply, given that a .dropdown-menu is used immediately after it +.btn-group > .btn:last-child:not(:first-child), +.btn-group > .dropdown-toggle:not(:first-child) { + @include border-left-radius(0); +} + +// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group) +.btn-group > .btn-group { + float: left; +} +.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group > .btn-group:first-child:not(:last-child) { + > .btn:last-child, + > .dropdown-toggle { + @include border-right-radius(0); + } +} +.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { + @include border-left-radius(0); +} + +// On active and open, don't show outline +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} + + +// Sizing +// +// Remix the default button sizing classes into new ones for easier manipulation. + +.btn-group-xs > .btn { @extend .btn-xs; } +.btn-group-sm > .btn { @extend .btn-sm; } +.btn-group-lg > .btn { @extend .btn-lg; } + + +// Split button dropdowns +// ---------------------- + +// Give the line between buttons some depth +.btn-group > .btn + .dropdown-toggle { + padding-left: 8px; + padding-right: 8px; +} +.btn-group > .btn-lg + .dropdown-toggle { + padding-left: 12px; + padding-right: 12px; +} + +// The clickable button for toggling the menu +// Remove the gradient and set the same inset shadow as the :active state +.btn-group.open .dropdown-toggle { + @include box-shadow(inset 0 3px 5px rgba(0,0,0,.125)); + + // Show no shadow for `.btn-link` since it has no other button styles. + &.btn-link { + @include box-shadow(none); + } +} + + +// Reposition the caret +.btn .caret { + margin-left: 0; +} +// Carets in other button sizes +.btn-lg .caret { + border-width: $caret-width-large $caret-width-large 0; + border-bottom-width: 0; +} +// Upside down carets for .dropup +.dropup .btn-lg .caret { + border-width: 0 $caret-width-large $caret-width-large; +} + + +// Vertical button groups +// ---------------------- + +.btn-group-vertical { + > .btn, + > .btn-group, + > .btn-group > .btn { + display: block; + float: none; + width: 100%; + max-width: 100%; + } + + // Clear floats so dropdown menus can be properly placed + > .btn-group { + @include clearfix; + > .btn { + float: none; + } + } + + > .btn + .btn, + > .btn + .btn-group, + > .btn-group + .btn, + > .btn-group + .btn-group { + margin-top: -1px; + margin-left: 0; + } +} + +.btn-group-vertical > .btn { + &:not(:first-child):not(:last-child) { + border-radius: 0; + } + &:first-child:not(:last-child) { + @include border-top-radius($btn-border-radius-base); + @include border-bottom-radius(0); + } + &:last-child:not(:first-child) { + @include border-top-radius(0); + @include border-bottom-radius($btn-border-radius-base); + } +} +.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group-vertical > .btn-group:first-child:not(:last-child) { + > .btn:last-child, + > .dropdown-toggle { + @include border-bottom-radius(0); + } +} +.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { + @include border-top-radius(0); +} + + +// Justified button groups +// ---------------------- + +.btn-group-justified { + display: table; + width: 100%; + table-layout: fixed; + border-collapse: separate; + > .btn, + > .btn-group { + float: none; + display: table-cell; + width: 1%; + } + > .btn-group .btn { + width: 100%; + } + + > .btn-group .dropdown-menu { + left: auto; + } +} + + +// Checkbox and radio options +// +// In order to support the browser's form validation feedback, powered by the +// `required` attribute, we have to "hide" the inputs via `clip`. We cannot use +// `display: none;` or `visibility: hidden;` as that also hides the popover. +// Simply visually hiding the inputs via `opacity` would leave them clickable in +// certain cases which is prevented by using `clip` and `pointer-events`. +// This way, we ensure a DOM element is visible to position the popover from. +// +// See https://github.com/twbs/bootstrap/pull/12794 and +// https://github.com/twbs/bootstrap/pull/14559 for more information. + +[data-toggle="buttons"] { + > .btn, + > .btn-group > .btn { + input[type="radio"], + input[type="checkbox"] { + position: absolute; + clip: rect(0,0,0,0); + pointer-events: none; + } + } +} diff --git a/_sass/bootstrap/_buttons.scss b/_sass/bootstrap/_buttons.scss new file mode 100644 index 0000000..6452b70 --- /dev/null +++ b/_sass/bootstrap/_buttons.scss @@ -0,0 +1,168 @@ +// +// Buttons +// -------------------------------------------------- + + +// Base styles +// -------------------------------------------------- + +.btn { + display: inline-block; + margin-bottom: 0; // For input.btn + font-weight: $btn-font-weight; + text-align: center; + vertical-align: middle; + touch-action: manipulation; + cursor: pointer; + background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214 + border: 1px solid transparent; + white-space: nowrap; + @include button-size($padding-base-vertical, $padding-base-horizontal, $font-size-base, $line-height-base, $btn-border-radius-base); + @include user-select(none); + + &, + &:active, + &.active { + &:focus, + &.focus { + @include tab-focus; + } + } + + &:hover, + &:focus, + &.focus { + color: $btn-default-color; + text-decoration: none; + } + + &:active, + &.active { + outline: 0; + background-image: none; + @include box-shadow(inset 0 3px 5px rgba(0,0,0,.125)); + } + + &.disabled, + &[disabled], + fieldset[disabled] & { + cursor: $cursor-disabled; + @include opacity(.65); + @include box-shadow(none); + } + + // [converter] extracted a& to a.btn +} + +a.btn { + &.disabled, + fieldset[disabled] & { + pointer-events: none; // Future-proof disabling of clicks on `` elements + } +} + + +// Alternate buttons +// -------------------------------------------------- + +.btn-default { + @include button-variant($btn-default-color, $btn-default-bg, $btn-default-border); +} +.btn-primary { + @include button-variant($btn-primary-color, $btn-primary-bg, $btn-primary-border); +} +// Success appears as green +.btn-success { + @include button-variant($btn-success-color, $btn-success-bg, $btn-success-border); +} +// Info appears as blue-green +.btn-info { + @include button-variant($btn-info-color, $btn-info-bg, $btn-info-border); +} +// Warning appears as orange +.btn-warning { + @include button-variant($btn-warning-color, $btn-warning-bg, $btn-warning-border); +} +// Danger and error appear as red +.btn-danger { + @include button-variant($btn-danger-color, $btn-danger-bg, $btn-danger-border); +} + + +// Link buttons +// ------------------------- + +// Make a button look and behave like a link +.btn-link { + color: $link-color; + font-weight: normal; + border-radius: 0; + + &, + &:active, + &.active, + &[disabled], + fieldset[disabled] & { + background-color: transparent; + @include box-shadow(none); + } + &, + &:hover, + &:focus, + &:active { + border-color: transparent; + } + &:hover, + &:focus { + color: $link-hover-color; + text-decoration: $link-hover-decoration; + background-color: transparent; + } + &[disabled], + fieldset[disabled] & { + &:hover, + &:focus { + color: $btn-link-disabled-color; + text-decoration: none; + } + } +} + + +// Button Sizes +// -------------------------------------------------- + +.btn-lg { + // line-height: ensure even-numbered height of button next to large input + @include button-size($padding-large-vertical, $padding-large-horizontal, $font-size-large, $line-height-large, $btn-border-radius-large); +} +.btn-sm { + // line-height: ensure proper height of button next to small input + @include button-size($padding-small-vertical, $padding-small-horizontal, $font-size-small, $line-height-small, $btn-border-radius-small); +} +.btn-xs { + @include button-size($padding-xs-vertical, $padding-xs-horizontal, $font-size-small, $line-height-small, $btn-border-radius-small); +} + + +// Block button +// -------------------------------------------------- + +.btn-block { + display: block; + width: 100%; +} + +// Vertically space out multiple block buttons +.btn-block + .btn-block { + margin-top: 5px; +} + +// Specificity overrides +input[type="submit"], +input[type="reset"], +input[type="button"] { + &.btn-block { + width: 100%; + } +} diff --git a/_sass/bootstrap/_carousel.scss b/_sass/bootstrap/_carousel.scss new file mode 100644 index 0000000..753d881 --- /dev/null +++ b/_sass/bootstrap/_carousel.scss @@ -0,0 +1,270 @@ +// +// Carousel +// -------------------------------------------------- + + +// Wrapper for the slide container and indicators +.carousel { + position: relative; +} + +.carousel-inner { + position: relative; + overflow: hidden; + width: 100%; + + > .item { + display: none; + position: relative; + @include transition(.6s ease-in-out left); + + // Account for jankitude on images + > img, + > a > img { + @include img-responsive; + line-height: 1; + } + + // WebKit CSS3 transforms for supported devices + @media all and (transform-3d), (-webkit-transform-3d) { + @include transition-transform(0.6s ease-in-out); + @include backface-visibility(hidden); + @include perspective(1000px); + + &.next, + &.active.right { + @include translate3d(100%, 0, 0); + left: 0; + } + &.prev, + &.active.left { + @include translate3d(-100%, 0, 0); + left: 0; + } + &.next.left, + &.prev.right, + &.active { + @include translate3d(0, 0, 0); + left: 0; + } + } + } + + > .active, + > .next, + > .prev { + display: block; + } + + > .active { + left: 0; + } + + > .next, + > .prev { + position: absolute; + top: 0; + width: 100%; + } + + > .next { + left: 100%; + } + > .prev { + left: -100%; + } + > .next.left, + > .prev.right { + left: 0; + } + + > .active.left { + left: -100%; + } + > .active.right { + left: 100%; + } + +} + +// Left/right controls for nav +// --------------------------- + +.carousel-control { + position: absolute; + top: 0; + left: 0; + bottom: 0; + width: $carousel-control-width; + @include opacity($carousel-control-opacity); + font-size: $carousel-control-font-size; + color: $carousel-control-color; + text-align: center; + text-shadow: $carousel-text-shadow; + background-color: rgba(0, 0, 0, 0); // Fix IE9 click-thru bug + // We can't have this transition here because WebKit cancels the carousel + // animation if you trip this while in the middle of another animation. + + // Set gradients for backgrounds + &.left { + @include gradient-horizontal($start-color: rgba(0,0,0,.5), $end-color: rgba(0,0,0,.0001)); + } + &.right { + left: auto; + right: 0; + @include gradient-horizontal($start-color: rgba(0,0,0,.0001), $end-color: rgba(0,0,0,.5)); + } + + // Hover/focus state + &:hover, + &:focus { + outline: 0; + color: $carousel-control-color; + text-decoration: none; + @include opacity(.9); + } + + // Toggles + .icon-prev, + .icon-next, + .glyphicon-chevron-left, + .glyphicon-chevron-right { + position: absolute; + top: 50%; + margin-top: -10px; + z-index: 5; + display: inline-block; + } + .icon-prev, + .glyphicon-chevron-left { + left: 50%; + margin-left: -10px; + } + .icon-next, + .glyphicon-chevron-right { + right: 50%; + margin-right: -10px; + } + .icon-prev, + .icon-next { + width: 20px; + height: 20px; + line-height: 1; + font-family: serif; + } + + + .icon-prev { + &:before { + content: '\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039) + } + } + .icon-next { + &:before { + content: '\203a';// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A) + } + } +} + +// Optional indicator pips +// +// Add an unordered list with the following class and add a list item for each +// slide your carousel holds. + +.carousel-indicators { + position: absolute; + bottom: 10px; + left: 50%; + z-index: 15; + width: 60%; + margin-left: -30%; + padding-left: 0; + list-style: none; + text-align: center; + + li { + display: inline-block; + width: 10px; + height: 10px; + margin: 1px; + text-indent: -999px; + border: 1px solid $carousel-indicator-border-color; + border-radius: 10px; + cursor: pointer; + + // IE8-9 hack for event handling + // + // Internet Explorer 8-9 does not support clicks on elements without a set + // `background-color`. We cannot use `filter` since that's not viewed as a + // background color by the browser. Thus, a hack is needed. + // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Internet_Explorer + // + // For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we + // set alpha transparency for the best results possible. + background-color: #000 \9; // IE8 + background-color: rgba(0,0,0,0); // IE9 + } + .active { + margin: 0; + width: 12px; + height: 12px; + background-color: $carousel-indicator-active-bg; + } +} + +// Optional captions +// ----------------------------- +// Hidden by default for smaller viewports +.carousel-caption { + position: absolute; + left: 15%; + right: 15%; + bottom: 20px; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: $carousel-caption-color; + text-align: center; + text-shadow: $carousel-text-shadow; + & .btn { + text-shadow: none; // No shadow for button elements in carousel-caption + } +} + + +// Scale up controls for tablets and up +@media screen and (min-width: $screen-sm-min) { + + // Scale up the controls a smidge + .carousel-control { + .glyphicon-chevron-left, + .glyphicon-chevron-right, + .icon-prev, + .icon-next { + width: ($carousel-control-font-size * 1.5); + height: ($carousel-control-font-size * 1.5); + margin-top: ($carousel-control-font-size / -2); + font-size: ($carousel-control-font-size * 1.5); + } + .glyphicon-chevron-left, + .icon-prev { + margin-left: ($carousel-control-font-size / -2); + } + .glyphicon-chevron-right, + .icon-next { + margin-right: ($carousel-control-font-size / -2); + } + } + + // Show and left align the captions + .carousel-caption { + left: 20%; + right: 20%; + padding-bottom: 30px; + } + + // Move up the indicators + .carousel-indicators { + bottom: 20px; + } +} diff --git a/_sass/bootstrap/_close.scss b/_sass/bootstrap/_close.scss new file mode 100644 index 0000000..3b74d8a --- /dev/null +++ b/_sass/bootstrap/_close.scss @@ -0,0 +1,36 @@ +// +// Close icons +// -------------------------------------------------- + + +.close { + float: right; + font-size: ($font-size-base * 1.5); + font-weight: $close-font-weight; + line-height: 1; + color: $close-color; + text-shadow: $close-text-shadow; + @include opacity(.2); + + &:hover, + &:focus { + color: $close-color; + text-decoration: none; + cursor: pointer; + @include opacity(.5); + } + + // [converter] extracted button& to button.close +} + +// Additional properties for button version +// iOS requires the button element instead of an anchor tag. +// If you want the anchor version, it requires `href="#"`. +// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile +button.close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; +} diff --git a/_sass/bootstrap/_code.scss b/_sass/bootstrap/_code.scss new file mode 100644 index 0000000..caa5f06 --- /dev/null +++ b/_sass/bootstrap/_code.scss @@ -0,0 +1,69 @@ +// +// Code (inline and block) +// -------------------------------------------------- + + +// Inline and block code styles +code, +kbd, +pre, +samp { + font-family: $font-family-monospace; +} + +// Inline code +code { + padding: 2px 4px; + font-size: 90%; + color: $code-color; + background-color: $code-bg; + border-radius: $border-radius-base; +} + +// User input typically entered via keyboard +kbd { + padding: 2px 4px; + font-size: 90%; + color: $kbd-color; + background-color: $kbd-bg; + border-radius: $border-radius-small; + box-shadow: inset 0 -1px 0 rgba(0,0,0,.25); + + kbd { + padding: 0; + font-size: 100%; + font-weight: bold; + box-shadow: none; + } +} + +// Blocks of code +pre { + display: block; + padding: (($line-height-computed - 1) / 2); + margin: 0 0 ($line-height-computed / 2); + font-size: ($font-size-base - 1); // 14px to 13px + line-height: $line-height-base; + word-break: break-all; + word-wrap: break-word; + color: $pre-color; + background-color: $pre-bg; + border: 1px solid $pre-border-color; + border-radius: $border-radius-base; + + // Account for some code outputs that place code tags in pre tags + code { + padding: 0; + font-size: inherit; + color: inherit; + white-space: pre-wrap; + background-color: transparent; + border-radius: 0; + } +} + +// Enable scrollable blocks of code +.pre-scrollable { + max-height: $pre-scrollable-max-height; + overflow-y: scroll; +} diff --git a/_sass/bootstrap/_component-animations.scss b/_sass/bootstrap/_component-animations.scss new file mode 100644 index 0000000..ca3b43c --- /dev/null +++ b/_sass/bootstrap/_component-animations.scss @@ -0,0 +1,37 @@ +// +// Component animations +// -------------------------------------------------- + +// Heads up! +// +// We don't use the `.opacity()` mixin here since it causes a bug with text +// fields in IE7-8. Source: https://github.com/twbs/bootstrap/pull/3552. + +.fade { + opacity: 0; + @include transition(opacity .15s linear); + &.in { + opacity: 1; + } +} + +.collapse { + display: none; + + &.in { display: block; } + // [converter] extracted tr&.in to tr.collapse.in + // [converter] extracted tbody&.in to tbody.collapse.in +} + +tr.collapse.in { display: table-row; } + +tbody.collapse.in { display: table-row-group; } + +.collapsing { + position: relative; + height: 0; + overflow: hidden; + @include transition-property(height, visibility); + @include transition-duration(.35s); + @include transition-timing-function(ease); +} diff --git a/_sass/bootstrap/_dropdowns.scss b/_sass/bootstrap/_dropdowns.scss new file mode 100644 index 0000000..aac8459 --- /dev/null +++ b/_sass/bootstrap/_dropdowns.scss @@ -0,0 +1,216 @@ +// +// Dropdown menus +// -------------------------------------------------- + + +// Dropdown arrow/caret +.caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: $caret-width-base dashed; + border-top: $caret-width-base solid \9; // IE8 + border-right: $caret-width-base solid transparent; + border-left: $caret-width-base solid transparent; +} + +// The dropdown wrapper (div) +.dropup, +.dropdown { + position: relative; +} + +// Prevent the focus on the dropdown toggle when closing dropdowns +.dropdown-toggle:focus { + outline: 0; +} + +// The dropdown menu (ul) +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: $zindex-dropdown; + display: none; // none by default, but block on "open" of the menu + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; // override default ul + list-style: none; + font-size: $font-size-base; + text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer) + background-color: $dropdown-bg; + border: 1px solid $dropdown-fallback-border; // IE8 fallback + border: 1px solid $dropdown-border; + border-radius: $border-radius-base; + @include box-shadow(0 6px 12px rgba(0,0,0,.175)); + background-clip: padding-box; + + // Aligns the dropdown menu to right + // + // Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]` + &.pull-right { + right: 0; + left: auto; + } + + // Dividers (basically an hr) within the dropdown + .divider { + @include nav-divider($dropdown-divider-bg); + } + + // Links within the dropdown menu + > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: $line-height-base; + color: $dropdown-link-color; + white-space: nowrap; // prevent links from randomly breaking onto new lines + } +} + +// Hover/Focus state +.dropdown-menu > li > a { + &:hover, + &:focus { + text-decoration: none; + color: $dropdown-link-hover-color; + background-color: $dropdown-link-hover-bg; + } +} + +// Active state +.dropdown-menu > .active > a { + &, + &:hover, + &:focus { + color: $dropdown-link-active-color; + text-decoration: none; + outline: 0; + background-color: $dropdown-link-active-bg; + } +} + +// Disabled state +// +// Gray out text and ensure the hover/focus state remains gray + +.dropdown-menu > .disabled > a { + &, + &:hover, + &:focus { + color: $dropdown-link-disabled-color; + } + + // Nuke hover/focus effects + &:hover, + &:focus { + text-decoration: none; + background-color: transparent; + background-image: none; // Remove CSS gradient + @include reset-filter; + cursor: $cursor-disabled; + } +} + +// Open state for the dropdown +.open { + // Show the menu + > .dropdown-menu { + display: block; + } + + // Remove the outline when :focus is triggered + > a { + outline: 0; + } +} + +// Menu positioning +// +// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown +// menu with the parent. +.dropdown-menu-right { + left: auto; // Reset the default from `.dropdown-menu` + right: 0; +} +// With v3, we enabled auto-flipping if you have a dropdown within a right +// aligned nav component. To enable the undoing of that, we provide an override +// to restore the default dropdown menu alignment. +// +// This is only for left-aligning a dropdown menu within a `.navbar-right` or +// `.pull-right` nav component. +.dropdown-menu-left { + left: 0; + right: auto; +} + +// Dropdown section headers +.dropdown-header { + display: block; + padding: 3px 20px; + font-size: $font-size-small; + line-height: $line-height-base; + color: $dropdown-header-color; + white-space: nowrap; // as with > li > a +} + +// Backdrop to catch body clicks on mobile, etc. +.dropdown-backdrop { + position: fixed; + left: 0; + right: 0; + bottom: 0; + top: 0; + z-index: ($zindex-dropdown - 10); +} + +// Right aligned dropdowns +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} + +// Allow for dropdowns to go bottom up (aka, dropup-menu) +// +// Just add .dropup after the standard .dropdown class and you're set, bro. +// TODO: abstract this so that the navbar fixed styles are not placed here? + +.dropup, +.navbar-fixed-bottom .dropdown { + // Reverse the caret + .caret { + border-top: 0; + border-bottom: $caret-width-base dashed; + border-bottom: $caret-width-base solid \9; // IE8 + content: ""; + } + // Different positioning for bottom up menu + .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 2px; + } +} + + +// Component alignment +// +// Reiterate per navbar.less and the modified component alignment there. + +@media (min-width: $grid-float-breakpoint) { + .navbar-right { + .dropdown-menu { + right: 0; left: auto; + } + // Necessary for overrides of the default right aligned menu. + // Will remove come v4 in all likelihood. + .dropdown-menu-left { + left: 0; right: auto; + } + } +} diff --git a/_sass/bootstrap/_forms.scss b/_sass/bootstrap/_forms.scss new file mode 100644 index 0000000..ac26a6a --- /dev/null +++ b/_sass/bootstrap/_forms.scss @@ -0,0 +1,617 @@ +// +// Forms +// -------------------------------------------------- + + +// Normalize non-controls +// +// Restyle and baseline non-control form elements. + +fieldset { + padding: 0; + margin: 0; + border: 0; + // Chrome and Firefox set a `min-width: min-content;` on fieldsets, + // so we reset that to ensure it behaves more like a standard block element. + // See https://github.com/twbs/bootstrap/issues/12359. + min-width: 0; +} + +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: $line-height-computed; + font-size: ($font-size-base * 1.5); + line-height: inherit; + color: $legend-color; + border: 0; + border-bottom: 1px solid $legend-border-color; +} + +label { + display: inline-block; + max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141) + margin-bottom: 5px; + font-weight: bold; +} + + +// Normalize form controls +// +// While most of our form styles require extra classes, some basic normalization +// is required to ensure optimum display with or without those classes to better +// address browser inconsistencies. + +// Override content-box in Normalize (* isn't specific enough) +input[type="search"] { + @include box-sizing(border-box); +} + +// Position radios and checkboxes better +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; // IE8-9 + line-height: normal; +} + +input[type="file"] { + display: block; +} + +// Make range inputs behave like textual form controls +input[type="range"] { + display: block; + width: 100%; +} + +// Make multiple select elements height not fixed +select[multiple], +select[size] { + height: auto; +} + +// Focus for file, radio, and checkbox +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + @include tab-focus; +} + +// Adjust output element +output { + display: block; + padding-top: ($padding-base-vertical + 1); + font-size: $font-size-base; + line-height: $line-height-base; + color: $input-color; +} + + +// Common form controls +// +// Shared size and type resets for form controls. Apply `.form-control` to any +// of the following form controls: +// +// select +// textarea +// input[type="text"] +// input[type="password"] +// input[type="datetime"] +// input[type="datetime-local"] +// input[type="date"] +// input[type="month"] +// input[type="time"] +// input[type="week"] +// input[type="number"] +// input[type="email"] +// input[type="url"] +// input[type="search"] +// input[type="tel"] +// input[type="color"] + +.form-control { + display: block; + width: 100%; + height: $input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border) + padding: $padding-base-vertical $padding-base-horizontal; + font-size: $font-size-base; + line-height: $line-height-base; + color: $input-color; + background-color: $input-bg; + background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214 + border: 1px solid $input-border; + border-radius: $input-border-radius; // Note: This has no effect on s in CSS. + @include box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); + @include transition(border-color ease-in-out .15s, box-shadow ease-in-out .15s); + + // Customize the `:focus` state to imitate native WebKit styles. + @include form-control-focus; + + // Placeholder + @include placeholder; + + // Unstyle the caret on `` background color +$input-bg: #fff !default; +//** `` background color +$input-bg-disabled: $gray-lighter !default; + +//** Text color for ``s +$input-color: $gray !default; +//** `` border color +$input-border: #ccc !default; + +// TODO: Rename `$input-border-radius` to `$input-border-radius-base` in v4 +//** Default `.form-control` border radius +// This has no effect on ``s in CSS. +$input-border-radius: $border-radius-base !default; +//** Large `.form-control` border radius +$input-border-radius-large: $border-radius-large !default; +//** Small `.form-control` border radius +$input-border-radius-small: $border-radius-small !default; + +//** Border color for inputs on focus +$input-border-focus: #66afe9 !default; + +//** Placeholder text color +$input-color-placeholder: #999 !default; + +//** Default `.form-control` height +$input-height-base: ($line-height-computed + ($padding-base-vertical * 2) + 2) !default; +//** Large `.form-control` height +$input-height-large: (ceil($font-size-large * $line-height-large) + ($padding-large-vertical * 2) + 2) !default; +//** Small `.form-control` height +$input-height-small: (floor($font-size-small * $line-height-small) + ($padding-small-vertical * 2) + 2) !default; + +//** `.form-group` margin +$form-group-margin-bottom: 15px !default; + +$legend-color: $gray-dark !default; +$legend-border-color: #e5e5e5 !default; + +//** Background color for textual input addons +$input-group-addon-bg: $gray-lighter !default; +//** Border color for textual input addons +$input-group-addon-border-color: $input-border !default; + +//** Disabled cursor for form controls and buttons. +$cursor-disabled: not-allowed !default; + + +//== Dropdowns +// +//## Dropdown menu container and contents. + +//** Background for the dropdown menu. +$dropdown-bg: #fff !default; +//** Dropdown menu `border-color`. +$dropdown-border: rgba(0,0,0,.15) !default; +//** Dropdown menu `border-color` **for IE8**. +$dropdown-fallback-border: #ccc !default; +//** Divider color for between dropdown items. +$dropdown-divider-bg: #e5e5e5 !default; + +//** Dropdown link text color. +$dropdown-link-color: $gray-dark !default; +//** Hover color for dropdown links. +$dropdown-link-hover-color: darken($gray-dark, 5%) !default; +//** Hover background for dropdown links. +$dropdown-link-hover-bg: #f5f5f5 !default; + +//** Active dropdown menu item text color. +$dropdown-link-active-color: $component-active-color !default; +//** Active dropdown menu item background color. +$dropdown-link-active-bg: $component-active-bg !default; + +//** Disabled dropdown menu item background color. +$dropdown-link-disabled-color: $gray-light !default; + +//** Text color for headers within dropdown menus. +$dropdown-header-color: $gray-light !default; + +//** Deprecated `$dropdown-caret-color` as of v3.1.0 +$dropdown-caret-color: #000 !default; + + +//-- Z-index master list +// +// Warning: Avoid customizing these values. They're used for a bird's eye view +// of components dependent on the z-axis and are designed to all work together. +// +// Note: These variables are not generated into the Customizer. + +$zindex-navbar: 1000 !default; +$zindex-dropdown: 1000 !default; +$zindex-popover: 1060 !default; +$zindex-tooltip: 1070 !default; +$zindex-navbar-fixed: 1030 !default; +$zindex-modal-background: 1040 !default; +$zindex-modal: 1050 !default; + + +//== Media queries breakpoints +// +//## Define the breakpoints at which your layout will change, adapting to different screen sizes. + +// Extra small screen / phone +//** Deprecated `$screen-xs` as of v3.0.1 +$screen-xs: 480px !default; +//** Deprecated `$screen-xs-min` as of v3.2.0 +$screen-xs-min: $screen-xs !default; +//** Deprecated `$screen-phone` as of v3.0.1 +$screen-phone: $screen-xs-min !default; + +// Small screen / tablet +//** Deprecated `$screen-sm` as of v3.0.1 +$screen-sm: 768px !default; +$screen-sm-min: $screen-sm !default; +//** Deprecated `$screen-tablet` as of v3.0.1 +$screen-tablet: $screen-sm-min !default; + +// Medium screen / desktop +//** Deprecated `$screen-md` as of v3.0.1 +$screen-md: 992px !default; +$screen-md-min: $screen-md !default; +//** Deprecated `$screen-desktop` as of v3.0.1 +$screen-desktop: $screen-md-min !default; + +// Large screen / wide desktop +//** Deprecated `$screen-lg` as of v3.0.1 +$screen-lg: 1200px !default; +$screen-lg-min: $screen-lg !default; +//** Deprecated `$screen-lg-desktop` as of v3.0.1 +$screen-lg-desktop: $screen-lg-min !default; + +// So media queries don't overlap when required, provide a maximum +$screen-xs-max: ($screen-sm-min - 1) !default; +$screen-sm-max: ($screen-md-min - 1) !default; +$screen-md-max: ($screen-lg-min - 1) !default; + + +//== Grid system +// +//## Define your custom responsive grid. + +//** Number of columns in the grid. +$grid-columns: 12 !default; +//** Padding between columns. Gets divided in half for the left and right. +$grid-gutter-width: 30px !default; +// Navbar collapse +//** Point at which the navbar becomes uncollapsed. +$grid-float-breakpoint: $screen-sm-min !default; +//** Point at which the navbar begins collapsing. +$grid-float-breakpoint-max: ($grid-float-breakpoint - 1) !default; + + +//== Container sizes +// +//## Define the maximum width of `.container` for different screen sizes. + +// Small screen / tablet +$container-tablet: (720px + $grid-gutter-width) !default; +//** For `$screen-sm-min` and up. +$container-sm: $container-tablet !default; + +// Medium screen / desktop +$container-desktop: (940px + $grid-gutter-width) !default; +//** For `$screen-md-min` and up. +$container-md: $container-desktop !default; + +// Large screen / wide desktop +$container-large-desktop: (1140px + $grid-gutter-width) !default; +//** For `$screen-lg-min` and up. +$container-lg: $container-large-desktop !default; + + +//== Navbar +// +//## + +// Basics of a navbar +$navbar-height: 50px !default; +$navbar-margin-bottom: $line-height-computed !default; +$navbar-border-radius: $border-radius-base !default; +$navbar-padding-horizontal: floor(($grid-gutter-width / 2)) !default; +$navbar-padding-vertical: (($navbar-height - $line-height-computed) / 2) !default; +$navbar-collapse-max-height: 340px !default; + +$navbar-default-color: #777 !default; +$navbar-default-bg: #f8f8f8 !default; +$navbar-default-border: darken($navbar-default-bg, 6.5%) !default; + +// Navbar links +$navbar-default-link-color: #777 !default; +$navbar-default-link-hover-color: #333 !default; +$navbar-default-link-hover-bg: transparent !default; +$navbar-default-link-active-color: #555 !default; +$navbar-default-link-active-bg: darken($navbar-default-bg, 6.5%) !default; +$navbar-default-link-disabled-color: #ccc !default; +$navbar-default-link-disabled-bg: transparent !default; + +// Navbar brand label +$navbar-default-brand-color: $navbar-default-link-color !default; +$navbar-default-brand-hover-color: darken($navbar-default-brand-color, 10%) !default; +$navbar-default-brand-hover-bg: transparent !default; + +// Navbar toggle +$navbar-default-toggle-hover-bg: #ddd !default; +$navbar-default-toggle-icon-bar-bg: #888 !default; +$navbar-default-toggle-border-color: #ddd !default; + + +//=== Inverted navbar +// Reset inverted navbar basics +$navbar-inverse-color: lighten($gray-light, 15%) !default; +$navbar-inverse-bg: #222 !default; +$navbar-inverse-border: darken($navbar-inverse-bg, 10%) !default; + +// Inverted navbar links +$navbar-inverse-link-color: lighten($gray-light, 15%) !default; +$navbar-inverse-link-hover-color: #fff !default; +$navbar-inverse-link-hover-bg: transparent !default; +$navbar-inverse-link-active-color: $navbar-inverse-link-hover-color !default; +$navbar-inverse-link-active-bg: darken($navbar-inverse-bg, 10%) !default; +$navbar-inverse-link-disabled-color: #444 !default; +$navbar-inverse-link-disabled-bg: transparent !default; + +// Inverted navbar brand label +$navbar-inverse-brand-color: $navbar-inverse-link-color !default; +$navbar-inverse-brand-hover-color: #fff !default; +$navbar-inverse-brand-hover-bg: transparent !default; + +// Inverted navbar toggle +$navbar-inverse-toggle-hover-bg: #333 !default; +$navbar-inverse-toggle-icon-bar-bg: #fff !default; +$navbar-inverse-toggle-border-color: #333 !default; + + +//== Navs +// +//## + +//=== Shared nav styles +$nav-link-padding: 10px 15px !default; +$nav-link-hover-bg: $gray-lighter !default; + +$nav-disabled-link-color: $gray-light !default; +$nav-disabled-link-hover-color: $gray-light !default; + +//== Tabs +$nav-tabs-border-color: #ddd !default; + +$nav-tabs-link-hover-border-color: $gray-lighter !default; + +$nav-tabs-active-link-hover-bg: $body-bg !default; +$nav-tabs-active-link-hover-color: $gray !default; +$nav-tabs-active-link-hover-border-color: #ddd !default; + +$nav-tabs-justified-link-border-color: #ddd !default; +$nav-tabs-justified-active-link-border-color: $body-bg !default; + +//== Pills +$nav-pills-border-radius: $border-radius-base !default; +$nav-pills-active-link-hover-bg: $component-active-bg !default; +$nav-pills-active-link-hover-color: $component-active-color !default; + + +//== Pagination +// +//## + +$pagination-color: $link-color !default; +$pagination-bg: #fff !default; +$pagination-border: #ddd !default; + +$pagination-hover-color: $link-hover-color !default; +$pagination-hover-bg: $gray-lighter !default; +$pagination-hover-border: #ddd !default; + +$pagination-active-color: #fff !default; +$pagination-active-bg: $brand-primary !default; +$pagination-active-border: $brand-primary !default; + +$pagination-disabled-color: $gray-light !default; +$pagination-disabled-bg: #fff !default; +$pagination-disabled-border: #ddd !default; + + +//== Pager +// +//## + +$pager-bg: $pagination-bg !default; +$pager-border: $pagination-border !default; +$pager-border-radius: 15px !default; + +$pager-hover-bg: $pagination-hover-bg !default; + +$pager-active-bg: $pagination-active-bg !default; +$pager-active-color: $pagination-active-color !default; + +$pager-disabled-color: $pagination-disabled-color !default; + + +//== Jumbotron +// +//## + +$jumbotron-padding: 30px !default; +$jumbotron-color: inherit !default; +$jumbotron-bg: $gray-lighter !default; +$jumbotron-heading-color: inherit !default; +$jumbotron-font-size: ceil(($font-size-base * 1.5)) !default; +$jumbotron-heading-font-size: ceil(($font-size-base * 4.5)) !default; + + +//== Form states and alerts +// +//## Define colors for form feedback states and, by default, alerts. + +$state-success-text: #3c763d !default; +$state-success-bg: #dff0d8 !default; +$state-success-border: darken(adjust-hue($state-success-bg, -10), 5%) !default; + +$state-info-text: #31708f !default; +$state-info-bg: #d9edf7 !default; +$state-info-border: darken(adjust-hue($state-info-bg, -10), 7%) !default; + +$state-warning-text: #8a6d3b !default; +$state-warning-bg: #fcf8e3 !default; +$state-warning-border: darken(adjust-hue($state-warning-bg, -10), 5%) !default; + +$state-danger-text: #a94442 !default; +$state-danger-bg: #f2dede !default; +$state-danger-border: darken(adjust-hue($state-danger-bg, -10), 5%) !default; + + +//== Tooltips +// +//## + +//** Tooltip max width +$tooltip-max-width: 200px !default; +//** Tooltip text color +$tooltip-color: #fff !default; +//** Tooltip background color +$tooltip-bg: #000 !default; +$tooltip-opacity: .9 !default; + +//** Tooltip arrow width +$tooltip-arrow-width: 5px !default; +//** Tooltip arrow color +$tooltip-arrow-color: $tooltip-bg !default; + + +//== Popovers +// +//## + +//** Popover body background color +$popover-bg: #fff !default; +//** Popover maximum width +$popover-max-width: 276px !default; +//** Popover border color +$popover-border-color: rgba(0,0,0,.2) !default; +//** Popover fallback border color +$popover-fallback-border-color: #ccc !default; + +//** Popover title background color +$popover-title-bg: darken($popover-bg, 3%) !default; + +//** Popover arrow width +$popover-arrow-width: 10px !default; +//** Popover arrow color +$popover-arrow-color: $popover-bg !default; + +//** Popover outer arrow width +$popover-arrow-outer-width: ($popover-arrow-width + 1) !default; +//** Popover outer arrow color +$popover-arrow-outer-color: fade_in($popover-border-color, 0.05) !default; +//** Popover outer arrow fallback color +$popover-arrow-outer-fallback-color: darken($popover-fallback-border-color, 20%) !default; + + +//== Labels +// +//## + +//** Default label background color +$label-default-bg: $gray-light !default; +//** Primary label background color +$label-primary-bg: $brand-primary !default; +//** Success label background color +$label-success-bg: $brand-success !default; +//** Info label background color +$label-info-bg: $brand-info !default; +//** Warning label background color +$label-warning-bg: $brand-warning !default; +//** Danger label background color +$label-danger-bg: $brand-danger !default; + +//** Default label text color +$label-color: #fff !default; +//** Default text color of a linked label +$label-link-hover-color: #fff !default; + + +//== Modals +// +//## + +//** Padding applied to the modal body +$modal-inner-padding: 15px !default; + +//** Padding applied to the modal title +$modal-title-padding: 15px !default; +//** Modal title line-height +$modal-title-line-height: $line-height-base !default; + +//** Background color of modal content area +$modal-content-bg: #fff !default; +//** Modal content border color +$modal-content-border-color: rgba(0,0,0,.2) !default; +//** Modal content border color **for IE8** +$modal-content-fallback-border-color: #999 !default; + +//** Modal backdrop background color +$modal-backdrop-bg: #000 !default; +//** Modal backdrop opacity +$modal-backdrop-opacity: .5 !default; +//** Modal header border color +$modal-header-border-color: #e5e5e5 !default; +//** Modal footer border color +$modal-footer-border-color: $modal-header-border-color !default; + +$modal-lg: 900px !default; +$modal-md: 600px !default; +$modal-sm: 300px !default; + + +//== Alerts +// +//## Define alert colors, border radius, and padding. + +$alert-padding: 15px !default; +$alert-border-radius: $border-radius-base !default; +$alert-link-font-weight: bold !default; + +$alert-success-bg: $state-success-bg !default; +$alert-success-text: $state-success-text !default; +$alert-success-border: $state-success-border !default; + +$alert-info-bg: $state-info-bg !default; +$alert-info-text: $state-info-text !default; +$alert-info-border: $state-info-border !default; + +$alert-warning-bg: $state-warning-bg !default; +$alert-warning-text: $state-warning-text !default; +$alert-warning-border: $state-warning-border !default; + +$alert-danger-bg: $state-danger-bg !default; +$alert-danger-text: $state-danger-text !default; +$alert-danger-border: $state-danger-border !default; + + +//== Progress bars +// +//## + +//** Background color of the whole progress component +$progress-bg: #f5f5f5 !default; +//** Progress bar text color +$progress-bar-color: #fff !default; +//** Variable for setting rounded corners on progress bar. +$progress-border-radius: $border-radius-base !default; + +//** Default progress bar color +$progress-bar-bg: $brand-primary !default; +//** Success progress bar color +$progress-bar-success-bg: $brand-success !default; +//** Warning progress bar color +$progress-bar-warning-bg: $brand-warning !default; +//** Danger progress bar color +$progress-bar-danger-bg: $brand-danger !default; +//** Info progress bar color +$progress-bar-info-bg: $brand-info !default; + + +//== List group +// +//## + +//** Background color on `.list-group-item` +$list-group-bg: #fff !default; +//** `.list-group-item` border color +$list-group-border: #ddd !default; +//** List group border radius +$list-group-border-radius: $border-radius-base !default; + +//** Background color of single list items on hover +$list-group-hover-bg: #f5f5f5 !default; +//** Text color of active list items +$list-group-active-color: $component-active-color !default; +//** Background color of active list items +$list-group-active-bg: $component-active-bg !default; +//** Border color of active list elements +$list-group-active-border: $list-group-active-bg !default; +//** Text color for content within active list items +$list-group-active-text-color: lighten($list-group-active-bg, 40%) !default; + +//** Text color of disabled list items +$list-group-disabled-color: $gray-light !default; +//** Background color of disabled list items +$list-group-disabled-bg: $gray-lighter !default; +//** Text color for content within disabled list items +$list-group-disabled-text-color: $list-group-disabled-color !default; + +$list-group-link-color: #555 !default; +$list-group-link-hover-color: $list-group-link-color !default; +$list-group-link-heading-color: #333 !default; + + +//== Panels +// +//## + +$panel-bg: #fff !default; +$panel-body-padding: 15px !default; +$panel-heading-padding: 10px 15px !default; +$panel-footer-padding: $panel-heading-padding !default; +$panel-border-radius: $border-radius-base !default; + +//** Border color for elements within panels +$panel-inner-border: #ddd !default; +$panel-footer-bg: #f5f5f5 !default; + +$panel-default-text: $gray-dark !default; +$panel-default-border: #ddd !default; +$panel-default-heading-bg: #f5f5f5 !default; + +$panel-primary-text: #fff !default; +$panel-primary-border: $brand-primary !default; +$panel-primary-heading-bg: $brand-primary !default; + +$panel-success-text: $state-success-text !default; +$panel-success-border: $state-success-border !default; +$panel-success-heading-bg: $state-success-bg !default; + +$panel-info-text: $state-info-text !default; +$panel-info-border: $state-info-border !default; +$panel-info-heading-bg: $state-info-bg !default; + +$panel-warning-text: $state-warning-text !default; +$panel-warning-border: $state-warning-border !default; +$panel-warning-heading-bg: $state-warning-bg !default; + +$panel-danger-text: $state-danger-text !default; +$panel-danger-border: $state-danger-border !default; +$panel-danger-heading-bg: $state-danger-bg !default; + + +//== Thumbnails +// +//## + +//** Padding around the thumbnail image +$thumbnail-padding: 4px !default; +//** Thumbnail background color +$thumbnail-bg: $body-bg !default; +//** Thumbnail border color +$thumbnail-border: #ddd !default; +//** Thumbnail border radius +$thumbnail-border-radius: $border-radius-base !default; + +//** Custom text color for thumbnail captions +$thumbnail-caption-color: $text-color !default; +//** Padding around the thumbnail caption +$thumbnail-caption-padding: 9px !default; + + +//== Wells +// +//## + +$well-bg: #f5f5f5 !default; +$well-border: darken($well-bg, 7%) !default; + + +//== Badges +// +//## + +$badge-color: #fff !default; +//** Linked badge text color on hover +$badge-link-hover-color: #fff !default; +$badge-bg: $gray-light !default; + +//** Badge text color in active nav link +$badge-active-color: $link-color !default; +//** Badge background color in active nav link +$badge-active-bg: #fff !default; + +$badge-font-weight: bold !default; +$badge-line-height: 1 !default; +$badge-border-radius: 10px !default; + + +//== Breadcrumbs +// +//## + +$breadcrumb-padding-vertical: 8px !default; +$breadcrumb-padding-horizontal: 15px !default; +//** Breadcrumb background color +$breadcrumb-bg: #f5f5f5 !default; +//** Breadcrumb text color +$breadcrumb-color: #ccc !default; +//** Text color of current page in the breadcrumb +$breadcrumb-active-color: $gray-light !default; +//** Textual separator for between breadcrumb elements +$breadcrumb-separator: "/" !default; + + +//== Carousel +// +//## + +$carousel-text-shadow: 0 1px 2px rgba(0,0,0,.6) !default; + +$carousel-control-color: #fff !default; +$carousel-control-width: 15% !default; +$carousel-control-opacity: .5 !default; +$carousel-control-font-size: 20px !default; + +$carousel-indicator-active-bg: #fff !default; +$carousel-indicator-border-color: #fff !default; + +$carousel-caption-color: #fff !default; + + +//== Close +// +//## + +$close-font-weight: bold !default; +$close-color: #000 !default; +$close-text-shadow: 0 1px 0 #fff !default; + + +//== Code +// +//## + +$code-color: #c7254e !default; +$code-bg: #f9f2f4 !default; + +$kbd-color: #fff !default; +$kbd-bg: #333 !default; + +$pre-bg: #f5f5f5 !default; +$pre-color: $gray-dark !default; +$pre-border-color: #ccc !default; +$pre-scrollable-max-height: 340px !default; + + +//== Type +// +//## + +//** Horizontal offset for forms and lists. +$component-offset-horizontal: 180px !default; +//** Text muted color +$text-muted: $gray-light !default; +//** Abbreviations and acronyms border color +$abbr-border-color: $gray-light !default; +//** Headings small color +$headings-small-color: $gray-light !default; +//** Blockquote small color +$blockquote-small-color: $gray-light !default; +//** Blockquote font size +$blockquote-font-size: ($font-size-base * 1.25) !default; +//** Blockquote border color +$blockquote-border-color: $gray-lighter !default; +//** Page header border color +$page-header-border-color: $gray-lighter !default; +//** Width of horizontal description list titles +$dl-horizontal-offset: $component-offset-horizontal !default; +//** Point at which .dl-horizontal becomes horizontal +$dl-horizontal-breakpoint: $grid-float-breakpoint !default; +//** Horizontal line color. +$hr-border: $gray-lighter !default; diff --git a/_sass/bootstrap/_wells.scss b/_sass/bootstrap/_wells.scss new file mode 100644 index 0000000..b865711 --- /dev/null +++ b/_sass/bootstrap/_wells.scss @@ -0,0 +1,29 @@ +// +// Wells +// -------------------------------------------------- + + +// Base class +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: $well-bg; + border: 1px solid $well-border; + border-radius: $border-radius-base; + @include box-shadow(inset 0 1px 1px rgba(0,0,0,.05)); + blockquote { + border-color: #ddd; + border-color: rgba(0,0,0,.15); + } +} + +// Sizes +.well-lg { + padding: 24px; + border-radius: $border-radius-large; +} +.well-sm { + padding: 9px; + border-radius: $border-radius-small; +} diff --git a/_sass/bootstrap/mixins/_alerts.scss b/_sass/bootstrap/mixins/_alerts.scss new file mode 100644 index 0000000..3faf0b5 --- /dev/null +++ b/_sass/bootstrap/mixins/_alerts.scss @@ -0,0 +1,14 @@ +// Alerts + +@mixin alert-variant($background, $border, $text-color) { + background-color: $background; + border-color: $border; + color: $text-color; + + hr { + border-top-color: darken($border, 5%); + } + .alert-link { + color: darken($text-color, 10%); + } +} diff --git a/_sass/bootstrap/mixins/_background-variant.scss b/_sass/bootstrap/mixins/_background-variant.scss new file mode 100644 index 0000000..4c7769e --- /dev/null +++ b/_sass/bootstrap/mixins/_background-variant.scss @@ -0,0 +1,12 @@ +// Contextual backgrounds + +// [converter] $parent hack +@mixin bg-variant($parent, $color) { + #{$parent} { + background-color: $color; + } + a#{$parent}:hover, + a#{$parent}:focus { + background-color: darken($color, 10%); + } +} diff --git a/_sass/bootstrap/mixins/_border-radius.scss b/_sass/bootstrap/mixins/_border-radius.scss new file mode 100644 index 0000000..ce19499 --- /dev/null +++ b/_sass/bootstrap/mixins/_border-radius.scss @@ -0,0 +1,18 @@ +// Single side border-radius + +@mixin border-top-radius($radius) { + border-top-right-radius: $radius; + border-top-left-radius: $radius; +} +@mixin border-right-radius($radius) { + border-bottom-right-radius: $radius; + border-top-right-radius: $radius; +} +@mixin border-bottom-radius($radius) { + border-bottom-right-radius: $radius; + border-bottom-left-radius: $radius; +} +@mixin border-left-radius($radius) { + border-bottom-left-radius: $radius; + border-top-left-radius: $radius; +} diff --git a/_sass/bootstrap/mixins/_buttons.scss b/_sass/bootstrap/mixins/_buttons.scss new file mode 100644 index 0000000..b93f84b --- /dev/null +++ b/_sass/bootstrap/mixins/_buttons.scss @@ -0,0 +1,65 @@ +// Button variants +// +// Easily pump out default styles, as well as :hover, :focus, :active, +// and disabled options for all buttons + +@mixin button-variant($color, $background, $border) { + color: $color; + background-color: $background; + border-color: $border; + + &:focus, + &.focus { + color: $color; + background-color: darken($background, 10%); + border-color: darken($border, 25%); + } + &:hover { + color: $color; + background-color: darken($background, 10%); + border-color: darken($border, 12%); + } + &:active, + &.active, + .open > &.dropdown-toggle { + color: $color; + background-color: darken($background, 10%); + border-color: darken($border, 12%); + + &:hover, + &:focus, + &.focus { + color: $color; + background-color: darken($background, 17%); + border-color: darken($border, 25%); + } + } + &:active, + &.active, + .open > &.dropdown-toggle { + background-image: none; + } + &.disabled, + &[disabled], + fieldset[disabled] & { + &:hover, + &:focus, + &.focus { + background-color: $background; + border-color: $border; + } + } + + .badge { + color: $background; + background-color: $color; + } +} + +// Button sizes +@mixin button-size($padding-vertical, $padding-horizontal, $font-size, $line-height, $border-radius) { + padding: $padding-vertical $padding-horizontal; + font-size: $font-size; + line-height: $line-height; + border-radius: $border-radius; +} diff --git a/_sass/bootstrap/mixins/_center-block.scss b/_sass/bootstrap/mixins/_center-block.scss new file mode 100644 index 0000000..e06fb5e --- /dev/null +++ b/_sass/bootstrap/mixins/_center-block.scss @@ -0,0 +1,7 @@ +// Center-align a block level element + +@mixin center-block() { + display: block; + margin-left: auto; + margin-right: auto; +} diff --git a/_sass/bootstrap/mixins/_clearfix.scss b/_sass/bootstrap/mixins/_clearfix.scss new file mode 100644 index 0000000..dc3e2ab --- /dev/null +++ b/_sass/bootstrap/mixins/_clearfix.scss @@ -0,0 +1,22 @@ +// Clearfix +// +// For modern browsers +// 1. The space content is one way to avoid an Opera bug when the +// contenteditable attribute is included anywhere else in the document. +// Otherwise it causes space to appear at the top and bottom of elements +// that are clearfixed. +// 2. The use of `table` rather than `block` is only necessary if using +// `:before` to contain the top-margins of child elements. +// +// Source: http://nicolasgallagher.com/micro-clearfix-hack/ + +@mixin clearfix() { + &:before, + &:after { + content: " "; // 1 + display: table; // 2 + } + &:after { + clear: both; + } +} diff --git a/_sass/bootstrap/mixins/_forms.scss b/_sass/bootstrap/mixins/_forms.scss new file mode 100644 index 0000000..277aa5f --- /dev/null +++ b/_sass/bootstrap/mixins/_forms.scss @@ -0,0 +1,88 @@ +// Form validation states +// +// Used in forms.less to generate the form validation CSS for warnings, errors, +// and successes. + +@mixin form-control-validation($text-color: #555, $border-color: #ccc, $background-color: #f5f5f5) { + // Color the label and help text + .help-block, + .control-label, + .radio, + .checkbox, + .radio-inline, + .checkbox-inline, + &.radio label, + &.checkbox label, + &.radio-inline label, + &.checkbox-inline label { + color: $text-color; + } + // Set the border and box shadow on specific inputs to match + .form-control { + border-color: $border-color; + @include box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work + &:focus { + border-color: darken($border-color, 10%); + $shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten($border-color, 20%); + @include box-shadow($shadow); + } + } + // Set validation states also for addons + .input-group-addon { + color: $text-color; + border-color: $border-color; + background-color: $background-color; + } + // Optional feedback icon + .form-control-feedback { + color: $text-color; + } +} + + +// Form control focus state +// +// Generate a customized focus state and for any input with the specified color, +// which defaults to the `$input-border-focus` variable. +// +// We highly encourage you to not customize the default value, but instead use +// this to tweak colors on an as-needed basis. This aesthetic change is based on +// WebKit's default styles, but applicable to a wider range of browsers. Its +// usability and accessibility should be taken into account with any change. +// +// Example usage: change the default blue border and shadow to white for better +// contrast against a dark gray background. +@mixin form-control-focus($color: $input-border-focus) { + $color-rgba: rgba(red($color), green($color), blue($color), .6); + &:focus { + border-color: $color; + outline: 0; + @include box-shadow(inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px $color-rgba); + } +} + +// Form control sizing +// +// Relative text size, padding, and border-radii changes for form controls. For +// horizontal sizing, wrap controls in the predefined grid classes. `