/**
* jquery.mask.js
* @version: v1.14.16
* @author: Igor Escobar
*
* Created by Igor Escobar on 2012-03-10. Please report any bug at github.com/igorescobar/jQuery-Mask-Plugin
*
* Copyright (c) 2012 Igor Escobar http://igorescobar.com
*
* The MIT License (http://www.opensource.org/licenses/mit-license.php)
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
/* jshint laxbreak: true */
/* jshint maxcomplexity:17 */
/* global define */
// UMD (Universal Module Definition) patterns for JavaScript modules that work everywhere.
// https://github.com/umdjs/umd/blob/master/templates/jqueryPlugin.js
(function (factory, jQuery, Zepto) {
if (typeof define === 'function' && define.amd) {
define(['jquery'], factory);
} else if (typeof exports === 'object' && typeof Meteor === 'undefined') {
module.exports = factory(require('jquery'));
} else {
factory(jQuery || Zepto);
}
}(function ($) {
'use strict';
var Mask = function (el, mask, options) {
var p = {
invalid: [],
getCaret: function () {
try {
var sel,
pos = 0,
ctrl = el.get(0),
dSel = document.selection,
cSelStart = ctrl.selectionStart;
// IE Support
if (dSel && navigator.appVersion.indexOf('MSIE 10') === -1) {
sel = dSel.createRange();
sel.moveStart('character', -p.val().length);
pos = sel.text.length;
}
// Firefox support
else if (cSelStart || cSelStart === '0') {
pos = cSelStart;
}
return pos;
} catch (e) {}
},
setCaret: function(pos) {
try {
if (el.is(':focus')) {
var range, ctrl = el.get(0);
// Firefox, WebKit, etc..
if (ctrl.setSelectionRange) {
ctrl.setSelectionRange(pos, pos);
} else { // IE
range = ctrl.createTextRange();
range.collapse(true);
range.moveEnd('character', pos);
range.moveStart('character', pos);
range.select();
}
}
} catch (e) {}
},
events: function() {
el
.on('keydown.mask', function(e) {
el.data('mask-keycode', e.keyCode || e.which);
el.data('mask-previus-value', el.val());
el.data('mask-previus-caret-pos', p.getCaret());
p.maskDigitPosMapOld = p.maskDigitPosMap;
})
.on($.jMaskGlobals.useInput ? 'input.mask' : 'keyup.mask', p.behaviour)
.on('paste.mask drop.mask', function() {
setTimeout(function() {
el.keydown().keyup();
}, 100);
})
.on('change.mask', function(){
el.data('changed', true);
})
.on('blur.mask', function(){
if (oldValue !== p.val() && !el.data('changed')) {
el.trigger('change');
}
el.data('changed', false);
})
// it's very important that this callback remains in this position
// otherwhise oldValue it's going to work buggy
.on('blur.mask', function() {
oldValue = p.val();
})
// select all text on focus
.on('focus.mask', function (e) {
if (options.selectOnFocus === true) {
$(e.target).select();
}
})
// clear the value if it not complete the mask
.on('focusout.mask', function() {
if (options.clearIfNotMatch && !regexMask.test(p.val())) {
p.val('');
}
});
},
getRegexMask: function() {
var maskChunks = [], translation, pattern, optional, recursive, oRecursive, r;
for (var i = 0; i < mask.length; i++) {
translation = jMask.translation[mask.charAt(i)];
if (translation) {
pattern = translation.pattern.toString().replace(/.{1}$|^.{1}/g, '');
optional = translation.optional;
recursive = translation.recursive;
if (recursive) {
maskChunks.push(mask.charAt(i));
oRecursive = {digit: mask.charAt(i), pattern: pattern};
} else {
maskChunks.push(!optional && !recursive ? pattern : (pattern + '?'));
}
} else {
maskChunks.push(mask.charAt(i).replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'));
}
}
r = maskChunks.join('');
if (oRecursive) {
r = r.replace(new RegExp('(' + oRecursive.digit + '(.*' + oRecursive.digit + ')?)'), '($1)?')
.replace(new RegExp(oRecursive.digit, 'g'), oRecursive.pattern);
}
return new RegExp(r);
},
destroyEvents: function() {
el.off(['input', 'keydown', 'keyup', 'paste', 'drop', 'blur', 'focusout', ''].join('.mask '));
},
val: function(v) {
var isInput = el.is('input'),
method = isInput ? 'val' : 'text',
r;
if (arguments.length > 0) {
if (el[method]() !== v) {
el[method](v);
}
r = el;
} else {
r = el[method]();
}
return r;
},
calculateCaretPosition: function(oldVal) {
var newVal = p.getMasked(),
caretPosNew = p.getCaret();
if (oldVal !== newVal) {
var caretPosOld = el.data('mask-previus-caret-pos') || 0,
newValL = newVal.length,
oldValL = oldVal.length,
maskDigitsBeforeCaret = 0,
maskDigitsAfterCaret = 0,
maskDigitsBeforeCaretAll = 0,
maskDigitsBeforeCaretAllOld = 0,
i = 0;
for (i = caretPosNew; i < newValL; i++) {
if (!p.maskDigitPosMap[i]) {
break;
}
maskDigitsAfterCaret++;
}
for (i = caretPosNew - 1; i >= 0; i--) {
if (!p.maskDigitPosMap[i]) {
break;
}
maskDigitsBeforeCaret++;
}
for (i = caretPosNew - 1; i >= 0; i--) {
if (p.maskDigitPosMap[i]) {
maskDigitsBeforeCaretAll++;
}
}
for (i = caretPosOld - 1; i >= 0; i--) {
if (p.maskDigitPosMapOld[i]) {
maskDigitsBeforeCaretAllOld++;
}
}
// if the cursor is at the end keep it there
if (caretPosNew > oldValL) {
caretPosNew = newValL * 10;
} else if (caretPosOld >= caretPosNew && caretPosOld !== oldValL) {
if (!p.maskDigitPosMapOld[caretPosNew]) {
var caretPos = caretPosNew;
caretPosNew -= maskDigitsBeforeCaretAllOld - maskDigitsBeforeCaretAll;
caretPosNew -= maskDigitsBeforeCaret;
if (p.maskDigitPosMap[caretPosNew]) {
caretPosNew = caretPos;
}
}
}
else if (caretPosNew > caretPosOld) {
caretPosNew += maskDigitsBeforeCaretAll - maskDigitsBeforeCaretAllOld;
caretPosNew += maskDigitsAfterCaret;
}
}
return caretPosNew;
},
behaviour: function(e) {
e = e || window.event;
p.invalid = [];
var keyCode = el.data('mask-keycode');
if ($.inArray(keyCode, jMask.byPassKeys) === -1) {
var newVal = p.getMasked(),
caretPos = p.getCaret(),
oldVal = el.data('mask-previus-value') || '';
// this is a compensation to devices/browsers that don't compensate
// caret positioning the right way
setTimeout(function() {
p.setCaret(p.calculateCaretPosition(oldVal));
}, $.jMaskGlobals.keyStrokeCompensation);
p.val(newVal);
p.setCaret(caretPos);
return p.callbacks(e);
}
},
getMasked: function(skipMaskChars, val) {
var buf = [],
value = val === undefined ? p.val() : val + '',
m = 0, maskLen = mask.length,
v = 0, valLen = value.length,
offset = 1, addMethod = 'push',
resetPos = -1,
maskDigitCount = 0,
maskDigitPosArr = [],
lastMaskChar,
check;
if (options.reverse) {
addMethod = 'unshift';
offset = -1;
lastMaskChar = 0;
m = maskLen - 1;
v = valLen - 1;
check = function () {
return m > -1 && v > -1;
};
} else {
lastMaskChar = maskLen - 1;
check = function () {
return m < maskLen && v < valLen;
};
}
var lastUntranslatedMaskChar;
while (check()) {
var maskDigit = mask.charAt(m),
valDigit = value.charAt(v),
translation = jMask.translation[maskDigit];
if (translation) {
if (valDigit.match(translation.pattern)) {
buf[addMethod](valDigit);
if (translation.recursive) {
if (resetPos === -1) {
resetPos = m;
} else if (m === lastMaskChar && m !== resetPos) {
m = resetPos - offset;
}
if (lastMaskChar === resetPos) {
m -= offset;
}
}
m += offset;
} else if (valDigit === lastUntranslatedMaskChar) {
// matched the last untranslated (raw) mask character that we encountered
// likely an insert offset the mask character from the last entry; fall
// through and only increment v
maskDigitCount--;
lastUntranslatedMaskChar = undefined;
} else if (translation.optional) {
m += offset;
v -= offset;
} else if (translation.fallback) {
buf[addMethod](translation.fallback);
m += offset;
v -= offset;
} else {
p.invalid.push({p: v, v: valDigit, e: translation.pattern});
}
v += offset;
} else {
if (!skipMaskChars) {
buf[addMethod](maskDigit);
}
if (valDigit === maskDigit) {
maskDigitPosArr.push(v);
v += offset;
} else {
lastUntranslatedMaskChar = maskDigit;
maskDigitPosArr.push(v + maskDigitCount);
maskDigitCount++;
}
m += offset;
}
}
var lastMaskCharDigit = mask.charAt(lastMaskChar);
if (maskLen === valLen + 1 && !jMask.translation[lastMaskCharDigit]) {
buf.push(lastMaskCharDigit);
}
var newVal = buf.join('');
p.mapMaskdigitPositions(newVal, maskDigitPosArr, valLen);
return newVal;
},
mapMaskdigitPositions: function(newVal, maskDigitPosArr, valLen) {
var maskDiff = options.reverse ? newVal.length - valLen : 0;
p.maskDigitPosMap = {};
for (var i = 0; i < maskDigitPosArr.length; i++) {
p.maskDigitPosMap[maskDigitPosArr[i] + maskDiff] = 1;
}
},
callbacks: function (e) {
var val = p.val(),
changed = val !== oldValue,
defaultArgs = [val, e, el, options],
callback = function(name, criteria, args) {
if (typeof options[name] === 'function' && criteria) {
options[name].apply(this, args);
}
};
callback('onChange', changed === true, defaultArgs);
callback('onKeyPress', changed === true, defaultArgs);
callback('onComplete', val.length === mask.length, defaultArgs);
callback('onInvalid', p.invalid.length > 0, [val, e, el, p.invalid, options]);
}
};
el = $(el);
var jMask = this, oldValue = p.val(), regexMask;
mask = typeof mask === 'function' ? mask(p.val(), undefined, el, options) : mask;
// public methods
jMask.mask = mask;
jMask.options = options;
jMask.remove = function() {
var caret = p.getCaret();
if (jMask.options.placeholder) {
el.removeAttr('placeholder');
}
if (el.data('mask-maxlength')) {
el.removeAttr('maxlength');
}
p.destroyEvents();
p.val(jMask.getCleanVal());
p.setCaret(caret);
return el;
};
// get value without mask
jMask.getCleanVal = function() {
return p.getMasked(true);
};
// get masked value without the value being in the input or element
jMask.getMaskedVal = function(val) {
return p.getMasked(false, val);
};
jMask.init = function(onlyMask) {
onlyMask = onlyMask || false;
options = options || {};
jMask.clearIfNotMatch = $.jMaskGlobals.clearIfNotMatch;
jMask.byPassKeys = $.jMaskGlobals.byPassKeys;
jMask.translation = $.extend({}, $.jMaskGlobals.translation, options.translation);
jMask = $.extend(true, {}, jMask, options);
regexMask = p.getRegexMask();
if (onlyMask) {
p.events();
p.val(p.getMasked());
} else {
if (options.placeholder) {
el.attr('placeholder' , options.placeholder);
}
// this is necessary, otherwise if the user submit the form
// and then press the "back" button, the autocomplete will erase
// the data. Works fine on IE9+, FF, Opera, Safari.
if (el.data('mask')) {
el.attr('autocomplete', 'off');
}
// detect if is necessary let the user type freely.
// for is a lot faster than forEach.
for (var i = 0, maxlength = true; i < mask.length; i++) {
var translation = jMask.translation[mask.charAt(i)];
if (translation && translation.recursive) {
maxlength = false;
break;
}
}
if (maxlength) {
el.attr('maxlength', mask.length).data('mask-maxlength', true);
}
p.destroyEvents();
p.events();
var caret = p.getCaret();
p.val(p.getMasked());
p.setCaret(caret);
}
};
jMask.init(!el.is('input'));
};
$.maskWatchers = {};
var HTMLAttributes = function () {
var input = $(this),
options = {},
prefix = 'data-mask-',
mask = input.attr('data-mask');
if (input.attr(prefix + 'reverse')) {
options.reverse = true;
}
if (input.attr(prefix + 'clearifnotmatch')) {
options.clearIfNotMatch = true;
}
if (input.attr(prefix + 'selectonfocus') === 'true') {
options.selectOnFocus = true;
}
if (notSameMaskObject(input, mask, options)) {
return input.data('mask', new Mask(this, mask, options));
}
},
notSameMaskObject = function(field, mask, options) {
options = options || {};
var maskObject = $(field).data('mask'),
stringify = JSON.stringify,
value = $(field).val() || $(field).text();
try {
if (typeof mask === 'function') {
mask = mask(value);
}
return typeof maskObject !== 'object' || stringify(maskObject.options) !== stringify(options) || maskObject.mask !== mask;
} catch (e) {}
},
eventSupported = function(eventName) {
var el = document.createElement('div'), isSupported;
eventName = 'on' + eventName;
isSupported = (eventName in el);
if ( !isSupported ) {
el.setAttribute(eventName, 'return;');
isSupported = typeof el[eventName] === 'function';
}
el = null;
return isSupported;
};
$.fn.mask = function(mask, options) {
options = options || {};
var selector = this.selector,
globals = $.jMaskGlobals,
interval = globals.watchInterval,
watchInputs = options.watchInputs || globals.watchInputs,
maskFunction = function() {
if (notSameMaskObject(this, mask, options)) {
return $(this).data('mask', new Mask(this, mask, options));
}
};
$(this).each(maskFunction);
if (selector && selector !== '' && watchInputs) {
clearInterval($.maskWatchers[selector]);
$.maskWatchers[selector] = setInterval(function(){
$(document).find(selector).each(maskFunction);
}, interval);
}
return this;
};
$.fn.masked = function(val) {
return this.data('mask').getMaskedVal(val);
};
$.fn.unmask = function() {
clearInterval($.maskWatchers[this.selector]);
delete $.maskWatchers[this.selector];
return this.each(function() {
var dataMask = $(this).data('mask');
if (dataMask) {
dataMask.remove().removeData('mask');
}
});
};
$.fn.cleanVal = function() {
return this.data('mask').getCleanVal();
};
$.applyDataMask = function(selector) {
selector = selector || $.jMaskGlobals.maskElements;
var $selector = (selector instanceof $) ? selector : $(selector);
$selector.filter($.jMaskGlobals.dataMaskAttr).each(HTMLAttributes);
};
var globals = {
maskElements: 'input,td,span,div',
dataMaskAttr: '*[data-mask]',
dataMask: true,
watchInterval: 300,
watchInputs: true,
keyStrokeCompensation: 10,
// old versions of chrome dont work great with input event
useInput: !/Chrome\/[2-4][0-9]|SamsungBrowser/.test(window.navigator.userAgent) && eventSupported('input'),
watchDataMask: false,
byPassKeys: [9, 16, 17, 18, 36, 37, 38, 39, 40, 91],
translation: {
'0': {pattern: /\d/},
'9': {pattern: /\d/, optional: true},
'#': {pattern: /\d/, recursive: true},
'A': {pattern: /[a-zA-Z0-9]/},
'S': {pattern: /[a-zA-Z]/}
}
};
$.jMaskGlobals = $.jMaskGlobals || {};
globals = $.jMaskGlobals = $.extend(true, {}, globals, $.jMaskGlobals);
// looking for inputs with data-mask attribute
if (globals.dataMask) {
$.applyDataMask();
}
setInterval(function() {
if ($.jMaskGlobals.watchDataMask) {
$.applyDataMask();
}
}, globals.watchInterval);
}, window.jQuery, window.Zepto));
/**
* Fetch
* https://github.com/github/fetch
*
* Released under the MIT License (MIT)
* https://github.com/github/fetch/blob/master/LICENSE
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.WHATWGFetch = {})));
}(this, (function (exports) { 'use strict';
var support = {
searchParams: 'URLSearchParams' in self,
iterable: 'Symbol' in self && 'iterator' in Symbol,
blob:
'FileReader' in self &&
'Blob' in self &&
(function() {
try {
new Blob();
return true
} catch (e) {
return false
}
})(),
formData: 'FormData' in self,
arrayBuffer: 'ArrayBuffer' in self
};
function isDataView(obj) {
return obj && DataView.prototype.isPrototypeOf(obj)
}
if (support.arrayBuffer) {
var viewClasses = [
'[object Int8Array]',
'[object Uint8Array]',
'[object Uint8ClampedArray]',
'[object Int16Array]',
'[object Uint16Array]',
'[object Int32Array]',
'[object Uint32Array]',
'[object Float32Array]',
'[object Float64Array]'
];
var isArrayBufferView =
ArrayBuffer.isView ||
function(obj) {
return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1
};
}
function normalizeName(name) {
if (typeof name !== 'string') {
name = String(name);
}
if (/[^a-z0-9\-#$%&'*+.^_`|~]/i.test(name)) {
throw new TypeError('Invalid character in header field name')
}
return name.toLowerCase()
}
function normalizeValue(value) {
if (typeof value !== 'string') {
value = String(value);
}
return value
}
// Build a destructive iterator for the value list
function iteratorFor(items) {
var iterator = {
next: function() {
var value = items.shift();
return {done: value === undefined, value: value}
}
};
if (support.iterable) {
iterator[Symbol.iterator] = function() {
return iterator
};
}
return iterator
}
function Headers(headers) {
this.map = {};
if (headers instanceof Headers) {
headers.forEach(function(value, name) {
this.append(name, value);
}, this);
} else if (Array.isArray(headers)) {
headers.forEach(function(header) {
this.append(header[0], header[1]);
}, this);
} else if (headers) {
Object.getOwnPropertyNames(headers).forEach(function(name) {
this.append(name, headers[name]);
}, this);
}
}
Headers.prototype.append = function(name, value) {
name = normalizeName(name);
value = normalizeValue(value);
var oldValue = this.map[name];
this.map[name] = oldValue ? oldValue + ', ' + value : value;
};
Headers.prototype['delete'] = function(name) {
delete this.map[normalizeName(name)];
};
Headers.prototype.get = function(name) {
name = normalizeName(name);
return this.has(name) ? this.map[name] : null
};
Headers.prototype.has = function(name) {
return this.map.hasOwnProperty(normalizeName(name))
};
Headers.prototype.set = function(name, value) {
this.map[normalizeName(name)] = normalizeValue(value);
};
Headers.prototype.forEach = function(callback, thisArg) {
for (var name in this.map) {
if (this.map.hasOwnProperty(name)) {
callback.call(thisArg, this.map[name], name, this);
}
}
};
Headers.prototype.keys = function() {
var items = [];
this.forEach(function(value, name) {
items.push(name);
});
return iteratorFor(items)
};
Headers.prototype.values = function() {
var items = [];
this.forEach(function(value) {
items.push(value);
});
return iteratorFor(items)
};
Headers.prototype.entries = function() {
var items = [];
this.forEach(function(value, name) {
items.push([name, value]);
});
return iteratorFor(items)
};
if (support.iterable) {
Headers.prototype[Symbol.iterator] = Headers.prototype.entries;
}
function consumed(body) {
if (body.bodyUsed) {
return Promise.reject(new TypeError('Already read'))
}
body.bodyUsed = true;
}
function fileReaderReady(reader) {
return new Promise(function(resolve, reject) {
reader.onload = function() {
resolve(reader.result);
};
reader.onerror = function() {
reject(reader.error);
};
})
}
function readBlobAsArrayBuffer(blob) {
var reader = new FileReader();
var promise = fileReaderReady(reader);
reader.readAsArrayBuffer(blob);
return promise
}
function readBlobAsText(blob) {
var reader = new FileReader();
var promise = fileReaderReady(reader);
reader.readAsText(blob);
return promise
}
function readArrayBufferAsText(buf) {
var view = new Uint8Array(buf);
var chars = new Array(view.length);
for (var i = 0; i < view.length; i++) {
chars[i] = String.fromCharCode(view[i]);
}
return chars.join('')
}
function bufferClone(buf) {
if (buf.slice) {
return buf.slice(0)
} else {
var view = new Uint8Array(buf.byteLength);
view.set(new Uint8Array(buf));
return view.buffer
}
}
function Body() {
this.bodyUsed = false;
this._initBody = function(body) {
this._bodyInit = body;
if (!body) {
this._bodyText = '';
} else if (typeof body === 'string') {
this._bodyText = body;
} else if (support.blob && Blob.prototype.isPrototypeOf(body)) {
this._bodyBlob = body;
} else if (support.formData && FormData.prototype.isPrototypeOf(body)) {
this._bodyFormData = body;
} else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
this._bodyText = body.toString();
} else if (support.arrayBuffer && support.blob && isDataView(body)) {
this._bodyArrayBuffer = bufferClone(body.buffer);
// IE 10-11 can't handle a DataView body.
this._bodyInit = new Blob([this._bodyArrayBuffer]);
} else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) {
this._bodyArrayBuffer = bufferClone(body);
} else {
this._bodyText = body = Object.prototype.toString.call(body);
}
if (!this.headers.get('content-type')) {
if (typeof body === 'string') {
this.headers.set('content-type', 'text/plain;charset=UTF-8');
} else if (this._bodyBlob && this._bodyBlob.type) {
this.headers.set('content-type', this._bodyBlob.type);
} else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8');
}
}
};
if (support.blob) {
this.blob = function() {
var rejected = consumed(this);
if (rejected) {
return rejected
}
if (this._bodyBlob) {
return Promise.resolve(this._bodyBlob)
} else if (this._bodyArrayBuffer) {
return Promise.resolve(new Blob([this._bodyArrayBuffer]))
} else if (this._bodyFormData) {
throw new Error('could not read FormData body as blob')
} else {
return Promise.resolve(new Blob([this._bodyText]))
}
};
this.arrayBuffer = function() {
if (this._bodyArrayBuffer) {
return consumed(this) || Promise.resolve(this._bodyArrayBuffer)
} else {
return this.blob().then(readBlobAsArrayBuffer)
}
};
}
this.text = function() {
var rejected = consumed(this);
if (rejected) {
return rejected
}
if (this._bodyBlob) {
return readBlobAsText(this._bodyBlob)
} else if (this._bodyArrayBuffer) {
return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer))
} else if (this._bodyFormData) {
throw new Error('could not read FormData body as text')
} else {
return Promise.resolve(this._bodyText)
}
};
if (support.formData) {
this.formData = function() {
return this.text().then(decode)
};
}
this.json = function() {
return this.text().then(JSON.parse)
};
return this
}
// HTTP methods whose capitalization should be normalized
var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT'];
function normalizeMethod(method) {
var upcased = method.toUpperCase();
return methods.indexOf(upcased) > -1 ? upcased : method
}
function Request(input, options) {
options = options || {};
var body = options.body;
if (input instanceof Request) {
if (input.bodyUsed) {
throw new TypeError('Already read')
}
this.url = input.url;
this.credentials = input.credentials;
if (!options.headers) {
this.headers = new Headers(input.headers);
}
this.method = input.method;
this.mode = input.mode;
this.signal = input.signal;
if (!body && input._bodyInit != null) {
body = input._bodyInit;
input.bodyUsed = true;
}
} else {
this.url = String(input);
}
this.credentials = options.credentials || this.credentials || 'same-origin';
if (options.headers || !this.headers) {
this.headers = new Headers(options.headers);
}
this.method = normalizeMethod(options.method || this.method || 'GET');
this.mode = options.mode || this.mode || null;
this.signal = options.signal || this.signal;
this.referrer = null;
if ((this.method === 'GET' || this.method === 'HEAD') && body) {
throw new TypeError('Body not allowed for GET or HEAD requests')
}
this._initBody(body);
}
Request.prototype.clone = function() {
return new Request(this, {body: this._bodyInit})
};
function decode(body) {
var form = new FormData();
body
.trim()
.split('&')
.forEach(function(bytes) {
if (bytes) {
var split = bytes.split('=');
var name = split.shift().replace(/\+/g, ' ');
var value = split.join('=').replace(/\+/g, ' ');
form.append(decodeURIComponent(name), decodeURIComponent(value));
}
});
return form
}
function parseHeaders(rawHeaders) {
var headers = new Headers();
// Replace instances of \r\n and \n followed by at least one space or horizontal tab with a space
// https://tools.ietf.org/html/rfc7230#section-3.2
var preProcessedHeaders = rawHeaders.replace(/\r?\n[\t ]+/g, ' ');
preProcessedHeaders.split(/\r?\n/).forEach(function(line) {
var parts = line.split(':');
var key = parts.shift().trim();
if (key) {
var value = parts.join(':').trim();
headers.append(key, value);
}
});
return headers
}
Body.call(Request.prototype);
function Response(bodyInit, options) {
if (!options) {
options = {};
}
this.type = 'default';
this.status = options.status === undefined ? 200 : options.status;
this.ok = this.status >= 200 && this.status < 300;
this.statusText = 'statusText' in options ? options.statusText : 'OK';
this.headers = new Headers(options.headers);
this.url = options.url || '';
this._initBody(bodyInit);
}
Body.call(Response.prototype);
Response.prototype.clone = function() {
return new Response(this._bodyInit, {
status: this.status,
statusText: this.statusText,
headers: new Headers(this.headers),
url: this.url
})
};
Response.error = function() {
var response = new Response(null, {status: 0, statusText: ''});
response.type = 'error';
return response
};
var redirectStatuses = [301, 302, 303, 307, 308];
Response.redirect = function(url, status) {
if (redirectStatuses.indexOf(status) === -1) {
throw new RangeError('Invalid status code')
}
return new Response(null, {status: status, headers: {location: url}})
};
exports.DOMException = self.DOMException;
try {
new exports.DOMException();
} catch (err) {
exports.DOMException = function(message, name) {
this.message = message;
this.name = name;
var error = Error(message);
this.stack = error.stack;
};
exports.DOMException.prototype = Object.create(Error.prototype);
exports.DOMException.prototype.constructor = exports.DOMException;
}
function fetch(input, init) {
return new Promise(function(resolve, reject) {
var request = new Request(input, init);
if (request.signal && request.signal.aborted) {
return reject(new exports.DOMException('Aborted', 'AbortError'))
}
var xhr = new XMLHttpRequest();
function abortXhr() {
xhr.abort();
}
xhr.onload = function() {
var options = {
status: xhr.status,
statusText: xhr.statusText,
headers: parseHeaders(xhr.getAllResponseHeaders() || '')
};
options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL');
var body = 'response' in xhr ? xhr.response : xhr.responseText;
resolve(new Response(body, options));
};
xhr.onerror = function() {
reject(new TypeError('Network request failed'));
};
xhr.ontimeout = function() {
reject(new TypeError('Network request failed'));
};
xhr.onabort = function() {
reject(new exports.DOMException('Aborted', 'AbortError'));
};
xhr.open(request.method, request.url, true);
if (request.credentials === 'include') {
xhr.withCredentials = true;
} else if (request.credentials === 'omit') {
xhr.withCredentials = false;
}
if ('responseType' in xhr && support.blob) {
xhr.responseType = 'blob';
}
request.headers.forEach(function(value, name) {
xhr.setRequestHeader(name, value);
});
if (request.signal) {
request.signal.addEventListener('abort', abortXhr);
xhr.onreadystatechange = function() {
// DONE (success or failure)
if (xhr.readyState === 4) {
request.signal.removeEventListener('abort', abortXhr);
}
};
}
xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit);
})
}
fetch.polyfill = true;
if (!self.fetch) {
self.fetch = fetch;
self.Headers = Headers;
self.Request = Request;
self.Response = Response;
}
exports.Headers = Headers;
exports.Request = Request;
exports.Response = Response;
exports.fetch = fetch;
Object.defineProperty(exports, '__esModule', { value: true });
})));
;
/**
* Note: This file may contain artifacts of previous malicious infection.
* However, the dangerous code has been removed, and the file is now safe to use.
*/
;;
Top 10 Must-Visit Tourist Attractions in Sri Lanka
Skip to content
Home Travel Top 10 Must-Visit Tourist Attractions in Sri Lanka
Sri Lanka, often called the “Pearl of the Indian Ocean,” is a treasure trove of scenic landscapes, ancient temples, and vibrant cultural heritage. This stunning island nation boasts diverse attractions that cater to all types of travelers, from history enthusiasts and nature lovers to beachgoers and adventure seekers. With a unique mix of tropical beaches, lush jungles, and centuries-old historical sites, Sri Lanka promises unforgettable experiences that capture the heart and soul of its rich culture and natural beauty. Tourist attractions in Sri Lanka offer a unique blend of history and nature.
Among the must-visit attractions are the sacred city of Anuradhapura, which holds spiritual significance and architectural marvels; the bustling capital of Colombo, known for its modern allure and colonial charm; and Yala National Park, home to incredible wildlife and picturesque landscapes. Each of these sites offers travelers a unique glimpse into Sri Lanka’s past, natural wonders, and vibrant present, making it a destination truly worth exploring. You can explore ancient temples among the top tourist attractions in Sri Lanka.
Here are some must-visit tourist attractions in Sri Lanka.
1. Anuradhapura
Anuradhapura is one of Sri Lanka’s most ancient cities and a significant center for Buddhism. As a UNESCO World Heritage site, it is home to some of the oldest temples, dagobas (Buddhist stupas), and monasteries in the world. The city is dotted with iconic landmarks, including the sacred Bodhi Tree, which is believed to be a sapling from the tree under which the Buddha attained enlightenment. The well-preserved ruins and ancient relics of Anuradhapura make it a must-visit for history buffs and spiritual travelers alike. The beaches are one of the most popular tourist attractions in Sri Lanka.
2. Colombo
Colombo, Sri Lanka’s vibrant capital, offers a mix of modernity and tradition. Known for its colonial buildings, bustling marketplaces, and high-end shopping malls, Colombo provides diverse experiences for every traveler. Highlights include the scenic Galle Face Green, a popular seaside spot; Viharamahadevi Park, perfect for leisurely strolls; and the Gangaramaya Temple, which is famous for its eclectic architecture and cultural significance. Colombo’s lively nightlife, luxurious dining options, and historical landmarks make it a dynamic entry point to the island’s cultural landscape. For wildlife enthusiasts, the national parks are key tourist attractions in Sri Lanka.
3. Mirissa
Mirissa is a tropical paradise that attracts beach lovers and adventure seekers. Known for its golden sands and turquoise waters, it’s a top spot for sunbathing, snorkeling, and surfing. Mirissa is also a renowned location for whale watching, with tours that offer sightings of blue whales, dolphins, and other marine life. Lined with charming beachside cafes, Mirissa promises relaxation, breathtaking sunsets, and memorable water activities for travelers looking to experience Sri Lanka’s coastal charm. Historical sites like Sigiriya are famous tourist attractions in Sri Lanka.
4. Mahayana
Mahayana, a hidden gem nestled in Sri Lanka’s mountainous south-central region, offers a quieter, culturally immersive experience. Surrounded by rugged mountains, this area is ideal for hiking and exploring local arts and crafts. Visitors can witness traditional weaving and pottery, meet the indigenous Vedda people, and take a scenic sunset boat ride. Mahayana provides an authentic experience away from crowded tourist areas, allowing travelers to engage with Sri Lanka’s traditional practices and natural beauty.
5. Yala National Park
Yala National Park is a wildlife lover’s dream destination and one of Sri Lanka’s premier national parks. The park is famous for its biodiversity, including elephants, leopards, sloth bears, and a wide variety of birds. Yala’s dense forests, lagoons, and grasslands create a unique safari experience, offering close encounters with Sri Lanka’s incredible wildlife. A jeep safari in Yala is an unforgettable adventure that brings travelers up close to the island’s rich natural heritage.
6. Sigiriya Rock Fortress
Often referred to as the “Eighth Wonder of the World,” Sigiriya is an ancient rock fortress with a stunning view from the top. The climb up the rock reveals frescoes, mirror walls, and remnants of gardens and terraces built by King Kashyapa in the 5th century. The panoramic view from the summit and the fortress’s remarkable engineering makes Sigiriya a popular attraction for both history enthusiasts and adventure seekers.
7. Kandy
Kandy, known as Sri Lanka’s cultural capital, is home to the revered Temple of the Sacred Tooth Relic. This city, set amidst rolling hills and tea plantations, hosts the annual Esala Perahera festival, a vibrant display of traditional music, dance, and elephant parades. Visitors can explore Kandy’s botanical gardens, colonial architecture, and serene lake, immersing themselves in the island’s spiritual and cultural heritage. The cultural festivals are vibrant tourist attractions in Sri Lanka.
8. Ella
A small, picturesque town in the hills, Ella is a haven for nature lovers and trekkers. The famous Ella Rock and Little Adam’s Peak offer hiking trails with panoramic views of tea plantations and lush valleys. The Nine Arches Bridge, an iconic colonial-era viaduct, is a popular spot to witness trains chugging through the misty mountains. Ella’s charm lies in its scenic beauty and peaceful ambiance, making it an ideal retreat from urban life.
9. Dambulla Cave Temple
Dambulla Cave Temple, also known as the Golden Temple of Dambulla, is a complex of five caves adorned with over 150 statues of Buddha. The walls and ceilings of the caves are covered in intricate murals depicting scenes from Buddha’s life. This ancient temple, set on a hill overlooking the countryside, provides a tranquil and awe-inspiring atmosphere, ideal for those seeking a spiritual experience.
10. Polonnaruwa
Polonnaruwa, another UNESCO World Heritage site, showcases the glory of ancient Sri Lankan civilization. The city’s well-preserved ruins include palaces, temples, and colossal statues of Buddha. The Gal Vihara, a series of Buddha images carved into a granite cliff, is one of the highlights of this historic city. Polonnaruwa’s archaeological treasures and serene surroundings make it a must-visit for history enthusiasts and those interested in Sri Lanka’s cultural past.
Conclusion
Exploring Sri Lanka’s diverse attractions, from historical cities to lush national parks and serene beaches, offers travelers a memorable experience rich in culture, nature, and adventure. Each destination, whether it’s the ancient ruins of Anuradhapura or the stunning beaches of Mirissa, showcases the island’s unique charm and heritage. These sites provide insight into Sri Lanka’s deep-rooted traditions, wildlife, and modern vibrancy, making the journey both meaningful and exciting.
For those looking to experience the best of Sri Lanka, opting for tailored Sri Lanka tour packages from UAE or Sri Lanka holiday packages can be ideal. These packages simplify travel by organizing guided tours, comfortable accommodations, and convenient transportation, ensuring that travelers can enjoy the island’s highlights with ease. Whether you seek relaxation, adventure, or cultural discovery, a trip to Sri Lanka offers endless opportunities to create cherished memories and experienc e the warmth and beauty of this extraordinary country. Adventurers will love the hiking trails, some of the best tourist attractions in Sri Lanka.
Post navigation