diff --git a/docs/dsa/linkedlist/LinkedList.md b/docs/dsa/linkedlist/LinkedList.md
new file mode 100644
index 000000000..e002a1880
--- /dev/null
+++ b/docs/dsa/linkedlist/LinkedList.md
@@ -0,0 +1,695 @@
+---
+id: linkedlist-in-dsa
+title: LinkedList in Data Structures and Algorithms
+sidebar_label: LinkedList
+sidebar_position: 2
+description: "A linked list is a linear data structure in which elements are not stored in contiguous memory locations. Instead, each element, called a node, contains a data part and a reference (or link) to the next node in the sequence. Linked lists are used in various applications such as dynamic memory allocation, implementation of data structures like stacks and queues, and more."
+tags:
+ [
+ dsa,
+ data-structures,
+ linkedlist,
+ linked-list,
+ linkedlist-data-structure,
+ linkedlist-in-dsa,
+ linkedlist-in-data-structure,
+ linkedlist-in-algorithm,
+ linkedlist-in-dsa-example,
+ linkedlist-in-dsa-explanation,
+ linkedlist-in-dsa-conclusion,
+ linkedlist-in-dsa-importance,
+ linkedlist-in-dsa-syntax,
+ linkedlist-in-dsa-declaration,
+ linkedlist-in-dsa-access,
+ linkedlist-in-dsa-update,
+ linkedlist-in-dsa-insertion,
+ linkedlist-in-dsa-deletion,
+ linkedlist-in-dsa-traversal,
+ linkedlist-in-dsa-program,
+ linkedlist-in-dsa-code,
+ linkedlist-in-dsa-js,
+ linkedlist-in-dsa-java,
+ linkedlist-in-dsa-python,
+ linkedlist-in-dsa-c,
+ linkedlist-in-dsa-cpp,
+ linkedlist-in-dsa-ts,
+ ]
+---
+
+A linked list is a linear data structure in which elements are not stored in contiguous memory locations. Instead, each element, called a node, contains a data part and a reference (or link) to the next node in the sequence. Linked lists are used in various applications such as dynamic memory allocation, implementation of data structures like stacks and queues, and more.
+
+## Why are Linked Lists important?
+
+Linked lists are important because they provide a flexible way to store and manipulate data. They allow for efficient insertion and deletion of elements, which can be particularly useful in applications where the size of the data set changes frequently.
+
+## How to declare a Linked List?
+
+A linked list can be declared in various programming languages using the following syntax:
+
+# LinkedList in Data Structures and Algorithms (DSA)
+
+## Introduction
+
+A linked list is a fundamental data structure in computer science that represents a sequence of nodes. Each node contains data and a reference to the next node in the sequence.
+
+## Types of Linked Lists
+
+- **Singly Linked List**: Each node points to the next node and the last node points to null.
+- **Doubly Linked List**: Each node points to both the next and the previous nodes.
+- **Circular Linked List**: The last node points to the first node, forming a circle.
+- **Circular Doubly Linked List**: Combines properties of both circular and doubly linked lists.
+
+## Basic Operations
+
+- **Insertion**: Adding a node to the linked list.
+- **Deletion**: Removing a node from the linked list.
+- **Traversal**: Accessing each node of the linked list.
+- **Search**: Finding a node with a specific value.
+- **Update**: Modifying the value of an existing node.
+
+## Why are Linked Lists important?
+
+Linked lists are important because they provide a flexible way to store and manipulate data. They allow for efficient insertion and deletion of elements, which can be particularly useful in applications where the size of the data set changes frequently.
+
+## How to declare a Linked List?
+
+A linked list can be declared in various programming languages using the following syntax:
+
+
+
+
+ ```js
+ // Node class in JavaScript
+ class Node {
+ constructor(data) {
+ this.data = data;
+ this.next = null;
+ }
+ }
+
+ // LinkedList class in JavaScript
+ class LinkedList {
+ constructor() {
+ this.head = null;
+ }
+
+ // Add a node at the end
+ append(data) {
+ let newNode = new Node(data);
+ if (this.head === null) {
+ this.head = newNode;
+ return;
+ }
+ let current = this.head;
+ while (current.next) {
+ current = current.next;
+ }
+ current.next = newNode;
+ }
+ }
+ ```
+
+
+
+ ```java
+ // Node class in Java
+ class Node {
+ int data;
+ Node next;
+ Node(int d) { data = d; next = null; }
+ }
+
+ // LinkedList class in Java
+ public class LinkedList {
+ Node head;
+
+ // Add a node at the end
+ public void append(int data) {
+ Node newNode = new Node(data);
+ if (head == null) {
+ head = newNode;
+ return;
+ }
+ Node current = head;
+ while (current.next != null) {
+ current = current.next;
+ }
+ current.next = newNode;
+ }
+ }
+ ```
+
+
+
+ ```python
+ # Node class in Python
+ class Node:
+ def __init__(self, data):
+ self.data = data
+ self.next = None
+
+ # LinkedList class in Python
+ class LinkedList:
+ def __init__(self):
+ self.head = None
+
+ # Add a node at the end
+ def append(self, data):
+ new_node = Node(data)
+ if self.head is None:
+ self.head = new_node
+ return
+ last = self.head
+ while last.next:
+ last = last.next
+ last.next = new_node
+ ```
+
+
+
+ ```c
+ // Node structure in C
+ struct Node {
+ int data;
+ struct Node* next;
+ };
+
+ // LinkedList structure in C
+ struct LinkedList {
+ struct Node* head;
+ };
+
+ // Function to create a new node
+ struct Node* createNode(int data) {
+ struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
+ newNode->data = data;
+ newNode->next = NULL;
+ return newNode;
+ }
+
+ // Function to add a node at the end
+ void append(struct LinkedList* list, int data) {
+ struct Node* newNode = createNode(data);
+ if (list->head == NULL) {
+ list->head = newNode;
+ return;
+ }
+ struct Node* temp = list->head;
+ while (temp->next != NULL) {
+ temp = temp->next;
+ }
+ temp->next = newNode;
+ }
+ ```
+
+
+
+ ```cpp
+ // Node class in C++
+ class Node {
+ public:
+ int data;
+ Node* next;
+ Node(int d) { data = d; next = nullptr; }
+ };
+
+ // LinkedList class in C++
+ class LinkedList {
+ public:
+ Node* head;
+ LinkedList() { head = nullptr; }
+
+ // Add a node at the end
+ void append(int data) {
+ Node* newNode = new Node(data);
+ if (head == nullptr) {
+ head = newNode;
+ return;
+ }
+ Node* current = head;
+ while (current->next != nullptr) {
+ current = current->next;
+ }
+ current->next = newNode;
+ }
+ };
+ ```
+
+
+
+ ```ts
+ // Node class in TypeScript
+ class Node {
+ data: number;
+ next: Node | null;
+
+ constructor(data: number) {
+ this.data = data;
+ this.next = null;
+ }
+ }
+
+ // LinkedList class in TypeScript
+ class LinkedList {
+ head: Node | null;
+
+ constructor() {
+ this.head = null;
+ }
+
+ // Add a node at the end
+ append(data: number): void {
+ let newNode = new Node(data);
+ if (this.head === null) {
+ this.head = newNode;
+ return;
+ }
+ let current = this.head;
+ while (current.next !== null) {
+ current = current.next;
+ }
+ current.next = newNode;
+ }
+ }
+ ```
+
+
+
+## How to access a Linked List?
+
+A linked list can be accessed by traversing the nodes starting from the head.
+
+
+
+
+ ```js
+ // Access elements in a LinkedList in JavaScript
+ let list = new LinkedList();
+ list.append(10);
+ list.append(20);
+ list.append(30);
+
+ let current = list.head;
+ while (current !== null) {
+ console.log(current.data);
+ current = current.next;
+ }
+ ```
+
+
+
+ ```java
+ // Access elements in a LinkedList in Java
+ LinkedList list = new LinkedList();
+ list.append(10);
+ list.append(20);
+ list.append(30);
+
+ Node current = list.head;
+ while (current != null) {
+ System.out.println(current.data);
+ current = current.next;
+ }
+ ```
+
+
+
+ ```python
+ # Access elements in a LinkedList in Python
+ list = LinkedList()
+ list.append(10)
+ list.append(20)
+ list.append(30)
+
+ current = list.head
+ while current:
+ print(current.data)
+ current = current.next
+ ```
+
+
+
+ ```c
+ // Access elements in a LinkedList in C
+ struct LinkedList list;
+ list.head = NULL;
+ append(&list, 10);
+ append(&list, 20);
+ append(&list, 30);
+
+ struct Node* current = list.head;
+ while (current != NULL) {
+ printf("%d\n", current->data);
+ current = current->next;
+ }
+ ```
+
+
+
+ ```cpp
+ // Access elements in a LinkedList in C++
+ LinkedList list;
+ list.append(10);
+ list.append(20);
+ list.append(30);
+
+ Node* current = list.head;
+ while (current != nullptr) {
+ std::cout << current->data << std::endl;
+ current = current->next;
+ }
+ ```
+
+
+
+ ```ts
+ // Access elements in a LinkedList in TypeScript
+ let list = new LinkedList();
+ list.append(10);
+ list.append(20);
+ list.append(30);
+
+ let current = list.head;
+ while (current !== null) {
+ console.log(current.data);
+ current = current.next;
+ }
+ ```
+
+
+
+## How to update a Linked List?
+
+A linked list can be updated by changing the data of a node directly.
+
+
+
+
+ ```js
+ // Update elements in a LinkedList in JavaScript
+ let list = new LinkedList();
+ list.append(10);
+ list.append(20);
+ list.append(30);
+
+ let current = list.head;
+ while (current !== null) {
+ if (current.data === 20) {
+ current.data = 25;
+ }
+ current = current.next;
+ }
+ ```
+
+
+
+ ```java
+ // Update elements in a LinkedList in Java
+ LinkedList list = new LinkedList();
+ list.append(10);
+ list.append(20);
+ list.append(30);
+
+ Node current = list.head;
+ while (current != null) {
+ if (current.data == 20) {
+ current.data = 25;
+ }
+ current = current.next;
+ }
+ ```
+
+
+
+ ```python
+ # Update elements in a LinkedList in Python
+ list = LinkedList()
+ list.append(10)
+ list.append(20)
+ list.append(30)
+
+ current = list.head
+ while current:
+ if current.data == 20:
+ current.data = 25
+ current = current.next
+ ```
+
+
+
+ ```c
+ // Update elements in a LinkedList in C
+ struct LinkedList list;
+ list.head = NULL;
+ append(&list, 10);
+ append(&list, 20);
+ append(&list, 30);
+
+ struct Node* current = list.head;
+ while (current != NULL) {
+ if (current->data == 20) {
+ current->data = 25;
+ }
+ current = current->next;
+ }
+ ```
+
+
+
+ ```cpp
+ // Update elements in a LinkedList in C++
+ LinkedList list;
+ list.append(10);
+ list.append(20);
+ list.append(30);
+
+ Node* current = list.head;
+ while (current != nullptr) {
+ if (current->data == 20) {
+ current->data = 25;
+ }
+ current = current->next;
+ }
+ ```
+
+
+
+ ```ts
+ // Update elements in a LinkedList in TypeScript
+ let list = new LinkedList();
+ list.append(10);
+ list.append(20);
+ list.append(30);
+
+ let current = list.head;
+ while (current !== null) {
+ if (current.data === 20) {
+ current.data = 25;
+ }
+ current = current.next;
+ }
+ ```
+
+
+
+## How to delete a node from a Linked List?
+
+A node can be deleted from a linked list by adjusting the links of the adjacent nodes.
+
+
+
+
+ ```js
+ // Delete a node from a LinkedList in JavaScript
+ class LinkedList {
+ // ...
+ delete(data) {
+ if (this.head === null) return;
+ if (this.head.data === data) {
+ this.head = this.head.next;
+ return;
+ }
+ let current = this.head;
+ while (current.next !== null) {
+ if (current.next.data === data) {
+ current.next = current.next.next;
+ return;
+ }
+ current = current.next;
+ }
+ }
+ }
+ ```
+
+
+
+ ```java
+ // Delete a node from a LinkedList in Java
+ public class LinkedList {
+ // ...
+ public void delete(int data) {
+ if (head == null) return;
+ if (head.data == data) {
+ head = head.next;
+ return;
+ }
+ Node current = head;
+ while (current.next != null) {
+ if (current.next.data == data) {
+ current.next = current.next.next;
+ return;
+ }
+ current = current.next;
+ }
+ }
+ }
+ ```
+
+
+
+ ```python
+ # Delete a node from a LinkedList in Python
+ class LinkedList:
+ # ...
+ def delete(self, data):
+ if self.head is None:
+ return
+ if self.head.data == data:
+ self.head = self.head.next
+ return
+ current = self.head
+ while current.next:
+ if current.next.data == data:
+ current.next = current.next.next
+ return
+ current = current.next
+ ```
+
+
+
+ ```c
+ // Delete a node from a LinkedList in C
+ void deleteNode(struct LinkedList* list, int data) {
+ if (list->head == NULL) return;
+ struct Node* temp = list->head;
+ if (temp->data == data) {
+ list->head = temp->next;
+ free(temp);
+ return;
+ }
+ struct Node* prev = NULL;
+ while (temp != NULL && temp->data != data) {
+ prev = temp;
+ temp = temp->next;
+ }
+ if (temp == NULL) return;
+ prev->next = temp->next;
+ free(temp);
+ }
+ ```
+
+
+
+ ```cpp
+ // Delete a node from a LinkedList in C++
+ class LinkedList {
+ // ...
+ void deleteNode(int data) {
+ if (head == nullptr) return;
+ Node* temp = head;
+ if (temp->data == data) {
+ head = temp->next;
+ delete temp;
+ return;
+ }
+ Node* prev = nullptr;
+ while (temp != nullptr && temp->data != data) {
+ prev = temp;
+ temp = temp->next;
+ }
+ if (temp == nullptr) return;
+ prev->next = temp->next;
+ delete temp;
+ }
+ };
+ ```
+
+
+
+ ```ts
+ // Delete a node from a LinkedList in TypeScript
+ class LinkedList {
+ // ...
+ delete(data: number) {
+ if (this.head === null) return;
+ if (this.head.data === data) {
+ this.head = this.head.next;
+ return;
+ }
+ let current = this.head;
+ while (current.next !== null) {
+ if (current.next.data === data) {
+ current.next = current.next.next;
+ return;
+ }
+ current = current.next;
+ }
+ }
+ }
+ ```
+
+
+
+## Applications of Linked Lists
+
+- **Dynamic memory allocation**: Linked lists can efficiently manage memory allocation and deallocation.
+- **Implementation of stacks and queues**: Linked lists provide the foundation for stack and queue data structures.
+- **Graph representation**: Adjacency lists use linked lists to represent graphs.
+- **Handling sparse matrices**: Linked lists efficiently store and manipulate sparse matrices.
+
+## Common Linked List Problems
+
+- **Reverse a Linked List**: Reversing the nodes of a linked list.
+- **Detect a cycle in a Linked List**: Checking if a linked list contains a cycle.
+- **Merge two sorted Linked Lists**: Combining two sorted linked lists into one sorted linked list.
+- **Find the middle of a Linked List**: Finding the middle node in a linked list.
+
+## Advanced Linked List Variants
+
+- **Doubly Linked List**: A linked list where each node has references to both the next and previous nodes.
+- **Circular Linked List**: A linked list where the last node points back to the first node.
+- **Skip List**: A linked list with additional pointers for faster search.
+
+## Resources and References
+
+- **Books**:
+ - "Introduction to Algorithms" by Cormen, Leiserson, Rivest, and Stein
+ - "Data Structures and Algorithm Analysis in C" by Mark Allen Weiss
+- **Online Courses**:
+ - Coursera: Data Structures and Algorithms Specialization
+ - edX: Data Structures Fundamentals
+- **Websites**:
+ - [GeeksforGeeks](https://www.geeksforgeeks.org)
+ - [LeetCode](https://leetcode.com)
+ - [HackerRank](https://www.hackerrank.com)
+
+---
+
+By understanding and mastering these linked list concepts and algorithms, you will be well-equipped to tackle a wide range of problems in data structures and algorithms.
+
+## Conclusion
+
+Linked lists are a fundamental data structure in computer science and play a crucial role in various applications and algorithms. This guide covers the essential concepts and operations associated with linked lists, providing a comprehensive understanding of how they work and how to implement them in different programming languages.
+
+Understanding linked lists is crucial for solving numerous problems in computer science, from basic data manipulation to complex algorithms in dynamic memory allocation, graph representation, and more. The examples provided demonstrate how to work with linked lists efficiently, ensuring a robust foundation for tackling more advanced DSA concepts. Mastery of linked lists enhances your ability to handle data structures and perform operations crucial in both everyday programming and competitive coding.
+
+Problems for Practice
+To further practice and test your understanding of linked lists, consider solving the following problems from LeetCode:
+
+1. Reverse Linked List
+2. Linked List Cycle
+3. Merge Two Sorted Lists
+4. Remove Nth Node From End of List
+5. Add Two Numbers
+
+Engaging with these problems will help reinforce the concepts learned and provide practical experience in using linked lists effectively. By practicing these problems, you will enhance your problem-solving skills and deepen your understanding of linked list manipulation in various contexts.
diff --git a/docs/dsa/linkedlist/LinkedListProblems.md b/docs/dsa/linkedlist/LinkedListProblems.md
new file mode 100644
index 000000000..5c727033b
--- /dev/null
+++ b/docs/dsa/linkedlist/LinkedListProblems.md
@@ -0,0 +1,146 @@
+---
+id: leetcode-linkedlist-problems
+title: LeetCode LinkedList Problems
+sidebar_label: LinkedList Problems
+sidebar_position: 1
+description: "A collection of easy, medium, and hard LinkedList problems from LeetCode to help you practice and master LinkedList concepts in Data Structures and Algorithms."
+tags:
+ [
+ dsa,
+ data-structures,
+ linkedlist,
+ leetcode,
+ linkedlist-problems,
+ linkedlist-in-dsa,
+ linkedlist-in-data-structure,
+ linkedlist-in-algorithm,
+ linkedlist-in-dsa-example,
+ linkedlist-in-dsa-explanation,
+ linkedlist-in-dsa-conclusion,
+ linkedlist-in-dsa-importance,
+ linkedlist-in-dsa-syntax,
+ linkedlist-in-dsa-declaration,
+ linkedlist-in-dsa-access,
+ linkedlist-in-dsa-update,
+ linkedlist-in-dsa-delete,
+ linkedlist-in-dsa-iterate,
+ linkedlist-in-dsa-max-min,
+ linkedlist-in-dsa-program,
+ linkedlist-in-dsa-code,
+ linkedlist-in-dsa-js,
+ linkedlist-in-dsa-java,
+ linkedlist-in-dsa-python,
+ linkedlist-in-dsa-c,
+ linkedlist-in-dsa-cpp,
+ linkedlist-in-dsa-ts,
+ ]
+---
+
+# LeetCode LinkedList Problems
+
+## Easy Problems
+
+1. [Reverse Linked List](https://leetcode.com/problems/reverse-linked-list/)
+
+ - Problem: Reverse a singly linked list.
+ - LeetCode ID: 206
+
+2. [Remove Linked List Elements](https://leetcode.com/problems/remove-linked-list-elements/)
+
+ - Problem: Remove all elements from a linked list of integers that have value val.
+ - LeetCode ID: 203
+
+3. [Palindrome Linked List](https://leetcode.com/problems/palindrome-linked-list/)
+
+ - Problem: Check if a linked list is a palindrome.
+ - LeetCode ID: 234
+
+4. [Merge Two Sorted Lists](https://leetcode.com/problems/merge-two-sorted-lists/)
+
+ - Problem: Merge two sorted linked lists and return it as a new sorted list.
+ - LeetCode ID: 21
+
+5. [Linked List Cycle](https://leetcode.com/problems/linked-list-cycle/)
+
+ - Problem: Determine if a linked list has a cycle.
+ - LeetCode ID: 141
+
+6. [Remove Duplicates from Sorted List](https://leetcode.com/problems/remove-duplicates-from-sorted-list/)
+
+ - Problem: Delete all duplicates such that each element appears only once.
+ - LeetCode ID: 83
+
+7. [Intersection of Two Linked Lists](https://leetcode.com/problems/intersection-of-two-linked-lists/)
+ - Problem: Find the node at which the intersection of two singly linked lists begins.
+ - LeetCode ID: 160
+
+## Medium Problems
+
+1. [Add Two Numbers](https://leetcode.com/problems/add-two-numbers/)
+
+ - Problem: Add two numbers represented by linked lists.
+ - LeetCode ID: 2
+
+2. [Odd Even Linked List](https://leetcode.com/problems/odd-even-linked-list/)
+
+ - Problem: Group all odd nodes together followed by the even nodes.
+ - LeetCode ID: 328
+
+3. [Remove Nth Node From End of List](https://leetcode.com/problems/remove-nth-node-from-end-of-list/)
+
+ - Problem: Remove the nth node from the end of the list.
+ - LeetCode ID: 19
+
+4. [Reorder List](https://leetcode.com/problems/reorder-list/)
+
+ - Problem: Reorder the list to follow a specific order.
+ - LeetCode ID: 143
+
+5. [Rotate List](https://leetcode.com/problems/rotate-list/)
+
+ - Problem: Rotate the list to the right by k places.
+ - LeetCode ID: 61
+
+6. [Swap Nodes in Pairs](https://leetcode.com/problems/swap-nodes-in-pairs/)
+
+ - Problem: Swap every two adjacent nodes.
+ - LeetCode ID: 24
+
+7. [Partition List](https://leetcode.com/problems/partition-list/)
+ - Problem: Partition the list so that nodes less than x come before nodes greater than or equal to x.
+ - LeetCode ID: 86
+
+## Hard Problems
+
+1. [Merge k Sorted Lists](https://leetcode.com/problems/merge-k-sorted-lists/)
+
+ - Problem: Merge k sorted linked lists and return it as one sorted list.
+ - LeetCode ID: 23
+
+2. [Reverse Nodes in k-Group](https://leetcode.com/problems/reverse-nodes-in-k-group/)
+
+ - Problem: Reverse the nodes of a linked list k at a time.
+ - LeetCode ID: 25
+
+3. [Copy List with Random Pointer](https://leetcode.com/problems/copy-list-with-random-pointer/)
+
+ - Problem: A linked list with a random pointer, deep copy the list.
+ - LeetCode ID: 138
+
+4. [LRU Cache](https://leetcode.com/problems/lru-cache/)
+
+ - Problem: Design and implement a data structure for Least Recently Used (LRU) cache.
+ - LeetCode ID: 146
+
+5. [Flatten a Multilevel Doubly Linked List](https://leetcode.com/problems/flatten-a-multilevel-doubly-linked-list/)
+
+ - Problem: Flatten a multilevel doubly linked list.
+ - LeetCode ID: 430
+
+6. [Linked List Random Node](https://leetcode.com/problems/linked-list-random-node/)
+ - Problem: Return a random node's value from the linked list.
+ - LeetCode ID: 382
+
+## Conclusion
+
+Practicing these problems will help reinforce the concepts learned and provide practical experience in using linked lists effectively. By solving these problems, you will enhance your problem-solving skills and deepen your understanding of linked list manipulation in various contexts.
diff --git a/docs/dsa/linkedlist/_category_.json b/docs/dsa/linkedlist/_category_.json
new file mode 100644
index 000000000..471f3ca54
--- /dev/null
+++ b/docs/dsa/linkedlist/_category_.json
@@ -0,0 +1,8 @@
+{
+ "label": "LinkedList",
+ "position": 9,
+ "link": {
+ "type": "generated-index",
+ "description": "In data structures, Linked List is basically chains of nodes where each node contains information such as data and a pointer to the next node in the chain. It is a popular data structure with a wide range of real-world applications. In this article, we will provide a complete introduction of Linked List, which will help you tackle any problem based on Linked List."
+ }
+}
diff --git a/dsa-solutions/lc-solutions/0000-0099/0017-Letter-Combinations-of-a-Phone-Number.md b/dsa-solutions/lc-solutions/0000-0099/0017-Letter-Combinations-of-a-Phone-Number.md
index fd6fed234..890c371f1 100644
--- a/dsa-solutions/lc-solutions/0000-0099/0017-Letter-Combinations-of-a-Phone-Number.md
+++ b/dsa-solutions/lc-solutions/0000-0099/0017-Letter-Combinations-of-a-Phone-Number.md
@@ -314,4 +314,4 @@ Here's a step-by-step algorithm for generating all possible letter combinations
- Call the backtracking function with the initial index set to 0 and an empty string as the initial combination.
- Return the list of combinations.
-This algorithm ensures that all possible combinations are generated by exploring all valid paths through backtracking.
+This algorithm ensures that all possible combinations are generated by exploring all valid paths through backtracking.
\ No newline at end of file