sublime_video_layout 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +21 -0
  4. data/Rakefile +29 -0
  5. data/app/assets/fonts/SublimeIcons.eot +0 -0
  6. data/app/assets/fonts/SublimeIcons.svg +34 -0
  7. data/app/assets/fonts/SublimeIcons.ttf +0 -0
  8. data/app/assets/fonts/SublimeIcons.woff +0 -0
  9. data/app/assets/images/back_texture_my.png +0 -0
  10. data/app/assets/images/close_popup.png +0 -0
  11. data/app/assets/images/custom_checkbox.png +0 -0
  12. data/app/assets/images/custom_radio.png +0 -0
  13. data/app/assets/images/custom_select.png +0 -0
  14. data/app/assets/images/dm_banner.png +0 -0
  15. data/app/assets/images/dm_banner_bg.png +0 -0
  16. data/app/assets/images/fields/card_icon.png +0 -0
  17. data/app/assets/images/fields/domain_icon.png +0 -0
  18. data/app/assets/images/fields/email_icon.png +0 -0
  19. data/app/assets/images/fields/password_icon.png +0 -0
  20. data/app/assets/images/fields/path_icon.png +0 -0
  21. data/app/assets/images/fields/ticket_icon.png +0 -0
  22. data/app/assets/images/fields/user_icon.png +0 -0
  23. data/app/assets/images/fields/valid_icon.png +0 -0
  24. data/app/assets/images/footer_break.png +0 -0
  25. data/app/assets/images/footer_texture.png +0 -0
  26. data/app/assets/images/header_back_light.png +0 -0
  27. data/app/assets/images/header_inner_shadow.png +0 -0
  28. data/app/assets/images/header_repeat.jpg +0 -0
  29. data/app/assets/images/header_repeat.png +0 -0
  30. data/app/assets/images/header_repeat_max.jpg +0 -0
  31. data/app/assets/images/header_repeat_old.png +0 -0
  32. data/app/assets/images/header_signup_btn.png +0 -0
  33. data/app/assets/images/header_stars.png +0 -0
  34. data/app/assets/images/info_icon.png +0 -0
  35. data/app/assets/images/jilion.png +0 -0
  36. data/app/assets/images/jobs_highlight_note.png +0 -0
  37. data/app/assets/images/logout.png +0 -0
  38. data/app/assets/images/menu_bullet.png +0 -0
  39. data/app/assets/images/menu_bullet_active.png +0 -0
  40. data/app/assets/images/newsletter_btn_arrow.png +0 -0
  41. data/app/assets/images/plans/plays_icon.png +0 -0
  42. data/app/assets/images/plans/ssl_icon.png +0 -0
  43. data/app/assets/images/plans/stats_icon.png +0 -0
  44. data/app/assets/images/plans/support_icon.png +0 -0
  45. data/app/assets/images/popup_break.png +0 -0
  46. data/app/assets/images/popup_sign_up_btn.png +0 -0
  47. data/app/assets/images/sublimevideo_logo.png +0 -0
  48. data/app/assets/images/sublimevideo_logo@2x.png +0 -0
  49. data/app/assets/images/sublimevideo_maintenance.png +0 -0
  50. data/app/assets/images/twitter.png +0 -0
  51. data/app/assets/images/user_header_icon.png +0 -0
  52. data/app/assets/images/user_header_icon_active.png +0 -0
  53. data/app/assets/javascripts/form/password_checker.js.coffee +18 -0
  54. data/app/assets/javascripts/form/pseudo_placeholder.js.coffee +91 -0
  55. data/app/assets/javascripts/form/show_password.js.coffee +91 -0
  56. data/app/assets/javascripts/form/submit_manager.js.coffee +53 -0
  57. data/app/assets/javascripts/media/preloader.js.coffee +30 -0
  58. data/app/assets/javascripts/misc/browser_bugs_fixer.js.coffee +12 -0
  59. data/app/assets/javascripts/misc/cookie.js.coffee +42 -0
  60. data/app/assets/javascripts/misc/utils.js.coffee +17 -0
  61. data/app/assets/javascripts/sublimevideo.js.coffee +66 -0
  62. data/app/assets/javascripts/ui/link.js.coffee +24 -0
  63. data/app/assets/javascripts/ui/menu.js.coffee +36 -0
  64. data/app/assets/javascripts/ui/popup.js.coffee +121 -0
  65. data/app/assets/javascripts/ui/table.js.coffee +8 -0
  66. data/app/assets/javascripts/ui/utils.js.coffee +41 -0
  67. data/app/assets/stylesheets/_css3.scss +41 -0
  68. data/app/assets/stylesheets/ie.css.scss +2 -0
  69. data/app/assets/stylesheets/sublime_icons.css.scss.erb +46 -0
  70. data/app/assets/stylesheets/sublimevideo.css.scss.erb +947 -0
  71. data/app/controllers/maintenance_controller.rb +12 -0
  72. data/app/helpers/sublime_video_layout/engine_helper.rb +111 -0
  73. data/app/views/layouts/_facebook.html.haml +1 -0
  74. data/app/views/layouts/_footer.html.haml +54 -0
  75. data/app/views/layouts/_googleplus.html.haml +7 -0
  76. data/app/views/layouts/_gosquared.html.haml +11 -0
  77. data/app/views/layouts/_header_menu.html.haml +44 -0
  78. data/app/views/layouts/_ie.html.haml +14 -0
  79. data/app/views/layouts/_twitter.html.haml +2 -0
  80. data/app/views/layouts/maintenance.html.erb +79 -0
  81. data/app/views/layouts/sublimevideo.html.haml +61 -0
  82. data/app/views/users/new.html.haml +24 -0
  83. data/app/views/users/sessions/new.html.haml +25 -0
  84. data/config/locales/en.yml +14 -0
  85. data/config/routes.rb +5 -0
  86. data/lib/heroku-pages/error.html +82 -0
  87. data/lib/heroku-pages/maintenance.html +77 -0
  88. data/lib/heroku-pages/sublimevideo_maintenance.png +0 -0
  89. data/lib/rack/maintenance.rb +32 -0
  90. data/lib/site_token.rb +22 -0
  91. data/lib/sublime_video_layout.rb +18 -0
  92. data/lib/sublime_video_layout/version.rb +3 -0
  93. data/lib/tasks/sublime_video_layout_tasks.rake +4 -0
  94. data/public/404.html +28 -0
  95. data/public/404.png +0 -0
  96. data/public/422.html +29 -0
  97. data/public/500.html +28 -0
  98. data/public/500.png +0 -0
  99. data/public/apple-touch-icon-precomposed.png +0 -0
  100. data/public/error.png +0 -0
  101. data/public/errors.css +60 -0
  102. data/public/favicon.ico +0 -0
  103. data/public/robots.txt +5 -0
  104. data/public/sublimevideo.png +0 -0
  105. data/vendor/assets/javascripts/modernizr.js +1265 -0
  106. metadata +203 -0
@@ -0,0 +1,30 @@
1
+ class SublimeVideo.Media.Preloader
2
+ constructor: (@src, @callback, @options = {}) ->
3
+ @problem = false
4
+ this.preload()
5
+
6
+ class SublimeVideo.Media.ImagePreloader extends SublimeVideo.Media.Preloader
7
+ preload: ->
8
+ @image = new Image()
9
+
10
+ @image['onload'] = this.didComplete
11
+ @image['onerror'] = this.didFail
12
+ @image['onabort'] = this.didAbort
13
+ @image['src'] = @src
14
+
15
+ didFail: =>
16
+ @problem = true
17
+ this.didComplete()
18
+
19
+ didAbort: =>
20
+ @problem = true
21
+ this.didComplete()
22
+
23
+ didComplete: =>
24
+ @options['width'] = @image['width']
25
+ @options['height'] = @image['height']
26
+ @callback(@problem, @src, @options)
27
+
28
+ class SublimeVideo.Media.VideoPreloader extends SublimeVideo.Media.Preloader
29
+ preload: ->
30
+ SublimeVideoSizeChecker.getVideoSize(@src, @callback)
@@ -0,0 +1,12 @@
1
+ class SublimeVideo.Misc.BrowserBugsFixer
2
+ @fixAllBugs: ->
3
+ # ## Fix a <select> CSS bug in Safari (under v4.0.5)
4
+ # Safari 5.0 has webkit version 533
5
+ # Safari 4.0.5 is the last version pre-5.0
6
+ # NOTE: Safari 4.0.4 and 4.0.5 have the same webkit version number (531)
7
+ webkitVersionNumber = navigator.userAgent.match(/AppleWebKit\/([0-9]+)./)
8
+ isSafari405OrPrevious = navigator.userAgent.indexOf("Macintosh") > -1 and webkitVersionNumber and parseInt(webkitVersionNumber[1],10) <= 531;
9
+
10
+ if isSafari405OrPrevious
11
+ $('select').each ->
12
+ $(this).css('font-family': 'Lucida Grande, Arial, sans-serif', 'font-size': '15px')
@@ -0,0 +1,42 @@
1
+ class SublimeVideo.Misc.Cookie
2
+ constructor: (@name) ->
3
+
4
+ # It retrieve the value of the cookie with the `@name` key.
5
+ #
6
+ # @return [String] the cookie value or `null` if no cookie with this name exists
7
+ #
8
+ get: ->
9
+ escapedName = this._escapedAndAssignName()
10
+ if document.cookie.indexOf(escapedName) >= 0
11
+ cookies = document.cookie.split(/\s*;\s*/)
12
+ for cookie in cookies
13
+ if cookie.indexOf(escapedName) is 0
14
+ return unescape(cookie.substring(escapedName.length, cookie.length))
15
+
16
+ null
17
+
18
+ # It stores the given `value` at the `@name` key, given `options`.
19
+ #
20
+ # @param [String] value the value of the cookie to store
21
+ # @param [Object] options cookie options
22
+ # @option options [Date] expires the date when the cookie will expire
23
+ # @option options [String] path the path for which the cookie is available
24
+ # @option options [String] domain the domain for which the cookie is available
25
+ # @option options [Boolean] secure wether the cookie is accessible only through HTTPS
26
+ #
27
+ # @return [String] the cookie value
28
+ #
29
+ set: (value, options = {}) ->
30
+ newcookie = [this._escapedAndAssignName() + escape(value)]
31
+ if options
32
+ if options.expires then newcookie.push "expires=" + options.expires.toGMTString()
33
+ if options.path then newcookie.push "path=#{options.path}"
34
+ if options.domain then newcookie.push "domain=#{options.domain}"
35
+ if options.secure then newcookie.push "secure"
36
+ document.cookie = newcookie.join '; '
37
+
38
+ #
39
+ # @private
40
+ #
41
+ _escapedAndAssignName: ->
42
+ escape(@name) + '='
@@ -0,0 +1,17 @@
1
+ SublimeVideo.Misc.Utils =
2
+ topDomainHost: ->
3
+ document.location.host.split('.').slice(-2).join('.')
4
+
5
+ docsUrl: (path, stage = 'stable') ->
6
+ stage = if stage is 'stable'
7
+ ''
8
+ else
9
+ "/#{stage}"
10
+
11
+ "http://docs.#{SublimeVideo.Misc.Utils.topDomainHost()}#{stage}/#{path}"
12
+
13
+ iOS: ->
14
+ /i(p[oa]d|phone)/i.test(navigator.userAgent)
15
+
16
+ capitalize: (str) ->
17
+ str.replace(/^\w/, ($0) -> $0.toUpperCase())
@@ -0,0 +1,66 @@
1
+ #= require modernizr
2
+ #= require jquery_ujs
3
+ #
4
+ #= require_self
5
+ #= require_tree ./form
6
+ #= require_tree ./media
7
+ #= require_tree ./misc
8
+ #= require_tree ./ui
9
+
10
+ window.SublimeVideo =
11
+ Form: {}
12
+ Media: {}
13
+ Misc: {}
14
+ UI: {}
15
+
16
+ $.fn.exists = -> @length > 0
17
+
18
+ SublimeVideo.UI.prepareRemoteLinks = ->
19
+ $('a.remote').each ->
20
+ new SublimeVideo.UI.RemoteLink($(this))
21
+
22
+ SublimeVideo.UI.prepareStickyMenus = ->
23
+ $('ul.sticky').each ->
24
+ new SublimeVideo.UI.Menu($(this)).setupStickyItems()
25
+
26
+ SublimeVideo.UI.updateActiveItemMenus = ->
27
+ $('ul.sticky').each ->
28
+ new SublimeVideo.UI.Menu($(this)).updateActiveItem()
29
+
30
+ SublimeVideo.UI.prepareSignupAndLoginPopup = ->
31
+ $.each ['signup', 'login'], (index, action) ->
32
+ $("##{action}_button").on 'click', (event) ->
33
+ event.preventDefault()
34
+ SublimeVideo.UI.Utils.openAccountPopup(action)
35
+
36
+ SublimeVideo.documentReady = ->
37
+ SublimeVideo.Misc.BrowserBugsFixer.fixAllBugs()
38
+
39
+ # Only one popup can be opened-up at a time
40
+ SublimeVideo.UI.popup = null
41
+
42
+ if matches = document.location.search.match(/p=(login|signup)/)
43
+ SublimeVideo.UI.Utils.openAccountPopup(matches[1])
44
+
45
+ SublimeVideo.UI.prepareSignupAndLoginPopup()
46
+
47
+ $('input.show_password[type=password]').each (index, input) ->
48
+ new SublimeVideo.Form.ShowPassword($(this), index)
49
+
50
+ unless Modernizr.input.placeholder
51
+ $('input[placeholder]').each ->
52
+ new SublimeVideo.Form.PseudoPlaceholder($(this))
53
+ $('textarea[placeholder]').each ->
54
+ new SublimeVideo.Form.PseudoPlaceholder($(this))
55
+
56
+ $('form').each ->
57
+ new SublimeVideo.Form.SubmitManager($(this))
58
+
59
+ SublimeVideo.UI.prepareStickyMenus()
60
+
61
+ SublimeVideo.UI.prepareRemoteLinks()
62
+
63
+ new SublimeVideo.UI.Menu($('#header_menu')).setupLoggedInBehavior()
64
+
65
+ $(document).ready ->
66
+ SublimeVideo.documentReady()
@@ -0,0 +1,24 @@
1
+ # The RemoteLink add a sticky behavior, shows a table spinner and push new state.
2
+ #
3
+ class SublimeVideo.UI.RemoteLink
4
+ #
5
+ # @param [DOM Element] element the element to which attach the behavior
6
+ #
7
+ constructor: (element) ->
8
+ @element = $(element)
9
+ this.setupObserver()
10
+
11
+ setupObserver: ->
12
+ @element.on 'click', =>
13
+ this.stickyBehavior()
14
+ SublimeVideo.UI.Table.showSpinner()
15
+
16
+ if history and history.pushState?
17
+ history.pushState({ isHistory: true }, document.title, @element.attr('href'))
18
+
19
+ # @private
20
+ #
21
+ stickyBehavior: ->
22
+ @element.parent().find('a.active').each ->
23
+ $(this).removeClass('active')
24
+ @element.addClass('active')
@@ -0,0 +1,36 @@
1
+ # The Flash create a new flash notice element and prepend it to the `#content` element.
2
+ #
3
+ class SublimeVideo.UI.Menu
4
+ #
5
+ # @param [jQuery Element] element the menu (ul) element
6
+ #
7
+ constructor: (@element) ->
8
+
9
+ setupStickyItems: ->
10
+ @element.find('a').each (index, el) =>
11
+ $el = $(el)
12
+ unless $el.hasClass('no_sticky')
13
+ $el.on('click', this.stickyBehavior)
14
+
15
+ updateActiveItem: ->
16
+ @element.find('.active').removeClass('active')
17
+ @element.find('li').each (index, el) =>
18
+ $li = $(el)
19
+ if $li.find('a').first().attr('href') is location.href
20
+ $li.addClass 'active'
21
+
22
+ # @private
23
+ #
24
+ stickyBehavior: (event) =>
25
+ @element.find('.active').removeClass('active')
26
+ $link = $(event.delegateTarget)
27
+ if $li = $link.parent('li')
28
+ $li.addClass('active')
29
+ else
30
+ $link.addClass('active')
31
+
32
+ setupLoggedInBehavior: ->
33
+ @cookie = new SublimeVideo.Misc.Cookie('l')
34
+ if @cookie.get() is '1'
35
+ @element.find('.unlogged').hide()
36
+ @element.find('.logged').show()
@@ -0,0 +1,121 @@
1
+ # The SimplePopup simply add observers behaviors on a given `element` object.
2
+ #
3
+ class SublimeVideo.UI.SimplePopup
4
+ #
5
+ # @param [Object] options a set of options to customize the popup
6
+ # @option options [jQuery Element] element the element that represents the popup
7
+ #
8
+ constructor: (@options = {}) ->
9
+ @element = @options.element
10
+
11
+ startObservers: ->
12
+ $(document).on('keydown', { popup: this }, this.keyDown)
13
+ @element.on('click', { popup: this }, this.click)
14
+
15
+ stopObservers: ->
16
+ $(document).off('keydown', this.keyDown)
17
+ @element.off('click', this.click) if @element?
18
+
19
+ pauseVideos: ->
20
+ sublime_api = if sublime?
21
+ sublime
22
+ else
23
+ sublimevideo
24
+
25
+ sublime_api.ready ->
26
+ sublimevideo.pause() if SublimeVideo.Misc.Utils.iOS()
27
+
28
+ # It closes the popup if it's open, stop the current video playing with SublimeVideo on iOS,
29
+ # shows the popup (simply shows `@element`) and starts the observers that take care of the popup closing.
30
+ #
31
+ open: ->
32
+ this.close()
33
+
34
+ this.pauseVideos()
35
+
36
+ @element.show()
37
+ this.startObservers()
38
+
39
+ # Hides the popup (simply show `@element`) and stops the observers that take care of the popup closing.
40
+ #
41
+ close: ->
42
+ this.stopObservers()
43
+ @element.hide()
44
+
45
+ # @private
46
+ #
47
+ keyDown: (event) ->
48
+ switch event.which
49
+ when 27 then event.data.popup.close() # ESC
50
+
51
+ # @private
52
+ #
53
+ click: (event) ->
54
+ if event.target is event.data.popup.element[0]
55
+ event.data.popup.close()
56
+
57
+ #
58
+ # Handles creation and behavior of SV pop-up (used for showing the embed code and the usage, asking the password..)
59
+ #
60
+ class SublimeVideo.UI.Popup extends SublimeVideo.UI.SimplePopup
61
+ #
62
+ # @param [Object] options a set of options to customize the popup. Default: `{ class: 'popup' }`
63
+ # @option options [String] id the id of the popup (note that this id is also used as a class for
64
+ # the "content" div inside the popup element)
65
+ # @option options [String] class the class to apply to the popup
66
+ # @option options [jQuery Element] form the form from which originated the popup opening
67
+ # @option options [jQuery Element] anchor the anchor element in which re-add popup content after closing
68
+ # @option options [jQuery Element] url an url to GET in AJAX (not that the AJAX response must take care
69
+ # @option options [jQuery Element] content the content to put in the popup
70
+ # of populating the popup if needed)
71
+ #
72
+ constructor: (@options = { class: 'popup' }) ->
73
+ @element = null
74
+
75
+ setContent: (content) ->
76
+ @element.removeClass('loading')
77
+ @element.find('.content').html(content)
78
+
79
+ # Create the popup (if needed), append it to the `#content` div (if needed) and show it.
80
+ # It also starts the observers that take care of the popup closing.
81
+ #
82
+ open: ->
83
+ this.close()
84
+
85
+ this.pauseVideos()
86
+
87
+ unless @element?
88
+ @element = $('<div>', id: "#{@options.id or ''}", class: "#{@options.class or ''} loading")
89
+ @element.html("<div class='popup_wrap'>
90
+ <div class='lights'>
91
+ <div class='content'></div>
92
+ </div>
93
+ <a href='' onclick='return SublimeVideo.UI.Utils.closePopup()' data-no-turbolink class='close'><span>Close</span></a>
94
+ </div>")
95
+ if @options.content
96
+ this.setContent(@options.content)
97
+ else if @options.anchor
98
+ this.setContent(@options.anchor.html())
99
+ @options.anchor.html('')
100
+ $('#content').append(@element)
101
+
102
+ if @options.url?
103
+ # the called method will take care of replacing the wrap div with the response content
104
+ new Ajax.Request(@options.url, method: 'get')
105
+
106
+ this.startObservers()
107
+
108
+ # Stops the observers, move the popup content back to its `anchor` (if applicable)
109
+ # and re-enable `@options.form` buttons.
110
+ #
111
+ close: ->
112
+ this.stopObservers()
113
+
114
+ if @element
115
+ if @options.anchor?
116
+ @options.anchor.html(@element.find('.content').html())
117
+ @element.remove()
118
+
119
+ if @options.form?
120
+ @options.form.find('input[type=submit]', 'button').each ->
121
+ $(this).prop('disabled', false)
@@ -0,0 +1,8 @@
1
+ # The Flash create a new flash notice element and prepend it to the `#content` element.
2
+ #
3
+ SublimeVideo.UI.Table =
4
+ # Shows a spinner
5
+ #
6
+ showSpinner: ->
7
+ if ($tableSpinner = $('#table_spinner')).exists()
8
+ $tableSpinner.show()
@@ -0,0 +1,41 @@
1
+ SublimeVideo.UI.Utils =
2
+ # Opens a new popup and stores its reference in `SublimeVideo.UI.popup`
3
+ #
4
+ # @param [Object] options the options accepted by {SublimeVideo.UI.Popup}
5
+ # @see SublimeVideo.UI.Popup
6
+ #
7
+ openPopup: (options) ->
8
+ SublimeVideo.UI.popup = new SublimeVideo.UI.Popup(options)
9
+ SublimeVideo.UI.popup.open()
10
+
11
+ # Closes the currently opened `SublimeVideo.UI.popup`
12
+ #
13
+ closePopup: ->
14
+ unless SublimeVideo.UI.popup?
15
+ SublimeVideo.UI.popup = new SublimeVideo.UI.Popup()
16
+ SublimeVideo.UI.popup.close()
17
+
18
+ false
19
+
20
+ # Opens a new login or signup popup and stores its reference in `SublimeVideo.UI.popup`
21
+ #
22
+ # @param [String] type the type of popup ('login' or 'signup')
23
+ # @param [String] successUrl the URL to which redirect the user once login/signup succeeds (default: null)
24
+ # @see SublimeVideo.UI.Popup
25
+ #
26
+ openAccountPopup: (type, successUrl = null) ->
27
+ if ($el = $("#popup_#{type}")).exists()
28
+ SublimeVideo.UI.popup = new SublimeVideo.UI.SimplePopup(element: $el)
29
+
30
+ if successUrl?
31
+ $("#user_return_to").val(successUrl)
32
+
33
+ SublimeVideo.UI.popup.open()
34
+
35
+ if SublimeVideo.Misc.Utils.iOS()
36
+ $("#popup_#{type}").find("#user_email").focus()
37
+
38
+ if _gaq? and type is 'signup'
39
+ _gaq.push(['_trackEvent', 'SignUp', 'Clicked', undefined, 1, true])
40
+
41
+ false
@@ -0,0 +1,41 @@
1
+ @mixin transition($type, $time, $ease) {
2
+ -o-transition:$type $time $ease;
3
+ -moz-transition:$type $time $ease;
4
+ -webkit-transition:$type $time $ease;
5
+ transition:$type $time $ease;
6
+ }
7
+
8
+ @mixin gradient($from, $to, $middle) {
9
+ background:$middle;
10
+ background:-moz-linear-gradient($from, $to);
11
+ background:-webkit-gradient(linear, 0% 0%, 0% 100%, from($from), to($to));
12
+ background:-webkit-linear-gradient($from, $to);
13
+ background:-o-linear-gradient($from, $to);
14
+ }
15
+
16
+ @mixin box-shadow($value) {
17
+ -moz-box-shadow:$value;
18
+ -webkit-box-shadow:$value;
19
+ box-shadow:$value;
20
+ }
21
+
22
+ @mixin border-radius($value) {
23
+ -moz-border-radius:$value;
24
+ -webkit-border-radius:$value;
25
+ border-radius:$value;
26
+ }
27
+
28
+ @mixin mask-image($value) {
29
+ -webkit-mask-image:url($value);
30
+ -o-mask-image:url($value);
31
+ -moz-mask-image:url($value);
32
+ mask-image:url($value);
33
+ }
34
+
35
+ @mixin rotate($value) {
36
+ -webkit-transform:rotate($value);
37
+ -moz-transform:rotate($value);
38
+ -o-transform:rotate($value);
39
+ -ms-transform:rotate($value);
40
+ transform:rotate($value);
41
+ }