Compare commits
	
		
			19 Commits
		
	
	
		
			field-rena
			...
			darkmode
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					e6f8b44c27 | ||
| 
						 | 
					49bed43cff | ||
| 
						 | 
					4218f25cb8 | ||
| 
						 | 
					dfdd69de23 | ||
| 
						 | 
					f612df1b1b | ||
| 
						 | 
					c82bf98f13 | ||
| 
						 | 
					855605c434 | ||
| 
						 | 
					3b2b1ea2f7 | ||
| 
						 | 
					5219698b07 | ||
| 
						 | 
					00be226210 | ||
| 
						 | 
					3078ddb261 | ||
| 
						 | 
					cdf691d5c4 | ||
| 
						 | 
					50e50f1caf | ||
| 
						 | 
					f96340c45e | ||
| 
						 | 
					0696dfa30d | ||
| 
						 | 
					b65f08eadb | ||
| 
						 | 
					e3a1a4275a | ||
| 
						 | 
					b2da26b2f1 | ||
| 
						 | 
					427cf105a3 | 
@@ -202,7 +202,9 @@ def changedetection_app(config=None, datastore_o=None):
 | 
			
		||||
    watch_api.add_resource(api_v1.SystemInfo, '/api/v1/systeminfo',
 | 
			
		||||
                           resource_class_kwargs={'datastore': datastore, 'update_q': update_q})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def getDarkModeSetting():
 | 
			
		||||
      css_dark_mode = request.cookies.get('css_dark_mode')
 | 
			
		||||
      return True if (css_dark_mode == 'true' or css_dark_mode == True) else False
 | 
			
		||||
 | 
			
		||||
    # Setup cors headers to allow all domains
 | 
			
		||||
    # https://flask-cors.readthedocs.io/en/latest/
 | 
			
		||||
@@ -403,6 +405,7 @@ def changedetection_app(config=None, datastore_o=None):
 | 
			
		||||
 | 
			
		||||
        form = forms.quickWatchForm(request.form)
 | 
			
		||||
        output = render_template("watch-overview.html",
 | 
			
		||||
                                 dark_mode=getDarkModeSetting(),
 | 
			
		||||
                                 form=form,
 | 
			
		||||
                                 watches=sorted_watches,
 | 
			
		||||
                                 tags=existing_tags,
 | 
			
		||||
@@ -661,6 +664,7 @@ def changedetection_app(config=None, datastore_o=None):
 | 
			
		||||
                                     browser_steps_config=browser_step_ui_config,
 | 
			
		||||
                                     current_base_url=datastore.data['settings']['application']['base_url'],
 | 
			
		||||
                                     emailprefix=os.getenv('NOTIFICATION_MAIL_BUTTON_PREFIX', False),
 | 
			
		||||
                                     dark_mode=getDarkModeSetting(),
 | 
			
		||||
                                     form=form,
 | 
			
		||||
                                     has_default_notification_urls=True if len(datastore.data['settings']['application']['notification_urls']) else False,
 | 
			
		||||
                                     has_empty_checktime=using_default_check_time,
 | 
			
		||||
@@ -748,6 +752,7 @@ def changedetection_app(config=None, datastore_o=None):
 | 
			
		||||
 | 
			
		||||
        output = render_template("settings.html",
 | 
			
		||||
                                 form=form,
 | 
			
		||||
                                 dark_mode=getDarkModeSetting(),
 | 
			
		||||
                                 current_base_url = datastore.data['settings']['application']['base_url'],
 | 
			
		||||
                                 hide_remove_pass=os.getenv("SALTED_PASS", False),
 | 
			
		||||
                                 api_key=datastore.data['settings']['application'].get('api_access_token'),
 | 
			
		||||
@@ -788,6 +793,7 @@ def changedetection_app(config=None, datastore_o=None):
 | 
			
		||||
 | 
			
		||||
        # Could be some remaining, or we could be on GET
 | 
			
		||||
        output = render_template("import.html",
 | 
			
		||||
                                 dark_mode=getDarkModeSetting(),
 | 
			
		||||
                                 import_url_list_remaining="\n".join(remaining_urls),
 | 
			
		||||
                                 original_distill_json=''
 | 
			
		||||
                                 )
 | 
			
		||||
@@ -865,6 +871,7 @@ def changedetection_app(config=None, datastore_o=None):
 | 
			
		||||
                                 newest=newest_version_file_contents,
 | 
			
		||||
                                 previous=previous_version_file_contents,
 | 
			
		||||
                                 extra_stylesheets=extra_stylesheets,
 | 
			
		||||
                                 dark_mode=getDarkModeSetting(),
 | 
			
		||||
                                 versions=dates[:-1], # All except current/last
 | 
			
		||||
                                 uuid=uuid,
 | 
			
		||||
                                 newest_version_timestamp=dates[-1],
 | 
			
		||||
@@ -912,6 +919,7 @@ def changedetection_app(config=None, datastore_o=None):
 | 
			
		||||
                                     content=content,
 | 
			
		||||
                                     history_n=watch.history_n,
 | 
			
		||||
                                     extra_stylesheets=extra_stylesheets,
 | 
			
		||||
                                     dark_mode=getDarkModeSetting(),
 | 
			
		||||
#                                     current_diff_url=watch['url'],
 | 
			
		||||
                                     watch=watch,
 | 
			
		||||
                                     uuid=uuid,
 | 
			
		||||
@@ -958,6 +966,7 @@ def changedetection_app(config=None, datastore_o=None):
 | 
			
		||||
                                 content=content,
 | 
			
		||||
                                 history_n=watch.history_n,
 | 
			
		||||
                                 extra_stylesheets=extra_stylesheets,
 | 
			
		||||
                                 dark_mode=getDarkModeSetting(),
 | 
			
		||||
                                 ignored_line_numbers=ignored_line_numbers,
 | 
			
		||||
                                 triggered_line_numbers=trigger_line_numbers,
 | 
			
		||||
                                 current_diff_url=watch['url'],
 | 
			
		||||
@@ -976,6 +985,7 @@ def changedetection_app(config=None, datastore_o=None):
 | 
			
		||||
    def notification_logs():
 | 
			
		||||
        global notification_debug_log
 | 
			
		||||
        output = render_template("notification-log.html",
 | 
			
		||||
                                 dark_mode=getDarkModeSetting(),
 | 
			
		||||
                                 logs=notification_debug_log if len(notification_debug_log) else ["Notification logs are empty - no notifications sent yet."])
 | 
			
		||||
 | 
			
		||||
        return output
 | 
			
		||||
 
 | 
			
		||||
@@ -207,9 +207,9 @@ class ValidateTokensList(object):
 | 
			
		||||
            if not p.strip('{}') in notification.valid_tokens:
 | 
			
		||||
                message = field.gettext('Token \'%s\' is not a valid token.')
 | 
			
		||||
                raise ValidationError(message % (p))
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
class validateURL(object):
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
       Flask wtform validators wont work with basic auth
 | 
			
		||||
    """
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,7 @@ class model(dict):
 | 
			
		||||
                    'base_url' : None,
 | 
			
		||||
                    'extract_title_as_title': False,
 | 
			
		||||
                    'empty_pages_are_a_change': False,
 | 
			
		||||
                    'css_dark_mode': False,
 | 
			
		||||
                    'fetch_backend': getenv("DEFAULT_FETCH_BACKEND", "html_requests"),
 | 
			
		||||
                    'filter_failure_notification_threshold_attempts': _FILTER_FAILURE_THRESHOLD_ATTEMPTS_DEFAULT,
 | 
			
		||||
                    'global_ignore_text': [], # List of text to ignore when calculating the comparison checksum
 | 
			
		||||
 
 | 
			
		||||
@@ -1,42 +1,4 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<svg
 | 
			
		||||
   width="15"
 | 
			
		||||
   height="16.363636"
 | 
			
		||||
   viewBox="0 0 15 16.363636"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   id="svg4"
 | 
			
		||||
   sodipodi:docname="bell-off.svg"
 | 
			
		||||
   inkscape:version="1.1.1 (1:1.1+202109281949+c3084ef5ed)"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg">
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="namedview5"
 | 
			
		||||
     pagecolor="#ffffff"
 | 
			
		||||
     bordercolor="#666666"
 | 
			
		||||
     borderopacity="1.0"
 | 
			
		||||
     inkscape:pageshadow="2"
 | 
			
		||||
     inkscape:pageopacity="0.0"
 | 
			
		||||
     inkscape:pagecheckerboard="0"
 | 
			
		||||
     showgrid="false"
 | 
			
		||||
     fit-margin-top="0"
 | 
			
		||||
     fit-margin-left="0"
 | 
			
		||||
     fit-margin-right="0"
 | 
			
		||||
     fit-margin-bottom="0"
 | 
			
		||||
     inkscape:zoom="28.416667"
 | 
			
		||||
     inkscape:cx="-0.59824046"
 | 
			
		||||
     inkscape:cy="12"
 | 
			
		||||
     inkscape:window-width="1554"
 | 
			
		||||
     inkscape:window-height="896"
 | 
			
		||||
     inkscape:window-x="2095"
 | 
			
		||||
     inkscape:window-y="107"
 | 
			
		||||
     inkscape:window-maximized="0"
 | 
			
		||||
     inkscape:current-layer="svg4" />
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs8" />
 | 
			
		||||
  <path
 | 
			
		||||
     d="m 14.318182,11.762045 v 1.1925 H 5.4102273 L 11.849318,7.1140909 C 12.234545,9.1561364 12.54,11.181818 14.318182,11.762045 Z m -6.7984093,4.601591 c 1.0759091,0 2.0256823,-0.955909 2.0256823,-2.045454 H 5.4545455 c 0,1.089545 0.9879545,2.045454 2.0652272,2.045454 z M 15,2.8622727 0.9177273,15.636136 0,14.627045 l 1.8443182,-1.6725 h -1.1625 v -1.1925 C 4.0070455,10.677273 2.1784091,4.5388636 5.3611364,2.6897727 5.8009091,2.4347727 6.0709091,1.9609091 6.0702273,1.4488636 v -0.00205 C 6.0702273,0.64772727 6.7104545,0 7.5,0 8.2895455,0 8.9297727,0.64772727 8.9297727,1.4468182 v 0.00205 C 8.9290909,1.9602319 9.199773,2.4354591 9.638864,2.6897773 10.364318,3.111141 10.827273,3.7568228 11.1525,4.5129591 L 14.085682,1.8531818 Z M 6.8181818,1.3636364 C 6.8181818,1.74 7.1236364,2.0454545 7.5,2.0454545 7.8763636,2.0454545 8.1818182,1.74 8.1818182,1.3636364 8.1818182,0.98795455 7.8763636,0.68181818 7.5,0.68181818 c -0.3763636,0 -0.6818182,0.30613637 -0.6818182,0.68181822 z"
 | 
			
		||||
     id="path2"
 | 
			
		||||
     style="fill:#f8321b;stroke-width:0.681818;fill-opacity:1" />
 | 
			
		||||
<svg width="15" height="16.363636" viewBox="0 0 15 16.363636" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
 | 
			
		||||
  <path d="m 14.318182,11.762045 v 1.1925 H 5.4102273 L 11.849318,7.1140909 C 12.234545,9.1561364 12.54,11.181818 14.318182,11.762045 Z m -6.7984093,4.601591 c 1.0759091,0 2.0256823,-0.955909 2.0256823,-2.045454 H 5.4545455 c 0,1.089545 0.9879545,2.045454 2.0652272,2.045454 z M 15,2.8622727 0.9177273,15.636136 0,14.627045 l 1.8443182,-1.6725 h -1.1625 v -1.1925 C 4.0070455,10.677273 2.1784091,4.5388636 5.3611364,2.6897727 5.8009091,2.4347727 6.0709091,1.9609091 6.0702273,1.4488636 v -0.00205 C 6.0702273,0.64772727 6.7104545,0 7.5,0 8.2895455,0 8.9297727,0.64772727 8.9297727,1.4468182 v 0.00205 C 8.9290909,1.9602319 9.199773,2.4354591 9.638864,2.6897773 10.364318,3.111141 10.827273,3.7568228 11.1525,4.5129591 L 14.085682,1.8531818 Z M 6.8181818,1.3636364 C 6.8181818,1.74 7.1236364,2.0454545 7.5,2.0454545 7.8763636,2.0454545 8.1818182,1.74 8.1818182,1.3636364 8.1818182,0.98795455 7.8763636,0.68181818 7.5,0.68181818 c -0.3763636,0 -0.6818182,0.30613637 -0.6818182,0.68181822 z" id="path2" style="fill:#f8321b;stroke-width:0.681818;fill-opacity:1"/>
 | 
			
		||||
</svg>
 | 
			
		||||
 
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 1.2 KiB  | 
@@ -1,46 +1,5 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<svg
 | 
			
		||||
   width="18"
 | 
			
		||||
   height="19.92"
 | 
			
		||||
   viewBox="0 0 18 19.92"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   id="svg6"
 | 
			
		||||
   sodipodi:docname="spread.svg"
 | 
			
		||||
   inkscape:version="1.1.1 (1:1.1+202109281949+c3084ef5ed)"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs10" />
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="namedview8"
 | 
			
		||||
     pagecolor="#ffffff"
 | 
			
		||||
     bordercolor="#666666"
 | 
			
		||||
     borderopacity="1.0"
 | 
			
		||||
     inkscape:pageshadow="2"
 | 
			
		||||
     inkscape:pageopacity="0.0"
 | 
			
		||||
     inkscape:pagecheckerboard="0"
 | 
			
		||||
     showgrid="false"
 | 
			
		||||
     fit-margin-top="0"
 | 
			
		||||
     fit-margin-left="0"
 | 
			
		||||
     fit-margin-right="0"
 | 
			
		||||
     fit-margin-bottom="0"
 | 
			
		||||
     inkscape:zoom="28.416667"
 | 
			
		||||
     inkscape:cx="9.0087975"
 | 
			
		||||
     inkscape:cy="9.9941348"
 | 
			
		||||
     inkscape:window-width="1920"
 | 
			
		||||
     inkscape:window-height="1056"
 | 
			
		||||
     inkscape:window-x="1920"
 | 
			
		||||
     inkscape:window-y="0"
 | 
			
		||||
     inkscape:window-maximized="1"
 | 
			
		||||
     inkscape:current-layer="svg6" />
 | 
			
		||||
  <path
 | 
			
		||||
     d="M -3,-2 H 21 V 22 H -3 Z"
 | 
			
		||||
     fill="none"
 | 
			
		||||
     id="path2" />
 | 
			
		||||
  <path
 | 
			
		||||
     d="m 15,14.08 c -0.76,0 -1.44,0.3 -1.96,0.77 L 5.91,10.7 C 5.96,10.47 6,10.24 6,10 6,9.76 5.96,9.53 5.91,9.3 L 12.96,5.19 C 13.5,5.69 14.21,6 15,6 16.66,6 18,4.66 18,3 18,1.34 16.66,0 15,0 c -1.66,0 -3,1.34 -3,3 0,0.24 0.04,0.47 0.09,0.7 L 5.04,7.81 C 4.5,7.31 3.79,7 3,7 1.34,7 0,8.34 0,10 c 0,1.66 1.34,3 3,3 0.79,0 1.5,-0.31 2.04,-0.81 l 7.12,4.16 c -0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.61 1.31,2.92 2.92,2.92 1.61,0 2.92,-1.31 2.92,-2.92 0,-1.61 -1.31,-2.92 -2.92,-2.92 z"
 | 
			
		||||
     id="path4"
 | 
			
		||||
     style="fill:#0078e7;fill-opacity:1" />
 | 
			
		||||
<svg width="18" height="19.92" viewBox="0 0 18 19.92" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
 | 
			
		||||
  <path d="M -3,-2 H 21 V 22 H -3 Z" fill="none" id="path2"/>
 | 
			
		||||
  <path d="m 15,14.08 c -0.76,0 -1.44,0.3 -1.96,0.77 L 5.91,10.7 C 5.96,10.47 6,10.24 6,10 6,9.76 5.96,9.53 5.91,9.3 L 12.96,5.19 C 13.5,5.69 14.21,6 15,6 16.66,6 18,4.66 18,3 18,1.34 16.66,0 15,0 c -1.66,0 -3,1.34 -3,3 0,0.24 0.04,0.47 0.09,0.7 L 5.04,7.81 C 4.5,7.31 3.79,7 3,7 1.34,7 0,8.34 0,10 c 0,1.66 1.34,3 3,3 0.79,0 1.5,-0.31 2.04,-0.81 l 7.12,4.16 c -0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.61 1.31,2.92 2.92,2.92 1.61,0 2.92,-1.31 2.92,-2.92 0,-1.61 -1.31,-2.92 -2.92,-2.92 z" id="path4" style="fill:#0078e7;fill-opacity:1"/>
 | 
			
		||||
</svg>
 | 
			
		||||
 
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 787 B  | 
@@ -1,112 +1,110 @@
 | 
			
		||||
var a = document.getElementById('a');
 | 
			
		||||
var b = document.getElementById('b');
 | 
			
		||||
var result = document.getElementById('result');
 | 
			
		||||
var a = document.getElementById("a");
 | 
			
		||||
var b = document.getElementById("b");
 | 
			
		||||
var result = document.getElementById("result");
 | 
			
		||||
 | 
			
		||||
function changed() {
 | 
			
		||||
    // https://github.com/kpdecker/jsdiff/issues/389
 | 
			
		||||
    // I would love to use `{ignoreWhitespace: true}` here but it breaks the formatting
 | 
			
		||||
    options = {ignoreWhitespace: document.getElementById('ignoreWhitespace').checked};
 | 
			
		||||
  // https://github.com/kpdecker/jsdiff/issues/389
 | 
			
		||||
  // I would love to use `{ignoreWhitespace: true}` here but it breaks the formatting
 | 
			
		||||
  options = {
 | 
			
		||||
    ignoreWhitespace: document.getElementById("ignoreWhitespace").checked,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
    var diff = Diff[window.diffType](a.textContent, b.textContent, options);
 | 
			
		||||
    var fragment = document.createDocumentFragment();
 | 
			
		||||
    for (var i = 0; i < diff.length; i++) {
 | 
			
		||||
 | 
			
		||||
        if (diff[i].added && diff[i + 1] && diff[i + 1].removed) {
 | 
			
		||||
            var swap = diff[i];
 | 
			
		||||
            diff[i] = diff[i + 1];
 | 
			
		||||
            diff[i + 1] = swap;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var node;
 | 
			
		||||
        if (diff[i].removed) {
 | 
			
		||||
            node = document.createElement('del');
 | 
			
		||||
            node.classList.add("change");
 | 
			
		||||
            node.appendChild(document.createTextNode(diff[i].value));
 | 
			
		||||
 | 
			
		||||
        } else if (diff[i].added) {
 | 
			
		||||
            node = document.createElement('ins');
 | 
			
		||||
            node.classList.add("change");
 | 
			
		||||
            node.appendChild(document.createTextNode(diff[i].value));
 | 
			
		||||
        } else {
 | 
			
		||||
            node = document.createTextNode(diff[i].value);
 | 
			
		||||
        }
 | 
			
		||||
        fragment.appendChild(node);
 | 
			
		||||
  var diff = Diff[window.diffType](a.textContent, b.textContent, options);
 | 
			
		||||
  var fragment = document.createDocumentFragment();
 | 
			
		||||
  for (var i = 0; i < diff.length; i++) {
 | 
			
		||||
    if (diff[i].added && diff[i + 1] && diff[i + 1].removed) {
 | 
			
		||||
      var swap = diff[i];
 | 
			
		||||
      diff[i] = diff[i + 1];
 | 
			
		||||
      diff[i + 1] = swap;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    result.textContent = '';
 | 
			
		||||
    result.appendChild(fragment);
 | 
			
		||||
    var node;
 | 
			
		||||
    if (diff[i].removed) {
 | 
			
		||||
      node = document.createElement("del");
 | 
			
		||||
      node.classList.add("change");
 | 
			
		||||
      const wrapper = node.appendChild(document.createElement("span"));
 | 
			
		||||
      wrapper.appendChild(document.createTextNode(diff[i].value));
 | 
			
		||||
    } else if (diff[i].added) {
 | 
			
		||||
      node = document.createElement("ins");
 | 
			
		||||
      node.classList.add("change");
 | 
			
		||||
      const wrapper = node.appendChild(document.createElement("span"));
 | 
			
		||||
      wrapper.appendChild(document.createTextNode(diff[i].value));
 | 
			
		||||
    } else {
 | 
			
		||||
      node = document.createTextNode(diff[i].value);
 | 
			
		||||
    }
 | 
			
		||||
    fragment.appendChild(node);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    // Jump at start
 | 
			
		||||
    inputs.current = 0;
 | 
			
		||||
    next_diff();
 | 
			
		||||
  result.textContent = "";
 | 
			
		||||
  result.appendChild(fragment);
 | 
			
		||||
 | 
			
		||||
  // Jump at start
 | 
			
		||||
  inputs.current = 0;
 | 
			
		||||
  next_diff();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
window.onload = function () {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /* Convert what is options from UTC time.time() to local browser time */
 | 
			
		||||
    var diffList = document.getElementById("diff-version");
 | 
			
		||||
    if (typeof (diffList) != 'undefined' && diffList != null) {
 | 
			
		||||
        for (var option of diffList.options) {
 | 
			
		||||
            var dateObject = new Date(option.value * 1000);
 | 
			
		||||
            option.label = dateObject.toLocaleString();
 | 
			
		||||
        }
 | 
			
		||||
  /* Convert what is options from UTC time.time() to local browser time */
 | 
			
		||||
  var diffList = document.getElementById("diff-version");
 | 
			
		||||
  if (typeof diffList != "undefined" && diffList != null) {
 | 
			
		||||
    for (var option of diffList.options) {
 | 
			
		||||
      var dateObject = new Date(option.value * 1000);
 | 
			
		||||
      option.label = dateObject.toLocaleString();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    /* Set current version date as local time in the browser also */
 | 
			
		||||
    var current_v = document.getElementById("current-v-date");
 | 
			
		||||
    var dateObject = new Date(newest_version_timestamp*1000);
 | 
			
		||||
    current_v.innerHTML = dateObject.toLocaleString();
 | 
			
		||||
    onDiffTypeChange(document.querySelector('#settings [name="diff_type"]:checked'));
 | 
			
		||||
    changed();
 | 
			
		||||
  /* Set current version date as local time in the browser also */
 | 
			
		||||
  var current_v = document.getElementById("current-v-date");
 | 
			
		||||
  var dateObject = new Date(newest_version_timestamp * 1000);
 | 
			
		||||
  current_v.innerHTML = dateObject.toLocaleString();
 | 
			
		||||
  onDiffTypeChange(
 | 
			
		||||
    document.querySelector('#settings [name="diff_type"]:checked'),
 | 
			
		||||
  );
 | 
			
		||||
  changed();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
a.onpaste = a.onchange =
 | 
			
		||||
    b.onpaste = b.onchange = changed;
 | 
			
		||||
a.onpaste = a.onchange = b.onpaste = b.onchange = changed;
 | 
			
		||||
 | 
			
		||||
if ('oninput' in a) {
 | 
			
		||||
    a.oninput = b.oninput = changed;
 | 
			
		||||
if ("oninput" in a) {
 | 
			
		||||
  a.oninput = b.oninput = changed;
 | 
			
		||||
} else {
 | 
			
		||||
    a.onkeyup = b.onkeyup = changed;
 | 
			
		||||
  a.onkeyup = b.onkeyup = changed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function onDiffTypeChange(radio) {
 | 
			
		||||
    window.diffType = radio.value;
 | 
			
		||||
// Not necessary
 | 
			
		||||
//	document.title = "Diff " + radio.value.slice(4);
 | 
			
		||||
  window.diffType = radio.value;
 | 
			
		||||
  // Not necessary
 | 
			
		||||
  //	document.title = "Diff " + radio.value.slice(4);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var radio = document.getElementsByName('diff_type');
 | 
			
		||||
var radio = document.getElementsByName("diff_type");
 | 
			
		||||
for (var i = 0; i < radio.length; i++) {
 | 
			
		||||
    radio[i].onchange = function (e) {
 | 
			
		||||
        onDiffTypeChange(e.target);
 | 
			
		||||
        changed();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
document.getElementById('ignoreWhitespace').onchange = function (e) {
 | 
			
		||||
  radio[i].onchange = function (e) {
 | 
			
		||||
    onDiffTypeChange(e.target);
 | 
			
		||||
    changed();
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
document.getElementById("ignoreWhitespace").onchange = function (e) {
 | 
			
		||||
  changed();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var inputs = document.getElementsByClassName('change');
 | 
			
		||||
var inputs = document.getElementsByClassName("change");
 | 
			
		||||
inputs.current = 0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function next_diff() {
 | 
			
		||||
  var element = inputs[inputs.current];
 | 
			
		||||
  var headerOffset = 80;
 | 
			
		||||
  var elementPosition = element.getBoundingClientRect().top;
 | 
			
		||||
  var offsetPosition = elementPosition - headerOffset + window.scrollY;
 | 
			
		||||
 | 
			
		||||
    var element = inputs[inputs.current];
 | 
			
		||||
    var headerOffset = 80;
 | 
			
		||||
    var elementPosition = element.getBoundingClientRect().top;
 | 
			
		||||
    var offsetPosition = elementPosition - headerOffset + window.scrollY;
 | 
			
		||||
  window.scrollTo({
 | 
			
		||||
    top: offsetPosition,
 | 
			
		||||
    behavior: "smooth",
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
    window.scrollTo({
 | 
			
		||||
        top: offsetPosition,
 | 
			
		||||
        behavior: "smooth"
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    inputs.current++;
 | 
			
		||||
    if (inputs.current >= inputs.length) {
 | 
			
		||||
        inputs.current = 0;
 | 
			
		||||
    }
 | 
			
		||||
  inputs.current++;
 | 
			
		||||
  if (inputs.current >= inputs.length) {
 | 
			
		||||
    inputs.current = 0;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										24
									
								
								changedetectionio/static/js/toggle-theme.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,24 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 * Toggles theme between light and dark mode.
 | 
			
		||||
 */
 | 
			
		||||
$(document).ready(function () {
 | 
			
		||||
  const button = document.getElementsByClassName("toggle-theme")[0];
 | 
			
		||||
 | 
			
		||||
  button.onclick = () => {
 | 
			
		||||
    const htmlElement = document.getElementsByTagName("html");
 | 
			
		||||
    const isDarkMode = htmlElement[0].dataset.darkmode === "true";
 | 
			
		||||
    htmlElement[0].dataset.darkmode = !isDarkMode;
 | 
			
		||||
    if (isDarkMode) {
 | 
			
		||||
      button.classList.remove("dark");
 | 
			
		||||
      setCookieValue(false);
 | 
			
		||||
    } else {
 | 
			
		||||
      button.classList.add("dark");
 | 
			
		||||
      setCookieValue(true);
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const setCookieValue = (value) => {
 | 
			
		||||
    document.cookie = `css_dark_mode=${value};max-age=31536000`
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
@@ -1,5 +1,130 @@
 | 
			
		||||
/**
 | 
			
		||||
 * CSS custom properties (aka variables).
 | 
			
		||||
 */
 | 
			
		||||
:root {
 | 
			
		||||
  --color-white: #fff;
 | 
			
		||||
  --color-grey-50: #111;
 | 
			
		||||
  --color-grey-100: #262626;
 | 
			
		||||
  --color-grey-200: #333;
 | 
			
		||||
  --color-grey-300: #444;
 | 
			
		||||
  --color-grey-325: #555;
 | 
			
		||||
  --color-grey-350: #565d64;
 | 
			
		||||
  --color-grey-400: #666;
 | 
			
		||||
  --color-grey-500: #777;
 | 
			
		||||
  --color-grey-600: #999;
 | 
			
		||||
  --color-grey-700: #cbcbcb;
 | 
			
		||||
  --color-grey-750: #ddd;
 | 
			
		||||
  --color-grey-800: #e0e0e0;
 | 
			
		||||
  --color-grey-850: #eee;
 | 
			
		||||
  --color-grey-900: #f2f2f2;
 | 
			
		||||
  --color-black: #000;
 | 
			
		||||
  --color-background-page: var(--color-grey-100);
 | 
			
		||||
  --color-background-gradient-first: #5ad8f7;
 | 
			
		||||
  --color-background-gradient-second: #2f50af;
 | 
			
		||||
  --color-background-gradient-third: #9150bf;
 | 
			
		||||
  --color-background: var(--color-white);
 | 
			
		||||
  --color-text: var(--color-grey-200);
 | 
			
		||||
  --color-link: #1b98f8;
 | 
			
		||||
  --color-menu-accent: #ed5900;
 | 
			
		||||
  --color-background-code: var(--color-grey-850);
 | 
			
		||||
  --color-error: #a00;
 | 
			
		||||
  --color-error-input: #ffebeb;
 | 
			
		||||
  --color-error-list: #dd0000;
 | 
			
		||||
  --color-table-background: var(--color-background);
 | 
			
		||||
  --color-table-stripe: var(--color-grey-900);
 | 
			
		||||
  --color-text-tab: var(--color-white);
 | 
			
		||||
  --color-background-tab: rgba(255, 255, 255, 0.2);
 | 
			
		||||
  --color-background-tab-hover: rgba(255, 255, 255, 0.5);
 | 
			
		||||
  --color-text-tab-active: #222;
 | 
			
		||||
  --color-api-key: #0078e7;
 | 
			
		||||
  --color-background-button-primary: #0078e7;
 | 
			
		||||
  --color-background-button-green: #42dd53;
 | 
			
		||||
  --color-background-button-red: #dd4242;
 | 
			
		||||
  --color-background-button-success: rgb(28, 184, 65);
 | 
			
		||||
  --color-background-button-error: rgb(202, 60, 60);
 | 
			
		||||
  --color-text-button-error: var(--color-white);
 | 
			
		||||
  --color-background-button-warning: rgb(202, 60, 60);
 | 
			
		||||
  --color-text-button-warning: var(--color-white);
 | 
			
		||||
  --color-background-button-secondary: rgb(66, 184, 221);
 | 
			
		||||
  --color-background-button-cancel: rgb(200, 200, 200);
 | 
			
		||||
  --color-text-button: var(--color-white);
 | 
			
		||||
  --color-background-button-tag: rgb(99, 99, 99);
 | 
			
		||||
  --color-background-snapshot-age: #dfdfdf;
 | 
			
		||||
  --color-error-text-snapshot-age: var(--color-white);
 | 
			
		||||
  --color-error-background-snapshot-age: #ff0000;
 | 
			
		||||
  --color-background-button-tag-active: #9c9c9c;
 | 
			
		||||
  --color-text-messages: var(--color-white);
 | 
			
		||||
  --color-background-messages-message: rgba(255, 255, 255, .2);
 | 
			
		||||
  --color-background-messages-error: rgba(255, 1, 1, .5);
 | 
			
		||||
  --color-background-messages-notice: rgba(255, 255, 255, .5);
 | 
			
		||||
  --color-border-notification: #ccc;
 | 
			
		||||
  --color-background-checkbox-operations: rgba(0, 0, 0, 0.05);
 | 
			
		||||
  --color-warning: #ff3300;
 | 
			
		||||
  --color-border-warning: var(--color-warning);
 | 
			
		||||
  --color-text-legend: var(--color-white);
 | 
			
		||||
  --color-link-new-version: #e07171;
 | 
			
		||||
  --color-last-checked: #bbb;
 | 
			
		||||
  --color-text-footer: #444;
 | 
			
		||||
  --color-border-watch-table-cell: #eee;
 | 
			
		||||
  --color-text-watch-tag-list: #e70069;
 | 
			
		||||
  --color-background-new-watch-form: rgba(0, 0, 0, 0.05);
 | 
			
		||||
  --color-background-new-watch-input: var(--color-white);
 | 
			
		||||
  --color-text-new-watch-input: var(--color-text);
 | 
			
		||||
  --color-border-input: var(--color-grey-500);
 | 
			
		||||
  --color-shadow-input: var(--color-grey-400);
 | 
			
		||||
  --color-background-input: var(--color-white);
 | 
			
		||||
  --color-text-input: var(--color-text);
 | 
			
		||||
  --color-text-input-description: var(--color-grey-500);
 | 
			
		||||
  --color-text-input-placeholder: var(--color-grey-600);
 | 
			
		||||
  --color-background-table-thead: var(--color-grey-800);
 | 
			
		||||
  --color-border-table-cell: var(--color-grey-700);
 | 
			
		||||
  --color-text-menu-heading: var(--color-grey-350);
 | 
			
		||||
  --color-text-menu-link: var(--color-grey-500);
 | 
			
		||||
  --color-background-menu-link-hover: var(--color-grey-850);
 | 
			
		||||
  --color-text-menu-link-hover: var(--color-grey-300);
 | 
			
		||||
  --color-shadow-jump: var(--color-grey-500);
 | 
			
		||||
  --color-icon-github: var(--color-black);
 | 
			
		||||
  --color-icon-github-hover: var(--color-grey-300); }
 | 
			
		||||
 | 
			
		||||
html[data-darkmode="true"] {
 | 
			
		||||
  --color-link: #59bdfb;
 | 
			
		||||
  --color-text: var(--color-white);
 | 
			
		||||
  --color-background-gradient-first: #3f90a5;
 | 
			
		||||
  --color-background-gradient-second: #1e316c;
 | 
			
		||||
  --color-background-gradient-third: #4d2c64;
 | 
			
		||||
  --color-background-new-watch-input: var(--color-grey-100);
 | 
			
		||||
  --color-text-new-watch-input: var(--color-text);
 | 
			
		||||
  --color-background-table-thead: var(--color-grey-200);
 | 
			
		||||
  --color-table-background: var(--color-grey-300);
 | 
			
		||||
  --color-table-stripe: var(--color-grey-325);
 | 
			
		||||
  --color-background: var(--color-grey-300);
 | 
			
		||||
  --color-text-menu-heading: var(--color-grey-850);
 | 
			
		||||
  --color-text-menu-link: var(--color-grey-800);
 | 
			
		||||
  --color-border-table-cell: var(--color-grey-400);
 | 
			
		||||
  --color-text-tab-active: var(--color-text);
 | 
			
		||||
  --color-border-input: var(--color-grey-400);
 | 
			
		||||
  --color-shadow-input: var(--color-grey-50);
 | 
			
		||||
  --color-background-input: var(--color-grey-350);
 | 
			
		||||
  --color-text-input-description: var(--color-grey-600);
 | 
			
		||||
  --color-text-input-placeholder: var(--color-grey-600);
 | 
			
		||||
  --color-text-watch-tag-list: #fa3e92;
 | 
			
		||||
  --color-background-code: var(--color-grey-200);
 | 
			
		||||
  --color-background-tab: rgba(0, 0, 0, 0.2);
 | 
			
		||||
  --color-background-tab-hover: rgba(0, 0, 0, 0.5);
 | 
			
		||||
  --color-background-snapshot-age: var(--color-grey-200);
 | 
			
		||||
  --color-shadow-jump: var(--color-grey-200);
 | 
			
		||||
  --color-icon-github: var(--color-white);
 | 
			
		||||
  --color-icon-github-hover: var(--color-grey-700); }
 | 
			
		||||
  html[data-darkmode="true"] .watch-controls img {
 | 
			
		||||
    opacity: 0.4; }
 | 
			
		||||
  html[data-darkmode="true"] .icon-spread {
 | 
			
		||||
    filter: hue-rotate(-10deg) brightness(1.5); }
 | 
			
		||||
  html[data-darkmode="true"] .watch-table .title-col a[target="_blank"]::after,
 | 
			
		||||
  html[data-darkmode="true"] .watch-table .current-diff-url::after {
 | 
			
		||||
    filter: invert(0.5) hue-rotate(10deg) brightness(2); }
 | 
			
		||||
 | 
			
		||||
#diff-ui {
 | 
			
		||||
  background: #fff;
 | 
			
		||||
  background: var(--color-background);
 | 
			
		||||
  padding: 2em;
 | 
			
		||||
  margin-left: 1em;
 | 
			
		||||
  margin-right: 1em;
 | 
			
		||||
@@ -45,6 +170,10 @@ ins {
 | 
			
		||||
    margin-left: 1em;
 | 
			
		||||
    display: inline-block;
 | 
			
		||||
    font-weight: normal; }
 | 
			
		||||
  #settings del {
 | 
			
		||||
    padding: 0.5em; }
 | 
			
		||||
  #settings ins {
 | 
			
		||||
    padding: 0.5em; }
 | 
			
		||||
 | 
			
		||||
.source {
 | 
			
		||||
  position: absolute;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,96 +0,0 @@
 | 
			
		||||
#diff-ui {
 | 
			
		||||
 | 
			
		||||
    background: #fff;
 | 
			
		||||
    padding: 2em;
 | 
			
		||||
    margin-left: 1em;
 | 
			
		||||
    margin-right: 1em;
 | 
			
		||||
    border-radius: 5px;
 | 
			
		||||
    font-size: 11px;
 | 
			
		||||
 | 
			
		||||
    table {
 | 
			
		||||
        table-layout: fixed;
 | 
			
		||||
        width: 100%;
 | 
			
		||||
    }
 | 
			
		||||
    td {
 | 
			
		||||
        padding: 3px 4px;
 | 
			
		||||
        border: 1px solid transparent;
 | 
			
		||||
        vertical-align: top;
 | 
			
		||||
        font: 1em monospace;
 | 
			
		||||
        text-align: left;
 | 
			
		||||
    }
 | 
			
		||||
    pre {
 | 
			
		||||
            white-space: pre-wrap;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
h1 {
 | 
			
		||||
	display: inline;
 | 
			
		||||
	font-size: 100%;
 | 
			
		||||
}
 | 
			
		||||
del {
 | 
			
		||||
	text-decoration: none;
 | 
			
		||||
	color: #b30000;
 | 
			
		||||
	background: #fadad7;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ins {
 | 
			
		||||
	background: #eaf2c2;
 | 
			
		||||
	color: #406619;
 | 
			
		||||
	text-decoration: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#result {
 | 
			
		||||
	white-space: pre-wrap;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#settings {
 | 
			
		||||
    background: rgba(0,0,0,.05);
 | 
			
		||||
    padding: 1em;
 | 
			
		||||
    border-radius: 10px;
 | 
			
		||||
    margin-bottom: 1em;
 | 
			
		||||
    color: #fff;
 | 
			
		||||
    font-size: 80%;
 | 
			
		||||
    label {
 | 
			
		||||
	    margin-left: 1em;
 | 
			
		||||
	    display: inline-block;
 | 
			
		||||
	    font-weight: normal;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.source {
 | 
			
		||||
	position: absolute;
 | 
			
		||||
	right: 1%;
 | 
			
		||||
	top: .2em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@-moz-document url-prefix() {
 | 
			
		||||
	body {
 | 
			
		||||
		height: 99%; /* Hide scroll bar in Firefox */
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
td#diff-col div {
 | 
			
		||||
    text-align: justify;
 | 
			
		||||
    white-space: pre-wrap;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ignored {
 | 
			
		||||
    background-color: #ccc;
 | 
			
		||||
   /*  border: #0d91fa 1px solid; */
 | 
			
		||||
    opacity: 0.7;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.triggered {
 | 
			
		||||
    background-color: #1b98f8;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ignored and triggered? make it obvious error */
 | 
			
		||||
.ignored.triggered {
 | 
			
		||||
  background-color: #ff0000;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.tab-pane-inner#screenshot {
 | 
			
		||||
  text-align: center;
 | 
			
		||||
  img {
 | 
			
		||||
    max-width: 99%;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -4,7 +4,8 @@
 | 
			
		||||
  "description": "",
 | 
			
		||||
  "main": "index.js",
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "build": "node-sass styles.scss -o .;node-sass diff.scss -o ."
 | 
			
		||||
    "watch": "node-sass -w scss -o .",
 | 
			
		||||
    "build": "node-sass scss -o ."
 | 
			
		||||
  },
 | 
			
		||||
  "author": "",
 | 
			
		||||
  "license": "ISC",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										117
									
								
								changedetectionio/static/styles/scss/diff.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,117 @@
 | 
			
		||||
@import "parts/_variables.scss";
 | 
			
		||||
 | 
			
		||||
#diff-ui {
 | 
			
		||||
 | 
			
		||||
  background: var(--color-background);
 | 
			
		||||
  padding: 2em;
 | 
			
		||||
  margin-left: 1em;
 | 
			
		||||
  margin-right: 1em;
 | 
			
		||||
  border-radius: 5px;
 | 
			
		||||
  font-size: 11px;
 | 
			
		||||
 | 
			
		||||
  table {
 | 
			
		||||
    table-layout: fixed;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  td {
 | 
			
		||||
    padding: 3px 4px;
 | 
			
		||||
    border: 1px solid transparent;
 | 
			
		||||
    vertical-align: top;
 | 
			
		||||
    font: 1em monospace;
 | 
			
		||||
    text-align: left;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  pre {
 | 
			
		||||
    white-space: pre-wrap;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
h1 {
 | 
			
		||||
  display: inline;
 | 
			
		||||
  font-size: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
del {
 | 
			
		||||
  text-decoration: none;
 | 
			
		||||
  color: #b30000;
 | 
			
		||||
  background: #fadad7;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ins {
 | 
			
		||||
  background: #eaf2c2;
 | 
			
		||||
  color: #406619;
 | 
			
		||||
  text-decoration: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#result {
 | 
			
		||||
  white-space: pre-wrap;
 | 
			
		||||
 | 
			
		||||
  .change {
 | 
			
		||||
    span {}
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#settings {
 | 
			
		||||
  background: rgba(0, 0, 0, .05);
 | 
			
		||||
  padding: 1em;
 | 
			
		||||
  border-radius: 10px;
 | 
			
		||||
  margin-bottom: 1em;
 | 
			
		||||
  color: #fff;
 | 
			
		||||
  font-size: 80%;
 | 
			
		||||
 | 
			
		||||
  label {
 | 
			
		||||
    margin-left: 1em;
 | 
			
		||||
    display: inline-block;
 | 
			
		||||
    font-weight: normal;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  del {
 | 
			
		||||
    padding: 0.5em;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ins {
 | 
			
		||||
    padding: 0.5em;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.source {
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  right: 1%;
 | 
			
		||||
  top: .2em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@-moz-document url-prefix() {
 | 
			
		||||
  body {
 | 
			
		||||
    height: 99%;
 | 
			
		||||
    /* Hide scroll bar in Firefox */
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
td#diff-col div {
 | 
			
		||||
  text-align: justify;
 | 
			
		||||
  white-space: pre-wrap;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ignored {
 | 
			
		||||
  background-color: #ccc;
 | 
			
		||||
  /*  border: #0d91fa 1px solid; */
 | 
			
		||||
  opacity: 0.7;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.triggered {
 | 
			
		||||
  background-color: #1b98f8;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ignored and triggered? make it obvious error */
 | 
			
		||||
.ignored.triggered {
 | 
			
		||||
  background-color: #ff0000;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.tab-pane-inner#screenshot {
 | 
			
		||||
  text-align: center;
 | 
			
		||||
 | 
			
		||||
  img {
 | 
			
		||||
    max-width: 99%;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -90,5 +90,6 @@
 | 
			
		||||
    &:hover {
 | 
			
		||||
      cursor: pointer;
 | 
			
		||||
    }
 | 
			
		||||
    color: var(--color-grey-400);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										155
									
								
								changedetectionio/static/styles/scss/parts/_variables.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,155 @@
 | 
			
		||||
/**
 | 
			
		||||
 * CSS custom properties (aka variables).
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
:root {
 | 
			
		||||
  --color-white: #fff;
 | 
			
		||||
  --color-grey-50: #111;
 | 
			
		||||
  --color-grey-100: #262626;
 | 
			
		||||
  --color-grey-200: #333;
 | 
			
		||||
  --color-grey-300: #444;
 | 
			
		||||
  --color-grey-325: #555;
 | 
			
		||||
  --color-grey-350: #565d64;
 | 
			
		||||
  --color-grey-400: #666;
 | 
			
		||||
  --color-grey-500: #777;
 | 
			
		||||
  --color-grey-600: #999;
 | 
			
		||||
  --color-grey-700: #cbcbcb;
 | 
			
		||||
  --color-grey-750: #ddd;
 | 
			
		||||
  --color-grey-800: #e0e0e0;
 | 
			
		||||
  --color-grey-850: #eee;
 | 
			
		||||
  --color-grey-900: #f2f2f2;
 | 
			
		||||
  --color-black: #000;
 | 
			
		||||
 | 
			
		||||
  --color-background-page: var(--color-grey-100);
 | 
			
		||||
  --color-background-gradient-first: #5ad8f7;
 | 
			
		||||
  --color-background-gradient-second: #2f50af;
 | 
			
		||||
  --color-background-gradient-third: #9150bf;
 | 
			
		||||
  --color-background: var(--color-white);
 | 
			
		||||
  --color-text: var(--color-grey-200);
 | 
			
		||||
  --color-link: #1b98f8;
 | 
			
		||||
  --color-menu-accent: #ed5900;
 | 
			
		||||
  --color-background-code: var(--color-grey-850);
 | 
			
		||||
  --color-error: #a00;
 | 
			
		||||
  --color-error-input: #ffebeb;
 | 
			
		||||
  --color-error-list: #dd0000;
 | 
			
		||||
  --color-table-background: var(--color-background);
 | 
			
		||||
  --color-table-stripe: var(--color-grey-900);
 | 
			
		||||
  --color-text-tab: var(--color-white);
 | 
			
		||||
  --color-background-tab: rgba(255, 255, 255, 0.2);
 | 
			
		||||
  --color-background-tab-hover: rgba(255, 255, 255, 0.5);
 | 
			
		||||
  --color-text-tab-active: #222;
 | 
			
		||||
  --color-api-key: #0078e7;
 | 
			
		||||
 | 
			
		||||
  --color-background-button-primary: #0078e7;
 | 
			
		||||
  --color-background-button-green: #42dd53;
 | 
			
		||||
  --color-background-button-red: #dd4242;
 | 
			
		||||
  --color-background-button-success: rgb(28, 184, 65);
 | 
			
		||||
  --color-background-button-error: rgb(202, 60, 60);
 | 
			
		||||
  --color-text-button-error: var(--color-white);
 | 
			
		||||
  --color-background-button-warning: rgb(202, 60, 60);
 | 
			
		||||
  --color-text-button-warning: var(--color-white);
 | 
			
		||||
  --color-background-button-secondary: rgb(66, 184, 221);
 | 
			
		||||
  --color-background-button-cancel: rgb(200, 200, 200);
 | 
			
		||||
  --color-text-button: var(--color-white);
 | 
			
		||||
  --color-background-button-tag: rgb(99, 99, 99);
 | 
			
		||||
  --color-background-snapshot-age: #dfdfdf;
 | 
			
		||||
  --color-error-text-snapshot-age: var(--color-white);
 | 
			
		||||
  --color-error-background-snapshot-age: #ff0000;
 | 
			
		||||
  --color-background-button-tag-active: #9c9c9c;
 | 
			
		||||
 | 
			
		||||
  --color-text-messages: var(--color-white);
 | 
			
		||||
  --color-background-messages-message: rgba(255, 255, 255, .2);
 | 
			
		||||
  --color-background-messages-error: rgba(255, 1, 1, .5);
 | 
			
		||||
  --color-background-messages-notice: rgba(255, 255, 255, .5);
 | 
			
		||||
  --color-border-notification: #ccc;
 | 
			
		||||
 | 
			
		||||
  --color-background-checkbox-operations: rgba(0, 0, 0, 0.05);
 | 
			
		||||
  --color-warning: #ff3300;
 | 
			
		||||
  --color-border-warning: var(--color-warning);
 | 
			
		||||
  --color-text-legend: var(--color-white);
 | 
			
		||||
 | 
			
		||||
  --color-link-new-version: #e07171;
 | 
			
		||||
  --color-last-checked: #bbb;
 | 
			
		||||
  --color-text-footer: #444;
 | 
			
		||||
  --color-border-watch-table-cell: #eee;
 | 
			
		||||
 | 
			
		||||
  --color-text-watch-tag-list: #e70069;
 | 
			
		||||
  --color-background-new-watch-form: rgba(0, 0, 0, 0.05);
 | 
			
		||||
  --color-background-new-watch-input: var(--color-white);
 | 
			
		||||
  --color-text-new-watch-input: var(--color-text);
 | 
			
		||||
 | 
			
		||||
  --color-border-input: var(--color-grey-500);
 | 
			
		||||
  --color-shadow-input: var(--color-grey-400);
 | 
			
		||||
  --color-background-input: var(--color-white);
 | 
			
		||||
  --color-text-input: var(--color-text);
 | 
			
		||||
  --color-text-input-description: var(--color-grey-500);
 | 
			
		||||
  --color-text-input-placeholder: var(--color-grey-600);
 | 
			
		||||
 | 
			
		||||
  --color-background-table-thead: var(--color-grey-800);
 | 
			
		||||
  --color-border-table-cell: var(--color-grey-700);
 | 
			
		||||
 | 
			
		||||
  --color-text-menu-heading: var(--color-grey-350);
 | 
			
		||||
  --color-text-menu-link: var(--color-grey-500);
 | 
			
		||||
  --color-background-menu-link-hover: var(--color-grey-850);
 | 
			
		||||
  --color-text-menu-link-hover: var(--color-grey-300);
 | 
			
		||||
 | 
			
		||||
  --color-shadow-jump: var(--color-grey-500);
 | 
			
		||||
  --color-icon-github: var(--color-black);
 | 
			
		||||
  --color-icon-github-hover: var(--color-grey-300);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
html[data-darkmode="true"] {
 | 
			
		||||
  --color-link: #59bdfb;
 | 
			
		||||
  --color-text: var(--color-white);
 | 
			
		||||
 | 
			
		||||
  --color-background-gradient-first: #3f90a5;
 | 
			
		||||
  --color-background-gradient-second: #1e316c;
 | 
			
		||||
  --color-background-gradient-third: #4d2c64;
 | 
			
		||||
 | 
			
		||||
  --color-background-new-watch-input: var(--color-grey-100);
 | 
			
		||||
  --color-text-new-watch-input: var(--color-text);
 | 
			
		||||
  --color-background-table-thead: var(--color-grey-200);
 | 
			
		||||
  --color-table-background: var(--color-grey-300);
 | 
			
		||||
  --color-table-stripe: var(--color-grey-325);
 | 
			
		||||
  --color-background: var(--color-grey-300);
 | 
			
		||||
  --color-text-menu-heading: var(--color-grey-850);
 | 
			
		||||
  --color-text-menu-link: var(--color-grey-800);
 | 
			
		||||
  --color-border-table-cell: var(--color-grey-400);
 | 
			
		||||
  --color-text-tab-active: var(--color-text);
 | 
			
		||||
 | 
			
		||||
  --color-border-input: var(--color-grey-400);
 | 
			
		||||
  --color-shadow-input: var(--color-grey-50);
 | 
			
		||||
  --color-background-input: var(--color-grey-350);
 | 
			
		||||
  --color-text-input-description: var(--color-grey-600);
 | 
			
		||||
  --color-text-input-placeholder: var(--color-grey-600);
 | 
			
		||||
  --color-text-watch-tag-list: #fa3e92;
 | 
			
		||||
 | 
			
		||||
  --color-background-code: var(--color-grey-200);
 | 
			
		||||
 | 
			
		||||
  --color-background-tab: rgba(0, 0, 0, 0.2);
 | 
			
		||||
  --color-background-tab-hover: rgba(0, 0, 0, 0.5);
 | 
			
		||||
 | 
			
		||||
  --color-background-snapshot-age: var(--color-grey-200);
 | 
			
		||||
  --color-shadow-jump: var(--color-grey-200);
 | 
			
		||||
  --color-icon-github: var(--color-white);
 | 
			
		||||
  --color-icon-github-hover: var(--color-grey-700);
 | 
			
		||||
 | 
			
		||||
  // Anything that can't be manipulated through variables follows.
 | 
			
		||||
  .watch-controls {
 | 
			
		||||
    img {
 | 
			
		||||
      opacity: 0.4;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .icon-spread {
 | 
			
		||||
    filter: hue-rotate(-10deg) brightness(1.5);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .watch-table {
 | 
			
		||||
 | 
			
		||||
    .title-col a[target="_blank"]::after,
 | 
			
		||||
    .current-diff-url::after {
 | 
			
		||||
      filter: invert(.5) hue-rotate(10deg) brightness(2);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,42 +1,107 @@
 | 
			
		||||
/*
 | 
			
		||||
 * -- BASE STYLES --
 | 
			
		||||
 * Most of these are inherited from Base, but I want to change a few.
 | 
			
		||||
nvm use v14.18.1 && npm install && npm run build
 | 
			
		||||
 * or npm run watch
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
@import "parts/spinners";
 | 
			
		||||
@import "parts/browser-steps";
 | 
			
		||||
@import "parts/_arrows.scss";
 | 
			
		||||
@import "parts/_variables";
 | 
			
		||||
@import "parts/_spinners";
 | 
			
		||||
@import "parts/_browser-steps";
 | 
			
		||||
@import "parts/_arrows";
 | 
			
		||||
 | 
			
		||||
body {
 | 
			
		||||
  color: #333;
 | 
			
		||||
  background: #262626;
 | 
			
		||||
  color: var(--color-text);
 | 
			
		||||
  background: var(--color-background-page);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.visually-hidden {
 | 
			
		||||
  clip: rect(0 0 0 0);
 | 
			
		||||
  clip-path: inset(50%);
 | 
			
		||||
  height: 1px;
 | 
			
		||||
  overflow: hidden;
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  white-space: nowrap;
 | 
			
		||||
  width: 1px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pure-table-even {
 | 
			
		||||
  background: #fff;
 | 
			
		||||
  background: var(--color-background);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Some styles from https://css-tricks.com/ */
 | 
			
		||||
a {
 | 
			
		||||
  text-decoration: none;
 | 
			
		||||
  color: #1b98f8;
 | 
			
		||||
  color: var(--color-link);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
a.github-link {
 | 
			
		||||
  color: #fff;
 | 
			
		||||
  color: var(--color-icon-github);
 | 
			
		||||
  margin: 0 1rem 0 0.5rem;
 | 
			
		||||
 | 
			
		||||
  svg {
 | 
			
		||||
    fill: currentColor;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  &:hover {
 | 
			
		||||
    color: var(--color-icon-github-hover);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
button.toggle-theme {
 | 
			
		||||
  width: 4rem;
 | 
			
		||||
  background: transparent;
 | 
			
		||||
  border: none;
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
 | 
			
		||||
  color: var(--color-icon-github);
 | 
			
		||||
 | 
			
		||||
  &:hover {
 | 
			
		||||
    color: var(--color-icon-github-hover);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  svg {
 | 
			
		||||
    fill: currentColor;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .icon-light {
 | 
			
		||||
    display: block;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .icon-dark {
 | 
			
		||||
    display: none;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  &.dark {
 | 
			
		||||
    .icon-light {
 | 
			
		||||
      display: none;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .icon-dark {
 | 
			
		||||
      display: block;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pure-menu-horizontal {
 | 
			
		||||
  background: #fff;
 | 
			
		||||
  background: var(--color-background);
 | 
			
		||||
  padding: 5px;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  justify-content: space-between;
 | 
			
		||||
  border-bottom: 2px solid #ed5900;
 | 
			
		||||
  border-bottom: 2px solid var(--color-menu-accent);
 | 
			
		||||
  align-items: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pure-menu-heading {
 | 
			
		||||
  color: var(--color-text-menu-heading);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pure-menu-link {
 | 
			
		||||
  color: var(--color-text-menu-link);
 | 
			
		||||
 | 
			
		||||
  &:hover {
 | 
			
		||||
    background-color: var(--color-background-menu-link-hover);
 | 
			
		||||
    color: var(--color-text-menu-link-hover);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
section.content {
 | 
			
		||||
  padding-top: 5em;
 | 
			
		||||
  padding-bottom: 1em;
 | 
			
		||||
@@ -47,7 +112,8 @@ section.content {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
code {
 | 
			
		||||
  background: #eee;
 | 
			
		||||
  background: var(--color-background-code);
 | 
			
		||||
  color: var(--color-text);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* table related */
 | 
			
		||||
@@ -60,7 +126,7 @@ code {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .error {
 | 
			
		||||
    color: #a00;
 | 
			
		||||
    color: var(--color-error);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  td {
 | 
			
		||||
@@ -74,11 +140,14 @@ code {
 | 
			
		||||
 | 
			
		||||
  th {
 | 
			
		||||
    white-space: nowrap;
 | 
			
		||||
 | 
			
		||||
    a {
 | 
			
		||||
      font-weight: normal;
 | 
			
		||||
 | 
			
		||||
      &.active {
 | 
			
		||||
        font-weight: bolder;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      &.inactive {
 | 
			
		||||
        .arrow {
 | 
			
		||||
          display: none;
 | 
			
		||||
@@ -87,14 +156,15 @@ code {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .title-col a[target="_blank"]::after, .current-diff-url::after {
 | 
			
		||||
  .title-col a[target="_blank"]::after,
 | 
			
		||||
  .current-diff-url::after {
 | 
			
		||||
    content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAQElEQVR42qXKwQkAIAxDUUdxtO6/RBQkQZvSi8I/pL4BoGw/XPkh4XigPmsUgh0626AjRsgxHTkUThsG2T/sIlzdTsp52kSS1wAAAABJRU5ErkJggg==);
 | 
			
		||||
    margin: 0 3px 0 5px;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.watch-tag-list {
 | 
			
		||||
  color: #e70069;
 | 
			
		||||
  color: var(--color-text-watch-tag-list);
 | 
			
		||||
  white-space: nowrap;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -126,10 +196,11 @@ code {
 | 
			
		||||
 | 
			
		||||
body:after {
 | 
			
		||||
  content: "";
 | 
			
		||||
  background: linear-gradient(130deg, #5ad8f7, #2f50af 41.07%, #9150bf 84.05%);
 | 
			
		||||
  background: linear-gradient(130deg, var(--color-background-gradient-first), var(--color-background-gradient-second) 41.07%, var(--color-background-gradient-third) 84.05%);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
body:after, body:before {
 | 
			
		||||
body:after,
 | 
			
		||||
body:before {
 | 
			
		||||
  display: block;
 | 
			
		||||
  height: 650px;
 | 
			
		||||
  position: absolute;
 | 
			
		||||
@@ -149,7 +220,8 @@ body::before {
 | 
			
		||||
  background-size: cover
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
body:after, body:before {
 | 
			
		||||
body:after,
 | 
			
		||||
body:before {
 | 
			
		||||
  -webkit-clip-path: polygon(100% 0, 0 0, 0 77.5%, 1% 77.4%, 2% 77.1%, 3% 76.6%, 4% 75.9%, 5% 75.05%, 6% 74.05%, 7% 72.95%, 8% 71.75%, 9% 70.55%, 10% 69.3%, 11% 68.05%, 12% 66.9%, 13% 65.8%, 14% 64.8%, 15% 64%, 16% 63.35%, 17% 62.85%, 18% 62.6%, 19% 62.5%, 20% 62.65%, 21% 63%, 22% 63.5%, 23% 64.2%, 24% 65.1%, 25% 66.1%, 26% 67.2%, 27% 68.4%, 28% 69.65%, 29% 70.9%, 30% 72.15%, 31% 73.3%, 32% 74.35%, 33% 75.3%, 34% 76.1%, 35% 76.75%, 36% 77.2%, 37% 77.45%, 38% 77.5%, 39% 77.3%, 40% 76.95%, 41% 76.4%, 42% 75.65%, 43% 74.75%, 44% 73.75%, 45% 72.6%, 46% 71.4%, 47% 70.15%, 48% 68.9%, 49% 67.7%, 50% 66.55%, 51% 65.5%, 52% 64.55%, 53% 63.75%, 54% 63.15%, 55% 62.75%, 56% 62.55%, 57% 62.5%, 58% 62.7%, 59% 63.1%, 60% 63.7%, 61% 64.45%, 62% 65.4%, 63% 66.45%, 64% 67.6%, 65% 68.8%, 66% 70.05%, 67% 71.3%, 68% 72.5%, 69% 73.6%, 70% 74.65%, 71% 75.55%, 72% 76.35%, 73% 76.9%, 74% 77.3%, 75% 77.5%, 76% 77.45%, 77% 77.25%, 78% 76.8%, 79% 76.2%, 80% 75.4%, 81% 74.45%, 82% 73.4%, 83% 72.25%, 84% 71.05%, 85% 69.8%, 86% 68.55%, 87% 67.35%, 88% 66.2%, 89% 65.2%, 90% 64.3%, 91% 63.55%, 92% 63%, 93% 62.65%, 94% 62.5%, 95% 62.55%, 96% 62.8%, 97% 63.3%, 98% 63.9%, 99% 64.75%, 100% 65.7%);
 | 
			
		||||
  clip-path: polygon(100% 0, 0 0, 0 77.5%, 1% 77.4%, 2% 77.1%, 3% 76.6%, 4% 75.9%, 5% 75.05%, 6% 74.05%, 7% 72.95%, 8% 71.75%, 9% 70.55%, 10% 69.3%, 11% 68.05%, 12% 66.9%, 13% 65.8%, 14% 64.8%, 15% 64%, 16% 63.35%, 17% 62.85%, 18% 62.6%, 19% 62.5%, 20% 62.65%, 21% 63%, 22% 63.5%, 23% 64.2%, 24% 65.1%, 25% 66.1%, 26% 67.2%, 27% 68.4%, 28% 69.65%, 29% 70.9%, 30% 72.15%, 31% 73.3%, 32% 74.35%, 33% 75.3%, 34% 76.1%, 35% 76.75%, 36% 77.2%, 37% 77.45%, 38% 77.5%, 39% 77.3%, 40% 76.95%, 41% 76.4%, 42% 75.65%, 43% 74.75%, 44% 73.75%, 45% 72.6%, 46% 71.4%, 47% 70.15%, 48% 68.9%, 49% 67.7%, 50% 66.55%, 51% 65.5%, 52% 64.55%, 53% 63.75%, 54% 63.15%, 55% 62.75%, 56% 62.55%, 57% 62.5%, 58% 62.7%, 59% 63.1%, 60% 63.7%, 61% 64.45%, 62% 65.4%, 63% 66.45%, 64% 67.6%, 65% 68.8%, 66% 70.05%, 67% 71.3%, 68% 72.5%, 69% 73.6%, 70% 74.65%, 71% 75.55%, 72% 76.35%, 73% 76.9%, 74% 77.3%, 75% 77.5%, 76% 77.45%, 77% 77.25%, 78% 76.8%, 79% 76.2%, 80% 75.4%, 81% 74.45%, 82% 73.4%, 83% 72.25%, 84% 71.05%, 85% 69.8%, 86% 68.55%, 87% 67.35%, 88% 66.2%, 89% 65.2%, 90% 64.3%, 91% 63.55%, 92% 63%, 93% 62.65%, 94% 62.5%, 95% 62.55%, 96% 62.8%, 97% 63.3%, 98% 63.9%, 99% 64.75%, 100% 65.7%)
 | 
			
		||||
}
 | 
			
		||||
@@ -165,51 +237,57 @@ body:after, body:before {
 | 
			
		||||
  display: block;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pure-button-primary,
 | 
			
		||||
a.pure-button-primary,
 | 
			
		||||
.pure-button-selected,
 | 
			
		||||
a.pure-button-selected {
 | 
			
		||||
  background-color: var(--color-background-button-primary);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.button-secondary {
 | 
			
		||||
  color: white;
 | 
			
		||||
  color: var(--color-text-button);
 | 
			
		||||
  border-radius: 4px;
 | 
			
		||||
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.button-success {
 | 
			
		||||
  background: rgb(28, 184, 65);
 | 
			
		||||
  /* this is a green */
 | 
			
		||||
  background: var(--color-background-button-success);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.button-tag {
 | 
			
		||||
  background: rgb(99, 99, 99);
 | 
			
		||||
  color: #fff;
 | 
			
		||||
  background: var(--color-background-button-tag);
 | 
			
		||||
  color: var(--color-text-button);
 | 
			
		||||
  font-size: 65%;
 | 
			
		||||
  border-bottom-left-radius: initial;
 | 
			
		||||
  border-bottom-right-radius: initial;
 | 
			
		||||
 | 
			
		||||
  &.active {
 | 
			
		||||
    background: #9c9c9c;
 | 
			
		||||
    background: var(--color-background-button-tag-active);
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.button-error {
 | 
			
		||||
  background: rgb(202, 60, 60);
 | 
			
		||||
  /* this is a maroon */
 | 
			
		||||
  background: var(--color-background-button-error);
 | 
			
		||||
  color: var(--color-text-button-error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.button-warning {
 | 
			
		||||
  background: rgb(223, 117, 20);
 | 
			
		||||
  /* this is an orange */
 | 
			
		||||
  background: var(--color-background-button-warning);
 | 
			
		||||
  color: var(--color-text-button-warning);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.button-secondary {
 | 
			
		||||
  background: rgb(66, 184, 221);
 | 
			
		||||
  /* this is a light blue */
 | 
			
		||||
  background: var(--color-background-button-secondary);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.button-cancel {
 | 
			
		||||
  background: rgb(200, 200, 200);
 | 
			
		||||
  /* this is a green */
 | 
			
		||||
  background: var(--color-background-button-cancel);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#save_button {
 | 
			
		||||
  margin-right: 1rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.messages {
 | 
			
		||||
@@ -217,50 +295,56 @@ body:after, body:before {
 | 
			
		||||
    list-style: none;
 | 
			
		||||
    padding: 1em;
 | 
			
		||||
    border-radius: 10px;
 | 
			
		||||
    color: #fff;
 | 
			
		||||
    color: var(--color-text-messages);
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
 | 
			
		||||
    &.message {
 | 
			
		||||
      background: rgba(255, 255, 255, .2);
 | 
			
		||||
      background: var(--color-background-messages-message);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    &.error {
 | 
			
		||||
      background: rgba(255, 1, 1, .5);
 | 
			
		||||
      background: var(--color-background-messages-error);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    &.notice {
 | 
			
		||||
      background: rgba(255, 255, 255, .5);
 | 
			
		||||
      background: var(--color-background-messages-notice);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  &.with-share-link {
 | 
			
		||||
    > *:hover {
 | 
			
		||||
    >*:hover {
 | 
			
		||||
      cursor: pointer;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.notifications-wrapper {
 | 
			
		||||
  padding: 0.5rem 0 1rem 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#notification-customisation {
 | 
			
		||||
  border: 1px solid #ccc;
 | 
			
		||||
  border: 1px solid var(--color-border-notification);
 | 
			
		||||
  padding: 0.5rem;
 | 
			
		||||
  border-radius: 5px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#notification-error-log {
 | 
			
		||||
  border: 1px solid #ccc;
 | 
			
		||||
  border: 1px solid var(--color-border-notification);
 | 
			
		||||
  padding: 1rem;
 | 
			
		||||
  border-radius: 5px;
 | 
			
		||||
  overflow-wrap: break-word;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#token-table {
 | 
			
		||||
  &.pure-table td, &.pure-table th {
 | 
			
		||||
 | 
			
		||||
  &.pure-table td,
 | 
			
		||||
  &.pure-table th {
 | 
			
		||||
    font-size: 80%;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#new-watch-form {
 | 
			
		||||
  background: rgba(0, 0, 0, .05);
 | 
			
		||||
  background: var(--color-background-new-watch-form);
 | 
			
		||||
  padding: 1em;
 | 
			
		||||
  border-radius: 10px;
 | 
			
		||||
  margin-bottom: 1em;
 | 
			
		||||
@@ -270,19 +354,25 @@ body:after, body:before {
 | 
			
		||||
    margin-bottom: 5px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  input:not(.pure-button) {
 | 
			
		||||
    background-color: var(--color-background-new-watch-input);
 | 
			
		||||
    color: var(--color-text-new-watch-input);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .label {
 | 
			
		||||
    display: none;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  legend {
 | 
			
		||||
    color: #fff;
 | 
			
		||||
    color: var(--color-text-legend);
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  #watch-add-wrapper-zone {
 | 
			
		||||
    > div {
 | 
			
		||||
    >div {
 | 
			
		||||
      display: inline-block;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @media only screen and (max-width: 760px) {
 | 
			
		||||
      #url {
 | 
			
		||||
        width: 100%;
 | 
			
		||||
@@ -300,15 +390,15 @@ body:after, body:before {
 | 
			
		||||
  position: fixed;
 | 
			
		||||
  left: 0px;
 | 
			
		||||
  top: 120px;
 | 
			
		||||
  background: #fff;
 | 
			
		||||
  background: var(--color-background);
 | 
			
		||||
  padding: 10px;
 | 
			
		||||
  border-top-right-radius: 5px;
 | 
			
		||||
  border-bottom-right-radius: 5px;
 | 
			
		||||
  box-shadow: 5px 0 5px -2px #888;
 | 
			
		||||
  box-shadow: 1px 1px 4px var(--color-shadow-jump);
 | 
			
		||||
 | 
			
		||||
  a {
 | 
			
		||||
    color: #1b98f8;
 | 
			
		||||
    cursor: grabbing;
 | 
			
		||||
    color: var(--color-link);
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
    -moz-user-select: none;
 | 
			
		||||
    -webkit-user-select: none;
 | 
			
		||||
    -ms-user-select: none;
 | 
			
		||||
@@ -319,8 +409,8 @@ body:after, body:before {
 | 
			
		||||
 | 
			
		||||
footer {
 | 
			
		||||
  padding: 10px;
 | 
			
		||||
  background: #fff;
 | 
			
		||||
  color: #444;
 | 
			
		||||
  background: var(--color-background);
 | 
			
		||||
  color: var(--color-text-footer);
 | 
			
		||||
  text-align: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -343,7 +433,7 @@ footer {
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  top: 60px;
 | 
			
		||||
  font-size: 65%;
 | 
			
		||||
  background: #fff;
 | 
			
		||||
  background: var(--color-background);
 | 
			
		||||
  padding: 10px;
 | 
			
		||||
 | 
			
		||||
  &#left-sticky {
 | 
			
		||||
@@ -362,10 +452,12 @@ footer {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#new-version-text a {
 | 
			
		||||
  color: #e07171;
 | 
			
		||||
  color: var(--color-link-new-version);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.watch-controls {
 | 
			
		||||
  color: #f8321b;
 | 
			
		||||
 | 
			
		||||
  .state-on {
 | 
			
		||||
    img {
 | 
			
		||||
      opacity: 0.8;
 | 
			
		||||
@@ -383,7 +475,6 @@ footer {
 | 
			
		||||
      opacity: 0.8;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.monospaced-textarea {
 | 
			
		||||
@@ -392,7 +483,8 @@ footer {
 | 
			
		||||
    font-family: monospace;
 | 
			
		||||
    white-space: pre;
 | 
			
		||||
    overflow-wrap: normal;
 | 
			
		||||
    overflow-x: scroll;
 | 
			
		||||
    // No scrollbars until needed.
 | 
			
		||||
    overflow-x: auto;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -407,7 +499,9 @@ footer {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .pure-control-group, .pure-group, .pure-controls {
 | 
			
		||||
  .pure-control-group,
 | 
			
		||||
  .pure-group,
 | 
			
		||||
  .pure-controls {
 | 
			
		||||
    padding-bottom: 1em;
 | 
			
		||||
 | 
			
		||||
    div {
 | 
			
		||||
@@ -415,28 +509,32 @@ footer {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .checkbox {
 | 
			
		||||
      > * {
 | 
			
		||||
      >* {
 | 
			
		||||
        display: inline;
 | 
			
		||||
        vertical-align: middle;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      > label {
 | 
			
		||||
      >label {
 | 
			
		||||
        padding-left: 5px;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    legend {
 | 
			
		||||
      color: var(--color-text-legend);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* The input fields with errors */
 | 
			
		||||
  .error {
 | 
			
		||||
    input {
 | 
			
		||||
      background-color: #ffebeb;
 | 
			
		||||
      background-color: var(--color-error-input);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* The list of errors */
 | 
			
		||||
  ul.errors {
 | 
			
		||||
    padding: .5em .6em;
 | 
			
		||||
    border: 1px solid #dd0000;
 | 
			
		||||
    border: 1px solid var(--color-error-list);
 | 
			
		||||
    border-radius: 4px;
 | 
			
		||||
    vertical-align: middle;
 | 
			
		||||
    -webkit-box-sizing: border-box;
 | 
			
		||||
@@ -444,7 +542,7 @@ footer {
 | 
			
		||||
 | 
			
		||||
    li {
 | 
			
		||||
      margin-left: 1em;
 | 
			
		||||
      color: #dd0000;
 | 
			
		||||
      color: var(--color-error-list);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -462,7 +560,7 @@ footer {
 | 
			
		||||
      list-style: none;
 | 
			
		||||
 | 
			
		||||
      li {
 | 
			
		||||
        > * {
 | 
			
		||||
        >* {
 | 
			
		||||
          display: inline-block;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
@@ -471,21 +569,25 @@ footer {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@media only screen and (max-width: 760px), (min-device-width: 768px) and (max-device-width: 1024px) {
 | 
			
		||||
@media only screen and (max-width: 760px),
 | 
			
		||||
(min-device-width: 768px) and (max-device-width: 1024px) {
 | 
			
		||||
  .box {
 | 
			
		||||
    max-width: 95%
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .edit-form {
 | 
			
		||||
    padding: 0.5em;
 | 
			
		||||
    margin: 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  #nav-menu {
 | 
			
		||||
    overflow-x: scroll;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@media only screen and (max-width: 760px), (min-device-width: 768px) and (max-device-width: 800px) {
 | 
			
		||||
@media only screen and (max-width: 760px),
 | 
			
		||||
(min-device-width: 768px) and (max-device-width: 800px) {
 | 
			
		||||
 | 
			
		||||
  div.sticky-tab#hosted-sticky {
 | 
			
		||||
    top: 60px;
 | 
			
		||||
@@ -514,24 +616,29 @@ footer {
 | 
			
		||||
  and also iPads specifically.
 | 
			
		||||
  */
 | 
			
		||||
  .watch-table {
 | 
			
		||||
 | 
			
		||||
    /* Force table to not be like tables anymore */
 | 
			
		||||
    thead, tbody, th, td, tr {
 | 
			
		||||
    thead,
 | 
			
		||||
    tbody,
 | 
			
		||||
    th,
 | 
			
		||||
    td,
 | 
			
		||||
    tr {
 | 
			
		||||
      display: block;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .last-checked {
 | 
			
		||||
      > span {
 | 
			
		||||
      >span {
 | 
			
		||||
        vertical-align: middle;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .last-checked::before {
 | 
			
		||||
      color: #555;
 | 
			
		||||
      color: var(--color-last-checked);
 | 
			
		||||
      content: "Last Checked ";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .last-changed::before {
 | 
			
		||||
      color: #555;
 | 
			
		||||
      color: var(--color-last-checked);
 | 
			
		||||
      content: "Last Changed ";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -547,15 +654,17 @@ footer {
 | 
			
		||||
      left: -9999px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .pure-table td, .pure-table th {
 | 
			
		||||
    .pure-table td,
 | 
			
		||||
    .pure-table th {
 | 
			
		||||
      border: none;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    td {
 | 
			
		||||
      /* Behave  like a "row" */
 | 
			
		||||
      border: none;
 | 
			
		||||
      border-bottom: 1px solid #eee;
 | 
			
		||||
      border-bottom: 1px solid var(--color-border-watch-table-cell);
 | 
			
		||||
      vertical-align: middle;
 | 
			
		||||
 | 
			
		||||
      &:before {
 | 
			
		||||
        /* Top/left values mimic padding */
 | 
			
		||||
        top: 6px;
 | 
			
		||||
@@ -568,11 +677,11 @@ footer {
 | 
			
		||||
 | 
			
		||||
    &.pure-table-striped {
 | 
			
		||||
      tr {
 | 
			
		||||
        background-color: #fff;
 | 
			
		||||
        background-color: var(--color-table-background);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      tr:nth-child(2n-1) {
 | 
			
		||||
        background-color: #eee;
 | 
			
		||||
        background-color: var(--color-table-stripe);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      tr:nth-child(2n-1) td {
 | 
			
		||||
@@ -583,12 +692,66 @@ footer {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pure-table {
 | 
			
		||||
  border-color: var(--color-border-table-cell);
 | 
			
		||||
 | 
			
		||||
  thead {
 | 
			
		||||
    background-color: var(--color-background-table-thead);
 | 
			
		||||
    color: var(--color-text);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  td,
 | 
			
		||||
  th {
 | 
			
		||||
    border-left-color: var(--color-border-table-cell);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pure-table-striped {
 | 
			
		||||
  tr:nth-child(2n-1) {
 | 
			
		||||
    td {
 | 
			
		||||
      background-color: var(--color-table-stripe);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pure-form input[type=color],
 | 
			
		||||
.pure-form input[type=date],
 | 
			
		||||
.pure-form input[type=datetime-local],
 | 
			
		||||
.pure-form input[type=datetime],
 | 
			
		||||
.pure-form input[type=email],
 | 
			
		||||
.pure-form input[type=month],
 | 
			
		||||
.pure-form input[type=number],
 | 
			
		||||
.pure-form input[type=password],
 | 
			
		||||
.pure-form input[type=search],
 | 
			
		||||
.pure-form input[type=tel],
 | 
			
		||||
.pure-form input[type=text],
 | 
			
		||||
.pure-form input[type=time],
 | 
			
		||||
.pure-form input[type=url],
 | 
			
		||||
.pure-form input[type=week],
 | 
			
		||||
.pure-form select,
 | 
			
		||||
.pure-form textarea {
 | 
			
		||||
  border: var(--color-border-input);
 | 
			
		||||
  box-shadow: inset 0 1px 3px var(--color-shadow-input);
 | 
			
		||||
  background-color: var(--color-background-input);
 | 
			
		||||
  color: var(--color-text-input);
 | 
			
		||||
 | 
			
		||||
  &:active {
 | 
			
		||||
    background-color: var(--color-background-input);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
input::placeholder,
 | 
			
		||||
textarea::placeholder {
 | 
			
		||||
  color: var(--color-text-input-placeholder);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/** Desktop vs mobile input field strategy
 | 
			
		||||
- We dont use 'size' with <input> because `size` is too unreliable to override, and will often push-out
 | 
			
		||||
- Rely always on width in CSS
 | 
			
		||||
*/
 | 
			
		||||
@media only screen and (min-width: 761px) {
 | 
			
		||||
 | 
			
		||||
  /* m-d is medium-desktop */
 | 
			
		||||
  .m-d {
 | 
			
		||||
    min-width: 80%;
 | 
			
		||||
@@ -605,20 +768,23 @@ footer {
 | 
			
		||||
    li {
 | 
			
		||||
      margin-right: 3px;
 | 
			
		||||
      display: inline-block;
 | 
			
		||||
      color: #fff;
 | 
			
		||||
      color: var(--color-text-tab);
 | 
			
		||||
      border-top-left-radius: 5px;
 | 
			
		||||
      border-top-right-radius: 5px;
 | 
			
		||||
      background-color: rgba(255, 255, 255, 0.2);
 | 
			
		||||
      background-color: var(--color-background-tab);
 | 
			
		||||
 | 
			
		||||
      &:not(.active) {
 | 
			
		||||
        &:hover {
 | 
			
		||||
          background-color: rgba(255, 255, 255, 0.5);
 | 
			
		||||
          background-color: var(--color-background-tab-hover);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      &.active, :target {
 | 
			
		||||
        background-color: #fff;
 | 
			
		||||
 | 
			
		||||
      &.active,
 | 
			
		||||
      :target {
 | 
			
		||||
        background-color: var(--color-background);
 | 
			
		||||
 | 
			
		||||
        a {
 | 
			
		||||
          color: #222;
 | 
			
		||||
          color: var(--color-text-tab-active);
 | 
			
		||||
          font-weight: bold;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
@@ -626,22 +792,24 @@ footer {
 | 
			
		||||
      a {
 | 
			
		||||
        display: block;
 | 
			
		||||
        padding: 0.8em;
 | 
			
		||||
        color: #fff;
 | 
			
		||||
        color: var(--color-text-tab);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
$form-edge-padding: 20px;
 | 
			
		||||
 | 
			
		||||
.pure-form-stacked {
 | 
			
		||||
  > div:first-child {
 | 
			
		||||
  >div:first-child {
 | 
			
		||||
    display: block;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.login-form {
 | 
			
		||||
  .inner {
 | 
			
		||||
    background: #fff;;
 | 
			
		||||
    background: var(--color-background);
 | 
			
		||||
    ;
 | 
			
		||||
    padding: $form-edge-padding;
 | 
			
		||||
    border-radius: 5px;
 | 
			
		||||
  }
 | 
			
		||||
@@ -671,11 +839,13 @@ $form-edge-padding: 20px;
 | 
			
		||||
#selector-header {
 | 
			
		||||
  padding-bottom: 1em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
body.full-width {
 | 
			
		||||
  .edit-form {
 | 
			
		||||
    width: 95%;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.edit-form {
 | 
			
		||||
  min-width: 70%;
 | 
			
		||||
  /* so it cant overflow */
 | 
			
		||||
@@ -686,17 +856,18 @@ body.full-width {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .inner {
 | 
			
		||||
    background: #fff;;
 | 
			
		||||
    background: var(--color-background);
 | 
			
		||||
    padding: $form-edge-padding;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  #actions {
 | 
			
		||||
    display: block;
 | 
			
		||||
    background: #fff;
 | 
			
		||||
    background: var(--color-background);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .pure-form-message-inline {
 | 
			
		||||
    padding-left: 0;
 | 
			
		||||
    color: var(--color-text-input-description);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -720,14 +891,15 @@ ul {
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  overflow-y: scroll;
 | 
			
		||||
  position: relative;
 | 
			
		||||
 | 
			
		||||
  //width: 100%;
 | 
			
		||||
  > img {
 | 
			
		||||
  >img {
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    z-index: 4;
 | 
			
		||||
    max-width: 100%;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  > canvas {
 | 
			
		||||
  >canvas {
 | 
			
		||||
    position: relative;
 | 
			
		||||
    z-index: 5;
 | 
			
		||||
    max-width: 100%;
 | 
			
		||||
@@ -755,54 +927,61 @@ ul {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#api-key-copy {
 | 
			
		||||
  color: #0078e7;
 | 
			
		||||
  color: var(--color-api-key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.button-green {
 | 
			
		||||
  background-color: #42dd53;
 | 
			
		||||
  background-color: var(--color-background-button-green);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.button-red {
 | 
			
		||||
  background-color: #dd4242;
 | 
			
		||||
  background-color: var(--color-background-button-red);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.noselect {
 | 
			
		||||
  -webkit-touch-callout: none; /* iOS Safari */
 | 
			
		||||
  -webkit-user-select: none; /* Safari */
 | 
			
		||||
  -moz-user-select: none; /* Old versions of Firefox */
 | 
			
		||||
  -ms-user-select: none; /* Internet Explorer/Edge */
 | 
			
		||||
  -webkit-touch-callout: none;
 | 
			
		||||
  /* iOS Safari */
 | 
			
		||||
  -webkit-user-select: none;
 | 
			
		||||
  /* Safari */
 | 
			
		||||
  -moz-user-select: none;
 | 
			
		||||
  /* Old versions of Firefox */
 | 
			
		||||
  -ms-user-select: none;
 | 
			
		||||
  /* Internet Explorer/Edge */
 | 
			
		||||
  user-select: none;
 | 
			
		||||
  /* Non-prefixed version, currently
 | 
			
		||||
                                   supported by Chrome, Edge, Opera and Firefox */
 | 
			
		||||
    supported by Chrome, Edge, Opera and Firefox */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.snapshot-age {
 | 
			
		||||
  padding: 4px;
 | 
			
		||||
  background-color: #dfdfdf;
 | 
			
		||||
  margin: 0.5rem 0;
 | 
			
		||||
  background-color: var(--color-background-snapshot-age);
 | 
			
		||||
  border-radius: 3px;
 | 
			
		||||
  font-weight: bold;
 | 
			
		||||
  margin-bottom: 4px;
 | 
			
		||||
 | 
			
		||||
  &.error {
 | 
			
		||||
    background-color: #ff0000;
 | 
			
		||||
    color: #fff;
 | 
			
		||||
    background-color: var(--color-error-background-snapshot-age);
 | 
			
		||||
    color: var(--color-error-text-snapshot-age);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#checkbox-operations {
 | 
			
		||||
  background: rgba(0, 0, 0, 0.05);
 | 
			
		||||
  background: var(--color-background-checkbox-operations);
 | 
			
		||||
  padding: 1em;
 | 
			
		||||
  border-radius: 10px;
 | 
			
		||||
  margin-bottom: 1em;
 | 
			
		||||
  display: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.checkbox-uuid {
 | 
			
		||||
  > * {
 | 
			
		||||
  >* {
 | 
			
		||||
    vertical-align: middle;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.inline-warning {
 | 
			
		||||
  > span {
 | 
			
		||||
  >span {
 | 
			
		||||
    display: inline-block;
 | 
			
		||||
    vertical-align: middle;
 | 
			
		||||
  }
 | 
			
		||||
@@ -813,8 +992,8 @@ ul {
 | 
			
		||||
    vertical-align: middle;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  border: 1px solid #ff3300;
 | 
			
		||||
  border: 1px solid var(--color-border-warning);
 | 
			
		||||
  padding: 0.5rem;
 | 
			
		||||
  border-radius: 5px;
 | 
			
		||||
  color: #ff3300;
 | 
			
		||||
  color: var(--color-warning);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,9 +1,131 @@
 | 
			
		||||
/*
 | 
			
		||||
 * -- BASE STYLES --
 | 
			
		||||
 * Most of these are inherited from Base, but I want to change a few.
 | 
			
		||||
nvm use v14.18.1 && npm install && npm run build
 | 
			
		||||
 * or npm run watch
 | 
			
		||||
 */
 | 
			
		||||
/**
 | 
			
		||||
 * CSS custom properties (aka variables).
 | 
			
		||||
 */
 | 
			
		||||
:root {
 | 
			
		||||
  --color-white: #fff;
 | 
			
		||||
  --color-grey-50: #111;
 | 
			
		||||
  --color-grey-100: #262626;
 | 
			
		||||
  --color-grey-200: #333;
 | 
			
		||||
  --color-grey-300: #444;
 | 
			
		||||
  --color-grey-325: #555;
 | 
			
		||||
  --color-grey-350: #565d64;
 | 
			
		||||
  --color-grey-400: #666;
 | 
			
		||||
  --color-grey-500: #777;
 | 
			
		||||
  --color-grey-600: #999;
 | 
			
		||||
  --color-grey-700: #cbcbcb;
 | 
			
		||||
  --color-grey-750: #ddd;
 | 
			
		||||
  --color-grey-800: #e0e0e0;
 | 
			
		||||
  --color-grey-850: #eee;
 | 
			
		||||
  --color-grey-900: #f2f2f2;
 | 
			
		||||
  --color-black: #000;
 | 
			
		||||
  --color-background-page: var(--color-grey-100);
 | 
			
		||||
  --color-background-gradient-first: #5ad8f7;
 | 
			
		||||
  --color-background-gradient-second: #2f50af;
 | 
			
		||||
  --color-background-gradient-third: #9150bf;
 | 
			
		||||
  --color-background: var(--color-white);
 | 
			
		||||
  --color-text: var(--color-grey-200);
 | 
			
		||||
  --color-link: #1b98f8;
 | 
			
		||||
  --color-menu-accent: #ed5900;
 | 
			
		||||
  --color-background-code: var(--color-grey-850);
 | 
			
		||||
  --color-error: #a00;
 | 
			
		||||
  --color-error-input: #ffebeb;
 | 
			
		||||
  --color-error-list: #dd0000;
 | 
			
		||||
  --color-table-background: var(--color-background);
 | 
			
		||||
  --color-table-stripe: var(--color-grey-900);
 | 
			
		||||
  --color-text-tab: var(--color-white);
 | 
			
		||||
  --color-background-tab: rgba(255, 255, 255, 0.2);
 | 
			
		||||
  --color-background-tab-hover: rgba(255, 255, 255, 0.5);
 | 
			
		||||
  --color-text-tab-active: #222;
 | 
			
		||||
  --color-api-key: #0078e7;
 | 
			
		||||
  --color-background-button-primary: #0078e7;
 | 
			
		||||
  --color-background-button-green: #42dd53;
 | 
			
		||||
  --color-background-button-red: #dd4242;
 | 
			
		||||
  --color-background-button-success: rgb(28, 184, 65);
 | 
			
		||||
  --color-background-button-error: rgb(202, 60, 60);
 | 
			
		||||
  --color-text-button-error: var(--color-white);
 | 
			
		||||
  --color-background-button-warning: rgb(202, 60, 60);
 | 
			
		||||
  --color-text-button-warning: var(--color-white);
 | 
			
		||||
  --color-background-button-secondary: rgb(66, 184, 221);
 | 
			
		||||
  --color-background-button-cancel: rgb(200, 200, 200);
 | 
			
		||||
  --color-text-button: var(--color-white);
 | 
			
		||||
  --color-background-button-tag: rgb(99, 99, 99);
 | 
			
		||||
  --color-background-snapshot-age: #dfdfdf;
 | 
			
		||||
  --color-error-text-snapshot-age: var(--color-white);
 | 
			
		||||
  --color-error-background-snapshot-age: #ff0000;
 | 
			
		||||
  --color-background-button-tag-active: #9c9c9c;
 | 
			
		||||
  --color-text-messages: var(--color-white);
 | 
			
		||||
  --color-background-messages-message: rgba(255, 255, 255, .2);
 | 
			
		||||
  --color-background-messages-error: rgba(255, 1, 1, .5);
 | 
			
		||||
  --color-background-messages-notice: rgba(255, 255, 255, .5);
 | 
			
		||||
  --color-border-notification: #ccc;
 | 
			
		||||
  --color-background-checkbox-operations: rgba(0, 0, 0, 0.05);
 | 
			
		||||
  --color-warning: #ff3300;
 | 
			
		||||
  --color-border-warning: var(--color-warning);
 | 
			
		||||
  --color-text-legend: var(--color-white);
 | 
			
		||||
  --color-link-new-version: #e07171;
 | 
			
		||||
  --color-last-checked: #bbb;
 | 
			
		||||
  --color-text-footer: #444;
 | 
			
		||||
  --color-border-watch-table-cell: #eee;
 | 
			
		||||
  --color-text-watch-tag-list: #e70069;
 | 
			
		||||
  --color-background-new-watch-form: rgba(0, 0, 0, 0.05);
 | 
			
		||||
  --color-background-new-watch-input: var(--color-white);
 | 
			
		||||
  --color-text-new-watch-input: var(--color-text);
 | 
			
		||||
  --color-border-input: var(--color-grey-500);
 | 
			
		||||
  --color-shadow-input: var(--color-grey-400);
 | 
			
		||||
  --color-background-input: var(--color-white);
 | 
			
		||||
  --color-text-input: var(--color-text);
 | 
			
		||||
  --color-text-input-description: var(--color-grey-500);
 | 
			
		||||
  --color-text-input-placeholder: var(--color-grey-600);
 | 
			
		||||
  --color-background-table-thead: var(--color-grey-800);
 | 
			
		||||
  --color-border-table-cell: var(--color-grey-700);
 | 
			
		||||
  --color-text-menu-heading: var(--color-grey-350);
 | 
			
		||||
  --color-text-menu-link: var(--color-grey-500);
 | 
			
		||||
  --color-background-menu-link-hover: var(--color-grey-850);
 | 
			
		||||
  --color-text-menu-link-hover: var(--color-grey-300);
 | 
			
		||||
  --color-shadow-jump: var(--color-grey-500);
 | 
			
		||||
  --color-icon-github: var(--color-black);
 | 
			
		||||
  --color-icon-github-hover: var(--color-grey-300); }
 | 
			
		||||
 | 
			
		||||
html[data-darkmode="true"] {
 | 
			
		||||
  --color-link: #59bdfb;
 | 
			
		||||
  --color-text: var(--color-white);
 | 
			
		||||
  --color-background-gradient-first: #3f90a5;
 | 
			
		||||
  --color-background-gradient-second: #1e316c;
 | 
			
		||||
  --color-background-gradient-third: #4d2c64;
 | 
			
		||||
  --color-background-new-watch-input: var(--color-grey-100);
 | 
			
		||||
  --color-text-new-watch-input: var(--color-text);
 | 
			
		||||
  --color-background-table-thead: var(--color-grey-200);
 | 
			
		||||
  --color-table-background: var(--color-grey-300);
 | 
			
		||||
  --color-table-stripe: var(--color-grey-325);
 | 
			
		||||
  --color-background: var(--color-grey-300);
 | 
			
		||||
  --color-text-menu-heading: var(--color-grey-850);
 | 
			
		||||
  --color-text-menu-link: var(--color-grey-800);
 | 
			
		||||
  --color-border-table-cell: var(--color-grey-400);
 | 
			
		||||
  --color-text-tab-active: var(--color-text);
 | 
			
		||||
  --color-border-input: var(--color-grey-400);
 | 
			
		||||
  --color-shadow-input: var(--color-grey-50);
 | 
			
		||||
  --color-background-input: var(--color-grey-350);
 | 
			
		||||
  --color-text-input-description: var(--color-grey-600);
 | 
			
		||||
  --color-text-input-placeholder: var(--color-grey-600);
 | 
			
		||||
  --color-text-watch-tag-list: #fa3e92;
 | 
			
		||||
  --color-background-code: var(--color-grey-200);
 | 
			
		||||
  --color-background-tab: rgba(0, 0, 0, 0.2);
 | 
			
		||||
  --color-background-tab-hover: rgba(0, 0, 0, 0.5);
 | 
			
		||||
  --color-background-snapshot-age: var(--color-grey-200);
 | 
			
		||||
  --color-shadow-jump: var(--color-grey-200);
 | 
			
		||||
  --color-icon-github: var(--color-white);
 | 
			
		||||
  --color-icon-github-hover: var(--color-grey-700); }
 | 
			
		||||
  html[data-darkmode="true"] .watch-controls img {
 | 
			
		||||
    opacity: 0.4; }
 | 
			
		||||
  html[data-darkmode="true"] .icon-spread {
 | 
			
		||||
    filter: hue-rotate(-10deg) brightness(1.5); }
 | 
			
		||||
  html[data-darkmode="true"] .watch-table .title-col a[target="_blank"]::after,
 | 
			
		||||
  html[data-darkmode="true"] .watch-table .current-diff-url::after {
 | 
			
		||||
    filter: invert(0.5) hue-rotate(10deg) brightness(2); }
 | 
			
		||||
 | 
			
		||||
/* spinner */
 | 
			
		||||
.spinner,
 | 
			
		||||
.spinner:after {
 | 
			
		||||
@@ -105,8 +227,10 @@ nvm use v14.18.1 && npm install && npm run build
 | 
			
		||||
    width: 80px;
 | 
			
		||||
    height: 80px;
 | 
			
		||||
    font-size: 3px; }
 | 
			
		||||
  #browsersteps-selector-wrapper #browsersteps-click-start:hover {
 | 
			
		||||
    cursor: pointer; }
 | 
			
		||||
  #browsersteps-selector-wrapper #browsersteps-click-start {
 | 
			
		||||
    color: var(--color-grey-400); }
 | 
			
		||||
    #browsersteps-selector-wrapper #browsersteps-click-start:hover {
 | 
			
		||||
      cursor: pointer; }
 | 
			
		||||
 | 
			
		||||
.arrow {
 | 
			
		||||
  border: solid #1b98f8;
 | 
			
		||||
@@ -127,28 +251,70 @@ nvm use v14.18.1 && npm install && npm run build
 | 
			
		||||
    -webkit-transform: rotate(45deg); }
 | 
			
		||||
 | 
			
		||||
body {
 | 
			
		||||
  color: #333;
 | 
			
		||||
  background: #262626; }
 | 
			
		||||
  color: var(--color-text);
 | 
			
		||||
  background: var(--color-background-page); }
 | 
			
		||||
 | 
			
		||||
.visually-hidden {
 | 
			
		||||
  clip: rect(0 0 0 0);
 | 
			
		||||
  clip-path: inset(50%);
 | 
			
		||||
  height: 1px;
 | 
			
		||||
  overflow: hidden;
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  white-space: nowrap;
 | 
			
		||||
  width: 1px; }
 | 
			
		||||
 | 
			
		||||
.pure-table-even {
 | 
			
		||||
  background: #fff; }
 | 
			
		||||
  background: var(--color-background); }
 | 
			
		||||
 | 
			
		||||
/* Some styles from https://css-tricks.com/ */
 | 
			
		||||
a {
 | 
			
		||||
  text-decoration: none;
 | 
			
		||||
  color: #1b98f8; }
 | 
			
		||||
  color: var(--color-link); }
 | 
			
		||||
 | 
			
		||||
a.github-link {
 | 
			
		||||
  color: #fff; }
 | 
			
		||||
  color: var(--color-icon-github);
 | 
			
		||||
  margin: 0 1rem 0 0.5rem; }
 | 
			
		||||
  a.github-link svg {
 | 
			
		||||
    fill: currentColor; }
 | 
			
		||||
  a.github-link:hover {
 | 
			
		||||
    color: var(--color-icon-github-hover); }
 | 
			
		||||
 | 
			
		||||
button.toggle-theme {
 | 
			
		||||
  width: 4rem;
 | 
			
		||||
  background: transparent;
 | 
			
		||||
  border: none;
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
  color: var(--color-icon-github); }
 | 
			
		||||
  button.toggle-theme:hover {
 | 
			
		||||
    color: var(--color-icon-github-hover); }
 | 
			
		||||
  button.toggle-theme svg {
 | 
			
		||||
    fill: currentColor; }
 | 
			
		||||
  button.toggle-theme .icon-light {
 | 
			
		||||
    display: block; }
 | 
			
		||||
  button.toggle-theme .icon-dark {
 | 
			
		||||
    display: none; }
 | 
			
		||||
  button.toggle-theme.dark .icon-light {
 | 
			
		||||
    display: none; }
 | 
			
		||||
  button.toggle-theme.dark .icon-dark {
 | 
			
		||||
    display: block; }
 | 
			
		||||
 | 
			
		||||
.pure-menu-horizontal {
 | 
			
		||||
  background: #fff;
 | 
			
		||||
  background: var(--color-background);
 | 
			
		||||
  padding: 5px;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  justify-content: space-between;
 | 
			
		||||
  border-bottom: 2px solid #ed5900;
 | 
			
		||||
  border-bottom: 2px solid var(--color-menu-accent);
 | 
			
		||||
  align-items: center; }
 | 
			
		||||
 | 
			
		||||
.pure-menu-heading {
 | 
			
		||||
  color: var(--color-text-menu-heading); }
 | 
			
		||||
 | 
			
		||||
.pure-menu-link {
 | 
			
		||||
  color: var(--color-text-menu-link); }
 | 
			
		||||
  .pure-menu-link:hover {
 | 
			
		||||
    background-color: var(--color-background-menu-link-hover);
 | 
			
		||||
    color: var(--color-text-menu-link-hover); }
 | 
			
		||||
 | 
			
		||||
section.content {
 | 
			
		||||
  padding-top: 5em;
 | 
			
		||||
  padding-bottom: 1em;
 | 
			
		||||
@@ -158,7 +324,8 @@ section.content {
 | 
			
		||||
  justify-content: center; }
 | 
			
		||||
 | 
			
		||||
code {
 | 
			
		||||
  background: #eee; }
 | 
			
		||||
  background: var(--color-background-code);
 | 
			
		||||
  color: var(--color-text); }
 | 
			
		||||
 | 
			
		||||
/* table related */
 | 
			
		||||
.watch-table {
 | 
			
		||||
@@ -167,7 +334,7 @@ code {
 | 
			
		||||
  .watch-table tr.unviewed {
 | 
			
		||||
    font-weight: bold; }
 | 
			
		||||
  .watch-table .error {
 | 
			
		||||
    color: #a00; }
 | 
			
		||||
    color: var(--color-error); }
 | 
			
		||||
  .watch-table td {
 | 
			
		||||
    white-space: nowrap; }
 | 
			
		||||
  .watch-table td.title-col {
 | 
			
		||||
@@ -181,12 +348,13 @@ code {
 | 
			
		||||
        font-weight: bolder; }
 | 
			
		||||
      .watch-table th a.inactive .arrow {
 | 
			
		||||
        display: none; }
 | 
			
		||||
  .watch-table .title-col a[target="_blank"]::after, .watch-table .current-diff-url::after {
 | 
			
		||||
  .watch-table .title-col a[target="_blank"]::after,
 | 
			
		||||
  .watch-table .current-diff-url::after {
 | 
			
		||||
    content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAQElEQVR42qXKwQkAIAxDUUdxtO6/RBQkQZvSi8I/pL4BoGw/XPkh4XigPmsUgh0626AjRsgxHTkUThsG2T/sIlzdTsp52kSS1wAAAABJRU5ErkJggg==);
 | 
			
		||||
    margin: 0 3px 0 5px; }
 | 
			
		||||
 | 
			
		||||
.watch-tag-list {
 | 
			
		||||
  color: #e70069;
 | 
			
		||||
  color: var(--color-text-watch-tag-list);
 | 
			
		||||
  white-space: nowrap; }
 | 
			
		||||
 | 
			
		||||
.box {
 | 
			
		||||
@@ -209,9 +377,10 @@ code {
 | 
			
		||||
 | 
			
		||||
body:after {
 | 
			
		||||
  content: "";
 | 
			
		||||
  background: linear-gradient(130deg, #5ad8f7, #2f50af 41.07%, #9150bf 84.05%); }
 | 
			
		||||
  background: linear-gradient(130deg, var(--color-background-gradient-first), var(--color-background-gradient-second) 41.07%, var(--color-background-gradient-third) 84.05%); }
 | 
			
		||||
 | 
			
		||||
body:after, body:before {
 | 
			
		||||
body:after,
 | 
			
		||||
body:before {
 | 
			
		||||
  display: block;
 | 
			
		||||
  height: 650px;
 | 
			
		||||
  position: absolute;
 | 
			
		||||
@@ -227,7 +396,8 @@ body::before {
 | 
			
		||||
  content: "";
 | 
			
		||||
  background-size: cover; }
 | 
			
		||||
 | 
			
		||||
body:after, body:before {
 | 
			
		||||
body:after,
 | 
			
		||||
body:before {
 | 
			
		||||
  -webkit-clip-path: polygon(100% 0, 0 0, 0 77.5%, 1% 77.4%, 2% 77.1%, 3% 76.6%, 4% 75.9%, 5% 75.05%, 6% 74.05%, 7% 72.95%, 8% 71.75%, 9% 70.55%, 10% 69.3%, 11% 68.05%, 12% 66.9%, 13% 65.8%, 14% 64.8%, 15% 64%, 16% 63.35%, 17% 62.85%, 18% 62.6%, 19% 62.5%, 20% 62.65%, 21% 63%, 22% 63.5%, 23% 64.2%, 24% 65.1%, 25% 66.1%, 26% 67.2%, 27% 68.4%, 28% 69.65%, 29% 70.9%, 30% 72.15%, 31% 73.3%, 32% 74.35%, 33% 75.3%, 34% 76.1%, 35% 76.75%, 36% 77.2%, 37% 77.45%, 38% 77.5%, 39% 77.3%, 40% 76.95%, 41% 76.4%, 42% 75.65%, 43% 74.75%, 44% 73.75%, 45% 72.6%, 46% 71.4%, 47% 70.15%, 48% 68.9%, 49% 67.7%, 50% 66.55%, 51% 65.5%, 52% 64.55%, 53% 63.75%, 54% 63.15%, 55% 62.75%, 56% 62.55%, 57% 62.5%, 58% 62.7%, 59% 63.1%, 60% 63.7%, 61% 64.45%, 62% 65.4%, 63% 66.45%, 64% 67.6%, 65% 68.8%, 66% 70.05%, 67% 71.3%, 68% 72.5%, 69% 73.6%, 70% 74.65%, 71% 75.55%, 72% 76.35%, 73% 76.9%, 74% 77.3%, 75% 77.5%, 76% 77.45%, 77% 77.25%, 78% 76.8%, 79% 76.2%, 80% 75.4%, 81% 74.45%, 82% 73.4%, 83% 72.25%, 84% 71.05%, 85% 69.8%, 86% 68.55%, 87% 67.35%, 88% 66.2%, 89% 65.2%, 90% 64.3%, 91% 63.55%, 92% 63%, 93% 62.65%, 94% 62.5%, 95% 62.55%, 96% 62.8%, 97% 63.3%, 98% 63.9%, 99% 64.75%, 100% 65.7%);
 | 
			
		||||
  clip-path: polygon(100% 0, 0 0, 0 77.5%, 1% 77.4%, 2% 77.1%, 3% 76.6%, 4% 75.9%, 5% 75.05%, 6% 74.05%, 7% 72.95%, 8% 71.75%, 9% 70.55%, 10% 69.3%, 11% 68.05%, 12% 66.9%, 13% 65.8%, 14% 64.8%, 15% 64%, 16% 63.35%, 17% 62.85%, 18% 62.6%, 19% 62.5%, 20% 62.65%, 21% 63%, 22% 63.5%, 23% 64.2%, 24% 65.1%, 25% 66.1%, 26% 67.2%, 27% 68.4%, 28% 69.65%, 29% 70.9%, 30% 72.15%, 31% 73.3%, 32% 74.35%, 33% 75.3%, 34% 76.1%, 35% 76.75%, 36% 77.2%, 37% 77.45%, 38% 77.5%, 39% 77.3%, 40% 76.95%, 41% 76.4%, 42% 75.65%, 43% 74.75%, 44% 73.75%, 45% 72.6%, 46% 71.4%, 47% 70.15%, 48% 68.9%, 49% 67.7%, 50% 66.55%, 51% 65.5%, 52% 64.55%, 53% 63.75%, 54% 63.15%, 55% 62.75%, 56% 62.55%, 57% 62.5%, 58% 62.7%, 59% 63.1%, 60% 63.7%, 61% 64.45%, 62% 65.4%, 63% 66.45%, 64% 67.6%, 65% 68.8%, 66% 70.05%, 67% 71.3%, 68% 72.5%, 69% 73.6%, 70% 74.65%, 71% 75.55%, 72% 76.35%, 73% 76.9%, 74% 77.3%, 75% 77.5%, 76% 77.45%, 77% 77.25%, 78% 76.8%, 79% 76.2%, 80% 75.4%, 81% 74.45%, 82% 73.4%, 83% 72.25%, 84% 71.05%, 85% 69.8%, 86% 68.55%, 87% 67.35%, 88% 66.2%, 89% 65.2%, 90% 64.3%, 91% 63.55%, 92% 63%, 93% 62.65%, 94% 62.5%, 95% 62.55%, 96% 62.8%, 97% 63.3%, 98% 63.9%, 99% 64.75%, 100% 65.7%); }
 | 
			
		||||
 | 
			
		||||
@@ -240,83 +410,96 @@ body:after, body:before {
 | 
			
		||||
  max-width: 400px;
 | 
			
		||||
  display: block; }
 | 
			
		||||
 | 
			
		||||
.pure-button-primary,
 | 
			
		||||
a.pure-button-primary,
 | 
			
		||||
.pure-button-selected,
 | 
			
		||||
a.pure-button-selected {
 | 
			
		||||
  background-color: var(--color-background-button-primary); }
 | 
			
		||||
 | 
			
		||||
.button-secondary {
 | 
			
		||||
  color: white;
 | 
			
		||||
  color: var(--color-text-button);
 | 
			
		||||
  border-radius: 4px;
 | 
			
		||||
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); }
 | 
			
		||||
 | 
			
		||||
.button-success {
 | 
			
		||||
  background: #1cb841;
 | 
			
		||||
  /* this is a green */ }
 | 
			
		||||
  background: var(--color-background-button-success); }
 | 
			
		||||
 | 
			
		||||
.button-tag {
 | 
			
		||||
  background: #636363;
 | 
			
		||||
  color: #fff;
 | 
			
		||||
  background: var(--color-background-button-tag);
 | 
			
		||||
  color: var(--color-text-button);
 | 
			
		||||
  font-size: 65%;
 | 
			
		||||
  border-bottom-left-radius: initial;
 | 
			
		||||
  border-bottom-right-radius: initial; }
 | 
			
		||||
  .button-tag.active {
 | 
			
		||||
    background: #9c9c9c;
 | 
			
		||||
    background: var(--color-background-button-tag-active);
 | 
			
		||||
    font-weight: bold; }
 | 
			
		||||
 | 
			
		||||
.button-error {
 | 
			
		||||
  background: #ca3c3c;
 | 
			
		||||
  /* this is a maroon */ }
 | 
			
		||||
  background: var(--color-background-button-error);
 | 
			
		||||
  color: var(--color-text-button-error); }
 | 
			
		||||
 | 
			
		||||
.button-warning {
 | 
			
		||||
  background: #df7514;
 | 
			
		||||
  /* this is an orange */ }
 | 
			
		||||
  background: var(--color-background-button-warning);
 | 
			
		||||
  color: var(--color-text-button-warning); }
 | 
			
		||||
 | 
			
		||||
.button-secondary {
 | 
			
		||||
  background: #42b8dd;
 | 
			
		||||
  /* this is a light blue */ }
 | 
			
		||||
  background: var(--color-background-button-secondary); }
 | 
			
		||||
 | 
			
		||||
.button-cancel {
 | 
			
		||||
  background: #c8c8c8;
 | 
			
		||||
  /* this is a green */ }
 | 
			
		||||
  background: var(--color-background-button-cancel); }
 | 
			
		||||
 | 
			
		||||
#save_button {
 | 
			
		||||
  margin-right: 1rem; }
 | 
			
		||||
 | 
			
		||||
.messages li {
 | 
			
		||||
  list-style: none;
 | 
			
		||||
  padding: 1em;
 | 
			
		||||
  border-radius: 10px;
 | 
			
		||||
  color: #fff;
 | 
			
		||||
  color: var(--color-text-messages);
 | 
			
		||||
  font-weight: bold; }
 | 
			
		||||
  .messages li.message {
 | 
			
		||||
    background: rgba(255, 255, 255, 0.2); }
 | 
			
		||||
    background: var(--color-background-messages-message); }
 | 
			
		||||
  .messages li.error {
 | 
			
		||||
    background: rgba(255, 1, 1, 0.5); }
 | 
			
		||||
    background: var(--color-background-messages-error); }
 | 
			
		||||
  .messages li.notice {
 | 
			
		||||
    background: rgba(255, 255, 255, 0.5); }
 | 
			
		||||
    background: var(--color-background-messages-notice); }
 | 
			
		||||
 | 
			
		||||
.messages.with-share-link > *:hover {
 | 
			
		||||
  cursor: pointer; }
 | 
			
		||||
 | 
			
		||||
.notifications-wrapper {
 | 
			
		||||
  padding: 0.5rem 0 1rem 0; }
 | 
			
		||||
 | 
			
		||||
#notification-customisation {
 | 
			
		||||
  border: 1px solid #ccc;
 | 
			
		||||
  border: 1px solid var(--color-border-notification);
 | 
			
		||||
  padding: 0.5rem;
 | 
			
		||||
  border-radius: 5px; }
 | 
			
		||||
 | 
			
		||||
#notification-error-log {
 | 
			
		||||
  border: 1px solid #ccc;
 | 
			
		||||
  border: 1px solid var(--color-border-notification);
 | 
			
		||||
  padding: 1rem;
 | 
			
		||||
  border-radius: 5px;
 | 
			
		||||
  overflow-wrap: break-word; }
 | 
			
		||||
 | 
			
		||||
#token-table.pure-table td, #token-table.pure-table th {
 | 
			
		||||
#token-table.pure-table td,
 | 
			
		||||
#token-table.pure-table th {
 | 
			
		||||
  font-size: 80%; }
 | 
			
		||||
 | 
			
		||||
#new-watch-form {
 | 
			
		||||
  background: rgba(0, 0, 0, 0.05);
 | 
			
		||||
  background: var(--color-background-new-watch-form);
 | 
			
		||||
  padding: 1em;
 | 
			
		||||
  border-radius: 10px;
 | 
			
		||||
  margin-bottom: 1em; }
 | 
			
		||||
  #new-watch-form input {
 | 
			
		||||
    display: inline-block;
 | 
			
		||||
    margin-bottom: 5px; }
 | 
			
		||||
  #new-watch-form input:not(.pure-button) {
 | 
			
		||||
    background-color: var(--color-background-new-watch-input);
 | 
			
		||||
    color: var(--color-text-new-watch-input); }
 | 
			
		||||
  #new-watch-form .label {
 | 
			
		||||
    display: none; }
 | 
			
		||||
  #new-watch-form legend {
 | 
			
		||||
    color: #fff;
 | 
			
		||||
    color: var(--color-text-legend);
 | 
			
		||||
    font-weight: bold; }
 | 
			
		||||
  #new-watch-form #watch-add-wrapper-zone > div {
 | 
			
		||||
    display: inline-block; }
 | 
			
		||||
@@ -331,14 +514,14 @@ body:after, body:before {
 | 
			
		||||
  position: fixed;
 | 
			
		||||
  left: 0px;
 | 
			
		||||
  top: 120px;
 | 
			
		||||
  background: #fff;
 | 
			
		||||
  background: var(--color-background);
 | 
			
		||||
  padding: 10px;
 | 
			
		||||
  border-top-right-radius: 5px;
 | 
			
		||||
  border-bottom-right-radius: 5px;
 | 
			
		||||
  box-shadow: 5px 0 5px -2px #888; }
 | 
			
		||||
  box-shadow: 1px 1px 4px var(--color-shadow-jump); }
 | 
			
		||||
  #diff-jump a {
 | 
			
		||||
    color: #1b98f8;
 | 
			
		||||
    cursor: grabbing;
 | 
			
		||||
    color: var(--color-link);
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
    -moz-user-select: none;
 | 
			
		||||
    -webkit-user-select: none;
 | 
			
		||||
    -ms-user-select: none;
 | 
			
		||||
@@ -347,8 +530,8 @@ body:after, body:before {
 | 
			
		||||
 | 
			
		||||
footer {
 | 
			
		||||
  padding: 10px;
 | 
			
		||||
  background: #fff;
 | 
			
		||||
  color: #444;
 | 
			
		||||
  background: var(--color-background);
 | 
			
		||||
  color: var(--color-text-footer);
 | 
			
		||||
  text-align: center; }
 | 
			
		||||
 | 
			
		||||
#feed-icon {
 | 
			
		||||
@@ -367,7 +550,7 @@ footer {
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  top: 60px;
 | 
			
		||||
  font-size: 65%;
 | 
			
		||||
  background: #fff;
 | 
			
		||||
  background: var(--color-background);
 | 
			
		||||
  padding: 10px; }
 | 
			
		||||
  .sticky-tab#left-sticky {
 | 
			
		||||
    left: 0px; }
 | 
			
		||||
@@ -379,9 +562,10 @@ footer {
 | 
			
		||||
    font-weight: bold; }
 | 
			
		||||
 | 
			
		||||
#new-version-text a {
 | 
			
		||||
  color: #e07171; }
 | 
			
		||||
  color: var(--color-link-new-version); }
 | 
			
		||||
 | 
			
		||||
.watch-controls {
 | 
			
		||||
  color: #f8321b;
 | 
			
		||||
  /* default */ }
 | 
			
		||||
  .watch-controls .state-on img {
 | 
			
		||||
    opacity: 0.8; }
 | 
			
		||||
@@ -396,7 +580,7 @@ footer {
 | 
			
		||||
  font-family: monospace;
 | 
			
		||||
  white-space: pre;
 | 
			
		||||
  overflow-wrap: normal;
 | 
			
		||||
  overflow-x: scroll; }
 | 
			
		||||
  overflow-x: auto; }
 | 
			
		||||
 | 
			
		||||
.pure-form {
 | 
			
		||||
  /* The input fields with errors */
 | 
			
		||||
@@ -406,27 +590,39 @@ footer {
 | 
			
		||||
    .pure-form fieldset ul {
 | 
			
		||||
      padding-bottom: 0px;
 | 
			
		||||
      margin-bottom: 0px; }
 | 
			
		||||
  .pure-form .pure-control-group, .pure-form .pure-group, .pure-form .pure-controls {
 | 
			
		||||
  .pure-form .pure-control-group,
 | 
			
		||||
  .pure-form .pure-group,
 | 
			
		||||
  .pure-form .pure-controls {
 | 
			
		||||
    padding-bottom: 1em; }
 | 
			
		||||
    .pure-form .pure-control-group div, .pure-form .pure-group div, .pure-form .pure-controls div {
 | 
			
		||||
    .pure-form .pure-control-group div,
 | 
			
		||||
    .pure-form .pure-group div,
 | 
			
		||||
    .pure-form .pure-controls div {
 | 
			
		||||
      margin: 0px; }
 | 
			
		||||
    .pure-form .pure-control-group .checkbox > *, .pure-form .pure-group .checkbox > *, .pure-form .pure-controls .checkbox > * {
 | 
			
		||||
    .pure-form .pure-control-group .checkbox > *,
 | 
			
		||||
    .pure-form .pure-group .checkbox > *,
 | 
			
		||||
    .pure-form .pure-controls .checkbox > * {
 | 
			
		||||
      display: inline;
 | 
			
		||||
      vertical-align: middle; }
 | 
			
		||||
    .pure-form .pure-control-group .checkbox > label, .pure-form .pure-group .checkbox > label, .pure-form .pure-controls .checkbox > label {
 | 
			
		||||
    .pure-form .pure-control-group .checkbox > label,
 | 
			
		||||
    .pure-form .pure-group .checkbox > label,
 | 
			
		||||
    .pure-form .pure-controls .checkbox > label {
 | 
			
		||||
      padding-left: 5px; }
 | 
			
		||||
    .pure-form .pure-control-group legend,
 | 
			
		||||
    .pure-form .pure-group legend,
 | 
			
		||||
    .pure-form .pure-controls legend {
 | 
			
		||||
      color: var(--color-text-legend); }
 | 
			
		||||
  .pure-form .error input {
 | 
			
		||||
    background-color: #ffebeb; }
 | 
			
		||||
    background-color: var(--color-error-input); }
 | 
			
		||||
  .pure-form ul.errors {
 | 
			
		||||
    padding: .5em .6em;
 | 
			
		||||
    border: 1px solid #dd0000;
 | 
			
		||||
    border: 1px solid var(--color-error-list);
 | 
			
		||||
    border-radius: 4px;
 | 
			
		||||
    vertical-align: middle;
 | 
			
		||||
    -webkit-box-sizing: border-box;
 | 
			
		||||
    box-sizing: border-box; }
 | 
			
		||||
    .pure-form ul.errors li {
 | 
			
		||||
      margin-left: 1em;
 | 
			
		||||
      color: #dd0000; }
 | 
			
		||||
      color: var(--color-error-list); }
 | 
			
		||||
  .pure-form label {
 | 
			
		||||
    font-weight: bold; }
 | 
			
		||||
  .pure-form textarea {
 | 
			
		||||
@@ -468,15 +664,19 @@ footer {
 | 
			
		||||
    /* Force table to not be like tables anymore */
 | 
			
		||||
    /* Force table to not be like tables anymore */
 | 
			
		||||
    /* Hide table headers (but not display: none;, for accessibility) */ }
 | 
			
		||||
    .watch-table thead, .watch-table tbody, .watch-table th, .watch-table td, .watch-table tr {
 | 
			
		||||
    .watch-table thead,
 | 
			
		||||
    .watch-table tbody,
 | 
			
		||||
    .watch-table th,
 | 
			
		||||
    .watch-table td,
 | 
			
		||||
    .watch-table tr {
 | 
			
		||||
      display: block; }
 | 
			
		||||
    .watch-table .last-checked > span {
 | 
			
		||||
      vertical-align: middle; }
 | 
			
		||||
    .watch-table .last-checked::before {
 | 
			
		||||
      color: #555;
 | 
			
		||||
      color: var(--color-last-checked);
 | 
			
		||||
      content: "Last Checked "; }
 | 
			
		||||
    .watch-table .last-changed::before {
 | 
			
		||||
      color: #555;
 | 
			
		||||
      color: var(--color-last-checked);
 | 
			
		||||
      content: "Last Changed "; }
 | 
			
		||||
    .watch-table td.inline {
 | 
			
		||||
      display: inline-block; }
 | 
			
		||||
@@ -484,12 +684,13 @@ footer {
 | 
			
		||||
      position: absolute;
 | 
			
		||||
      top: -9999px;
 | 
			
		||||
      left: -9999px; }
 | 
			
		||||
    .watch-table .pure-table td, .watch-table .pure-table th {
 | 
			
		||||
    .watch-table .pure-table td,
 | 
			
		||||
    .watch-table .pure-table th {
 | 
			
		||||
      border: none; }
 | 
			
		||||
    .watch-table td {
 | 
			
		||||
      /* Behave  like a "row" */
 | 
			
		||||
      border: none;
 | 
			
		||||
      border-bottom: 1px solid #eee;
 | 
			
		||||
      border-bottom: 1px solid var(--color-border-watch-table-cell);
 | 
			
		||||
      vertical-align: middle; }
 | 
			
		||||
      .watch-table td:before {
 | 
			
		||||
        /* Top/left values mimic padding */
 | 
			
		||||
@@ -499,12 +700,66 @@ footer {
 | 
			
		||||
        padding-right: 10px;
 | 
			
		||||
        white-space: nowrap; }
 | 
			
		||||
    .watch-table.pure-table-striped tr {
 | 
			
		||||
      background-color: #fff; }
 | 
			
		||||
      background-color: var(--color-table-background); }
 | 
			
		||||
    .watch-table.pure-table-striped tr:nth-child(2n-1) {
 | 
			
		||||
      background-color: #eee; }
 | 
			
		||||
      background-color: var(--color-table-stripe); }
 | 
			
		||||
    .watch-table.pure-table-striped tr:nth-child(2n-1) td {
 | 
			
		||||
      background-color: inherit; } }
 | 
			
		||||
 | 
			
		||||
.pure-table {
 | 
			
		||||
  border-color: var(--color-border-table-cell); }
 | 
			
		||||
  .pure-table thead {
 | 
			
		||||
    background-color: var(--color-background-table-thead);
 | 
			
		||||
    color: var(--color-text); }
 | 
			
		||||
  .pure-table td,
 | 
			
		||||
  .pure-table th {
 | 
			
		||||
    border-left-color: var(--color-border-table-cell); }
 | 
			
		||||
 | 
			
		||||
.pure-table-striped tr:nth-child(2n-1) td {
 | 
			
		||||
  background-color: var(--color-table-stripe); }
 | 
			
		||||
 | 
			
		||||
.pure-form input[type=color],
 | 
			
		||||
.pure-form input[type=date],
 | 
			
		||||
.pure-form input[type=datetime-local],
 | 
			
		||||
.pure-form input[type=datetime],
 | 
			
		||||
.pure-form input[type=email],
 | 
			
		||||
.pure-form input[type=month],
 | 
			
		||||
.pure-form input[type=number],
 | 
			
		||||
.pure-form input[type=password],
 | 
			
		||||
.pure-form input[type=search],
 | 
			
		||||
.pure-form input[type=tel],
 | 
			
		||||
.pure-form input[type=text],
 | 
			
		||||
.pure-form input[type=time],
 | 
			
		||||
.pure-form input[type=url],
 | 
			
		||||
.pure-form input[type=week],
 | 
			
		||||
.pure-form select,
 | 
			
		||||
.pure-form textarea {
 | 
			
		||||
  border: var(--color-border-input);
 | 
			
		||||
  box-shadow: inset 0 1px 3px var(--color-shadow-input);
 | 
			
		||||
  background-color: var(--color-background-input);
 | 
			
		||||
  color: var(--color-text-input); }
 | 
			
		||||
  .pure-form input[type=color]:active,
 | 
			
		||||
  .pure-form input[type=date]:active,
 | 
			
		||||
  .pure-form input[type=datetime-local]:active,
 | 
			
		||||
  .pure-form input[type=datetime]:active,
 | 
			
		||||
  .pure-form input[type=email]:active,
 | 
			
		||||
  .pure-form input[type=month]:active,
 | 
			
		||||
  .pure-form input[type=number]:active,
 | 
			
		||||
  .pure-form input[type=password]:active,
 | 
			
		||||
  .pure-form input[type=search]:active,
 | 
			
		||||
  .pure-form input[type=tel]:active,
 | 
			
		||||
  .pure-form input[type=text]:active,
 | 
			
		||||
  .pure-form input[type=time]:active,
 | 
			
		||||
  .pure-form input[type=url]:active,
 | 
			
		||||
  .pure-form input[type=week]:active,
 | 
			
		||||
  .pure-form select:active,
 | 
			
		||||
  .pure-form textarea:active {
 | 
			
		||||
    background-color: var(--color-background-input); }
 | 
			
		||||
 | 
			
		||||
input::placeholder,
 | 
			
		||||
textarea::placeholder {
 | 
			
		||||
  color: var(--color-text-input-placeholder); }
 | 
			
		||||
 | 
			
		||||
/** Desktop vs mobile input field strategy
 | 
			
		||||
- We dont use 'size' with <input> because `size` is too unreliable to override, and will often push-out
 | 
			
		||||
- Rely always on width in CSS
 | 
			
		||||
@@ -521,27 +776,29 @@ footer {
 | 
			
		||||
  .tabs ul li {
 | 
			
		||||
    margin-right: 3px;
 | 
			
		||||
    display: inline-block;
 | 
			
		||||
    color: #fff;
 | 
			
		||||
    color: var(--color-text-tab);
 | 
			
		||||
    border-top-left-radius: 5px;
 | 
			
		||||
    border-top-right-radius: 5px;
 | 
			
		||||
    background-color: rgba(255, 255, 255, 0.2); }
 | 
			
		||||
    background-color: var(--color-background-tab); }
 | 
			
		||||
    .tabs ul li:not(.active):hover {
 | 
			
		||||
      background-color: rgba(255, 255, 255, 0.5); }
 | 
			
		||||
    .tabs ul li.active, .tabs ul li :target {
 | 
			
		||||
      background-color: #fff; }
 | 
			
		||||
      .tabs ul li.active a, .tabs ul li :target a {
 | 
			
		||||
        color: #222;
 | 
			
		||||
      background-color: var(--color-background-tab-hover); }
 | 
			
		||||
    .tabs ul li.active,
 | 
			
		||||
    .tabs ul li :target {
 | 
			
		||||
      background-color: var(--color-background); }
 | 
			
		||||
      .tabs ul li.active a,
 | 
			
		||||
      .tabs ul li :target a {
 | 
			
		||||
        color: var(--color-text-tab-active);
 | 
			
		||||
        font-weight: bold; }
 | 
			
		||||
    .tabs ul li a {
 | 
			
		||||
      display: block;
 | 
			
		||||
      padding: 0.8em;
 | 
			
		||||
      color: #fff; }
 | 
			
		||||
      color: var(--color-text-tab); }
 | 
			
		||||
 | 
			
		||||
.pure-form-stacked > div:first-child {
 | 
			
		||||
  display: block; }
 | 
			
		||||
 | 
			
		||||
.login-form .inner {
 | 
			
		||||
  background: #fff;
 | 
			
		||||
  background: var(--color-background);
 | 
			
		||||
  padding: 20px;
 | 
			
		||||
  border-radius: 5px; }
 | 
			
		||||
 | 
			
		||||
@@ -571,13 +828,14 @@ body.full-width .edit-form {
 | 
			
		||||
  .edit-form .box-wrap {
 | 
			
		||||
    position: relative; }
 | 
			
		||||
  .edit-form .inner {
 | 
			
		||||
    background: #fff;
 | 
			
		||||
    background: var(--color-background);
 | 
			
		||||
    padding: 20px; }
 | 
			
		||||
  .edit-form #actions {
 | 
			
		||||
    display: block;
 | 
			
		||||
    background: #fff; }
 | 
			
		||||
    background: var(--color-background); }
 | 
			
		||||
  .edit-form .pure-form-message-inline {
 | 
			
		||||
    padding-left: 0; }
 | 
			
		||||
    padding-left: 0;
 | 
			
		||||
    color: var(--color-text-input-description); }
 | 
			
		||||
 | 
			
		||||
ul {
 | 
			
		||||
  padding-left: 1em;
 | 
			
		||||
@@ -614,13 +872,13 @@ ul {
 | 
			
		||||
  cursor: pointer; }
 | 
			
		||||
 | 
			
		||||
#api-key-copy {
 | 
			
		||||
  color: #0078e7; }
 | 
			
		||||
  color: var(--color-api-key); }
 | 
			
		||||
 | 
			
		||||
.button-green {
 | 
			
		||||
  background-color: #42dd53; }
 | 
			
		||||
  background-color: var(--color-background-button-green); }
 | 
			
		||||
 | 
			
		||||
.button-red {
 | 
			
		||||
  background-color: #dd4242; }
 | 
			
		||||
  background-color: var(--color-background-button-red); }
 | 
			
		||||
 | 
			
		||||
.noselect {
 | 
			
		||||
  -webkit-touch-callout: none;
 | 
			
		||||
@@ -633,20 +891,21 @@ ul {
 | 
			
		||||
  /* Internet Explorer/Edge */
 | 
			
		||||
  user-select: none;
 | 
			
		||||
  /* Non-prefixed version, currently
 | 
			
		||||
                                   supported by Chrome, Edge, Opera and Firefox */ }
 | 
			
		||||
    supported by Chrome, Edge, Opera and Firefox */ }
 | 
			
		||||
 | 
			
		||||
.snapshot-age {
 | 
			
		||||
  padding: 4px;
 | 
			
		||||
  background-color: #dfdfdf;
 | 
			
		||||
  margin: 0.5rem 0;
 | 
			
		||||
  background-color: var(--color-background-snapshot-age);
 | 
			
		||||
  border-radius: 3px;
 | 
			
		||||
  font-weight: bold;
 | 
			
		||||
  margin-bottom: 4px; }
 | 
			
		||||
  .snapshot-age.error {
 | 
			
		||||
    background-color: #ff0000;
 | 
			
		||||
    color: #fff; }
 | 
			
		||||
    background-color: var(--color-error-background-snapshot-age);
 | 
			
		||||
    color: var(--color-error-text-snapshot-age); }
 | 
			
		||||
 | 
			
		||||
#checkbox-operations {
 | 
			
		||||
  background: rgba(0, 0, 0, 0.05);
 | 
			
		||||
  background: var(--color-background-checkbox-operations);
 | 
			
		||||
  padding: 1em;
 | 
			
		||||
  border-radius: 10px;
 | 
			
		||||
  margin-bottom: 1em;
 | 
			
		||||
@@ -656,10 +915,10 @@ ul {
 | 
			
		||||
  vertical-align: middle; }
 | 
			
		||||
 | 
			
		||||
.inline-warning {
 | 
			
		||||
  border: 1px solid #ff3300;
 | 
			
		||||
  border: 1px solid var(--color-border-warning);
 | 
			
		||||
  padding: 0.5rem;
 | 
			
		||||
  border-radius: 5px;
 | 
			
		||||
  color: #ff3300; }
 | 
			
		||||
  color: var(--color-warning); }
 | 
			
		||||
  .inline-warning > span {
 | 
			
		||||
    display: inline-block;
 | 
			
		||||
    vertical-align: middle; }
 | 
			
		||||
 
 | 
			
		||||
@@ -18,12 +18,13 @@
 | 
			
		||||
                                <li><code>tgram://</code> only supports very limited HTML and can fail when extra tags are sent, <a href="https://core.telegram.org/bots/api#html-style">read more here</a> (or use plaintext/markdown format)</li>
 | 
			
		||||
                              </ul>
 | 
			
		||||
                            </div>
 | 
			
		||||
                            <br/>
 | 
			
		||||
                            <a id="send-test-notification" class="pure-button button-secondary button-xsmall" style="font-size: 70%">Send test notification</a>
 | 
			
		||||
{% if emailprefix %}
 | 
			
		||||
                            <a id="add-email-helper" class="pure-button button-secondary button-xsmall" style="font-size: 70%">Add email</a>
 | 
			
		||||
{% endif %}
 | 
			
		||||
                            <a href="{{url_for('notification_logs')}}" class="pure-button button-secondary button-xsmall" style="font-size: 70%">Notification debug logs</a>
 | 
			
		||||
                            <div class="notifications-wrapper">
 | 
			
		||||
                              <a id="send-test-notification" class="pure-button button-secondary button-xsmall" style="font-size: 70%">Send test notification</a>
 | 
			
		||||
                            {% if emailprefix %}
 | 
			
		||||
                              <a id="add-email-helper" class="pure-button button-secondary button-xsmall" style="font-size: 70%">Add email</a>
 | 
			
		||||
                            {% endif %}
 | 
			
		||||
                              <a href="{{url_for('notification_logs')}}" class="pure-button button-secondary button-xsmall" style="font-size: 70%">Notification debug logs</a>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div id="notification-customisation" class="pure-control-group">
 | 
			
		||||
                            <div class="pure-control-group">
 | 
			
		||||
 
 | 
			
		||||
@@ -1,121 +1,152 @@
 | 
			
		||||
<!doctype html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
<head>
 | 
			
		||||
    <meta charset="utf-8">
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
			
		||||
    <meta name="description" content="Self hosted website change detection.">
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en" data-darkmode="{{ dark_mode|lower }}">
 | 
			
		||||
 | 
			
		||||
  <head>
 | 
			
		||||
    <meta charset="utf-8"/>
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
 | 
			
		||||
    <meta name="description" content="Self hosted website change detection."/>
 | 
			
		||||
    <title>Change Detection{{extra_title}}</title>
 | 
			
		||||
    <link rel="alternate" type="application/rss+xml" title="Changedetection.io » Feed{% if active_tag %}- {{active_tag}}{% endif %}" href="{{ url_for('rss', tag=active_tag , token=app_rss_token)}}" />
 | 
			
		||||
    <link rel="stylesheet" href="{{url_for('static_content', group='styles', filename='pure-min.css')}}">
 | 
			
		||||
    <link rel="stylesheet" href="{{url_for('static_content', group='styles', filename='styles.css')}}">
 | 
			
		||||
    <link rel="alternate" type="application/rss+xml" title="Changedetection.io » Feed{% if active_tag %}- {{active_tag}}{% endif %}" href="{{ url_for('rss', tag=active_tag , token=app_rss_token)}}"/>
 | 
			
		||||
    <link rel="stylesheet" href="{{url_for('static_content', group='styles', filename='pure-min.css')}}"/>
 | 
			
		||||
    <link rel="stylesheet" href="{{url_for('static_content', group='styles', filename='styles.css')}}"/>
 | 
			
		||||
    {% if extra_stylesheets %}
 | 
			
		||||
        {% for m in extra_stylesheets %}
 | 
			
		||||
        <link rel="stylesheet" href="{{ m }}?ver=1000">
 | 
			
		||||
        {% endfor %}
 | 
			
		||||
      {% for m in extra_stylesheets %}
 | 
			
		||||
        <link rel="stylesheet" href="{{ m }}?ver=1000"/>
 | 
			
		||||
      {% endfor %}
 | 
			
		||||
    {% endif %}
 | 
			
		||||
 | 
			
		||||
    <link rel="apple-touch-icon" sizes="180x180" href="{{url_for('static_content', group='favicons', filename='apple-touch-icon.png')}}">
 | 
			
		||||
    <link rel="icon" type="image/png" sizes="32x32" href="{{url_for('static_content', group='favicons', filename='favicon-32x32.png')}}">
 | 
			
		||||
    <link rel="icon" type="image/png" sizes="16x16" href="{{url_for('static_content', group='favicons', filename='favicon-16x16.png')}}">
 | 
			
		||||
    <link rel="manifest" href="{{url_for('static_content', group='favicons', filename='site.webmanifest')}}">
 | 
			
		||||
    <link rel="mask-icon" href="{{url_for('static_content', group='favicons', filename='safari-pinned-tab.svg')}}" color="#5bbad5">
 | 
			
		||||
    <link rel="shortcut icon" href="{{url_for('static_content', group='favicons', filename='favicon.ico')}}">
 | 
			
		||||
    <meta name="msapplication-TileColor" content="#da532c">
 | 
			
		||||
    <meta name="msapplication-config" content="favicons/browserconfig.xml">
 | 
			
		||||
    <meta name="theme-color" content="#ffffff">
 | 
			
		||||
    <link rel="apple-touch-icon" sizes="180x180" href="{{url_for('static_content', group='favicons', filename='apple-touch-icon.png')}}"/>
 | 
			
		||||
    <link rel="icon" type="image/png" sizes="32x32" href="{{url_for('static_content', group='favicons', filename='favicon-32x32.png')}}"/>
 | 
			
		||||
    <link rel="icon" type="image/png" sizes="16x16" href="{{url_for('static_content', group='favicons', filename='favicon-16x16.png')}}"/>
 | 
			
		||||
    <link rel="manifest" href="{{url_for('static_content', group='favicons', filename='site.webmanifest')}}"/>
 | 
			
		||||
    <link rel="mask-icon" href="{{url_for('static_content', group='favicons', filename='safari-pinned-tab.svg')}}" color="#5bbad5"/>
 | 
			
		||||
    <link rel="shortcut icon" href="{{url_for('static_content', group='favicons', filename='favicon.ico')}}"/>
 | 
			
		||||
    <meta name="msapplication-TileColor" content="#da532c"/>
 | 
			
		||||
    <meta name="msapplication-config" content="favicons/browserconfig.xml"/>
 | 
			
		||||
    <meta name="theme-color" content="#ffffff"/>
 | 
			
		||||
 | 
			
		||||
    <style>
 | 
			
		||||
    body::before {
 | 
			
		||||
        background-image: url({{url_for('static_content', group='images', filename='gradient-border.png')}});
 | 
			
		||||
    }
 | 
			
		||||
      body::before {
 | 
			
		||||
        background-image: url({{url_for('static_content', group='images', filename='gradient-border.png') }});
 | 
			
		||||
      }
 | 
			
		||||
    </style>
 | 
			
		||||
    <script type="text/javascript" src="{{url_for('static_content', group='js', filename='jquery-3.6.0.min.js')}}"></script>
 | 
			
		||||
  </head>
 | 
			
		||||
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body>
 | 
			
		||||
 | 
			
		||||
<div class="header">
 | 
			
		||||
 | 
			
		||||
    <div class="home-menu pure-menu pure-menu-horizontal pure-menu-fixed" id="nav-menu">
 | 
			
		||||
  <body>
 | 
			
		||||
    <div class="header">
 | 
			
		||||
      <div class="home-menu pure-menu pure-menu-horizontal pure-menu-fixed" id="nav-menu">
 | 
			
		||||
        {% if has_password and not current_user.is_authenticated %}
 | 
			
		||||
            <a class="pure-menu-heading" href="https://github.com/dgtlmoon/changedetection.io" rel="noopener"><strong>Change</strong>Detection.io</a>
 | 
			
		||||
          <a class="pure-menu-heading" href="https://github.com/dgtlmoon/changedetection.io" rel="noopener">
 | 
			
		||||
            <strong>Change</strong>Detection.io</a>
 | 
			
		||||
        {% else %}
 | 
			
		||||
            <a class="pure-menu-heading" href="{{url_for('index')}}"><strong>Change</strong>Detection.io</a>
 | 
			
		||||
          <a class="pure-menu-heading" href="{{url_for('index')}}">
 | 
			
		||||
            <strong>Change</strong>Detection.io</a>
 | 
			
		||||
        {% endif %}
 | 
			
		||||
        {% if current_diff_url %}
 | 
			
		||||
        <a class=current-diff-url href="{{ current_diff_url }}"><span style="max-width: 30%; overflow: hidden;">{{ current_diff_url }}</span></a>
 | 
			
		||||
          <a class="current-diff-url" href="{{ current_diff_url }}">
 | 
			
		||||
            <span style="max-width: 30%; overflow: hidden">{{ current_diff_url }}</span></a>
 | 
			
		||||
        {% else %}
 | 
			
		||||
        {% if new_version_available and not (has_password and not current_user.is_authenticated) %}
 | 
			
		||||
        <span id="new-version-text" class="pure-menu-heading"><a href="https://github.com/dgtlmoon/changedetection.io">A new version is available</a></span>
 | 
			
		||||
        {% endif %}
 | 
			
		||||
          {% if new_version_available and not(has_password and not current_user.is_authenticated) %}
 | 
			
		||||
            <span id="new-version-text" class="pure-menu-heading">
 | 
			
		||||
              <a href="https://github.com/dgtlmoon/changedetection.io">A new version is available</a>
 | 
			
		||||
            </span>
 | 
			
		||||
          {% endif %}
 | 
			
		||||
        {% endif %}
 | 
			
		||||
 | 
			
		||||
        <ul class="pure-menu-list"  id="top-right-menu">
 | 
			
		||||
        {% if current_user.is_authenticated or not has_password %}
 | 
			
		||||
            {% if not current_diff_url %}
 | 
			
		||||
            <li class="pure-menu-item">
 | 
			
		||||
        <ul class="pure-menu-list" id="top-right-menu">
 | 
			
		||||
          {% if current_user.is_authenticated or not has_password %}
 | 
			
		||||
            {% if not
 | 
			
		||||
            current_diff_url %}
 | 
			
		||||
              <li class="pure-menu-item">
 | 
			
		||||
                <a href="{{ url_for('settings_page')}}" class="pure-menu-link">SETTINGS</a>
 | 
			
		||||
            </li>
 | 
			
		||||
            <li class="pure-menu-item">
 | 
			
		||||
              </li>
 | 
			
		||||
              <li class="pure-menu-item">
 | 
			
		||||
                <a href="{{ url_for('import_page')}}" class="pure-menu-link">IMPORT</a>
 | 
			
		||||
            </li>
 | 
			
		||||
            <li class="pure-menu-item">
 | 
			
		||||
              </li>
 | 
			
		||||
              <li class="pure-menu-item">
 | 
			
		||||
                <a href="{{ url_for('get_backup')}}" class="pure-menu-link">BACKUP</a>
 | 
			
		||||
            </li>
 | 
			
		||||
              </li>
 | 
			
		||||
            {% else %}
 | 
			
		||||
            <li class="pure-menu-item">
 | 
			
		||||
              <li class="pure-menu-item">
 | 
			
		||||
                <a href="{{ url_for('edit_page', uuid=uuid, next='diff') }}" class="pure-menu-link">EDIT</a>
 | 
			
		||||
            </li>
 | 
			
		||||
              </li>
 | 
			
		||||
            {% endif %}
 | 
			
		||||
        {% else %}
 | 
			
		||||
          {% else %}
 | 
			
		||||
            <li class="pure-menu-item">
 | 
			
		||||
                <a class="pure-menu-link" href="https://github.com/dgtlmoon/changedetection.io">Website Change Detection and Notification.</a>
 | 
			
		||||
              <a class="pure-menu-link" href="https://github.com/dgtlmoon/changedetection.io">Website Change Detection and Notification.</a>
 | 
			
		||||
            </li>
 | 
			
		||||
        {% endif %}
 | 
			
		||||
 | 
			
		||||
        {% if current_user.is_authenticated %}
 | 
			
		||||
            <li class="pure-menu-item"><a href="{{url_for('logout')}}" class="pure-menu-link">LOG OUT</a></li>
 | 
			
		||||
        {% endif %}
 | 
			
		||||
            <li class="pure-menu-item"><a class="github-link" href="https://github.com/dgtlmoon/changedetection.io">
 | 
			
		||||
                <svg class="octicon octicon-mark-github v-align-middle" height="32" viewBox="0 0 16 16"
 | 
			
		||||
                     version="1.1"
 | 
			
		||||
                     width="32" aria-hidden="true">
 | 
			
		||||
                    <path fill-rule="evenodd"
 | 
			
		||||
                          d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"></path>
 | 
			
		||||
                </svg>
 | 
			
		||||
            </a></li>
 | 
			
		||||
          {% endif %}
 | 
			
		||||
          {% if current_user.is_authenticated %}
 | 
			
		||||
            <li class="pure-menu-item">
 | 
			
		||||
              <a href="{{url_for('logout')}}" class="pure-menu-link">LOG OUT</a>
 | 
			
		||||
            </li>
 | 
			
		||||
          {% endif %}
 | 
			
		||||
          <li class="pure-menu-item">
 | 
			
		||||
            {% if dark_mode %}
 | 
			
		||||
            {% set darkClass = 'dark' %}
 | 
			
		||||
            {% endif %}
 | 
			
		||||
            <button class="toggle-theme {{darkClass}}" type="button">
 | 
			
		||||
              <span class="visually-hidden">Toggle light/dark mode</span>
 | 
			
		||||
              <span class="icon-light">
 | 
			
		||||
                {% include "svgs/light-mode-toggle-icon.svg" %}
 | 
			
		||||
              </span>
 | 
			
		||||
              <span class="icon-dark">
 | 
			
		||||
                {% include "svgs/dark-mode-toggle-icon.svg" %}
 | 
			
		||||
              </span>
 | 
			
		||||
            </button>
 | 
			
		||||
          </li>
 | 
			
		||||
          <li class="pure-menu-item">
 | 
			
		||||
            <a class="github-link" href="https://github.com/dgtlmoon/changedetection.io">
 | 
			
		||||
              {% include "svgs/github.svg" %}
 | 
			
		||||
            </a>
 | 
			
		||||
          </li>
 | 
			
		||||
        </ul>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
{% if hosted_sticky %}<div class="sticky-tab" id="hosted-sticky"><a href="https://lemonade.changedetection.io/start?ref={{guid}}">Let us host your instance!</a></div>{% endif %}
 | 
			
		||||
{% if left_sticky %}<div class="sticky-tab" id="left-sticky"><a href="{{url_for('preview_page', uuid=uuid)}}">Show current snapshot</a></div> {% endif %}
 | 
			
		||||
{% if right_sticky %}<div class="sticky-tab" id="right-sticky">{{ right_sticky }}</div> {% endif %}
 | 
			
		||||
<section class="content">
 | 
			
		||||
    <header>
 | 
			
		||||
    {% if hosted_sticky %}
 | 
			
		||||
      <div class="sticky-tab" id="hosted-sticky">
 | 
			
		||||
        <a href="https://lemonade.changedetection.io/start?ref={{guid}}">Let us host your instance!</a>
 | 
			
		||||
      </div>
 | 
			
		||||
    {% endif %}
 | 
			
		||||
    {% if left_sticky %}
 | 
			
		||||
      <div class="sticky-tab" id="left-sticky">
 | 
			
		||||
        <a href="{{url_for('preview_page', uuid=uuid)}}">Show current snapshot</a>
 | 
			
		||||
      </div>
 | 
			
		||||
    {% endif %}
 | 
			
		||||
    {% if right_sticky %}
 | 
			
		||||
      <div class="sticky-tab" id="right-sticky">{{ right_sticky }}</div>
 | 
			
		||||
    {% endif %}
 | 
			
		||||
    <section class="content">
 | 
			
		||||
      <header>
 | 
			
		||||
        {% block header %}{% endblock %}
 | 
			
		||||
    </header>
 | 
			
		||||
      </header>
 | 
			
		||||
 | 
			
		||||
    {% with messages = get_flashed_messages(with_categories=true) %}
 | 
			
		||||
      {% if messages %}
 | 
			
		||||
        <ul class=messages>
 | 
			
		||||
        {% for category, message in messages %}
 | 
			
		||||
          <li class="{{ category }}">{{ message }}</li>
 | 
			
		||||
        {% endfor %}
 | 
			
		||||
      {% with messages = get_flashed_messages(with_categories = true) %}
 | 
			
		||||
      {% if
 | 
			
		||||
      messages %}
 | 
			
		||||
        <ul class="messages">
 | 
			
		||||
          {% for category, message in messages %}
 | 
			
		||||
            <li class="{{ category }}">{{ message }}</li>
 | 
			
		||||
          {% endfor %}
 | 
			
		||||
        </ul>
 | 
			
		||||
      {% endif %}
 | 
			
		||||
    {% endwith %}
 | 
			
		||||
 | 
			
		||||
    {% if session['share-link'] %}
 | 
			
		||||
      {% endwith %}
 | 
			
		||||
      {% if session['share-link'] %}
 | 
			
		||||
        <ul class="messages with-share-link">
 | 
			
		||||
          <li class="message">Share this link: <span id="share-link">{{ session['share-link'] }}</span> <img style="height: 1em;display:inline-block;" src="{{url_for('static_content', group='images', filename='copy.svg')}}" /></li>
 | 
			
		||||
          <li class="message">
 | 
			
		||||
            Share this link:
 | 
			
		||||
            <span id="share-link">{{ session['share-link'] }}</span>
 | 
			
		||||
            <img style="height: 1em; display: inline-block" src="{{url_for('static_content', group='images', filename='copy.svg')}}"/>
 | 
			
		||||
          </li>
 | 
			
		||||
        </ul>
 | 
			
		||||
    {% endif %}
 | 
			
		||||
      {% endif %}
 | 
			
		||||
      {% block content %}{% endblock %}
 | 
			
		||||
    </section>
 | 
			
		||||
    <script
 | 
			
		||||
      type="text/javascript"
 | 
			
		||||
      src="{{url_for('static_content', group='js', filename='toggle-theme.js')}}"
 | 
			
		||||
      defer></script>
 | 
			
		||||
  </body>
 | 
			
		||||
 | 
			
		||||
    {% block content %}
 | 
			
		||||
 | 
			
		||||
    {% endblock %}
 | 
			
		||||
</section>
 | 
			
		||||
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,32 +1,49 @@
 | 
			
		||||
{% extends 'base.html' %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
{% extends 'base.html' %} {% block content %}
 | 
			
		||||
<div class="edit-form">
 | 
			
		||||
    <div class="box-wrap inner">
 | 
			
		||||
    <form class="pure-form pure-form-stacked" action="{{url_for('clear_all_history')}}" method="POST">
 | 
			
		||||
        <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
 | 
			
		||||
        <fieldset>
 | 
			
		||||
            <div class="pure-control-group">
 | 
			
		||||
                This will remove version history (snapshots) for ALL watches, but keep your list of URLs! <br/>
 | 
			
		||||
                You may like to use the <strong>BACKUP</strong> link first.<br/>
 | 
			
		||||
            </div>
 | 
			
		||||
            <br/>
 | 
			
		||||
            <div class="pure-control-group">
 | 
			
		||||
                <label for="confirmtext">Confirmation text</label>
 | 
			
		||||
                <input type="text" id="confirmtext" required="" name="confirmtext" value="" size="10"/>
 | 
			
		||||
                <span class="pure-form-message-inline">Type in the word <strong>clear</strong> to confirm that you understand.</span>
 | 
			
		||||
            </div>
 | 
			
		||||
            <br/>
 | 
			
		||||
            <div class="pure-control-group">
 | 
			
		||||
                <button type="submit" class="pure-button pure-button-primary">Clear History!</button>
 | 
			
		||||
            </div>
 | 
			
		||||
            <br/>
 | 
			
		||||
            <div class="pure-control-group">
 | 
			
		||||
                <a href="{{url_for('index')}}" class="pure-button button-small button-cancel">Cancel</a>
 | 
			
		||||
            </div>
 | 
			
		||||
        </fieldset>
 | 
			
		||||
  <div class="box-wrap inner">
 | 
			
		||||
    <form
 | 
			
		||||
      class="pure-form pure-form-stacked"
 | 
			
		||||
      action="{{url_for('clear_all_history')}}"
 | 
			
		||||
      method="POST"
 | 
			
		||||
    >
 | 
			
		||||
      <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
 | 
			
		||||
      <fieldset>
 | 
			
		||||
        <div class="pure-control-group">
 | 
			
		||||
          This will remove version history (snapshots) for ALL watches, but keep
 | 
			
		||||
          your list of URLs! <br />
 | 
			
		||||
          You may like to use the <strong>BACKUP</strong> link first.<br />
 | 
			
		||||
        </div>
 | 
			
		||||
        <br />
 | 
			
		||||
        <div class="pure-control-group">
 | 
			
		||||
          <label for="confirmtext">Confirmation text</label>
 | 
			
		||||
          <input
 | 
			
		||||
            type="text"
 | 
			
		||||
            id="confirmtext"
 | 
			
		||||
            required=""
 | 
			
		||||
            name="confirmtext"
 | 
			
		||||
            value=""
 | 
			
		||||
            size="10"
 | 
			
		||||
          />
 | 
			
		||||
          <span class="pure-form-message-inline"
 | 
			
		||||
            >Type in the word <strong>clear</strong> to confirm that you
 | 
			
		||||
            understand.</span
 | 
			
		||||
          >
 | 
			
		||||
        </div>
 | 
			
		||||
        <br />
 | 
			
		||||
        <div class="pure-control-group">
 | 
			
		||||
          <button type="submit" class="pure-button pure-button-primary">
 | 
			
		||||
            Clear History!
 | 
			
		||||
          </button>
 | 
			
		||||
        </div>
 | 
			
		||||
        <br />
 | 
			
		||||
        <div class="pure-control-group">
 | 
			
		||||
          <a href="{{url_for('index')}}" class="pure-button button-cancel"
 | 
			
		||||
            >Cancel</a
 | 
			
		||||
          >
 | 
			
		||||
        </div>
 | 
			
		||||
      </fieldset>
 | 
			
		||||
    </form>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,186 +1,290 @@
 | 
			
		||||
{% extends 'base.html' %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
{% from '_helpers.jinja' import render_field, render_checkbox_field, render_button %}
 | 
			
		||||
{% from '_common_fields.jinja' import render_common_settings_form %}
 | 
			
		||||
{% extends 'base.html' %} {% block content %} {% from '_helpers.jinja' import
 | 
			
		||||
render_field, render_checkbox_field, render_button %} {% from
 | 
			
		||||
'_common_fields.jinja' import render_common_settings_form %}
 | 
			
		||||
<script>
 | 
			
		||||
    const notification_base_url="{{url_for('ajax_callback_send_notification_test')}}";
 | 
			
		||||
{% if emailprefix %}
 | 
			
		||||
    const email_notification_prefix=JSON.parse('{{emailprefix|tojson}}');
 | 
			
		||||
{% endif %}
 | 
			
		||||
      const notification_base_url="{{url_for('ajax_callback_send_notification_test')}}";
 | 
			
		||||
  {% if emailprefix %}
 | 
			
		||||
      const email_notification_prefix=JSON.parse('{{emailprefix|tojson}}');
 | 
			
		||||
  {% endif %}
 | 
			
		||||
</script>
 | 
			
		||||
<script type="text/javascript" src="{{url_for('static_content', group='js', filename='tabs.js')}}" defer></script>
 | 
			
		||||
<script type="text/javascript" src="{{url_for('static_content', group='js', filename='notifications.js')}}" defer></script>
 | 
			
		||||
<script
 | 
			
		||||
  type="text/javascript"
 | 
			
		||||
  src="{{url_for('static_content', group='js', filename='tabs.js')}}"
 | 
			
		||||
  defer
 | 
			
		||||
></script>
 | 
			
		||||
<script
 | 
			
		||||
  type="text/javascript"
 | 
			
		||||
  src="{{url_for('static_content', group='js', filename='notifications.js')}}"
 | 
			
		||||
  defer
 | 
			
		||||
></script>
 | 
			
		||||
 | 
			
		||||
<script type="text/javascript" src="{{url_for('static_content', group='js', filename='global-settings.js')}}" defer></script>
 | 
			
		||||
<script
 | 
			
		||||
  type="text/javascript"
 | 
			
		||||
  src="{{url_for('static_content', group='js', filename='global-settings.js')}}"
 | 
			
		||||
  defer
 | 
			
		||||
></script>
 | 
			
		||||
<div class="edit-form">
 | 
			
		||||
    <div class="tabs collapsable">
 | 
			
		||||
        <ul>
 | 
			
		||||
            <li class="tab" id=""><a href="#general">General</a></li>
 | 
			
		||||
            <li class="tab"><a href="#notifications">Notifications</a></li>
 | 
			
		||||
            <li class="tab"><a href="#fetching">Fetching</a></li>
 | 
			
		||||
            <li class="tab"><a href="#filters">Global Filters</a></li>
 | 
			
		||||
            <li class="tab"><a href="#api">API</a></li>
 | 
			
		||||
        </ul>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="box-wrap inner">
 | 
			
		||||
        <form class="pure-form pure-form-stacked settings" action="{{url_for('settings_page')}}" method="POST">
 | 
			
		||||
            <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
 | 
			
		||||
            <div class="tab-pane-inner" id="general">
 | 
			
		||||
                <fieldset>
 | 
			
		||||
                    <div class="pure-control-group">
 | 
			
		||||
                        {{ render_field(form.requests.form.time_between_check, class="time-check-widget") }}
 | 
			
		||||
                        <span class="pure-form-message-inline">Default time for all watches, when the watch does not have a specific time setting.</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="pure-control-group">
 | 
			
		||||
                        {{ render_field(form.requests.form.jitter_seconds, class="jitter_seconds") }}
 | 
			
		||||
                        <span class="pure-form-message-inline">Example - 3 seconds random jitter could trigger up to 3 seconds earlier or up to 3 seconds later</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="pure-control-group">
 | 
			
		||||
                        {{ render_field(form.application.form.filter_failure_notification_threshold_attempts, class="filter_failure_notification_threshold_attempts") }}
 | 
			
		||||
                        <span class="pure-form-message-inline">After this many consecutive times that the CSS/xPath filter is missing, send a notification
 | 
			
		||||
                            <br/>
 | 
			
		||||
                        Set to <strong>0</strong> to disable
 | 
			
		||||
                        </span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="pure-control-group">
 | 
			
		||||
                        {% if not hide_remove_pass %}
 | 
			
		||||
                            {% if current_user.is_authenticated %}
 | 
			
		||||
                                {{ render_button(form.application.form.removepassword_button) }}
 | 
			
		||||
                            {% else %}
 | 
			
		||||
                            {{ render_field(form.application.form.password) }}
 | 
			
		||||
                            <span class="pure-form-message-inline">Password protection for your changedetection.io application.</span>
 | 
			
		||||
                            {% endif %}
 | 
			
		||||
                        {% else %}
 | 
			
		||||
                            <span class="pure-form-message-inline">Password is locked.</span>
 | 
			
		||||
                        {% endif %}
 | 
			
		||||
                    </div>
 | 
			
		||||
  <div class="tabs collapsable">
 | 
			
		||||
    <ul>
 | 
			
		||||
      <li class="tab" id=""><a href="#general">General</a></li>
 | 
			
		||||
      <li class="tab"><a href="#notifications">Notifications</a></li>
 | 
			
		||||
      <li class="tab"><a href="#fetching">Fetching</a></li>
 | 
			
		||||
      <li class="tab"><a href="#filters">Global Filters</a></li>
 | 
			
		||||
      <li class="tab"><a href="#api">API</a></li>
 | 
			
		||||
    </ul>
 | 
			
		||||
  </div>
 | 
			
		||||
  <div class="box-wrap inner">
 | 
			
		||||
    <form
 | 
			
		||||
      class="pure-form pure-form-stacked settings"
 | 
			
		||||
      action="{{url_for('settings_page')}}"
 | 
			
		||||
      method="POST"
 | 
			
		||||
    >
 | 
			
		||||
      <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
 | 
			
		||||
      <div class="tab-pane-inner" id="general">
 | 
			
		||||
        <fieldset>
 | 
			
		||||
          <div class="pure-control-group">
 | 
			
		||||
            {{ render_field(form.requests.form.time_between_check,
 | 
			
		||||
            class="time-check-widget") }}
 | 
			
		||||
            <span class="pure-form-message-inline"
 | 
			
		||||
              >Default time for all watches, when the watch does not have a
 | 
			
		||||
              specific time setting.</span
 | 
			
		||||
            >
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="pure-control-group">
 | 
			
		||||
            {{ render_field(form.requests.form.jitter_seconds,
 | 
			
		||||
            class="jitter_seconds") }}
 | 
			
		||||
            <span class="pure-form-message-inline"
 | 
			
		||||
              >Example - 3 seconds random jitter could trigger up to 3 seconds
 | 
			
		||||
              earlier or up to 3 seconds later</span
 | 
			
		||||
            >
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="pure-control-group">
 | 
			
		||||
            {{
 | 
			
		||||
            render_field(form.application.form.filter_failure_notification_threshold_attempts,
 | 
			
		||||
            class="filter_failure_notification_threshold_attempts") }}
 | 
			
		||||
            <span class="pure-form-message-inline"
 | 
			
		||||
              >After this many consecutive times that the CSS/xPath filter is
 | 
			
		||||
              missing, send a notification
 | 
			
		||||
              <br />
 | 
			
		||||
              Set to <strong>0</strong> to disable
 | 
			
		||||
            </span>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="pure-control-group">
 | 
			
		||||
            {% if not hide_remove_pass %} {% if current_user.is_authenticated %}
 | 
			
		||||
            {{ render_button(form.application.form.removepassword_button) }} {%
 | 
			
		||||
            else %} {{ render_field(form.application.form.password) }}
 | 
			
		||||
            <span class="pure-form-message-inline"
 | 
			
		||||
              >Password protection for your changedetection.io
 | 
			
		||||
              application.</span
 | 
			
		||||
            >
 | 
			
		||||
            {% endif %} {% else %}
 | 
			
		||||
            <span class="pure-form-message-inline">Password is locked.</span>
 | 
			
		||||
            {% endif %}
 | 
			
		||||
          </div>
 | 
			
		||||
 | 
			
		||||
                    <div class="pure-control-group">
 | 
			
		||||
                        {{ render_field(form.application.form.base_url, placeholder="http://yoursite.com:5000/",
 | 
			
		||||
                        class="m-d") }}
 | 
			
		||||
                        <span class="pure-form-message-inline">
 | 
			
		||||
                            Base URL used for the <code>{base_url}</code> token in notifications and RSS links.<br/>Default value is the ENV var 'BASE_URL' (Currently "{{settings_application['current_base_url']}}"),
 | 
			
		||||
                            <a href="https://github.com/dgtlmoon/changedetection.io/wiki/Configurable-BASE_URL-setting">read more here</a>.
 | 
			
		||||
                        </span>
 | 
			
		||||
                    </div>
 | 
			
		||||
          <div class="pure-control-group">
 | 
			
		||||
            {{ render_field(form.application.form.base_url,
 | 
			
		||||
            placeholder="http://yoursite.com:5000/", class="m-d") }}
 | 
			
		||||
            <span class="pure-form-message-inline">
 | 
			
		||||
              Base URL used for the <code>{base_url}</code> token in
 | 
			
		||||
              notifications and RSS links.<br />Default value is the ENV var
 | 
			
		||||
              'BASE_URL' (Currently
 | 
			
		||||
              "{{settings_application['current_base_url']}}"),
 | 
			
		||||
              <a
 | 
			
		||||
                href="https://github.com/dgtlmoon/changedetection.io/wiki/Configurable-BASE_URL-setting"
 | 
			
		||||
                >read more here</a
 | 
			
		||||
              >.
 | 
			
		||||
            </span>
 | 
			
		||||
          </div>
 | 
			
		||||
 | 
			
		||||
                    <div class="pure-control-group">
 | 
			
		||||
                        {{ render_checkbox_field(form.application.form.extract_title_as_title) }}
 | 
			
		||||
                        <span class="pure-form-message-inline">Note: This will automatically apply to all existing watches.</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="pure-control-group">
 | 
			
		||||
                        {{ render_checkbox_field(form.application.form.empty_pages_are_a_change) }}
 | 
			
		||||
                        <span class="pure-form-message-inline">When a page contains HTML, but no renderable text appears (empty page), is this considered a change?</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                {% if form.requests.proxy %}
 | 
			
		||||
                    <div class="pure-control-group inline-radio">
 | 
			
		||||
                        {{ render_field(form.requests.form.proxy, class="fetch-backend-proxy") }}
 | 
			
		||||
                        <span class="pure-form-message-inline">
 | 
			
		||||
                        Choose a default proxy for all watches
 | 
			
		||||
                        </span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                {% endif %}
 | 
			
		||||
                </fieldset>
 | 
			
		||||
            </div>
 | 
			
		||||
          <div class="pure-control-group">
 | 
			
		||||
            {{
 | 
			
		||||
            render_checkbox_field(form.application.form.extract_title_as_title)
 | 
			
		||||
            }}
 | 
			
		||||
            <span class="pure-form-message-inline"
 | 
			
		||||
              >Note: This will automatically apply to all existing
 | 
			
		||||
              watches.</span
 | 
			
		||||
            >
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="pure-control-group">
 | 
			
		||||
            {{
 | 
			
		||||
            render_checkbox_field(form.application.form.empty_pages_are_a_change)
 | 
			
		||||
            }}
 | 
			
		||||
            <span class="pure-form-message-inline"
 | 
			
		||||
              >When a page contains HTML, but no renderable text appears (empty
 | 
			
		||||
              page), is this considered a change?</span
 | 
			
		||||
            >
 | 
			
		||||
          </div>
 | 
			
		||||
          {% if form.requests.proxy %}
 | 
			
		||||
          <div class="pure-control-group inline-radio">
 | 
			
		||||
            {{ render_field(form.requests.form.proxy,
 | 
			
		||||
            class="fetch-backend-proxy") }}
 | 
			
		||||
            <span class="pure-form-message-inline">
 | 
			
		||||
              Choose a default proxy for all watches
 | 
			
		||||
            </span>
 | 
			
		||||
          </div>
 | 
			
		||||
          {% endif %}
 | 
			
		||||
        </fieldset>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
            <div class="tab-pane-inner" id="notifications">
 | 
			
		||||
                <fieldset>
 | 
			
		||||
                    <div class="field-group">
 | 
			
		||||
                        {{ render_common_settings_form(form.application.form, emailprefix, settings_application) }}
 | 
			
		||||
                    </div>
 | 
			
		||||
                </fieldset>
 | 
			
		||||
            </div>
 | 
			
		||||
      <div class="tab-pane-inner" id="notifications">
 | 
			
		||||
        <fieldset>
 | 
			
		||||
          <div class="field-group">
 | 
			
		||||
            {{ render_common_settings_form(form.application.form, emailprefix,
 | 
			
		||||
            settings_application) }}
 | 
			
		||||
          </div>
 | 
			
		||||
        </fieldset>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
            <div class="tab-pane-inner" id="fetching">
 | 
			
		||||
                <div class="pure-control-group inline-radio">
 | 
			
		||||
                    {{ render_field(form.application.form.fetch_backend, class="fetch-backend") }}
 | 
			
		||||
                    <span class="pure-form-message-inline">
 | 
			
		||||
                        <p>Use the <strong>Basic</strong> method (default) where your watched sites don't need Javascript to render.</p>
 | 
			
		||||
                        <p>The <strong>Chrome/Javascript</strong> method requires a network connection to a running WebDriver+Chrome server, set by the ENV var 'WEBDRIVER_URL'. </p>
 | 
			
		||||
                    </span>
 | 
			
		||||
                    <br/>
 | 
			
		||||
                    Tip: <a href="https://github.com/dgtlmoon/changedetection.io/wiki/Proxy-configuration#brightdata-proxy-support">Connect using BrightData Proxies, find out more here.</a>
 | 
			
		||||
                </div>
 | 
			
		||||
                <fieldset class="pure-group" id="webdriver-override-options">
 | 
			
		||||
                    <div class="pure-form-message-inline">
 | 
			
		||||
                        <strong>If you're having trouble waiting for the page to be fully rendered (text missing etc), try increasing the 'wait' time here.</strong>
 | 
			
		||||
                        <br/>
 | 
			
		||||
                        This will wait <i>n</i> seconds before extracting the text.
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="pure-control-group">
 | 
			
		||||
                        {{ render_field(form.application.form.webdriver_delay) }}
 | 
			
		||||
                    </div>
 | 
			
		||||
                </fieldset>
 | 
			
		||||
            </div>
 | 
			
		||||
      <div class="tab-pane-inner" id="fetching">
 | 
			
		||||
        <div class="pure-control-group inline-radio">
 | 
			
		||||
          {{ render_field(form.application.form.fetch_backend,
 | 
			
		||||
          class="fetch-backend") }}
 | 
			
		||||
          <span class="pure-form-message-inline">
 | 
			
		||||
            <p>
 | 
			
		||||
              Use the <strong>Basic</strong> method (default) where your watched
 | 
			
		||||
              sites don't need Javascript to render.
 | 
			
		||||
            </p>
 | 
			
		||||
            <p>
 | 
			
		||||
              The <strong>Chrome/Javascript</strong> method requires a network
 | 
			
		||||
              connection to a running WebDriver+Chrome server, set by the ENV
 | 
			
		||||
              var 'WEBDRIVER_URL'.
 | 
			
		||||
            </p>
 | 
			
		||||
          </span>
 | 
			
		||||
          <br />
 | 
			
		||||
          Tip:
 | 
			
		||||
          <a
 | 
			
		||||
            href="https://github.com/dgtlmoon/changedetection.io/wiki/Proxy-configuration#brightdata-proxy-support"
 | 
			
		||||
            >Connect using BrightData Proxies, find out more here.</a
 | 
			
		||||
          >
 | 
			
		||||
        </div>
 | 
			
		||||
        <fieldset class="pure-group" id="webdriver-override-options">
 | 
			
		||||
          <div class="pure-form-message-inline">
 | 
			
		||||
            <strong
 | 
			
		||||
              >If you're having trouble waiting for the page to be fully
 | 
			
		||||
              rendered (text missing etc), try increasing the 'wait' time
 | 
			
		||||
              here.</strong
 | 
			
		||||
            >
 | 
			
		||||
            <br />
 | 
			
		||||
            This will wait <i>n</i> seconds before extracting the text.
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="pure-control-group">
 | 
			
		||||
            {{ render_field(form.application.form.webdriver_delay) }}
 | 
			
		||||
          </div>
 | 
			
		||||
        </fieldset>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
            <div class="tab-pane-inner" id="filters">
 | 
			
		||||
 | 
			
		||||
                    <fieldset class="pure-group">
 | 
			
		||||
                    {{ render_checkbox_field(form.application.form.ignore_whitespace) }}
 | 
			
		||||
                    <span class="pure-form-message-inline">Ignore whitespace, tabs and new-lines/line-feeds when considering if a change was detected.<br/>
 | 
			
		||||
                    <i>Note:</i> Changing this will change the status of your existing watches, possibly trigger alerts etc.
 | 
			
		||||
                    </span>
 | 
			
		||||
                    </fieldset>
 | 
			
		||||
                <fieldset class="pure-group">
 | 
			
		||||
                    {{ render_checkbox_field(form.application.form.render_anchor_tag_content) }}
 | 
			
		||||
                    <span class="pure-form-message-inline">Render anchor tag content, default disabled, when enabled renders links as <code>(link text)[https://somesite.com]</code>
 | 
			
		||||
                        <br/>
 | 
			
		||||
                    <i>Note:</i> Changing this could affect the content of your existing watches, possibly trigger alerts etc.
 | 
			
		||||
                    </span>
 | 
			
		||||
                    </fieldset>
 | 
			
		||||
                    <fieldset class="pure-group">
 | 
			
		||||
                      {{ render_field(form.application.form.global_subtractive_selectors, rows=5, placeholder="header
 | 
			
		||||
      <div class="tab-pane-inner" id="filters">
 | 
			
		||||
        <fieldset class="pure-group">
 | 
			
		||||
          {{ render_checkbox_field(form.application.form.ignore_whitespace) }}
 | 
			
		||||
          <span class="pure-form-message-inline"
 | 
			
		||||
            >Ignore whitespace, tabs and new-lines/line-feeds when considering
 | 
			
		||||
            if a change was detected.<br />
 | 
			
		||||
            <i>Note:</i> Changing this will change the status of your existing
 | 
			
		||||
            watches, possibly trigger alerts etc.
 | 
			
		||||
          </span>
 | 
			
		||||
        </fieldset>
 | 
			
		||||
        <fieldset class="pure-group">
 | 
			
		||||
          {{
 | 
			
		||||
          render_checkbox_field(form.application.form.render_anchor_tag_content)
 | 
			
		||||
          }}
 | 
			
		||||
          <span class="pure-form-message-inline"
 | 
			
		||||
            >Render anchor tag content, default disabled, when enabled renders
 | 
			
		||||
            links as <code>(link text)[https://somesite.com]</code>
 | 
			
		||||
            <br />
 | 
			
		||||
            <i>Note:</i> Changing this could affect the content of your existing
 | 
			
		||||
            watches, possibly trigger alerts etc.
 | 
			
		||||
          </span>
 | 
			
		||||
        </fieldset>
 | 
			
		||||
        <fieldset class="pure-group">
 | 
			
		||||
          {{ render_field(form.application.form.global_subtractive_selectors,
 | 
			
		||||
          rows=5, placeholder="header
 | 
			
		||||
footer
 | 
			
		||||
nav
 | 
			
		||||
.stockticker") }}
 | 
			
		||||
                      <span class="pure-form-message-inline">
 | 
			
		||||
                        <ul>
 | 
			
		||||
                          <li> Remove HTML element(s) by CSS selector before text conversion. </li>
 | 
			
		||||
                          <li> Add multiple elements or CSS selectors per line to ignore multiple parts of the HTML. </li>
 | 
			
		||||
                        </ul>
 | 
			
		||||
                      </span>
 | 
			
		||||
                    </fieldset>
 | 
			
		||||
                    <fieldset class="pure-group">
 | 
			
		||||
                    {{ render_field(form.application.form.global_ignore_text, rows=5, placeholder="Some text to ignore in a line
 | 
			
		||||
/some.regex\d{2}/ for case-INsensitive regex
 | 
			
		||||
                    ") }}
 | 
			
		||||
                    <span class="pure-form-message-inline">Note: This is applied globally in addition to the per-watch rules.</span><br/>
 | 
			
		||||
                    <span class="pure-form-message-inline">
 | 
			
		||||
                        <ul>
 | 
			
		||||
                            <li>Note: This is applied globally in addition to the per-watch rules.</li>
 | 
			
		||||
                            <li>Each line processed separately, any line matching will be ignored (removed before creating the checksum)</li>
 | 
			
		||||
                            <li>Regular Expression support, wrap the entire line in forward slash <code>/regex/</code></li>
 | 
			
		||||
                            <li>Changing this will affect the comparison checksum which may trigger an alert</li>
 | 
			
		||||
                            <li>Use the preview/show current tab to see ignores</li>
 | 
			
		||||
                        </ul>
 | 
			
		||||
                     </span>
 | 
			
		||||
                    </fieldset>
 | 
			
		||||
           </div>
 | 
			
		||||
          <span class="pure-form-message-inline">
 | 
			
		||||
            <ul>
 | 
			
		||||
              <li>
 | 
			
		||||
                Remove HTML element(s) by CSS selector before text conversion.
 | 
			
		||||
              </li>
 | 
			
		||||
              <li>
 | 
			
		||||
                Add multiple elements or CSS selectors per line to ignore
 | 
			
		||||
                multiple parts of the HTML.
 | 
			
		||||
              </li>
 | 
			
		||||
            </ul>
 | 
			
		||||
          </span>
 | 
			
		||||
        </fieldset>
 | 
			
		||||
        <fieldset class="pure-group">
 | 
			
		||||
          {{ render_field(form.application.form.global_ignore_text, rows=5,
 | 
			
		||||
          placeholder="Some text to ignore in a line /some.regex\d{2}/ for
 | 
			
		||||
          case-INsensitive regex ") }}
 | 
			
		||||
          <span class="pure-form-message-inline"
 | 
			
		||||
            >Note: This is applied globally in addition to the per-watch
 | 
			
		||||
            rules.</span
 | 
			
		||||
          ><br />
 | 
			
		||||
          <span class="pure-form-message-inline">
 | 
			
		||||
            <ul>
 | 
			
		||||
              <li>
 | 
			
		||||
                Note: This is applied globally in addition to the per-watch
 | 
			
		||||
                rules.
 | 
			
		||||
              </li>
 | 
			
		||||
              <li>
 | 
			
		||||
                Each line processed separately, any line matching will be
 | 
			
		||||
                ignored (removed before creating the checksum)
 | 
			
		||||
              </li>
 | 
			
		||||
              <li>
 | 
			
		||||
                Regular Expression support, wrap the entire line in forward
 | 
			
		||||
                slash <code>/regex/</code>
 | 
			
		||||
              </li>
 | 
			
		||||
              <li>
 | 
			
		||||
                Changing this will affect the comparison checksum which may
 | 
			
		||||
                trigger an alert
 | 
			
		||||
              </li>
 | 
			
		||||
              <li>Use the preview/show current tab to see ignores</li>
 | 
			
		||||
            </ul>
 | 
			
		||||
          </span>
 | 
			
		||||
        </fieldset>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
            <div class="tab-pane-inner" id="api">
 | 
			
		||||
      <div class="tab-pane-inner" id="api">
 | 
			
		||||
        <p>
 | 
			
		||||
          Drive your changedetection.io via API, More about
 | 
			
		||||
          <a
 | 
			
		||||
            href="https://github.com/dgtlmoon/changedetection.io/wiki/API-Reference"
 | 
			
		||||
            >API access here</a
 | 
			
		||||
          >
 | 
			
		||||
        </p>
 | 
			
		||||
 | 
			
		||||
                <p>Drive your changedetection.io via API, More about <a href="https://github.com/dgtlmoon/changedetection.io/wiki/API-Reference">API access here</a></p>
 | 
			
		||||
        <div class="pure-control-group">
 | 
			
		||||
          {{
 | 
			
		||||
          render_checkbox_field(form.application.form.api_access_token_enabled)
 | 
			
		||||
          }}
 | 
			
		||||
          <div class="pure-form-message-inline">
 | 
			
		||||
            Restrict API access limit by using <code>x-api-key</code> header
 | 
			
		||||
          </div>
 | 
			
		||||
          <br />
 | 
			
		||||
          <div class="pure-form-message-inline">
 | 
			
		||||
            <br />API Key <span id="api-key">{{api_key}}</span>
 | 
			
		||||
            <span style="display: none" id="api-key-copy">copy</span>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
                <div class="pure-control-group">
 | 
			
		||||
                    {{ render_checkbox_field(form.application.form.api_access_token_enabled) }}
 | 
			
		||||
                    <div class="pure-form-message-inline">Restrict API access limit by using <code>x-api-key</code> header</div><br/>
 | 
			
		||||
                    <div class="pure-form-message-inline"><br/>API Key <span id="api-key">{{api_key}}</span>
 | 
			
		||||
                        <span style="display:none;" id="api-key-copy" >copy</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
            <div id="actions">
 | 
			
		||||
                <div class="pure-control-group">
 | 
			
		||||
                    {{ render_button(form.save_button) }}
 | 
			
		||||
                    <a href="{{url_for('index')}}" class="pure-button button-small button-cancel">Back</a>
 | 
			
		||||
                    <a href="{{url_for('clear_all_history')}}" class="pure-button button-small button-cancel">Clear Snapshot History</a>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
            </div>
 | 
			
		||||
        </form>
 | 
			
		||||
    </div>
 | 
			
		||||
      <div id="actions">
 | 
			
		||||
        <div class="pure-control-group">
 | 
			
		||||
          {{ render_button(form.save_button) }}
 | 
			
		||||
          <a href="{{url_for('index')}}" class="pure-button button-cancel"
 | 
			
		||||
            >Back</a
 | 
			
		||||
          >
 | 
			
		||||
          <a
 | 
			
		||||
            href="{{url_for('clear_all_history')}}"
 | 
			
		||||
            class="pure-button button-cancel"
 | 
			
		||||
            >Clear Snapshot History</a
 | 
			
		||||
          >
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </form>
 | 
			
		||||
  </div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1 @@
 | 
			
		||||
<svg xmlns="http://www.w3.org/2000/svg" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd" viewBox="0 0 512 262.86"><path fill-rule="nonzero" d="M316.78 16.55h-205.9c-30.5 0-58.22 12.48-78.31 32.57C12.47 69.21 0 96.93 0 127.44c0 30.5 12.47 58.22 32.57 78.31 20.09 20.1 47.81 32.57 78.31 32.57h193.25c21.54 15.43 47.9 24.54 76.26 24.54h.18c36.14 0 69.02-14.79 92.83-38.6 23.8-23.81 38.6-56.67 38.6-92.83 0-36.15-14.78-69.03-38.63-92.8C449.53 14.8 416.67 0 380.57 0h-.18c-23.02 0-44.72 6.02-63.61 16.55zm70.62 97.17.43.09c.82-3.45 2.83-6.19 6.04-8.16 3.2-1.98 6.53-2.57 10.01-1.75l.1-.43c-3.47-.82-6.2-2.83-8.17-6.03-1.98-3.22-2.57-6.55-1.75-10.01l-.43-.1c-.82 3.47-2.83 6.2-6.03 8.18-3.21 1.98-6.55 2.56-10.02 1.74l-.1.43c3.47.82 6.2 2.84 8.18 6.04 1.99 3.19 2.56 6.52 1.74 10zm36.87 16.77.53.12c1.02-4.35 3.55-7.78 7.58-10.26 4.02-2.49 8.2-3.22 12.56-2.19l.13-.53c-4.35-1.03-7.78-3.55-10.26-7.59-2.49-4.03-3.22-8.22-2.2-12.56l-.53-.12c-1.02 4.35-3.55 7.77-7.58 10.26-4.02 2.49-8.21 3.22-12.56 2.19l-.13.53c4.36 1.03 7.78 3.55 10.26 7.58 2.49 4.02 3.22 8.22 2.2 12.57zm-38.79-61.01c-15.69 7.67-26.98 23.26-28.29 41.93-1.96 27.88 19.05 52.06 46.92 54.02 13.23.93 25.64-3.32 35.22-11.02 4.75-3.82 9.66-.45 7.59 4.36-11.33 26.42-38.45 44.04-68.74 41.91-38.29-2.69-67.14-35.91-64.45-74.19C316.3 89.8 347.05 61.67 383.44 62c6.71.06 8.13 4.5 2.04 7.48zm-5.09-53.95h.18c63.75 0 115.91 52.15 115.91 115.9 0 63.75-52.23 115.91-115.91 115.91h-.18c-63.68 0-115.91-52.16-115.91-115.91s52.16-115.9 115.91-115.9z"/></svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 1.6 KiB  | 
							
								
								
									
										3
									
								
								changedetectionio/templates/svgs/github.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,3 @@
 | 
			
		||||
<svg class="octicon octicon-mark-github v-align-middle" height="32" viewbox="0 0 16 16" version="1.1" width="32" aria-hidden="true">
 | 
			
		||||
  <path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"></path>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 749 B  | 
@@ -0,0 +1 @@
 | 
			
		||||
<svg xmlns="http://www.w3.org/2000/svg" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd" viewBox="0 0 512 256.04"><path d="M128.02 0h.18c22.03 0 42.83 5.66 61 15.6h210.38c30.89 0 59 12.65 79.38 33.04C499.35 68.99 512 97.1 512 128.02c0 30.92-12.66 59.03-33.02 79.4l-.42.38c-20.34 20.15-48.29 32.64-78.98 32.64H189.24c-18.17 9.93-38.98 15.6-61.04 15.6h-.18c-35.2 0-67.22-14.41-90.42-37.6C14.41 195.25 0 163.24 0 128.02s14.4-67.24 37.59-90.43l.91-.83C61.65 14.05 93.29 0 128.02 0zm-5.95 54.42c0-1.95.8-3.73 2.08-5 2.74-2.77 7.27-2.76 10.02-.01l.14.16a7.042 7.042 0 0 1 1.94 4.85v12.95c0 1.95-.8 3.73-2.08 5.01-2.75 2.75-7.27 2.75-10.02 0a7.084 7.084 0 0 1-2.08-5.01V54.42zm6.05 31.17c11.72 0 22.32 4.75 30 12.43 7.67 7.68 12.43 18.29 12.43 30 0 11.72-4.75 22.32-12.43 30s-18.28 12.43-30 12.43c-11.72 0-22.32-4.75-30.01-12.43-7.67-7.68-12.43-18.28-12.43-30 0-11.72 4.76-22.32 12.43-30 7.69-7.67 18.3-12.43 30.01-12.43zm-56.33-5.34a7.114 7.114 0 0 1-2.07-5.01c0-3.9 3.18-7.09 7.09-7.09 1.81 0 3.62.69 5 2.07l9.16 9.16a7.065 7.065 0 0 1 2.08 5.01c0 1.8-.7 3.62-2.08 5.01a7.057 7.057 0 0 1-5.01 2.08c-1.8 0-3.61-.7-5-2.07l-9.17-9.16zm-17.28 53.81c-1.95 0-3.73-.8-5-2.08-2.77-2.74-2.76-7.27-.01-10.01l.15-.14a7.04 7.04 0 0 1 4.86-1.94h12.94a7.082 7.082 0 0 1 7.09 7.09c0 1.95-.8 3.73-2.07 5.01a7.099 7.099 0 0 1-5.02 2.07H54.51zm25.82 50.28a7.049 7.049 0 0 1-5 2.07c-3.91 0-7.09-3.16-7.09-7.08 0-1.81.68-3.62 2.07-5.01l9.31-9.29a7.02 7.02 0 0 1 4.86-1.94 7.09 7.09 0 0 1 7.09 7.09c0 1.79-.69 3.6-2.08 4.99l-9.16 9.17zm53.82 17.29c0 1.94-.8 3.73-2.08 5-2.74 2.76-7.27 2.75-10.02 0l-.13-.15a7.033 7.033 0 0 1-1.94-4.85v-12.95c0-1.96.8-3.73 2.07-5.01 2.76-2.75 7.27-2.75 10.03 0a7.1 7.1 0 0 1 2.07 5.01v12.95zm50.28-25.83a7.055 7.055 0 0 1 2.07 5.01c0 3.89-3.18 7.09-7.08 7.09-1.81 0-3.63-.69-5.01-2.07l-9.16-9.16a7.095 7.095 0 0 1-2.07-5.02c0-3.9 3.18-7.09 7.08-7.09 1.8 0 3.61.7 5 2.08l9.17 9.16zm17.29-53.82c1.93 0 3.73.81 5 2.08 2.76 2.75 2.75 7.27 0 10.02l-.15.14a7.098 7.098 0 0 1-4.85 1.94h-12.95c-1.96 0-3.74-.8-5.01-2.08-2.76-2.75-2.76-7.27 0-10.02a7.049 7.049 0 0 1 5.01-2.08h12.95zM175.89 71.7a7.074 7.074 0 0 1 5-2.07c3.9 0 7.1 3.19 7.1 7.09 0 1.81-.69 3.62-2.07 5l-9.32 9.31a7.12 7.12 0 0 1-4.86 1.93c-3.91 0-7.09-3.18-7.09-7.09 0-1.8.7-3.61 2.08-5l9.16-9.17zm34.17-41.87c2.96 2.47 5.81 5.07 8.53 7.8 23.22 23.15 37.63 55.17 37.63 90.39s-14.42 67.23-37.6 90.42a130.2 130.2 0 0 1-8.5 7.77h189.46c26.83 0 51.24-10.91 69.02-28.5l.32-.35c17.79-17.79 28.85-42.35 28.85-69.34 0-26.99-11.06-51.55-28.85-69.35-17.77-17.8-42.33-28.84-69.34-28.84H210.06zm-82.04-14.71h.18c62.09 0 112.89 50.81 112.89 112.9 0 62.1-50.86 112.9-112.89 112.9h-.18c-62.03 0-112.9-50.8-112.9-112.9 0-62.09 50.81-112.9 112.9-112.9z"/></svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 2.7 KiB  | 
@@ -80,15 +80,15 @@
 | 
			
		||||
                <td class="inline checkbox-uuid" ><input name="uuids"  type="checkbox" value="{{ watch.uuid}} "/> <span>{{ loop.index }}</span></td>
 | 
			
		||||
                <td class="inline watch-controls">
 | 
			
		||||
                    {% if not watch.paused %}
 | 
			
		||||
                    <a class="state-off" href="{{url_for('index', op='pause', uuid=watch.uuid, tag=active_tag)}}"><img src="{{url_for('static_content', group='images', filename='pause.svg')}}" alt="Pause checks" title="Pause checks"/></a>
 | 
			
		||||
                    <a class="state-off" href="{{url_for('index', op='pause', uuid=watch.uuid, tag=active_tag)}}"><img src="{{url_for('static_content', group='images', filename='pause.svg')}}" alt="Pause checks" title="Pause checks" class="icon icon-pause"/></a>
 | 
			
		||||
                    {% else %}
 | 
			
		||||
                    <a class="state-on" href="{{url_for('index', op='pause', uuid=watch.uuid, tag=active_tag)}}"><img src="{{url_for('static_content', group='images', filename='play.svg')}}" alt="UnPause checks" title="UnPause checks"/></a>
 | 
			
		||||
                    <a class="state-on" href="{{url_for('index', op='pause', uuid=watch.uuid, tag=active_tag)}}"><img src="{{url_for('static_content', group='images', filename='play.svg')}}" alt="UnPause checks" title="UnPause checks" class="icon icon-unpause"/></a>
 | 
			
		||||
                    {% endif %}
 | 
			
		||||
                    <a class="state-{{'on' if watch.notification_muted}}" href="{{url_for('index', op='mute', uuid=watch.uuid, tag=active_tag)}}"><img src="{{url_for('static_content', group='images', filename='bell-off.svg')}}" alt="Mute notifications" title="Mute notifications"/></a>
 | 
			
		||||
                    <a class="link-mute state-{{'on' if watch.notification_muted else 'off'}}" href="{{url_for('index', op='mute', uuid=watch.uuid, tag=active_tag)}}"><img src="{{url_for('static_content', group='images', filename='bell-off.svg')}}" alt="Mute notifications" title="Mute notifications" class="icon icon-mute"/></a>
 | 
			
		||||
                </td>
 | 
			
		||||
                <td class="title-col inline">{{watch.title if watch.title is not none and watch.title|length > 0 else watch.url}}
 | 
			
		||||
                    <a class="external" target="_blank" rel="noopener" href="{{ watch.link.replace('source:','') }}"></a>
 | 
			
		||||
                    <a href="{{url_for('form_share_put_watch', uuid=watch.uuid)}}"><img style="height: 1em;display:inline-block;" src="{{url_for('static_content', group='images', filename='spread.svg')}}" /></a>
 | 
			
		||||
                    <a class="link-spread" href="{{url_for('form_share_put_watch', uuid=watch.uuid)}}"><img style="height: 1em;display:inline-block;" src="{{url_for('static_content', group='images', filename='spread.svg')}}" class="icon icon-spread" /></a>
 | 
			
		||||
 | 
			
		||||
                    {%if watch.fetch_backend == "html_webdriver" %}<img style="height: 1em; display:inline-block;" src="{{url_for('static_content', group='images', filename='Google-Chrome-icon.png')}}" />{% endif %}
 | 
			
		||||
 | 
			
		||||
@@ -111,13 +111,13 @@
 | 
			
		||||
                </td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <a {% if watch.uuid in queued_uuids %}disabled="true"{% endif %} href="{{ url_for('form_watch_checknow', uuid=watch.uuid, tag=request.args.get('tag')) }}"
 | 
			
		||||
                       class="recheck pure-button button-small pure-button-primary">{% if watch.uuid in queued_uuids %}Queued{% else %}Recheck{% endif %}</a>
 | 
			
		||||
                    <a href="{{ url_for('edit_page', uuid=watch.uuid)}}" class="pure-button button-small pure-button-primary">Edit</a>
 | 
			
		||||
                       class="recheck pure-button pure-button-primary">{% if watch.uuid in queued_uuids %}Queued{% else %}Recheck{% endif %}</a>
 | 
			
		||||
                    <a href="{{ url_for('edit_page', uuid=watch.uuid)}}" class="pure-button pure-button-primary">Edit</a>
 | 
			
		||||
                    {% if watch.history_n >= 2 %}
 | 
			
		||||
                    <a href="{{ url_for('diff_history_page', uuid=watch.uuid) }}" target="{{watch.uuid}}" class="pure-button button-small pure-button-primary diff-link">Diff</a>
 | 
			
		||||
                    <a href="{{ url_for('diff_history_page', uuid=watch.uuid) }}" target="{{watch.uuid}}" class="pure-button pure-button-primary diff-link">Diff</a>
 | 
			
		||||
                    {% else %}
 | 
			
		||||
                        {% if watch.history_n == 1 or (watch.history_n ==0 and watch.error_text_ctime )%}
 | 
			
		||||
                            <a href="{{ url_for('preview_page', uuid=watch.uuid)}}" target="{{watch.uuid}}" class="pure-button button-small pure-button-primary">Preview</a>
 | 
			
		||||
                            <a href="{{ url_for('preview_page', uuid=watch.uuid)}}" target="{{watch.uuid}}" class="pure-button pure-button-primary">Preview</a>
 | 
			
		||||
                        {% endif %}
 | 
			
		||||
                    {% endif %}
 | 
			
		||||
                </td>
 | 
			
		||||
 
 | 
			
		||||