ブックマークサイト.html

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ブックマークサイト</title>
    <style>
        :root {
            --bg-color: #f4f4f9;
            --text-color: #000;
            --link-color: #007bff;
            --btn-bg-color: #007bff;
            --btn-hover-color: #0056b3;
            --delete-btn-bg-color: #dc3545;
            --delete-btn-hover-color: #c82333;
        }

        [data-theme="dark"] {
            --bg-color: #2e2e2e;
            --text-color: #fff;
            --link-color: #66b2ff;
            --btn-bg-color: #0056b3;
            --btn-hover-color: #007bff;
            --delete-btn-bg-color: #c82333;
            --delete-btn-hover-color: #dc3545;
        }

        body {
            font-family: Arial, sans-serif;
            margin: 20px;
            padding: 0;
            background-color: var(--bg-color);
            color: var(--text-color);
            transition: background-color 0.3s, color 0.3s;
        }
        .container {
            max-width: 800px;
            margin: auto;
            padding: 20px;
            background: #fff;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
            border-radius: 8px;
            background-color: var(--bg-color);
            color: var(--text-color);
            transition: background-color 0.3s, color 0.3s;
        }
        .bookmark-form {
            display: flex;
            flex-direction: column;
            gap: 10px;
            margin-bottom: 20px;
        }
        .bookmark-form input, .bookmark-form select {
            padding: 10px;
            font-size: 16px;
            border: 1px solid #ddd;
            border-radius: 5px;
            background-color: var(--bg-color);
            color: var(--text-color);
        }
        .bookmark-form button {
            padding: 10px;
            font-size: 16px;
            background-color: var(--btn-bg-color);
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
        }
        .bookmark-form button:hover {
            background-color: var(--btn-hover-color);
        }
        .bookmark-list {
            list-style-type: none;
            padding: 0;
        }
        .bookmark-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin: 10px 0;
            padding: 10px;
            border: 1px solid #ddd;
            border-radius: 5px;
            background-color: #fafafa;
            background-color: var(--bg-color);
            color: var(--text-color);
        }
        .bookmark-item a {
            text-decoration: none;
            color: var(--link-color);
        }
        .bookmark-item button {
            padding: 5px 10px;
            font-size: 14px;
            background-color: var(--delete-btn-bg-color);
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
        }
        .bookmark-item button:hover {
            background-color: var(--delete-btn-hover-color);
        }
        .controls {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
        }
    </style>
</head>
<body data-theme="light">

    <div class="container">
        <h1>ブックマークサイト</h1>
        
        <div class="controls">
            <input type="text" id="search-bar" placeholder="ブックマークを検索" oninput="filterBookmarks()">
            <select id="category-filter" onchange="filterByCategory()">
                <option value="all">すべてのカテゴリー</option>
            </select>
            <button onclick="toggleTheme()">ダークモード切り替え</button>
        </div>

        <div class="bookmark-form">
            <input type="text" id="bookmark-title" placeholder="タイトルを入力してください" required>
            <input type="url" id="bookmark-url" placeholder="URLを入力してください" required>
            <input type="text" id="bookmark-category" placeholder="カテゴリーを入力してください">
            <button onclick="addBookmark()">ブックマークを追加</button>
        </div>

        <ul id="bookmark-list" class="bookmark-list"></ul>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', loadBookmarks);

        function loadBookmarks() {
            const bookmarks = JSON.parse(localStorage.getItem('bookmarks')) || [];
            const categories = new Set();
            bookmarks.forEach(bookmark => {
                renderBookmark(bookmark);
                categories.add(bookmark.category);
            });
            updateCategoryFilter(Array.from(categories));
        }

        function addBookmark() {
            const titleInput = document.getElementById('bookmark-title');
            const urlInput = document.getElementById('bookmark-url');
            const categoryInput = document.getElementById('bookmark-category');
            const title = titleInput.value.trim();
            const url = urlInput.value.trim();
            const category = categoryInput.value.trim();

            if (title === '' || url === '') {
                alert('タイトルとURLを入力してください。');
                return;
            }

            const bookmark = { title, url, category };
            saveBookmark(bookmark);
            renderBookmark(bookmark);

            titleInput.value = '';
            urlInput.value = '';
            categoryInput.value = '';

            updateCategoryFilter([category]);
        }

        function saveBookmark(bookmark) {
            const bookmarks = JSON.parse(localStorage.getItem('bookmarks')) || [];
            bookmarks.push(bookmark);
            localStorage.setItem('bookmarks', JSON.stringify(bookmarks));
        }

        function renderBookmark(bookmark) {
            const bookmarkList = document.getElementById('bookmark-list');
            const listItem = document.createElement('li');
            listItem.className = 'bookmark-item';

            listItem.innerHTML = `
                <span>${bookmark.title} (${bookmark.category})</span>
                <div>
                    <a href="${bookmark.url}" target="_blank">訪問</a>
                    <button onclick="editBookmark('${bookmark.url}')">編集</button>
                    <button onclick="deleteBookmark('${bookmark.url}')">削除</button>
                </div>
            `;

            bookmarkList.appendChild(listItem);
        }

        function deleteBookmark(url) {
            let bookmarks = JSON.parse(localStorage.getItem('bookmarks')) || [];
            bookmarks = bookmarks.filter(bookmark => bookmark.url !== url);
            localStorage.setItem('bookmarks', JSON.stringify(bookmarks));
            refreshBookmarkList();
        }

        function editBookmark(url) {
            let bookmarks = JSON.parse(localStorage.getItem('bookmarks')) || [];
            const bookmark = bookmarks.find(bookmark => bookmark.url === url);
            if (bookmark) {
                document.getElementById('bookmark-title').value = bookmark.title;
                document.getElementById('bookmark-url').value = bookmark.url;
                document.getElementById('bookmark-category').value = bookmark.category;
                deleteBookmark(url);  // 編集のために一旦削除
            }
        }

        function refreshBookmarkList() {
            const bookmarkList = document.getElementById('bookmark-list');
            bookmarkList.innerHTML = '';
            loadBookmarks();
        }

        function filterBookmarks() {
            const query = document.getElementById('search-bar').value.toLowerCase();
            const bookmarkItems = document.querySelectorAll('.bookmark-item');
            bookmarkItems.forEach(item => {
                const title = item.querySelector('span').innerText.toLowerCase();
                item.style.display = title.includes(query) ? 'flex' : 'none';
            });
        }

        function filterByCategory() {
            const category = document.getElementById('category-filter').value;
            const bookmarkItems = document.querySelectorAll('.bookmark-item');
            bookmarkItems.forEach(item => {
                const itemCategory = item.querySelector('span').innerText.split(' (')[1].slice(0, -1);
                item.style.display = (category === 'all' || itemCategory === category) ? 'flex' : 'none';
            });
        }

        function updateCategoryFilter(categories) {
            const filter = document.getElementById('category-filter');
            categories.forEach(category => {
                if (![...filter.options].some(option => option.value === category)) {
                    const option = document.createElement('option');
                    option.value = category;
                    option.textContent = category;
                    filter.appendChild(option);
                }
            });
        }

        function toggleTheme() {
            const body = document.body;
            const currentTheme = body.getAttribute('data-theme');
            const newTheme = currentTheme === 'light' ? 'dark' : 'light';
            body.setAttribute('data-theme', newTheme);
        }
    </script>

</body>
</html>

Javascript 日時を更新してみよう

main.js

'use strict';

{
    // 2000 4 11
    // const d = new Date(2000, 3, 11);
    // 2000 2 ??
    const d = new Date(2000, 3, 0);
    d.setDate(d.getDate() + 100);


    console.log(d.toLocaleString());
}

index.html

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My JavaScript</title>
</head>

<body>
    <script src="main.js"></script>
</body>

</html>

Here’s a brief overview of C++, one of the most powerful and widely used programming languages, especially in areas like game development, system programming, and high-performance applications:

Here’s a brief overview of C++, one of the most powerful and widely used programming languages, especially in areas like game development, system programming, and high-performance applications:

Overview of C++

  • History: C++ was developed by Bjarne Stroustrup starting in 1979 at Bell Labs. It was designed as an extension of the C programming language, adding object-oriented, generic, and functional features.
  • Key Features:
    • Object-Oriented Programming (OOP): Supports encapsulation, inheritance, and polymorphism.
    • Templates: Allows for generic programming, which is crucial for creating reusable code.
    • Standard Template Library (STL): Provides a rich set of algorithms, containers, and iterators.
    • Memory Management: Direct control over memory with new and delete, though modern C++ encourages smart pointers for safety.
    • Performance: Known for its efficiency, close to the hardware, making it ideal for performance-critical applications.
  • Syntax and Structure:
    • C++ retains C’s syntax but adds features like classes, templates, and exceptions.
    • Example of a simple C++ program:
      cpp#include <iostream> int main() { std::cout << "Hello, World!" << std::endl; return 0; }
  • Modern C++ (C++11, C++14, C++17, C++20):
    • Introduced many features like auto, lambda expressions, move semantics, and more expressive syntax for containers and algorithms.
    • Example of using auto and a lambda:
      cpp#include <vector> #include <algorithm> int main() { std::vector<int> numbers = {1, 2, 3, 4, 5}; auto result = std::find_if(numbers.begin(), numbers.end(), [](int x) { return x > 3; }); if (result != numbers.end()) { std::cout << "First number greater than 3: " << *result << std::endl; } return 0; }
  • Use Cases:
    • Game Development: Used in engines like Unreal Engine.
    • System Software: Operating systems, device drivers.
    • High-Performance Computing: Scientific simulations, financial systems.
    • Embedded Systems: Due to its efficiency and control over hardware.
  • Learning C++:
    • Start with basic C programming concepts.
    • Learn object-oriented programming principles.
    • Dive into templates and the STL.
    • Understand modern C++ features for safer, more expressive code.
  • Challenges:
    • Complexity: C++ is vast with many features, which can be overwhelming for beginners.
    • Memory Management: Manual memory handling can lead to bugs if not managed correctly.

If you have any specific questions about C++ or need help with a particular aspect of the language, feel free to ask!

Solve the Two Sum problem in Python

Solve the Two Sum problem in Python

回答

Certainly, I’ll provide a solution to the Two Sum problem in Python. This problem is a common interview question where you’re given an array of integers and a target sum, and you need to find two numbers in the array that add up to the target.

Here’s a step-by-step approach:

  1. Use a Hash Map: This approach allows for O(n) time complexity, where n is the number of elements in the array.
  2. Iterate Through the Array: For each number, calculate what the other number should be to reach the target sum.
  3. Check if the Complement Exists: If the complement exists in the hash map, return the indices of both numbers.

Here’s the implementation:

python

def two_sum(nums, target):
    # Dictionary to store the number and its index
    num_dict = {}
    
    # Iterate through the list
    for i, num in enumerate(nums):
        # Calculate the complement
        complement = target - num
        
        # If the complement exists in the dictionary, return the indices
        if complement in num_dict:
            return [num_dict[complement], i]
        
        # If not, add the current number and its index to the dictionary
        num_dict[num] = i
    
    # If no solution is found, return an empty list or raise an exception
    return []  # or raise ValueError("No two sum solution")

# Example usage
nums = [2, 7, 11, 15]
target = 9
result = two_sum(nums, target)
print(result)  # Should print [0, 1] because nums[0] + nums[1] == 9

Explanation:

  • We use a dictionary (num_dict) to keep track of numbers we’ve seen and their indices.
  • As we iterate through the list:
    • We calculate what number, when added to the current number, would give us the target.
    • If this number exists in our dictionary, we’ve found our pair, and we return their indices.
    • If not, we add the current number and its index to the dictionary.

This solution ensures that we only traverse the list once, making it efficient with a time complexity of O(n). The space complexity is also O(n) in the worst case where all numbers are unique.

ruby 数当てゲーム

数当てゲーム

class NumberGuessingGame
attr_accessor :player_name, :target_number, :guess, :attempts, :difficulty, :games_played, :total_attempts

def initialize
@player_name = “”
@target_number = 0
@guess = nil
@attempts = 0
@difficulty = “easy”
@games_played = 0
@total_attempts = 0
end

def start
welcome_message
get_player_name
loop do
set_difficulty
setup_game
play_round
display_result
update_statistics
break unless play_again?
end
display_statistics
farewell_message
end

def welcome_message
puts “数当てゲームへようこそ!”
end

def get_player_name
print “あなたの名前を入力してください: “
@player_name = gets.chomp
end

def set_difficulty
puts “難易度を選択してください: easy, medium, hard”
@difficulty = gets.chomp.downcase
end

def setup_game
@target_number = case @difficulty
when “medium”
rand(1..500)
when “hard”
rand(1..1000)
else
rand(1..100)
end
@attempts = 0
end

def play_round
until @guess == @target_number
print “数を予想してください: “
@guess = gets.to_i
@attempts += 1
give_hint
end
end

def give_hint
if @guess < @target_number puts “もっと大きい数です。” elsif @guess > @target_number
puts “もっと小さい数です。”
else
puts “正解です!”
end
end

def display_result
puts “#{@player_name}さん、おめでとうございます!”
puts “#{@attempts}回目で正解です!”
end

def play_again?
print “もう一度プレイしますか?(yes/no): “
answer = gets.chomp.downcase
answer == ‘yes’
end

def update_statistics
@games_played += 1
@total_attempts += @attempts
end

def display_statistics
puts “統計情報:”
puts “プレイしたゲーム数: #{@games_played}”
puts “総試行回数: #{@total_attempts}”
puts “平均試行回数: #{@total_attempts / @games_played}” if @games_played > 0
end

def farewell_message
puts “ゲームをプレイしていただきありがとうございました!またお会いしましょう!”
end
end

ゲーム開始

game = NumberGuessingGame.new
game.start
機能概要
難易度選択: プレイヤーはeasy, medium, hardのいずれかの難易度を選択でき、難易度によって予想する数の範囲が変わります。

easy: 1-100
medium: 1-500
hard: 1-1000
プレイ統計の表示: プレイしたゲーム数、総試行回数、平均試行回数を表示します。

再プレイ機能: プレイヤーはゲーム終了後、再度プレイするかどうかを選択できます。

実行方法
上記のコードをファイル(例: number_guessing_game_extended.rb)として保存します。
ターミナル(コマンドプロンプト)を開き、そのファイルがあるディレクトリに移動します。
以下のコマンドを実行してゲームを開始します。
bash
ruby number_guessing_game_extended.rb
この拡張版では、より多くの機能を楽しむことができ、プレイヤーは複数回のゲームプレイを通じて自分のパフォーマンスを追跡することができます。

Unity C# 変数

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour
{
    int HP = 100, ATK = 100;
    int DEF = 50;
    //
    string name = "";

    //少数
    float f = 0.1f;

    bool isDead = false;
    // Start is called before the first frame update
    void Start()
    {
        HP = 1000;

        f = 1000;

        name = "名前は勇者" + "です";

        isDead = true;

        HP = 200;
        UnityEngine.Debug.Log("HP" + HP);

        HP = 100;

        UnityEngine.Debug.Log("HP" + HP);
    }

    private void FixedUpdate()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

ELDER

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ELDER</title>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" rel="stylesheet">
<style>
  body {
    padding-top: 20px;
    background-color: #f8f9fa;
  }
  .card {
    margin-bottom: 20px;
  }
  .profile-img {
    width: 50px;
    height: 50px;
    object-fit: cover;
    border-radius: 50%;
  }
  .comment-section {
    margin-top: 20px;
  }
  .navbar {
    margin-bottom: 20px;
  }
  .form-error {
    color: red;
    font-size: 0.9em;
  }
</style>
</head>
<body>

<nav class="navbar navbar-expand-lg navbar-light bg-light">
  <a class="navbar-brand" href="#">SNS</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>
  <div class="collapse navbar-collapse" id="navbarNav">
    <ul class="navbar-nav ml-auto">
      <li class="nav-item">
        <a class="nav-link" href="#" onclick="showLoginForm()">ログイン</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#" onclick="showRegisterForm()">登録</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#" onclick="showProfile()" style="display: none;" id="navProfile">プロフィール</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#" onclick="logout()" style="display: none;" id="navLogout">ログアウト</a>
      </li>
    </ul>
  </div>
</nav>

<div class="container">
  <h1 class="text-center mb-4">ソーシャルネットワーキングサービス</h1>

  <!-- ログインフォーム -->
  <div id="loginForm" class="card w-50 mx-auto">
    <div class="card-body">
      <h2 class="card-title text-center mb-4">ログイン</h2>
      <div class="form-group">
        <input type="text" id="loginUsername" class="form-control" placeholder="ユーザー名">
        <span id="loginUsernameError" class="form-error" style="display: none;">ユーザー名を入力してください</span>
      </div>
      <div class="form-group">
        <input type="password" id="loginPassword" class="form-control" placeholder="パスワード">
        <span id="loginPasswordError" class="form-error" style="display: none;">パスワードを入力してください</span>
      </div>
      <button onclick="login()" class="btn btn-primary btn-block">ログイン</button>
      <button onclick="showRegisterForm()" class="btn btn-secondary btn-block">登録</button>
    </div>
  </div>

  <!-- 登録フォーム -->
  <div id="registerForm" class="card w-50 mx-auto" style="display: none;">
    <div class="card-body">
      <h2 class="card-title text-center mb-4">登録</h2>
      <div class="form-group">
        <input type="text" id="registerName" class="form-control" placeholder="氏名">
        <span id="registerNameError" class="form-error" style="display: none;">氏名を入力してください</span>
      </div>
      <div class="form-group">
        <input type="text" id="registerUsername" class="form-control" placeholder="ユーザー名">
        <span id="registerUsernameError" class="form-error" style="display: none;">ユーザー名を入力してください</span>
      </div>
      <div class="form-group">
        <input type="password" id="registerPassword" class="form-control" placeholder="パスワード">
        <span id="registerPasswordError" class="form-error" style="display: none;">パスワードを入力してください</span>
      </div>
      <div class="form-group">
        <input type="password" id="registerConfirmPassword" class="form-control" placeholder="パスワードを確認">
        <span id="registerConfirmPasswordError" class="form-error" style="display: none;">パスワードが一致しません</span>
      </div>
      <button onclick="register()" class="btn btn-primary btn-block">登録</button>
      <button onclick="showLoginForm()" class="btn btn-secondary btn-block">ログインに戻る</button>
    </div>
  </div>

  <!-- プロフィール -->
  <div id="profile" class="card w-50 mx-auto" style="display: none;">
    <div class="card-body">
      <h2 class="card-title text-center mb-4">プロフィール</h2>
      <div class="text-center mb-3">
        <img id="profileImg" class="profile-img" src="default_profile_img.jpg" alt="プロフィール画像">
      </div>
      <p class="text-center mb-2"><strong>氏名:</strong> <span id="profileName"></span></p>
      <p class="text-center mb-4"><strong>ユーザー名:</strong> <span id="profileUsername"></span></p>
      <div class="form-group">
        <input type="file" id="profileImageInput" accept="image/*" class="form-control-file">
      </div>
      <button onclick="uploadProfileImage()" class="btn btn-primary btn-block"><i class="fas fa-upload"></i> プロフィール画像をアップロード</button>
      <button id="followButton" onclick="toggleFollow()" class="btn btn-primary btn-block"></button>
      <button id="messageButton" onclick="openDirectMessageModal()" class="btn btn-primary btn-block">ダイレクトメッセージを送信</button>
      <button onclick="logout()" class="btn btn-danger btn-block"><i class="fas fa-sign-out-alt"></i> ログアウト</button>
    </div>
  </div>

  <!-- 投稿フォーム -->
  <div id="postForm" class="card w-75 mx-auto" style="display: none;">
    <div class="card-body">
      <h2 class="card-title text-center mb-4">投稿を作成</h2>
      <div class="form-group">
        <textarea id="postContent" class="form-control" rows="3" placeholder="今何を考えていますか?"></textarea>
      </div>
      <button onclick="createPost()" class="btn btn-primary btn-block">投稿</button>
    </div>
  </div>

  <!-- FEED登録フォーム -->
  <div id="feedForm" class="card w-75 mx-auto" style="display: none;">
    <div class="card-body">
      <h2 class="card-title text-center mb-4">FEEDを登録</h2>
      <div class="form-group">
        <input type="text" id="feedUrl" class="form-control" placeholder="RSSフィードのURL">
        <span id="feedUrlError" class="form-error" style="display: none;">RSSフィードのURLを入力してください</span>
      </div>
      <button onclick="registerFeed()" class="btn btn-primary btn-block">登録</button>
    </div>
  </div>

  <!-- タイムライン -->
  <div id="timeline" class="w-75 mx-auto mt-4"></div>
</div>

<!-- リプライモーダル -->
<div class="modal fade" id="replyModal" tabindex="-1" role="dialog" aria-labelledby="replyModalLabel" aria-hidden="true">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="replyModalLabel">投稿に返信</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="閉じる">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <textarea id="replyContent" class="form-control" rows="3" placeholder="返信をここに書いてください..."></textarea>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal">閉じる</button>
        <button type="button" onclick="postReply()" class="btn btn-primary">返信</button>
      </div>
    </div>
  </div>
</div>

<!-- ダイレクトメッセージモーダル -->
<div class="modal fade" id="directMessageModal" tabindex="-1" role="dialog" aria-labelledby="directMessageModalLabel" aria-hidden="true">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="directMessageModalLabel">ダイレクトメッセージを送信</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="閉じる">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <select id="recipient" class="form-control">
          <option value="">送信先を選択</option>
          <!-- ユーザーリストがここに追加される -->
        </select>
        <textarea id="directMessageContent" class="form-control mt-2" rows="3" placeholder="メッセージをここに書いてください..."></textarea>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal">閉じる</button>
        <button type="button" onclick="sendDirectMessage()" class="btn btn-primary">送信</button>
      </div>
    </div>
  </div>
</div>

<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.4/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<script>
  let currentUser = null; // 現在のログインユーザー
  let users = []; // ユーザーの配列
  let posts = []; // 投稿の配列
  let feeds = []; // フィードの配列

  // ローカルストレージにユーザー情報を保存
  function saveUsersToLocalStorage() {
    localStorage.setItem('users', JSON.stringify(users));
  }

  // ローカルストレージに投稿情報を保存
  function savePostsToLocalStorage() {
    localStorage.setItem('posts', JSON.stringify(posts));
  }

  // ローカルストレージにフィード情報を保存
  function saveFeedsToLocalStorage() {
    localStorage.setItem('feeds', JSON.stringify(feeds));
  }

  // ローカルストレージからユーザー情報を読み込み
  function loadUsersFromLocalStorage() {
    const storedUsers = localStorage.getItem('users');
    if (storedUsers) {
      users = JSON.parse(storedUsers);
    }
  }

  // ローカルストレージから投稿情報を読み込み
  function loadPostsFromLocalStorage() {
    const storedPosts = localStorage.getItem('posts');
    if (storedPosts) {
      posts = JSON.parse(storedPosts);
    }
  }

  // ローカルストレージからフィード情報を読み込み
  function loadFeedsFromLocalStorage() {
    const storedFeeds = localStorage.getItem('feeds');
    if (storedFeeds) {
      feeds = JSON.parse(storedFeeds);
    }
  }

  function showLoginForm() {
    hideAll();
    document.getElementById('loginForm').style.display = 'block';
  }

  function showRegisterForm() {
    hideAll();
    document.getElementById('registerForm').style.display = 'block';
  }

  function validateLoginForm() {
    let valid = true;
    const username = document.getElementById('loginUsername').value;
    const password = document.getElementById('loginPassword').value;
    
    if (!username) {
      document.getElementById('loginUsernameError').style.display = 'block';
      valid = false;
    } else {
      document.getElementById('loginUsernameError').style.display = 'none';
    }
    
    if (!password) {
      document.getElementById('loginPasswordError').style.display = 'block';
      valid = false;
    } else {
      document.getElementById('loginPasswordError').style.display = 'none';
    }
    
    return valid;
  }

  function login() {
    if (!validateLoginForm()) {
      return;
    }

    const username = document.getElementById('loginUsername').value;
    const password = document.getElementById('loginPassword').value;
    const user = users.find(u => u.username === username && u.password === password);
    if (user) {
      currentUser = user;
      showProfile();
    } else {
      alert('ユーザー名またはパスワードが間違っています。');
    }
  }

  function logout() {
    currentUser = null;
    hideAll();
    document.getElementById('loginForm').style.display = 'block';
    document.getElementById('navProfile').style.display = 'none';
    document.getElementById('navLogout').style.display = 'none';
  }

  function validateRegisterForm() {
    let valid = true;
    const name = document.getElementById('registerName').value;
    const username = document.getElementById('registerUsername').value;
    const password = document.getElementById('registerPassword').value;
    const confirmPassword = document.getElementById('registerConfirmPassword').value;
    
    if (!name) {
      document.getElementById('registerNameError').style.display = 'block';
      valid = false;
    } else {
      document.getElementById('registerNameError').style.display = 'none';
    }
    
    if (!username) {
      document.getElementById('registerUsernameError').style.display = 'block';
      valid = false;
    } else {
      document.getElementById('registerUsernameError').style.display = 'none';
    }
    
    if (!password) {
      document.getElementById('registerPasswordError').style.display = 'block';
      valid = false;
    } else {
      document.getElementById('registerPasswordError').style.display = 'none';
    }
    
    if (password !== confirmPassword) {
      document.getElementById('registerConfirmPasswordError').style.display = 'block';
      valid = false;
    } else {
      document.getElementById('registerConfirmPasswordError').style.display = 'none';
    }
    
    return valid;
  }

  function register() {
    if (!validateRegisterForm()) {
      return;
    }

    const name = document.getElementById('registerName').value;
    const username = document.getElementById('registerUsername').value;
    const password = document.getElementById('registerPassword').value;

    users.push({ name, username, password, following: false });
    saveUsersToLocalStorage(); // ユーザー情報を保存
    alert('登録が完了しました!ログインしてください。');
    showLoginForm();
  }

  function showProfile() {
    hideAll();
    document.getElementById('profile').style.display = 'block';
    document.getElementById('profileName').textContent = currentUser.name;
    document.getElementById('profileUsername').textContent = currentUser.username;
    document.getElementById('postForm').style.display = 'block';
    document.getElementById('feedForm').style.display = 'block';
    loadProfileImage(); // プロフィール画像をロード
    displayTimeline(); // タイムラインを表示
    updateFollowButton(); // フォローボタンの表示を更新
    loadDirectMessageRecipients(); // ダイレクトメッセージの送信先をロード
    document.getElementById('navProfile').style.display = 'block';
    document.getElementById('navLogout').style.display = 'block';
  }

  // プロフィール画像をロード
  function loadProfileImage() {
    const profileImg = document.getElementById('profileImg');
    // プロフィール画像が設定されている場合はその画像を表示
    if (currentUser.profileImage) {
      profileImg.src = currentUser.profileImage;
    } else {
      // デフォルトのプロフィール画像を表示
      profileImg.src = 'default_profile_img.jpg';
    }
  }

  // プロフィール画像をアップロード
  function uploadProfileImage() {
    const input = document.getElementById('profileImageInput');
    const file = input.files[0];
    if (file) {
      // FileReaderを使用して画像を読み込む
      const reader = new FileReader();
      reader.onload = function(e) {
        // 読み込んだ画像をプロフィール画像として設定
        currentUser.profileImage = e.target.result;
        // プロフィール画像を更新して表示
        loadProfileImage();
        saveUsersToLocalStorage(); // プロフィール画像を保存
      }
      reader.readAsDataURL(file);
    }
  }

  // フォローボタンの更新
  function updateFollowButton() {
    const followButton = document.getElementById('followButton');
    if (currentUser.following) {
      followButton.textContent = 'フォロー解除';
    } else {
      followButton.textContent = 'フォロー';
    }
    saveUsersToLocalStorage(); // フォロー状態を保存
  }

  // フォローの切り替え
  function toggleFollow() {
    currentUser.following = !currentUser.following;
    updateFollowButton();
  }

  // ダイレクトメッセージの送信先をロード
  function loadDirectMessageRecipients() {
    const select = document.getElementById('recipient');
    select.innerHTML = '<option value="">送信先を選択</option>';
    users.forEach(user => {
      if (user !== currentUser) {
        const option = document.createElement('option');
        option.value = user.username;
        option.textContent = user.name;
        select.appendChild(option);
      }
    });
  }

  // ダイレクトメッセージのモーダルを開く
  function openDirectMessageModal() {
    $('#directMessageModal').modal('show');
  }

  // ダイレクトメッセージを送信
  function sendDirectMessage() {
    const recipientUsername = document.getElementById('recipient').value;
    const messageContent = document.getElementById('directMessageContent').value;
    if (recipientUsername && messageContent.trim() !== '') {
      const recipient = users.find(user => user.username === recipientUsername);
      if (recipient) {
        alert(`メッセージを${recipient.name}に送信しました: ${messageContent}`);
        $('#directMessageModal').modal('hide');
      } else {
        alert('送信先が見つかりません。');
      }
    } else {
      alert('送信先を選択し、メッセージを入力してください。');
    }
  }

  function createPost() {
    const postContent = document.getElementById('postContent').value;
    if (postContent.trim() !== '') {
      const post = {
        id: Date.now(),
        content: postContent,
        author: currentUser.name,
        authorUsername: currentUser.username,
        authorProfileImage: currentUser.profileImage, // プロフィール画像を追加
        likes: 0,
        comments: []
      };
      posts.unshift(post); // 最新の投稿を先頭に追加
      savePostsToLocalStorage(); // 投稿を保存
      displayTimeline();
      document.getElementById('postContent').value = ''; // 投稿後、入力欄を空にする
    }
  }

  function registerFeed() {
    const feedUrl = document.getElementById('feedUrl').value;
    if (feedUrl.trim() !== '') {
      feeds.push(feedUrl);
      saveFeedsToLocalStorage(); // フィード情報を保存
      alert('RSSフィードが登録されました!');
      document.getElementById('feedUrl').value = ''; // 登録後、入力欄を空にする
    } else {
      document.getElementById('feedUrlError').style.display = 'block';
    }
  }

  function displayTimeline() {
    const timeline = document.getElementById('timeline');
    timeline.innerHTML = '';
    posts.forEach(post => {
      const postElement = document.createElement('div');
      postElement.classList.add('card', 'mb-3');
      postElement.innerHTML = `
        <div class="card-body">
          <div class="d-flex align-items-center mb-3">
            <img src="${post.authorProfileImage || 'default_profile_img.jpg'}" class="profile-img mr-2" alt="プロフィール画像">
            <div>
              <strong>${post.author}</strong> (@${post.authorUsername})
            </div>
          </div>
          <p class="card-text">${post.content}</p>
          ${post.link ? `<a href="${post.link}" target="_blank" class="btn btn-link">続きを読む</a>` : ''}
          <div class="d-flex justify-content-between">
            <div>
              <button onclick="likePost(${post.id})" class="btn btn-primary btn-sm"><i class="fas fa-thumbs-up"></i> いいね (${post.likes})</button>
              <button onclick="toggleComments(${post.id})" class="btn btn-secondary btn-sm"><i class="fas fa-comments"></i> コメント (${post.comments.length})</button>
              <button onclick="replyToPost(${post.id})" class="btn btn-info btn-sm"><i class="fas fa-reply"></i> 返信</button>
            </div>
            <small class="text-muted">${new Date(post.id).toLocaleString()}</small>
          </div>
          <div id="comments-${post.id}" class="comment-section mt-3" style="display: none;">
            ${post.comments.map(comment => `
              <div class="card mb-2">
                <div class="card-body">
                  <p><strong>${comment.author}</strong>: ${comment.content}</p>
                </div>
              </div>
            `).join('')}
          </div>
        </div>
      `;
      timeline.appendChild(postElement);
    });
  }

  function likePost(postId) {
    const post = posts.find(p => p.id === postId);
    post.likes++;
    savePostsToLocalStorage(); // いいねを保存
    displayTimeline();
  }

  function toggleComments(postId) {
    const commentSection = document.getElementById(`comments-${postId}`);
    commentSection.style.display = commentSection.style.display === 'none' ? 'block' : 'none';
  }

  function replyToPost(postId) {
    const modal = document.getElementById('replyModal');
    modal.dataset.postId = postId;
    $('#replyModal').modal('show');
  }

  function postReply() {
    const postId = parseInt(document.getElementById('replyModal').dataset.postId);
    const post = posts.find(p => p.id === postId);
    const replyContent = document.getElementById('replyContent').value;
    if (replyContent.trim() !== '') {
      post.comments.push({ author: currentUser.name, content: replyContent });
      $('#replyModal').modal('hide');
      savePostsToLocalStorage(); // コメントを保存
      displayTimeline();
    } else {
      alert('返信を入力してください。');
    }
  }

  function fetchFeeds() {
    feeds.forEach(feedUrl => {
      fetch(`https://api.rss2json.com/v1/api.json?rss_url=${encodeURIComponent(feedUrl)}`)
        .then(response => response.json())
        .then(data => {
          data.items.forEach(item => {
            const post = {
              id: Date.now() + Math.random(), // 重複しないIDを生成
              content: item.title,
              link: item.link, // リンクを追加
              author: 'RSSフィード',
              authorUsername: 'rssfeed',
              authorProfileImage: 'default_profile_img.jpg', // プロフィール画像を設定
              likes: 0,
              comments: []
            };
            posts.unshift(post); // 最新の投稿を先頭に追加
            savePostsToLocalStorage(); // 投稿を保存
          });
          displayTimeline(); // タイムラインを表示
        })
        .catch(error => console.error('Error fetching RSS feed:', error));
    });
  }

  function hideAll() {
    document.getElementById('loginForm').style.display = 'none';
    document.getElementById('registerForm').style.display = 'none';
    document.getElementById('profile').style.display = 'none';
    document.getElementById('postForm').style.display = 'none';
    document.getElementById('feedForm').style.display = 'none';
  }

  // 初期データをローカルストレージから読み込む
  loadUsersFromLocalStorage();
  loadPostsFromLocalStorage();
  loadFeedsFromLocalStorage();

  // 初期ログイン画面表示
  hideAll();
  document.getElementById('loginForm').style.display = 'block';

  // 1時間ごとにRSSフィードをフェッチして自動投稿
  setInterval(fetchFeeds, 5); // 3600000ミリ秒 = 1時間

</script>

</body>
</html>

RSSの機能を使えるようにしました

Q&Aサイト

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Q&A Site</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 20px;
            background-color: #f4f4f4;
        }

        h1, h2, h3 {
            color: #333;
        }

        #question-list, #add-question, #question-detail {
            margin-bottom: 20px;
        }

        #questions {
            list-style-type: none;
            padding: 0;
        }

        .question, .answer {
            background-color: #fff;
            padding: 10px;
            margin-bottom: 10px;
            border-radius: 5px;
            box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
        }

        .answer {
            margin-left: 20px;
        }

        form {
            display: flex;
            flex-direction: column;
        }

        form input, form textarea {
            margin-bottom: 10px;
            padding: 10px;
            border-radius: 5px;
            border: 1px solid #ccc;
        }

        form button {
            padding: 10px;
            border: none;
            border-radius: 5px;
            background-color: #333;
            color: #fff;
            cursor: pointer;
        }

        form button:hover {
            background-color: #555;
        }

        .hidden {
            display: none;
        }

        .action-buttons {
            display: flex;
            gap: 10px;
        }
    </style>
</head>
<body>
    <h1>Q&A Site</h1>
    <div id="question-list">
        <h2>Questions</h2>
        <ul id="questions"></ul>
    </div>
    <div id="add-question">
        <h2>Add a Question</h2>
        <form id="question-form">
            <input type="text" id="question-title" placeholder="Title" required>
            <textarea id="question-body" placeholder="Question" required></textarea>
            <button type="submit">Add Question</button>
        </form>
    </div>
    <div id="question-detail" class="hidden">
        <h2 id="detail-title"></h2>
        <p id="detail-body"></p>
        <div class="action-buttons">
            <button id="edit-question-button">Edit</button>
            <button id="delete-question-button">Delete</button>
        </div>
        <div id="edit-question" class="hidden">
            <h3>Edit Question</h3>
            <form id="edit-question-form">
                <input type="text" id="edit-question-title" required>
                <textarea id="edit-question-body" required></textarea>
                <button type="submit">Save Changes</button>
            </form>
        </div>
        <h3>Answers</h3>
        <ul id="answers"></ul>
        <h3>Add an Answer</h3>
        <form id="answer-form">
            <input type="text" id="answer-name" placeholder="Your name" required>
            <textarea id="answer-body" placeholder="Your answer" required></textarea>
            <button type="submit">Add Answer</button>
        </form>
        <button id="back-button">Back to Questions</button>
    </div>
    <script>
        document.addEventListener('DOMContentLoaded', () => {
            let questions = [];
            let currentQuestionIndex = null;

            const questionForm = document.getElementById('question-form');
            const questionTitle = document.getElementById('question-title');
            const questionBody = document.getElementById('question-body');
            const questionsList = document.getElementById('questions');

            const questionDetail = document.getElementById('question-detail');
            const detailTitle = document.getElementById('detail-title');
            const detailBody = document.getElementById('detail-body');
            const answersList = document.getElementById('answers');
            const answerForm = document.getElementById('answer-form');
            const answerName = document.getElementById('answer-name');
            const answerBody = document.getElementById('answer-body');
            const backButton = document.getElementById('back-button');

            const editQuestionButton = document.getElementById('edit-question-button');
            const deleteQuestionButton = document.getElementById('delete-question-button');
            const editQuestionForm = document.getElementById('edit-question-form');
            const editQuestionTitle = document.getElementById('edit-question-title');
            const editQuestionBody = document.getElementById('edit-question-body');

            questionForm.addEventListener('submit', (e) => {
                e.preventDefault();

                const newQuestion = {
                    title: questionTitle.value,
                    body: questionBody.value,
                    answers: []
                };

                questions.push(newQuestion);
                displayQuestions();

                questionTitle.value = '';
                questionBody.value = '';
            });

            answerForm.addEventListener('submit', (e) => {
                e.preventDefault();

                const newAnswer = {
                    name: answerName.value,
                    body: answerBody.value
                };

                questions[currentQuestionIndex].answers.push(newAnswer);
                displayQuestionDetail(currentQuestionIndex);

                answerName.value = '';
                answerBody.value = '';
            });

            editQuestionButton.addEventListener('click', () => {
                editQuestionForm.classList.remove('hidden');
                editQuestionTitle.value = questions[currentQuestionIndex].title;
                editQuestionBody.value = questions[currentQuestionIndex].body;
            });

            editQuestionForm.addEventListener('submit', (e) => {
                e.preventDefault();
                questions[currentQuestionIndex].title = editQuestionTitle.value;
                questions[currentQuestionIndex].body = editQuestionBody.value;
                displayQuestionDetail(currentQuestionIndex);
                displayQuestions();
                editQuestionForm.classList.add('hidden');
            });

            deleteQuestionButton.addEventListener('click', () => {
                questions.splice(currentQuestionIndex, 1);
                questionDetail.classList.add('hidden');
                document.getElementById('question-list').classList.remove('hidden');
                document.getElementById('add-question').classList.remove('hidden');
                displayQuestions();
            });

            backButton.addEventListener('click', () => {
                questionDetail.classList.add('hidden');
                document.getElementById('question-list').classList.remove('hidden');
                document.getElementById('add-question').classList.remove('hidden');
            });

            function displayQuestions() {
                questionsList.innerHTML = '';

                questions.forEach((question, index) => {
                    const li = document.createElement('li');
                    li.className = 'question';
                    li.innerHTML = `
                        <h3>${question.title}</h3>
                        <p>${question.body}</p>
                        <button onclick="viewQuestion(${index})">View Details</button>
                    `;
                    questionsList.appendChild(li);
                });
            }

            window.viewQuestion = (index) => {
                currentQuestionIndex = index;
                displayQuestionDetail(index);
                document.getElementById('question-list').classList.add('hidden');
                document.getElementById('add-question').classList.add('hidden');
                questionDetail.classList.remove('hidden');
            };

            function displayQuestionDetail(index) {
                const question = questions[index];
                detailTitle.textContent = question.title;
                detailBody.textContent = question.body;
                displayAnswers(index);
            }

            function displayAnswers(index) {
                const question = questions[index];
                answersList.innerHTML = '';

                question.answers.forEach((answer, answerIndex) => {
                    const li = document.createElement('li');
                    li.className = 'answer';
                    li.innerHTML = `
                        <p><strong>${answer.name}:</strong> ${answer.body}</p>
                        <button onclick="editAnswer(${index}, ${answerIndex})">Edit</button>
                        <button onclick="deleteAnswer(${index}, ${answerIndex})">Delete</button>
                    `;
                    answersList.appendChild(li);
                });
            }

            window.editAnswer = (questionIndex, answerIndex) => {
                const answer = questions[questionIndex].answers[answerIndex];
                const newBody = prompt("Edit your answer:", answer.body);
                if (newBody) {
                    answer.body = newBody;
                    displayAnswers(questionIndex);
                }
            };

            window.deleteAnswer = (questionIndex, answerIndex) => {
                questions[questionIndex].answers.splice(answerIndex, 1);
                displayAnswers(questionIndex);
            };

            displayQuestions();
        });
    </script>
</body>
</html>