@function map-deep-get($map, $keys...) {
	@each $key in $keys {
		$map: map-get($map, $key);
	}
	@return $map;
}

/// poly-fluid-sizing
/// Generate linear interpolated size values through multiple break points
/// @param $property - A string CSS property name
/// @param $map - A SASS map of viewport unit and size value pairs
/// @requires function linear-interpolation
/// @requires function map-sort
/// @example
///   @include poly-fluid-sizing('font-size', (576px: 22px, 768px: 24px, 992px: 34px));
/// @author Jake Wilson <jake.e.wilson@gmail.com> & Update version by Wiloke
@mixin poly-fluid-sizing($property, $map) {
	@include poly-fluid-sizing_cal($property, $map);
}
@mixin pfs($property, $map) {
	@include poly-fluid-sizing_cal($property, $map);
}
@mixin poly-fluid-sizing_cal($property, $map) {
  	// Get the number of provided breakpoints
	$length: length(map-keys($map));
  	// Error if the number of breakpoints is < 2
	@if ($length < 2) {
		@error "poly-fluid-sizing() $map requires at least values";
	}
	// Sort the map by viewport width (key)
	$map: map-sort($map);
	$keys: map-keys($map);
	// Minimum size
	@if (type-of(str-index($property, ',')) == 'number') {
		$properties: str-to-list(#{$property});
		@each $_property in $properties {
			@if (type-of(str-index($_property, ',')) == 'number') {
				$_property: str-slice($_property, 1, str-index($_property, ',') - 1);
			}
			#{$_property}: map-get($map, nth($keys, 1));
		}
	} @else {
		#{$property}: map-get($map, nth($keys, 1));
	}
	// Interpolated size through breakpoints
	@for $i from 1 through ($length - 1) {
		@media (min-width: nth($keys, $i)) {

			@if (type-of(str-index($property, ',')) == 'number') {
				$properties: str-to-list(#{$property});
				@each $_property in $properties {
					@if (type-of(str-index($_property, ',')) == 'number') {
						$_property: str-slice($_property, 1, str-index($_property, ',') - 1);
					}
					#{$_property}: linear-interpolation((nth($keys, $i): map-get($map, nth($keys, $i)), nth($keys, ($i+1)): map-get($map, nth($keys, ($i + 1)))));
				}
			} @else {
				#{$property}: linear-interpolation((nth($keys, $i): map-get($map, nth($keys, $i)), nth($keys, ($i+1)): map-get($map, nth($keys, ($i + 1)))));
			}
		}
	}
	// Maxmimum size
	@media (min-width:nth($keys, $length)) {
		@if (type-of(str-index($property, ',')) == 'number') {
			$properties: str-to-list(#{$property});
			@each $_property in $properties {
				@if (type-of(str-index($_property, ',')) == 'number') {
					$_property: str-slice($_property, 1, str-index($_property, ',') - 1);
				}
				#{$_property}: map-get($map, nth($keys, $length));
			}
		} @else {
			#{$property}: map-get($map, nth($keys, $length));
		}
	}
}

// String to list
@function str-to-list($string, $separator: ' ', $startAt: 1) {
    $workStr: str-slice($string,$startAt);
    $list: ();
    $indexOfFirstSpace: str-index($workStr,$separator);
    @if $indexOfFirstSpace == null {
        $list: ($workStr);
    } @else {
        $list: (str-slice($workStr, 1, $indexOfFirstSpace - 1));
        $list: join($list,str-to-list($workStr, $startAt: $indexOfFirstSpace + 1));
    }
    @return $list;
}

/// linear-interpolation
/// Calculate the definition of a line between two points
/// @param $map - A SASS map of viewport widths and size value pairs
/// @returns A linear equation as a calc() function
/// @example
///   font-size: linear-interpolation((320px: 18px, 768px: 26px));
/// @author Jake Wilson <jake.e.wilson@gmail.com>
@function linear-interpolation($map) {
	$keys: map-keys($map);
	@if (length($keys) !=2) {
		@error "linear-interpolation() $map must be exactly 2 values";
	}
	// The slope
	$m: (map-get($map, nth($keys, 2)) - map-get($map, nth($keys, 1)))/(nth($keys, 2) - nth($keys, 1));
	// The y-intercept
	$b: map-get($map, nth($keys, 1)) - $m * nth($keys, 1);
	// Determine if the sign should be positive or negative
	$sign: "+";
	@if ($b < 0) {
		$sign: "-";
		$b: abs($b);
	}
	@return calc(#{$m*100}vw #{$sign} #{$b});
}

/// list-sort
/// Sort a SASS list
/// @param $list - A SASS list
/// @returns A sorted SASS list
/// @requires function list-remove
/// @author Jake Wilson <jake.e.wilson@gmail.com>
@function list-sort($list) {
	$sortedlist: ();
	@while length($list) > 0 {
		$value: nth($list, 1);
		@each $item in $list {
			@if $item < $value {
				$value: $item;
			}
		}
		$sortedlist: append($sortedlist, $value, 'space');
		$list: list-remove($list, index($list, $value));
	}
	@return $sortedlist;
}

/// map-sort
/// Sort map by keys
/// @param $map - A SASS map
/// @returns A SASS map sorted by keys
/// @requires function list-sort
/// @author Jake Wilson <jake.e.wilson@gmail.com>
@function map-sort($map) {
	$keys: list-sort(map-keys($map));
	$sortedMap: ();
	@each $key in $keys {
		$sortedMap: map-merge($sortedMap, ($key: map-get($map, $key)));
	}
	@return $sortedMap;
}

/// list-remove
/// Remove an item from a list
/// @param $list - A SASS list
/// @param $index - The list index to remove
/// @returns A SASS list
/// @author Jake Wilson <jake.e.wilson@gmail.com>
@function list-remove($list, $index) {
	$newList: ();
	@for $i from 1 through length($list) {
		@if $i !=$index {
			$newList: append($newList, nth($list, $i), 'space');
		}
	}
	@return $newList;
}

// Clear Lines
$screen-xs: 480px;
$screen-sm: 768px;
$screen-md: 992px;
$screen-lg: 1200px;

@mixin row-clear-lines() {
    $sizes: 2 3 4 6;
    $toggles: (1 'xs' 0) (2 'sm' $screen-xs-max) (3 'md' $screen-sm-max) (4 'lg' $screen-md-max);

    $i: 0;
    @each $i in $toggles {
        $index: index($toggles, $i);

        // For each toggle point (xs, sm, md, lg), we add a clear:both property to the First item of the line
        > .col-#{nth($i, 2)} {
            @media (min-width: #{nth($i, 3)}) {

                @each $s in $sizes {
                    $div: 12 / $s;

                    // Disabling of other clear (nth-child(n) to have the priority)
                    &-#{nth($s, 1)}:nth-child(n) {
                        clear: none;
                    }

                    // Application of clear both on first line items
                    &-#{nth($s, 1)}:nth-child(#{$div}n + 1) {
                        clear: both;
                    }
                }
            }
        }
    }
}
