diff --git a/data/src/main/java/one/nem/kidshift/data/KSActions.java b/data/src/main/java/one/nem/kidshift/data/KSActions.java index 732d810..85c440f 100644 --- a/data/src/main/java/one/nem/kidshift/data/KSActions.java +++ b/data/src/main/java/one/nem/kidshift/data/KSActions.java @@ -2,6 +2,7 @@ package one.nem.kidshift.data; import java.util.concurrent.CompletableFuture; +import one.nem.kidshift.data.retrofit.model.task.TaskListResponse; import one.nem.kidshift.model.ParentModel; /** @@ -9,7 +10,7 @@ import one.nem.kidshift.model.ParentModel; */ public interface KSActions { - void syncTasks(); + CompletableFuture syncTasks(); void syncChildList(); diff --git a/data/src/main/java/one/nem/kidshift/data/TaskData.java b/data/src/main/java/one/nem/kidshift/data/TaskData.java index 09420f5..7e85cc4 100644 --- a/data/src/main/java/one/nem/kidshift/data/TaskData.java +++ b/data/src/main/java/one/nem/kidshift/data/TaskData.java @@ -1,6 +1,7 @@ package one.nem.kidshift.data; import java.util.List; +import java.util.concurrent.CompletableFuture; import one.nem.kidshift.model.tasks.TaskItemModel; @@ -10,9 +11,16 @@ public interface TaskData { /** * 存在する全てのタスクを取得する - * @return List タスクリスト + * @return CompletableFuture> タスクリスト */ - List getTasks(); + CompletableFuture> getTasks(); + + /** + * アタッチされている全てのタスクを取得する + * @param childId 子ID + * @return CompletableFuture> タスクリスト + */ + CompletableFuture> getTasks(String childId); /** * タスクを追加する diff --git a/data/src/main/java/one/nem/kidshift/data/impl/KSActionsImpl.java b/data/src/main/java/one/nem/kidshift/data/impl/KSActionsImpl.java index 9cf9f7c..6b2558c 100644 --- a/data/src/main/java/one/nem/kidshift/data/impl/KSActionsImpl.java +++ b/data/src/main/java/one/nem/kidshift/data/impl/KSActionsImpl.java @@ -8,6 +8,7 @@ import one.nem.kidshift.data.KSActions; import one.nem.kidshift.data.UserSettings; import one.nem.kidshift.data.retrofit.KidShiftApiService; import one.nem.kidshift.data.retrofit.model.parent.ParentInfoResponse; +import one.nem.kidshift.data.retrofit.model.task.TaskListResponse; import one.nem.kidshift.model.ParentModel; import one.nem.kidshift.utils.KSLogger; import retrofit2.Call; @@ -28,8 +29,27 @@ public class KSActionsImpl implements KSActions { } @Override - public void syncTasks() { - + public CompletableFuture syncTasks() { + return CompletableFuture.supplyAsync(() -> { + Call call = kidShiftApiService.getTasks(); + try { + Response response = call.execute(); + if (!response.isSuccessful()) { + logger.error("Error fetching tasks: " + response.errorBody().string()); + throw new RuntimeException("Error fetching tasks: " + response.errorBody().string()); + } + TaskListResponse responseBody = response.body(); + logger.info("Tasks fetched with status: " + response.code()); + logger.debug("Tasks: " + responseBody.getList()); +// // Save to cache +// userSettings.getCache().setTasks(responseBody.getList()); +// logger.info("Tasks saved to cache"); + return responseBody; + } catch (Exception e) { + logger.error("Error fetching tasks"); + throw new RuntimeException(e); + } + }); } @Override diff --git a/data/src/main/java/one/nem/kidshift/data/impl/TaskDataDummyImpl.java b/data/src/main/java/one/nem/kidshift/data/impl/TaskDataDummyImpl.java deleted file mode 100644 index 4c5af1b..0000000 --- a/data/src/main/java/one/nem/kidshift/data/impl/TaskDataDummyImpl.java +++ /dev/null @@ -1,78 +0,0 @@ -package one.nem.kidshift.data.impl; - -import com.github.javafaker.Faker; - -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -import javax.inject.Inject; - -import one.nem.kidshift.data.TaskData; -import one.nem.kidshift.model.tasks.TaskItemModel; -import one.nem.kidshift.model.tasks.condition.TaskConditionBaseModel; -import one.nem.kidshift.model.tasks.condition.TaskConditionNoneModel; -import one.nem.kidshift.utils.KSLogger; - -public class TaskDataDummyImpl implements TaskData { - - private Faker faker; - - @Inject - KSLogger logger; - - @Inject - public TaskDataDummyImpl() { - faker = new Faker(); -// logger.setTag("TaskDataDummyImpl"); - } - - @Override - public List getTasks() { -// logger.info("getTotalReward called"); - List tasks = new ArrayList<>(); - int totalTasks = faker.number().numberBetween(1, 15); -// logger.info("Returning total tasks: " + totalTasks); - for (int i = 0; i < totalTasks; i++) { - tasks.add(new TaskItemModel( - UUID.randomUUID().toString(), - faker.lorem().sentence(), UUID.randomUUID().toString(), - new TaskConditionNoneModel(), - faker.number().numberBetween(1, 1000))); - } -// logger.info("Returning tasks: " + tasks); - return tasks; - } - - @Override - public void addTask(TaskItemModel task) { - logger.info("addTask called"); - logger.info("Task: " + task); - } - - @Override - public void removeTask(String taskId) { - logger.info("removeTask called"); - logger.info("Task ID: " + taskId); - } - - @Override - public void updateTask(TaskItemModel task) { - logger.info("updateTask called"); - logger.info("Task: " + task); - } - - @Override - public TaskItemModel getTask(String taskId) { - List tasks = getTasks(); - // return random task - return tasks.get(faker.number().numberBetween(0, tasks.size())); - } - - @Override - public void recordTaskCompletion(String taskId, String childId) { - logger.info("recordTaskCompletion called"); - logger.info("Task ID: " + taskId); - logger.info("Child ID: " + childId); - } -} diff --git a/data/src/main/java/one/nem/kidshift/data/impl/TaskDataImpl.java b/data/src/main/java/one/nem/kidshift/data/impl/TaskDataImpl.java new file mode 100644 index 0000000..592f4ba --- /dev/null +++ b/data/src/main/java/one/nem/kidshift/data/impl/TaskDataImpl.java @@ -0,0 +1,68 @@ +package one.nem.kidshift.data.impl; + +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; + +import javax.inject.Inject; + +import one.nem.kidshift.data.KSActions; +import one.nem.kidshift.data.TaskData; +import one.nem.kidshift.data.retrofit.model.task.TaskListResponse; +import one.nem.kidshift.model.tasks.TaskItemModel; + +public class TaskDataImpl implements TaskData { + + KSActions ksActions; + + @Inject + public TaskDataImpl(KSActions ksActions) { + this.ksActions = ksActions; + } + + @Override + public CompletableFuture> getTasks() { + return CompletableFuture.supplyAsync(() -> { + TaskListResponse data = ksActions.syncTasks().join(); + return data.getList().stream().map(task -> { + // Convert TaskItemModel + TaskItemModel model = new TaskItemModel(); + model.setInternalId(task.getId()); + model.setDisplayName(task.getName()); + model.setReward(task.getReward()); + + return model; + }).collect(Collectors.toList()); + }); + } + + @Override + public CompletableFuture> getTasks(String childId) { + return null; + } + + @Override + public void addTask(TaskItemModel task) { + + } + + @Override + public void removeTask(String taskId) { + + } + + @Override + public void updateTask(TaskItemModel task) { + + } + + @Override + public TaskItemModel getTask(String taskId) { + return null; + } + + @Override + public void recordTaskCompletion(String taskId, String childId) { + + } +} diff --git a/data/src/main/java/one/nem/kidshift/data/modules/TaskDataDummyModule.java b/data/src/main/java/one/nem/kidshift/data/modules/TaskDataModule.java similarity index 60% rename from data/src/main/java/one/nem/kidshift/data/modules/TaskDataDummyModule.java rename to data/src/main/java/one/nem/kidshift/data/modules/TaskDataModule.java index 764f040..87f27e4 100644 --- a/data/src/main/java/one/nem/kidshift/data/modules/TaskDataDummyModule.java +++ b/data/src/main/java/one/nem/kidshift/data/modules/TaskDataModule.java @@ -5,12 +5,12 @@ import dagger.Module; import dagger.hilt.InstallIn; import dagger.hilt.android.components.FragmentComponent; import one.nem.kidshift.data.TaskData; -import one.nem.kidshift.data.impl.TaskDataDummyImpl; +import one.nem.kidshift.data.impl.TaskDataImpl; @Module @InstallIn(FragmentComponent.class) -abstract public class TaskDataDummyModule { +public abstract class TaskDataModule { @Binds - public abstract TaskData bindTaskData(TaskDataDummyImpl taskDataDummyImpl); + public abstract TaskData bindTaskData(TaskDataImpl taskDataImpl); } diff --git a/data/src/main/java/one/nem/kidshift/data/retrofit/KidShiftApiService.java b/data/src/main/java/one/nem/kidshift/data/retrofit/KidShiftApiService.java index c075559..261a32e 100644 --- a/data/src/main/java/one/nem/kidshift/data/retrofit/KidShiftApiService.java +++ b/data/src/main/java/one/nem/kidshift/data/retrofit/KidShiftApiService.java @@ -4,6 +4,7 @@ import one.nem.kidshift.data.retrofit.interceptor.AuthorizationInterceptor; import one.nem.kidshift.data.retrofit.model.parent.ParentInfoResponse; import one.nem.kidshift.data.retrofit.model.parent.auth.ParentLoginRequest; import one.nem.kidshift.data.retrofit.model.parent.auth.ParentLoginResponse; +import one.nem.kidshift.data.retrofit.model.task.TaskListResponse; import retrofit2.Call; import retrofit2.http.Body; import retrofit2.http.GET; @@ -20,4 +21,7 @@ public interface KidShiftApiService { @Headers(AuthorizationInterceptor.HEADER_PLACEHOLDER) Call getParentInfo(); + @GET("/parent/task") + @Headers(AuthorizationInterceptor.HEADER_PLACEHOLDER) + Call getTasks(); } diff --git a/data/src/main/java/one/nem/kidshift/data/retrofit/model/child/ChildAddRequest.java b/data/src/main/java/one/nem/kidshift/data/retrofit/model/child/ChildAddRequest.java new file mode 100644 index 0000000..e887ead --- /dev/null +++ b/data/src/main/java/one/nem/kidshift/data/retrofit/model/child/ChildAddRequest.java @@ -0,0 +1,23 @@ +package one.nem.kidshift.data.retrofit.model.child; + +// Request to add a child +public class ChildAddRequest { + private String name; + + // Constructor + public ChildAddRequest(String name) { + this.name = name; + } + + public ChildAddRequest() { + } + + // Getters and setters + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} \ No newline at end of file diff --git a/data/src/main/java/one/nem/kidshift/data/retrofit/model/child/ChildBaseItem.java b/data/src/main/java/one/nem/kidshift/data/retrofit/model/child/ChildBaseItem.java new file mode 100644 index 0000000..8177caa --- /dev/null +++ b/data/src/main/java/one/nem/kidshift/data/retrofit/model/child/ChildBaseItem.java @@ -0,0 +1,33 @@ +package one.nem.kidshift.data.retrofit.model.child; + +// Base class for children +public class ChildBaseItem { + private String id; + private String name; + + // Constructor + public ChildBaseItem(String id, String name) { + this.id = id; + this.name = name; + } + + public ChildBaseItem() { + } + + // Getters and setters + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/data/src/main/java/one/nem/kidshift/data/retrofit/model/child/ChildDetailsResponse.java b/data/src/main/java/one/nem/kidshift/data/retrofit/model/child/ChildDetailsResponse.java new file mode 100644 index 0000000..15db2ad --- /dev/null +++ b/data/src/main/java/one/nem/kidshift/data/retrofit/model/child/ChildDetailsResponse.java @@ -0,0 +1,36 @@ +package one.nem.kidshift.data.retrofit.model.child; + +import java.util.Date; + +// Response for detailed information about a child +public class ChildDetailsResponse extends ChildBaseItem { + private Date createdAt; + private String homeGroupId; + + // Constructor + public ChildDetailsResponse(String id, String name, Date createdAt, String homeGroupId) { + super(id, name); + this.createdAt = createdAt; + this.homeGroupId = homeGroupId; + } + + public ChildDetailsResponse() { + } + + // Getters and setters + public Date getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Date createdAt) { + this.createdAt = createdAt; + } + + public String getHomeGroupId() { + return homeGroupId; + } + + public void setHomeGroupId(String homeGroupId) { + this.homeGroupId = homeGroupId; + } +} diff --git a/data/src/main/java/one/nem/kidshift/data/retrofit/model/child/ChildListResponse.java b/data/src/main/java/one/nem/kidshift/data/retrofit/model/child/ChildListResponse.java new file mode 100644 index 0000000..cada8b8 --- /dev/null +++ b/data/src/main/java/one/nem/kidshift/data/retrofit/model/child/ChildListResponse.java @@ -0,0 +1,25 @@ +package one.nem.kidshift.data.retrofit.model.child; + +import java.util.List; + +// Response for a list of children +public class ChildListResponse { + private List list; + + // Constructor + public ChildListResponse(List list) { + this.list = list; + } + + public ChildListResponse() { + } + + // Getters and setters + public List getList() { + return list; + } + + public void setList(List list) { + this.list = list; + } +} diff --git a/data/src/main/java/one/nem/kidshift/data/retrofit/model/child/ChildRequest.java b/data/src/main/java/one/nem/kidshift/data/retrofit/model/child/ChildRequest.java new file mode 100644 index 0000000..ab37e8a --- /dev/null +++ b/data/src/main/java/one/nem/kidshift/data/retrofit/model/child/ChildRequest.java @@ -0,0 +1,4 @@ +package one.nem.kidshift.data.retrofit.model.child; + +public class ChildRequest extends ChildBaseItem { +} diff --git a/data/src/main/java/one/nem/kidshift/data/retrofit/model/child/ChildResponse.java b/data/src/main/java/one/nem/kidshift/data/retrofit/model/child/ChildResponse.java new file mode 100644 index 0000000..92fd685 --- /dev/null +++ b/data/src/main/java/one/nem/kidshift/data/retrofit/model/child/ChildResponse.java @@ -0,0 +1,4 @@ +package one.nem.kidshift.data.retrofit.model.child; + +public class ChildResponse extends ChildBaseItem { +} diff --git a/data/src/main/java/one/nem/kidshift/data/retrofit/model/task/TaskAddRequest.java b/data/src/main/java/one/nem/kidshift/data/retrofit/model/task/TaskAddRequest.java new file mode 100644 index 0000000..ba3b2b5 --- /dev/null +++ b/data/src/main/java/one/nem/kidshift/data/retrofit/model/task/TaskAddRequest.java @@ -0,0 +1,39 @@ +package one.nem.kidshift.data.retrofit.model.task; + +import java.util.List; + +// Request to add a task, with optional attached children +public class TaskAddRequest extends TaskBaseItem { + private List attachedChildren; + + // Full + public TaskAddRequest(String name, String iconEmoji, String bgColor, int reward, List attachedChildren) { + super(name, iconEmoji, bgColor, reward); + this.attachedChildren = attachedChildren; + } + + // Required + public TaskAddRequest(String name, int reward, List attachedChildren) { + super(name, reward); + this.attachedChildren = attachedChildren; + } + + // Empty + public TaskAddRequest() { + } + + // Extend + public TaskAddRequest(TaskBaseItem taskBaseItem, List attachedChildren) { + super(taskBaseItem.getName(), taskBaseItem.getIconEmoji(), taskBaseItem.getBgColor(), taskBaseItem.getReward()); + this.attachedChildren = attachedChildren; + } + + // Getters and setters + public List getAttachedChildren() { + return attachedChildren; + } + + public void setAttachedChildren(List attachedChildren) { + this.attachedChildren = attachedChildren; + } +} \ No newline at end of file diff --git a/data/src/main/java/one/nem/kidshift/data/retrofit/model/task/TaskBaseItem.java b/data/src/main/java/one/nem/kidshift/data/retrofit/model/task/TaskBaseItem.java new file mode 100644 index 0000000..bbb5816 --- /dev/null +++ b/data/src/main/java/one/nem/kidshift/data/retrofit/model/task/TaskBaseItem.java @@ -0,0 +1,85 @@ +package one.nem.kidshift.data.retrofit.model.task; + +// Base class for tasks +public class TaskBaseItem { + private String id; + private String name; + private String iconEmoji; // Optional + private String bgColor; // Optional + private int reward; + + // Full + public TaskBaseItem(String id, String name, String iconEmoji, String bgColor, int reward) { + this.id = id; + this.name = name; + this.iconEmoji = iconEmoji; + this.bgColor = bgColor; + this.reward = reward; + } + + // Without id + public TaskBaseItem(String name, String iconEmoji, String bgColor, int reward) { + this.name = name; + this.iconEmoji = iconEmoji; + this.bgColor = bgColor; + this.reward = reward; + } + + // Required + public TaskBaseItem(String id, String name, int reward) { + this.id = id; + this.name = name; + this.reward = reward; + } + + // Without id and optional fields + public TaskBaseItem(String name, int reward) { + this.name = name; + this.reward = reward; + } + + // Empty + public TaskBaseItem() { + } + + // Getters and setters + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getIconEmoji() { + return iconEmoji; + } + + public void setIconEmoji(String iconEmoji) { + this.iconEmoji = iconEmoji; + } + + public String getBgColor() { + return bgColor; + } + + public void setBgColor(String bgColor) { + this.bgColor = bgColor; + } + + public int getReward() { + return reward; + } + + public void setReward(int reward) { + this.reward = reward; + } +} diff --git a/data/src/main/java/one/nem/kidshift/data/retrofit/model/task/TaskListResponse.java b/data/src/main/java/one/nem/kidshift/data/retrofit/model/task/TaskListResponse.java new file mode 100644 index 0000000..dd2c16a --- /dev/null +++ b/data/src/main/java/one/nem/kidshift/data/retrofit/model/task/TaskListResponse.java @@ -0,0 +1,26 @@ +package one.nem.kidshift.data.retrofit.model.task; + +import java.util.List; + +// Response for a list of tasks +public class TaskListResponse { + private List list; + + // Full + public TaskListResponse(List list) { + this.list = list; + } + + // Empty + public TaskListResponse() { + } + + // Getters and setters + public List getList() { + return list; + } + + public void setList(List list) { + this.list = list; + } +} diff --git a/data/src/main/java/one/nem/kidshift/data/retrofit/model/task/TaskResponse.java b/data/src/main/java/one/nem/kidshift/data/retrofit/model/task/TaskResponse.java new file mode 100644 index 0000000..1312d5d --- /dev/null +++ b/data/src/main/java/one/nem/kidshift/data/retrofit/model/task/TaskResponse.java @@ -0,0 +1,39 @@ +package one.nem.kidshift.data.retrofit.model.task; + +import java.util.List; + +// Response for a single task with attached children +public class TaskResponse extends TaskBaseItem { + private List attachedChildren; + + // Full + public TaskResponse(String id, String name, String iconEmoji, String bgColor, int reward, List attachedChildren) { + super(id, name, iconEmoji, bgColor, reward); + this.attachedChildren = attachedChildren; + } + + // Required + public TaskResponse(String id, String name, int reward, List attachedChildren) { + super(id, name, reward); + this.attachedChildren = attachedChildren; + } + + // Empty + public TaskResponse() { + } + + // Extend + public TaskResponse(TaskBaseItem taskBaseItem, List attachedChildren) { + super(taskBaseItem.getId(), taskBaseItem.getName(), taskBaseItem.getIconEmoji(), taskBaseItem.getBgColor(), taskBaseItem.getReward()); + this.attachedChildren = attachedChildren; + } + + // Getters and setters + public List getAttachedChildren() { + return attachedChildren; + } + + public void setAttachedChildren(List attachedChildren) { + this.attachedChildren = attachedChildren; + } +} \ No newline at end of file diff --git a/feature/debug/src/main/java/one/nem/kidshift/feature/debug/DebugMockTestFragment.java b/feature/debug/src/main/java/one/nem/kidshift/feature/debug/DebugMockTestFragment.java deleted file mode 100644 index 9fa62d4..0000000 --- a/feature/debug/src/main/java/one/nem/kidshift/feature/debug/DebugMockTestFragment.java +++ /dev/null @@ -1,62 +0,0 @@ -package one.nem.kidshift.feature.debug; - -import android.os.Bundle; - -import androidx.fragment.app.Fragment; - -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import javax.inject.Inject; - -import dagger.hilt.android.AndroidEntryPoint; -import one.nem.kidshift.data.RewardData; -import one.nem.kidshift.data.TaskData; - -@AndroidEntryPoint -public class DebugMockTestFragment extends Fragment { - - @Inject - TaskData taskData; - - @Inject - RewardData rewardData; - - public DebugMockTestFragment() { - // Required empty public constructor - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - // Inflate the layout for this fragment - return inflater.inflate(R.layout.fragment_debug_mock_test, container, false); - } - - @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - - // TaskData - TextView taskDataStatus = view.findViewById(R.id.taskData_mockedStatusTextView); - taskDataStatus.setText("isMocked: true"); // TODO: 固定値やめる - - TextView taskDataResult = view.findViewById(R.id.taskData_resultTextView); - - view.findViewById(R.id.taskData_getTasksButton).setOnClickListener(v -> { - taskDataResult.setText(taskData.getTasks().stream().map(Object::toString).reduce("", (a, b) -> a + b + "\n")); - }); - - // RewardData - TextView rewardDataStatus = view.findViewById(R.id.rewardData_mockedStatusTextView); - rewardDataStatus.setText("isMocked: true"); // TODO: 固定値やめる - - TextView rewardDataResult = view.findViewById(R.id.rewardData_resultTextView); - view.findViewById(R.id.rewardData_getTotalRewardButton).setOnClickListener(v -> { - rewardDataResult.setText(rewardData.getTotalReward().toString()); - }); - } - -} \ No newline at end of file diff --git a/feature/debug/src/main/java/one/nem/kidshift/feature/debug/DebugTopMenuFragment.java b/feature/debug/src/main/java/one/nem/kidshift/feature/debug/DebugTopMenuFragment.java index ff5f079..05e23bd 100644 --- a/feature/debug/src/main/java/one/nem/kidshift/feature/debug/DebugTopMenuFragment.java +++ b/feature/debug/src/main/java/one/nem/kidshift/feature/debug/DebugTopMenuFragment.java @@ -31,7 +31,6 @@ public class DebugTopMenuFragment extends Fragment { recyclerView.setLayoutManager(new androidx.recyclerview.widget.LinearLayoutManager(getContext())); List debugMenuListItems = new ArrayList<>(); - debugMenuListItems.add(new DebugMenuListItemModel("Data mock tester", "データモジュールの取得処理のモックをテストします", R.id.action_debugTopMenuFragment_to_debugMockTestFragment, true)); debugMenuListItems.add(new DebugMenuListItemModel("Debug console", "デバッグコマンドを実行します", R.id.action_debugTopMenuFragment_to_debugDebugConsoleFragment, true)); debugMenuListItems.add(new DebugMenuListItemModel("Temp login", "仮置きログイン画面を表示", R.id.action_debugTopMenuFragment_to_debugTempLoginFragment, true)); debugMenuListItems.add(new DebugMenuListItemModel("Temp register", "仮置き登録画面を表示", R.id.action_debugTopMenuFragment_to_debugTempRegisterFragment, true)); diff --git a/feature/debug/src/main/res/layout/fragment_debug_mock_test.xml b/feature/debug/src/main/res/layout/fragment_debug_mock_test.xml deleted file mode 100644 index 6420269..0000000 --- a/feature/debug/src/main/res/layout/fragment_debug_mock_test.xml +++ /dev/null @@ -1,119 +0,0 @@ - - - - - - - - - - - - - - - - - -