
// Borrowed from sugar.js HEAD since startsWith/endsWith were very slow when
// they supported regexps.
(function() {
    function getCoercedStringSubject(obj) {
        if(obj == null) {
            throw new TypeError();
        }
        return String(obj);
    }

    function getCoercedSearchString(obj, errorOnRegex) {
        if(errorOnRegex && obj instanceof RegExp) {
            throw new TypeError();
        }
        return String(obj);
    }

    String.prototype.startsWith = function(searchString) {
        var str, start, pos, len, searchLength, position = arguments[1];
        str = getCoercedStringSubject(this);
        searchString = getCoercedSearchString(searchString, true);
        pos = Number(position) || 0;
        len = str.length;
        start = Math.min(Math.max(pos, 0), len);
        searchLength = searchString.length;
        if(searchLength + start > len) {
            return false;
        }
        if(str.substr(start, searchLength) === searchString) {
            return true;
        }
        return false;
    };

    String.prototype.endsWith = function(searchString) {
        var str, start, end, pos, len, searchLength, endPosition = arguments[1];
        str = getCoercedStringSubject(this);
        searchString = getCoercedSearchString(searchString, true);
        len = str.length;
        pos = len;
        if(endPosition != undefined) {
            pos = Number(endPosition) || 0;
        }
        end = Math.min(Math.max(pos, 0), len);
        searchLength = searchString.length;
        start = end - searchLength;
        if(start < 0) {
            return false;
        }
        if(str.substr(start, searchLength) === searchString) {
            return true;
        }
        return false;
    };
})();

// Polymer provides this, but we add it just in case so you can use models
// without polymer.
if (!NodeList.prototype.array) {
    NodeList.prototype.array = function() {
        return Array.prototype.slice.call(this);
    };
}

// Manually implement this so that Shadow DOM polyfill works.
// https://github.com/Polymer/ShadowDOM/issues/395
if (!Element.prototype.remove) {
    Element.prototype.remove = function() {
        if (!this.parentNode)
            return;
        this.parentNode.removeChild(this);
    };
}

// We only have String#contains if "Experimental JavaScript is enabled."
if (!String.prototype.contains) {
    String.prototype.contains = function(text) {
        return this.indexOf(text) != -1;
    };
}

@@ -1,108 +1,18 @@
-%0A// Borrowed from sugar.js HEAD since startsWith/endsWith were very slow when%0A// they supported regexps.
+%22use strict%22;%0A
 %0A(fu
@@ -22,20 +22,17 @@
 ion() %7B%0A
-    
+%0A
 function
@@ -36,43 +36,59 @@
 ion 
-getCoercedStringSubject(obj
+clampToLength(value, defaultValue, maxValue
 ) %7B%0A    
     
@@ -87,303 +87,233 @@
     
-    if(obj == null) %7B%0A            throw new TypeError();%0A        %7D%0A        return String(obj);%0A    %7D%0A%0A    function getCoercedSearchString(obj, errorOnRegex) %7B%0A        if(errorOnRegex && obj instanceof RegExp) %7B%0A            throw new TypeError();%0A        %7D%0A        return String(obj);%0A    %7D%0A%0A    
+if (value === undefined)%0A        return defaultValue;%0A    return Math.min(Math.max(value, 0), maxValue) %7C%7C 0;%0A%7D%0A%0A// FIXME: Remove this once sugar is updated. 1.4.1 has very slow startsWith%0A// because of the regex code in it.%0A
 Stri
@@ -347,36 +347,29 @@
 unction(
-searchString
+input
 ) %7B%0A    
     var 
@@ -364,1058 +364,759 @@
     
-    var str, start, pos, len, searchLength, position = arguments%5B1%5D;%0A        str = getCoercedStringSubject(this);%0A        searchString = getCoercedSearchString(searchString, true);%0A        pos = Number(position) %7C%7C 0;%0A        len = str.length;%0A        start = Math.min(Math.max(pos, 0), len
+if (this == null)%0A        throw new TypeError();%0A    var subject = String(this);%0A    if (input instanceof RegExp)%0A        throw new TypeError(
 );%0A    
-   
+var
  search
-Length = searchString.length;%0A        if(searchLength + start %3E len) %7B%0A            return false;%0A        %7D%0A        if(str.substr(start, searchLength) === searchString) %7B%0A            return true;%0A        %7D%0A        return false;%0A    %7D;%0A%0A    String.prototype.endsWith = function(searchString) %7B%0A        var str, start, end, pos, len, searchLength, endPosition = arguments%5B1%5D;%0A        str = getCoercedStringSubject(this);%0A        searchString = getCoercedSearchString(searchString, true);%0A        len = str.length;%0A        pos = len;%0A        if(endPosition != undefined) %7B%0A            pos = Number(endPosition) %7C%7C 0;%0A        %7D%0A        end = Math.min(Math.max(pos, 0), len);%0A        searchLength = searchString
+ = String(input);%0A    var position = clampToLength(arguments%5B1%5D, 0, subject.length);%0A    return subject.lastIndexOf(search, position) == position;%0A%7D;%0A%0A// FIXME: Remove this once sugar is updated. 1.4.1 has very slow endsWith%0A// because of the regex code in it.%0AString.prototype.endsWith = function(input) %7B%0A    if (this == null)%0A        throw new TypeError();%0A    var subject = String(this);%0A    if (input instanceof RegExp)%0A        throw new TypeError();%0A    var search = String(input);%0A    var position = clampToLength(arguments%5B1%5D, subject.length, subject
 .length
+)
 ;%0A    
-    start = end
+position
  -
+=
  search
-L
+.l
 engt
@@ -1126,191 +1126,116 @@
     
-    if(start %3C 0) %7B%0A            return false;%0A        %7D%0A        if(str.substr(start, searchLength) === searchString) %7B%0A            return true;%0A        %7D%0A        return false;%0A    
+var lastIndex = subject.indexOf(search, position);%0A    return lastIndex != -1 && lastIndex == position;%0A
 %7D;%0A
+%0A
 %7D)()

Simplify startsWith and endsWith shims.