phone Number validation in java - java

I want to validate a phone number in such Way :-
The field should allow the user to enter characters and should auto-correct. So an entry of "+1-908-528-5656" would not create an error for the user, it would just change to "19085285656".
I also want to number range between 9 to 11.
I also tried with the below code but not concluded to the final solution:
final String PHONE_REGEX = "^\\+([0-9\\-]?){9,11}[0-9]$";
final Pattern pattern = Pattern.compile(PHONE_REGEX);
String phone = "+1-908-528-5656";
phone=phone.replaceAll("[\\-\\+]", "");
System.out.println(phone);
final Matcher matcher = pattern.matcher(phone);
System.out.println(matcher.matches());

You can use simple String.matches(regex) to test any string against a regex pattern instead of using Pattern and Matcher classes.
Sample:
boolean isValid = phoneString.matches(regexPattern);
Find more examples
Here is the regex pattern as per your input string:
\+\d(-\d{3}){2}-\d{4}
Online demo
Better use Spring validation annotation for validation.
Example

// The Regex not validate mobile number, which is in internation format.
// The Following code work for me.
// I have use libphonenumber library to validate Number from below link.
// http://repo1.maven.org/maven2/com/googlecode/libphonenumber/libphonenumber/8.0.1/
// https://github.com/googlei18n/libphonenumber
// Here, is my source code.
public boolean isMobileNumberValid(String phoneNumber)
{
boolean isValid = false;
// Use the libphonenumber library to validate Number
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
Phonenumber.PhoneNumber swissNumberProto =null ;
try {
swissNumberProto = phoneUtil.parse(phoneNumber, "CH");
} catch (NumberParseException e) {
System.err.println("NumberParseException was thrown: " + e.toString());
}
if(phoneUtil.isValidNumber(swissNumberProto))
{
isValid = true;
}
// The Library failed to validate number if it contains - sign
// thus use regex to validate Mobile Number.
String regex = "[0-9*#+() -]*";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(phoneNumber);
if (matcher.matches()) {
isValid = true;
}
return isValid;
}

Assuming your input field take any kind of character and you just want the digits.
String phone = "+1-908-528-5656";
phone=phone.replaceAll("[\\D]","");
if(phone.length()>=9 || phone.length()<=11)
System.out.println(phone);

We can use String.matches(String regex)1 to validate phone numbers using java.
Sample code snippet
package regex;
public class Phone {
private static boolean isValid(String s) {
String regex = "\\d{3}-\\d{3}-\\d{4}"; // XXX-XXX-XXXX
return s.matches(regex);
}
public static void main(String[] args) {
System.out.println(isValid("123-456-7890"));
}
}
P.S. The regex pattern we use extra '\' for escaping when we use in java string. (Try to use "\d{3}-\d{3}-\d{4}" in java program, you will get an error.

Assuming you want an optimization (which is what your comment suggests).
How bout this? (the "0" is to exclude if they give complete garbage without even a single digit).
int parse(String phone){
int num = Integer.parseInt("0"+phone.replaceAll("[^0-9]",""));
return 100000000<=num&&num<100000000000?num:-1;
}

I am not sure but removing the garbage characters parenthesis, spaces and hyphens, if you match with ^((\+[1-9]?[0-9])|0)?[7-9][0-9]{9}$ , you may validate a mobile number
private static final String PHONE_NUMBER_GARBAGE_REGEX = "[()\\s-]+";
private static final String PHONE_NUMBER_REGEX = "^((\\+[1-9]?[0-9])|0)?[7-9][0-9]{9}$";
private static final Pattern PHONE_NUMBER_PATTERN = Pattern.compile(PHONE_NUMBER_REGEX);
public static boolean validatePhoneNumber(String phoneNumber) {
return phoneNumber != null && PHONE_NUMBER_PATTERN.matcher(phoneNumber.replaceAll(PHONE_NUMBER_GARBAGE_REGEX, "")).matches();
}

One easy and simple to use java phone validation regex:
public static final String PHONE_VERIFICATION = "^[+0-9-\\(\\)\\s]*{6,14}$";
private static Pattern p;
private static Matcher m;
public static void main(String[] args)
{
//Phone validation
p = Pattern.compile(PHONE_VERIFICATION);
m = p.matcher("+1 212-788-8609");
boolean isPhoneValid = m.matches();
if(!isPhoneValid)
{
System.out.println("The Phone number is NOT valid!");
return;
}
System.out.println("The Phone number is valid!");
}

i have done testing one regex for this combination of phone numbers
(294) 784-4554
(247) 784 4554
(124)-784 4783
(124)-784-4783
(124) 784-4783
+1(202)555-0138
THIS REGEX SURELY WILL BE WORKING FOR ALL THE US NUMBERS
\d{10}|(?:\d{3}-){2}\d{4}|\(\d{3}\)\d{3}-?\d{4}|\(\d{3}\)-\d{3}-?\d{4}|\(\d{3}\) \d{3} ?\d{4}|\(\d{3}\)-\d{3} ?\d{4}|\(\d{3}\) \d{3}-?\d{4}

Building on #k_g's answers, but for US numbers.
static boolean isValidTelephoneNumber(String number) {
long num = Long.parseLong("0" + number.replaceAll("[^0-9]", ""));
return 2000000000L <= num && num < 19999999999L;
}
public static void main(String[] args) {
var numbers = List.of("+1 212-788-8609", "212-788-8609", "1 212-788-8609", "12127888609", "2127888609",
"7143788", "736103355");
numbers.forEach(number -> {
boolean isPhoneValid = isValidTelephoneNumber(number);
log.debug(number + " matches = " + isPhoneValid);
});
}

Related

How to match with two regex Expression?

I should check if that string is valid. So i can i check UUID parts with this regex expression
private String UUID = "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})"
private String url = "customers/00000000-0000-0000-0000-000000000111/areas/00000000-0000-0000-0000-000000000222/orders/00000000-0000-0000-0000-000000000555/invoices/00000000-0000-0000-0000-000000000777/employees/2018-10-31T00:27:31.205+0000.jpg"
like this
Pattern JPG_PATTERN = Pattern.compile(
String.format("customers/%s/areas/%<s/orders/%<s/invoices/%<s/employees/", UUID));
Matcher m = JPG_PATTERN.matcher(url);
if (m.find()) {
System.out.println("found);
}
But when i add another regex to check last part of the string. It doesn't work.
private String EXTENSION = "(?:mov|jpg)";
Pattern JPG_PATTERN = Pattern.compile(
String.format("customers/%s/areas/%<s/orders/%<s/invoices/%<s/employees/%s", UUID, EXTENSION));
Matcher m = JPG_PATTERN.matcher(url);
if (m.find()) {
System.out.println("found);
}
How can use these two apart regex expression and check if the string is valid?
Your regex does not match filename: 2018-10-31T00:27:31.205+0000.
Change extension regex to String EXTENSION = ".+(?:mov|jpg)";
And change find to matches, otherwise .jpg1 is considered valid. Here is full the code:
private static String UUID = "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})";
private static String url = "customers/00000000-0000-0000-0000-000000000111/areas/00000000-0000-0000-0000-000000000222/orders/00000000-0000-0000-0000-000000000555/invoices/00000000-0000-0000-0000-000000000777/employees/2018-10-31T00:27:31.205+0000.jpg";
private static String EXTENSION = ".+(?:mov|jpg)";
public static void main(String[] args) {
Pattern JPG_PATTERN = Pattern.compile(String.format("customers/%s/areas/%<s/orders/%<s/invoices/%<s/employees/%s", UUID, EXTENSION));
Matcher m = JPG_PATTERN.matcher(url);
if (m.matches()) {
System.out.println("found");
} else {
System.out.println("not found");
}
}
Here is a fixed version of your code. The blocker I saw on your end seemed to be a misunderstanding of how String#format works. Because you are trying to bind more than one placeholder, I suggest just using %s everywhere and then specifying each string explicitly. Note that the pattern you want to use for the final path component for the extension is slightly different than what you suggested.
String UUID = "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})";
String EXTENSION = ".*(?:mov|jpg)$";
String pattern = String.format("^customers/%s/areas/%s/orders/%s/invoices/%s/employees/%s", UUID, UUID, UUID, UUID, EXTENSION);
System.out.println(pattern);
^customers/([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})/areas/
([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})/orders/
([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})/invoices/
([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})/employees/.*(?:mov|jpg)$
Follow the link below for a running regex demo which shows that the above pattern matched your test URL.
Demo

Splitting string on spaces unless in double quotes but double quotes can have a preceding string attached

I need to split a string in Java (first remove whitespaces between quotes and then split at whitespaces.)
"abc test=\"x y z\" magic=\" hello \" hola"
becomes:
firstly:
"abc test=\"xyz\" magic=\"hello\" hola"
and then:
abc
test="xyz"
magic="hello"
hola
Scenario :
I am getting a string something like above from input and I want to break it into parts as above. One way to approach was first remove the spaces between quotes and then split at spaces. Also string before quotes complicates it. Second one was split at spaces but not if inside quote and then remove spaces from individual split. I tried capturing quotes with "\"([^\"]+)\"" but I'm not able to capture just the spaces inside quotes. I tried some more but no luck.
We can do this using a formal pattern matcher. The secret sauce of the answer below is to use the not-much-used Matcher#appendReplacement method. We pause at each match, and then append a custom replacement of anything appearing inside two pairs of quotes. The custom method removeSpaces() strips all whitespace from each quoted term.
public static String removeSpaces(String input) {
return input.replaceAll("\\s+", "");
}
String input = "abc test=\"x y z\" magic=\" hello \" hola";
Pattern p = Pattern.compile("\"(.*?)\"");
Matcher m = p.matcher(input);
StringBuffer sb = new StringBuffer("");
while (m.find()) {
m.appendReplacement(sb, "\"" + removeSpaces(m.group(1)) + "\"");
}
m.appendTail(sb);
String[] parts = sb.toString().split("\\s+");
for (String part : parts) {
System.out.println(part);
}
abc
test="xyz"
magic="hello"
hola
Demo
The big caveat here, as the above comments hinted at, is that we are really using a regex engine as a rudimentary parser. To see where my solution would fail fast, just remove one of the quotes by accident from a quoted term. But, if you are sure you input is well formed as you have showed us, this answer might work for you.
I wanted to mention the java 9's Matcher.replaceAll lambda extension:
// Find quoted strings and remove there whitespace:
s = Pattern.compile("\"[^\"]*\"").matcher(s)
.replaceAll(mr -> mr.group().replaceAll("\\s", ""));
// Turn the remaining whitespace in a comma and brace all.
s = '{' + s.trim().replaceAll("\\s+", ", ") + '}';
Probably the other answer is better but still I have written it so I will post it here ;) It takes a different approach
public static void main(String[] args) {
String test="abc test=\"x y z\" magic=\" hello \" hola";
Pattern pattern = Pattern.compile("([^\\\"]+=\\\"[^\\\"]+\\\" )");
Matcher matcher = pattern.matcher(test);
int lastIndex=0;
while(matcher.find()) {
String[] parts=matcher.group(0).trim().split("=");
boolean newLine=false;
for (String string : parts[0].split("\\s+")) {
if(newLine)
System.out.println();
newLine=true;
System.out.print(string);
}
System.out.println("="+parts[1].replaceAll("\\s",""));
lastIndex=matcher.end();
}
System.out.println(test.substring(lastIndex).trim());
}
Result is
abc
test="xyz"
magic="hello"
hola
It sounds like you want to write a basic parser/Tokenizer. My bet is that after you make something that can deal with pretty printing in this structure, you will soon want to start validating that there arn't any mis-matching "'s.
But in essence, you have a few stages for this particular problem, and Java has a built in tokenizer that can prove useful.
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.stream.Collectors;
public class Q50151376{
private static class Whitespace{
Whitespace(){ }
#Override
public String toString() {
return "\n";
}
}
private static class QuotedString {
public final String string;
QuotedString(String string) {
this.string = "\"" + string.trim() + "\"";
}
#Override
public String toString() {
return string;
}
}
public static void main(String[] args) {
String test = "abc test=\"x y z\" magic=\" hello \" hola";
StringTokenizer tokenizer = new StringTokenizer(test, "\"");
boolean inQuotes = false;
List<Object> out = new LinkedList<>();
while (tokenizer.hasMoreTokens()) {
final String token = tokenizer.nextToken();
if (inQuotes) {
out.add(new QuotedString(token));
} else {
out.addAll(TokenizeWhitespace(token));
}
inQuotes = !inQuotes;
}
System.out.println(joinAsStrings(out));
}
private static String joinAsStrings(List<Object> out) {
return out.stream()
.map(Object::toString)
.collect(Collectors.joining());
}
public static List<Object> TokenizeWhitespace(String in){
List<Object> out = new LinkedList<>();
StringTokenizer tokenizer = new StringTokenizer(in, " ", true);
boolean ignoreWhitespace = false;
while (tokenizer.hasMoreTokens()){
String token = tokenizer.nextToken();
boolean whitespace = token.equals(" ");
if(!whitespace){
out.add(token);
ignoreWhitespace = false;
} else if(!ignoreWhitespace) {
out.add(new Whitespace());
ignoreWhitespace = true;
}
}
return out;
}
}

Need help understanding why this Regex doesn't work

The homework assignment says I have to write code that validates dates in yyyy/mm/dd format.
It asks that I first check the input String so that the first part, the year is exactly 4 numbers and month is between 1 and 2 (inclusive). And if it doesn't match that criteria, i throw an exception called "InvalidDateException", (I've already wrote the class for that)
So my given example is 2016/05/12 should be considered a valid date.
Looking into how Regex works, I come to the conclusion that I would need \\d+ so that java can find numbers.
Here's my code (variable date is a String, instantiated in the method that contains this code):
int yr = date.substring(0, date.indexOf("/")).length();
int mo = date.substring(date.indexOf("/")+1, date.lastIndexOf("/")).length();
if (date.matches("\\d+") && (yr == 4) && (mo <= 2 && mo >= 1)) {
//I've put code here that outputs it as a valid date
}
So then if I put 2016/05/12, it should say that it's a valid date, however it instead goes to my error message of "InvalidDateException"
I've looked through the other regex questions on StackOverflow but I can't seem to find out why my code doesn't work.
any help is appreciated
Example 1
This would give you a straight-forward solution but you'd still need to parse the String for its components.
Pattern pattern = Pattern.compile("\\d{4}/\\d{1,2}/\\d{1,2}");
Matcher matcher = pattern.matcher(input);
if (matcher.matches())
{
// Some code here to extract the year/month/day...
}
Example 2
A better way is to group the results (with parenthesis).
Pattern pattern = Pattern.compile("(\\d{4})/(\\d{1,2})/(\\d{1,2})");
Matcher matcher = pattern.matcher(input);
if (matcher.matches())
{
int year = Integer.valueOf(matcher.group(1)); // First group
int month = Integer.valueOf(matcher.group(2)); // Second group
int day = Integer.valueOf(matcher.group(3)); // Third group
// Some code here...
}
Example 3
An even better way is to name the grouped results.
Pattern pattern = Pattern.compile("(?<year>\\d{4})/(?<month>\\d{1,2})/(?<day>\\d{1,2})");
Matcher matcher = pattern.matcher(input);
if (matcher.matches())
{
int year = Integer.valueOf(matcher.group("year")); // "year" group
int month = Integer.valueOf(matcher.group("month")); // "month" group
int day = Integer.valueOf(matcher.group("day")); // "day" group
// Some code here...
}
Example 4.a
You could use a regex builder class. This is beneficial as it has some re-usability.
public class Regex {
private StringBuilder regexBuilder = new StringBuilder();
private final String input;
private Regex(String input) {
this.input = input;
}
public static Regex of(String input) {
return new Regex(input);
}
public Regex append(String regex) {
regexBuilder.append(regex);
return this;
}
public Regex group(String groupName, String regex) {
regexBuilder.append("(?<")
.append(groupName)
.append(">")
.append(regex)
.append(")");
return this;
}
public Matcher matcher() {
return Pattern.compile(regexBuilder.toString()).matcher(input);
}
}
Example 4.b
Using the builder...
final String yearGroup = "year";
final String monthGroup = "month";
final String dayGroup = "day";
Matcher matcher =
Regex.of(input)
.group(yearGroup, "\\d{4}")
.append("/")
.group(monthGroup, "\\d{1,2}")
.append("/")
.group(dayGroup, "\\d{1,2}")
.matcher();
if (matcher.matches())
{
int year = Integer.valueOf(matcher.group(yearGroup)); // "year" group
int month = Integer.valueOf(matcher.group(monthGroup)); // "month" group
int day = Integer.valueOf(matcher.group(dayGroup)); // "day" group
// Some code here...
}
Split solution is good if you need to make further complicated validations.
public boolean isDateValid (String date) {
String[] dateElements = date.split("/");
if (dateElements.length == 3)
return isDateElementsValid(dateElements);
else
throw new RuntimeException();
}
public boolean isDateElementsValid(String[] dateElements){
String year = dateElements[0];
String month = dateElements[1];
String day = dateElements[2];
return isYearValid(year) && isMonthValid(month) && isDayValid(day);
}
Regex is good to have less code.
public boolean isDateValid (String date) {
if (date.matches("\\d{4}/\\d{1,2}/\\d{1,2}"))
return true;
else
throw new RuntimeException();
}
*Replace RuntimeException with custom implementation. Best practice will be to extend custom exception from RuntimeException.

Using regular expression to find a set number of + JAVA

I have a program where I want to filter Strings with a set number of "+"'s at the beginning.
For example:
+++Adam is working very well.
++Adam is working well.
+Adam is doing OK.
How do I only pick up each particular case (i.e. only one plus sign, only two plus signs, only three plus signs)? I usually get a return of anything beginning with a +.
I have the following regex patterns compiled, but I either get only one return (usually the two ++) or all of them:
public static String regexpluschar = "^\\Q+\\E{1}[\\w <]";
public static String regexpluspluschar = "^\\Q+\\E{2}[\\w <]";
public static String regexpluspluspluschar = "^\\Q+\\E{3}[\\w <]";
Pattern plusplusplus = Pattern.compile(regexpluspluspluschar);
Pattern plusplus = Pattern.compile(regexpluspluschar);
Pattern plus = Pattern.compile(regexpluschar);
I then try to find using a Matcher class - I've used .find() and .matches() but don't get the result I'm after (java+regex newbie alert here).
Matcher matcherplusplusplus = plusplusplus.matcher(check);
Matcher matcherplusplus = plusplus.matcher(check);
Matcher matcherplus = plus.matcher(check);
//OK we have 3+'s
if ((matcherplusplusplus.find())==true){
System.out.println("Filtering 3 +s.");
System.out.println("filter is " + filter + " in the 3 + filter.");
String toChange = getItem(i);
setItemFiltered(i, toChange);
}
//OK - we have 2 +'s
if ((matcherplusplus.find())==true){
System.out.println("Filtering 2 +s.");
System.out.println("filter is " + filter + " in the 2 + filter.");
String toChange = getItem(i);
setItemFiltered(i, toChange);
}
//OK - we have 1 +'s
if ((matcherplus.find())==true){
System.out.println("Filtering 1 +.");
System.out.println("filter is " + filter + " in the 1 + filter.");
String toChange = getItem(i);
setItemFiltered(i, toChange);
}
For the very curious, the above if's are embedded in a for loop that cycles around some JTextFields. Full code at: http://pastebin.ca/2199327
Why not simpler :
public static String regexpluschar = "^\\+[\\w <]";
public static String regexpluspluschar = "^\\+{2}[\\w <]";
public static String regexpluspluspluschar = "^\\+{3}[\\w <]";
or even
public static String regexpluschar = "^\\+[^\\+]";
public static String regexpluspluschar = "^\\+{2}[^\\+]";
public static String regexpluspluspluschar = "^\\+{3}[^\\+]";
Edit : It's working on my test program, but I had to removed your specific code :
String toChange = getItem(i);
setItemFiltered(i, toChange);
proof : my output is :
Filtering 3 +s.
+++Adam is working very well. is in the 3 + filter.
Filtering 2 +s.
++Adam is working well. is in the 2 + filter.
Filtering 1 +.
+Adam is doing OK. is in the 1 + filter.
Your filter is working, but you specific code may not... (maybe have a look at setItemFiltered?)
I was thinking something like this would be easier:
public static void main(String[] args) {
Pattern pattern = Pattern.compile("^(\\+{1,3}).*");
Matcher matcher = pattern.matcher(<your text>);
if (matcher.matches()) {
String pluses = matcher.group(1);
switch (pluses.length()) {
}
}
}
And if you want to be sure that ++++This is insane does not match then change the pattern to
Pattern pattern = Pattern.compile("^(\\+{1,3})[^+].*");

Java Pattern match

I've a long template from which I need to extract certain strings based on certain patterns. When I went through some examples I found that use of quantifiers is good in such situations.For example following is my template, from which I need to extract while and doWhile.
This is a sample document.
$while($variable)This text can be repeated many times until do while is called.$endWhile.
Some sample text follows this.
$while($variable2)This text can be repeated many times until do while is called.$endWhile.
Some sample text.
I need to extract the whole text, starting from $while($variable) till $endWhile. I then need to process the value of $variable. After that I need to insert the text between $while and $endWhile to the original text.
I've the logic of extracting the variable. But I'm not sure how to use quantifiers or pattern match here.
Can someone please provide me a sample code for this? Any help will be greatly appreciated
You can use a rather simple regex-based solution here with a Matcher:
Pattern pattern = Pattern.compile("\\$while\\((.*?)\\)(.*?)\\$endWhile", Pattern.DOTALL);
Matcher matcher = pattern.matcher(yourString);
while(matcher.find()){
String variable = matcher.group(1); // this will include the $
String value = matcher.group(2);
// now do something with variable and value
}
If you want to replace the variables in the original text, you should use the Matcher.appendReplacement() / Matcher.appendTail() solution:
Pattern pattern = Pattern.compile("\\$while\\((.*?)\\)(.*?)\\$endWhile", Pattern.DOTALL);
Matcher matcher = pattern.matcher(yourString);
StringBuffer sb = new StringBuffer();
while(matcher.find()){
String variable = matcher.group(1); // this will include the $
String value = matcher.group(2);
// now do something with variable and value
matcher.appendReplacement(sb, value);
}
matcher.appendTail(sb);
Reference:
Methods of the Pattern Class
(Sun Java Tutorial)
Methods of the Matcher Class
(Sun Java Tutorial)
Pattern JavaDoc
Matcher JavaDoc
public class PatternInString {
static String testcase1 = "what i meant here";
static String testcase2 = "here";
public static void main(String args[])throws StringIndexOutOfBoundsException{
PatternInString testInstance= new PatternInString();
boolean result = testInstance.occurs(testcase1,testcase2);
System.out.println(result);
}
//write your code here
public boolean occurs(String str1, String str2)throws StringIndexOutOfBoundsException
{ int i;
boolean result=false;
int num7=str1.indexOf(" ");
int num8=str1.lastIndexOf(" ");
String str6=str1.substring(num8+1);
String str5=str1.substring(0,num7);
if(str5.equals(str2))
{
result=true;
}
else if(str6.equals(str2))
{
result=true;
}
int num=-1;
try
{
for(i=0;i<str1.length()-1;i++)
{ num=num+1;
num=str1.indexOf(" ",num);
int num1=str1.indexOf(" ",num+1);
String str=str1.substring(num+1,num1);
if(str.equals(str2))
{
result=true;
break;
}
}
}
catch(Exception e)
{
}
return result;
}
}

Categories

Resources