Menu

Skip to content
AppleScriptの穴
  • Home
  • Products
  • Books
  • Docs
  • Events
  • Forum
  • About This Blog
  • License
  • 仕事依頼

AppleScriptの穴

Useful & Practical AppleScript archive. Click '★Click Here to Open This Script' Link to download each AppleScript

タグ: Sorting

Chat GPTに書かせたQuickSort(昇順・降順ソート)2D

Posted on 12月 4 by Takaaki Naganoya

2D List(2次元配列)のソートルーチンをChatGPTに書かせてみました。1,000項目のソートで0.6秒(MacBook Air M2)、10,000項目のソートで329秒(MacBook Air M2)。

そのままでは使い物にならないので、listの持ち方を変えて高速化対応を行い、10,000項目のソートで0.32秒まで速くなりました。

Cocoaの機能を利用して10,000項目の2D Listソートすると、0.08秒ほど(MacBook Air M2)でしたが、Cocoaでソートする場合にはList中にアプリケーションのオブジェクト情報を入れられないので、Vanilla Scriptのソートルーチンもそれなりに高速なものをそろえておく必要があります。

ChatGPTにソートルーチンを書かせてみたら、AppleScriptのListは遅いとか言い訳をしだしたので、「こうしたら速くなるよ、100倍ぐらい」と言い返したら、少しマシな内容を返してきました。人間だと思って相手をすると腹が立ちますが、人間だと思わず、あらかじめ正解を知っていればそちらに誘導するぐらいはできそうです。

AppleScript名:Chat GPTに書かせたQuickSort(昇順・降順ソート_高速化改造版)2D.scpt
use AppleScript
use scripting additions
use framework "Foundation"

script spd
  property aList : {}
end script

set (aList of spd) to {}

repeat 10000 times
  set end of (aList of spd) to {(random number 1000 from 1 to 9999), (random number 1000 from 1 to 9999)}
end repeat

–昇順ソート
set a1Dat to current application’s NSDate’s timeIntervalSinceReferenceDate()
set sortedList to quickSort2DArray((aList of spd), 2, true) –ソート
set b1Dat to current application’s NSDate’s timeIntervalSinceReferenceDate()
set c1Dat to b1Dat – a1Dat

–降順ソート
set a2Dat to current application’s NSDate’s timeIntervalSinceReferenceDate()
set sortedList to quickSort2DArray((aList of spd), 2, false) –ソート
set b2Dat to current application’s NSDate’s timeIntervalSinceReferenceDate()
set c2Dat to b2Dat – a2Dat

display dialog (c1Dat as number as text) & return & (c2Dat as number as text)
–> 0.01 sec @MacBook Air M2 (1,000 items)
–> 0.32 sec @MacBook Air M2 (10,000 items)

return {c1Dat, c2Dat}

— クイックソートの関数(高速化対応版)
on quickSort2DArray(array2D, columnIndex, ascendingOrder)
  script oBj
    property list : array2D
    
property lessList : {}
    
property greaterList : {}
  end script
  
  
if (length of (oBj’s list)) ≤ 1 then
    return (oBj’s list) — 要素が1つ以下の場合はそのまま返す
  else
    — ピボットを選択(最初の要素を基準)
    
set pivot to item 1 of (oBj’s list)
    
set pivotValue to item columnIndex of pivot
    
    
— ピボットより小さい要素のリスト
    
set (oBj’s lessList) to {}
    
— ピボット以上の要素のリスト
    
set (oBj’s greaterList) to {}
    
    
repeat with i from 2 to length of (oBj’s list) — ピボットを除いたリストを処理
      set currentItem to item i of (oBj’s list)
      
set currentValue to item columnIndex of currentItem
      
      
— 昇順または降順で分岐
      
if (ascendingOrder and currentValue ≤ pivotValue) or ((not ascendingOrder) and currentValue ≥ pivotValue) then
        set end of (oBj’s lessList) to currentItem
      else
        set end of (oBj’s greaterList) to currentItem
      end if
    end repeat
    
    
— 再帰的にソートして結合
    
return (quickSort2DArray((oBj’s lessList), columnIndex, ascendingOrder) & {pivot} & quickSort2DArray((oBj’s greaterList), columnIndex, ascendingOrder))
  end if
end quickSort2DArray

★Click Here to Open This Script 

Posted in list | Tagged 13.0savvy 14.0savvy 15.0savvy Sorting | Leave a comment

複数キーによるソートテスト3.1(OLD Style AppleScript)

Posted on 2月 27, 2018 by Takaaki Naganoya

OLD Style AppleScriptによる2D Listの複数キーによるソートを行うAppleScriptです。

以前掲載したソートルーチンの速度比較で、2D ArrayのソートでOLD Style AppleScript版はSingle Keyのルーチンでしたが、本来であればこのMulti-Keyのルーチンで比較を行うべきでした。

ASOC版はMulti-Keyのソートルーチンなので、2.0 vs 0.3 secondsというところ。

AppleScript名:複数キーによるソートテスト3.1
–複数キーによるソートテスト3(複数キーを許容。キー数無制限)
script orig
  property aList : {}
end script

–テストデータ作成
set aList of orig to {}
repeat 10000 times
  –3次まですべてのキーを使ったソートが発生するよう、1次、2次キーは乱数範囲をわざと狭くしてある
  
set the end of aList of orig to {"a", random number from 1 to 10, random number from 1 to 10, random number from 1 to 100}
end repeat

set sDat to current date –ソート時間計測(開始時刻)

–item 2をPrimary key、item 3とitem 4をサブキーにして降順ソート
set resList to multiKeySortDescending(aList of orig, {2, 3, 4}) of multiKeySort

set eDat to current date –ソート時間計測(終了時刻)

return (eDat – sDat)

–複数キーによるソート
script multiKeySort
  
  
script spd
    property bList : {} –1次キーでソートした結果が入る
    
property cList : {} –1次キーでソートした結果のうち、1次キーで同じ値が連続する範囲が入る {{1,3},{10,20}}
    
    
property dList : {} –2次キーで再ソートする対象の一部のリストが入る(ワーク用)
    
property eList : {} –2次キーで再ソートした結果のリストが入る(ワーク用)
  end script
  
  
  
–複数キー(Primary, Secondary……)による降順ソート。キーは指定用のリストに入れる
  
–falseが返ってきたらエラー
  
on multiKeySortDescending(aList, keyList)
    
    
–Initialize
    
–set aList of spd to {}
    
set bList of spd to {}
    
    
–■■■■ ここからパラメータのチェック ■■■■
    
    
–型チェック
    
set aLen to length of keyList
    
if class of keyList is not equal to list then
      return false –キー値のリストがlistではなかった場合error
    end if
    
    
–ソート対象の2D Listの要素数を取得
    
set tmpLen to length of first item of aList
    
repeat with i in keyList
      if i > tmpLen then
        return false –キー値として指定した内容が、ソート対象のリストの要素数よりも大きかった場合error
      end if
    end repeat
    
    
–キー指定内容で重複がないかチェック
    
set dupList to detectDuplicates(keyList) of me
    
if dupList is not equal to {} then
      return false –指定したキーで重複があったらerror
    end if
    
    
–キー指定内容に0が入っていないかチェック
    
if 0 is in keyList then return false
    
    
–■■■■ パラメータのチェックここまで ■■■■
    
    
    
    
set firstKeyNo to first item of keyList
    
    
–1次キーで2D Listをソート(降順)
    
set bList of spd to shellSortListDescending(aList, firstKeyNo) of me
    
    
–複数キーによるソート検証および実行ループ
    
repeat with iii from 1 to aLen – 1
      
      
set cList of spd to {}
      
set dList of spd to {}
      
set eList of spd to {}
      
      
–n次キーの値が連続する箇所を探す
      
set curData to missing value
      
      
set sucF to false –データ連続箇所検出中フラグ(false=非連続、true=連続中)
      
set biginItem to 0
      
set endItem to 0
      
      
set itemC to 0
      
      
repeat with i in bList of spd
        set thisData to item (item iii of keyList) of i –n次キー
        
        
–現在の値と前の値が等しい(連続箇所を検出した、あるいは連続箇所の中にいる)
        
if curData = thisData then
          
          
if sucF = false then
            set biginItem to itemC
            
set sucF to true
          else if sucF = true then
            –連続箇所の検索継続中、何もしない
          end if
          
        else
          –現在の値と前の値が等しくない(連続していない、あるいは連続箇所の末尾を検出した)
          
if sucF = true then
            set the end of cList of spd to {biginItem, itemC}
            
set sucF to false
          end if
          
          
set curData to thisData
          
        end if
        
        
set itemC to itemC + 1
        
      end repeat
      
      
–n次キーの連続状態の検出中のままリスト末尾に来た場合には、最終データを出力する
      
if sucF = true and curData = thisData then
        set the end of cList of spd to {biginItem, itemC}
      end if
      
      
      
–n次キーによる重複箇所がない場合には、n次キーによるソート結果をそのまま返す
      
if cList of spd = {} then
        return bList of spd
      end if
      
      
–n+1次キーによる部分ソートし直し
      
repeat with i in cList of spd
        set {tmpB, tmpE} to i
        
        
copy items tmpB thru tmpE of (bList of spd) to (dList of spd)
        
set (eList of spd) to shellSortListDescending((dList of spd), (item (iii + 1) of keyList)) of me
        
        
set tmpCounter to 1
        
repeat with ii from tmpB to tmpE
          copy item tmpCounter of (eList of spd) to item ii of (bList of spd)
          
set tmpCounter to tmpCounter + 1
        end repeat
      end repeat
      
    end repeat
    
    
return (bList of spd)
    
  end multiKeySortDescending
  
  
–リスト中から重複項目をリストアップする
  
on detectDuplicates(aList)
    set aCount to length of aList
    
    
set duplicationList to {}
    
repeat aCount times
      set anItem to contents of (first item of aList)
      
set aList to rest of aList
      
if anItem is in aList then
        set the end of duplicationList to anItem
      end if
    end repeat
    
    
return duplicationList
  end detectDuplicates
  
  
–シェルソートで入れ子のリストを降順ソート
  
on shellSortListDescending(aSortList, aKeyItem)
    script oBj
      property list : aSortList
    end script
    
set len to count oBj’s list’s items
    
set gap to 1
    
repeat while (gap ≤ len)
      set gap to ((gap * 3) + 1)
    end repeat
    
repeat while (gap > 0)
      set gap to (gap div 3)
      
if (gap < len) then
        repeat with i from gap to (len – 1)
          set temp to oBj’s list’s item (i + 1)
          
set j to i
          
repeat while ((j ≥ gap) and (contents of item aKeyItem of (oBj’s list’s item (j – gap + 1)) < item aKeyItem of temp))
            set oBj’s list’s item (j + 1) to oBj’s list’s item (j – gap + 1)
            
set j to j – gap
          end repeat
          
set oBj’s list’s item (j + 1) to temp
        end repeat
      end if
    end repeat
    
return oBj’s list
  end shellSortListDescending
  
end script

★Click Here to Open This Script 

Posted in list Sort | Tagged 10.11savvy 10.12savvy 10.13savvy Sorting | Leave a comment

AppleScript sorting performance comparison

Posted on 2月 22, 2018 by Takaaki Naganoya

Pure AppleScriptからAppleScriptObjCに部品を書き換えて、どの程度パフォーマンスが向上するかを調べてまとめてみました。グラフ内の単位は秒(seconds)です。

1D Array(list)では、Pure AppleScriptを使う意義はほとんど感じません。

2D Arrayで思ったよりもASOCが速いように見えませんが、Pure AppleScript側は指定できるキー数が1つのみのルーチンで、ASOC側は複数キーで個別にAscending/Descendingの指定ができるため、複数キー対応ソートルーチンで比較するべきなのかもしれません。

ただし、各GUIアプリケーションのオブジェクトはNSArrayに入れることはできないため、Pure AppleScript版の2D listのソーティングルーチンには利用価値があります。

今回のテストで予想外の結果が出たのがコレです。思ったよりもdictionary in array(record in list)のソートでパフォーマンス向上が見られない、といったところでしょうか。大量のデータをソートする場合に、dictionary in arrayよりも2D Arrayでデータを保持したほうが高速、ということは確実にいえるでしょう。

Posted in list Sort | Tagged Sorting | 1 Comment

TextEdit本文色に応じて青っぽい色は男性の音声で、赤っぽい色は女性の音声で読み上げ

Posted on 2月 16, 2018 by Takaaki Naganoya

TextEditの本文内で文字色が青っぽい色の文字は男性の音声で、赤っぽい色の文字は女性の音声で読み上げる(sayコマンド)AppleScriptです。

実行時には日本語読み上げ音声のKyokoとOtoyaをインストールしてある必要があります。インストールしてあるかどうか、対象の言語、性別で検出を行い、存在していなかった場合には読み上げを行いません。

AppleScript名:TextEdit本文色に応じて青っぽい色は男性の音声で、赤っぽい色は女性の音声で読み上げ
— Created 2018-02-15 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"

property NSColor : a reference to current application’s NSColor
property NSArray : a reference to current application’s NSArray
property NSSortDescriptor : a reference to current application’s NSSortDescriptor

–TTS音声情報を取得する
set curLang to "ja_JP"

set v1List to getTTSVoiceNameWithLanguageAndGender(curLang, "Male") of me
if length of v1List = 0 then return
set v1 to contents of item 1 of v1List –Male Voice

set v2List to getTTSVoiceNameWithLanguageAndGender(curLang, "Female") of me
if length of v2List = 0 then return
set v2 to contents of item 1 of v2List –Female Voice

–TextEditの書類から情報を取得
set aResRec to (getTextStrAndColor() of me)
set colList to colorDat of aResRec
set strList to strList of aResRec

set aLen to length of strList

repeat with i from 1 to aLen
  set curColor to contents of item i of colList
  
set curStr to contents of item i of strList
  
set aColor to retColorDomainNameFromList(curColor, 65535) of me
  
  
if aColor = "blue" then
    –Read by Male Voice
    
say curStr using v1
  else if aColor = "red" then
    –Read by Female Voice  
    
say curStr using v2
  end if
  
end repeat

on getTextStrAndColor()
  tell application "TextEdit"
    if (count every document) = 0 then error "No Document"
    
    
tell front document
      set colList to (color of every attribute run)
      
set attList to every attribute run
    end tell
    
return {colorDat:colList, strList:attList}
  end tell
  
end getTextStrAndColor

on retCocoaColorList(aColorList, aMax)
  set cocoaColorList to {}
  
repeat with i in aColorList
    set the end of cocoaColorList to i / aMax
  end repeat
  
set the end of cocoaColorList to 1.0 –Alpha
  
return cocoaColorList
end retCocoaColorList

–数値の1D List with Recordをソート
on sort1DRecList(aList as list, aKey as string, ascendingF as boolean)
  set aArray to NSArray’s arrayWithArray:aList
  
set desc1 to NSSortDescriptor’s sortDescriptorWithKey:aKey ascending:ascendingF selector:"compare:"
  
set bList to (aArray’s sortedArrayUsingDescriptors:{desc1}) as list
  
return bList
end sort1DRecList

on getTTSVoiceNameWithLanguageAndGender(voiceLang, aGen)
  if aGen = "Male" then
    set aGender to "VoiceGenderMale"
  else if aGen = "Female" then
    set aGender to "VoiceGenderFemale"
  end if
  
  
set outArray to current application’s NSMutableArray’s new()
  
  
–Make Installed Voice List
  
set aList to current application’s NSSpeechSynthesizer’s availableVoices()
  
set bList to aList as list
  
  
repeat with i in bList
    set j to contents of i
    
set aDIc to (current application’s NSSpeechSynthesizer’s attributesForVoice:j)
    (
outArray’s addObject:aDIc)
  end repeat
  
  
set aPredicate to current application’s NSPredicate’s predicateWithFormat_("VoiceLocaleIdentifier == %@ && VoiceGender== %@", voiceLang, aGender)
  
set filteredArray to outArray’s filteredArrayUsingPredicate:aPredicate
  
set aResList to (filteredArray’s valueForKey:"VoiceName") as list
  
  
return aResList
end getTTSVoiceNameWithLanguageAndGender

on retColorDomainNameFromList(aColList as list, aColMax as integer)
  set {rNum, gNum, bNum, aNum} to retCocoaColorList(aColList, aColMax) of me
  
set aCol to NSColor’s colorWithCalibratedRed:rNum green:gNum blue:bNum alpha:aNum
  
return retColorDomainNameFronNSColor(aCol) of me
end retColorDomainNameFromList

on retColorDomainNameFronNSColor(aCol)
  set hueVal to aCol’s hueComponent()
  
set satVal to aCol’s saturationComponent()
  
set brightVal to aCol’s brightnessComponent()
  
  
if satVal ≤ 0.01 then set satVal to 0.0
  
  
set colName to ""
  
  
if satVal = 0.0 then
    if brightVal ≤ 0.2 then
      set colName to "black"
    else if (brightVal > 0.95) then
      set colName to "white"
    else
      set colName to "gray"
    end if
  else
    if hueVal ≤ (15.0 / 360) or hueVal ≥ (330 / 360) then
      set colName to "red"
    else if hueVal ≤ (45.0 / 360) then
      set colName to "orange"
    else if hueVal < (70.0 / 360) then
      set colName to "yellow"
    else if hueVal < (150.0 / 360) then
      set colName to "green"
    else if hueVal < (190.0 / 360) then
      set colName to "light blue" –cyan
    else if (hueVal < 250.0 / 360.0) then
      set colName to "blue"
    else if (hueVal < 290.0 / 360.0) then
      set colName to "purple"
    else
      set colName to "pink" –magenta
    end if
  end if
  
  
return colName
end retColorDomainNameFronNSColor

★Click Here to Open This Script 

Posted in Color Sound Text | Tagged 10.11savvy 10.12savvy 10.13savvy Sorting TextEdit | Leave a comment

配列をソートする(1D)

Posted on 2月 6, 2018 by Takaaki Naganoya
AppleScript名:配列をソートする(1D)
— Created 2015-09-02 by Takaaki Naganoya
— 2015 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set anArray to current application’s NSArray’s arrayWithObjects_(1, 2, 3)
–>  (NSArray) {​​​​​1, ​​​​​2, ​​​​​3​​​}

–ソートする
set sortRes1 to anArray’s sortedArrayUsingSelector:"compare:" –逆順の場合には、sortDescriptorを指定する必要がある
–>  (NSArray) {​​​​​1, ​​​​​2, ​​​​​3​​​}

–compare:
–caseInsensitiveCompare:
–localizedCompare:
–localizedCaseInsensitiveCompare:
–localizedStandardCompare:

★Click Here to Open This Script 

Posted in list Sort | Tagged 10.11savvy 10.12savvy 10.13savvy Sorting | Leave a comment

電子書籍(PDF)をオンラインストアで販売中!

Google Search

Popular posts

  • 開発機としてM2 Mac miniが来たのでガチレビュー
  • macOS 13.6.5 AS系のバグ、一切直らず
  • CotEditorで2つの書類の行単位での差分検出
  • Apple純正マウス、キーボードのバッテリー残量取得
  • macOS 15, Sequoia
  • 初心者がつまづきやすい「log」コマンド
  • ディスプレイをスリープ状態にして処理続行
  • Adobe AcrobatをAppleScriptから操作してPDF圧縮
  • 指定のWordファイルをPDFに書き出す
  • メキシカンハットの描画
  • 与えられた文字列の1D Listのすべての順列組み合わせパターン文字列を返す v3(ベンチマーク用)
  • macOS 13 TTS環境の変化について
  • Pixelmator Pro v3.6.4でAppleScriptからの操作時の挙動に違和感が
  • 2023年に書いた価値あるAppleScript
  • Pages本執筆中に、2つの書類モード切り替えに気がついた
  • 可変次元のベクトルに対応したコサイン類似度計算
  • AdobeがInDesign v19.4からPOSIX pathを採用
  • Safariで「プロファイル」機能を使うとAppleScriptの処理に影響
  • Cocoa Scripting Course 続刊計画
  • 指定のPages書類の言語設定を英語に

Tags

10.11savvy (1102) 10.12savvy (1243) 10.13savvy (1392) 10.14savvy (587) 10.15savvy (438) 11.0savvy (282) 12.0savvy (203) 13.0savvy (148) 14.0savvy (96) 15.0savvy (73) CotEditor (63) Finder (51) iTunes (19) Keynote (112) NSAlert (60) NSArray (51) NSBitmapImageRep (20) NSBundle (20) NSButton (34) NSColor (51) NSDictionary (27) NSFileManager (23) NSFont (19) NSImage (41) NSJSONSerialization (21) NSMutableArray (62) NSMutableDictionary (21) NSPredicate (36) NSRunningApplication (56) NSScreen (30) NSScrollView (22) NSString (117) NSURL (97) NSURLRequest (23) NSUTF8StringEncoding (30) NSView (33) NSWorkspace (20) Numbers (70) Pages (52) Safari (44) Script Editor (26) WKUserContentController (21) WKUserScript (20) WKWebView (23) WKWebViewConfiguration (22)

カテゴリー

  • 2D Bin Packing
  • 3D
  • AirDrop
  • AirPlay
  • Animation
  • AppleScript Application on Xcode
  • Beginner
  • Benchmark
  • beta
  • Bluetooth
  • Books
  • boolean
  • bounds
  • Bug
  • Calendar
  • call by reference
  • Clipboard
  • Cocoa-AppleScript Applet
  • Code Sign
  • Color
  • Custom Class
  • dialog
  • diff
  • drive
  • Droplet
  • exif
  • file
  • File path
  • filter
  • folder
  • Font
  • Font
  • GAME
  • geolocation
  • GUI
  • GUI Scripting
  • Hex
  • History
  • How To
  • iCloud
  • Icon
  • Image
  • Input Method
  • Internet
  • iOS App
  • JavaScript
  • JSON
  • JXA
  • Keychain
  • Keychain
  • Language
  • Library
  • list
  • Locale
  • Localize
  • Machine Learning
  • Map
  • Markdown
  • Menu
  • Metadata
  • MIDI
  • MIME
  • Natural Language Processing
  • Network
  • news
  • Noification
  • Notarization
  • Number
  • Object control
  • OCR
  • OSA
  • parallel processing
  • PDF
  • Peripheral
  • PRODUCTS
  • QR Code
  • Raw AppleEvent Code
  • Record
  • rectangle
  • recursive call
  • regexp
  • Release
  • Remote Control
  • Require Control-Command-R to run
  • REST API
  • Review
  • RTF
  • Sandbox
  • Screen Saver
  • Script Libraries
  • sdef
  • search
  • Security
  • selection
  • shell script
  • Shortcuts Workflow
  • Sort
  • Sound
  • Spellchecker
  • Spotlight
  • SVG
  • System
  • Tag
  • Telephony
  • Text
  • Text to Speech
  • timezone
  • Tools
  • Update
  • URL
  • UTI
  • Web Contents Control
  • WiFi
  • XML
  • XML-RPC
  • イベント(Event)
  • 未分類

アーカイブ

  • 2024年12月
  • 2024年11月
  • 2024年10月
  • 2024年9月
  • 2024年8月
  • 2024年7月
  • 2024年6月
  • 2024年5月
  • 2024年4月
  • 2024年3月
  • 2024年2月
  • 2024年1月
  • 2023年12月
  • 2023年11月
  • 2023年10月
  • 2023年9月
  • 2023年8月
  • 2023年7月
  • 2023年6月
  • 2023年5月
  • 2023年4月
  • 2023年3月
  • 2023年2月
  • 2023年1月
  • 2022年12月
  • 2022年11月
  • 2022年10月
  • 2022年9月
  • 2022年8月
  • 2022年7月
  • 2022年6月
  • 2022年5月
  • 2022年4月
  • 2022年3月
  • 2022年2月
  • 2022年1月
  • 2021年12月
  • 2021年11月
  • 2021年10月
  • 2021年9月
  • 2021年8月
  • 2021年7月
  • 2021年6月
  • 2021年5月
  • 2021年4月
  • 2021年3月
  • 2021年2月
  • 2021年1月
  • 2020年12月
  • 2020年11月
  • 2020年10月
  • 2020年9月
  • 2020年8月
  • 2020年7月
  • 2020年6月
  • 2020年5月
  • 2020年4月
  • 2020年3月
  • 2020年2月
  • 2020年1月
  • 2019年12月
  • 2019年11月
  • 2019年10月
  • 2019年9月
  • 2019年8月
  • 2019年7月
  • 2019年6月
  • 2019年5月
  • 2019年4月
  • 2019年3月
  • 2019年2月
  • 2019年1月
  • 2018年12月
  • 2018年11月
  • 2018年10月
  • 2018年9月
  • 2018年8月
  • 2018年7月
  • 2018年6月
  • 2018年5月
  • 2018年4月
  • 2018年3月
  • 2018年2月

https://piyomarusoft.booth.pm/items/301502

メタ情報

  • ログイン
  • 投稿フィード
  • コメントフィード
  • WordPress.org

Forum Posts

  • 人気のトピック
  • 返信がないトピック

メタ情報

  • ログイン
  • 投稿フィード
  • コメントフィード
  • WordPress.org
Proudly powered by WordPress
Theme: Flint by Star Verte LLC